Threads for coventry

  1. 1

    I walk by this place from time to time, and always wonder how they stay afloat:

    https://byteshop.io/

    I struggle to see old computers as anything more than junk. There are exceptions of great historic significance, like Colossus, but I have no use for a TRS-80 Color Computer II, my first ever computer, for instance.

    1. 1

      I’d be curious about the author’s views on golang interfaces.

      1. 1

        I’d like to know how to get wireguard working with IPv6. When I have an IPv6 connection, I often have to disable IPv6 locally, so that I can fail over to IPv4, which works fine with wireguard.

        1. 6

          So what we’re saying, if anything sets Symbol.IsConcatSpreadable anywhere in the gazillion deps of your average NodeJS-application, the speed of Array.concat for the entire javascript engine will suffer?

          Hm Hm can I implement a runtime check for this?

          1. 2

            If you’re running on known hardware it’d be pretty easy to test for the performance regression…

            1. 2

              Maybe run a benchmark to get a baseline, turn IsConcatSpreadable on, run the benchmark again, compare the times, and if there’s no significant change IsConcatSpreadable was already turned on?

            1. 16

              “To keep Signal a free global communication service without spam, we must depart from our totally-open posture and develop one piece of the server in private: a system for detecting and disrupting spam campaigns.”

              I don’t know what to think…

              1. 12

                As someone who loves Signal, and has made most family and a few friends switch to it, quite frankly, I think it’s stupid and unnecessary.

                I have never in my years and years of using Signal, had a spam message.
                Regardless, won’t spammers just find a way around the block, keep spamming, then Signal will update their anti-spam, ad infinitum?

                My biggest issue with this is that it can totally be (ab)used to censor specific groups. When they integrate software that’s able to “detect and disrupt spam campaigns”, don’t people think this could, even accidentally, censor some messages that aren’t spam?

                Surely there’s some benefit in opening their anti-spam process/code to the public, even purely for transparency’s sake. If they’re using a ML algorithm then just release the model files so people can scrutinise how accurate the model is, and/or if it’s prone to censor non-spam messages.

                1. 9

                  I have never in my years and years of using Signal, had a spam message.

                  Same, but it looks like others haven’t been so lucky: https://community.signalusers.org/t/spam-scam-on-signal/26665

                  Regardless, won’t spammers just find a way around the block, keep spamming, then Signal will update their anti-spam, ad infinitum?

                  Doesn’t this describe basically every anti-spam measure, though?

                  IMO the photo blurring and non-linkifying described in the article sounds like a reasonable place to start. It’s largely unobtrusive and doesn’t seem like it’d require that much iteration vs. server side mechanics.

                  Yeah, those opaque server side mechanics will need updating, but they aren’t unaware of this:

                  As our spam-fighting capabilities expand, so does the complexity and size of our spam-specific software. To prevent spam on Signal, we need to build this spam-battling logic in a separate server component. The interfaces to this code will be public, but the implementation will not be shared.

                  So yeah, it seems like they’re at least somewhat committed to making this work. At the very least these measures should help.

                  My biggest issue with this is that it can totally be (ab)used to censor specific groups. When they integrate software that’s able to “detect and disrupt spam campaigns”, don’t people think this could, even accidentally, censor some messages that aren’t spam?

                  Maybe I’m misreading but it seems like they’re taking recipient-generated “this number spammed me” reports and issuing captchas for the sender. That seems fairly straightforward, and it would be hard for Signal to discriminate against message content with that approach.

                  1. 3

                    Maybe I’m misreading but it seems like they’re taking recipient-generated “this number spammed me” reports and issuing captchas for the sender. That seems fairly straightforward, and it would be hard for Signal to discriminate against message content with that approach.

                    I think you’re probably right. If that is the case, I have more confidence in it than I did when I first wrote that comment.

                  2. 7

                    The root problem with spam on Signal is that they (like the phone system and email) conflate two concepts:

                    • A unique identity.
                    • A capability to contact a person.

                    If you can name someone’s phone number, you can send them messages. This may be restricted to a single ‘may I contact you’ message, but if you can create large numbers of Signal accounts then that’s not really ideal.

                    The correct fix for this would be for Signal to create capabilities that allowed contact creation, with automatic registration for people in your address book. If you get a message from someone in your address book, unless you’ve explicitly blocked them then they should be allowed to contact you. Everyone else, you should have done some explicit process for establishing the contact. The simplest model is a single-use capability. If, for example, I want a company to be able to contact me with Signal but not to be able to pass on that ability, I would generate a one-time token and send it to them (this should be wrapped in some nice mechanism, probably involving them presenting me with a QR code and my scanning it with my phone). They can then use that token to negotiate a key pair that is tied to their identity. They can then send me as many messages as they want, but only from that identity and I can block that identity if I choose to. Any attempt to use the token a second time would fail.

                    For other flows, you could allow time-limited or revokable tokens that can be used multiple times. I could put such a token on my web site and if it starts to get spam I revoke it and replace it with a new one. Anyone who uses a valid token can try to connect to me and I’ll get their ‘allow contact’ message but if you crawl the web and try to bulk harvest them then it won’t work because I’ll roll them over once they’ve found it and so they’d need to poll the location to find a current one, which gives me something I can block on the server. This kind of flow is more useful for journalists that want to provide a mechanism for secure contact with informants than for normal folks, so it doesn’t matter too much if it’s a bit clunky if you need rapid turnover. If you want to put a signal token in an email signature then you can do fairly infrequent turnover because you generally aren’t sending emails to people that you don’t want to contact you (but you could potentially configure your mail client to generate per-email tokens so that you can revoke them individually).

                    Everything that they’re doing at the moment is just a work around for that initial conflation.

                    1. 6

                      I have never in my years and years of using Signal, had a spam message.

                      Me neither, even though I am using Signal heavily. But that experience might depend on your location? Spam calls and text always seem to be a bigger problem in the US than over here in Europe, so maybe that’s the same for Signal spam?

                      1. 3

                        Location is something I didn’t consider. You have a good point there.

                        1. 3

                          I’m based in the US and have never received a single spam Signal message over the years and years I’ve used Signal. I’ve received a freakton of SMS-based spam, though. I don’t use Signal as my default SMS provider, so the spam messages I see don’t even appear inside of Signal.

                          I wonder if setting Signal to be the default SMS app would cause confusion between SMS-based spam and Signal-based spam messages.

                        2. 4

                          » I have never in my years and years of using Signal, had a spam message.

                          I was almost ready to defend signal but I’ve never had a single spam message on the Signal network itself. I’ve seen some spam recently but that’s spam text messages on Android which this blog post doesn’t seem to cover anyways.

                          (Sample https://user-images.githubusercontent.com/1676445/139789818-82d6f038-c0b5-4707-a4a3-6140ad6d72d5.png)

                          1. 4

                            Personally, I don’t use signal as my SMS app for this reason; I don’t want to ever even have to think about whether a message has come through SMS or the Signal network.

                            I know Signal has the “Unsecured SMS” message in the text box, but I’d rather keep them separate apps entirely.

                          2. 3

                            I get tons of spam on signal.

                            1. 1

                              I have never in my years and years of using Signal, had a spam message.

                              hmm, I don’t use Signal too much (have just three convos in it) yet at some point I was getting spam requests a couple times per month. I don’t use it as an SMS app.

                            2. 3

                              Seems like a reasonable step, to me. They’re not changing the protocol, so whatever methods they’re using for spam detection operate without the plaintext or extra metadata (apart from what they get when you explicitly report spam.)

                              1. 2

                                I‘ve also never received spam on Signal… I think I received spam on WhatsApp a few times and it was no hassle for me to just click it away. I think it is quite easy to spot it, because its really uncommon to get messages from an unknown number…

                              1. 4

                                I’ve been enjoying all the discussion recently about methods people are using to be faster at programming, so I decided I’d contribute my a list of my own.

                                I’d be eager to hear what everyone else does that I haven’t listed!

                                One area I know I’m quite lacking is in using good keyboard shortcuts and keybaord-based navigation as a whole. I still do a good amount of clicking around the editor to select stuff and move the cursor, and I’ve seen some vim users who take pride in never taking their hands off the keyboard.

                                1. 3

                                  Honest question: Is it really the tooling that does it…? Or is it just icing on the cake? Compared to knowledge of algorithms, choosing the right language for the job, and stuff like that.

                                  1. 1

                                    Having to pick up the mouse from time to time is an annoying distraction though. When I moved from Vim to VSCode, not learning the keyboard shortcuts feels quite destructive in the tight modify-compile-run loop. Having learned how to switch between editor window and terminal helps a lot.

                                    1. 1

                                      In case you haven’t seen it yet, vim extension for vscode is really good. Less relearning that way.

                                  2. 3

                                    Long ago Bruce Tognazzini did some experiments showing that choosing a command from a GUI menu was measurably faster than pressing the keyboard shortcut, even though the people doing it felt that the keyboard was faster. (The exceptions were super common shortcuts like Copy and Paste that were burned into muscle memory.) He hypothesized that subjective experience of time was different when performing a physical task like moving a mouse, than for a memory based task like remembering a key command.

                                    I’m sure an expert can get the full range of keyboard navigation commands burned into muscle memory to where it’s faster than mousing, but personally, I’m waiting for eye-tracking interfaces that can move the cursor to where I’m looking.

                                    1. 12

                                      Dan Luu did a rebuttal to Bruce’s claims: https://danluu.com/keyboard-v-mouse/

                                      1. 3

                                        The fundamental flaw with mousing is that you have to look (at things) to use it.

                                        The operational cycle is: 1) actuate muscle motor skills, 2) watch mouse pointer movement, and other on-screen UI changes, 3) loop (1 -> 2) until target is reached, 4) complete task (click, hover, release drag)

                                        With keyboard, assuming you are zeroed in on your home row position, you can execute the vast majority of your tasks without looking. The cycle is: 1) actuate muscles, 2) complete task

                                        1. 3

                                          Exactly. The point is not to minimize the amount of milliseconds that the operation takes, but to minimize the amount of distraction or context switching. Ideally one can edit the code without paying special attention to the editing process itself, so your mind can devote all space to solving the actual problem you are taking on.

                                          I’d say this goal is easier to reach with keyboard shortcuts than with the mouse. But perhaps one can do this with the mouse too after enough training.

                                        2. 1

                                          Interesting finding! In my case, I opened a really old delphi project recently, I think I hadn’t had delphi installed in years, but the shortcuts immediately were in my muscle memory. What I used often stayed there - just like riding the bike. There are so many commands today that nearly impossible to memorize ’em all, but what you use the most frequently worth the effort to memorize (which is like using it 6-8 times to learn?) - those will actually speed up your daily routine.

                                        3. 1

                                          I have this in my .spacemacs:

                                            ;; Don't use the mouse in emacs. It's just annoying.
                                            (load-file "~/.emacs.d/private/disable-mouse.el")
                                          

                                          https://github.com/purcell/disable-mouse/blob/master/disable-mouse.el

                                          1. 3

                                            What’s the agenda for the meeting this Tuesday?

                                            1. 2

                                              On Tuesday, we will read the first couple of pages of the handbook and discuss the first few introductory problems in the problem set. We will keep an updated schedule and study plan available here: https://offbeat.cc/cses/. Right now it says,

                                              Current plan: Problems 1-6; Pages 3-11 (Oct 19-21)

                                              In case that looks like a slow schedule, indeed our reading sessions tend to be slow-paced most of the time. We pick only about one or two topics in most meetings. As a meeting host, I focus on spending a decent amount of time with each concept with the intention of developing good intuition for the subject matter, as opposed to covering too many items in the same meeting.

                                              1. 3

                                                Thanks.

                                            1. 1

                                              Weird to go through all that without mentioning clojure.

                                              1. 1

                                                Maybe they don’t have clojure experience. Why would you have liked to see it added?

                                                1. 2

                                                  Its design philosophy is pretty specific about the limitations of OO for handling data and managing state transitions.

                                                  https://www.youtube.com/watch?v=-I-VpPMzG7c

                                                  1. 2

                                                    Clojure’s covered in a follow up article to a follow up article: https://www.tedinski.com/2018/03/06/more-on-the-expression-problem.html

                                                    1. 1

                                                      Thanks.

                                                1. 4

                                                  I’ve definitely faced this in the context of property-based testing. The resistance dissipated when we hit a bug which would have clearly been hit by a natural property-based test, FWIW.

                                                  1. 11

                                                    Why are we vendor locked into GNU? Why are we still pretending that’s good or not as evil as the vendor lock-in measures taken by Google, MS, or Apple?

                                                    Because FSF’s explicit values are better aligned with my personal interests and their software implementations have so far proved trustworthy and in line with those values?

                                                    1. 3

                                                      You might consider putting some basic benchmark comparisons in the README.

                                                      1. 1

                                                        Thanks for the suggestion! We added some :)

                                                        1. 1

                                                          Sweet!

                                                      1. 35

                                                        return err is almost always the wrong thing to do. Instead of:

                                                        if err := foo(); err != nil {
                                                        	return err
                                                        }
                                                        

                                                        Write:

                                                        if err := foo(); err != nil {
                                                        	return fmt.Errorf("fooing: %w", err)
                                                        }
                                                        

                                                        Yes, this is even more verbose, but doing this is what makes error messages actually useful. Deciding what to put in the error message requires meaningful thought and cannot be adequately automated. Furthermore, stack traces are not adequate context for user-facing, non-programming errors. They are verbose, leak implementation details, are disrupted by any form of indirection or concurrency, etc.

                                                        Even with proper context, lots of error paths like this is potentially a code smell. It means you probably have broader error strategy problems. I’d try to give some advice on how to improve the code the author provided, but it is too abstract in order to provide any useful insights.

                                                        1. 18

                                                          I disagree on a higher level. What we really want is a stacktrace so we know where the error originated, not manually dispensed breadcrumbs…

                                                          1. 32

                                                            maybe you do, but I prefer an error chain that was designed. A Go program rarely has just one stack, because every goroutine is its own stack. Having the trace of just that one stack isn’t really a statement of the program as a whole since there’s many stacks, not one. Additionally, stack traces omit the parameters to the functions at each frame, which means that understanding the error means starting with your stack trace, and then bouncing all over your code and reading the code and running it in your head in order to understand your stack trace. This is even more annoying if you’re looking at an error several days later in a heterogeneous environment where you may need the additional complication of having to figure out which version of the code was running when that trace originated. Or you could just have an error like “failed to create a room: unable to reserve room in database ‘database-name’: request timed out” or something similar. Additionally, hand-crafted error chains have the effect that they are often much easier to understand for people who operate but don’t author something; they may have never seen the code before, so understanding what a stack trace means exactly may be difficult for them, especially if they’re not familiar with the language.

                                                            1. 6

                                                              I dunno. Erlang and related languages give you back a stack trace (with parameters) in concurrently running processes no problem

                                                              1. 5

                                                                It’s been ages since I wrote Erlang, but I remember that back then I rarely wanted a stack trace. My stack were typically 1-2 levels deep: each process had a single function that dispatched messages and did a small amount of work in each one. The thing that I wanted was the state of the process that had sent the unexpected message. I ended up with some debugging modes that attached the PID of the sending process and some other information so that I could reconstruct the state at the point where the problem occurred. This is almost the same situation as Go, where you don’t want the stack trace of the goroutine, you want to capture a stack trace of the program at the point where a goroutine was created and inspect that at the point where the goroutine failed.

                                                                This isn’t specific to concurrent programs, though it is more common there, it’s similar for anything written in a dataflow / pipeline style. For example, when I’m debugging something in clang’s IR generation I often wish I could go back and see what had caused that particular AST node to be constructed during parsing or semantic analysis. I can’t because all of the state associated with that stack is long gone.

                                                            2. 10

                                                              FWIW, I wrote a helper that adds tracing information.

                                                              I sort of have two minds about this. On the one hand, yeah, computers are good at tracking stack traces, why are we adding them manually and sporadically? OTOH, it’s nice that you can decide if you want the traces or not and it gives you the ability to do higher level things like using errors as response codes and whatnot.

                                                              The thing that I have read about in Zig that I wish Go had is an error trace which is different from the stack trace, which shows how the error was created, not the how the error propagates back to the execution error boundary which is not very interesting in most scenarios.

                                                              1. 7

                                                                The nice thing about those error traces is that they end where the stack trace begins, so it’s seamless to the point that you don’t even need to know that they are a thing, you just get exactly the information that otherwise you would be manually looking for.

                                                              2. 8

                                                                In a multiprocess system that’s exchanging messages: which stack?

                                                                1. 2

                                                                  see: erlang

                                                                2. 5

                                                                  You don’t want stack traces; you want to know what went wrong.

                                                                  A stack trace can suggest what may have gone wrong, but an error message that declares exactly what went wrong is far more valuable, no?

                                                                  1. 8

                                                                    An error message is easy, we already have that: “i/o timeout”. A stack trace tells me the exact code path that lead to that error. Building up a string of breadcrumbs that led to that timeout is just a poorly implemented, ad-hoc stack trace.

                                                                    1. 5

                                                                      Indeed and I wouldn’t argue with that. I love a good stack trace, but I find they’re often relied upon in lieu of useful error messages and I think that’s a problem.

                                                                      1. 2

                                                                        Building up a string of breadcrumbs that led to that timeout is just a poorly implemented, ad-hoc stack trace.

                                                                        That’s a bit of an over-generalization. A stack trace is inherently a story about the construction of the program that originated the error, while an error chain is a story about the events that led to an error. A stack trace can’t tell you what went wrong if you don’t have access to the program’s source code in the way that a hand crafted error chain can. A stack trace is more about where an error occurred, while an error chain is more about why an error occurred. I think they’re much more distinct than you are suggesting.

                                                                        and of course, if people are just bubbling up errors without wrapping them, yeah you’re going to have a bad time, but I think attacking that case is like suggesting that every language that has exceptions encourages Pokémon exception handling. That’s a bad exception-handling pattern, but I don’t think that the possibility of this pattern is a fair indictment of exceptions generally. Meanwhile you’re using examples of bad error handling practices that are not usually employed by Go programmers with more than a few weeks experience to indict the entire paradigm.

                                                                    2. 4

                                                                      Stack traces are expensive to compute and inappropriate to display to most users. Also, errors aren’t exceptions.

                                                                      1. 1

                                                                        That’s why Swift throws errors instead. Exceptions immediately abort the program.

                                                                      2. 3

                                                                        What really is the “origin” of an error? Isn’t that somewhat arbitrary? If the error comes from a system call, isn’t the origin deeper in the kernel somewhere? What if you call in to a remote, 3rd party service. Do you want the client to get the stack trace with references to the service’s private code? If you’re using an interface, presumably the purpose is to abstract over the specific implementation. Maybe the stack trace should be truncated at the boundary like a kernel call or API call?

                                                                        Stack traces are inherently an encapsulation violation. They can be useful for debugging your internals, but they are an anti-feature for your users debugging their own system. If your user sees a stack trace, that means your program is bugged, not theirs.

                                                                        1. 5

                                                                          I get a line of logging output: error: i/o timeout. What do I do with that? With Ruby, I get a stack trace which tells me exactly where the timeout came from, giving me a huge lead on debugging the issue.

                                                                          1. 6

                                                                            I get a line of logging output: error: i/o timeout. What do I do with that?

                                                                            Well, that’s a problem you fix by annotating your errors properly. You don’t need stack traces.

                                                                            1. 3

                                                                              When your Ruby service returns an HTTP 500, do you send me the stack trace in the response body? What do I do with that?

                                                                              Go will produce stack traces on panics as well, but that’s precisely the point here: these are two different things. Panics capture stack traces as a “better than nothing” breadcrumb trail for when the programmer has failed to account for a possibility. They are for producers of code, not consumers of it.

                                                                            2. 2

                                                                              There’s definitely competing needs between different audiences and environments here.

                                                                              A non-technical end user doesn’t want to see anything past “something went wrong on our end, but we’re aware of it”. Well, they don’t even want to see that.

                                                                              A developer wants to see the entire stack trace, or at least have it available. They probably only care about frames in their own code at first, and maybe will want to delve into library code if the error truly doesn’t seem to come from their code or is hard to understand in the first place.

                                                                              A technical end user might want to see something in-between: they don’t want to see “something was wrong”. They might not even want to see solely the outer error of “something went wrong while persisting data” if the root cause was “I couldn’t reach this host”, because the latter is something they could actually debug within their environment.

                                                                          2. 9

                                                                            This is one reason I haven’t gone back to Go since university - There’s no right way to do anything. I think I’ve seen a thousand different right ways to return errors.

                                                                            1. 10

                                                                              Lots of pundits say lots of stuff. One good way to learn good patterns (I won’t call them “right”), is to look at real code by experienced Go developers. For instance, if you look at https://github.com/tailscale/tailscale you’ll find pervasive use of fmt.Errorf. One thing you might not see – at least not without careful study – is how to handle code with lots of error paths. That is by it’s very nature harder to see because you have to read and understand what the code is trying to do and what has to happen when something goes wrong in that specific situation.

                                                                              1. 6

                                                                                there is a right way to do most things; but it takes some context and understanding for why.

                                                                                the mistake is thinking go is approachable for beginners; it’s not.

                                                                                go is an ergonomic joy for people that spend a lot of time investing in it, or bring a ton of context from other languages.

                                                                                for beginners with little context, it is definitely a mess.

                                                                                1. 9

                                                                                  I thought Go was for beginners, because Rob Pike doesn’t trust programmers to be good.

                                                                                  1. 19

                                                                                    I’d assume that Rob Pike, an industry veteran, probably has excellent insight into precisely how good the average programmer at Google is, and what kind of language will enable them to be productive at the stuff Google makes. If this makes programming languages connaisseurs sad, that’s not his problem.

                                                                                    1. 9

                                                                                      Here’s the actual quote:

                                                                                      The key point here is our programmers are Googlers, they’re not researchers. They’re typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They’re not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.

                                                                                      So I have to wonder who is capable of understanding a “brilliant language” …

                                                                                      1. 8

                                                                                        So I have to wonder who is capable of understanding a “brilliant language” …

                                                                                        Many people. They don’t work at Google at an entry-level capacity, that’s all.

                                                                                        There’s a subtle fallacy at work here - Google makes a lot of money, so Google can afford to employ smart people (like Rob Pike!) It does not follow that everyone who works at Google is, on average, smarter than anyone else.

                                                                                        (edited to include quote)

                                                                                        1. 8

                                                                                          Let’s say concretely we are talking about OCaml. Surely entry-level Googlers are capable of understanding OCaml. Jane Street teaches it to all new hires (devs or not) in a two-week bootcamp. I’ve heard stories of people quickly becoming productive in Elm too.

                                                                                          The real meaning of that quote is not ‘entry-level Googlers are not capable of it’, it’s ‘We don’t trust them with it’ and ‘We’re not willing to invest in training them in it’. They want people to start banging out code almost instantly, not take some time to ramp up.

                                                                                          1. 8

                                                                                            Let’s say concretely we are talking about OCaml. Surely entry-level Googlers are capable of understanding OCaml. Jane Street teaches it to all new hires (devs or not) in a two-week bootcamp.

                                                                                            I suspect that Jane Street’s hiring selects for people who are capable of understanding OCaml; I guarantee that the inverse happens and applicants interested in OCaml self select for careers at Jane Street, just like Erlang-ers used to flock towards Ericsson.

                                                                                            Google has two orders of magnitude more employees than Jane Street. It needs a much bigger funnel and is likely far less selective in hiring. Go is “the law of large numbers” manifest as a programming language. That’s not necessarily bad, just something that is important for a massive software company and far less important for small boutiques.

                                                                                            1. 3

                                                                                              And I remember when Google would require at minimum a Masters Degree before hiring.

                                                                                              1. 1

                                                                                                I had a master’s degree in engineering (though not in CS) and I couldn’t code my way out of a paper bag when I graduated. Thankfully no-one cared in Dot Com Bubble 1.0!

                                                                                              2. 2

                                                                                                applicants interested in OCaml self select for careers at Jane Street,

                                                                                                As I said, they teach it to all hires, including non-devs.

                                                                                                Google has two orders of magnitude more employees than Jane Street. It needs a much bigger funnel and is likely far less selective in hiring

                                                                                                Surely though, they are not so loose that they hire Tom Dick and Harry off the street. Why don’t we actually look at an actual listing and check? E.g. https://careers.google.com/jobs/results/115367821606560454-software-developer-intern-bachelors-summer-2022/

                                                                                                Job title: Software Developer Intern, Bachelors, Summer 2022 (not exactly senior level)

                                                                                                Minimum qualifications:

                                                                                                Pursuing a Bachelor’s degree program or post secondary or training experience with a focus on subjects in software development or other technical related field. Experience in Software Development and coding in a general purpose programming language. Experience coding in two of C, C++, Java, JavaScript, Python or similar.

                                                                                                I’m sorry but there’s no way I’m believing that these candidates would be capable of learning Go but not OCaml (e.g.). It’s not about their capability, it’s about what Google wants to invest in them. Another reply even openly admits this! https://lobste.rs/s/yjvmlh/go_ing_insane_part_one_endless_error#c_s3peh9

                                                                                              3. 3

                                                                                                They want people to start banging out code almost instantly, not take some time to ramp up.

                                                                                                Yes, and? The commodification of software developers is a well-known trend (and goal) of most companies. When your assets are basically servers, intangible assets like software and patents, and the people required to keep the stuff running, you naturally try to lower the costs of hiring and paying salary, just like you try to have faster servers and more efficient code.

                                                                                                People are mad at Rob Pike, but he just made a language for Google. It’s not his fault the rest of the industry thought “OMG this is the bee’s knees, let’s GO!” and adopted it widely.

                                                                                                1. 1

                                                                                                  Yes, I agree that the commodification of software developers is prevalent today. And we can all see the result, the profession is in dire straits–hard to hire because of bonkers interview practices, hard to keep people because management refuses to compensate them properly, and cranking out bugs like no tomorrow.

                                                                                                2. 3

                                                                                                  on the contrary, google provides a ton of ramp up time for new hires because getting to grips with all the internal infrastructure takes a while (the language is the least part of it). indeed, when I joined a standard part of the orientation lecture was that whatever our experience level was, we should not expect to be productive any time soon.

                                                                                                  what go (which I do not use very much) might be optimising for is a certain straightforwardness and uniformity in the code base, so that engineers can move between projects without having to learn essentially a new DSL every time they do.

                                                                                                  1. 1

                                                                                                    You may have a misconception that good programming languages force people to ‘essentially learn a new DSL’ in every project. In any case, as you yourself said, the language is the least part of the ramp-up of a new project, so even if that bit were true, it’s still optimizing for the wrong thing.

                                                                                                    1. 1

                                                                                                      no, you misunderstood what i was getting at. i was saying that go was optimisng for straightforwardness and uniformity so that there would be less chance of complex projects evolving their own way of doing things, not that better languages would force people to invent their own DSLs per project.

                                                                                                      also the ramp-up time i was referring to was for new hires; a lot of google’s internal libraries and services are pretty consistently used across projects (and even languages via bindings and RPC) so changing teams requires a lot less ramp up than joining google in the first place.

                                                                                                      1. 1

                                                                                                        i was saying that go was optimisng for straightforwardness and uniformity so that there would be less chance of complex projects evolving their own way of doing things,

                                                                                                        Again, the chances of that happening are not really as great as the Go people seem to be afraid it is, provided we are talking about a reasonable, good language. So let’s say we leave out Haskell or Clojure. The fear of language-enabled complexity seems pretty overblown to me. Especially considering the effort put into the response, creating an entirely new language and surrounding ecosystem.

                                                                                          2. 9

                                                                                            No, Rob observed, correctly, that in an organization of 10,000 programmers, the skill level trends towards the mean. And so if you’re designing a language for this environment, you have to keep that in mind.

                                                                                            1. 4

                                                                                              it’s not just that. It’s a language that has to reconcile the reality that skill level trends toward the mean, with the fact that the way that google interviews incurs a selection/survival bias towards very junior programmers who think they are the shit, and thus are very dangerous with the wrong type of power.

                                                                                              1. 4

                                                                                                As I get older and become, presumably, a better programmer, it really does occur to me just how bad I was for how long. I think because I learned how to program as a second grader, I didn’t get how much of a factor “it’s neat he can do it all” was in my self-assessment. I was pretty bad, but since I was being compared to the other kids who did zero programming, it didn’t matter that objectively I was quite awful, and I thought I was hot shit.

                                                                                              2. 4

                                                                                                Right! But the cargo-cult mentality of the industry meant that a language designed to facilitate the commodification of software development for a huge, singular organization escaped and was inflicted on the rest of us.

                                                                                                1. 4

                                                                                                  But let’s be real for a moment:

                                                                                                  a language designed to facilitate the commodification of software development

                                                                                                  This is what matters.

                                                                                                  It doesn’t matter if you work for a company of 12 or 120,000: if you are paid to program – that is, you are not a founder – the people who sign your paychecks are absolutely doing everything within their power to make you and your coworkers just cogs in the machine.

                                                                                                  So I don’t think this is a case of “the little fish copying what big bad Google does” as much as it is an essential quality of being a software developer.

                                                                                                  1. 1

                                                                                                    Thank you, yes. But also, the cargo cult mentality is real.

                                                                                              3. 3

                                                                                                Go is for compilers, because Google builds a billion lines a day.

                                                                                          3. 2

                                                                                            return errors.Wrapf(err, "fooing %s", bar) is a bit nicer.

                                                                                            1. 13

                                                                                              That uses the non-standard errors package and has been obsolete since 1.13: https://stackoverflow.com/questions/61933650/whats-the-difference-between-errors-wrapf-errors-errorf-and-fmt-errorf

                                                                                              1. 1

                                                                                                Thanks, that’s good to know.

                                                                                              2. 8

                                                                                                return fmt.Errorf("fooing %s %w", bar, err) is idiomatic.

                                                                                                1. 9

                                                                                                  Very small tweak: normally you’d include a colon between the current message and the %w, to separate error messages in the chain, like so:

                                                                                                  return fmt.Errorf("fooing %s: %w", bar, err)
                                                                                                  
                                                                                              3. 1

                                                                                                It makes error messages useful but if it returns a modified err then I can’t catch it further up with if err == someErr, correct?

                                                                                                1. 2

                                                                                                  You can use errors.Is to check wrapped errors - https://pkg.go.dev/errors#Is

                                                                                                  Is unwraps its first argument sequentially looking for an error that matches the second. It reports whether it finds a match. It should be used in preference to simple equality checks

                                                                                                  1. 2

                                                                                                    Thanks! I actually didn’t know about that.

                                                                                                  2. 2

                                                                                                    Yes, but you can use errors.Is and errors.As to solve that problem. These use errors.Unwrap under the hood. This error chaining mechanism was introduced in Go 1.13 after being incubated in the “errors” package for a long while before that. See https://go.dev/blog/go1.13-errors for details.

                                                                                                1. 18

                                                                                                  PyLint - W0102, dangerous-default-value

                                                                                                  Please use an IDE or lint your code to prevent this.

                                                                                                  1. 10

                                                                                                    That doesn’t change the fact that’s is recurring WTF. Either you’ve worked with python for a while and have it internalized (or an IDE), but blaming an actual shortcoming of the language on the developer isn’t helpful.

                                                                                                    1. 7

                                                                                                      To me most lint tools are overly aggressive, and good warnings like this one get drowned out by bad ones.

                                                                                                      FWIW the google python style guide disallows mutable default arguments: https://google.github.io/styleguide/pyguide.html#212-default-argument-values

                                                                                                      But I think it would better if there was some non-lint / non-IDE / non-google place where this knowledge is stored and linkable.

                                                                                                      Googling reveals a book: https://docs.python-guide.org/writing/gotchas/

                                                                                                      People still rediscover it not just in 2021, but 2018 too: https://florimond.dev/en/posts/2018/08/python-mutable-defaults-are-the-source-of-all-evil/ (I’ve known about this issue approximately since I started using Python, which was ~2003 or so)

                                                                                                      1. 7

                                                                                                        The first time I encountered this behavior was through a linter warning, which can be seen in my original comment. I did the research and I understood what was happening. Then I changed my code accordingly and never made that mistake again.

                                                                                                        The only thing I „criticize“ is that the developer learned about this well known behavior of Python, because of a production bug. I wanted to point out that there is another way.

                                                                                                        1. 3

                                                                                                          How should the default-value parameter be assigned when the function is called? I see four options:

                                                                                                          • it’s assigned the object obtained by evaluating the default-value expression when the function was initially defined (the current way,
                                                                                                          • it’s assigned the object obtained by freshly evaluating the default-value expression, on every call,
                                                                                                          • it’s assigned a deep copy of the object obtained when the function was initially defined,
                                                                                                          • only known-immutable python values are allowed as default values.

                                                                                                          They all have different drawbacks.

                                                                                                          1. 4

                                                                                                            Naïvely, I would expect a default value to behave identically to having the expression written in at the call site.

                                                                                                            With:

                                                                                                            def f(a=expr)
                                                                                                            

                                                                                                            I would expect

                                                                                                            f()
                                                                                                            

                                                                                                            To behave identically to

                                                                                                            f(expr)
                                                                                                            

                                                                                                            Scoping issues aside (I would expect syms in expr to be bound at the definition site.)

                                                                                                            So, 2. I think this is what most people expect, and why this decision is so surprising.

                                                                                                            1. 2

                                                                                                              Are there languages that do (3) and (4)? And any language other than Python that does (1)?

                                                                                                              1. 2

                                                                                                                Python is the only language I can think of right now where this is a caveat. Maybe C. But even there you deliberately hand in a reference if you want that to be mutable.

                                                                                                            2. 2

                                                                                                              PyLint is overly aggressive, and doesn’t catch all instances. For e.g. see.

                                                                                                              class MyC:
                                                                                                                  def __init__(self):
                                                                                                                      self.val = []
                                                                                                              
                                                                                                                  def process(self, e):
                                                                                                                      return self.val.append(e)
                                                                                                              
                                                                                                              def processed(element, o = MyC()):
                                                                                                                  o.process(element)
                                                                                                                  return o.val
                                                                                                              
                                                                                                              print(processed(42))
                                                                                                              print(processed(51))
                                                                                                              
                                                                                                            1. 19

                                                                                                              Yesterday on Twitter, someone said:

                                                                                                              The success of docker was always based in the fact that the most popular web technologies of that day and age sucked so bad at dependency management that “just download a tarball of a stripped down os image” seemed like a reasonable solution.

                                                                                                              This is true, but it’s sort of more true that as TFA says,

                                                                                                              The reason why we can often get away with using languages like Python or JavaScript to drive resource-intensive computations, is because under the hood somebody took years to perfect a C implementation of a key procedure and shared it with the world under a permissive license.

                                                                                                              And C/C++ have an ugly Makefile where an actual dependency manager should be, which makes Docker feel like a solution and not a bandaid.

                                                                                                              I think TFA is correct that moving forward, it’s not going to be possible to boil the ocean and throw out all existing unsafe software, but we can at least simplify things by using simpler and more direct dependency management in C/C++.

                                                                                                              1. 29

                                                                                                                And C/C++ have an ugly Makefile where an actual dependency manager should be, which makes Docker feel like a solution and not a bandaid.

                                                                                                                I completely disagree. Makefile/CMake/Meson/whatever are convoluted, difficult to learn, etc but they are fundamentally different from what docker gives you. They plug in to the existing ecosystem, they compose nicely with downstream packages, they’re amenable to distro packaging, they offer well-defined, stable, and standardized interfaces for consumption. They are part of an ecosystem and are great team players.

                                                                                                                A docker image says “f this, here’s everything and the kitchen sink in the exact version and configuration that worked for me, don’t change anything, good luck maintaining dependencies when we don’t bother fast enough. Screw your system preferences for the behavior of dependency x, y, or z (which they rightly have no need to know about or concern themselves with - but the user very much has the right to), this is what works for me and you’re on your own if you want to diverge in the slightest.”

                                                                                                                I write and maintain open source software (including things you might use). It’s hard to use system dependencies and abstract away our dependency on them behind well-defined boundaries. But it’s important because I respect that it’s not my machine the code will run under, it’s the users’.

                                                                                                                Docker - like Electron but let’s not get into that here - isn’t about what’s better in principal or even in practice - it’s solely about what’s easier. At some point, it was universally accepted that things should be easy for the user even if that makes the developer’s job a living hell. It’s what we do. Then sometime in the past ten years, it all became about what’s easiest and most pain-free for developers. Software development (don’t you dare say software engineering) became lazy.

                                                                                                                We can argue about the motives but I don’t blame the developers, I think they are following a path that was paved by corporations that realized users don’t know any better and developers were their only advocates. It was cheaper to invent these alternatives that let you push software out the door faster with greener and greener developers than it was investing in the existing ecosystem and holding the industry to a higher standard. Users have no one advocating for them and they don’t even realize it.

                                                                                                                1. 4

                                                                                                                  Software development (don’t you dare say software engineering) became lazy.

                                                                                                                  This sentiment is as old as Unix: https://en.wikipedia.org/wiki/Worse_is_better

                                                                                                                  1. 10

                                                                                                                    Docker is neither simple nor correct nor consistent nor complete in either the New Jersey or MIT sense.

                                                                                                                    I think that if the takeaway from reading Worse Is Better is that lazy software development is acceptable, then that is the incorrect takeaway. The essay is about managing complexity in order to get a rough fit sooner than a perfect fit perhaps too late to matter. Read the essay.

                                                                                                                    1. 8

                                                                                                                      I read the essay. The essay itself codifies a position that it opposes, based on the author’s observations about the state of the New Jersey/MIT split. It’s one person’s idea of what “Worse Is Better” means, with the essay created to criticize the self-defined argument, not the definitive idea. But we can split semantics about the essay some other time.

                                                                                                                      When someone says that “software development has become lazy” and adds a bunch of supporting information around that for a specific situation, what I read is “I am frustrated with the human condition”. Software developers have been lazy, are lazy, and will continue to be lazy. Much like a long-standing bug becomes an expectation of functionality. Fighting human nature results in disappointment. To ignore the human factors around your software is to be willingly ignorant. Docker isn’t popular in a vacuum and there’s no grand capitalist conspiracy to convince you that Docker is the way to make software. Docker solves real problems with software distribution. It may be a hamfisted solution, but railing against the human condition and blaming corporate interests is not the way to understand the problems that Docker solves, it’s just an ill-defined appeal to a boogeyman.

                                                                                                                      1. 8

                                                                                                                        Docker isn’t popular in a vacuum and there’s no grand capitalist conspiracy to convince you that Docker is the way to make software.

                                                                                                                        You, uh, you sure about that? Like, really sure?

                                                                                                                        1. 4

                                                                                                                          Our community’s discourse is so dominated by cynicism, we need to find a way to de-escalate that, not add fuel to the fire. So the benefit of the doubt is more important now than ever. That means that whenever there’s a benign explanation for something, we should accept it.

                                                                                                                          1. 11

                                                                                                                            Our community is split into two groups:

                                                                                                                            • Those exploiting software and human labor for financial gain at the expense of the Earth and its inhabitants.
                                                                                                                            • Those engaging in craftsmanship and improving the state of technology for end users, by creating software you can love.

                                                                                                                            Think carefully before choosing to defend the former group.

                                                                                                                            1. 3

                                                                                                                              I don’t think it’s that simple. I definitely feel the pull of the second group and its ideals, but sometimes the practices of the first group can be put to good use to, as you say, improve the state of technology for end-users. Consider: if there’s an unsolved problem affecting end-users, e.g. one caused by the sudden changes that happened in response to the pandemic, and the most practical way to solve that problem is to develop and deploy a web application, then if I spend time crafting an elegant, efficient solution that I would be proud to show to people here, then I’ve likely done the actual users a disservice, since I could get the solution out to them sooner by taking the shortcuts of the first group. That’s why I defend those practices.

                                                                                                                              1. 3

                                                                                                                                This fast-to-market argument only has a home because the world is run so much by the former group.

                                                                                                                                Consider the case of email vs instant messaging. Email was standardized and made ubiquitous at a time before market forces had a chance to spoil it with vendor lock-in. Meanwhile, text messaging, and messaging in general is incredibly user-hostile. But it didn’t have to be this way. If messaging were orchestrated by the second group, with the end-user experience in mind as the primary concern, we would have widely popular federated messaging with robust protocols. Further, many other technologies would exist this way, with software of the world, in general, being more cooperative and reusable. In such case, total time to develop and deploy a web application would be decreased from where it is today, and furthermore it would have more capabilities to aid the end-user.

                                                                                                                                All this “glue” code that needs to be written is not fundamentally necessary in a technical sense; it’s a direct result of the churn of venture capital.

                                                                                                                                1. 8

                                                                                                                                  The friendliest ways of building websites, with the least amount of code, right now are things like Wix, Wordpress, cPanel, and so forth. These are all very much commercial ventures, squarely from the first camp.

                                                                                                                                  Your example of messaging is also questionable, because the successful messaging stuff was taken over by the first camp while the second camp was screwing around with XMPP and IRCv3 and all the rest.

                                                                                                                                  The killer advantage the first camp has over the craftsmen in the second camp is that they’re not worried about “quality” or “products people love”…they are worried about the more straightforward (and sustainable) goal of “fastest thing we can put out with the highest profit margin the most people want”.

                                                                                                                                  I wish–oh how much do I wish!–that the second group was favored, but they aren’t as competitive as they need to be and they aren’t as munificent or excellent as they think they are.

                                                                                                                          2. 2
                                                                                                                            1. 5

                                                                                                                              In my eyes that’s proof that Docker failed to build a moat more than anything else, and in fact it has greater chances to be evidence in support of friendlysock’s theory than the opposite: companies don’t go gently into the night, VC funded ones especially, so you can be sure that those billions fueled pantagruelian marketing budgets in a desperate scramble to become the leading brand for deploying distributed systems.

                                                                                                                              Unfortunately for them the open source game didn’t play out in their favor.

                                                                                                                              1. 4

                                                                                                                                Unfortunately for them the open source game didn’t play out in their favor.

                                                                                                                                I don’t think there’s any actual disagreement here; just differences about how snarky we want to be when talking about the underlying reality. Yes, Docker is a company with VC cash that had an incentive to promote its core offering. But no, Docker can’t actually make the market accept its solutions, so e.g. Docker Swarm was killed by Kubernetes.

                                                                                                                                Okay, maybe you can say, but Kubernetes was just promoted by Google, which is an even bigger capitalist nightmare, which okay, fine is true, but at the end of the day, propaganda/capitalism/whatever you want to call it can only go so far. You can get to a certain point by just being big and hyped, but then if you aren’t actually any good, you’ll eventually end up crashing against reality, like Docker Swarm or Windows Mobile or XML or the Soviet Union or whoever else tries to substitute a marketing budget for reality.

                                                                                                                                1. 2

                                                                                                                                  but at the end of the day, propaganda/capitalism/whatever you want to call it can only go so far.

                                                                                                                                  I do agree that containers are a solution to a problem. An imperfect solution to a problem we should not have in the first place but, regardless, it’s true that they can be a useful tool in the modern development world. That said, I fear that it’s the truth that can only go so far, and that skilled use of a communication medium can produce much bigger impact in the short to medium term.

                                                                                                                              2. 5

                                                                                                                                That article suggests they raised more than a quarter of a billion dollars, and then talks about how they lost to the even more heavily propagandized (by Google) Kubernetes meme when they couldn’t figure out how to monetize all the victims. Neither of those seems a clear counter to there being a vast capitalist conspiracy.

                                                                                                                                Like, devs get memed into dumb shit all the time by sales engineers.

                                                                                                                                If they didn’t there wouldn’t be devrel/devangelist positions.

                                                                                                                                Edit:

                                                                                                                                (and just to be clear…I’m not denying that Docker has some use cases. I myself like it for wrapping up the seeping viscera of Python projects. I’m just disagreeing that it was from some spontaneous outpouring of developer affection that it got where it is today. See also, Java and React.)

                                                                                                                                1. 4

                                                                                                                                  Like, devs get memed into dumb shit all the time by sales engineers.

                                                                                                                                  If they didn’t there wouldn’t be devrel/devangelist positions.

                                                                                                                                  Yeah, true enough based on my experience as a former dev advocate.

                                                                                                                                  1. 2

                                                                                                                                    Neither of those seems a clear counter to there being a vast capitalist conspiracy.

                                                                                                                                    There can’t be two vast capitalist conspiracies. If there are two, it’s not a vast conspiracy. Calling it a “capitalist conspiracy” either means that there is only one or that you like using snarky names for perfectly ordinary things.

                                                                                                                                    1. 2

                                                                                                                                      I would call a conspiracy of half the capitalists pretty vast, FWIW.

                                                                                                                          3. 2

                                                                                                                            Yes. But that was only the conclusion of my argument; I think it’s fair to say that the actual points I was making regarding dependencies are pretty objective/factual and specific to the docker situation.

                                                                                                                          4. 2

                                                                                                                            While I agree and am loathe to defend docker in any way, if instead of a docker image we were talking about a Dockerfile then that is comparable to a build system that declares dependencies also.

                                                                                                                            1. 2

                                                                                                                              I completely disagree. Makefile/CMake/Meson/whatever are convoluted, difficult to learn, etc but they are fundamentally different from what docker gives you.

                                                                                                                              Agreed.

                                                                                                                              They plug in to the existing ecosystem, they compose nicely with downstream packages, they’re amenable to distro packaging, they offer well-defined, stable, and standardized interfaces for consumption.

                                                                                                                              I disagree. The interfaces aren’t stable or standardized at all. Distros put a huge amount of effort into trying to put fingers into the leaking dam, but the core problem is that Make is a Turing complete language with extreme late binding of symbols. The late binding makes it easy to write a Makefile that works on one machine but not another. Adding more layers of autoconf and whatnot does not really solve the core problem. The thing C/C++ are trying to do is… not actually that hard at all? It’s just linking and building files and trying to cache stuff along the way. Newer languages just include this as part of their core. But because every C/C++ project has its own Turing complete bespoke solution, they are incompatible and can’t be moved to new/different platforms without a ton of human effort. It’s a huge ongoing PITA for everyone.

                                                                                                                              The thing that would actually be good is to standardize a descriptive non-Turing complete, configuration language that can just describe dependencies between files and version constraints. If you had that (big if!), then it wouldn’t be a big deal to move to new platforms, deal with platforms changing, etc. Instead we get duplication where every distro does their own work to fill in the gaps by being the package manager that C/C++ need.

                                                                                                                              1. 2

                                                                                                                                Sorry if I wasn’t clear: the abstracted interfaces I’m referring to aren’t provided by the Makefile or whatever. I meant standardized things like pkgconf definition files in their place, man files in their place, using the packages made available by the system package manager rather than bringing in your own deps, etc.

                                                                                                                          1. 3

                                                                                                                            I’m still looking for an argument/example for why all this abstraction carries its own weight, in a software-development context.

                                                                                                                            1. 3

                                                                                                                              Like most software engineering patterns, it exists to facilitate code reuse in a principled way. An abstraction’s utility can be measured along two axes:

                                                                                                                              1. Working only within the abstraction, what things can I say?
                                                                                                                              2. How many things embody this abstraction?

                                                                                                                              Monad is a useful abstraction because it applies to a surprisingly large range of types, while still allowing a broad vocabulary of functions that work over any Monad. It is also hard to understand for these reasons, which is why the most effective teaching method seems to involve finding some vaguely familiar concept (e.g., promises) that happens to be a Monad, using that to give the student a toe-hold, and then asking the student to write Monad instances for a zillion types, letting the instinctive, pattern-matching part of the student’s brain notice the underlying similarities.

                                                                                                                              The Monad abstraction in Haskell enables (among other things) a large family of functions (when, unless, forever, etc) that would be control structures in other languages. This is handy because a) we don’t have to petition some language steward to add new ones (contrast: Python’s with statement), and b) we can use our normal programming tools to work with them.

                                                                                                                              I can use the Monad abstraction when checking for missing values, to halt my program on the first error, to make an ergonomic database Transaction data type that prohibits non-database I/O, to write deserialisers, to set up eDSLs with great ergonomics, to treat lists as nondeterministic computations, to provide a good interface to software transactional memory, to build up an additional “summary” result in a computation, to pass around additional arguments, and other things I’ve surely forgotten. You could well say (as you said to /u/shapr in a sibling comment) that none of these need the theory of Monads. And they don’t. What the theory of Monads gives you is a useful toolbox to see how they’re all similar, and it’s one that’s usefully expressed only in a few programming languages. A tool like mapM works exactly as well in each of those apparently-diverse cases, and only needed writing once.

                                                                                                                              1. 2

                                                                                                                                mapM’s functionality is trivial, though, and I expect anything you can do with an arbitrary monad would be equally trivial. In my experience, code reuse is useful when the code carries significant domain knowledge or provides a single point of reference for application details which are subject to change. Abstracting away repeated patterns for the sake of it, or simply for the sake of concision, is often not worth the cognitive load it adds.

                                                                                                                              2. 3

                                                                                                                                I’m not a haskeller, but I’ve spent a little time with the language. One benefit is that you can write your functions for the success case and the monadic machinery will short circuit if there is a failure. This means that you don’t need to litter you code with checks for nulls or nothings.

                                                                                                                                1. 2

                                                                                                                                  One thing I like is that I can use the same code with a fake in memory database without changing the code itself, just feeding a different value into the monad.

                                                                                                                                  1. 7

                                                                                                                                    You don’t need the theory of monads to enable that.

                                                                                                                                    1. 1

                                                                                                                                      Using a monad to separate concerns and do easy dependency injection is one of many cases where the monad abstraction carries its weight.

                                                                                                                                      I agree, you don’t need the theory to do those things with a monad, you just use it.

                                                                                                                                      1. 3

                                                                                                                                        I can do those things quite easily in languages which don’t even have the concept of “monad.” The abstractions I use might be representable as monads, but I see no benefit to calling them out as such.

                                                                                                                                        1. 1

                                                                                                                                          Consider Elm. Its designer has banned the word monad from all the documentation. Nevertheless, it has a very consistent and intuitive way of handling all monadic types. How can that be? Because the designer knew they were monads.

                                                                                                                                          Most users won’t ever have to declare a monad. They don’t need monad tutorials or even know the word, but the world would be a better place if all language designers did.

                                                                                                                                    2. 3

                                                                                                                                      that’s just an interface, isn’t it?

                                                                                                                                      1. 1

                                                                                                                                        If you mean an interface as in an API being a pattern of functions and data, then yes. A good interface can make a problem easier to think about and solve.

                                                                                                                                        1. 2

                                                                                                                                          Or an interface as in literally like a Java interface, i.e. a simple everyday programming concept that doesn’t need any theoretical mathematics to understand.

                                                                                                                                          1. 3

                                                                                                                                            That’s what I was thinking. Jdbc is the ultimate example here. You program only against interfaces and you can swap databases in tests trivially easy. All without reading complex Monad tutorials.

                                                                                                                                            1. 1

                                                                                                                                              Interface theory is very complex and mathematical. You never see blog sized tutorials about all the theory because it doesn’t fit in a blog. Monads are stupid simple in comparison, which is why there are so many blogs about it. Get over the abstract nonsense words, implement it yourself in 10 lines, then write a blog about how you finally understood it. That’s all there is to it.

                                                                                                                                              Designing interface rules for your language is hard to get right even if you know all the theory, cause there are many tradeoffs and you might make the wrong choice for what you’ll want later on. Getting monads wrong is only possible when you refuse to acknowledge you’re dealing with a monad, like JS’s Promises.

                                                                                                                                              1. 2

                                                                                                                                                Interface theory is very complex and mathematical. You never see blog sized tutorials about all the theory because it doesn’t fit in a blog.

                                                                                                                                                I think you never see blogs about it, because - at least Java programmers - learn about them in the very beginning and then use them. They are trivial to understand and use. Java programmers write them every single day and most of them do not have deep type theory backgrounds. I think that is what this thread is about. Pragmatic programmers using something vs. pure functional programmers exchanging complex Monad tutorials.

                                                                                                                                                1. 2

                                                                                                                                                  Exactly, you can use monad-like things without ever learning about monads. You’ll have a better time if the language designer did know monad theory though. Same goes for interfaces.

                                                                                                                                                  I really don’t want to call monads complex though. That’s what leads to this “monad tutorial fallacy”, it’s always the first mythical hard thing new Haskellers run in to, so when it clicks they must write a tutorial. Haskell has other stuff much more complex, that never gets blog explanations either. I’d say GADTs are at the level of interfaces, and when a new Haskeller reaches those, suddenly they’re pragmatics again. (And then after a year you make it your master thesis and never touch Haskell again lmao.)

                                                                                                                                    3. 1

                                                                                                                                      Code reuse

                                                                                                                                    1. 4

                                                                                                                                      This is really cool! :) I’m curious about some of the choices (RSA, scrypt) but I think using ASCII is an interesting twist.

                                                                                                                                      I’ve been quietly working on my own similar tool (a little more ambitious, and also in rust) for creating encrypted archives, if you want to peek in on the progress: https://code.lag.net/robey/bitbottle

                                                                                                                                      1. 4

                                                                                                                                        scrypt was abandoned some time ago it seems from their design document. It was replaced with Argon2. Also they use X25519 by default instead of RSA. RSA-2048+ is used as a fallback when using it with SSH keys instead of Age own keys.

                                                                                                                                        1. 2

                                                                                                                                          I’m curious about some of the choices (RSA…

                                                                                                                                          Looking at the design doc, it seems like this is primarily used for encryption to ssh RSA keys. That seems like useful functionality, because many people already have published ssh RSA keys (same logic I based RSADonations on.)

                                                                                                                                        1. 5

                                                                                                                                          In this case, passing a pointer into a function is still passing by value in the strictest sense, but it’s actually the pointer’s value itself that is being copied, not the thing that the pointer refers to

                                                                                                                                          Is this not how every language works when handling pointers?

                                                                                                                                          1. 6

                                                                                                                                            I think so, but I believe the main point of the article is how there are certain types, like slices, maps, and channels, that feel as if you’re passing them by value, even though they behave like references.

                                                                                                                                            This sometimes trips people up (like me), for example: https://eli.thegreenplace.net/2018/beware-of-copying-mutexes-in-go/

                                                                                                                                            1. 8

                                                                                                                                              I learned recently that go vet will give that warning on copying any struct which implements Lock() and Unlock() methods.

                                                                                                                                              E.g.,

                                                                                                                                              package main
                                                                                                                                              type t struct{}; func (*t) Lock() {};func (*t) Unlock() {}
                                                                                                                                              func main() { a := t{}; _ = a }
                                                                                                                                              

                                                                                                                                              will trigger the vet warning.

                                                                                                                                            2. 2

                                                                                                                                              C++ references are distinct! For example in Python (and I imagine in Go as well) you can’t pass a reference to an integer. You can’t do

                                                                                                                                              x = 3
                                                                                                                                              f(x)
                                                                                                                                              # x now equals 4
                                                                                                                                              

                                                                                                                                              (in CPython you can by doing some stack trace trickery)

                                                                                                                                              This is kind of linked back to a fundamental C++-ism of built-ins being “the same as” other data types. Whereas Python/Java/Go/lots of other stuff have this distinction between builtins and aggregate types.

                                                                                                                                              Rust, being the true successor to C++ in so many ways, carries over references nicely tho…

                                                                                                                                              fn f(x: &mut i32){
                                                                                                                                                  *x += 1;
                                                                                                                                              }
                                                                                                                                              
                                                                                                                                              fn main() {
                                                                                                                                                  let mut x:i32=4;
                                                                                                                                                  println!("x={}", x);
                                                                                                                                                  f(&mut x);
                                                                                                                                                  println!("x={}", x);
                                                                                                                                                  println!("Done");
                                                                                                                                              }
                                                                                                                                              

                                                                                                                                              And beyond “changing the contents of an integer”, ultimately being able to change the variable itself (even replacing it with an entirely different object) is only really an option in systems languages.

                                                                                                                                              1. 1

                                                                                                                                                The only exceptions I can think of are:

                                                                                                                                                • perl - lists are copied
                                                                                                                                                • tcl - lists are strings
                                                                                                                                                • C - structurs are actually copied without explicit pointers
                                                                                                                                                • languages with explicit value types like C#
                                                                                                                                              1. 1

                                                                                                                                                Lost me at “existentialist embrace of the hoplessness of programming complexity”… Sounds like a losing philosophy, to me.

                                                                                                                                                1. 20

                                                                                                                                                  It’d be nice to have some actual background on hashing in here instead of just broad generalizations and links to various hash functions. Examples:

                                                                                                                                                  • There’s no mention of cyclic redundancy checks and why they are not valid as crypto functions (a mistake some programmers have made).
                                                                                                                                                  • There’s no mention of avalanche effects, which is a good way of seeing how “random” a digest scheme is (with some implications for how well the output can be predicted/controlled by an attacker).
                                                                                                                                                  • The mentioned attack on JSON hash tables in PHP (if you dig into it) would’ve been a great place to talk about trivial hashes (e.g., f(x) =0 or f(x)=x) and why they cause problems even in non-hostile environments, but that would’ve required more of an introduction to how hashing works…)
                                                                                                                                                  • Lots of usage of jargon like “non-invertible”, “collision-resistance”, “preimage attack resistance”, etc. which is probably inaccessible if your audience is programmers who “don’t understand hash functions”.
                                                                                                                                                  • There’s not really an explanation about the differences/similarities of crypto-strong hash functions, password hash functions, and key derivation functions, other than a mention that there is some relation but which isn’t elaborated on at all.
                                                                                                                                                  • There’s not really any useful information at all about perceptual hashing vs other forms of multimedia digest approaches–there’s just some Apple hate.
                                                                                                                                                  • etc.

                                                                                                                                                  Programmers might not understand hash functions, but infosec furries may also not understand pedagogy.

                                                                                                                                                  (also, can you please cool it with the inflammatory article headlines?)

                                                                                                                                                  1. 24

                                                                                                                                                    Programmers might not understand hash functions, but infosec furries may also not understand pedagogy.

                                                                                                                                                    Please don’t pick a fight. It seems more angry than friendly.

                                                                                                                                                    1. 22

                                                                                                                                                      Honestly I think it’s a valid concern. One of the biggest problems with the computer security world, as stated repeatedly by leading experts in the field, is communication and teaching.

                                                                                                                                                      1. 23

                                                                                                                                                        A valid concern would be “infosec experts may not understand pedagogy” but why call out “infosec furries” specifically? Unless we should be concerned about infosec furries in particular vs other infosec experts?

                                                                                                                                                        Are these acceptable?

                                                                                                                                                        • but infosec gays may also not understand pedagogy
                                                                                                                                                        • but infosec women may also not understand pedagogy
                                                                                                                                                        • but infosec people of color may also not understand pedagogy

                                                                                                                                                        No. So why furries? People need to get over it and quit furry bashing. This isn’t acceptable behavior on Lobste.rs, and I’m tired of it.

                                                                                                                                                        1. 3

                                                                                                                                                          See elsewhere for the explanation; furry bashing doesn’t enter into it, though I see why you might have read it that way. Furries are internet denizens like the rest of us, with all that entails.

                                                                                                                                                          1. 12

                                                                                                                                                            I agree with you that it’s a bad title.

                                                                                                                                                            I also think that you wouldn’t have reacted nearly this strongly to the title if it wasn’t a furry blog.

                                                                                                                                                            1. 11

                                                                                                                                                              I read your other comments. But you said what you said, and that undermines all your pontificating about the harm of “insulting/demeaning a group” and “the sort of microaggression/toxicity that everybody talks so much about.” Take your own advice.

                                                                                                                                                            2. 2

                                                                                                                                                              “Furry” is a kink, not an identity or protected class. And normally you have to get people’s consent before you bring them into your kink.

                                                                                                                                                              1. 7

                                                                                                                                                                I don’t see any sexual imagery in this blog post.

                                                                                                                                                                1. 2

                                                                                                                                                                  The OP’s site has some pretty well reasoned and presented articles on precisely why “furry” cannot reasonably be summarized as “a kink”.

                                                                                                                                                                  And, no, you do not “normally” have to get someone’s consent to introduce them to the idea of your kink, unless said introduction involves you engaging them in the practice of your kink.

                                                                                                                                                                2. 1

                                                                                                                                                                  Sorry, I didn’t realize the “furry” part was what you were opposed to. It sounded like you were upset with the implication that the infosec world is bad at teaching.

                                                                                                                                                            3. 6

                                                                                                                                                              Programmers might not understand hash functions, but infosec furries may also not understand pedagogy.

                                                                                                                                                              (also, can you please cool it with the inflammatory article headlines?)

                                                                                                                                                              https://www.youtube.com/watch?v=S2xHZPH5Sng

                                                                                                                                                              1. 10

                                                                                                                                                                One of the things he talks about there is testing the hypothesis and seeing which title actually worked. I only clicked this link because I recognized your domain name and knew you had written interesting articles in the past and might legitimately explain something I didn’t know. If not for that, I probably would have bypassed it since the title alone was not interesting at all.

                                                                                                                                                                1. 9

                                                                                                                                                                  Even so, it is still possible to write clickbait titles that aren’t predicated on insulting/demeaning a group.

                                                                                                                                                                  • “Hash functions: hard or just misunderstood?”
                                                                                                                                                                  • “Things I wish more programmers knew about hashes”
                                                                                                                                                                  • “Programmer hashes are not infosec hashes”
                                                                                                                                                                  • “Are you hashing wrong? It’s more common than you might think”
                                                                                                                                                                  • “uwu whats this notices ur hash function

                                                                                                                                                                  How would you feel if I wrote “Gay furries don’t understand blog posting”? Even if I raise good points, and even if more people would click on it (out of outrage, presumably), it would still probably annoy a gay furry who wrote blogs and they’d go in with their hackles raised.

                                                                                                                                                                  1. 8

                                                                                                                                                                    The important difference between what I wrote and your hypothetical is the difference between punching up and punching down.

                                                                                                                                                                    My original title was along the same lines as “Falsehoods Programmers Believe About _____” but I’ve grown a distaste for the cliche.

                                                                                                                                                                    1. 7

                                                                                                                                                                      The difference between “Programmers don’t understand hash functions” and “Gay furries don’t understand blog posting” is quite obvious to me and I definitely don’t want to engage in whatever Internet flame is going on here. Especially since, uh, I have a preeetty good idea about what the problem here is, and I tend to think it’s about gay furries, not article titles, which is definitely not a problem that I have. (This should probably be obvious but since I’m posting in this particular thread, I wanted to make sure :P).

                                                                                                                                                                      But I also think this title really is needlessly nasty, independent of how it might be titled if it were about other audiences. It’s a bad generalisation – there are, in fact, plenty of programmers who understand hash functions – and it’s not exactly encouraging to those programmers who want to get into security, or who think their understanding of these matters is insufficient.

                                                                                                                                                                      I am (or was?) one of them – this was an interest of mine many, many years ago, at a time when I was way too young to understand the advanced math. My career took me elsewhere, and not always where I wanted to go, and I tried to keep an eye on these things in the hope that maybe one day it’ll take me there. Needless to say, there’s only so much you can learn about these topics by spending a couple of evenings once in a blue moon studying them, so I never really got to be any good at it. So I think the explanation is amazing, but it would definitely benefit from not reminding me of my inadequacy.

                                                                                                                                                                      And I’m in a happy boat, actually, this is only an interest of mine – but there are plenty of people who have to do it as part of their jobs, are not provided with adequate training of any kind, have no time to figure it out on their own, and regularly get yelled at when they get it wrong.

                                                                                                                                                                      Now, I realise the title is tongue-in-cheek to some degree, the playful furries and the clever humour scattered throughout the post sort of gives it away. If you think about it for a moment it’s pretty clear that this is meant to grab attention, not remind people how much they suck. But it’s worth remembering that, in an age where web syndication is taken for granted to the point where it sounds like a Middle English term, this context isn’t carried everywhere. Case in point, this lobste.rs page includes only the title. Some people might react to it by clicking because you grabbed their attention, but others might just say yeah, thanks for reminding me, I’ll go cry in a corner.

                                                                                                                                                                      Even if I didn’t realise it was tongue-in-cheek, it probably wouldn’t bother me, partly because I understand how writing “competitively” works (ironically, from around the same time), partly because I’ve developed a thick skin, and partly because, honestly, I’ve kindda given up on it, so I don’t care about it as much as I once did. But I can see why others would not feel the same way at all. You shouldn’t count on your audience having a thick skin or being old enough to have given up on most of their dreams anyway.

                                                                                                                                                                      I know this is a real struggle because that’s just how blogs and blogging work today. You have to compete for attention to some degree, and this is particularly important when a large part of the technical audience is “confined” to places like HN and lobste.rs, where you have to grab attention through the title because there’s nothing else to grab attention through. But maybe you can find a kinder way to grab it, I dunno, maybe a clever pun? That never hurt anyone. These radical, blunt (supposedly “bluntly honest” but that’s just wishful thinking) headlines are all the rage in “big” Internet media because, just like Internet trolls, they thrive on controversy, us vs. them and a feeling of smugness, but is that really the kind of thing you want to borrow?

                                                                                                                                                                      (Edit: just to make sure I get the other part of my message across, because I think it’s even more important: title aside, which could be nicer, the article was super bloody amazing: the explanation’s great, and I like the additional pointers, and the humour, and yes, the drawings! Please don’t take any of all that stuff above as a criticism of some sort: I wanted to present a different viewpoint from which the title might read differently than you intended, not that the article is bad. It’s not!)

                                                                                                                                                                      1. 15

                                                                                                                                                                        How do you know that you’re punching up?

                                                                                                                                                                        What if the person encountering your blog is a programmer from an underrepresented background, just barely overcoming imposter syndrome, and now here’s this scary suggestion that they don’t understand hash functions? What if they actually made one of the mistakes in the article, and feel like they’re a complete fraud, and should leave the industry? This is the sort of microaggression/toxicity that everybody talks so much about, if I’m not mistaken.

                                                                                                                                                                        The point is: you don’t know. You can’t know.

                                                                                                                                                                        So, err on the side of not adding more negative shit to the world accidentally in the name of pageviews–especially when there are many, many other more positive options in easy reach.

                                                                                                                                                                        EDIT:

                                                                                                                                                                        I wouldn’t care if it weren’t for the fact that you’re a smart dude and clearly passionate about your work and that you have good knowledge to share, and that it pains me to see somebody making mistakes I’ve made in the past.

                                                                                                                                                                        1. 8

                                                                                                                                                                          I wouldn’t care if it weren’t for the fact that you’re a smart dude and clearly passionate about your work

                                                                                                                                                                          I’m neither of those things :P

                                                                                                                                                                          and that you have good knowledge to share, and that it pains me to see somebody making mistakes I’ve made in the past.

                                                                                                                                                                          I appreciate your compassion on this subject. It’s definitely new territory for me (since forever I’ve been in the “boring headline out of clickbait adversion” territory).

                                                                                                                                                                          1. 9

                                                                                                                                                                            Do you actually not see a difference between saying a slightly negative thing about people of a certain profession and how they engage in that profession, and an ad-hominem using sexual orientation? What a weird and bad analogy?

                                                                                                                                                                            I’m trying to assume good intent here but all your comments make it sound like you’re annoyed at the furry pics and awkwardly trying to use cancel culture to lash out the author.

                                                                                                                                                                            1. 7

                                                                                                                                                                              Neither the label of programmers (with which I identify) nor of gay furries (with which the author identifies, according to their writing) is being misapplied. I’m sorry you feel that a plain statement of fact is somehow derogatory–there is nothing wrong with being a proud programmer or a proud gay furry.

                                                                                                                                                                              My point in giving that example was to critique the used construction of “ is ”. I picked that label because the author identified with it, and I picked the “bad at blogging” because it’s pretty obviously incorrect in its bluntness. If I had picked “lobsters” or “internet randos” the conjured association for the person I was in discussion with may not have had the same impact it that “programmers” had on me, so I went with what seemed reasonable.

                                                                                                                                                                              1. 4

                                                                                                                                                                                What do you gain by emphasizing soatok’s sexual identity, other than this morass of objections?

                                                                                                                                                                              2. 5

                                                                                                                                                                                I’m trying to assume good intent here

                                                                                                                                                                                that’s exactly what friendlysock is hoping for

                                                                                                                                                                                1. 5

                                                                                                                                                                                  you’re right but it’s best not to feed them

                                                                                                                                                                                2. 8

                                                                                                                                                                                  What if the person encountering your blog is a programmer from an underrepresented background, just barely overcoming imposter syndrome, and now here’s this scary suggestion that they don’t understand hash functions?

                                                                                                                                                                                  Or they may read this and think ‘I’m glad it’s not just me!’. As a programmer who probably has a better than average understanding of hash functions, I don’t feel demeaned by this generalisation, if I were worried about my level of understanding I’d feel comforted by the idea that I wasn’t in a minority in my lack of understanding.

                                                                                                                                                                                  What if they actually made one of the mistakes in the article, and feel like they’re a complete fraud, and should leave the industry?

                                                                                                                                                                                  Or they may feel better that this mistake is so common that someone writes about it on a list of mistakes programmers make.

                                                                                                                                                                                  1. 1

                                                                                                                                                                                    What if the person encountering your blog is a programmer from an underrepresented background….

                                                                                                                                                                                    While I said you’re picking a fight (and would add: “look at the thread, it’s a fight”), I see what you’re saying in this paragraph. I also value non-judgmental explanations.

                                                                                                                                                                                3. 6

                                                                                                                                                                                  My problem with the title isn’t that it’s insulting, but that it’s inaccurate. Clearly some programmers do understand hash functions, even if other programmers do not. If nothing else, @soatok, a programmer, presumably understands hash functions, or why else would he write a blog post purporting to explain the right way to use them?

                                                                                                                                                                                  Programmers don’t understand hash functions, and I can demonstrate this to most of the people that will read this with a single observation:

                                                                                                                                                                                  When you saw the words “hash function” in the title, you might have assumed this was going to be a blog post about password storage.

                                                                                                                                                                                  Specifically is wrong, at least about me, and almost certainly among other programmers as well. I don’t claim to have deep knowledge about cryptography, and I do expect that there’s probably something I could learn from this blog post, which I will read more carefully when I have a chance. But I am aware that the computer science concept of hash functions is useful for a variety of programming problems, and not just storing password-related data.