Threads for lithp

    1. 10

      Lithp is an implementation of an interpreter for the original LISP

      Genius name

      1. 2

        Agreed!

    2. 2

      I’m noticing I don’t have much sympathy for this view. I have plenty of empathy, it sounds very frustrating to have a tool taken away from you when you expected it would be around forever and made plans assuming it would be around forever!

      To the extent that someone needs codex in order to reproduce results, to the extent that their results fail to generalize beyond codex, it sounds a lot like they were studying codex, they were not studying llms. Now that codex no longer exists there is no longer a need to study codex, so it’s not a great loss that this work can no longer be reproduced.

      Or am I missing something?

      1. 1

        What you are missing is that contrary to what OpenAI says, Codex can’t be replaced by GPT-3.5 or GPT-4 for some research. Specifically, all GPT-3.5 and GPT-4 models are post-trained by InstructGPT-like post training. To study the effect of post training, you need the control without post training. What OpenAI did is to stop providing any access to its models without post training.

    3. 4

      This is fairly incredible, so much work has been done that it feels like peering into an alternate reality. What this video demonstrates may seem straightforward but getting there involved ripping out much of how linux works and then writing an environment from scratch:

      • The entire system uses what seems like a novelish programming paradigm (erlang meets tuplespaces meets E?): https://synit.org/book/syndicated-actor-model.html
        • There’s even a bit of dataflow thrown in, as both tuple retractions and tuple subscriptions are just additional kinds of events actors can react to.
      • This model is implemented at the OS level with a custom init, think systemd&d-bus rolled together: https://synit.org/book/operation/index.html#sbinsynit-pid1
      • Together, this means you can configure and administer your system by manipulating the root tuple space.
      • Data is transferred using Preserves, an apparently novel data model & serialization format; think JSON with some additional properties: https://preserves.dev/ It comes with multiple canonical serializations as well as implementations in several languages.
      • The underlying actor model has what looks like decent in multiple languages: https://syndicate-lang.org/code/repos/
      • It’s still very rough around the edges but just check out this glossary, quite a lot of thought and work has happened: https://synit.org/book/glossary.html#system-layer

      And somehow all of this also actually works? This is a video with actual hardware running a smalltalk image inside this contraption and it reacts when the filesystem is changed, just as it should.

      1. 1

        Thank you for the kind words!

    4. 3

      Ladder logic is an esoteric family of languages which doesn’t quite fit into any other language here. Ladder logic allows you to specify state machines and all the transitions to other states but in a way so different from ML that it don’t really belong in the ML family.

    5. 11

      Make is the Prolog language most journeyman programmers know.

      Weird to call the Smalltalk group “Self”. That’d be like calling the Algol group C or the ML group Haskell.

      I would add assembly as an 8th kind.

      1. 9

        I chose Self because I regard classes as vestigial. Prototype based systems are more in your face about making you give up on patterns from other families, so I chose it as the type specimen.

      2. 5

        SQL also belongs to the Prolog family, though you’re right that Make is closer than SQL is.

        What makes you say assembly doesn’t belong in the ALGOL bucket? asm and the other ALGOLs are imperative: there’s an instruction pointer which runs commands in sequence and jumps around. The instruction pointer has a lot more freedom to jump around in asm than it does in most other ALGOL languages but the fundamentals are identical.

        1. 2

          Right, but Assembler is both highly dependent on what system you are using, and also on the whole only has one or two ideas that also happened to be in ALGOL. Both were influenced by how computers used to be built, which was a memory drum with a current position.

        2. 1

          ALGOL introduced structured programming, which is not something assembly lends itself to.

    6. 86

      The article adequately picks up a phenomenon that I’ve been witnessing for years now: Second-hand offendedness.

      To explain this term, if it isn’t already clear: Certain people go out, identify and criticise something as possibly offensive to a group of people they are not a part of. The git-master-discussion, which the article picks up, is one example, but another one is the criticism of non-natives dressing up as Native Americans for carnival (criticised as “cultural appropriation”).

      Never in those cases do I hear voices from the actually affected groups. I’ve never heard a tribe complaining about out-groupers dressing up in tribal costumes. To the contrary and more sensefully, some support and are content with the fact that their customs are celebrated and brought into the world this way. Slavery obviously is not to be celebrated and must be opposed (it still exists to this day on a massive scale!), however, I find it ridiculous that the word “master”, which is a perfectly normal word in the English language, is being reduced to its one negative use in history and effectively demanded by those second-hand offended to be wiped from memory (“1984” comes to mind, which describes dramatically similar proceedings to censor the language from “dangerous” words). In truth, there is no good synonymous replacement for “master”.

      Now one might say that these groups are too vulnerable and that we need to speak up for them! However, maybe we should instead just listen better and stop shouting into the void, silencing those voices that really matter in such debates (namely those that are affected). I even find it very disrespectful and belittling towards those groups that some people think they can speak for them.

      I could go on, but the point is this: Around 40 million people (Global Slavery Index, 2018) are currently living in slavery, and banning “master” and “slave” from our vocabulary won’t change one thing about it. It won’t benefit those slaves, but only bring good feelings to those who, sitting from the comfort of their own homes in a first-world-country, voice their opinions on social networks and other echo chambers to signal their virtue, which doesn’t take much time or effort.

      Of course, GitHub is free to do as it pleases, but removing “offensive” words like “master” and “slave” from our language does not create a save space, but only makes it harder to adress and talk about real and current problems, i.e. contemporary slavery.

      All in all, I find this a really sad state of affairs, and those who practice second-hand offendedness for social confirmation and self-indulgence should be ashamed of themselves.

      1. 39

        However, maybe we should instead just listen better and stop shouting into the void, silencing those voices that really matter in such debates (namely those that are affected). I even find it very disrespectful and belittling towards those groups that some people think they can speak for them.

        Can vouch, white people shouted over me when I told them it was weird and creepy that the first thought that came to their mind seeing the word “master” was “the transatlantic slave trade”.

        1. 7

          Why is it “weird and creepy” that there is a prominent association between the word “master” and one of the largest components of North American history? That seems like a natural thing.

          1. 35

            The word master applied to a lot of contexts outside of slavery and dates back to Latin. For teachers, heads of household, shipowners, and within artisan groups (apprentice, journeyman, master).

            1. 10

              The word slave applied to contexts outside of slavery as well, and dates back to Late Latin and Byzantine Greek … it originally meant “speaker of the language of Slavonia”. But all of that’s irrelevant because problematic words aren’t problematic because of their etymology or manifold definitions, but the one definition from which they derive their meaning. The word master as used in version control never held any relationship to any of those other associations, though. It was explicitly taken from master / slave semantics, borrowed directly from chattel slavery, and used to describe a situation in which a subservient thing must exactly respond to / reproduce a controlling thing’s commands / actions.

              I’m not sure that the community needs to abandon a term that has a problematic history – the OP makes a good point that those actually in a position to be offended should probably be consulted before a bunch of rich white folk cure premature offense on their behalf – but I definitely don’t think we should work to distract from the fact that the origins of the terminology are problematic.

              Master mold, master switch, replication master, glass master … intellectual honesty says they’re problematic in the same way that master race is, the question is are they far enough removed from the reality that they inherit their root meaning from that they’ve be effectively re-coined. That’s up to the people actually harmed by slavery to decide … but let’s not literally and figuratively white wash the words … SVN’s slaves were not pupils, wives / children, sailing vessels, or less than completely skilled craftspeople.

              1. 3

                It was explicitly taken from master / slave semantics

                This connection seemed weak last time I saw it. At best one of the authors considering a name had this vaguely in mind.

                Edit: It occurs to me, as you point out, meanings shift. Most people using master branches don’t consider this a reference to chattel slavery.

                1. 4

                  Most people are wrong. The name in Git came from “master recording”, but that term takes its meaning directly from master / slave semantics… from wax cylinders to audio and video tape the master would spin, the slave(s) would spin, and the copy would be written from master to slave(s). The slaves have no will, doing precisely what the master tells them to do… I dunno how much time you’ve spent in video tape replication houses, but there’s a master deck and there’s a whole bunch of slave decks, all slaved to the VITC clock on the master… and all of this was common terminology long before version control came around.

                  There’s nothing particularly surprising about it being picked up as the terminology, and sure it’s far enough removed for most people not to think about the origins, but spend much time thinking about it and it’s a pretty regrettable choice.

                  And don’t even get me going on what happens when it comes time to deal with “male” and “female” plugs and sockets and people start arguing the inarguable.

                  1. 6

                    There’s something I don’t quite understand, why does it matter which meaning was intended? There seems to be a trivial distinction between the practice of human slavery, which is correctly understood to be morally indefensible, and the usage of the terminology of master-slave relationships. If you have master decks and slave decks doesn’t that accurately describe the nature of their relationship; what is regrettable about using those words?

                    1. 1

                      The latter is a product of the former; we can only blithely use terminology derived from atrocity by treating the atrocity as mundane.

                      I mean let’s extend that logic… what would be regrettable about using the term “Jew oven” if the words accurately described some process relationship? If there was some new algorithm that seemed to fit would there be anything regrettable about using an “asian massage parlor attack”?

                      Of course there would be. Nobody sufficiently close to an atrocity would think to name any mundane thing that just happened to have vaguely analogous dynamics after an atrocity still fresh in memory; to do so would be inhumanly cruel and, frankly, a pretty sure sign of a psychopath.

                      Well, when chattel slavery is happening today, and when there are millions of people today still very much impacted by the ripples rolling out from the chattel slavery of yesterday — the Atlantic slave trade is less than two generations from living memory — there’s something inhumanly cruel and psychopathic inherent in the fact we picked up the terminology to begin with.

                      Now, there’s some amount of time beyond which it’s okay to start using terms that have lost any obvious reference to the atrocity — there’s a point at which “Trojan horse” truly isn’t bothering any Trojans — but there’s definitely something regrettable before that unknown time has passed.

                      Especially if the people seeking to coin the term, and thereby dilute the atrocity, were or descend from the instigators of the atrocity.

                      1. 1

                        the Atlantic slave trade is less than two generations from living memory — there’s something inhumanly cruel and psychopathic inherent in the fact we picked up the terminology to begin with.

                        Calling an entire industry “inhumanly cruel and psychopathic” seems a bit much, no?

                        At any rate, you can reminisce over the past for a long time, but what’s done is done and no one directly involved is alive today. What matters now is the future. I think this was the point of this post: what really is the quality of lives of people alive today, and all of this seems kind of … fluff because I’m not seeing how this really improves the life of anyone.

            2. 3

              So… if, for example, you’re a White American person working at a company like GitHub and you’ve come to understand the large part of the American experience that is shaped by the history of slavery, it would be “weird and creepy” to associate the word master with that history because the word “master” is applied to shipowners and artisan groups too?

              1. 23

                One would assume that many people who work at large tech companies hold (or know someone who holds) Masters degrees.

                I would struggle to find someone who owned a slave (even though today there are more slaves than at any time in recorded human history).

                So, yeah, I think it’s weird.

                1. 4

                  even though today there are more slaves than at any time in recorded human history

                  … if you think in absolute numbers, utterly ignore proportion of population size, and considerably expand the definition beyond chattel slavery, maybe.

                  1. 2

                    Amusingly, if we expand it even further we will arrive at a place where pretty much every person can be considered a “slave”. As John Lennon put it, in the lyrics of ‘Working Class Hero’:

                    When they’ve tortured and scared you for twenty-odd years … Then they expect you to pick a career … When you can’t really function you’re so full of fear. (…). Keep you doped with religion and sex and TV … And you think you are so clever and classless and free … But you are still fucking peasants as far as I can see.

                    1. 3

                      And that watering down of words is precisely how we end up with today’s “wage slaves” thinking they have anything whatsoever in common with actual chattel slaves. Probably why it’s much easier to talk about reparations for those who were sold a false dream than it is to talk about reparations for those who were actually sold.

                      Hell of a song though. Shame Marilyn Manson went and ruined his cover.

                      1. 1

                        “wage slaves”

                        It is not a misnomer; though ‘modern-day serfdom’ is more accurate.

                        1. 4

                          They’re both absurd misnomers… an actual serf would think the modern variety an idiot king, for all the plenty they’re steeped in daily but fail to recognize, just as the chattel slave would look real hard for the scourge marks on today’s wage slave’s back before gawping at the unbearable ignorance of anyone having thought the idea remotely relative.

                          What we really need are new words to describe new realities.

                          1. 1

                            What we really need are new words to describe new realities.

                            There’s nothing wrong with “proletarian” - a person whose only worth is the labor they can produce.

                            1. 3

                              I mean other than some slightly problematic associations with totalitarian dictators, sure.

                              Thing is, proletarian describes a person who doesn’t really exist in modern western, post-industrial, post-information age economic systems, hence the issue with “new realities”.

                              I mean what’s the word for a person whose only worth is the number of hours of media they consume and the associated metadata around their viewing patterns?

                              What’s the word for a person whose only value to society is to unknowingly label route data for the autonomous vehicle fleet that’s going to replace them in exchange for an Uber fare?

                              Marx is useful, but we moved beyond the veil of what he was talking about a ways back.

                              1. 0

                                I do agree that the nightmare scenario of the Iron Law pushing down wages to the absolute subsistence level hasn’t (yet) come to pass. Modern society relies on a certain level of discretionary income to pay for more than shelter and food. After all, the purpose of “surveillance capitalism” is to sell people stuff (or rather, help others sell to people more efficiently).

                                I’ve always felt that Marx was better at analysis than solutions, and in fact applying a small tincture of materialist economics is generally an excellent solvent for revealing the true nature of many real-life situations. Start by asking cui bono?

                  2. 2

                    Or we could just look at Qatar and the UAE, where millions of people (80% or more of the total residents!) are non-permanent residents and only there to work. Human-rights abuses are vast, and it’s generally agreed that these folks are being pressed into slave labor. There’s also large amounts of prison labor and conscription worldwide, still; some 40 million people are enslaved today.

                    1. 3

                      Yes, I know… because the definition in use is considerably expanded from chattel slavery. If we just look at chattel slavery — we have no useful numbers on historical economic or carceral or conscript slavery to compare with — then there’s certainly fewer enslaved people today as a percentage of world population than there was in even the quite recent past.

                      Expand the definition and start thinking in absolute counts and sure, as the general population has expanded exponentially the total population engaged in actually involuntary labor has gone up, despite the percentage of people being held in such bondage going down.

                      Don’t get me wrong, all these statistics are abhorrent, but the percentage of the population going down is precisely why the “I’d struggle to find a slaveowner today despite there being absolutely more slaves” is both true and still a false equivalence. It’s hard for that poster to find a chattel slave owner, therefore it’s weird to think “master” is a reference to slavery, despite acknowledging that if you look very far at all it’s not at all difficult to find people engaged in the active exploitation of involuntary labor, ie “masters”.

      2. 24

        Never in those cases do I hear voices from the actually affected groups. I’ve never heard a tribe complaining about out-groupers dressing up in tribal costumes. To the contrary and more sensefully, some support and are content with the fact that their customs are celebrated and brought into the world this way.

        While we are on anecdotal evidence, I’ve seen native group complaining about non-native simplifying and misrepresenting their culture and I’ve seen non-white people being uncomfortable about the use of master/slave and more specifically about how much energy many people put to defend these terms.

        In truth, there is no good synonymous replacement for “master”.

        Many have been proposed and are now used…

        1. 12

          more specifically about how much energy many people put to defend these terms.

          Sure but that’s a different thing, right? When one side of the CW has staked a claim on “X is racist”, then it becomes nearly impossible to defend X without being associated with racism. Control the framing, control the debate.

          Did you see anyone complaining before this became a Thing?

          1. 17

            Did you see anyone complaining before this became a Thing?

            Is it possible that you didn’t hear anyone complaining about it before it “became a Thing” because you don’t seek out the views of marginalized people? Or that marginalized people don’t speak up about microaggressions for fear of retaliation? Or because they don’t feel like having an argument right now?

            1. 3

              Sure, it’s always possible. But it’s still true that the way it was raised changes the conversation. So you list valid reasons why we wouldn’t hear anyone before it “became a thing”, but that doesn’t invalidate my argument for why people complaining after it “became a thing” are complaining about a different thing.

      3. 13

        but only makes it harder to adress and talk about real and current problems, i.e. contemporary slavery.

        If by this you mean it draws away attention and energy from real problems and substantive action, then I 100% agree with all you have said (otherwise just 99% ;-)). I don’t think renaming the default branch name of a project is the same as censoring or prohibiting anyone from discussing (modern) slavery.

        1. 12

          Yes, one can nuance what I said more, but I meant exactly that. From what I can tell, most would see themselves as anti-slavery activists by demanding the words to be put out of use, trivializing anti-slavery-initiatives. People only take action if they are emotionally inclined, and their inclination is definitely reduced by feel-good-tactics like the one I mentioned above. And this only if we agree that “master” is a definite slavery-term, which I don’t.

          1. 12

            I think this is a made-up situation. No serious person thinks they’re an “anti-slavery activists by demanding the words to be put out of use.” This just isn’t the case. It’s completely possible for someone to want a word to be used less and to understand that it doesn’t solve the problem.

      4. 9

        John McWhorter is talking about this issue and coined a term “The Elect” - https://johnmcwhorter.substack.com/p/the-elect-neoracists-posing-as-antiracists

        It’s a good read, doesn’t matter if you agree him or not.

        1. 5

          There are more people like John McWhorter, and they recently founded an organization that actually stands against racism (sans CRT): https://www.fairforall.org/

        2. 1

          I actually like John McWhorter in general (and really like his Lexicon Valley podcast), but didn’t think that was particularly good. I think using his platform as a thoughtful academic linguist and black man to paint overly broadly strokes about how people who hold a wide variety of beliefs that he thinks are too subtle (and therefore must be contradictory) as religious zealots is an attempt to ridicule people instead of having a dialog. I know he’s actually more centrist than that, but attacking people as a large group of ideologically identical people isn’t particularly accurate or useful.

      5. 14

        This second-hand offendedness also makes mutual trust and forgiveness a lot harder, which in turn makes outreach and training new folks–required to fix pipeline issues–more difficult.

        Bluntly: constant brainwashing around microaggressions and racism and whatnot have resulted in a hostile environment where it is simply easier to let devs flounder than try and get involved. I’ve seen a senior dev get scuttled via woke office politics while being one of the only folks mentoring junior developers of color, I’ve seen a senior black manager screwed over by white woke folks backchanneling via a different intersectionality, and so on and so forth.

        We need to train people and teach people to raise the next (hopefully more demographically representative) generation, full stop. We need to do better by our juniors and train them, full stop. We need to give everybody the skills and support they need to eke out a living, full stop.

        Unfortunately, people seem to be missing that this identity politics shit creates division (by construction) and makes it harder to teach and lead, to learn and be led. The constant undercurrent and messaging makes people wonder if their work needs improvement or if they’re being discriminated against–or if they need to temper or skip feedback entirely because they’ll be cast as an oppressor. An hour long (and expensive! Good work if you can find it!) sermon on pronoun usage is an hour not spent advancing the careers of the developers who need it the most (and money not spent on training them in the field they work in).

      6. 7

        I’ve never heard a tribe complaining about out-groupers dressing up in tribal costumes.

        I agree with your overall point, but this is probably because the news media often ignores their voices.

        Instead, the news media gives that voice to some media savvy white person speaking for some advocacy group who’s taken the opportunity to insert themselves into the drama, and the tribe is left to get their word out by posting a statement on their tiny website that nobody visits.

        We see this time and time again in the PNW with regard to Native American issues, such as tribal costumes, sports teams, etc.

      7. 5

        another one is the criticism of non-natives dressing up as Native Americans for carnival (criticised as “cultural appropriation”).

        Never in those cases do I hear voices from the actually affected groups. I’ve never heard a tribe complaining about out-groupers dressing up in tribal costumes.

        If you haven’t heard of costume complaints then you’re not listening

      8. 6

        Frankly I just haven’t encountered many black programmers whose opinion I could ask, and you have to wonder, hm, is it because the community is unwelcoming?

        At any rate, one black person who favors this change is Mike Little, co-founder of Wordpress: https://make.wordpress.org/core/2020/06/18/proposal-update-all-git-repositories-to-use-main-instead-of-master/#comment-38831

        1. 2

          Does being co-founder of Wordpress, a CMS, give his opinion on a social matter additional weight?

          1. 6

            I don’t think so, but he helped create a very influential piece of the modern web and has clearly been around for a while. Until I came across this thread, I didn’t know that Matt Mullenweg had a co-founder, or that that co-founder was black. As we try to make the profession more inclusive, it’s worth noting who is already present.

            I would say that his having been in the industry for some time is notable, since you might expect some older programmers to be more “conservative”, in the sense of being opposed to change.

          2. 3

            I don’t know what role Little has now, but wordpress.com was/is a sort of social network (with federated identities that could comment on other’s blogs) so I’m sure the organization itself has been exposed to the questions of moderation and limits to speech that define the modern culture war landscape.

            1. 1

              Interesting, I didn’t know that wordpress functioned to some extent as a social network in the slightest!

              1. 2

                Note that I stated wordpress.com, the free hosted version.

                Maybe “on-prem” WP instances give WP.com users an instant auth for commenting, I honestly don’t know. It’s been a long time since I commented on a WP blog…

        2. 1

          But is “people being hurt” a decision one group can take by itself?

          As someone who grew up in Turkey, trust me it always confused the hell out of me when the US president pardoned a turkey on Thanksgiving. Can someone say, naming a country after an animal is hurting people, sure but where do we draw the line? There should be some nuance and currently there’s none, nuance is dead on the internet.

          1. 2

            Can someone say, naming a country after an animal is hurting people

            I’m assuming you mean the other way around.

      9. 5

        I find your position here logically incoherent. Someone (call them “A”) did something. Someone else (call them “B”) is upset by it. Now you are joining in to be offended against “A” on behalf of “B” while simultaneously decrying “second-hand offensiveness”. Either it’s bad or it’s not – it can’t be bad only when other people do it but good when you do it.

        Meanwhile, neither you nor anyone else should be affected on a technical level by what some third party chose to name a git branch. If you were, it could only have been due to technical negligence on your part, such as by assuming that the primary/default branch would always have a certain name, rather than using available mechanisms to discover that name on a per-repository basis. That’s an error in the same category as, say, when Adobe assumed their hidden folder name would always sort ahead of all others alphabetically and then deleted files from other applications as a result.

        Which means that the only possible objection would be based on non-technical factors. But there is no inherent right on your part to force someone else to change their branch naming. If a maintainer with full control of a repository wants to name the primary branch “main”, you have no right to force them to choose otherwise. Same as if they want to name that branch “rainbowsandunicorns”. Or sell naming rights to the branch to raise funding for the project, so that now all checkouts and pull requests should target the “goldenpalacecasino” branch. Same as if they want to name the branch to advocate for some cause they care about – perhaps Bram Moolenaar will one day change his branch name to suggest supporting the children in Uganda.

        All of these are beyond your power to control. The most you can do is fork, use your preferred naming conventions in the fork, and hope that your fork becomes more popular than the original. But of course everyone else has the right to reject your fork and conventions, especially if they have a policy of disregarding the feelings of others in anything tech-related. So, now that I come to think of it, you might be better off avoiding such (for example, if you are hoping to have maintainers make decisions that take your feelings into account, you might want to avoid communities like suckless.org, as they notably take a stance against this), and instead looking to communities which are receptive to that type of concern. Unfortunately, such communities tend to get a bad name and wind up with “f*ck your (decision)” articles written about them and highly upvoted on tech sites, which is a risk factor you probably want to be aware of.

        1. 6

          If you were, it could only have been due to technical negligence on your part, such as by assuming that the primary/default branch would always have a certain name, rather than using available mechanisms to discover that name on a per-repository basis. That’s an error in the same category [..]

          Hindsight is 20/20.

          If you’d have asked me a year ago, I think I would have found the assumption that the primary branch is always called ‘master’ a lot more reasonable than assuming some folder will always be sorted into the first position. I believe I would come up with a counterexample for the latter, but not for the former. I may well have some code out there with a hardcoded ‘master’ somewhere. I won’t have code that deletes files based on their sort position.

          1. 4

            In the past decade I’ve used three different version-control systems which between them had at least four different (at different times) automatic default names for the primary branch. I don’t think it would occur to me to hard-code something like that unless I saw API documentation for the system which made a guarantee of that name.

      10. 5

        Never in those cases do I hear voices from the actually affected groups.

        Then you’re not listening.

        1. 1

          Agreed. I’ve seen plenty of criticism of a certain insurrectionist shaman.

      11. 3

        another one is the criticism of non-natives dressing up as Native Americans for carnival

        This is not a great example.

      12. 2

        Second-hand offendedness.

        Not sure why it got really popular on tumblr, but those voices really joined up there and escalated to silly levels.

        Never in those cases do I hear voices from the actually affected groups. I’ve never heard a tribe complaining about out-groupers dressing up in tribal costumes.

        It’s hard when those voices drown in things repeated by more numerous / loud population, but it’s not hard to find native Americans on twitter saying this about coachella outfits for example.

        But some things and culture preferences and history are actually complicated. For example how you refer to native Australians - you’ll find conflicting preferred expressions. Then a well meaning person will repeat the answer in another context and cause more chaos.

    7. 1

      A good post on system design with some pretty funny writing. The zero-knowledge proof solution is dismissed out of hand but if things go well we might just be a few years away from them being usable. If that comes to pass I wonder which other problems will have become easier to solve.

    8. 8

      If your DB exists inside one org - sure. If your DB is shared between multiple orgs and you want to concentrate on tech, not on legal… Maybe time-series database won’t cut it.

      1. 10

        What attack, exactly, do you fear that is allowed by giving your partner orgs append-only access to a DB, but is not possibly by giving them append access to your blockchain?

        I note that the article explicitly addresses the ‘partners who don’t trust each other’ use case.

        For example, a private ledger allows data to be shared and seen by different parties who do not need to trust each other because of the software’s rules – this could be a bank and a regulator sharing data access to customer trades data. I would argue that such data access could be done via the business logic layer sitting on top of the database layer to provide data to outside parties.

        1. 7

          This

          ‘partners who don’t trust each other’

          is not compatible with this:

          giving your partner orgs append-only access to a DB

          Because it requires your partner to trust that you do not do funny stuff on DB yourself. Simplest attack - place a buy before appending a large incoming buy order, and place a sell just after it. Free money. Happens on public blockchains all the time.

          BTW, this article is a dumpster fire. It is full of false claims, half-truths and just irrelevant bullshit. The guy who wrote it knows his time-series databases and knows almost nothing about blockchain design space.

          Blocks are added to the blockchain at regular time intervals. For each block of data, there is an associated timestamp.

          Yes. Trains also arrive at different time points. Is Amtrak a blockchain? How is this even relevant?

          Data replication: Each node in the blockchain holds the entire history of transactions. If one node is compromised, we rely on the others to provide the full history. Again, this concept has been in effect for decades with traditional databases: if one database fails, we may want another as a backup.

          False. There are multiple types of nodes. There are chains where history can be truncated - chains with snapshots. Reason for nodes to have the full state is an ability to validate every state transition. Data availability is an important concern, but it is secondary since the need to share some data can be removed with the help of zksnarks / bulletproofs.

          full history of all individual transactions ordered by time; this is how blockchain nodes work

          No, this is not how blockchains work. They implement total global ordering of events. But the order is logical, not time based. E.g. both Bitcoin and Ethereum include transactions in the order defined by the fee paid - from txes paying high fees, to txes paying low fees. Total global order of transactions plus deterministic execution equals ability to arrive to the same final state. It has very little to do with time.

          Blockchains would have multiple parties (i.e., nodes) to agree for a specific transaction. There are consensus algorithms such as Raft and Paxos in traditional databases akin to a voting mechanism.

          This bit is just lazy. Consensus determines the order of inclusion of transactions. Nothing more.

          Long 256 format: This is the format of crypto public addresses. At QuestDB we have built a data type that is better than a string to efficiently write and read Long 256 blockchain addresses.

          Irrelevant. This is a wrong layer. See Tendermint. It provides a total ordering on a set of binary blobs. Binary blobs are untyped, and Tendermint knows nothing about details of business logic of the application it is running.

      2. 8

        You are not avoiding any “legal”.

        This reminds me how a bunch of blockchain peddlers that made their way into a meeting of a municipal IT steering committee, trying to sell their “block-chain based authentication mechanism”. They did not read eIDAS and GDPR (nor the related local laws) did not read the public service information systems law, nor the cybernetic security law and showed that they had zero understanding of the fact, that if public administration screws up proving someone’s identity and that someone is harmed by that, the administration is held liable.

        It is several times easier to write a contract between couple of parties detailing how you share data and who is responsible for what, adjust your respective privacy policies and use a couple of regular databases than “putting it all onto a blockchain”, potentially being liable for publishing personal information that cannot ever be deleted.

        And frankly, I am pretty confident writing small-scale contracts myself, without being a lawyer. Continental Law tends to provide mostly sane defaults (to a point it is safe to sign most of the common contracts without any additional clauses apart from the mandatory ones) and since overly unfair contracts are invalid and courts are expected to read into what the signatories meant, you only need lawyers in high-risk situations or once something blows up.

        And if you need it to scale, just use adhesive contract (terms of service) with one organization acting as a steward. If you need it to be neutral, association is both the simplest of corporations to fund and also the simplest to administer (almost no accounting) providing democratic (one member = one vote) decision-making by default.

      3. 6

        How do you realistically prevent a 51% attack though…?

        1. 8

          What you decide to do will depend a lot on the specifics of your use-case. You might decide to run your own proof of authority blockchain, or to run some other BFT protocol such as HotStuff. You also might communicate using a public blockchain. However, what you must not do is run your own proof of work blockchain. Your comment correctly identifies one of the reasons why doing so is a bad idea.

          1. 4

            Web of Trust style, ala Proof of Authority, doesn’t actually handle adversarial consensus, only who can publish to the blockchain, so often you’ll see another consensus algorithm underneath that layer, like IBFT, Raft, what-have-you, if you’re concerned with adversaries within the trusted nodes

            1. 2

              Thank you, that’s helpful.

              1. 2

                of course! It’s a really interesting space, and there’s lots of nuances to it all. We obviously deal with it a lot at work, more than other folks may in their day to day

        2. 2

          Enterprise organisations are also vulnerable to 51% attack. You can buy 51% of the shares, then burn the whole thing to the ground.

      4. 4

        Yeah this is my understanding of the value of enterprise blockchains. It’s more about getting diverse organisations to run a database together in an interoperable manner without one of them becoming the “owner” of the database or similar. I’ve never actually worked in such a large organisation so I have no idea if this rings true.

        1. 4

          This is generally the case; my company reviews blockchains quite frequently, as well as their installations, and we’ve seen this comment often. Having said that, I haven’t seen as much success from that sort of thing; very often it’s a pilot, and doesn’t go much further than that.

    9. 4

      I’m having a hard time sympathizing with this one.

      There have been periods of time where states weren’t very good at or interested in defending their citizens from violence. During these periods of time those citizens have needed to take matters of defense into their own hands. The occasional citizen decides to take advantage of the situation and go on the offense, typically for nefarious ends.

      This describes the wild west, fudal japan, the roman empire (kind of). It also describes the current state of computer security. The modern internet is a sprawling metropolis where leaving your door unlocked will lead to a break-in. It is a violent society, and metaphors to other forms of violence seem completely appropriate.

      The author objects to the term “military-grade encryption”, among many others. Let’s ignore the validity of claims of “military-grade encryption” and focus on the term itself. If you lived in a city where people openly carried battering rams you very well might appreciate a “military-grade front door”. The military must deal with threats much stronger and violent than you or I are likely to encounter, and they deal with those threats on the very same internet that you and I use. It seems prudent to defend yourself with some of the same tools they use.

      Confusingly, the author also objects to terms which are primarily used by the actual military.

    10. 8

      Honestly, it’s probably easier to fork a new process with the updated library, devise a fast serialization mechanism for your data, ship it from the old process to the new, then cutover to the new.

      For some value of easy, of course.

      1. 1

        If I remember correctly this is how xmonad handles configuration changes.

      2. 1

        I’ve thought about using Cap’n Proto for that.

    11. 5

      Honestly, I feel the ACM prices are fair.

      Membership with library access is only $198 a year, and realistically that’s not a burden for most people who would want access.

      Furthermore, as the author points out, “The ACM exists to serve the field of computing and society itself,” and the main way they fund that work is through membership fees and charging for library access. The money has to come from somewhere.

      1. 6

        If journal access is the only value that the ACM can provide for their membership fees, then they don’t have much of a legitimate reason to exist. Real professional societies do much more, both for their members and for society at large. I can appreciate that the ACM doesn’t have anything close to the kind of leverage that they would need to really fulfill their mission, but they’ll never get there with that kind of petty gatekeeping mindset and revenue model. It’s simply off-putting.

        Here’s what Scott Aaronson had to say about the practice of charging for access to academic research. Please do follow the links to statements from John Baez and Donald Knuth, too.

        1. 3

          Journal access isn’t the only value they provide, it’s the only thing they provide that gets them net revenue. They also do things like run conferences, running the library, and “magazines”. You can read the full breakdown here.

          1. 2

            Membership is what brings them revenue. Tying that to journal access is just a marketing strategy.

      2. 5

        I looked into getting ACM membership, but unfortunately I did not agree with all of their principles and other things as stated, and did not wish to compromise my own integrity or insult their stance by agreeing to a membership just so I could download articles.

        1. 7

          Woof. I see what you mean.

          They’re really walking themselves out onto an ethical cliff, aren’t they?

          I’ve never gone for membership simply because the price/value equation never made sense to me, but having read the above now I have two reasons to avoid it :)

          I own a hardbound set of volumes 1-3 of their History of Programming Languages series though, and treasure them :)

          1. 6

            Any chance you can point out the problematic principle?

            1. 5

              It’s less about one single principle, and more about the fact that many of these are an INCREDIBLY slippery slope.

              Let me give you an example:

              3.1 Ensure that the public good is the central concern during all professional computing work.

              Step back and think about that for a moment.

              Is anything any of us ever does in this industry short of those of us doing charity work REALLY in the public good?

              Lots of folks think writing open source software is in the public good. Is it? It encourages the use of computers, which have some VERY serious environmental impacts both in terms of their manufacture and their use at scale.

              It’s a very slippery slope. I appreciate the fact that they are striving to live and work by a set of ideals, but my point is that trying to reduce those ideals down to an actionable set of guidelines for our daily work is an incredibly daunting task, and possibly impossible.

              1. 2

                Is anything any of us ever does in this industry short of those of us doing charity work REALLY in the public good?

                Yes! (After a long career of “not really”).

                World would be a markedly worse place for humans without the stuff I get to work on (a widely used study aid for medicine), including a few people who are alive today because their doctors were able to look things up (in much of the world the specialist textbooks you would otherwise need are prohibitively expensive).

                1. 2

                  As usual I phrased that poorly.

                  I wasn’t saying that such jobs don’t exist, because I’ve worked at jobs like that as well.

                  What I was ham fisted-ly trying to communicate is that not everyone is so lucky, and so putting that in their list of tenets is creating a moral quandary where there doesn’t need to be one.

                  Do no harm is enough for me.

        2. 7

          Huh, I admit I didn’t read the principles very carefully, but after skimming through them these all seem pretty reasonable to me. Could you say which ones you don’t agree with?

          1. 8

            For what it’s worth, while I don’t like the ACM’s code of ethics I do support something in the form of the ASME code of ethics or the AlChE code of ethics.

            A big difference I see between the ACM and those other forms is that there is a focus not on some lofty idealism but instead on the realpolitick of a guild looking to protect its interest. An extremely cynical reading of those classical engineering ethics suggests an impetus of “Hey, look, people don’t understand what we do and they’re gonna blame us if we fuck up. so, we need to explicitly always be trying to serve the public good so that they trust us, ensure we don’t engage in buddyfucking that would harm our guild, and act in a generally moral way that means our mandate to charge what we do to do the work we do to the standards we want is not revoked.”

            I’ll point at a few to give the flavor, though I think @asthasr has a good explanation of overall what bothers me.

            In section 1.2, “harm” is vague and made worse by the frequent qualifier of “unjustified”. If somebody thinks something is “justified”, poof, there goes the protections.

            The requirement to use “generally accepted best practices” is so at odds with how software is actually developed today that it shakes my belief in the empirical grounding of any of what follows. Ditto the absurd idea that “consequences of data aggregation and emergent properties of systems should be carefully analyzed”–not that those sentiments are wrong, but they’re so clearly not how we do software “engineering” outside of a few niche applications.

            The entire bit about “capricious or misguided reporting of risks” is basically useless–practitioners must report risks, expect when there’s a chance the reporting might introduce “harm”. So, your obligation is to report issues except when reporting it might have further issues. The ASME criteria (criteria section, 1.3.1) is a lot more straightforward:

            Whenever the Engineers’ professional judgments are over ruled under circumstances where the safety, health, and welfare of the public are endangered, the Engineers shall inform their clients and/or employers of the possible consequences.

            You report the risks, always. If they go ahead with it and you believe there is imminent danger to the public, you go to the authorities. You don’t have this “a computing professional should carefully assess relevant aspects of the situation” nonsense–if you see something, you say something, and if it’s bad enough to endanger the public you fucking report it.

            The problem with the ACM stuff here is that, frankly, it’s very rare that any individual software system is going to pose such an obvious threat to life and limb (compared with, say, a bridge) that a practitioner is going to risk souring their relationship with their work over it. Only recently have we seen any approximation of this behavior with the walkouts over ICE contracts or what have you, but that’s been quite limited.

            In section 1.4, the wording of discrimination includes the phrase “inappropriate factor”. This implies that there are in fact appropriate factors for discrimination, and thus some subset of people that should be discriminated against. This goes directly against (in my reading) the immediately preceding claim of that we “should foster fair participation of all people, including those of underrepresented groups.”. Well, which is it?

            It goes on to talk about “computing professionals should take action to avoid creating systems or technologies that disenfranchise or oppress people.” What exactly does this mean? If I work on software for ultrasound used in abortions, am I not aiding in disenfranchising or oppressing future people? If I work on door lock software for prisons where we put violent white nationalists, am I not doing the same? What about banking software that by necessity only serves those with some pre-existing form of wealth?

            Section 1.5 is about supporting patents. In the first paragraph, we are told to “respect copyrights, patents, trade secrets, license agreements, and other methods of protecting authors’ works.” In the very next paragraph, “Computing professionals should not unduly oppose reasonable uses of their intellectual works”. Again, which is it? The entire bloody point of patents is to prevent any unauthorized use of intellectual work (for a good cause or no!) and grant a limited monopoly so as to encourage further innovation. The invocation of “protecting of authors’ works” is supporting a fictional narrative where we don’t live in a world where every salaried or engaged software engineer signs away their rights as parts of Assignments of Invention.

            It goes on and on, and I won’t take up more space here.

            The real failure of the ACM document is that it’s so goddamn long. Any sort of reasonable ethical boundaries need to be succinct, trivially seen to be representative of common practice, and ideally not containing text that directly contradicts itself. The ACM Code fails on all three of those counts for me.

          2. 2

            The problem with these sorts of lists is that they are meaningless without an ethics. What does it mean to “do no harm?” What is the “public good?” What is the justifying authority behind the “compelling belief” that accessing someone else’s system would help the public good?

            Without an ethical basis this is worse than useless: it’s gormless sloganeering.

            1. 2

              i don’t think you have to provide a clear plan before saying you want to do no harm

              1. 2

                So what if I think it’s very harmful not to send your data to my religious organization for inspection to make sure you’re not sinning? That’s clearly “justified” disclosure of information.

        3. 4

          I’m sure you’re not the only one. For as toothless and out-of-touch as they are, they sure do a lot of purity testing and virtue signalling. It just serves to keep them irrelevant outside academia… which in turn sure doesn’t enhance the relevance of academia to industrial practice. The whole thing is a sad mess, IMHO.

        4. 3

          Seems like a pretty reasonable list, and the baseline of ethical, professional responsibility for somebody working in the field of computing. What in particular do you have an issue with?

        5. 1

          Interesting. You may not want to explain on a public forum but that’s some really mild stuff. If you dropped the “computing” phrases it wouldn’t be out of line in a list of Abrahamic religion’s sermon topics (and maybe other faiths, I don’t have first hand experience in those).

    12. 28

      I’m not meaning to dissuade the SourceHut developer(s) from using GraphQL, but I am still on the fence about GraphQL, having used it at $employer for, oh, 4-ish months now. GraphQL is a shift in thinking, and there are sometimes several ways to provide data for a given business need.

      In any system with models and DB tables, some tables/classes/types have more than one link to them (in an ERD). For example, an Article could have an Author, but it could also be in a MagazineIssue. When you have multiple pathways to reach a given entity, you (as the developer of a given use case, web page, whatever) have to decide which path you’re going to code in your query. Carrying on with the example schema: It could be currentUser -> articlesWritten; or it could be currentUser -> magazinesSubscribedTo -> issues -> articles. This kind of multiplicity of paths increases the complexity of the system, and makes the system more challenging to work with.

      Authorization with GraphQL is quite non-trivial. Suppose you had: Authors organize with Folders, in which they put Articles; and then Readers read Articles. A simple schema would be to have this heirarchy: authors -> folders -> articles. Folders would have-many articles, and articles would belong-to folders. But if you have a query that needs to get articles for a reader to read, if you stick with this simple schema, then you have to include folders in the query. But readers should not have access to or knowledge about the folder the author has put the article in. Or maybe the reader doesn’t care about who wrote what, and wants to get articles on a given topic or tag, like “politics”. Worse yet: a reader [UI] should not be able to query “upstream”, and get at article -> folder -> author -> author.email. “So don’t put upstream association links in your schema” you might say. But is it so simple? What if a pair of entities are not in a simple, obvious hierarchy where one is “higher” than the other. Say, a Person model with a friendsWith association.

      I grant that there may be some correct way(s) to go about things to deal with issues like the above, but GraphQL doesn’t come with guardrails to prevent problematic schemas, and I think it’s not only possible, but somewhat likely for a team new to GraphQL to plant footguns and landmines in parts of their schema.

      So, yeah. I’m still on the fence about this GraphQL thing.

      1. 24

        Indeed. At GitHub we had a VP who was All About GraphQL – we GraphQL’d everything, over a period of a couple years. By the time I left, there were RFCs circulating about how we’d undo all the damage done :|

        1. 24

          Could you describe some of the damage which had been done? What did the push for GraphQL break?

        2. 6

          I’m curious about this as well.

      2. 18

        Thanks for these comments. I would appreciate more specific feedback, if you have the time to provide some. You can use our equivalent of the GraphQL playground here:

        https://git.sr.ht/graphql

        Expand the text at the bottom to see the whole schema for git.sr.ht. This went through many design revisions, and I’m personally pretty satisfied with the results.

        Also, specifically on the subject of authorization, the library we’re using provides good primitives for locking down access to specific paths under specific conditions, and combined with a re-application of some techniques we developed in Python, this is basically a non-problem for us. I’m still working on an improved approach to authentication, but none of the open questions have anything to do with GraphQL.

        1. 2

          Could I ask about this part?

          GraphQL does not solve many of the problems I would have hoped it would solve. It does not represent, in my opinion, the ultimate answer to the question of how we build a good web API.

          Which additional problems would you like to see solved? In which direction might the ultimate answer lie?

          1. 9

            I don’t think it solves pagination well. It should have first-class primitives for this. That’s the main issue.

      3. 9

        Same here, except we’ve had lackluster success with GraphQL for 18-ish months instead of 4.

        I could see it being a big step up for data models that are oriented primarily around a graph, but I’m having a really hard time seeing how sourcehut’s would work this way, outside of the git commits themselves. I’d be interested in reading more about the dissatisfaction with REST, because everything we’ve done so far with GraphQL could have been done better with REST along with something like JSON-schema.

        1. 2

          For small projects, I’ve started just using json-rpc (what’s old is new again!) with a well defined schema (with validation). Nice side effect is the schema gets used as part of the documentation generation.
          Saves lots of time noodling around with REST. I probably wouldn’t recommend it for large projects though, as it is a bit harder to version apis (a bit more “client fragile”).

          I’ve used GraphQL on a few projects, and I thought it was ok. It certainly has its own set of problems.

      4. 4

        Caching and pagination are also issues I’ve seen with graphql, as well as many many failures around n+1 queries.

        1. 1

          About the n+1 problem:

          Disclaimer: I have only dabbled with graphql and never used it professionally.

          Let’s compare this to a REST API (or what would be a better reference point?). In a REST API, you also have the n+1 problem if your entities refer to other entities.

          It is just more common to solve this on the client rather than on the server – which is worse due to higher roundtrips. Alternatively, you provide a denormalized view in your API that provides all data for, let’s say a screen or page, on the server. That means that you have to change your server in lockstep with the client – and also worry about versioning. In the server code you can either use a generalized solution (much like with GraphQL) or a specialized version because it only has to work with this one query. In my opinion, a generalized version is also usually the preferred option but it is nice to have the option for hand-optimization.

          Therefore I think that solving the n+1 problem in GraphQL requires some thought - but also in a REST API. There are good enough solutions. On one hand, since you have more information in your schema, you actually have some more options than in REST. On the other hand, REST is more constrained so you can work with more specialized solutions.

          Am I missing something important?

        2. 1

          Pagination is not really a problem, you just have to make a type specifically for pagination.

          So for an Article you would have an ArticleConnection containing… yeah just use REST it’s way more sane.

          1. 4

            One thing to consider is that “just have to make a type” relies on the fact that GraphQL fields can have parameters. This introduces a challenge for caching, since those parameters become part of your cache key. If you’re trying to take advantage of a normalizing graph cache on your client, the cache engine needs to be aware of the pagination primitives.

            Not advocating for REST, since you have a similar problem there. However, REST makes some static decisions about what fields are included and so the cache key is reasonably a URL instead of a GraphQL AST + variables map. If you decide you don’t want a normalizing cache, but do want a naive document cache ah la REST, managed by the browser, you can’t get that unless you have named queries stored on the server. Then you can query for /query/someName?x=1&y=2 sort of thing.

            I guess my point is that nothing with GraphQL is “just” anything. You’re discarding a lot of builtin stuff from the browser and have to recreate it yourself through cooperation of client JavaScript and specialized server code. Whether or not that’s worthwhile really depends on what you’re building.

      5. 4

        When you have multiple pathways to reach a given entity, you (as the developer of a given use case, web page, whatever) have to decide which path you’re going to code in your query

        Why is this a bad thing? Presumably you always fetch articles using the same ArticleResolver, this doesn’t take any extra effort to support on the backend. And the multiplicity of paths is the nature of graphs! I don’t see why it makes the front-end more complicated.

        Authorization with GraphQL is quite non-trivial

        The best advice I’ve seen for this is: don’t do authorization in GraphQL. You have some system which accepts and resolves GraphQL queries, it fetches data from other systems, those other systems should be doing the authorization. I haven’t had a chance to apply this advice in practice, I think that for some use-cases postgres row-level security would do wonders here, but it seems reasonable to me and it would solve most of your complaints. If your GraphQL resolve can’t even see author.email, then it’s no problem at all to include that link in your schema, it’ll only resolve if the user is allowed to see that email.

        1. 3

          The best advice I’ve seen for this is: don’t do authorization in GraphQL. You have some system which accepts and resolves GraphQL queries, it fetches data from other systems, those other systems should be doing the authorization. I haven’t had a chance to apply this advice in practice, I think that for some use-cases postgres row-level security would do wonders here, but it seems reasonable to me and it would solve most of your complaints. If your GraphQL resolve can’t even see author.email, then it’s no problem at all to include that link in your schema, it’ll only resolve if the user is allowed to see that email.

          “just not resolve”: But how does that actually play out in practice?

          Your query which requested 40 fields in a hierarchical structure gets 34 values back – and just has to deal with it. Your frontend might have Typescript types corresponding to some models in your system. So then some places, which query under certain contexts, get 38 values back, other places get 34, and so on. So does your Typescript now just have to have everything marked with a ? suffix (not required, null is permissible)? Suppose you have an Angular component which takes an Article type prop, or gets it from NgRX, or wherever. Now, your component cannot just populate its HTML template with all known fields of the Article type, like author name, article title, date published, etc. Sometimes that data will just not be there, “because auth”. So will it have to have *ngIf all over the place? Or just have {{ someField }} interpolations peppered throughout that just render as a blank space – sometimes? Should you have a different Angular component for each context that this type appears?

          And this is all just talking about a simple single defined GraphQL type and its fields. Things get even more fun when you have 3+ levels of hierarchy, and arrays of results. What if the model hierarchy is A -> B -> C, and your currentUser has access to the queried A, and the queried C, but not the queried B? Or, because of lack of authorization, it only has access to a subset of the array of values of a given field. So, your frontend now displays a partial set of results – without writing any error in your error log. Or maybe an auth error on an array field makes it return no records at all. Or maybe a null instead of []. So Engineer Alice is expecting to see 10 records, just like she saw on Engineer Bob’s screen when they were pairing yesterday. But today, when she goes to work in her branch, she only sees 7 – and cannot easily see why. “Well, your devs are supposed to know your (whole) schema”, we might say. That’s ideal, but in a team beyond a certain size, that can’t be assured (and, beyond a certain size after that, shouldn’t be expected).

          “Okay, so don’t make auth problems silent, make them noisy” we might say. Yes, I agree. So how noisy should these be? Should a single auth problem, in one single node in a 7-level hierarchy of 82 fields in a GraphQL query cause the entire query to return non-200? Teams have to decide about that, and some teams won’t agree to that approach. For example, at $current_employer, our (non-unanimous) agreement at the moment is to write to error logs, dispatch to $third_party_error_service, but return null and return success (200) for the query. But, in so doing, we are still having some engineers come into the Slack channel(s) and reach out for help because they don’t understand why their GraphQL isn’t working any more, or why such and such page used to return whatever yesterday, but is returning something else today.

          I’m just trying to point out that GraphQL isn’t problem-free. There are warts and challenges that need to be acknowledged and addressed before success can be had.

          1. 6

            I put my comment out there knowing it was wrong and hoping someone would come along to tell me what I was wrong about, but I don’t think this particular criticism holds water.

            You’re pointing out that if the frontend tries to access data it may or not be authorized to see it… may or not see it. The ? is essential complexity that is no fault of GraphQL, REST will have the same problem.

            I think you’re arguing that:

            • In GraphQL all of your data fetches happen at once, so it’s not possible to 403 just the missing pieces, or feasible to 403 the whole request. We agree here!
            • It’s not feasible to expect every engineer to know how the schema works. I agree, and think that’s exactly why types were invented. If User.email is nullable then engineers using User should expect that there will sometimes not be an email. Going further, you might want to make some types self-documenting. If it’s expected they’ll often fail, due to lack of authorization, you might return a union type: ViewableUser | CloakedUser.
            • Silently not returning data you can’t see is a recipe for confusion. That’s sometimes true, I agree! However, say you’re writing a task manager and the query asks for a list of all tasks. There, it’s pretty intuitive that the query would only return the tasks you’re allowed to see. I would expect that in most situations there’s an intuitive solution, authorization is a concept that we’ve all spent a lot of time getting used to.

            There’s another technique you might use, which is to return the errors inline with the query. Return both the data and also the errors. If some field fails to resolve you might leave it null and also bundle an error in with the response explaining why the field is null.

            Which of these techniques you go for will depend on the situation, and probably there are some situations where none of them are satisfying, but I don’t think it’s reasonable to expect any technology to be problem-free. You’re holding GraphQL up to a very high standard here!

          2. 4

            Context: After dablling, I think that GraphQL is usually better than a REST API – and I want to find out if I am wrong. I am fine if it doesn’t solve all problems but it shouldn’t make things worse.

            Back to your comment: I think, it is normal that your data schema has to take authorization constraints into consideration. Agreed, that does not make it always easy.

            If you cannot always return data, you have to make it optional. Most likely, you don’t have to do this field by field but put them into their own sub object.

            This is also what you would need to do if you used a REST API with a schema. Or not?

            Just an idea: If you want to make authentication restrictions more obvious, maybe you can use union types instead of optional fields? Similar to Either/Try in functional languages or Result Rust, you could either provide the result or the error that prevented it. Or instead of an error, a restricted view… Then clients having trouble see the reason for the trouble directly in their result but the schema gets more complicated.

            1. 1

              If you cannot always return data, you have to make it optional. Most likely, you don’t have to do this field by field but put them into their own sub object.

              This is also what you would need to do if you used a REST API with a schema. Or not?

              Just an idea: If you want to make authentication restrictions more obvious, maybe you can use union types instead of optional fields? Similar to Either/Try in functional languages or Result Rust, you could either provide the result or the error that prevented it. Or instead of an error, a restricted view… Then clients having trouble see the reason for the trouble directly in their result but the schema gets more complicated.

              Frankly, I would have rathered that auth errors were noisy and fatal, making developers immediately aware of issues before things get to production. The counterargument from my team, though, was that they did not want to provide information to malicious actors about unauthorized things. So the decision was to make auth errors return 200s, and poke null holes in the payload fields, and/or snip subtrees out of the payload.

              Context: After dablling, I think that GraphQL is usually better than a REST API – and I want to find out if I am wrong. I am fine if it doesn’t solve all problems but it shouldn’t make things worse.

              Indeed, it’s much the same for me. I don’t have any big personal problem with GraphQL. I just try to assess things objectively, and avoid getting pulled along with hype waves without reason. I just haven’t had an overall positive experience yet with GraphQL. It’s been plus-and-minus.

              1. 1

                Thank you for your thoughtful replies :)

                The counterargument from my team, though, was that they did not want to provide information to malicious actors about unauthorized things.

                It’s is hard to judge without your schema but that sounds slightly weird. An attacker gets potentially more information by what fields are missing than a generic auth denied. But even if that’s not true, sounds like security by obscurity to me. [But yes, I am frequently wrong, and maybe there is a good reason for this in your case ;)]

                1. 1

                  The counterargument from my team, though, was that they did not want to provide information to malicious actors about unauthorized things.

                  It’s is hard to judge without your schema but that sounds slightly weird. An attacker gets potentially more information by what fields are missing than a generic auth denied. But even if that’s not true, sounds like security by obscurity to me. [But yes, I am frequently wrong, and maybe there is a good reason for this in your case ;)]

                  Your point stands, but the nuance here is that it’s more like: If someone doesn’t have access to X, if you tell them it’s missing, they can’t infer existence by trial-and-erroring and seeing what gives error vs. what gives absence.

      6. 1

        Can you elaborate how you would solve the “graph” thing better with other API designs? E.g. in a REST design you would have the same potential path ways that you could use for querying? (Just in separate requests?)

        1. 2

          I don’t know if it’s better, but what I do is this: I actually am pretty far from a REST purist, insofar as I do not strictly adhere to a 1:1 mapping between the object hierarchy and the REST endpoints. Instead, I prefer steering towards having endpoints 1:1 with frontend pages (for GETs, at least). So, where there are multiple pathways, my endpoints give only the information needed for the page. For the previous example, a Reader needing Articles would only get an array of Articles back, and would not have any Folders or Authors come along for the ride in the returned payload. If the page needs to display, say, an Author name, then it would come in the [same] payload, too, except as an extra field right on the Articles in the payload.

          I like the simplicity and straightforwardness of “1:1 with frontend pages”, even though it causes criss-crossing and mixing of models/types in a given payload. I leave the entity relationship strictness to the model/DB level (has-many, belongs-to, etc.).

          1. 1

            Thank you for elaborating. I have used that pattern and it worked fairly well for me, too.

            You have to keep client/server in sync, though. I really like the flexibility of graphql here but I haven’t used it on a real life project.

    13. 2

      How would humor be different in this language? You can’t hide the punchline while you’re setting it up. Are there jokes that are just as funny read backwards as forwards?

      1. 3

        I guess it would be somewhat similar as looking at a single frame cartoon: https://www.google.com/search?q=single+frame+cartoon&tbm=isch

        I am sure humor would work differently in this language, but it might introduce alternative ways to express it?

        1. 2

          I’d also add that, while Sapir-Whorf is in general…well, um, provably wrong, to be blunt…there are certain things, especially around humour, that are language-dependent. Puns are only available in some languages, for example; German can’t really do them. Or they’re available spoken, but not written (for example, Japanese, which has many cognates, but uses a Chinese writing system in part to avoid ambiguity in written forms).

          In this case, I can imagine an almost reverse of the Japanese situation: some of these sentences would be recognizable as drawings, and could have a unique form of written-only pun depending on how that worked out.

          1. 4

            German can do puns. Maybe Germans can’t, though. ;)

            1. 2

              I speak German okay, not great, so I confess I’m forwarding what I was told. Can you give me a German pun? I love them in English.

              1. 5

                Germans can definitely do puns, and puns are in fact pretty common in German (though generally considered to be “lame” jokes). The German name is Kalauer. A classic one: “Es wird nie wieder ein Kalauer über meine Lippen kommen, und wenn du lauerst, bist du kahl wirst.” (Of course it doesn’t work in English, but the translation would be “Never again shall a pun cross my lips, even if you lurk till you turn bald”).

                1. 1

                  Ooh, nice! Thanks! I’ll need to ask my buddy what he actually meant.

              2. 4

                Most famous German pun (at least among English speakers): https://genius.com/Rammstein-du-hast-lyrics

                The phrases ‘du hast’ and ‘du hast mich’ when spoken can mean either ‘you have’ or ‘you hate’ and ‘you have … me’ and ‘you hate me’ respectively. When written hate is spelled differently, i.e. hast -> hasst.

                In effect the song tricks the hearer into believing that the singer is accusing them of being hateful towards him. Only when the complete sentence is sung is it clear that the much tamer meaning ‘You asked me’ is meant the whole time.

                I am not a huge fan but its such a famous example I thought it worth bringing up.

              3. 1

                Google for “Wortspiele”.

                Wikipedia has a few: https://de.m.wikipedia.org/wiki/Wortspiel

        2. 1

          That’s a good comparison! I think Scalar families is in part what prompted this thought. You could make the glyph for “big” be comically big, like 10x bigger than the rest of the sentence.

          Maybe you could show irony by making a big glyph that says “small”, or vice versa. Like the trope of a big guy named “Tiny”.

      2. 1

        An ironic situation is ironic no matter which order you learn about it.

    14. 1

      Holy shit. What is the Pythonic way?

      1. 7

        They’re all different use cases. There isn’t “one way to do it” since there are multiple “it”s.

      2. 5

        asyncio is an embarrassment and though it is the officially blessed library the truly Pythonic way is to ignore it and use trio

        Here’s a post on some of the issues with asyncio: https://web.archive.org/web/20171206104600/https://veriny.tf/asyncio-a-dumpster-fire-of-bad-design/

        And another one (by the eventual author of trio): https://vorpus.org/blog/some-thoughts-on-asynchronous-api-design-in-a-post-asyncawait-world/

        I used to have some links to what made Trio great but seem to have lost them. The documentation is pretty good: https://trio.readthedocs.io/en/stable/design.html And in practice, I’ve spent unknown amounts of time debugging crazy asyncio issues because some task threw a StopIteration wen it shouldn’t have and caused some other coro to fail silently or whatever the problem of the day is. I’ve used Trio less but these kinds of problems just don’t seem to happen.

        1. 4

          I like Trio but the ecosystem around it seems in it’s infancy. I made a library for the Quart web framework that supports both the asyncio and Trio eventloop. This library communicates with Redis so I had to get an adapter for both.

          For asyncio, aioredis is an easy pick, however for Trio it was hard to find something. I ended up copying some unmaintained toy project into my project as-is since I could not find a better alternative (which is working fine so far, but def. not an optimal situation). This effectively splits the community in half.

          Using Trio for my professional work is a hard sell because of that reason, even though I reckon Trio is probably the better implementation.

          1. 1

            Yes, most libraries are written for asyncio, which is kind of a shame.

            However, trio-asyncio lets you use them from inside your trio app: https://trio-asyncio.readthedocs.io/en/latest/

            It’s kind of a nightmare to port a large existing app from asyncio to trio, and probably isn’t worth it, but I think the existence of trio-asyncio means there are few reasons to start a new asyncio app.

        2. 1

          asyncio is a worse-is-better API. It’s good enough to be productive despite its warts and that’s going to require any replacement to keep a substantial compatibility layer or else stay in relative obscurity as most other better projects suffer when a worse-is-better API or project becomes popular.

          1. 6

            asyncio is a worse-is-better API. It’s good enough to be productive despite its warts

            I’m going to try not to sound too bitter, but asyncio is not even worse-is-better

            It’s not simple, for either implementers or users. It’s not correct, given how it’s essentially impossible to cleanly handle cancellations and exceptions. And it’s not consistent, it’s a collection of layers that have slowly accreted, occasionally you have to drop down and real with the raw generators.

            that’s going to require any replacement to keep a substantial compatibility layer or else stay in relative obscurity

            I would have agreed with you a few years ago, the things you’re saying are generically correct, but now we have Trio. Trio is simpler both in implementation and also in programming model, it just makes sense.

            It also has a lovely compatibility layer: https://trio-asyncio.readthedocs.io/en/latest/

            1. 2

              I’m going to try not to sound too bitter

              It’s okay. I avoid asyncio Protocols and transports like the plague - they’re just too fragile for me to handle.

              Thank you for the trio asyncio adapter. I wonder if I can integrate it into my sanic + uvloop + aioredis + asyncpg project

      3. 1

        Awaiting bare coroutines in the simplest procedural case, using asyncio.get_running_loop() to get the event loop reference and loop.create_task(coroutine) to make Tasks to schedule in parallel for fan-out operations. At a previous job, I actually plugged an ProcessPoolExecutor in the loop.run_in_executor as the default one and used it to do truly parallel fan-outs for a project that would index TomTom product data with an API key, determine the new releases and download in parallel the 7z archives for map shapes, unpack and repack into an S3 backed tar of shapefile tar gzs and index the offsets into a database so it was trivial to fetch exactly what country/state/city polygon on the fly for use in our data science and staged polygon updating. It was pretty nifty actually, considering that archive packing was cpu bound which necessitated process concurrency and my hack allowed me to develop single process first (using a ThreadPoolExecutor descendant class which just scheduled coroutines in parallel) and then go full multiprocess for the things that ate CPU.

    15. 2

      Building something like this has been on my todo someday list for years now. I’m excited to give it a try!

    16. 5

      My first attempt at recording myself coding is using ffmpeg -video_size 3840x2160 -framerate 2 -f x11grab -i :0.0 output.mp4 to record two frames per second of my native screen resolution. Any improvements or other ideas?

      1. 7

        I’ve found OBS Studio painless for desktop recordings, but it sounds like you’re set already.

      2. 3

        If most of your work happens in the terminal you might use script or asciinema. They result in smaller recording sizes.

      3. 2

        If it works for you, it’s probably not worth changing software.

    17. 10

      I struggle with the same predicament: I run my own email server and have seen emails received from my email server fluctuate over the years between the Inbox and Spam folder in my recipient’s email, irrespective of what rules I follow:

      • SPF, DMARC, and other greater than zero length letter email-related acronyms
      • asking people to mark my emails as “Not Spam”
      • registering my IP and domain with Google Webmasters
      • registering my IP and domain with DNSWL.org

      I have gone to lengths trying to solve this problem but gave up a few years back. But let’s take this issue and internalize it within our community:

      What would you do if you were tasked with handling the spam problem at GMail?

      1. 3

        What would you do if you were tasked with handling the spam problem at GMail?

        I’ve been following this debate for a long time, and suffered myself from the problem (albeit it’s outlook.com that’s blocking me usually, not gmail, and outlook.com has quite some marketshare in Germany). Personally, to circumvent it, I pay for an SMTP relay. This means that my mail server directs all outgoing mail to that SMTP relay server, which then does the real delivery. Since many people (mostly businesses) use that SMTP relay server, it has a high volume and mail usually goes directly to INBOX.

        I acknowledge this is a workaround. The other workaround is to pay Google and have Google’s staff fix the problem. But I think there’s a possibility for a real solution (apart from the best solution, which is to fix the SMTP protocol itself). What I see is that it’s almost always low-volume senders that are self-hosting who have the delivery problems. Based on that, I suggest the following:

        People who self-host mail should form groups and create an SMTP relay server with a clean IP reputation. Every member of that group then has his/her mail server direct all the outgoing mail to the group’s SMTP relay, which does the real delivery. As a consequence, the group SMTP relay has the cumulated volume of all group members and has a much better stand in the delivery. The bigger the group, the better.

        It’s required that someone administers that mail relay, most notably to prevent any member from sending spam (e.g. compromised account). Maybe try rotating the administrative duty annually or so. Finally, from a German perspective, an association (Verein) would make a candidate for the legal framework of such a collective SMTP relay. It’d be the legal entity to address in case of problems. It’d also allow some kind of charity “business” model: assocation members may use the SMTP relay for free, but non-members have to pay. In any case, only individuals are accepted as members. German Ehrenamt at work.

        The individual’s fight against GMail and similar companies is not winnable. My suggestion can give the self-hosters a better stand, and still allow real self-hosting: it’s your SMTP server that accepts all the incoming mail, does the spam filtering, the sieve scripts, and whatever you wish. It’s also your server that sends out the outgoing mail, with just one little twist: all outgoing mail is submitted to the group’s SMTP relay server, thereby joining the group SMTP server’s volume and reputation.

        1. 1

          People who self-host mail should form groups and create an SMTP relay server with a clean IP reputation. Every member of that group then has his/her mail server direct all the outgoing mail to the group’s SMTP relay, which does the real delivery. As a consequence, the group SMTP relay has the cumulated volume of all group members and has a much better stand in the delivery. The bigger the group, the better.

          Sorry, but this is just really silly. I don’t want someone else to be running my mail server. If you do, you can already use one of the vapourware products for sending bulk email or whatnot (be careful, though, because a lot of it doesn’t actually implement SMTP correctly, and cannot do greylisting, for example, so, you’d probably only want to use it to send mail to Gmail and Outlook, still using your own IP address to send mail to anyone else).

          OTOH, I certainly wouldn’t mind to contribute to a legal fund to sue Google and Google Mail, due to them having a monopoly position on the corporate email front, and refusing to accept my mail under false pretences of low domain reputation, which was acquired merely because I’m myself a Gmail user, and have been sending mail to my own account that they misclassified as Spam, and extended such misclassification to the rest of their userbase, too.

      2. 1

        What would you do if you were tasked with handling the spam problem at GMail?

        Maybe this, right?

        I mean, the current situation is kind of the worst of both worlds. Not only do we have an ossified protocol nobody can change, but it isn’t even giving us interoperability!

        However, I can only assume there’s been a slowly-escalating cat-and-mouse game, and as more and more people use email powered by one of the big providers it’s at least plausible to me that more spam than legitimate mail would be coming from self-hosted mail. Without working there I’m not sure how I could estimate what kind of spam they’re getting, and without knowing what kind of spam they’re getting I don’t know that they’re actually doing the wrong thing. Maybe the proper application of bayes rule really should lead you to conclude that self-hosted mail is probably spam.

        I would hate it if that were true, but I don’t know how I would be able to tell if it wasn’t true.

        1. 1

          The biggest problem is that the whole Google Mail thing is a black box, that there’s no way to know why exactly your mail is being rejected (e.g., it tells me that my domain has a low reputation, but doesn’t tell me why), and that there’s no recourse on fixing the situation (e.g., there’s no way for appealing the misclassification of those cron emails that I sent from my own domain to my own Gmail account that Google, apparently, deems to contribute to the low reputation).

          Google Search already has a solution for picking up new web properties very fast, whereas the rest of the players (e.g., Yandex) take ages to move a new site from a Spam to a non-Spam status and to include it in their main index — there’s little reason this couldn’t be done for email. The fact that it’s the very small players that are most affected leads me to believe that it’s merely a CoI at play — they don’t want you or me to run our own mail servers — they want all of us to simply use Gmail and G Suite instead.

    18. 6

      If powershell seems interesting but you’re put off it nushell is a less-mature implementation of some of the core concepts, it looks promising.

      If I remember correctly Oil shell is another attempt to make shells easier to use, it’s not as obviously inspired by powershell, but includes the ability to pass around structured data (among many other improvements).

    19. 45

      Things like this are why I don’t trust Martin’s opinions. He didn’t say a single bad thing about Clojure, he didn’t have any nuance, he doesn’t respect the other viewpoints. He does the same thing with TDD and clean code, where it’s impossible for them to be the wrong tool. He’s been programming for five decades and still thinks in silver bullets.

      For the record, his Clojure example is even shorter in J. It’s just *: i. 25.

      1. 10

        His example is shorter even in Clojure:

        (map sqr (range 25))

        but that misses the point. Both Clojure examples are easy to explain and understand, where in J it is not obvious what *: and . stand for, and how these should be changed should we wanted to compute something different. But even that is not the point.

        The point is that Uncle Bob is writing about his own experience with the language that he finds fascinating. He writes about his experience and he gets to choose how he writes it. If anyone disagrees (plenty people do, I suppose) they are very well entitled to write about their experience themselves.

        1. 19

          I don’t want to sound like an asshole, but what exactly is his experience besides teaching and writing books ? Cause we see so many people advocating for specific language/technology without any substantial real world experience.

          1. 2

            As professional advocates go, he’s well known and (at least be me) well regarded.

            A professional advocate advocating for something is a signal too… and a lot of the things he was advocating 25 years ago are still relevant today.

            http://web.archive.org/web/20000310234010/http://objectmentor.com/base.asp?id=42

            1. 10

              A professional advocate advocating for something is a signal too

              Yes, it’s called Appeal to Authority.

              I’m also not convinced he’s much of an authority. I’d say he’s a zealot. His tirades against types are tired. His odes to discipline are masturbatory. His analogies… well… This is the same guy who said C++ is a “man’s language” and that you need big balls to write it.

              1. 4

                His analogies… well… This is the same guy who said C++ is a “man’s language” and that you need big balls to write it.

                This is called an ad hominem. If you’re going to be a stickler about logical fallacies I’m surprised that you can’t even make it a few sentences without contradicting yourself. Are they important or not?

                A professional advocate advocating for something is a signal too

                This is called inductive reasoning. Given some evidence, such as a well-regarded professional advocating for some tool, we can try to generalize that evidence, and decide the tool has a good chance of being useful. You’ve surely heard of Bayesian probability; signals exist and they’re noisy and often incorrect but minding them is necessary if you want to make any sense of the world around you.

                Yes, it’s called Appeal to Authority.

                Logical fallacies only really apply when you’re working in the world of what’s called deductive reasoning. Starting from some premises which are assumed to be true, and moving forward using only techniques which are known to be sound, we can reach conclusions which are definitely true (again, assuming the premises). In this context, the one of deductive reasoning, appeal to authority is distinctly unsound and yet quit common, so it’s been given a nice name and we try to avoid it.

                Tying it all together, the parent is saying something like “here’s some evidence”, and you’re interjecting with “evidence isn’t proof”. Great, everybody already knew that wasn’t proof, all that we’ve really learned from your comment is that you’re kind of rude.

                1. 4

                  Fallacies can apply to inductive arguments too, but you are right in that there’s an important distinction between the two types and how they differ. I would say that the comment you’re replying to is referring to the idea of informal fallacies in the more non-academic context. The Stanford encyclopedia has a good in-depth page about the term.

                  Also, not all fallacies are equal, appeal to authority may be seen as worse than ad hominem these days.

                  1. 5

                    This thread started with, “Things like this are why I don’t trust Martin’s opinions.” Uncle Bob’s star power (or noteriety) and whether that qualifies as social proof or condemnation, is the point of the discussion, not a distraction.

        2. 12

          The point is that Uncle Bob is writing about his own experience with the language that he finds fascinating. He writes about his experience and he gets to choose how he writes it.

          I wouldn’t be complaining if he was just sharing a language he liked. The problem is he’s pushing clojure as the best language for (almost) everything. Every language has tradeoffs. We need to know those to make an informed decision. Not only is he not telling us the tradeoffs, he’s saying there aren’t any! He’s either naïve or disingenuous, so why should we trust his pitch?

          1. 1

            The problem is he’s pushing clojure as the best language for (almost) everything.

            That’s not what he said though. The closest he came to that is:

            Building large systems is Clojure is just simpler and easier than in any other language I’ve used.

            Note the qualification: ‘… than any other language I’ve used’. This implies there may well be languages which are easier for building large systems. He just hasn’t used them.

            Not only is he not telling us the tradeoffs, he’s saying there aren’t any!

            He repeated, three times for emphasis, that it doesn’t have static typing. And that it doesn’t give you C-level performance.

            1. 8

              Note the qualification: ‘… than any other language I’ve used’. This implies there may well be languages which are easier for building large systems. He just hasn’t used them.

              We need to consider the connotations and broader context here. He frames the post with

              I’ve programmed systems in many different languages; from assembler to Java. I’ve written programs in binary machine language. I’ve written applications in Fortran, COBOL, PL/1, C, Pascal, C++, Java, Lua, Smalltalk, Logo, and dozens of other languages. […] Over the last 5 decades, I’ve used a LOT of different languages.

              He doesn’t directly say it, but he’s really strongly implying that he’s seen enough languages to make a universal judgement. So “than anything other language I used” has to be seen in that context.

              Nor does he allow special cases. Things like

              But what about Javascript? ClojureScript compiles right down to Javascript and runs in the browser just fine.

              Strongly connotating that “I’m writing frontend code for the web” is not a good enough reason to use Clojure, and he brushes off the lack of “C-level performance” with

              But isn’t it slow? … 99.9% of the software we write nowadays has no need of nanosecond performance.

              If Clojure is not the best choice for only 0.1% of software, or even 5% of software, that’s pretty darn close to “best language for (almost) everything.”

              He repeated, three times for emphasis, that it doesn’t have static typing.

              He repeats it as if the reader is hung up on that objection, and not listening to him in dismissing it. Note the increasing number of exclamations he uses each time. And he ends with

              OK, I get it. You like static typing. Fine. You use a nice statically typed language, and I’ll use Clojure. And I’ll be in Scotland before ye.

              Combined with his other posts (see “The Dark Path”), he doesn’t see static typing as a drawback. We can infer it as a drawback, but he thinks we’d be totally wrong in doing so.

        3. 3

          You have to explain both examples for them to make sense. What does map do? How do you change sqr out for a different function? If you learn the purpose of the snippet, or the semantics of each of the individual elements, you can understand either the J or Clojure example just as well as the other (if your understanding of both languages is equal).

          Also the meat of the article is trying to convince the reader to use Clojure (by explaining the syntax and semantics, comparing its syntax to two of the big 5 languages, and rebutting a bunch of strawman arguments - nothing particularly in-depth). I don’t see a balance of pros and cons that would be in a true account of an experience learning and using the language, including more than just a bullet point on the ecosystem, tooling, optimisation, community, etc.

          1. 3

            I am sure that any programmer that has any experience in any language would guess that you change sqr out for a different function by typing the name of that other function. For example, you compute exp instead of sqr by, well, typing “exp” instead of “sqr”.

            The same with map. Of course that someone has to know what particular function does to be able to use it effectively. The thing with Clojure (and other Lisps) is that it is enough to know that. You don’t need special case syntax rules. Any expression that has pretty much complex semantics is easy to write following a few basic rules.

            1. 5

              I understand the benefits of the uniformity of Lisp, but my point was just that you can’t really say that (map sqr (range 25)) is any more or less understandable than *: i. 25 if you know the purpose of the expressions and the semantics of their constituent parts. And given that knowledge, you can reasonably make substitutions like exp for sqr or ^: for *: (though I would end up consulting a manual for the exact spelling).

              Further experimentation would require more knowledge of either language. For instance, why if isn’t a function in Clojure, or why lists don’t have delimiters in J. It’s all apples and oranges at this superficial level.

        4. 1

          My version of Clojure doesn’t define sqr—is that built in?

          That aside, I don’t find either version very easy to explain to someone who isn’t already experienced with functional programming. What does “map” mean? How does it make sense that it takes a function as an argument? These seem obvious once you’ve internalized them, but aren’t easy to understand from scratch at all.

          If I were reviewing this code, I would suggest they write (for [x (range 25)] (* x x))

          1. 4

            Of course that one has to understand the semantics of what they’re doing. But, in Clojure, and Lisps it is enough to understand the semantics, while in most other languages, one has to additionally master many syntax rules for special cases.

            1. 5

              Closure has quite a lot of special syntax compared to many Lisps. for example, data type literals and other reader macros like literal lambdas, def forms, let forms, if forms and other syntax macros like -> are all built in. Each of these has their own special rules for syntax and semantics.

            2. 2

              We’re on the same page I think, except that I think knowledge of semantics should be enough to understand any language. If you see a verb and a noun in close proximity, you’d be able to make a good guess as to what’s happening regardless of the glyphs representing their relationship on screen.

              1. 5

                If you want a language that emphases semantics over syntax, then APL is the language for you! There are just a few things to understand about syntax, in order of importance.

                1. Array literals
                  • Numeric arrays are just numbers separated by spaces. Negative numbers are prefixed with ¯. Some dialects have special-case syntax for complex or rational numbers: 42 3.14 1J¯4
                  • Character arrays are just text delimited by '' quotes. Doubling the quote inside an array escapes it: 'is' or 'isn''t'
                2. Array indexing with [] braces: 'cafe'[3 2 1 4] ←→ 'face' (Many APLers have a disdain for this form because it has some inconsistency with the rest of the language.)
                3. Function definitions
                  • Inline anonymous “direct” functions delimited by {} braces.
                  • Traditional named functions defined by the ∇ form.
                4. Statement sequencing with (Mainly useful for jamming more code into a single line)

                From there, the grammatical rules are simple and natural in the form of verb noun or noun verb noun or verb adverb noun etc. Probably the most difficult thing to learn and remember is that there is no operator precedence and evaluation reduces from right-to-left.

                When I’m programming in APL, I rarely think about the syntax. When I’m programming in Clojure, syntax is often a concern. Should I use map or for? Should I nest these function calls or use ->?

                1. 2

                  When I’m programming in Clojure, syntax is often a concern. Should I use map or for? Should I nest these function calls or use ->?

                  None of those are syntax. map is a function and the rest are macros. They’re all inside the existing Clojure syntax.

                  1. 1

                    Macros can be used to define syntactic constructs which would require primitives or built-in support in other languages. [my emphasis]

                    https://clojure.org/reference/macros

                    1. 2

                      True enough. However, at least in Clojure, macros are pretty deliberately limited so as not to allow drastically changing the look-and-feel of the language. So I’m pretty sure every macro you’ll come across (except I guess reader macros) will have the same base syntax, (a b ...).