Threads for uzl

    1. 2

      I can’t imagine what argument would convince me that the license of your artefact should in any way inform the choice of implementation language, but I’d love to hear anybody try.

      1. 6

        The basic idea is:

        • Most FOSS projects are created by one or a small number of people and not large teams
        • “Corporate” languages (Golang, Rust, Typescript) are backed by large organizations
        • Large organizations tend to have high turn over and large code bases that can’t fit into any one persons head, so they optimize for the following major priorities:
          • discouragement of “dialects” and encouragement of a consistent or standard way of expression
          • explicit and verbose code
          • “quick to pick up” languages whose focus is less on mastery than consistency of expression
        • One or few person teams tend to not have high turn over and work on projects without major funding which favors the priorities of:
          • languages that have high expressiveness and rewards mastery
          • communities that are “friendly”
          • languages that are “fun”

        To me, this is kind of talking about corporate vs. “DIY” (or “artisinal/amateur/journeyperson”) and it so happens that most FOSS projects are sole developers or a small number of people. As such, the FOSS projects will presumably favor languages that allow ‘shortcuts’, high levels of expressiveness, perhaps a DSL. Sole developers also won’t be as willing to put up with a toxic community.

        In a corporate context, consistency is much more important as there might be high turnover of developers, a large code base without any one or a few people knowing the whole code base. Consistency and standardization are favored as they want to be able to have programmers be as fungible as possible.

        You can see this in Golang, especially considering one of it’s explicit intended goals was to service Google’s needs. The fact that it can be used outside of that context is great but the goal of the language was in service to Google, just as Rust was in service to Mozilla and it’s browser development effort. The same could also be said of Java as it was marketed as “business friendly” language for basically the reasons listed above.

        The speaker goes on to talk about Raku, which I guess is what Perl6 turned into (?), as being one of the fun languages with a friendly community.

        So I think it’s a little reversed. It’s more like, most free software is written by a single or small number of people, and this workflow has a selection bias of a particular type of language, or a language that favors a particular set of features while discouraging others.

        1. 2

          Yikes, I wouldn’t touch perl with a barge pole :)

          I understand the idea behind small teams better being able to handle a codebase filled with dynamic magic and various other “spooky action at a distance”, but the problem isn’t just how much cognitive load you’re wasting getting up to speed, it’s the defects you build because so much is hidden and things you thought would be orthogonal end up touching at the edges.

          1. 4

            Raku really isn’t Perl. I don’t know enough Perl to have an opinion on it one way or the other (though its sub-millisecond startup time – about an order of magnitude faster than Python and about the same as Bash – give it a pretty clear niche in some sysadmin settings). But they are definitely different languages.

            The analogy I’d pick is that their relationship is a lot like the relationship between go and C. Go (Raku) was designed by people who were deeply familiar with C (Perl) and think that it got a lot right on a philosophical level. At the same time, the designers also wanted to solve certain (in their view) flaws with the other language and to create a language aimed at a somewhat different use case. The result is a language that shares the “spirit” of C (Perl), but that makes very different tradeoffs and thus is attractive to a different set of users and is not at all a replacement for the more established language.

            1. 1

              TBH I know nothing about Raku. I vaguely remember the next version of Perl being right around the corner for years, but by then I’d had enough of line noise masquerading as source code (which all Perl written to be “clever” definitely was at the time) so I wasn’t paying attention.

            2. 4

              There’s an argument that you might not introduce those defects if you’re a single person working on a project because the important bits stay in your head and you remember what all the implicit invariants are.

              I personally buy a weak form of that argument: things developed by individual developers do tend to have webs of plans and invariants in those individuals’ heads. AFAIK there’s some reasonable empirical research indicating that having software be modified by people other than the original authors comes with a higher rate of defects. (Lots of caveats on that: e.g. perhaps higher quality software that has its design and invariants documented well does not suffer from this.)

              I’m told that hardware / FPGA designers tend to be much more territorial about having other people touch their code than software people, because of the difficulty of re-understanding code after it has been edited by someone else, because hardware contains a greater density of tricky invariants than software.

              1. 4

                Yikes, I wouldn’t touch perl with a barge pole :)

                I think that’s unnecessarily mean…

                1. 4

                  I hear what you’re saying and I think there’s a lot of validity to it but there’s a lot of subtlety and shades of gray that you’re glossing over with that argument.

                  So here’s a weak attempt at a counter argument: all that dynamic magic or other trickery that might end up messing things up for beginner/intermediate programmers, or even programmers that just aren’t familiar with the trickery/context/optimizations, are not such a big deal for more experienced programmers, especially ones that would invest enough time to be the primary maintainer.

                  It’s not that one method is inherently better than the other, it’s that the context of how the code is created selects for a particular style of development, depending on what resources you’re optimizing for. Large company with high turnover and paid employees: “boring” languages that don’t leave a lot of room for rock star programmers. Individual or small team: choose a language that gives space for an individual programmers knowledge to shine.

                  I saw a talk (online) by Jonathan Blow on “How to program independent games” and, to me at least, I see a lot of similarities. The tactics used as a single developer vs. a developer in a team environment are different and sometimes go against orthodoxy.

                  There’s no silver bullet and one method is not going to be the clear winner in all contexts, on an individual or corporate level, but, to me at least, the idea that development strategies change depending on the project context (corporate vs. individual) is enlightening and helps explain some of the friction I’ve encountered at some of the jobs I’ve worked at.

                  1. 1

                    Right, but if you’re the only person working on an OSS project you’re not doing it full time, and you’re also (probably) working on a wide variety of other code 9-5 to pay the rent, basically meaning whenever you’ve got some time for it, you’re always going to be coming back to your OSS code without having it all fresh in working memory.

                  2. 3

                    (disclaimer: video author)

                    [The larger problem is] the defects you build because so much is hidden and things you thought would be orthogonal end up touching at the edges.

                    I 100% agree with this; spooky action at a distance is bad, and increases cognitive load no matter what. However, I think a language can be both dynamic/high context and prevent hidden interaction between supposedly orthogonal points.

                    Here’s one example: Raku lets you define custom operators. This can make reading code harder for a newcomer (you might not know what the symbols even mean), but is very expressive for someone spending more time in the codebase. Crucially, however, these new operator definitions are lexically scoped, so there’s no chance that someone will use them in a different module or run into issues of broken promises of orthogonality. And, generalizing a bit, Raku takes lexical scope very seriously, which helps prevent many of the sorts of hidden issues you’re discussing.

                    (Some of this will also depend on your usecase/performance requirements. Consider upper-casing a string. In Raku, this is done like 'foo'.uc, which has the signature (available via introspection) of Str:D --> Str:D (that is, it takes a single definite string and returns a new definite string). For my usecase, this doesn’t have any spooky action. But the zig docs talk about this as an example of hidden control flow in a way that could have performance impacts for the type of code Zig is targeting).

                    1. 1

                      Yikes, I wouldn’t touch perl with a barge pole :)

                      Arguably Perl isn’t Raku.

                  3. 1

                    Can you imagine Free Software being produced with MUMPS? Some languages are only viable in certain corporate environments.

                  1. 5

                    My first contact with tacit programming came from J and left amazed by the potential of it. Looking at others languages implementing it seems like kind of w/hacky. It goes far beyond using a pipe-ish operators. I remember discovering the concept of hooks & forks and never seen it in other languages. Generalized composition techniques and using being able to create a function by chaining/composing a train of functions are one of the aspect connected to tacit programming that I really like and may (or may not) enhance self-documented code, IMHO.

                    I wish to see more flawless integration of tacit programming concepts in the future. Haskell’s pointfree is a bit disappointing due to heavy use of the dot . everywhere.

                    1. 5

                      My first contact with tacit programming came from J and left amazed by the potential of it.

                      I had a similar first contact experience – except that it was Dyalog APL in my case, so the experience came with a lot more non-ASCII characters.

                      I remember discovering the concept of hooks & forks and never seen it in other languages.

                      I’m not sure that any non-array language will ever be able to quite match J/APL, etc. But Raku comes far closer than I ever thought I’d see. For example, the docs you link say:

                      3 hours and 15 minutes is 3.25 hours. A verb hr, such that (3 hr 15) is 3.25, can be written as a hook. We want x hr y to be x + (y%60) and so the hook is:

                         hr =: + (%&60)
                         3 hr 15

                      You can do essentially the same thing in Raku, with only a few more characters:

                         my &hr = * + * / 60;
                         3 [&hr] 15

                      (Admittedly, this isn’t idiomatic in Raku. In particular, I’m not sure I’ve ever seen an infix function call in real Raku code. But still!)

                      1. 2

                        I just began to look at Raku and will be learning a bit of it during the Christmas holidays, it really seems a versatile language and a funny one. I realized a long time ago that non-array language can’t provide the same level of expressiveness and compactness of J/APL for tacit programming.

                        What characterize idiomatic code in Raku when you have so many ways to do it?

                        And looking for your example, if I want to do something similar but with the average function. In J,

                        avg =: +/%#

                        Using the Whatever star seems to imply different positional arguments. Using pointy block,

                        my &avg = -> @a { @a.sum / @a.elems}

                        and simply using a block with the topical variable :

                        my &avg = {$_.sum / $_.elems}

                        Can we go further than that or take another approach to express it?

                        1. 1

                          Can we go further than that or take another approach to express it?

                          There’s also the placeholder parameter route via the ^ twigil:

                          my &avg = { @^a.sum / @^a.elems }