1. 6

    I think that the view that type systems exist to just enforce rules and check that your programs are correct is very incomplete: type systems are extremely powerful reasoning mechanisms that themselves allow you to express properties of your programs and are a space where you construct them, not just restrict them at the value level. I think Idris is the best example of this, although Haskell might be more accessible and serve as a bridge if you want to go in that direction. I suggest getting the Idris book, currently going through it and it’s extremely well-written!

    The central idea in Idris are dependent types: essentially they remove the distinction between a type variable and a regular variable, allowing you to say that for example a Matrix 3 4 is a wholly different type than Matrix 4 3, and when you have access to such specific types, a large part of your programming is lifted to the type level.

    The author still seems to think, for example, that good type systems don’t force you to write annotations unless you really must. In Idris, type annotations are enforced, because they aren’t merely annotations to help the compiler infer other types, but are just the place where you write a large part of your program (albeit dependent types make type inference harder so there’s a technical component to that).

    1. 1

      Well, nothing stops you from writing stringly typed code full of mutations using IORefs in Idris. The point with strong type systems is not that you have to write safe code, it’s that you can do so.

    1. 1

      “all you need to annotate are function parameters and return values” - true in C++ now too, it’s not just Rust.

      “gtest sucks” - it does, but there are far better alternatives. I agree that pytest rocks. I’m curious as to whether dependency injection and mocking are better in Rust than in C++, especially given the lack of compile-time reflection.

      1. 3

        In my experience C++ generally requires more annotation of types within a function body, so it is still fair to call out annotating only function parameters and return values as a strength of Rust in particular.

        For example in Rust:

        // Within the same function body we push a `&str` into the vector
        // so compiler understands this must be a `Vec<&str>`.
        let mut vec = Vec::new();
        vec.push("str");
        

        versus C++:

        // Vector element type cannot be inferred.
        std::vector<const char *> vec;
        vec.push_back("str");
        
        1. 1

          C++17 has constructor template argument deduction, so you can just say auto vec = vector({"str"}) now. Though Rust’s type inference is obviously more powerful.

      1. 3

        Working remotely and having flexible working hours seems like two completely different topics to me. I wouldn’t mix them up.

        1. 2

          Well, not completely different, if remote means anywhere in the world, setting company-wide fixed working hours would be impractical. So the issues aren’t entirely orthogonal.

          1. 1

            I’d say it completely depends on the job and the team. I work remotely with people all around north america and europe (mostly), and I appreciate knowing when someone will be online to answer a question or handle a request. I see no reason why a remotee shouldn’t be asked to work 9-5 if it’s needed for communication/productivity/other reasons. That is, to me, a different topic from physical location.

          2. 1

            You certainly can have flexible hours without working remotely, but how many office bound staff have accsss to that office outside of say 6am till 8pm?

          1. 4

            Honestly, the driving script in bash feels like it’s cheating. It actually feels like despite all the new toys, metaprogramming in C++ still isn’t that powerful.

            Couldn’t this be done more easily with lisp macros? I can sort of see how to do it with D compile-time structures.

            1. 3

              I don’t think there’s much point comparing such exercises across languages. For instance, with Template Haskell, you can run arbitrary Haskell code and even do IO at compile time, you could even write a 3D shooter, but I’d still say C++ templates are more powerful than TH in many aspects, due to the way they interact with the rest of their respective languages.

              1. 1

                Maybe I shouldn’t have said “powerful”, but “convenient”? I think it does make sense to have these comparisons at least for this example. In both Lisp and D, you have all of the language at compile time, so you can do just about anything.

                It appears that even when attempting a ridiculous feat, thus accepting some inconvenience, C++ compile-time features are still too onerous to put the whole game loop into them.

                Edit: After thinking about this for a second, I’m not sure it’s possible in D anymore since compile-time D functions have to be deterministic.

                1. 2

                  I understand your point about the convenience, but my point is that the real purpose of the metaprogramming features isn’t to write interactive games. What matters is how it interacts with the run-time features. For instance, C++ templates are more powerful than Template Haskell, because of template argument deduction and due to how template instantiation can cause other templates to be instantiated seamlessly. Whereas in TH, you cause all template expansions by hand. Without considering the interaction with the rest of the language, the best metaprogramming would simply be generating C++ code using C++, then running that program as a preprocessing step. That’s why I think comparing the power of metaprogramming features accross languages through non-metaprogramming things you can do with them is pointless.

                  1. 1

                    Ah, it does sound inconvenient in TH to not have automatic instantiations.

                    1. 1

                      Yeah, it is, TH is much more bolted-on in Haskell compared to templates in C++, but on the other hand, Haskell’s type system is vastly more powerful without metaprogramming, so you rarely really need it. As I said, hard to compare across languages :)

              2. 2

                In Lisp you have the full language in disposal at compile-time, so it’s way too easy.

                1. 1

                  That was my first thought, that the actual game loop is still implemented at runtime (with a bash runtime), which is sort of cheating. On the other hand, since one of my research areas is modeling game mechanics in formal logic, it somehow feels natural to accept an implementation of a state->state' transition function as morally equivalent to an implemention of a game. :-)

                1. 6

                  I can’t agree with this article.

                  When writing new code, I can accept that making tasks smaller and discrete doesn’t require as much mental scaffolding, therefore it might be possible in some contexts to handle being interrupted without it being disastrous, but most of the time we’re working on existing code. We are compiling code in our brains and making all kinds of mental leaps stashing temporary memories as we debug and process what’s going on.

                  I’m not saying programmers are special snowflakes; I’m sure there are other fields of brain work that are as taxing, but yes, interruptions are catastrophic for programmers.

                  1. 2

                    I definitely agree, interrupting a debugging session is effectively resetting all progress. Not to mention the fact that the more you have to restart a specific debugging session, the harder it gets, because a sort of learned helplessness sets in.

                  1. 12

                    I thought it would actually be about std::optional, not workspace issues that have nothing to do with the problem at hand.

                    TL;DR: keep your toolchain up to date if you want to use recent language features.

                    1. 3

                      yeah. I suspect better article naming would be better at not leaving people feel like they kept on expecting the article to go somewhere it didn’t.

                      1. 9

                        I think it’s funny because the reader’s experience parallels the author’s experience of wanting to get someplace.

                        1. 4

                          Somebody gets me! :)

                        2. 2

                          Sorry folks :(. But std::optional works as one expects - you can write functions to accept std::optional and you just check early on if it evaluates to true and just return empty as needed, so you can chain functions neatly.

                          Now, if only we could have pattern matching …

                          1. 3

                            I think the consensus of languages with options and pattern matching is “don’t use pattern matching, use combinators”.

                            1. 4

                              Hmm as a full-time Haskeller “don’t use pattern matching” is news to me. Do you mean “don’t use pattern matching for fundamental vocabulary types like Maybe or Either? In which case it’s a reasonable guideline. For types representing your business domain, pattern matching is perfectly good practice. IMHO exhaustiveness checking of pattern matching is an indispensable feature for modelling your domain with types.

                              1. 1

                                Do you mean “don’t use pattern matching for fundamental vocabulary types like Maybe or Either?

                                Yes.

                              2. 3

                                Consensus, really? I’m a big fan of combinators, but I’ll still match on option types sometimes if I think it looks clearer.

                                1. 2

                                  Ooh, this is interesting to me - can you expand on this (or point me to some writeups)? Thanks!

                              3. 2

                                Agreed. I read all the way down and nothing significant about std::optional.

                                I thought it was going to be some sort of piece about how using std::optional could lead to yak shaving or something :(

                            1. 1

                              TL;DR If a worker in an arbitrarily large group is faulty in a way that it immediately discards assigned tasks and asks for more, it can spoil a disproportionately large number of tasks in a load-balanced setting.

                              1. 17

                                Pointfree style in ML-family languages (e.g. Haskell) lets you avoid naming things, though the style was designed more for general conciseness than that specifically.

                                1. 9

                                  Similarly, pipelines in shell scripts let you avoid naming intermediates.

                                  (Pipelines are a combination of pointfree style and array language style, in that well-designed pipelines are side-effect-free and the programs in the pipeline mostly implicitly iterate over their input.)

                                  1. 2

                                    There’s also a tool called Pointfree which auto converts code into “pointfree style” - e.g.

                                    \a b c -> b * c
                                    
                                    const (*)
                                    

                                    And there’s also Pointful, for the other way around.

                                    1. 1

                                      I think Haskell strikes a very fine balance here. Both point-free and pointful styles are very ergonomic, so you tend to name precisely those things that would be better off named.

                                    1. 5

                                      This a fascinating case. It’s very unfortunate that the cyclist had to die for it to come before us. However, had the car been driven by a human, nobody would be talking about it!

                                      That said, the law does not currently hold autonomous vehicles to a higher standard than human drivers, even though it probably could do so given the much greater perceptiveness of LIDAR. But is there any precedent for doing something like this (having a higher bar for autonomous technology than humans)?

                                      1. 13

                                        Autonomous technology is not an entity in law, and if we are lucky, it never will be. Legal entities designed or licensed the technology, and those are the ones the law finds responsible. This is similar to the argument that some tech companies have made that “it’s not us, it’s the algorithm.” The law does not care. It will find a responsible legal entity.

                                        This is a particularly tough thing for many of us in tech to understand.

                                        1. 25

                                          It’s hard for me to understand why people in tech find it so hard to understand. Someone wrote the algorithm. Even in ML systems where we have no real way of explaining its decision process, someone designed it the system, someone implemented it, and someone made the decision to deploy it in a given circumstance.

                                          1. 11

                                            Not only that, but one other huge aspect of things nobody is probably thinking about. This incident is going to probably start the ball rolling on certification and liability for software.

                                            Move fast and break things is probably not going to fly in the faces of too many deaths to autonomous cars. Even if they’re safer than humans, there is going to be repercussions.

                                            1. 8

                                              Even if they’re safer than humans, there is going to be repercussions.

                                              Even if they are safer than humans, a human must be held accountable of the deaths they will cause.

                                              1. 2

                                                Indeed, and I believe those humans will be the programmers.

                                                1. 4

                                                  Well… it depends.

                                                  When a bridge breaks down and kills people due to bad construction practices, do you put in jail the bricklayers?

                                                  And what about a free software that you get from me “without warranty”?

                                                  1. 4

                                                    No - but they do take the company that build the bridge to court.

                                                    1. 5

                                                      Indeed. The same would work for software.

                                                      At the end of the day, who is accountable for the company’s products is accountable for the deaths that such products cause.

                                                    2. 2

                                                      Somewhat relevant article that raised an interesting point RE:VW cheating emissions tests. I think we should ask ourselves if there is a meaningful difference between these two cases that would require us to shift responsibility.

                                                      1. 2

                                                        Very interesting read.

                                                        I agree that the AI experts’ troupe share a moral responsibility about this death, just like the developers at Volkswagen of America shared a moral responsibility about the fraud.

                                                        But, at the end of the day, software developers and statisticians were working for a company that is accountable for the whole artifact they sell. So the legal accountability must be assigned at the company’s board of directors/CEO/stock holders… whoever is accountable for the activities of the company.

                                                      2. 2

                                                        What I’m saying is this is a case where those “without warranty” provisions may be deemed invalid due to situations like this.

                                                      3. 1

                                                        I don’t think it’ll ever be the programmers. It would be negligence either on the part of QA or management. Programmers just satisfy specs and pass QA standards.

                                                  2. 2

                                                    It’s hard to take reponsability for something evolving in a such dynamic environment, with potentially used for billions of hours everyday, for the next X years. I mean, knowing that, you would expect to have a 99,99% of cases tested, but here it’s impossible.

                                                    1. 1

                                                      It’s expensive, not impossible.

                                                      It’s a business cost and an entrepreneurial risk.

                                                      If you can take the risks an pay the costs, that business it not for you.

                                                2. 4

                                                  It’s only a higher bar if you look at it from the perspective of “some entity replacing a human.” If you look at it from the perspective of a tool created by a company, the focus should be ok whether there was negligence in the implementation of the system.

                                                  It might be acceptable and understandable for the average human to not be able to react that fast. It would not be acceptable and understandable for the engineers on a self-driving car project to write a system that can’t detect an unobstructed object straight ahead, for the management to sign off on testing, etc.

                                                1. 12

                                                  He didn’t really answer the question though :(

                                                  I think they’re CONSIDERED in opposition as a historical thing. While objects entered heavy use in the 80’s, the paradigm of “everything is an object” started with Java in the mid 90’s. Java rapidly became the most popular language, and functional languages started representing themselves as “not OOP”. Note that before the Java Era we had CLOS and Ocaml, both of which are functional languages with objects.

                                                  1. 5

                                                    You are right, he didn’t answer it! He answered “Is FP in opposition to OO”. I think your answer is pretty accurate. People confused C++ and Java as OOP (instead of recognizing them for what they were, Class Based Programming). And because these languages mutated state, FP is in opposition to them, and therefore OOP.

                                                    I think more importantly, the pop culture has no idea what OOP is and therefore people are confused when they think FP is in opposition to OOP.

                                                    1. 5

                                                      I think more importantly, the pop culture has no idea what OOP is and therefore people are confused when they think FP is in opposition to OOP.

                                                      I don’t think it’s fair to say that the “pop culture” doesn’t know what “OOP is”, because there really isn’t a definition of OOP. A lot of people equate it with Smalltalk, but you could also say OOP is Eiffel, or Ada, or Simula…

                                                      1. 3

                                                        People confused C++ and Java as OOP (instead of recognizing them for what they were, Class Based Programming).

                                                        I don’t really think that classes are problem*. They were not just Class Based Programming, but imperative Class Based Programming inspired by C. If you look at Smalltalk (which is also Class Based), missing component is late binding, which allows you to do all kinds of neat stuff and cleaner style of programming (imho).

                                                        *Although I really like Self, which is basically prototype based Smalltalk-like system.

                                                        1. 3

                                                          Unfortunately to most people class based programming and OOP are the same.

                                                          1. 5

                                                            I don’t know if “most” people do, but there is certainly a decent collection of people out there who think this. Consider this document (“Object-Oriented Programming in C”, revised December 2017), which starts out with this:

                                                            Object-oriented programming (OOP) is not the use of a particular language or a tool. It is rather a way of design based on the three fundamental design meta-patterns:

                                                            • Encapsulation – the ability to package data and functions together into classes
                                                            • Inheritance – the ability to define new classes based on existing classes in order to obtain reuse and code organization
                                                            • Polymorphism – the ability to substitute objects of matching interfaces for one another at run-time
                                                            1. 1

                                                              most people I have met while programming professionally in New Zealand.

                                                              1. 1

                                                                Inheritance – the ability to define new classes based on existing classes in order to obtain reuse and code organization

                                                                I think this is universally accepted as an anti-pattern, both by OO programmers and FP.

                                                              2. 2

                                                                I think how most C++, Java, and .NET programmers code supports your position. At least, how most code I’ve seen works looking at code from… everywhere. Whatever my sample bias is, it’s not dependent on any one location. The bad thinking clearly spread along with the language and tools themselves.

                                                          1. 22

                                                            Comments really aren’t a “code smell.”

                                                            1. 16

                                                              Nothing stinks quite like uncommented complicated code.

                                                              1. 7

                                                                Exactly! Margaret Hamilton’s code itself, whom the author cites, is full of comments. Possibly more comments than source code. Which, if you’re sending a ship with the processing power of a toothbrush to the Moon, is a great idea.

                                                                1. 10

                                                                  This code is not readable on it’s own, if it was possible to use variable and function names most of those comments could be removed. It’s also quite likely that every detail of the program was decided before writing the code. In a modern codebase things are always evolving and comments can get left behind.

                                                                  1. 5

                                                                    This is my fear with comments. I code in a team of 2, so we don’t really comment stuff. I know it’s bad, but I’m a team of two, we kind of know the whole code anyway.

                                                                    We also don’t write tests. We’re bad people.

                                                                    1. 4

                                                                      Oh man, save yourself some pain and write unit tests. You don’t need 100% test coverage, even non-zero coverage of basic functionality will save you so much time. If you don’t know how to use test frameworks then you don’t have to bother, just write one big main file with a function per test you want to do, and call them all in main. That’s basically what test frameworks are, so if you need a low barrier to entry then don’t bother learning one yet, just do something. If you program in a language with a REPL you can literally just save the stuff you use to manually test into a file so you don’t have to type it more than once.

                                                                      I personally couldn’t develop without unit tests. You can test the application and do something that hits the code path you just changed, which is time consuming and tedious, especially to do repeatedly, or you can write a little bit of code that calls the code and run it with zero effort every time all the time for the rest of forever. Even a small sanity test of the happy path is better than nothing, you can at least check your code doesn’t blatantly fuck up with normal input and save yourself the round trip through the application.

                                                                      If I had to code without unit tests I’d quit. And I have worked on teams that didn’t want to unit test, so I had out-of-tree tests I wrote for myself. The amount of bugs I fixed a couple hours after someone else committed was mind boggling.

                                                                      1. 4

                                                                        How do you even develop without unit tests?

                                                                        I’d avoid this kind of shaming, especially since the commenter has already noted (in a self-deprecating manner) that they’re aware of the stigma associated with not using tests.

                                                                        If the intent is to encourage the use of tests, I would put your last paragraph first and focus on how it would help GP.

                                                                        1. 3

                                                                          Revised, thank you for the feedback. 😊

                                                                        2. 2

                                                                          Depends on the language and coding style though. I wrote a 25000 line game in C++ without a single test, and I never had a regression. I obviously had occasional bugs in new code, but they’re unavoidable either way. Now my preferred language is Haskell, and I feel the need for tests even less. I generally prefer correct-by-construction to correct-by-our-tests-pass. My purpose isn’t to discredit tests though, just that not every codebase has as much need for them.

                                                                          1. 2

                                                                            I’m just self taught and kind of out of my depth on it. I had a dev friend who did integration tests, and they were really brittle and slowed us down a lot. Are unit tests not as bad at slowing down a small team of two devs who are both self taught? We’re good / mediocre / we build good stuff (I consider ourselves hackers) but we don’t have a ton of time.

                                                                            1. 1

                                                                              Unit tests don’t have to slow things down like integration tests. In your situation, I’d wait until the next bug comes up, then instead of fixing the bug immediately, I’d write a test that reproduces the bug. Usually doing that helps narrow down where the bug is, and after fixing it, the test passes and (here’s the cool part) you will never see that bug again

                                                                              1. 1

                                                                                That’s what i was told about integration tests, but I had to set up all these extra dependencies so that the integration tests continued to work every time we added an external service… we’d have to mock it or shit would break.

                                                                                I’m assuming since Unit tests don’t run like that, they don’t have external dependencies like that? You’d mock on a component by component basis, and wouldn’t have to mock unrelated shit just to keep them running… hmm… maybe i will.

                                                                                Any unit testing video series I could watch as a noob to get started you’d recommend? Or anything like that?

                                                                            2. 1

                                                                              I second saving yourself pain with writing tests! I’ve avoided lots of rakes with a handful of tests

                                                                          2. 2

                                                                            What makes everybody think that the programmers who change code so that it no longer matches the comments they just used to understand it will somehow write code so clear you don’t need comments to understand it?

                                                                            1. 1

                                                                              Often people write code like total = price * 1.10 #This is tax which can be rewritten as total = price * TAX A lot of comments like that can be removed by just putting them in the actual code.

                                                                              1. 2

                                                                                I’m not suggesting it can’t be done I’m suggesting it won’t be done

                                                                          3. 4

                                                                            I’ll also correct the article to say a team did the code and review per the reports I read. She describes it here in “Apollo Beginnings” as a team with a lot of freedom and management backing with unusual requirement to get software right the first time. Unfortunately, a rare environment to work in.

                                                                          4. 5

                                                                            You can’t write test coverage for a comment. You can’t have your compiler warn you that a comment is inaccurate.

                                                                            If you have no tests, and your code is full of dead paths, you can’t even percieve the risk posed by an errant, out of date, or unintentionally misleading comment.

                                                                            Sometimes they’re necessary. But the best default advice to a ‘mediocre’ developer is to write better code, not add more comments.

                                                                            1. 5

                                                                              You can’t write test coverage for a comment. You can’t have your compiler warn you that a comment is inaccurate.

                                                                              https://docs.python.org/3/library/doctest.html

                                                                              If you have no tests, and your code is full of dead paths, you can’t even percieve the risk posed by an errant, out of date, or unintentionally misleading comment.

                                                                              If you have no tests or comments you have no way of knowing whether your code is actually matching your spec, anyway.

                                                                              Sometimes they’re necessary. But the best default advice to a ‘mediocre’ developer is to write better code, not add more comments.

                                                                              That’s like saying that the best default advice to a ‘mediocre’ developer is to write less buggy code, not add unit tests.

                                                                              1. 2

                                                                                doctest is great for testing comments that include code, but nothing else… If a comment says “Framework X is expecting variable foo in JSON format inside the array bar.” I would be inclined to believe it at first and then test the hypothesis that the comment is wrong. That’s the danger of comments.

                                                                                1. 1

                                                                                  A couple of times today I caught myself committing deleted or changed lines without deleting or changing the associated comment. Luckily I could go back and fix things so that the comments weren’t complete nonsense. Sometimes though they escape detection.

                                                                              2. 2

                                                                                Once the code is cleaned as much as possible and still is hard to understand, or if something is tricky, comments help a lot!

                                                                                I guess the author talked about comments that could be removed by making the code cleaner.

                                                                                Maybe it depends on what motivates one to add comments, there might be good reasons as well.

                                                                                1. 2

                                                                                  True.

                                                                                  But Comments that are wrong or out of date stink like dead rats.

                                                                                  I view asserts as “executable comments” that are never out of date. Sometimes they are wrong… but testing will tell you that.

                                                                                  If a plain comment is wrong… nothing will tell you except a very long, very Bad Day at work.

                                                                                  1. 7

                                                                                    But Comments that are wrong or out of date stink like dead rats.

                                                                                    Valuable comments are something along the lines of “this looks weird, but I did it because of [historical reason that is likely to be forgotten] even though [other implementation] looks like the more obvious solution at first glance; it wouldn’t have worked because [rationale].”

                                                                                    The longer I spend working with old codebases, the more I’ve come to treasure such comments. But comments that just explain what the code is doing rather than why are suspect.

                                                                                1. 1

                                                                                  Hi, we are a small startup with ~10 engineers. We’re using AWS, both for customer services (we deploy a few instances per customer, so they are completely isolated) and for the services that support our own workflows (CI etc.). For customer instances, we currently use simple scripts utilizing the AWS CLI tools. For our supporting infrastructure we use NixOps. NixOps is a blast when it works, though it requires some nix-fu to keep it working.

                                                                                  1. 5

                                                                                    The right to be able to transfer your data from system to system is part of the new General Data Protection Regulation of the European Union.Apart from the above article on the GDPR (quoted below), see also the specific Wikipedia article on data portability in the GDPR. Not sure whether this also guarantees right to import your data in the other provider, though!

                                                                                    A person is to be able to transfer personal data from one electronic processing system to and into another, without being prevented from doing so by the data controller. Data that has been sufficiently anonymised is excluded, but data that has been only de-identified but remains possible to link to the individual in question, such as by providing the relevant identifier, is not.[25] Both data being ‘provided’ by the data subject and data being ‘observed’, such as about behaviour, are included. In addition, the data must be provided by the controller in a structured and commonly used a standard electronic format. The right to data portability is provided by Article 20 of the GDPR.[6] Legal experts see in the final version of this measure a “new right” created that “reaches beyond the scope of data portability between two controllers as stipulated in [Article 20]”.[26]

                                                                                    1. 1

                                                                                      Hmm, I wonder what happens if your data is inseparably mixed with other people’s private data.

                                                                                      1. 1

                                                                                        Fortunately, there are already market incentives to allow importing data :)

                                                                                        Will the GDPR force FB to allow users to take their social graphs with them?

                                                                                      1. 3

                                                                                        So, silly question, what happens when you are on a site that awards reviews 1-5 stars and you move to a site that’s 1-4 stars?

                                                                                        1. 3

                                                                                          I think this is a very minor issue. If the lawmakers were to step-in, they could easily force a standard for ratings that would make them transferable. Actually, you don’t even need to transfer anything, it would be enough even if you could just link your profiles across platforms, so a customer could be burdened to judge what it means to be rated 3.7/4 on Uber while 3.12/3.1415 on Lyft.

                                                                                          1. 0

                                                                                            If the lawmakers were to step-in, they could easily force a standard for ratings

                                                                                            It would be crazy to expect lawmakers to do anything sensible here. Ignoring the moral issues with forcing companies to adopt particular algorithms, it also doesn’t make practical sense if you want your software to work correctly. Ratings also aren’t a solved problem.

                                                                                            The real solution here is technical/UX; we have the technology for distributed, trustless rating systems. They’re just really inconvenient to use right now. Getting that to work is better for everyone than legislators forcing some particular ratings format.

                                                                                            1. 1

                                                                                              Getting that to work is better for everyone than legislators forcing some particular ratings format.

                                                                                              Well, you might need the legislators to force the current platforms to integrate with the trustless rating systems. On the other hand, you probably don’t need much support from the platform, all it takes could be the ability to include a secure hash in your profile on a given platform to link your account on an external system.

                                                                                          2. 2

                                                                                            That’s easily addressed by the importing site writing a function to convert scores from 1 system to the other. I’ve done this before - it’s not hard at all.

                                                                                          1. 12

                                                                                            How does this work. If programmer A spends ~5 hours a day programming at work and programmer B spends the same at work and then a few hours at home how can they be anything but better? Practice improves skills so unless your programming at home is just adding 1+1 in python all day how can you not come out better?

                                                                                            1. 8

                                                                                              The key to understanding this conundrum is that there is a tension between one’s workplace environment and what one does after work for programmers. The essential problem is that someone who writes code in their free time (not necessarily for work) and is passionate about it is likely going to be viewed favorably in contrast to someone who doesn’t do that. The problem here is that it ups the ante by setting a bar that is unreasonably high. It is viewed as a significant problem likely because there are many people who code on their free time and enjoy it. This has a serious impact on the work environment. At the very least:

                                                                                              • If someone is coding a lot in their free time, others may feel obligated to do the same, even if they don’t want to. This is an indirect form of social pressure, and a lot of people view it negatively.
                                                                                              • Often times, people will use weasel words like “I want someone passionate” to mean “I want someone to dedicate a lot more than 40 hour work week to their practice.” Thus, there are lots of emotions bottled up in words like “passionate.” On the one hand, it is an admirable quality. On the other hand, it’s doublespeak.

                                                                                              Combating these sorts of things is difficult. Posts like this one seem to be doing just that. I think it’s not a bad idea, even though I don’t know what to do with the implied conclusion: “diversity is good, and everyone brings their own skillset to the table.” To me, it’s vacuously true, but I don’t know what to do with it. Maybe it means we should be playing to each individual’s strengths? Sure, that seems fine. But it neglects to answer the hard questions: what do you do when an individual’s strengths aren’t a match for what you need to accomplish? Or what if the individual has too few strengths?

                                                                                              In any case, I do think the argumentation has kind of reached a ridiculous level. In most walks of life, I’d be willing to wager that more practice on foo generally results in stronger skills in foo. There’s all sorts of ways you can dice that up with respect to the form of that practice, but I don’t think it weakens the point. It is just a correlation after all, and isn’t always true. As best I can tell, these types of posts are gentle reminders of that fact, but equalizing everything in that pursuit seems like folly.

                                                                                              Alas, I may have a skewed perspective. I didn’t grow up programming. I grew up in competitive sports. That others may be more naturally gifted or more dedicated to practice was as natural to me as anything. (Note that I am not making an analogy; competitive childhood sports are not the same as one’s livelihood. I’m just explaining my perspective.)

                                                                                              1. 4

                                                                                                I guess if programmer A spends the rest of the time in coma your model works, but the problem is that 5 hours of programming everyday may well bring you to the saturation point where programming further does little to improve your skills, while doing other things to improve your health and general intelligence indirectly improve your performance more.

                                                                                                1. 3

                                                                                                  I guess if programmer A spends the rest of the time in coma your model works

                                                                                                  Sure, let’s borrow varjag’s examples and assume programmer A spends the corresponding time on guitar, photography, or snowboarding. Do you really think it’s likely - not possible, but likely - that A is a better programmer than B?

                                                                                                  1. 5

                                                                                                    Well, yes. Do you think it’s unlikely? Why?

                                                                                                    The comment you’re replying to about a saturation point explains why it is. I’d also add that guitar, photography and snowboarding all can contribute to understanding yourself and life in general which then translates into being a better programmer. Programmers who think that programming is only about coding tend not to be very good programmers.

                                                                                                    1. 2

                                                                                                      Do you really think it’s likely - not possible, but likely - that A is a better programmer than B?

                                                                                                      I think the image in your mind is 5 hours of boring repetitive enterprise work + 3 hours of explorative programming, then it’s of course not likely. But if we’re comparing 5 hours vs. 8 hours of similar kind of programming, I wouldn’t be surprised. Think about a body builder, would you really be surprised if someone who lifted weights 5 hours/day ended up stronger than someone that does 8?

                                                                                                      Besides, it also depends on what you include in the notion of “a good programmer”? Is it lines of code per minute? Then 8 hours might be better. But if you include things like the ability to mentor others, understand the domain better to spot spec errors, communicate with the rest of the organisation to solve other people’s problems and get things done, schedule activities etc. 3 hours solitary programming will definitely not help on those areas, and programmer A will most probably be better at them.

                                                                                                      1. 1

                                                                                                        A will most probably be better at them.

                                                                                                        But why will A be better? Why is it assumed that the programmer who programs in their free time will be doing worse at work?

                                                                                                        1. 1

                                                                                                          The point is programming isn’t only about programming. Even if you’re a 10x faster at the keyboard, you still need to understand what the customer needs, what designers had in mind, what the product management prioritizes, what the sales has promised, how the standards are applied/violated, how devops deploys your code, how support tries to diagnose problems etc.. At the end of the day, this is all a huge team effort. Your programming ability is of course important, but there’s a multiplicative factor in front of it, which is determined by your ability to communicate with other people. Otherwise, you’ll be writing useless code (however efficiently you might write it).

                                                                                                          The question is, if programmer B keeps writing code all the time, when will they develop their soft skills? Obviously, programmer B might still be a pleasant individual, who’s attentive and one who cares about other’s opinions, observations and feelings. The whole point is you need to develop those skills as well.

                                                                                                  2. 2

                                                                                                    More time does not necessarily result in being better - the practice has to be deliberate - and actually improve the skill you are practising. Otherwise it can be counter productive.

                                                                                                    1. 5

                                                                                                      Let’s say your hobby is not programming but guitar, photography or snowboarding. Would you say more practice doesn’t necessarily help?

                                                                                                      1. 4

                                                                                                        As a BMX coach - I would definitely say that more practice does not always help - especially if the technique is not correct as what you create is a habit / reflex / muscle memory that is not beneficial. Yes it is possible to re-programme a bad habit but it takes a lot more work, effort and practice to change the bad habit into a good one. So deliberate practice is far more valuable that quantity of practice. Also, in sports if you do things when you are tired / worn out there can be an enhanced risk of injury - which is really detrimental as then you add a pain response…

                                                                                                        I believe the same is true for musical instruments, but I’m tone deaf so don’t take my word for it ;~)

                                                                                                        1. 4

                                                                                                          I’ve played guitar for 20+ years, it’s the same for musical instruments. Deliberate, effective practice is hard, and too much of it can seriously hurt you (I have some hand issues because I wasn’t careful enough for a stretch of time).

                                                                                                      2. 3

                                                                                                        How can more practice make you worse, if you are doing the same things at work as programmer A then you would have to try really hard to get worse with your at home programming. I also find my at home programming gives me many skills I can take to work because I can mess around with random things that I don’t know will be of any use and sometimes they are where as at work it’s all kept fairly safe.

                                                                                                        1. 4

                                                                                                          The following article from Havard Business Review[1] has some interesting research into the problems of practice. Unfortunately, I’m unable to find an open access copy of the article.

                                                                                                          [1]The making of an expert, Harvard business review, the article can be read here

                                                                                                    1. 32

                                                                                                      Oh boy, I have a lot of feelings about this. Good on the author for bringing it up.

                                                                                                      Junior developers (having been one) are amazing to have around and, if handled properly, are a major force multiplier.

                                                                                                      Personally observed benefits of junior devs:

                                                                                                      • They are hungry. They are looking to get that paycheck, no matter how small it is compared to a senior developer, and since they’re often hourly they’ll actively look for additional work to do if managed properly to pad out beer money or rent or childcare or family care or whatever. Senior devs begin playing a game (if they’re smart) of “I am salaried…how can I exert minimum effort for maximum possible revenue?” Senior devs also know themselves better, and so they can often say “Yeah, $X is enough, I don’t see the personal upside in taking on more work even with a pecuniary benefit”.
                                                                                                      • They don’t know what is hard and what isn’t. They are juniors, and so they attack tasks (architectural and scutwork) with near equal optimism. You can give them something that’s impossible and they’ll come back with solutions that actually are good-enough fudges for business purposes.
                                                                                                      • They want to learn. The only way to become a senior developer is by learning things, and a lot of junior devs have a chip on their shoulder (acknowledged or not) about not knowing enough–so, they’ll go do new things and learn about them and try to show off that learning. Senior devs often go with tried-and-true knowledge because they know how to execute most quickly with it; a junior dev can help uncover better solutions that would be ignored otherwise.
                                                                                                      • They might know things you don’t. Hell, I learned React in from an excellent junior dev.
                                                                                                      • They’ll stick around longer. Similar to being hungry, the friction for a junior dev to switch companies is higher (they underestimate their own knowledge and value, remember?) than for a senior dev. So, if you display even marginal competence and compassion towards them, they probably won’t jump ship. Also, their pay scale starts so much lower so that you can keep giving real raises without worrying about breaking the bank.

                                                                                                      However, there are severe pathologies to junior devs:

                                                                                                      • They suffer extra from morale-stressing situations (modulo life experience). A junior dev can get stuck in a project or stuck with a bad situation and really just ground down by it, where in the same place a senior might go “well, this sucks, but we can see it through”. They haven’t had a lot of history of failed and successful projects, so they can take things too hard.
                                                                                                      • They love learning new things, and want to try them out all the time. Until trained properly, junior devs have very little conservatism in their engineering. They’ll switch from Backbone to Angular to React because they’re learning new and exciting things–even if the original domain just needed a static server-side page.
                                                                                                      • They are really bad at software estimates. Like, even moreso than normal, because they lack the breadth of experience to know what paths in a project are probably most filled with spiders and which ones are tedious but quick.
                                                                                                      • They are bad at managing others. Juniors are just barely getting their own career and projects in order, and usually lack the technical, political, and engineering proficiency to organize and communicate effectively with others in a leadership role. This does not mean they shouldn’t (with careful and direct supervision) be forced into it–after all, that’s how they learn!
                                                                                                      • Modulo life experience, they focus on tech more than customers. Due to their desire for knowledge and improvement, they often miss the essential chatting with customers/users of a software project that can pull out hidden requirements or even allow for shipping partially complete work.
                                                                                                      • They can make a huge mess. Given credentials to production system, or given large foundational architecture work, juniors can do bizarrely well-intentioned things that result in total chaos. Seniors can (and do!) have the same problems, but they’re usually more likely to ask for help or exercise caution.
                                                                                                      • Modulo life experience, they don’t understand themselves. Juniors have a hard time spotting when they’re getting overloaded or burned out, and they have a hard time figuring out why they feel a certain way about technical and interpersonal conflicts. This results in communication problems, chaos, and general bad vibes until addressed.
                                                                                                      • They will dutifully reproduce the dev practices around them. So, if all of the example code for solving something does weird shit, juniors will dutifully continue doing weird shit. If the build process is crackheaded and error-prone, the juniors will dutifully keep running it and running into problems and, as noted above, probably continue creating problems. And they’ll teach other more-junior devs to do the same!

                                                                                                      I’ve got thoughts on the care and feeding of junior devs, but this post is already rather long.

                                                                                                      1. 4

                                                                                                        Thanks for sharing this, you’ve crystallized a lot of my own thoughts on junior devs excellently. I taught at a bootcamp for a while, and my favorite thing about new dev you summed up as, “They don’t know what is hard and what isn’t.” It was so cool to see these fresh students attack problems that I would have immediately dismissed simply because they didn’t know how hard it was. I think this is an excellent lesson for senior devs as well, a kind of “beginner’s mind” that’s hard to obtain.

                                                                                                        I think any project is like this: if you knew how tough it would be at the end, you probably wouldn’t have started it. Our ability to over- and under- estimate can sometimes be a huge boon.

                                                                                                        1. 3

                                                                                                          If you get the urge to write about the care and feeding of junior devs, I would be interested in reading it.

                                                                                                          1. 2

                                                                                                            It’s not totally independent of the items you’ve listed, but one thing I’ve noticed about juniors is that they also don’t stop to think whether the things they build upon are designed to be taken to scale. So with juniors around, it can be dangerous to say “OK, let’s embrace the fact that we have 5-10 of these things currently, so we’ll do something quick that relies on this fact, and we’ll switch to something more sensible when we need to scale in this direction.”. The moment you look away, you’ll find that a junior has written a script to auto-generate thousands of those things and built an entire structure around it without questioning whether the rest of the system was ready for it (however obvious that might seem to you).

                                                                                                            I think the broader point here is that juniors are much more susceptible to tunnel vision, where they only focus on what they’re trying to solve at a given moment without considering the big picture.

                                                                                                          1. 2

                                                                                                            Maybe another way to think about this is “Can I not do FP in my language?”. Yes for JavaScript and Scala and Rust - you can write procedural code to your heart’s content in these languages, even if JavaScript gives you the tools to use functional abstractions and Scala and Rust actively encourage them. No for Haskell and Elm - there’s no way to write code that looks imperative in these langauges.

                                                                                                            1. 9

                                                                                                              No for Haskell and Elm - there’s no way to write code that looks imperative in these langauges.

                                                                                                              main = do
                                                                                                                putStrLn "What is your name?"
                                                                                                                name <- getStr
                                                                                                                putStrLn $ "Hello, " ++ name
                                                                                                              
                                                                                                              1. 5

                                                                                                                No for Haskell and Elm - there’s no way to write code that looks imperative in these langauges.

                                                                                                                What do you mean by “looks imperative”? Doing everything inside the IO monad is not much different from writing a program in an imperative language.

                                                                                                                1. 2

                                                                                                                  You mean StateT and IO. And then learning how to use both.

                                                                                                                2. 3

                                                                                                                  Writing Haskell at my day job, I’ve seen my fair share of Fortran written in it. The language is expressive enough to host any design pathology you throw at it. No language will save you from yourself.

                                                                                                                1. 9

                                                                                                                  Okay, sure. But does that really mean that every language would be better off with monads? From what I’ve seen, buying into monads can strew code with long, confusing type signatures and higher-order functions (e.g., flip, liftM) that leave the code more cluttered and removed from its writers’ intentions than the ad hoc solutions do.

                                                                                                                  Every approach to programming touts the pretty examples its creators thought up while it was being designed, but I believe the true test of such approaches is how ugly and unreadable they get at their worst. Learn Rust from scratch and write a basic program that does more than implement a basic calculator in the first week if you want to prove me wrong. You’ll run headlong into the type system before you know it.*

                                                                                                                  Now, given that many of the people who clicked through to this thread have probably bought into monads for long enough that they’ve gotten used to them, I’m probably going to get slaughtered. However, even if you are planning to downvote me and write a point-by-point rebuttal about how you had a dandy time with monads/Rust/etc., I hope you understand that I’m not saying that monads and the like don’t fix the problems they set out to fix. In fact, I’m not even saying that they don’t solve those problems well. I’m just saying that any attempt to create a system that abstracts over different types of code will inevitably restrain the programmer themselves, and this can often force them to write more of their code for the sake of the language than for the functionality of the program itself.

                                                                                                                  Replacing excessive boilerplate with excessive abstractions is jumping out of the frying pan and into the fire. It’s not the job of a good programming language to avoid boilerplate at all costs, but rather to keep the programmer focused on describing the actual behavior of their program; this precludes both boilerplate and abstractions when they are in excess. We must not let the problems we encounter most often while writing code induce us to implement solutions that create unavoidable barriers to entry as applications scale, especially not for what I think is otherwise some of the most innovative, pragmatic, and forward-thinking work in the field of programming languages today.

                                                                                                                  *This is something the Rust developers are aware of and actively working on, but that just gives you an idea of how far into development language designers can get before they realize they’ve created something that only the most patient, intelligent, and experienced developers can wrangle.

                                                                                                                  1. 11

                                                                                                                    The issue I’ve been noticing is that weaker versions of monads are making it into languages, like Kotlin and Swift which have this ? version of bind. So they have recognized that there is value in the abstraction but only offer the programmer a specialization. But this is a problem because this style of controlling sequencing opens up a lot of doors. For example, while everyone loves to talk about the Maybe monad, that’s actually so 5 years ago. I use the result or Either monad almost exclusively over Maybe. I want to be able to encode the error that happened so I can give the user a more valuable response than “something bad happened”. I use Ocaml and, while not as powerful as Haskell in this regard, I can just switch over to the result monad and get the same pretty code that I had with the Maybe monad (option in Ocaml). You can’t do that in Swift or Kotlin. I’m sure you could hack something in there but in Ocaml and Haskell it’s not a hack, it’s equally elegant no matter what monad you want to use.

                                                                                                                    For Ocaml, since we don’t have type classes, you explicitly pick the monad you want to use in a function so the function type doesn’t change but the implementation does. I think the functions I use the result monad on would be significantly harder to understand without being to redefine the sequencing operator so it is a net win.

                                                                                                                    1. 4

                                                                                                                      Having very little experience with monads and the likes, I believe the goal is to use monads as an abstraction over the lower-level elements in the language, like checking for null values.

                                                                                                                      For example, I’d argue that it’s more obvious what this block of code does:

                                                                                                                      do
                                                                                                                        a <- getData
                                                                                                                        b <- getMoreData a
                                                                                                                        c <- getMoreData b
                                                                                                                        d <- getEvenMoreData a c
                                                                                                                        print d
                                                                                                                      

                                                                                                                      which is print the value of d, compared to this:

                                                                                                                      var a = getData();
                                                                                                                      if (a != null) {
                                                                                                                        var b = getMoreData(a);
                                                                                                                        if (b != null) {
                                                                                                                           var c = getMoreData(b);
                                                                                                                           if (c != null) {
                                                                                                                              var d = getEvenMoreData(a, c)
                                                                                                                              if (d != null) {
                                                                                                                                print(d);
                                                                                                                              }
                                                                                                                           }
                                                                                                                        }
                                                                                                                      }
                                                                                                                      

                                                                                                                      which might print the value of d based on a number of conditions that need to happen at the same time (and we don’t even have the else branches shown which would make the code even more cluttered!). It’s also a lot easier to reason about the code that’s based on the usage of the Maybe monad, at least in my opinion.

                                                                                                                      Otherwise, I do agree with the point that, at the end of the day we do ship features, not monads.

                                                                                                                      1. 7

                                                                                                                        I don’t think that imperative code is a reasonable point of comparison (which is my biggest criticism of the OP). It’s seemingly trying to play on the fact that a bunch of nested conditionals is really bad and complicated—which I agree with—but I almost never write code like that in imperative languages. Instead, I’d use early returns:

                                                                                                                        var a = getData();
                                                                                                                        if (a == null) {
                                                                                                                          return null;
                                                                                                                        }
                                                                                                                        
                                                                                                                        var b = getMoreData(a);
                                                                                                                        if (b == null) {
                                                                                                                          return null;
                                                                                                                        }
                                                                                                                        
                                                                                                                        var c = getMoreData(b);
                                                                                                                        if (c == null) {
                                                                                                                          return null;
                                                                                                                        }
                                                                                                                        
                                                                                                                        var d = getEvenMoreData(a, c)
                                                                                                                        if (d == null) {
                                                                                                                          return null;
                                                                                                                        }
                                                                                                                        
                                                                                                                        print(d);
                                                                                                                        

                                                                                                                        I’m not saying this is better than the monadic approach, but it certainly offends me a lot less than nesting everything.

                                                                                                                        1. 4

                                                                                                                          Yeah, the nested example was a bit intellectually dishonest in that case. This is what Go opts for instead, and just avoids nesting for callbacks entirely due to co-routines.

                                                                                                                          It is still pretty verbose, but it is simple for everyone to understand.

                                                                                                                          1. 1

                                                                                                                            I see early return as another ad-hoc solution to that case. A priori I wouldn’t necessarily expect a language to have it.

                                                                                                                            1. 1

                                                                                                                              I think it’s reasonable to expect any imperative language to allow you to return a value as soon as you know what you’d like to return.

                                                                                                                        2. 4

                                                                                                                          I definitely agree with you more than I disagree with you. This is why I’m not a fan of the idea of adding monads to Rust, and why I like our hack for error handling. (Although it’s not clear that monads in the general case would work well in Rust anyway.)

                                                                                                                          For example, I rarely write (or need/want) supremely generic code. Adding a type parameter to a type is a big deal and needs to be managed with care. Most uses of generics in Rust I find myself using are things like “give me any argument that can be converted to a file path” or “give me any argument that can be converted into an iterator that yields strings.”

                                                                                                                          With that said, I haven’t seen much Rust code that elevates to the level of genericism that you see in languages like Haskell, and I generally consider that to be a good thing.

                                                                                                                          1. 6

                                                                                                                            This is why I’m not a fan of the idea of adding monads to Rust

                                                                                                                            What do you mean when you say this? Monads aren’t a language feature, per se, but they are the combination of a few laws. You can express monads in a lot of ways even if the language has no concept of them. The Future’s library I saw for Rust had a bunch of and_then combinators which were basically monadic. Ocaml doesn’t “have monads” but you can define an operator called bind or >>= and implement the rules. It happens that Ocaml has a fairly pleasant way to express that which makes working with them not-terrible but that has nothing to do with monads. So I can do monads in Ocaml but they aren’t a language feature.

                                                                                                                            1. 5

                                                                                                                              When I say “monads” I mean “the ability to write code that is generic over any monad.” (Which I gather is consistent with how the OP thinks of monads too.)

                                                                                                                              1. 2

                                                                                                                                You can implement them in almost anything, but I agree with this article that to have the usefulness they have in Haskell the language needs to: “1. Support ML-style function-fu (trivial currying, single namespace). 2. Have type classes. 3. Allow polymorphism on return types.” (The linked article is about why they haven’t caught on in Common Lisp, despite being implementable.)

                                                                                                                            2. 4

                                                                                                                              Every approach to programming touts the pretty examples its creators thought up while it was being designed, but I believe the true test of such approaches is how ugly and unreadable they get at their worst.

                                                                                                                              Funny, this is exactly why I think monads are necessary. The ad-hoc solutions are more readable solutions to those specific cases - async/await allows a more natural/friendly way of doing async than using Futures and general-purpose monad operations, ?.-style operators are a more natural/friendly way of doing early return than using Options and general-purpose monad operations. Even in a language that does have monads, the ad-hoc solutions are valuable sugar. But when you want to do something the language creator didn’t think of, if you don’t have general-purpose monads you’re stuffed.

                                                                                                                              I’m just saying that any attempt to create a system that abstracts over different types of code will inevitably restrain the programmer themselves, and this can often force them to write more of their code for the sake of the language than for the functionality of the program itself.

                                                                                                                              I understand that’s what you’re saying. I still think you’re wrong. The only things the abstraction restrains you from doing is the things that were wrong, and the wrongness will always bite you sooner or later. I’ve written plenty of law-breaking typeclass instances out of a sense of pragmatism and I’ve always come to regret it.

                                                                                                                              Replacing excessive boilerplate with excessive abstractions is jumping out of the frying pan and into the fire. It’s not the job of a good programming language to avoid boilerplate at all costs, but rather to keep the programmer focused on describing the actual behavior of their program; this precludes both boilerplate and abstractions when they are in excess.

                                                                                                                              I suspect you’re saying this because of experience with bad abstractions. Good abstractions are zero-overhead, or at least O(1) overhead: you learn them once and can benefit from them your whole career.

                                                                                                                              We must not let the problems we encounter most often while writing code induce us to implement solutions that create unavoidable barriers to entry as applications scale

                                                                                                                              That’s exactly what implementing only the ad-hoc solutions does. When applications scale is precisely when you need the ability to define your own custom monads and reuse generic functions with them.

                                                                                                                              1. 1

                                                                                                                                Even in a language that does have monads, the ad-hoc solutions are valuable sugar. But when you want to do something the language creator didn’t think of, if you don’t have general-purpose monads you’re stuffed.

                                                                                                                                So clearly there’s a tradeoff between flexibility and simplicity. But given the complex systems to which monads lend themselves, that flexibility won’t benefit most people.

                                                                                                                                The only things the abstraction restrains you from doing is the things that were wrong, and the wrongness will always bite you sooner or later.

                                                                                                                                The abstraction may prevent you from doing things wrong, but you’ll never do things right if you can’t wrap your head around it.

                                                                                                                                I suspect you’re saying this because of experience with bad abstractions. Good abstractions are zero-overhead, or at least O(1) overhead: you learn them once and can benefit from them your whole career.

                                                                                                                                I was referring to cognitive, not computational, overhead. Low computational overhead; high cognitive overhead. (And by the way, even the best abstractions can leak.)

                                                                                                                                We must not let the problems we encounter most often while writing code induce us to implement solutions that create unavoidable barriers to entry as applications scale.

                                                                                                                                That’s exactly what implementing only the ad-hoc solutions does. When applications scale is precisely when you need the ability to define your own custom monads and reuse generic functions with them.

                                                                                                                                The key phrase here is “barriers to entry”. A scaling application necessitates a simple, not a flexible, interface. Writing more “low-level” code is less work than writing less “high-level” code. You shouldn’t have to work around the interface in any application; all the more so for one that is scaling.

                                                                                                                                1. 2

                                                                                                                                  So clearly there’s a tradeoff between flexibility and simplicity.

                                                                                                                                  No, not at all. ?. or await implemented as a native language operation is no simpler than ?. or await implemented as a monad. Indeed using a monad makes it harder to overcomplicate it with special cases (e.g. Java’s Option would never have made the mistake of erroring on null if they’d implemented it in a “monad-first” way).

                                                                                                                                  given the complex systems to which monads lend themselves, that flexibility won’t benefit most people.

                                                                                                                                  If a user is happy using ?. and await and understands how they work, it makes no difference to them whether there’s an underlying abstraction that can be generalised or not. The flexibility can wait for them until they need it, and if they never get to the point of solving a problem so complex that they need that power then good for them.

                                                                                                                                  In practice, back when I worked in Java every nontrivial codebase ended up needing a bunch of annotations/reflection/agents that were always a disproportionate source of bugs - not because developers were stupid but because they needed to do something the language couldn’t, so they had to step outside the language. In a language with monads that wouldn’t have happened.

                                                                                                                                  I was referring to cognitive, not computational, overhead.

                                                                                                                                  So was I. Good abstractions save you cognition; instead of having to understand the particular sequencing rules for this new kind of context, you just know it’s a monad and can think about it as such.

                                                                                                                                  And by the way, even the best abstractions can leak.

                                                                                                                                  No, this is a myth, and in fact monads are a good example; they don’t leak.

                                                                                                                                  A scaling application necessitates a simple, not a flexible, interface.

                                                                                                                                  The two dovetail, and the monad interface is remarkably simple.

                                                                                                                                  Writing more “low-level” code is less work than writing less “high-level” code.

                                                                                                                                  Maybe on the initial write, but code is read more than it’s written, so the high-level approach pays dividends for maintainability. Sometimes I’ll write code out longhand to start with and then realise I can simplify it by using State or Writer or some such.

                                                                                                                                  You shouldn’t have to work around the interface in any application; all the more so for one that is scaling.

                                                                                                                                  100% agreed. Monad is the opposite of that though; it’s such an elegant and simple interface that it’s very easy to conform to. (Indeed one sometimes does so accidentally, and only notices that a given type forms a monad once it’s pointed out)

                                                                                                                                  1. 1

                                                                                                                                    So clearly there’s a tradeoff between flexibility and simplicity.

                                                                                                                                    No, not at all. ?. or await implemented as a native language operation is no simpler than ?. or await implemented as a monad. Indeed using a monad makes it harder to overcomplicate it with special cases (e.g. Java’s Option would never have made the mistake of erroring on null if they’d implemented it in a “monad-first” way).

                                                                                                                                    A scaling application necessitates a simple, not a flexible, interface.

                                                                                                                                    The two dovetail, and the monad interface is remarkably simple.

                                                                                                                                    We have different understandings of “simplicity”. I argue that having monads be deeply ingrained in a language’s design can actually make things more complicated. It does matter whether there’s an underlying abstraction, because that abstraction will have to be propagated to all dependent code.

                                                                                                                                    Sidenote: I’m not aware of any monadic implementations of ?. and await and would love to see them! I need to do more research on this front.

                                                                                                                                    I was referring to cognitive, not computational, overhead.

                                                                                                                                    So was I. Good abstractions save you cognition; instead of having to understand the particular sequencing rules for this new kind of context, you just know it’s a monad and can think about it as such.

                                                                                                                                    It is pattern recognition, not inbuilt abstraction, that saves cognitive waste. Abstractions are a good learning aid, but nothing need be forced into the language itself in order to make this learning happen. All the foundational precepts of functional programming can be implemented in straight-up C.

                                                                                                                                    And by the way, even the best abstractions can leak.

                                                                                                                                    No, this is a myth, and in fact monads are a good example; they don’t leak.

                                                                                                                                    In general, one shouldn’t get too comfortable with liberal use of abstraction.

                                                                                                                                    Writing more “low-level” code is less work than writing less “high-level” code.

                                                                                                                                    Maybe on the initial write, but code is read more than it’s written, so the high-level approach pays dividends for maintainability. Sometimes I’ll write code out longhand to start with and then realise I can simplify it by using State or Writer or some such.

                                                                                                                                    You shouldn’t have to work around the interface in any application; all the more so for one that is scaling.

                                                                                                                                    100% agreed. Monad is the opposite of that though; it’s such an elegant and simple interface that it’s very easy to conform to. (Indeed one sometimes does so accidentally, and only notices that a given type forms a monad once it’s pointed out)

                                                                                                                                    Again, committing to an abstraction is a decision that mustn’t be taken lightly. Monad is an elegant and simple mathematical notion; implementation is inevitably hairier. That’s not to say OO is any better with respect to implementation of theory, just that no abstraction is perfect in practice.

                                                                                                                              2. 4

                                                                                                                                liftM et al are usually code smell, but they’re usually less obnoxious than the stuff I end up doing without monads, like checking for error codes or null pointers after every function call, or using .then() or whatever if I’m using some hip java(script) framework that emulates the Either or Maybe monad.

                                                                                                                                You can usually get rid of them as well, if you use MTL-style monad transformers. A lot of libraries define things in terms of MonadState, MonadIO, etc. constraints so you don’t ever have to call lift<whatever>. I don’t actually remember the last time I used a lift function besides liftIO, which is used for running an arbitrary IO action inside some arbitrary IO-capable monad.

                                                                                                                                In good monadic code, you stick all the “lift”s and “flip”s and stuff in some file that handles the low-level behavior of your monad, and you can do a really good job of making the “business logic” or whatever you want to call it free of clutter.

                                                                                                                                1. 1

                                                                                                                                  In good monadic code, you stick all the “lift”s and “flip”s and stuff in some file that handles the low-level behavior of your monad, and you can do a really good job of making the “business logic” or whatever you want to call it free of clutter.

                                                                                                                                  But isn’t that just replacing one form of “low-level” with another? I thought the entire point of monads was to absolve the developer from having to do things the tedious, “low-level” way in the first place; after all, they are a “high-level” construct.

                                                                                                                                  1. 1

                                                                                                                                    The difference is that the join between the low level and high level is more continuous. Writing code that works with a State monad and writing code that works with a hidden variable looks very similar, and in both cases you can pretty easily understand what’s going on at the low level or at the high level. But the monad makes it much clearer how the high-level sequencing interacts with the low-level variable manipulation, and you can easily tell how changing one will affect the other.

                                                                                                                                    1. 1

                                                                                                                                      …the monad makes it much clearer…

                                                                                                                                      Whose job is it to make code clear and concise?

                                                                                                                                      As we all know, there’s only so much automated systems can do before they’re out of their depth. Trust me, I’d love to wholeheartedly commit to monads as much as the next guy, but their simplicity comes at the cost of long-term ease of use.

                                                                                                                                      1. 1

                                                                                                                                        It’s also really nice in the sense that how the hidden variable can change is consistent. There is only one bind and return in there and the distinction between what is done and performing it in the monad is clear. In ad-hoc solutions, anything can happen anywhere. So even the nastiest monadic code is significantly more “learnable”, IME, than the nastiest imperative code because one still is constrained on where the nastiness can happen.

                                                                                                                                  2. 3

                                                                                                                                    But does that really mean that every language would be better off with monads?

                                                                                                                                    I think this question is meaningless since every Turing-complete language already has monads. Don’t believe me? Monads in C: https://gist.github.com/enobayram/4c9ba6e7723a1622530e56884fc97357

                                                                                                                                    The only thing that makes monads special in Haskell is the do notation, which is a syntactic sugar for monads. without it, the example would look like the following in plain Haskell:

                                                                                                                                    program =
                                                                                                                                      getData             >>= \a ->
                                                                                                                                      getMoreData a       >>= \b ->
                                                                                                                                      getMoreData b       >>= \c ->
                                                                                                                                      getEvenMoreData a c >>= \d ->
                                                                                                                                      print d
                                                                                                                                    

                                                                                                                                    Which is probably better than most other languages.

                                                                                                                                    So the question should be, “should every language have an expressive enough type system to express monads and should it have a flexible enough syntax that monadic code doesn’t look terrible in it?”

                                                                                                                                    1. 3

                                                                                                                                      How would you implement more interesting monads, say, streams and delimited continuations, in C?

                                                                                                                                      1. 3

                                                                                                                                        The procedure is quite simple; whenever you see a type class constraint, replace it with an explicit argument accepting a method dictionary. Whenever you need to express polymorphism, replace it with a void * and hope the user won’t mess up the arguments. If you were serious about this, you’d also make all functions accept an extra void * that carries “user data”, so that you can pass around closures for your functions. You’d also implement some form of garbage collection/some architecture to allow for managing lifetimes. In the end, monads would be barely recognizable, but they would still be there, I mean, you could write a function that works on all monads.

                                                                                                                                        Obviously, monads will also be much harder to use without lambdas, so you’d have to define a lot of top level functions that are called step_1_of_x, but my point isn’t to demonstrate monads are a good way to program in C anyway.

                                                                                                                                        1. 3

                                                                                                                                          I see, you’re looking at things operationally. Of course, any sufficiently powerful language can emulate the mechanics of type class dispatch (or any other implementable language feature).

                                                                                                                                          But, for those of us who care about abstractions (like monads or any other algebraic structure), that is kind of missing the point. The point to using abstractions is to have a clearly defined boundary between implementors and users, so that users don’t need to worry about implementation specifics, and implementors don’t need to worry about users’ concrete use cases. The only shared concern between implementors and users should be the abstraction’s semantics. This, I’m afraid, you can’t easily replicate in C.

                                                                                                                                          1. 1

                                                                                                                                            Yeah, it does degenerate to untyped void * goo when you attempt this in C, but it’s still architecturally the same. You can still express monads in the category of monads. If you were an alien with a flawless mind, you could just as easily express and use your abstractions in C as you would in Haskell.

                                                                                                                                            On a more practical note, you can actually do useful stuff with monads using C++. C++‘s templates are flexible enough to express (something like) typeclass dispatch, and in some ways you can even go beyond Haskell, since you have a tight control over what gets statically specialized. You could, for instance, have deep monad transformer stacks that get compiled down to overhead-free assembly. I’m not saying you should do that, but thinking “C++ doesn’t have monads” will unnecessarily narrow your vision.

                                                                                                                                            1. 2

                                                                                                                                              you have a tight control over what gets statically specialized

                                                                                                                                              It’s not clear to me whether you are talking about the fact templates are instantiated at compile time or the fact templates can be specialized, but in either case you lose expressiveness.

                                                                                                                                              • Compile-time instantiation prevents you from having polymorphic recursion (e.g., a Tree<T> containing subtrees of type Tree<List<T>>) or first-class existential quantification (e.g., Java’s infamous wildcards: List<? extends Animal>, although other languages do this more sensibly).

                                                                                                                                              • Template specialization reduces the amount of static analysis that can be carried out in a modular fashion, because, well, templates can be specialized anytime, anywhere. With bona fide parametric polymorphism, you can say “my generic definition is guaranteed to have such and such properties”. With templates, you can only say “assuming nobody else specializes my templates or anything else they depend on in ways that contradict my wishes, the resulting specialized code will have such and such properties”. Assuming nobody will specialize your templates is a very big if.

                                                                                                                                              1. 2

                                                                                                                                                It’s not clear to me whether you are talking about the fact templates are instantiated at compile time…

                                                                                                                                                Yeah, that’s what I meant, but I used the word “specialize” because that’s what haskell uses for something similar to what C++ calls template instantiation. So, in haskell if you have a function f.x a -> [a], you can specialize it for Int -> [Int] with compiler pragmas, and GHC will see it as a possible optimization. In theory this breaks parametricity, since you can easily violate it this way, but you have to be very careful with those pragmas. Which brings us to your second point, in C++, you’re basically always in this “you have to be careful” mode. So, please, for the sake of this discussion forget about how much the compiler helps you avoid shooting yourself in the foot, we’re talking about what can be expressed.

                                                                                                                                                So, for instance, if you have a template in C++, and you’re using it in contexts where all of its specializations need to respect parametricity, you write a comment at the top of its declaration

                                                                                                                                                /* If you intend to specialize this template, please respect parametricity, 
                                                                                                                                                 * if you don't know what it is, go func* yourself. (* educate yourself in the 
                                                                                                                                                 * ways of functional programming) 
                                                                                                                                                 */
                                                                                                                                                

                                                                                                                                                Coming back to your first point, you can very well express polymorphic recursion with C++, if you declare (via comments) List<T> to be parametric, so you can use List<shared_ptr<void *>> to stand for an existential a. You can even wrap this in a type-safe manner within the context of Tree<T>, so, you can for instance define a type-safe Traversible instance for Tree<T>. I would like to implement this for you, but I doubt I’ll find the time to do so anytime soon.

                                                                                                                                      2. 2

                                                                                                                                        So the question should be, “should every language have an expressive enough type system to express monads and should it have a flexible enough syntax that monadic code doesn’t look terrible in it?”

                                                                                                                                        You act as though there aren’t far-reaching consequences within a codebase for initial committal to a monadic interface. Different interfaces are best suited to different applications.

                                                                                                                                        1. 1

                                                                                                                                          I don’t see where you got the impression that there aren’t far-reaching consequences. Monads are too powerful an interface to expose to the library user under most circumstances, and the art of software architecture is to find the balance between the interface consumer and implementer.

                                                                                                                                          The point still stands though, if your language’s type system and syntax isn’t powerful enough to make monads practical, the chances are you’ll have trouble expressing profunctors from your application domain’s category to the category of endofunctors in your programming language (or whatever abstraction it takes to express your architecture)…

                                                                                                                                          1. 1

                                                                                                                                            You act as though there aren’t far-reaching consequences…

                                                                                                                                            I don’t see where you got the impression that there aren’t far-reaching consequences.

                                                                                                                                            I was implying there are far-reaching consequences.

                                                                                                                                            1. 1

                                                                                                                                              Sorry, I meant where you got the impression that I implied there weren’t any.

                                                                                                                                              1. 1

                                                                                                                                                Oh okay. In that case I think we agree 100% 😁

                                                                                                                                                Though I didn’t fully understand this part, and would like to:

                                                                                                                                                …you’ll have trouble expressing profunctors from your application domain’s category to the category of endofunctors in your programming language…

                                                                                                                                                1. 2

                                                                                                                                                  I strongly believe that beneath the hot dark crust of functional programming, there’s a pressure buildup of what people might one day call “categorical programming” once it erupts. When the dust settles, people will probably call Conal Eliott’s Compiling to Categories work one of the early milestones. You can already see the early signs of this upcoming paradigm applied to real world problems in the Haskell community.

                                                                                                                                                  The part you haven’t understood may or may not be meaningful for a real world application domain, but the point is, you can model the relationships in your domain abstractly as a number of categories and functors between them a la OLOGS, then your software architecture can be reduced to functors from those categories to some categories you construct using your programming language(s) (plural, as in for example, your back-end, database and front-end might all be part of the model, so you have your entire system along with the users and the world around it modelled). These are all big words, but the surprising thing is some of that mumbo-jumbo is directly expressible in Haskell. We’re actually using some of this stuff at my day job, and we intend to write about it when we have the time.

                                                                                                                                                  1. 1

                                                                                                                                                    The part you haven’t understood may or may not be meaningful for a real world application domain…

                                                                                                                                                    I sincerely appreciate your saying this. I think the middle ground between our respective positions could be stated in short as follows: “The tenets of FP have amazing application-dependent benefits.”

                                                                                                                                                    When the dust settles, people will probably call Conal Eliott’s Compiling to Categories work one of the early milestones.

                                                                                                                                                    [If] you can model the relationships in your domain abstractly as a number of categories and functors between them a la OLOGS, then your software architecture can be reduced to functors from those categories to some categories you construct using your programming language(s)…

                                                                                                                                                    This all sounds fascinating. Do you know of any interesting papers / talks / blog posts that further what Conal and Spivak & Kent discussed, i.e., preëmpt a move toward real-world application of o-logs to software development?

                                                                                                                                        2. 2

                                                                                                                                          You could say that about every language feature - it’s always possible to greenspun a given feature into a language that doesn’t have it. I think you can draw a line between languages that let you implement useful monad-generic code /in the language/ and languages that don’t.

                                                                                                                                          1. 3

                                                                                                                                            I understand what you mean, but I honestly think it doesn’t apply to monads. do notation is a language feature, but “monad” is a concept from abstract math. C is an extreme example, but you could easily find C++, Java or Python projects that would greatly benefit from expressing some core architectural elements through monads.

                                                                                                                                            1. 2

                                                                                                                                              Monads are a mathematical concept defined in terms of arrows and objects, sure, but the usual sense of “monad” in a programming context comes from identifying those with functions and types, and you can only really say that you have monads “in” the language if you can use them with ordinary functions and types in the language. You can’t really write a monad-generic function in Java because the language won’t let you write the type signature that function should have, and while you technically can work with monads in Python, not having a type checker means you lose most of the benefits. (AIUI this is substantially true in C++ as well; C++ does have type checking but only after template expansion, which makes development of generic code difficult).

                                                                                                                                        3. 2

                                                                                                                                          It seems to me that the problems described in this article are more about syntax than semantics. A good macro system could probably bring the same expressivity benefits as monads in this case.

                                                                                                                                          1. 4

                                                                                                                                            Well, macros can do anything; almost any programming language can be viewed as a named, standardized bundle of macros. I think there’s a lot of value in standardizing on the concept of a monad and a single syntax for it; that allows for reuse both at the syntactic pattern level and for library functions like whileM described above.

                                                                                                                                        1. 0

                                                                                                                                          If you are doing something somebody will pay for, then that means that whatever you are doing is good for that somebody, otherwise why would he pay for it. So the more money you make, the more meaningful your activity is.

                                                                                                                                          So the more money you make, the more meaningful your life is. Don’t trust your brain internal measure of meaningfulness, it was evolved when we were hunter-gatherers and it is incapable of correctly measuring meaningfulness of your activities in the modern world. Trust your bank accounts or crypto-wallets.

                                                                                                                                          Some people think that giving food to random starving children around the world is ‘meaningful’, but it’s not. You are just doing genetic socialism and propping up bad reproductive strategies that are proven to not work. In continuing to propagate the information embedded in the DNA of those starving children, you are actually allowing the bad strategy to be more widely implemented, and thus making the problem you are trying to solve worse. And what does your bank account say? It says you have less money. Brain: 0, Bank account: 1

                                                                                                                                          But that’s just one way of defining ‘meaningful’.

                                                                                                                                          In reality life in inherently meaningless. You have been lucky (or unlucky) to be born into a time and place of plenty that allows you to ask yourself a question with no answer. If you had been born in a pre-industrial farming community, then you only care about surviving the next winter. You have no time for such pointless thought processes as asking yourself what is a ‘meaningful’ life.

                                                                                                                                          You can try reading philosophies but those are just the rambling non-answers of those who came before you who asked the same question.

                                                                                                                                          You are just a robot who was built to replicate information embedded in DNA. You by accident was given a nervous system capable of asking questions like “What is the meaning of life?” and “How do I live a meaningful life?”. Those questions are just syntactically correct enough to convince you that they are meaningful questions, but they are not.

                                                                                                                                          Don’t worry though, sooner or later your children will come home from school and your neural “let’s make sure the children are well so they will propagate my genes” system will fire and you will forget about all these silly questions.

                                                                                                                                          Life is without meaning, and any attempt to find one is just your mind incapable of accepting the fact that you are mortal and small, and wanting to be large and forever.

                                                                                                                                          1. 10

                                                                                                                                            This perspective is vulgar:

                                                                                                                                            Some people think that giving food to random starving children around the world is ‘meaningful’, but it’s not. You are just doing genetic socialism and propping up bad reproductive strategies that are proven to not work.

                                                                                                                                            Social Darwinism is a sickness.

                                                                                                                                            1. -3

                                                                                                                                              Social Darwinism is a sickness.

                                                                                                                                              That is strange, when it is essentially impossible for natural selection to not apply to humans. If an all pervasive and always applicable by definition effect is a sickness, then the word sickness has such weak boundaries on its definition as to render it pointless as a word.

                                                                                                                                              1. 3

                                                                                                                                                What you might call a “sickness” is the tendency to over-simplify important and complex issues in the real world into a few convenient logical predicates and them arrive at serious conclusions, which if taken seriously, would result in actual people actually suffering.

                                                                                                                                                I also once were a robot like you, but then I realized that the real world is many orders of magnitude orders of magnitude more complicated than I could ever hope to analyze or even observe, so I’ve learned to trust my hard-evolved feelings to take care of the complexity, and I only use my logic to choose between the alternatives that feel right relying on the predicates that feel right. As a matter of fact, anything that involves people suffering has a very little chance of feeling right.

                                                                                                                                                1. 0

                                                                                                                                                  Does it feel right to chase away a predator in order to save a cute prey?

                                                                                                                                                  1. 1

                                                                                                                                                    If I witnessed a wolf chasing a cute rabbit, I’d probably save the rabbit if I had the means. But if I had the means to save all rabbits from being eaten by all predators, I’d definitely not do it since it’d have a terrible impact on the environment. But then, if you came to me and convinced me, through logical arguments, that saving that one rabbit from that wolf will have a significant negative impact on anything I care about, my feelings about the former issue could change and I could let the wolf eat the rabbit.

                                                                                                                                                    Now, hypotheticals aside, there’s no universe in which I could be convinced that children dying from starvation could be the solution to anything. Even if you made very good arguments about why them not dying from starvation would cause something very bad, I’d still try infinitely many ways to find other means of avoiding that very bad thing. But children dying from starvation is off the table. In general, convincing me to support the suffering of people would take far more that some juvenile arguments coming from an extremely simplified and naive interpretation of the very complex phenomenon that is evolution.

                                                                                                                                                    1. 1

                                                                                                                                                      Why is the wolf starving to death preferable to the rabbit being killed by the wolf?

                                                                                                                                                      1. 2

                                                                                                                                                        You don’t get the point, I’m not pushing that wolf to starvation by stopping it from eating that rabbit. It has a whole forest to hunt. If the circumstances were such that me saving that rabbit means certain starvation for that wolf, I’d feel differently about the issue. To save you the trouble, you really should stop wasting your energy trying to come up with simplified dilemmas to draw logical arguments about complicated situations. And that’s actually my whole point. Logic is an illusion, it’s a tool our pathetic brains use to overcome our inability to conceive even a tiny fraction of the world around us.

                                                                                                                                                        1. 1

                                                                                                                                                          Logic is an illusion,

                                                                                                                                                          well if you reject logic, then what tool do I have to argue against you? My feelings?

                                                                                                                                                    2. 1

                                                                                                                                                      Since we’re really talking in metaphor, I wouldn’t just chase it away, I’d kill it. You have failed to understand the role and nature of social interaction. You will be discarded, just as you have discarded others unless you change.

                                                                                                                                                      1. -1

                                                                                                                                                        So it’s okay for predator to starve to death because they are not cute?

                                                                                                                                                        1. 2

                                                                                                                                                          Survival of the cutest my friend.

                                                                                                                                                  2. 2

                                                                                                                                                    It’s funny given your ideas on genetics if you were right you’d be the defective one because failing to realize social implications is a pretty obviously material defect. Thank goodness you’re wrong because you’re totally uninformed about modern science. You can improve!

                                                                                                                                                2. 9

                                                                                                                                                  I used to engage in this sort of nihilism and it was a sad and depressing way to live, so I sympathise, fellow robot. That’s the trouble with too much logic and not enough context (indeed, how robotic!). Once I learned that my conclusions hinged on blatantly false unexamined assumptions, I was able to shift my views to something more constructive.

                                                                                                                                                  Having children doesn’t stop questions about meaning, by the way.

                                                                                                                                                  1. 1

                                                                                                                                                    Once I learned that my conclusions hinged on blatantly false unexamined assumptions,

                                                                                                                                                    Now if only you would be so kind as to state those false assumptions and why they are false, I would be enlightened.

                                                                                                                                                    But you chose not to.

                                                                                                                                                    1. 6

                                                                                                                                                      I thought it rather unlikely that you would be enlightened by a stranger on the internet. It was far more likely to result in a pointless argument.

                                                                                                                                                      Anyway, for me there were two primary false assumptions:

                                                                                                                                                      • That it’s all about me - my individual fulfilment, freedom etc. This is plainly against where the human evolutionary path led us - we’re a social animal, not a solitary one. Caring about others is essential to us.
                                                                                                                                                      • That the meaning is to be found somehow. Clearly, the universe just is, as you also point out, so there’s nothing to be found, but that’s beside the point because we have the capacity to make up the meaning. When we have this capacity and the alternatives are so depressing, what’s the point of refusing to make something up?

                                                                                                                                                      Once I got rid of these assumptions, it turned out that contributing to the sustainable future of the human race or ensuring that I personally see a continuation of my family is actually pretty meaningful if I let it be meaningful. Even better, it aligns well with what it means to be a human robot, as you suggested regarding DNA propagation.

                                                                                                                                                  2. 4

                                                                                                                                                    You are just doing genetic socialism and propping up bad reproductive strategies that are proven to not work.

                                                                                                                                                    There’s something odd about someone calling themselves libertarian but espousing racial collectivism. Or is your username meant to be ironic or something?

                                                                                                                                                    Life is without meaning, and any attempt to find one is just your mind incapable of accepting the fact that you are mortal and small, and wanting to be large and forever.

                                                                                                                                                    This may be true.

                                                                                                                                                    Don’t worry though, sooner or later your children will come home from school and your neural “let’s make sure the children are well so they will propagate my genes” system will fire and you will forget about all these silly questions.

                                                                                                                                                    This is completely false.

                                                                                                                                                    1. 2

                                                                                                                                                      They aren’t a libertarian just like the nazis weren’t national socialists. It’s just a way for them to spout bullshit and hope naive libertarians will buy in to it without questioning the line of reasoning. While I do have reservations about libertarian ideology, this person is just a classist racist bigot and frankly has no place on lobsters. I’ve yet to see anything they’ve spouted to actually be libertarian anyway.

                                                                                                                                                      1. -1

                                                                                                                                                        There’s something odd about someone calling themselves libertarian but espousing racial collectivism.

                                                                                                                                                        You are clearly projecting here because there’s nothing racial about my comments.

                                                                                                                                                        1. 4

                                                                                                                                                          You claim that starving children are starving because they are genetically inferior.

                                                                                                                                                          1. 6

                                                                                                                                                            This user probably isn’t worth replying to. Expect to be sealioned to hell.

                                                                                                                                                            1. -3

                                                                                                                                                              I never said they are inferior, but that the reproductive strategy embedded within their DNA has proven to fail by the very fact that they are starving.

                                                                                                                                                              You really are projecting.

                                                                                                                                                              1. 10

                                                                                                                                                                I intended to stay out of this but there’s nothing genetic about any of:

                                                                                                                                                                • being born into an unstable, grossly unfair, or failed nation-state.
                                                                                                                                                                • experiencing a famine or a natural disaster.
                                                                                                                                                                • being surrounded by a civil war.
                                                                                                                                                                • having your ethnic group despised and persecuted.
                                                                                                                                                                • not acquiring a useful education when basic needs are unmet.
                                                                                                                                                                • having children when birth control is unavailable or proscribed.
                                                                                                                                                                • being unable to emigrate or prevented from emigrating.

                                                                                                                                                                These are exactly the sorts of situations that produce the kind of human suffering that people respond to with generosity. You might argue that in some cases aid perversely subsidizes and supports corrupt regimes and allows the situations to fester that prevent these people from having a reasonable life longer than if there were no aid and the society/state collapsed (with an even greater degree of short-term misery) but it’s not “embedded within their DNA”.

                                                                                                                                                                Restating OP’s argument, “Fuck them, they’re unlucky. Let them die out of my sight and don’t you help them because they’re undeserving by virtue of being unlucky. Now go tend to your lucky off-spring.”

                                                                                                                                                            2. 2

                                                                                                                                                              Said the horrible racist. Get banned already please.

                                                                                                                                                          2. 2

                                                                                                                                                            Your ideas around genetics are outdated and wrong.

                                                                                                                                                          1. [Comment removed by author]

                                                                                                                                                            1. 1

                                                                                                                                                              Just to drill down here; so there is no type of application you feel can benefit from spa approach? For example the “one page with many possible views” like an email client? You are saying the best way to view emails in such an app is on page per email, in your estimation?

                                                                                                                                                              1. 2

                                                                                                                                                                If it doesn’t run nicely without JavaScript, it doesn’t belong on the Web. It’s like trying to write a book with oil paint. Use the right medium.

                                                                                                                                                                1. 2

                                                                                                                                                                  And how do you back that claim?

                                                                                                                                                                  1. 1

                                                                                                                                                                    Have you been on the Internet lately? It’s a wasteland. Our computers have got much faster, but the Web has only got slower and more bloated. This is why.

                                                                                                                                                                    1. 1

                                                                                                                                                                      If you see this solely from the performance or accessibility point of view, then yes, the web as it is today is bloated.

                                                                                                                                                                      On the other end, if you see this in term of evolution (what you can do nowadays on the web) then I don’t mind.

                                                                                                                                                                  2. 1

                                                                                                                                                                    I’m pretty sad to disagree with you on this one.

                                                                                                                                                                    The web solves distribution in a way that no other platform does. If it’s for-profit, the returns are much better when you ‘write a book with oil paint’ instead of trying to convince people to download and install software (see eg patio11’s writeup of doing SAAS vs a native app).

                                                                                                                                                                    It certainly sucks that there’s no better way.