Threads for icefox

  1. 7

    Free email providers, mining supposedly-private data and causing problems by accident? Color me shocked.

    Surprised we don’t see more of this, tbqh.


      What I find shocking is that people are still shocked by this.

      We apparently have to do more to educate the masses that email is 1) not secure, and 2) not private. Especially when google, microsoft, etc are involved. Small email providers may ignore user email contents, but the big players actively use it to game ad clicks, and are thus heavily incentivized to not ignore mail contents. In any case, my previous two points still apply, regardless of the provider.


        I wonder if some sort of crackdown on e-mail hosting providers would work. Like, if Google, MS and all those others had to ditch their mail services and have them operate independantly, like fastmail or something.


          I’ve wondered that and came to the conclusion that they would just go away, because what’s the point for any of them to run financially-free services if they don’t pay their way in data? I mean, I wouldn’t mind that, and email might be actually federated without capricious black holes dragging everything inside them, but … doesn’t seem too likely.

    1. 9

      I appreciate this kind of work, but this repo feels like someone who doesn’t understand a lot of the things he’s explaining.

      A function f :: A => B is an expression - often called arrow or lambda expression - with exactly one (immutable) parameter of type A and exactly one return value of type B.

      That’s not true at all! Some programming languages like Haskell only allow one parameter, but plenty of languages have multiple arity functions. They even give an example of an arity-2 function under the definition of arity!

      [Isomorphism] A pair of transformations between 2 types of objects that is structural in nature and no data is lost.

      For example, 2D coordinates could be stored as an array [2,3] or object {x: 2, y: 3}.

      It’s not enough to have a bijection between the elements, it also needs to be homomorphic. You could add restrictions to make the array and point object isomorphic, but they’re not necessarily: you can append to the array to get a 3D point.

      Setoid: An object that has an equals function which can be used to compare other objects of the same type.

      A setoid is an object with an equivalence relation, not an equals function. Those are different. For example, you can have a setoid of all arrays where the equivalence relation is number of elements, meaning [1, 2] ~ [4, 5].

      1. 5

        I think your comment would be even better If it was a pull request so all the world can benefit, not just the few readers of lobsters

        1. 1

          I opened some issues, but I can’t guarantee that I’ll remember to come back for them.

          My honest opinion, though, is that some of the definitions, like “category”, are almost complete; and as a result, they might as well have been copied out of a textbook. So, given that there are like a half-dozen good category-theory textbooks available for free already, I don’t think that the problem with this jargon is that the material is not fully presented on this single particular article. Rather, I think that the issue is with the overflowing teacups of the typical programmer; a “simple terms” explainer article is not going to fix their unwillingness to be mathematical.

          To make this extremely vivid, I’ve contributed to English Wikipedia and nLab, and so if I were to write explanations of “category”, “functor”, “natural transformation”, etc. then they would probably resemble one of those two wikis. For example, here’s the first sentence for “functor” from the article:

          [A functor is a]n object that implements a map function that takes a function which is run on the contents of that object.

          And from English WP:

          In mathematics, specifically category theory, a functor is a mapping between categories.

          And from nLab:

          Idea: A functor is a homomorphism of categories.

          And, finally, from the issue that I opened:

          The central idea behind a functor is that it is a map between categories; for every arrow in the source category, the functor designates an arrow in the target category, such that identity and composition (the algebraic laws for categories) are preserved.

          I don’t mind contributing, but how am I supposed to simplify this idea when the article prefers to make it more complicated instead?

          1. 9

            I find Wikipedia’s mathematics articles frustrating in that they’re generally not approachable by non-mathematicians. (IMHO, of course, but I speak as a career programmer who has a B.Sci Eng. from a fairly elite university and did minor in math for a year until defeated by finite fields.)

            To wit, the definition of functor from WP (that you quoted) doesn’t bother to explain what “a mapping between categories” means; it thinks it sufficient to have linked to definitions of “mapping” and “category”. (And the one for “mapping” is to a dictionary definition, which is even less helpful.)

            The result is that Wikipedia’s math articles are an endless rabbit hole where the reader finds themself in an ontological free-fall of definitions, unless they decide to stay in one article and hack their way through a dense thicket of unexplained terminology like “functors were first considered in algebraic topology, where algebraic objects (such as the fundamental group) are associated to topological spaces, and maps between these algebraic objects are associated to continuous maps between spaces”, which is literally the second sentence in the article.

            (I know textbooks are often written this way, but usually only the more advanced ones in a field, and textbooks are usually provided along with lectures by a prof who goes into more detail at a shallower angle.)

            The ironic thing is that this is against Wilipedia’s policies, such that they have a canned warning to paste on articles saying that “this is written such that only an expert can understand it.” And yet I’ve never seen that warning on their math articles…

            The glossary in question may be less accurate than the sources you quote, but I found it approachable and comprehensible. It’s a shame it has errors, but I think I’d rather come away with a sketchy understanding of functors or monads than bounce completely off them and be turned off of the entire topic.


              For me, too, the glossary is something I can read and understand. I’m pretty good at maths but I struggle with strict definitions in mathematical language. Give me something in plainer English and I’ll dig into it to understand and resolve ambiguities and eventually get to the point where the mathematical language seems obvious.


                At least the math folks seem to be self-aware


                  It didn’t used to be that way, for reference.

          1. 4

            The title interested me ’cause I recently had an adventure or two with them myself, but unfortunately the site seems to be down –on IPv4 and IPv6 both. Anyone know of a mirror?

            Edit: Aha, DOES have a copy:

            1. 4

              Interesting idea but not much substance.

              1. 1

                it does feel like a lot like just a backwards way to say a mesh network, with some compute.

              1. 1

                Returning void means you return no value. [[noreturn]] means you don’t return at all. ie, put a debugger breakpoint right before the function’s } and it will never get triggered.

                1. 15

                  This lead me to the docs for std::f32::total_cmp(), which has the following brilliant example code:

                  struct GoodBoy {
                      name: String,
                      weight: f32,
                  let mut bois = vec![
                      GoodBoy { name: "Pucci".to_owned(), weight: 0.1 },
                      GoodBoy { name: "Woofer".to_owned(), weight: 99.0 },
                      GoodBoy { name: "Yapper".to_owned(), weight: 10.0 },
                      GoodBoy { name: "Chonk".to_owned(), weight: f32::INFINITY },
                      GoodBoy { name: "Abs. Unit".to_owned(), weight: f32::NAN },
                      GoodBoy { name: "Floaty".to_owned(), weight: -5.0 },
                  bois.sort_by(|a, b| a.weight.total_cmp(&b.weight));
                  1. 2

                    Since I’m looking for a backend, I’m curious over the relative benefits between QBE and TCC. Does anybody have experience with both and any thoughts on the matter?

                    I’m currently leaning a bit towards TCC, since I’m familiar with C and it emits object code directly.

                    1. 1

                      I’d give TCC a go and see how it feels, it’s a cool little project that needs more love.

                      1. 1

                        Yes, TCC is a cool compiler; the generated code is only as fast as GCC with no optimization though; GCC optimized with -O2 is about twice as fast.

                    1. 4

                      The fact that you have to pass -no-pie has nothing to do with ARM64 or Linux. I’m guessing your gcc was configured with --enable-default-pie, so it will try to link as PIE by default. QBE doesn’t generate position-independent code, so it can’t be linked as a PIE. This is why you have to pass -no-pie, and why gcc was complaining about the relocation types. The same thing will happen if you compile code with gcc -fno-PIE and then link it with gcc -pie.

                      Regarding the “bug” described, if you define a function with one set of parameters and call it with a different set of parameters, of course you’ll get incorrect code. QBE has no notion of “function declarations” and doesn’t do type checking. The function call syntax gives QBE all the information it needs to generate code for the function call, but you have to give it the correct information. It is up to the frontend to output correctly typed function calls.

                      Ignoring the env feature entirely, this also doesn’t work:

                      data $str = { b "%f", b 0 }
                      function $print_f64(d %x) {
                          call $printf(l $str, ..., d %x)
                      export function w $main() {
                              call $print_f64(l 12)
                              ret 0

                      This is because print_f64 is defined to take a d parameter, so the code generated for it expects it in a floating point register, but it is called with an l parameter, so the code generated for the call puts the argument in an integer register.

                      1. 1

                        The fact that you have to pass -no-pie has nothing to do with ARM64 or Linux…

                        It has something to do with ARM64 or Linux, because on my AMD64 system with the same Linux distro I don’t have to do it. QBE appears to generate code that is position independent on AMD64:

                        > ./qbe thing.ssa > thing.s
                        > gcc thing.s
                         > file ./a.out
                        ./a.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, ...

                        On the other hand the default cc command line args used in the unit test script all appear to include -no-pie by default. Soooooo I can only conclude that in this case it generates x86 asm code that is just coincidentally position-independent, and a different/more complex case would not.

                        QBE has no notion of “function declarations” and doesn’t do type checking.

                        …I could have sworn this was incorrect, and remember even seeing the code for arg type checking, but upon testing it appears that you are correct. I am quite confused, and annoyed. Thank you for the correction though. Maybe the code I was looking at was for checking the arg types of instructions rather than function calls?

                      1. 3

                        What would you recommend as a compiler backend for implementing a toy language?

                        1. 7

                          I’d recommend LLVM. Generating LLVM IR from your AST can be a somewhat simple procedure (even simpler if you have your own SSA IR), and you can declare external functions in your LLVM IR modules to call anything compatible with the C ABI. This means you can attach libc, a GC, or other libraries very quickly. The LLVM API also has lots of bindings for various languages: C, C++, OCaml, Java, etc.

                          LLVM has its fair share of issues, but for a toy language I’ve yet to find a codegen library that’s as well equipped and easy to pickup as LLVM. I’ve spun up a good amount of toy languages with LLVM and nothing has convinced me to switch away from it so far. If LLVM is too bulky for you (which I think doesn’t really matter in the realm of “toy” languages), then QBE, CraneLift, or straight to WASM are other options. My general advice is pick something that maps well to the constructs in your language.

                          1. 3

                            How about an interpreter instead of a backend?

                            1. 2

                              QBE. The code is dense, but quite nice.

                              1. 2

                                Webassembly has some bumps but is pretty easy to get going with. A high level language like C or Zig or whatever also isn’t a bad choice to get started with. At the moment, I’m literally compiling to Rust and it works far better than it really should. LLVM is maybe a bit more work but honestly probably worth knowing anyway, if you’re interested in it.

                                You can call it a cop-out, as I did to myself for a long time, but frankly there’s nothing wrong with focusing on the part of the compiler you’re really interested in. I’m going to bootstrap this compiler ASAP anyway, so I’ll have to rewrite the backend no matter what and there’s no real downside to leaning on another language until that time.

                                1. 2

                                  Consider just generating C


                                  • much easier than struggling through all the vagaries of a huge and complex IR and platform like LLVM
                                  • a C compiler is available on every conceivable platform, so you’re not restricted to e.g. x86_64 or arm64
                                  • you can expect a priori a good performance, because C compilers usually generate very good code
                                  • C ABI compatibility included
                                  • source level debugging is feasible e.g. with GDB
                                  • there are lean C compilers like TCC that integrate directly with your compiler


                                  • less “fancy” than e.g. WASM
                                  • not suited for every kind of language

                                  If you are planning a dynamic language and need a VM rather than an AOT compiler, you can generate e.g. Lua source code or bytecode and benefit from the lean, efficient and proven Lua engines available.

                                1. 5

                                  This is why my offsite backups are an unencrypted hard drive sitting in a drawer in a family member’s house, in another city. Whenever you’re tying a knot, leave yourself a bit of string to tug on in case you need to undo it later.

                                  1. 3

                                    Trying to tie up loose ends in the last couple of weeks at my current job. I think things are getting to a pretty good state for a smooth handover!

                                    Otherwise, I’m working a lot on my side project, an email alias service. I’m migrating from a hosted email sender to a self-hosted MTA, which is necessary but comes with a whole lot of (ongoing) work!

                                    1. 2

                                      Woof. Self hosting an MTA is quite a lot of work indeed.

                                      I admire anyone who stays on top of this. I feel like GOOG, MSFT and a couple of other key players these days control the horizontal and the vertical, and don’t much care how many smaller players they tread on in the process.

                                      Good luck!

                                      1. 2

                                        Woof. Self hosting an MTA is quite a lot of work indeed.

                                        That hasn’t actually been my experience, surprisingly. I started self-hosting my own email in… 2019 I think, and since early 2021 or so have used it for essentially everything. It took a few days to set up, using postfix + postgres for virtual accounts and dovecot for IMAP. But since then it has probably taken an average of one hour per year to actually support, maybe less. It’s not a perfect setup, but works pretty well and I have zero fears of it suddenly breaking. The only actual outage I’ve had was when I upgraded postgres and had to re-import the user database from backups.

                                        Now that I actually say this, I’m a little surprised by it myself. But I can heartily recommend it to anyone likes being self-reliant, and is running their own VPS anyway.

                                        1. 1

                                          I’m really, REALLY glad to hear!

                                          I know a bunch of other folks and myself got impacted recently when GOOG really clamped down on their rules around DKIM signing and domains.

                                          Found it kind of frustrating when all my outgoing mail all of a sudden to Gmail addresses was getting bit-bucketed, but c’est la guerre I guess :)

                                          1. 2

                                            Yeah I have SPF and reverse DNS, but no DKIM set up at all IIRC. And as far as I can tell I’ve never had problems sending to gmail or any other mail server. Maybe I just got lucky and my VPS’s IP address has never been owned by a spammer? ¯\_(ツ)_/¯

                                            Edit: Just remembered that I still have a gmail account as a backup and it’s set up to forward email to my own server. Maybe that makes a difference to Google?

                                    1. 3

                                      Playing with QBE, maybe doing more type checking, grappling with systemd. Enjoying the nice weather.

                                      1. 1

                                        Self-care and maybe play a little with compiler dev. My basic type checker seems to work, time to add some simple generics and see what happens. Or maybe I’ll take a break from that and play with a backend targeting QBE, now that it’s 1.0.

                                        1. 2

                                          Good suggestions. Though the curmudgeon in me says, “why doesn’t django do this by default?”

                                          I was quite happy when I realized that cargo would create a .gitignore file for me by default when it detected a .git repo, and same for .hgignore. On the one hand it’s kinda extra complexity tucked into an odd spot… on the other it now makes me very much aware of when a tool doesn’t do that.

                                          1. 5

                                            Though the curmudgeon in me says, “why doesn’t django do this by default?”

                                            In order:

                                            1. Because there’s no simple cross-platform way (remember, people will develop on Windows!) to automatically set the env variable locally for a new project. There’s really not even a good way if you just restrict yourself to Unix-y systems, because any approach you take, like buying into direnv or whatever, will cause screaming rage from some subset of users who think that approach is evil and wrong and must never be used.
                                            2. Similar to (1) because really this is about being able to set a single value in the env and then parse it out into all the config Django wants for the database. Django also has to support setting a lot of DB config that doesn’t easily fit into a simple URL.
                                            3. It’s a massive backwards-compatibility headache to change the default user-model approach. Fixing this would basically require complete deprecation and replacement of the current django.contrib.auth, which is such a huge disruptive change that it’s unlikely ever to happen. Though pressure to support modern MFA and/or hardware-token-based auth protocols may end up forcing Django’s hand on massive backwards-incompatible changes in the auth app.
                                            4. This is entirely a matter of subjective taste and would be bikeshedded to death if Django tried to do it for you.
                                            5. Same as (4).
                                            6. Patches welcome.

                                            (and an obligatory reminder that although I have in the past held leadership positions within both the Django open-source project and the nonprofit foundation which supports it, I stepped down from all of them a couple years ago and am now merely someone with a lot of experience in Django, rather than someone who makes or can speak for the technical decisions of the project; thus, the above are my own personal answers and do not necessarily represent any official stance of the Django technical board)

                                            1. 1

                                              Thanks for the info.

                                          1. 4

                                            Kinda highlights the differences between modern encryption/decryption tech and pre-WW2 tech. Also a great demonstration that context still matters.

                                            1. 8

                                              I read the first line and was like “wow I hate this”. …Then I read five more lines and was like “wow I love this”. I need to make this required reading for new hires at work.

                                              1. 1

                                                Might take a break from type checking and play with Erlang. Or Elixir?

                                                So, should I do robotics stuff with it, or should I build a video streaming site?

                                                1. 6

                                                  My 5yo son is really into space at the moment, so I’m taking him to the Smithsonian Air and Space Museum and seeing a short IMAX movie on space there.

                                                  Working on resting better for myself; I’ve had issues with migraines and TMJ as of late and need to build better patterns of rest in to mitigate.

                                                  Might start hacking on a tiny WebAssembly interpreter. Other than the official spec, does anyone have any reference material for it they really like?

                                                  1. 3

                                                    I love the Air And Space Museum and wish I was going with you.

                                                  1. 8

                                                    I fully support this kind of content. It is as lobsteresque as it comes. I enjoyed the descriptions of the maths behind it all.

                                                    I have some comments

                                                    1. The description of the actual hardware is a bit buried, and should have been a bit more front and center. I’m still not sure what it is exactly, but it looks to be a geiger counter attached to an interrupt pin which is used to sample from a counter.
                                                    2. Not clear if the banana has an actual role here, besides being a McGuffin, since the counter is likely mostly responding to the background radiation.
                                                    1. 10

                                                      My experience with bananas and geiger counters is that the banana is the dominant source of radiation. Background radiation varies, so if you are in a radon filled basement or in the Chernobyl exclusion zone, your experience may be different.

                                                      Also, a medium size white potato has twice the potassium of the average banana. So you would probably get more entropy with a potato. But, on the other hand, bananas are inherently more funny.

                                                      1. 3

                                                        I dunno, potatoes are pretty funny too. I wonder if one could build one of these that uses the potato as a battery to power itself as well?

                                                          1. 1

                                                            I think that Brainiac75 is using the wrong kind of Geiger counter. There are different kinds of Geiger counters, using different kinds of detectors. The low energy beta radiation emitted by a banana can’t penetrate most solid objects, so you need the right kind of detector to measure it. The Geiger counter in Brainiac75’s video appears to be the wrong kind. The right kind of Geiger counter typically has a cylindrical “wand”, connected to a box. The wand contains an “end window” type Geiger–Müller tube. The end window (at the tip of the wand) is made of mica, which the banana’s beta radiation can penetrate. The radiation can’t penetrate the sides of the tube.


                                                            1. 1

                                                              Later on in the video he shows recordings from pure potassium.


                                                              Each banana can emit .01 millirem (0.1 microsieverts) of radiation. This is a very small amount of radiation. To put that in context, you would need to eat about 100 bananas to receive the same amount of radiation exposure as you get each day in United States from natural radiation in the environment.

                                                              It does seem to be that the radiation from a single banana is pretty close to background levels.

                                                      1. 1

                                                        Something that doesn’t involve making plans, hopefully. Maybe some yard work, since the weather is cooling off. Might be a good opportunity to play with a pressure washer.

                                                        Garnet’s type checker is actually working so far, amazingly enough, so it’s likely I’ll keep plugging away at it. It can almost do all primitive types, so after all my tests for those pass I can work on functions with generic arguments, and once those work it will be time to attack compound types that may have generics. I expect it to either go okay, or completely melt my code again and make me give up and play with Erlang or something.