1. 31

I would like to learn a new language during quarantine! I’m looking for something that will be a little different from just a new C-like imperative language.

I’ve spent the last 4 years of my career writing Go. Languages I have messed around in in the past: Haskell, Rust, Java, Python.

Requirements:

  • Must be statically typed, or at least have a static analyzer (e.g. Sorbet).
  • Some available documentation must be able to take a beginner through (e.g. Learn You a Haskell, The Rust Book).
  • Must be able to run on Linux.

I really wanted to get into Unison but that’s still pre-alpha and very far from being usable for writing actual programs.

  1. 35

    I guess I’ll be the one to say it… Learn a LISP. Doesn’t matter which one, though I would recommend Clojure.

    If you want to get away from the C-style imperative programming, LISP is quite far away. But it contains many ideas that C-style languages have been trying to emulate for decades with mixed success. I think that this footnote in the Structure and Interpretation of Computer Programming (chapter 3 #27) explains what is meaningful about LISP and the LISP way of doing things more succinctly than any other explanation I have seen (funny that it’s just a footnote).

    For Clojure itself there is a good number of resources, many of which listed here. The first on that list Clojure Distilled provides a great introduction to the language, and Clojure for the Brave and True provides a much fuller guide.

    However I am cheating a little, since most LISPs including Clojure are dynamically typed, and I initially considered this a weak point of the language. However it is my opinion that they LISP syntax and methodology provide the best experience of dynamically typed programming there is, and Clojure provides many facilities such as pre/post conditions, spec, and TypedClojure.

    1. 5

      Lisp is a good suggestion, despite not fitting all the criteria. I personally would recommend going for either Common Lisp (SBCL) or Scheme (Racket) to start with though. Clojure for the Brave and True isn’t a bad book, but I think that A Gentle Introduction to Symbolic Computation or The Little Schemer followed by SICP provides a much nicer path for a beginner, and then if one feels that switching to Clojure would be advantageous they can do so after the fact.

      Obviously this is just personal opinion, but that’s my experience (I don’t use Clojure much though, and started to learn it after experience with both Common Lisp and Scheme).

      1. 3

        This Introduction to Clojure was posted a year ago and was a really good (relatively) short-form induction for me.

        1. 2

          Any reason for recommending Clojure over more traditional suggestions CL or Scheme (including concrete implementations)?

        2. 28

          Racket! Racket’s wonderful because it takes the basis of Scheme, which is a language simple enough that you can write an [effective, no macros] definition of it on an index card, and it adds everything but makes it all optional.

          Racket’s also a great introduction to language-oriented programming and creating DSLs, namely due to its powerful macro system being wonderful for code generation.

          The Racket Guide gives a pretty good overview of the language. How To Design Programs is a wonderful book, and what I would consider SICP’s modern successor; albeit most of the information in it won’t be knew if you have experience with functional languages. Finally, Beautiful Racket is a great introduction to using Racket for language-oriented programming.

          While racket and racket/base are dynamically typed, Typed Racket exists, and has an extremely powerful dependent type system that puts lots of languages to shame.

          1. 4

            I just ordered The Little Typer which I’m looking forward to using with Racket as a sort of introduction-for-the-impatient to both dependent type implementation and Racket :]

            1. 1

              Is Little Typer to be read after Little Schemer or can it be read standalone as a first book for learning Racket?

              1. 2

                I haven’t read The Little Schemer so I don’t know. Pie (the language of The Little Typer) is a sublanguage of Racket, which means that there will be overlap with general Racket, but I don’t know how much. I’m going this route because I don’t find general programming books to be very engaging, and I have to be lured into a topic with some challenging subject like this.

            2. 2

              Upvote for Racket. I forgot that Typed Racket was a thing, making it even more worthwhile for the OP.

              Just wanted to say that SICP is still a good book, and Racket comes with #lang sicp.

              1. 2

                Im with you on that. If I get spare time, Im doing How to Design Programs. The big advantage of Racket was it lets me create little languages or easily transform my programs. That I code in a portable style makes that easier, too.

                So, I think using Racket might give me productivity gains on new code now and legacy code down the line. Alternatively, I learn Racket to learn Lisp before switching to Common Lisp later with all that awesome tooling Lobsters posted a while back.

              2. 19

                Elixir is probably the most practical language to learn today that meets your criteria.

                Not exactly statically typed, but has type annotations and the compiler checks all function calls (names and arity) at compile time. Erlang’s static analyzer (Dialyzer) can check the types but i haven’t used it.

                The official guide is pretty good : https://elixir-lang.org/getting-started/introduction.html

                1. 4

                  Regarding static analysis with Dialyzer, I’m using it day-to-day right now and I’ve found that the tooling situation has improved greatly for me over the past couple years. I use VSCode and the latest versions of the ElixirLS plugin work great:

                  https://github.com/elixir-lsp/vscode-elixir-ls

                  I used to have to add a package called dialyxir to my project and run stuff manually, now I get first-class editor integration with everything taken care of for me seamlessly. I think most of the Elixir community still doesn’t use Dialyzer, though, which means help can be hard to come by.

                  Dialyzer itself isn’t perfect, and there’s no comparison with a type system like Haskell’s. It can be frustrating running up against its limitations and figuring out which surprising things it will let you do to shoot yourself in the foot…but over time I’ve found that I can kind of “meet it half way” by adjusting my coding habits and expectations. Right now I have a pretty good relationship with it, and it helps me write Elixir code in a way that feels almost-sort-of like it were a language with a strong first-class type checker built into the compiler.

                  1. 4

                    Oh, I totally blanked on Elixir. Thank you for the reminder! I always did want to poke around at it.

                    1. 2

                      The cool thing about learning Elixir is that you’ll also learn the most of Erlang for free. Syntax differs a lot and Elixir has a whole bunch of additional libraries and tooling, but that’s about it. Types, semantic, memory models, runtime are just exactly the same and there’s no FFI, calling Erlang code from Elixir is so easy and seamless that I often use the Elixir REPL to play with Erlang libraries.

                      Maybe you’ll wonder what’s the point of learning Erlang if Elixir is better*. The point is about existing code. Lots of super interesting software has been written in Erlang since decades and is still in use.

                      *: This is subjective of course! There are probably people out there who prefer Erlang.

                      1. 2

                        I’ve been wondering about the relation of Elixir to Erlang, is there an analogy one could make, that goes beyond just the technical aspects, and reflects how the communities see each-other? Is it like Java to Kotlin, or Javascript to Typescript? C to C++?

                        1. 2

                          Not an active member of the Elixir community, but from what I can tell it’s probably most similar to Javascript to Coffeescript; the developer isn’t making any particular changes to the language like with Typescript or C++, rather just making the syntax more conventional. Maybe that’s like the Java-Kotlin relationship but I’ve never really used either. José Valim seems to have a very healthy relationship with a lot of the Erlang community.

                          That’s just what I can tell as an outsider, though.

                          1. 2

                            Is it like Java to Kotlin, or Javascript to Typescript?

                            Yes! This is a very relevant analogy because both Elixir and Erlang share the same virtual machine (ERTS), which is similar to the JVM or a JavaScript engine like V8. Interoperability works without FFI (at least for JavaScript/TypeScript).

                            C to C++

                            Well, it’s more complicated. I’d say “not really” because these are not dynamic languages, there’s no big runtime and they are not compatible (C++ is not an exact superset of C, and more importantly you need extern "C" in C++ headers and this is a kind of FFI, and AFAIK there’s no way to use C++-specific features from C).

                        2. 2

                          I second the Elixir recommendation. If you’re valuing types more and are ready for a bit more experimental / early stuff, I would give Gleam a shot.

                          1. 1

                            Elixir runs on the Erlang VM, right? Has that VM’s performance been improved since I last looked at it circa 2012? Back then it was a standard bytecode interpreter without JIT or native compilation options, and so rather slow, e.g. way slower than JavaScript. (Too slow for my use case, which was on smartphone-class hardware.)

                            I know people tout Erlang’s performance, but it gets that from parallelization and scalability, even though each CPU core isn’t being used very efficiently. Or wasn’t, at the time. Maybe it’s better now?

                          2. 12

                            What about Prolog? Unfortunately it doesn’t satisfy the static typing requirement, but it’s so away from C-like imperativeness that you should forgive it. At least it’s the most anti-imperative language I know. You may also try other languages inspired by Prolog like Mercury (this one is statically typed) or µKanren (I never tried these however).

                            1. 3

                              I can highly recommend Prolog. I learned it for a course in data retrieval at my university and it definitely was my tool to bring my understanding of data relationships to a new level.

                              The disadvantage is that there’s tons of dialects (including attempts to add a type system), all with some specific addons and standard libraries.

                            2. 9

                              Here’s some that I had my eye on:

                              • Chapel: a programming language designed for parallel computing. A lot of data locality constructs as part of the core language, and I like how to they do configuration.
                              • P: A language with first class state machines! Might not satisfy the “beginner documentation” requirement though.
                              • Esterel: real niche, but the only free, battle-tested, synchronous programming language I know about.
                              1. 1

                                This P language seems really nice! I will give it a try!

                                Thank you!

                              2. 8

                                Ada:

                                1. 6

                                  You might enjoy learning Cat, a statically typed concatenative language.

                                  1. 6

                                    I’d suggest continuing with Haskell, or trying PureScript if you want something that compiles to JavaScript.

                                    1. 1

                                      Yes, I think I will definitely put PureScript on the list. Thank you :)

                                    2. 6

                                      Check out nim. It’s a very practical python/pascal -like language with many modern features. Strong and static types. Compiles to efficient C/C++/Javascript. GC with optional realtime capabilities.

                                      1. 9

                                        awk

                                        1. 5

                                          I’m going to pitch Clojure, it’s a modern Lisp that’s well designed and applicable in many domains. It targets some of the most popular runtimes with JVM, .NET, Js, and Python, and offers REPL driven development which is something you won’t see in many languages. I wrote a bit more here regarding why it’s been my language of choice for many years now.

                                          Here are some beginner resources my team uses for onboarding that will help with getting started.

                                          1. 1

                                            I thought it was just Java. I’ve been using Python recently looking at Lisps. What Python integration does it have?

                                            1. 2

                                              Python ecosystem can be used via clj-python, you can see some examples here.

                                          2. 4

                                            I’d suggest either a Lisp and/or Elm. Both will change how you think about programming. @rushsteve1 already goes over suggestions around learning a Lisp so I won’t duplicate their work. For Elm I’d recommend starting with the offficial guide https://guide.elm-lang.org/ as it’s interactive and relatively short compared to reading about Haskell or Rust.

                                            1. 4

                                              I’ll go with one that isn’t all that out there, but is very much worth learning: OCaml.

                                              It fulfils all your requirements, and Real World OCaml is being revised out in the open.

                                              1. 4

                                                Clojure is pretty awesome. The only downside (for me) is it depends on the JVM, which will die off after the zombie apocalypse. It is really a pleasure to write code in. Rust is nice, but I think they try to do too much. Zig looks promising.

                                                If you don’t know C enough to actually write useful things in it, then try C. I learned C recently and it was/is a learning experience. It has that “everything is included” idea , because i mean all cool libs are in C. There is a lot of boilerplate like Java, but in Java it’s superfluous, almost an insult. In C the boilerplate just is what it is.

                                                1. 4

                                                  APL is not statically typed, but you may find one of the modern versions (K or J, etc…) to be interesting nevertheless. Here’s a really quick introduction that shows some of the steps to writing code using it: https://www.youtube.com/watch?v=UltnvW83_CQ

                                                  Despite being dynamic, implementations like shakti fit comfortably inside the L1 cache and heavily utilize SIMD, so it’s likely to outperform programs written in other languages both in terms of terseness of code and in terms of processing throughput.

                                                  A few of the popular implementations have a columnar database built-in too, which is fun.

                                                  1. 3

                                                    Agra or Idris but you said “usable for write actual programs” which raises some questions for these two. What type of programs?

                                                    1. 1

                                                      Presuming you mean Agda not agra. And I second Idris, though its hard to know what “actual programs” are in this context.

                                                    2. 3

                                                      Since you mention “c-like”. Do something different, don’t learn a new or usable language, learn BCPL. You’ll have no use for it, but it’ll teach you something about the C family. Understanding that ancient viewpoint was worth the time for me, as I see these things.

                                                      1. 3

                                                        Although I said Racket (mind-expanding), the best, C-like language I’ve seen with good typing, contracts, and robust compilers is D language. Much of that language comes from an expert on C/C++ compilers who wanted to make sure the replacement had none of C++‘s failings. It’s a well-designed language that can be used with GC or without it. It has two compilers: one for fast iterations like Go compiler; one on LLVM for fastest, runtime performance. It will have less IDE’s, support tooling, and libraries than popular languages. Check their libraries page, though, since what you need might still be there.

                                                        There’s a nice book whose Table of Contents immediately shows you how thorough they were in the language design. There are others, some free. The cool thing about Alexandrescu’s book is that he often talks about the context and tradeoffs around the decisions they made. Especially comparisons with C and C++ whose successes and failures they tried to learn from.

                                                        1. 3

                                                          You may be in quarantine, but you do not state the time you can commit per day to the task. I’d say Groovy or Clojure because you already know Java.

                                                          1. 3

                                                            Maybe instead of a new programming language, you could learn a specification language that will be useful for programming in any language!

                                                            TLA+ is probably a good choice. It is a static analyzer! And there are resources for beginners to learn: @hwayne’s Practical TLA+ and Leslie Lamport’s own video series and free books on his website.

                                                            1. 4

                                                              Hoon and Nock are pretty different. They’re part of the substrate of Urbit, a super ambitious social network / rethinking-of-the-Internet. Nock is a minuscule functional kernel, kind of like LISP as a machine language, and Hoon is a slightly less weird pure functional language that compiles into Nock. Then they’ve got a content-addressed file system / VCS that distributes programs to everyone’s Nock virtual machines…

                                                              I don’t know either language, though I’ve puzzled my way through the 33-line Nock spec. Urbit as a whole is kind of amazing; one of those rare things that hovers in a superimposition of “deeply brilliant” and “batshit crazy”. I’ve decided it’s not a crank pipe-dream nor a hoax, but it does still seem breathtakingly overengineered. Anyway, they’ve decided that the way to take on Facebook is to reinvent computing from the very lowest level, and you’ve got to give them props for that.

                                                              1. 3

                                                                Ooo Hoon looks nuts. I’ll certainly take a crack at it. Thanks for this one!

                                                                1. 6

                                                                  Pyramid scheme for nazis, next.

                                                                  1. 4

                                                                    Godwin’s Law, next?

                                                                    1. 3

                                                                      You can’t just cry “lol godwin’s law” because someone mentions nazis.

                                                                      Nazis do, in fact, exist, kindly pull your head out of the dirt.

                                                                      1. 1

                                                                        Obviously. But they’re rare, and claims of Nazi sightings require evidence. Living in the Bay Area and associating mostly with lefties, I’m aware of how easy it is to whip out slurs like ‘Nazi” or “Fascist” at anyone on the other side of the political spectrum. It’s lazy, and it makes me roll my eyes.

                                                                        1. 5

                                                                          Urbit is https://en.wikipedia.org/wiki/Curtis_Yarvin ‘s brain child. About Curtis’ view, that page says: “alluding to the idea that Hitler’s invasions were acts of self-defense. He argued these discrepancies were pushed by America’s ‘ruling communists’, who invented political correctness as an ‘extremely elaborate mechanism for persecuting racists and fascists’”.

                                                                          Considering these invasions self-defense, and calling a government like the US’ (of all countries!) communist are classic extreme right tropes. Where on the boundary to Nazism that lies depends on the precise definition used, but he seems (much) closer to that than to republican, democratic and/or liberal world views.

                                                                          Urbit is, in some ways, an implementation of his world view, e.g. with its highly hierarchical namespace (and amounts of control granted through it), which affords for both the “Pyramid scheme” description (the first folks to get into are, by design, in a very privileged position) and Yarvin’s ideas of some being inherently massively more powerful than others.

                                                                          I believe that a network based around these ideas gaining traction would also influence the society using it in normalizing such views. I suspect that such effects were anticipated and intended by Yarvin (just that Urbit didn’t take off).

                                                                          1. 2

                                                                            Well, if you honestly believe “Nazi”/“fascist” are slurs, I know all I need to know about you. I’m done.

                                                                            1. 1

                                                                              Slur (n): An insinuation or allegation about someone that is likely to insult them or damage their reputation

                                                                              (Oxford Dictionary of English).

                                                                              ¯_(ツ)_/¯

                                                                              1. 0

                                                                                I took that statement to mean “how easy it is to be lazy and declare somebody a ‘Nazi’ or ‘Fascist’, using these terms as short hand slurs for ‘they seem to be politically on the right and I strongly disagree with that’ (even if what they refer to is merely some flavor of conservative politics)”, even if phrased rather badly.

                                                                                I’ve seen that happen, and I don’t think such use of the terms is helpful because it disregards the gravity of what they stand for.

                                                                                In the context of this thread, the use of “… for Nazis” above can be misunderstood as such a lazy use of the term when it doesn’t come with some explanation what the problem with Urbit is.

                                                                                1. 2

                                                                                  The fact is, Urbit was created by someone who is, by all means, an alt-right fascist. To this day it retains functionality reminisicent of the ideas of who created it.

                                                                                  End of story. Crypto for nazis.

                                                                                  1. 2

                                                                                    I agree, but that context was the bit of information missing above.

                                                                      2. 6

                                                                        Would be really nice if we could stop promoting a project started by a neo-feudalist alt-right crank.

                                                                        1. 2

                                                                          [Citations Needed]

                                                                          1. 1

                                                                            I could be an asshole and just post an lmgtfy link but.

                                                                            https://en.wikipedia.org/wiki/Curtis_Yarvin

                                                                            1. 1

                                                                              Interesting. His political views do seem reprehensible, but I don’t see them reflected in the design of Urbit; how is a decentralized P2P system a tool for monarchy or fascism? And I can’t help but assume that his public retirement from the project was to avoid it being tarred with his politics.

                                                                              Plenty of worthy things have been created by people with serious moral/ethical problems, like Werner Von Braun, Ezra Pound, H.P. Lovecraft, John Lennon [pre-1969], Ike Turner, most of the Futurist movement, Henry Ford, Isaac Asimov, Richard Dawkins, etc. The bad things these people did and said can’t be swept under the rug, but it’s naive to think anything associated with them should be suppressed.

                                                                              1. 2

                                                                                It’s feudal in the sense that the founders maintain control over the ‘planets’ in perpetuity - in a way that ensures the only meaningful way to actually accrue wealth on the platform is to be a loyal servant and hope for a reward.

                                                                                1. 1

                                                                                  So you buy a ‘planet’ and you get to keep it forever if you want? Sounds like that time I bought a ‘house’ here in California and apparently I get to keep it forever if I want.

                                                                                  Also, there are 2^32 planets … that’s kind of a lot of “founders”, no?

                                                                                  Feudalism, to me, looks a lot more like Facebook or Twitter, where I’m sharecropping land owned by the .com in question, which makes money off my eyeballs.

                                                                                  1. 4

                                                                                    Sounds like that time I bought a ‘house’ here in California and apparently I get to keep it forever if I want.

                                                                                    I personally don’t understand the need to translate the concept of limited land/real estate into the digital domain, which is in effect unbounded

                                                                                    1. 3

                                                                                      Well, as I just commented to pgeorgi, I’d assumed it was to create value (somewhat like a cryptocurrency) that could be used to fund their startup. They also have a decent argument that if namespace costs money, it limits the ability of spammers/trolls to outrun their reputations by creating endless new accounts.

                                                                                      But in connection with the founder’s political views and the hierarchical way power is allocated it does start to look more sinister than that. Color me provisionally convinced.

                                                                                      1. 1

                                                                                        Thanks for taking the time to participating in the discussion, and for keeping it civil.

                                                                                        It’s unfortunate that the “fun stuff” of an esolang like nock/hoon is colored by the circumstances of its creator. I personally find the language description to approach dadaist poetry, which can be quite entertaining:

                                                                                        https://urbit.org/docs/tutorials/arvo/ford/

                                                                                        %bake

                                                                                        Tries to functionally produce the file at a given beam with the given mark and heel. It fails if there is no way to translate at this level.

                                                                                        %boil

                                                                                        Functionally produces the file at a given beam with the given mark and heel. If there is no way to translate at this beam, we pop levels off the stack and attempt to bake there until we find a level we can bake. This should almost always be called instead of %bake.

                                                                                        %call

                                                                                        Slams the result of one silk against the result of another.

                                                                                        %cast

                                                                                        Translates the given silk to the given mark, if possible. This is one of the critical and fundamental operations of ford.

                                                                                        1. 2

                                                                                          The use of 4-letter names for everything is cute but weird, indeed. But I think I figured out one reason: since everything is an integer at the Nock level, I believe they use long integers to represent strings (or at least identifiers), and a 4-letter string fits in a 32-bit int. So the naming may be for efficiency purposes, at least in part.

                                                                                          This reminds me strongly of the ‘classic’ Mac OS, which used 4-character/32-bit identifiers for a lot of things including file types, ‘resource’ types, and app identifiers. It’s a clever way to have low-overhead mnemonic identifiers in a constrained environment.

                                                                                    2. 3

                                                                                      Planets are collected in 2^8 galaxies, which is a rather small namespace.

                                                                                      About them: “Galaxies, in this sense, have the power to issue stars, meaning that all other kinds of identities ultimate derive from galaxies. Galaxies also form a Senate, the governing body of Azimuth. The Senate has the power to update the logic of Azimuth by majority vote.” (https://urbit.org/docs/glossary/galaxy/)

                                                                                      So 129 Galaxy owners can drive the system. Let’s see: (https://urbit.org/blog/the-urbit-address-space/)

                                                                                      “Urbit was created by Curtis Yarvin, who has distributed the 256 galaxies as follows (allocation as of June 1, 2016):

                                                                                      95, to the Tlon Corporation. 50, to urbit.org, the future community foundation. 40, to Tlon employees and their family members (24 to Curtis, who started in 2002; 16 to everyone else, who started in 2014). 34, to outside investors in Tlon. 37, to 33 other individuals, who donated to the project, contributed code or services, won a contest, or were just in the right place at the right time.”

                                                                                      They’re free to split power on their toy however they please of course, but I don’t think a structure like this needs to be promoted as anything better than Twitter or Facebook (as discussed elsewhere in the thread): That platform, distributed as it may seem, has share cropping built right into its DNA, and that wasn’t an accident.

                                                                                      1. 2

                                                                                        The limitation of 2^32 planets didn’t make much sense to me initially when I read their docs, but I assumed it was done as a way to generate value and make Tlon financially viable. I hadn’t put it together with the hierarchical structure.

                                                                                        I wonder how tight;y this structure is baked into the system — could the good parts of the architecture be forked into a system without the artificial scarcity and hierarchy?

                                                                          2. 1

                                                                            I’d second this. Urbit is a really fascinating computational system on multiple levels, and is worth spending some time understanding. If nothing else, Hoon is definitely very different from a C-like imperative language.

                                                                          3. 2

                                                                            I’m going to give Julia a try. It looks pretty interesting. It’s statically typed, but you can still use a REPL, it’s supposed to be fast, and the syntax looks familiar enough to be easy to learn.

                                                                            1. 2

                                                                              COBOL.

                                                                              1. 2

                                                                                janet: it is easy to learn easy to compile very small and neat can be used as scripting language also can be embedded in c lisp familiy

                                                                                1. 2

                                                                                  I’d say to learn at least one assembly, since you list none.

                                                                                  68000 (e.g. asmtwo on Amiga) and 8086 (e.g. Flat Assembler on FreeDOS) are my suggestions.

                                                                                  1. 2

                                                                                    I would recommend Brainfsck. Although, it’s not statically typed (there aren’t any types, everything is an 8bit integer). For an interpreter, I would recommend my own, braindead :^)

                                                                                    1. 2

                                                                                      f#

                                                                                      1. 1

                                                                                        I get the feeling that Go 2 will be quite different (it will have generics, for instance.) So that might be a good conservative choice.

                                                                                        1. 1

                                                                                          I would suggest reading and practicing on https://pragprog.com/book/btlang/seven-languages-in-seven-weeks

                                                                                          I might be out of scope, but I think that’s still relevant.

                                                                                          1. 1

                                                                                            I like the requirements you laid out. Did Go fulfill the second one when you picked it up? If so, what’s the “Learn You A Haskell” of Go?

                                                                                            The only language that checks all the boxes that doesn’t seem to have been mentioned yet is Scala, which is surprising given how good the Coursera materials are. It probably won’t make very much of a difference on your arsenal if you already know Haskell, though. I’m not competent on either, so pls do correct me if I’m wrong!

                                                                                            1. 2

                                                                                              if you like “the c programming language”, there is “the go programming language”

                                                                                              1. 2

                                                                                                The tour of go is very good, and the “where to go from here” links at the end of the tour are great as well.