1. 44
  1.  

  2. 12

    The interesting part are the comments on this article. People replied that the wish-list reminds them the lang they are in love with at the moment. So one person suggested D, another Elixir, Clojure, OCaml and so on..

    This reminds us how emotional attachment is powerful even in tech world, where everything supposed to be based on facts and evidences.

    1. 9

      That’s a good list. A couple of minor observations:

      1) “Everything should have a clear, lexical, scope. It should be obvious where a variable is introduced. The answer should never be “into the global namespace”. It should be hard to make typos and not notice.

      As far as I can tell, basically the only languages which get this right are statically typed or a lisp."

      Perl gets this right. If you’re writing perl under use strict (which everybody since 1995 is) you have to lexically declare variables, even though there is a dynamic type system

      [Advanced debate: is perl a lisp :-)]

      2) “A solid HTTP client (I’m ambivalent as to whether there should also be a server. Experience of how little ones from the standard libraries of existing languages are used suggests no)”

      I’ve had so much value out of the golang “super easy http server”. Basically every golang app I write on top of my cheesy framework layer exports a bunch of stuff over http on localhost - because it’s easier than not. Live stack traces, profiling, configuration reading and updating, memory stats, force ‘gc now’, it’s wonderful to encounter that problematic running system and be able to get some introspection on what is going on. I know it’s a subset of what a true REPL would give me, but it’s pretty damn useful.

      1. 11

        *quietly edits repl into the list, looks vaguely embarrassed that it wasn’t included*.

        1. 3

          On the rest: You’re right that having an easily embeddable web server is a win. I’m just not sure it’s that useful to have it in the standard library. This is more “I don’t have a strong opinion on the subject” than “I think it shouldn’t be there”.

          Thanks for the mention of Perl. I’d got the impression Perl scoping was less well defined than that, but I don’t really know Perl except in the most passing of senses, so it’s easy for me to get these things wrong.

          1. 3

            Perl has a dynamic scope and a lexical scope, and almost all one’s business takes place in lexicals. The dynamic scope is like a global tree of symbol tables, and under strict you have to explicitly say what you’re expecting:

            • my $cat - lexical
            • $Some::Package::FOO - dynamic, sometimes called package variables
            • our $FOO - lexical alias to one of your own package variables

            Dropping strict means that you can suddenly mention $FOO in your code and it will be assumed to fall into the dynamic scope – basically a global in your package. Long ago this was acknowledged as not the best behavior, but breaking that compatibility requires the opt-in strict.

            With strict, $FOO alone as a first-use would choke at compile time – it must be declared by my, our, or more recently, state. This also helps catch typos of some variable names, plus there’s also a warning about variables used only once as well.

            (JavaScript has a strict of its own, totally a nod to the camel squad.)

            1. 2

              I think VB.NET has a strict too, and heaven knows it needs it.

              Actually, heaven knows VB.NET should go to the other place. But that’s off-topic.

        2. 10

          IMHO, ditch the language-specific packaging, or at least highly discourage it. I really prefer my dependencies to be managed globally by my system package manager, where they go in the right places and managed like anything else.

          Edit: also, language PMs means more updating procedure and likelihood of out of date libraries taking up space.

          1. 16

            I used to be of this opinion but changed it.

            The pros:

            • your system has a package manager, you know how to use it

            • your system package manager can probably handle ‘uninstall’ as well as ‘install’

            • your system package manager can pull in the appropriate dev libraries as packages

            The cons:

            • system release schedules will always lag upstream packages. Sometimes catastrophically.

            • system packages are ‘global variables’. An update to one application can affect another

            • this last point is writ large if your language is sufficiently popular to have some system compoenents written in it. Now you run the risk of breaking your system if you upgrade a dependecy of your app

            IMHO, the ‘right way’ to do this is the python virtualenv/perl local::lib etc. Vendor the packages you need into the runtime environment of your app.

            1. 3

              ◾system release schedules will always lag upstream packages. Sometimes catastrophically.

              ◾system packages are ‘global variables’. An update to one application can affect another

              ◾this last point is writ large if your language is sufficiently popular to have some system compoenents written in it. Now you run the risk of breaking your system if you upgrade a dependecy of your app

              All good things.

              1. The system is in charge of its release schedules and packaging, not its applications. This is why I like stable distributions - packages for a release are guaranteed to work with that release.

              2. Exactly - for security libraries, as an example. If the new version breaks ABI compatibility, then it should be a separate release (like there is libgtk2 and libgtk3)

              3. See 1 and 2.

              1. 3

                But what of packages that aren’t in the release? Or packages that have newer major versions that you suddenly need?

                I don’t want to have to do an os upgrade to get newer library versions. I also don’t want to have to give root permissions to an npm package script. Part of that could be fixed with user-level packaging a la nix, but there are still significant problems with os-level packaging (like having to target N distros vs 1 language repo - - the *nix-verse hasn’t standardized on one package format yet, and even common ones like .deb are not universally compatible among distributions that use that format)

                1. 2

                  The system is in charge of its release schedules and packaging, not its applications. This is why I like stable distributions - packages for a release are guaranteed to work with that release.

                  Yes, you get system stability that way. But as a concrete example, what do you do when you’re app is - say - using an aws feature added in the last 6 months which the upstream lib supports but your system doesn’t yet?

                  The development schedule can’t always operate in sync with the system update schedule. Sometimes you need to pull in updates on your own terms. Yes, you are then taking more responsibility for security and stability - and you can make an informed decision on that - but what is the alternative?

              2. 5

                we all wait for nix to gain more traction.

                1. 4

                  We’re actively discussing cargo install for Rust right now, and we see it as a compliment to system packaging, not a replacement. They’re for two separate use-cases.

                  PR: https://github.com/rust-lang/rfcs/pull/1200

                  1. 1

                    I’m in agreement on ditching the language-specific packaging, but I’m not so sure that having it globally managed is a good idea. My wish list pretty much matches up with @DRMacIver’s, but it would be nice if the packaging infrastructure could use an existing package manager (apt, rpm, whatever) either globally or in a local version of a system, like virtualenv, cabal sandboxes, or what have you.

                    Language specific package managers really feel like a case of yak shaving. (I haven’t been impressed with any language’s version of this so far.)

                    1. 2

                      I’d be perfectly happy (delighted even) for the packaging to be non language specific if it otherwise satisfies my wish list. You need some reasonably deep integration between the language and the package manager, but there’s no reason that can’t just consist of a package for the language itself.

                      That package manager might indeed be Nix. I haven’t used it to any serious degree, but what I’ve seen of it has been pleasant.

                      1. 1

                        Yeah, Nix is on my list of things to check out. From what I’ve heard, it may be what we’re looking for.

                        1. 3

                          I’ve been using Nix for a few weeks and it’s really clicking for me, in particular the declarative configuration and the completely autarkial (?) nature of software installs. I don’t and won’t use it to replace opam or list-packages, but the overall approach is clearly the right one.

                          There’s a lot of symlink wrangling, but that’s a legacy implementation detail. 4/5, would install again.

                          EDIT: Of course, it’s “autarkical”.

                      2. 1

                        Managing packages per user or in separate units of sort (container isn’t the right word here) should be up to the system’s as well, though sadly, this is in poor shape.

                    2. 6

                      A lot of these look like properties of elixir.

                      The exception would be the lack of the common serialization and HTTP libraries included in the stdlib, which I wish would be added, as they would make writing little scripts without needing to pull in dependencies a lot easier. But within an actual project, the dependency management is so good this is a none issue.

                      1. 5

                        Honestly this sounds an awful lot like Clojure (mod various community issues on the Core maintainership side which are being addressed) or Haskell (mod the awfulness of Cabal). I suppose I’m surprised that the author has turned to Python as their go to language as I found both Haskell and Clojure to be huge steps up from Python at least in terms of being able to understand my own code if not also in library infrastructure.

                        1. 4

                          I suppose I’m surprised that the author has turned to Python as their go to language as I found both Haskell and Clojure to be huge steps up from Python at least in terms of being able to understand my own code if not also in library infrastructure.

                          To be clear, I’m not in any way saying that Python tops the list of programming languages in terms of their ability to implement the wish list. If anything it’s the opposite: The wish list has been informed by things that I’ve found painful in writing in languages like Python.

                          The only item on this list that Python is among the front-runners for is community. My choice of Python is a mix of community, convenience and, uh, contingent factors, rather than a suggestion for other people to do the same.

                          1. 3

                            Agreed that this hews close to my sense of CLJ, and even more-so now that he added a section on REPLs.

                            mod various community issues on the Core maintainership side which are being addressed

                            Source / summary? I’m new to the community and curious.

                            1. 3

                              or Haskell (mod the awfulness of Cabal).

                              IMHO you also have to do something about the Haskell community as well, because

                              Friendly. Elitism is toxic, and a community that isn’t helpful to beginners or goes on and on about how they’re super smart for using this language that other people don’t get is the worst.

                              1. 8

                                I can neither confirm nor deny whether the Haskell community was near the top of the list of languages I had in mind when I wrote that sentence.

                                OK, I can confirm it. There are some absolutely lovely people in the Haskell community, many of whom I consider to be friends, but I also have very little desire to engage with the community as a whole due to an unfortunate prevalence of this sort of attitude.

                            2. 3

                              I’d add: an FFI that makes it so easy to use libraries from other programming languages that the language gets to skip the wasted decade where every description of it ends with “…but there aren’t many libraries available”.

                              1. 2

                                I think you linked to the wrong thing.

                                Unfortunately I don’t believe a good FFI is a solution to that problem. Wrapping a foreign library to get something that is actually pleasant to use is still a lot of work no matter how good your FFI is. A good FFI is on the list anyway, but it doesn’t remove the work of getting a good library ecosystem.

                                1. 3

                                  The link was supposed to be a litlte nod to how many wheels get reinvented by each new language, sorry it was opaque.

                                  1. 2

                                    I suspect the FFI helps the perception more than it helps the reality, but my Scala experience was that there was much less reporting of “… but there aren’t many libraries available” than other languages of similar vintage. When one gets seriously into Scala one wants idiomatic libraries or ends up wrapping foreign libraries oneself, but to someone just starting out the Java interop was usable enough that I didn’t worry if there wasn’t a native library for something, in sharp contrast to e.g. Python/C.

                                2. 2

                                  nice to see nice get a shoutout :) never had a chance to really use it, but i was rooting for it to become java.next

                                  1. 3

                                    Yeah. It was really, well, nice. Unfortunately it was thesisware, whileas Scala has a more ongoing research group backing it, so I ended up jumping ship to it quite early on.

                                    1. 1

                                      did you ever manage to use it in production? i was tempted once (i was young and foolish and it was a green field project on my first job); i shudder to think what might have happened if i’d gotten the go ahead from my boss and then ran into lack of support. but it was indeed a very sweet language, and somehow had a nicer feel to it than scala does. admittedly it did a lot less too; maybe kotlin is an apter comparison.

                                      1. 1

                                        Similar story of considering it but fortunately lacking the authority to try. Quite glad we didn’t - did end up using a similar era Scala about a year later and that was fraught enough.

                                  2. 2

                                    This all is very sensible to me, but I’d emphasize the need to think about the affordances different choices provide, and consider what one loses to provide e.g. vi-ability of source code, or pervasive use of text interfaces, or an HTTP server. There’s a place for all of that, but decisions impose costs.

                                    1. 2

                                      Differently typed values are never equal.

                                      Why should you be able to compare values of different types at all? I like the way Go treats types: no operations on different types and no implicit casting, not even when they’re of the same underlying type. The “let’s talk about Javascript” section of this lightning talk explains what happens if you go to the opposite extreme, but even C’s integer promotion can bite you.

                                      1. 3

                                        I agree completely. “You can’t compare different types at all” is a perfectly reasonable implementation of “Different types are never equal”, especially in a statically typed language.

                                      2. 1

                                        I think the JVM does get packaging right (via maven). I was very excited about Idris (I want a cleaner Scala, or equivalently a strict Haskell) until I discovered that its JVM backend didn’t extend anywhere near maven packages.

                                        Coverage tools have resulted in worse code everywhere I’ve seen them used.

                                        Calling C isn’t worth it (this may be JVM bias speaking).

                                        Fixed/machine size integers are such an obscure requirement these days that I don’t think a language needs them by default and they’re certainly not worth giving special treatment (e.g. syntax) to. There should probably be a library for them for the people who still need them. Likewise packed data.

                                        The standard library is where modules go to die. This is true in every language. If your package infrastructure is good enough then it shouldn’t be an issue if any of the things listed is an external library. Fortunately I think we are moving in that direction (e.g. see npm, see Scala pulling things out of its standard library and turning them into external dependencies). Likewise I think having a standardized database access approach (JDBC) has been actively harmful to the JVM ecosystem - it’s meant there’s been no real push for async-io database drivers, and the whole API has remained stagnant for a very long time.

                                        Collections is one of those things Scala does well (longest suicide note in history indeed), so I’m happy on that point.

                                        1. 3

                                          Calling C isn’t worth it (this may be JVM bias speaking).

                                          JVM has no JVM bias and calls C all the time ;)

                                          Fixed/machine size integers are such an obscure requirement these days that I don’t think a language needs them by default and they’re certainly not worth giving special treatment (e.g. syntax) to. There should probably be a library for them for the people who still need them. Likewise packed data.

                                          Not saying it needs special treatment, but “obscure”? Network protocols, file formats, sysctl… If you never need struct packing / binary encoding, it’s either because your world is XML over HTTP or because the libraries you use take care of this for you.

                                          The standard library is where modules go to die. This is true in every language.

                                          The standard library is where modules go to retire and live forever. This is true in every language whose standard library is well designed. And in C.

                                          If your package infrastructure is good enough then it shouldn’t be an issue if any of the things listed is an external library.

                                          Except that you you don’t know which of the twelve libfoos for barlang on github are any good, and can’t trust any of them not to be abandoned or change its API randomly at any moment. The standard library is normally well maintained, has been in wide use for a long time and is mostly devoid of bugs, which can seldom be said of random pieces of code flowing around the Net.

                                          Likewise I think having a standardized database access approach (JDBC) has been actively harmful to the JVM ecosystem

                                          Maybe the Java standard library sucks.

                                          1. 1

                                            JVM has no JVM bias and calls C all the time ;)

                                            A lot of the Java standard library is written in Java. And historically a lot of its security vulnerabilities come from the parts that call C (e.g. image parsing). I think the fact that JNI is cumbersome, which tilts the scales in favour of finding a JVM way to do something rather than calling out to C, often leads to better applications; I think new languages would do well to have the same property.

                                            Network protocols, file formats

                                            Should be machine-independent. And you don’t need a native 32-bit integer type in the language to be able to read and write a protocol that contains 32-bit integers - you can read into a 64-bit integer, and % 2^^ 32 when you write (of course realistically you’d wrap this up in a class or some such - but it could be an ordinary library class, it doesn’t need language-level support). You only need a 32-bit integer type if you want to do 32-bit arithmetic, and I honestly do think that’s a rare case. (A lot of C code abuses integer arithmetic to do bit manipulation, using e.g. ^ 8 for “flip bit 3”, but I’d sooner have native support for working with bits).

                                            If you never need struct packing / binary encoding, it’s either because your world is XML over HTTP or because the libraries you use take care of this for you.

                                            A bit of both, but if it’s going to be a library either way then it might as well be libraries all the way down. I wish we had actual stats on this, but my impression (of course biased by my own experience and the circles I move in) is that the overwhelming majority of programmers never do struct-packing by hand. In which case it shouldn’t be a language-level feature (e.g. it shouldn’t have dedicated syntax).

                                            The standard library is where modules go to retire and live forever. This is true in every language whose standard library is well designed. And in C.

                                            C is actually closer to what I’m advocating - its standard library doesn’t have most of the article’s list (HTTP client, XML parsing, JSON parsing, invoking external programs).

                                            Python’s standard library (where the quote comes from) drew a lot of praise. You won’t find many standard libraries that were considered better designed at the time. But what was a good library ten years ago is often not a good library now. I’d love to hear a counterexample - a language standard library that’s more than ten years old, that offered this kind of “rich” functionality, where the standard library is still the preferred way of doing that functionality today.

                                            Except that you you don’t know which of the twelve libfoos for barlang on github are any good, and can’t trust any of them not to be abandoned or change its API randomly at any moment. The standard library is normally well maintained, has been in wide use for a long time and is mostly devoid of bugs, which can seldom be said of random pieces of code flowing around the Net.

                                            This is not insoluble; I know because in the JVM ecosystem it does work. The likes of e.g. commons-httpclient are reliable and carefully maintain backwards compatibility, but even so they can evolve faster than they would if tied to the standard library release cycle. (I mean, if we forget about the idea of a standard library for a moment, it’s obvious that bundling the JSON parser and the date/time functionality in the same library with a combined release cycle would be bad - it would slow down development, and mean that users couldn’t upgrade one without upgrading the other. A big uber-library is only helpful to the extent that our library/dependency infrastructure is bad).

                                            Maybe the Java standard library sucks.

                                            It sucks now. It was very well written for 1997, and its evolution since then has probably been as good as possible for a standard-library component tied to the language itself (remember we’ve only had 8 releases since then). Languages should design for the likelihood that most libraries written today will suck in 20 years' time.

                                            1. 2

                                              Network protocols, file formats

                                              Should be machine-independent. And you don’t need a native 32-bit integer type in the language to be able to read and write a protocol that contains 32-bit integers

                                              True.

                                              But what was a good library ten years ago is often not a good library now.

                                              Is it really doubleplusungood, or is it just unfashionable? Maybe we, as an industry, should stop changing paradigms compulsively all the time.

                                              And if the standard library really is not adequate anymore, can it be that the language has become inadequate as well?

                                              1. 1

                                                Is it really doubleplusungood, or is it just unfashionable?

                                                It really is bad. Looking back I’m amazed that anyone ever wrote complex software in the ‘90s that wasn’t riddled with crashes and security holes. And then I use software from the '90s and am reminded that by and large, they didn’t. Hindsight is 20/20; I look back at decisions made by good, well-meaning programmers back then - myself included - and wonder how we could have been so stupid. But compsci is a young, fast-moving field; so much of what we know now we simply didn’t know back then.

                                                And sometimes the tradeoffs were correct for those use cases and are no longer. Specifically the synchronous approach and global state used by JDBC make writing batch processes very easy at the cost of making interactive ones harder. They make for better performance on single-processor machines at the cost of worse multicore performance. And they writing programs that support up to a few hundred simultaneous users very easy, at the cost of making programs that support tens of thousands of simultaneous users much harder. Those were good tradeoffs for the time, but not now.

                                                And if the standard library really is not adequate anymore, can it be that the language has become inadequate as well?

                                                Hmm. Certainly some languages from that time have become inadequate (perl, php). But plenty haven’t (whereas I think the vast majority of libraries of that era have gone bad). I’m not sure why this should be so.

                                                1. 1

                                                  I see where you’re coming from. Well yes, software in the 1990s was quite horrible indeed. And I wasn’t that impressed with all the 1990s' mainstream languages even at the time, neither with various interpreted languages starting with ‘p’ nor with the Javaesque family. Consequently I never got into Java so my opinion may be ill-informed, but to me it looked like a language that encouraged code bloat and (like many “object oriented” languages of the time) made design inflexible, and its standard library reflects that. That is, in my POV it was never any good, only fashionable.

                                                  Concurrency and parallelism are certainly issues we didn’t know how to deal with back then, and still don’t really, which may be one of the problems with JDBC.

                                                  I wonder how the Go standard library will feel a decade after its release.

                                                  1. 1

                                                    Consequently I never got into Java so my opinion may be ill-informed, but to me it looked like a language that encouraged code bloat and (like many “object oriented” languages of the time) made design inflexible, and its standard library reflects that. That is, in my POV it was never any good, only fashionable.

                                                    I think a lot of that was libraries/frameworks rather than the language itself. 2015-Java looks very different from 2000-Java even though the language itself has hardly changed.

                                                    Concurrency and parallelism are certainly issues we didn’t know how to deal with back then, and still don’t really, which may be one of the problems with JDBC.

                                                    Right. And my point is that e.g. Python has (IMO) found it easier to adapt to alternative approaches to concurrency in a database-access context, partly because (despite its “batteries included” philosophy) its standard library didn’t include a standardized way of connecting to a (“real” - I know about the sqlite and dbm modules) database.

                                                    I wonder how the Go standard library will feel a decade after its release.

                                                    Yeah. I’m betting that we’ll consider it a bad one, and that in a decade’s time, today’s languages with a smaller standard library (Rust?) will have a clear advantage over those with a large one. I guess there’s only one way to find out though.

                                          2. 5

                                            I think the JVM does get packaging right (via maven). I was very excited about Idris (I want a cleaner Scala, or equivalently a strict Haskell) until I discovered that its JVM backend didn’t extend anywhere near maven packages.

                                            I think regardless of your personal opinion on it, a system that is normally mentioned only following the words “I hate” does not count as doing it well.

                                            Coverage tools have resulted in worse code everywhere I’ve seen them used.

                                            My sympathies for your atypically bad experience.

                                            Calling C isn’t worth it (this may be JVM bias speaking).

                                            This is JVM Stockholm syndrome speaking.

                                            Fixed/machine size integers are such an obscure requirement these days that I don’t think a language needs them by default and they’re certainly not worth giving special treatment (e.g. syntax) to. There should probably be a library for them for the people who still need them.

                                            In general doing numeric types as a library is obviously better than doing them as a built-in. e.g. Haskell gets this right.

                                            Likewise packed data.

                                            Ah, you’re a person who never does any scientific or data centric computing. That explains the C thing too I guess.

                                            The standard library is where modules go to die. This is true in every language.

                                            Which is why I explicitly listed it as the place for things where there’s a fairly clear right way to do them and stability and completeness is what you want out of them.

                                            If your package infrastructure is good enough then it shouldn’t be an issue if any of the things listed is an external library.

                                            Which is how you get 7 different string types and 17 JSON parsers. For commonly used things with clear requirements, there is a strong benefit to standardization.

                                            Collections is one of those things Scala does well (longest suicide note in history indeed), so I’m happy on that point.

                                            As someone who was involved in the design process of the new collections library, I must respectfully disagree.

                                            1. 1

                                              Why did both this comment and the reply get downvoted?

                                              1. 2

                                                I downvoted the reply; I thought the tone was intended to make me angry, and therefore troll was appropriate. (I don’t like downvoting replies to my posts as I’d rather encourage people to reply to me, but in this case I would genuinely have preferred to receive no reply rather than that one).

                                                1. 4

                                                  Likewise, I’d much rather have got no reply than the “My use cases are different than yours therefore yours are clearly irrelevant” you lead with.

                                                  1. 3

                                                    Huh? That’s not what I meant, and I’m pretty sure it’s not what I said.

                                                    1. 4

                                                      It’s really very hard to read much of what you said as anything else.

                                                      However you’re right that my response was more snappish than it should have been. Sorry about that. I’ve been finding a lot of the responses to this piece (more elsewhere than here) very frustrating and you got caught me at the tail end of that.

                                                      1. 3

                                                        Are you talking about the machine-size integers? I think that’s the only case where I’m dismissing a use case. Python already doesn’t have any native support for machine-size integers (only in libraries like numpy or ctypes) and I find that works very well - do I take it you /have/ found that to be problematic in Python?