Hacker News new | ask | show | jobs
by karmakaze 2348 days ago
I've read a lot about Lisps with an open mind, worked through SICP in Racket, and worked on some personal projects in Clojure. It was all fine, but at no point did I feel like there wasn't another language that would have done as well, possibly better. The one area where I was never fully comfortable was the lack of static type checking. I've also dabbled with Haskell and though it it is the most clean and consistent language I've used. I never got to the point where I could wield higher kinded types to my advantage, I felt like I was doing extra work to satisfy the language requirements without necessarily getting the benefits back from it. I realize there's benefits of doing so, but it's unclear when/if I'll even break even.

Recently I tried F# having seen OCaml in the past but not really using it. F# seems to have progressed quite a bit since it was just OCaml on .NET. I'm able to work rather fluently with it having already been exposed to Java/Kotlin/Scala/Elixir which seemed close to what I want but seeming to fall short in ways I couldn't quite describe. F# came the closest to what I've always hoped to find in a language. It too has its quirks, some within itself and partly from interoperating within .NET Core. I've yet to use it on larger projects and on a team but the static type checking has already helped me save so much time on iterating design that I wont look at any Lisp for generic work. If I had a need for some specific DSL task it may come in handy as I've often baked minimally expressive configuration languages in the past for no good reason.

1 comments

Right. Lisp totally outshines every other language at building DSLs, so if you reconceptualize your project as a bunch of DSLs that utilize one another, you win big with lisp.
What I'm finding is that I can effectively do the same with a statically-typed functional language. The worst are DSLs with poor grammar and concept-fit which add-to rather than solve problems. The ways in which Lisp doesn't scale (people-wise) are well known and relate to each application essentially being its own programming language.
> The ways in which Lisp doesn't scale (people-wise) are well known

Well, memes about Lisp not scaling people-wise are well-known on forums like HN.

The actual data on this is lacking, like reports about someone having actually gathered five hundred Lisp developers onto one project and failed.

> each application essentially being its own programming language

Meme-fueled nonsense, I'm afraid.

Every complex application in any language is its own programming language.

New types and functions introduce new syntax, just like macros, along with new semantics.

So you know C? Okay, what's this, from the Linux kernel?

  struct usb_host_endpoint {
    struct usb_endpoint_descriptor          desc;
    struct usb_ss_ep_comp_descriptor        ss_ep_comp;
    struct usb_ssp_isoc_ep_comp_descriptor  ssp_isoc_ep_comp;
    struct list_head                urb_list;
    void *hcpriv;
    struct ep_device                *ep_dev;
    unsigned char *extra;
    int extralen;
    int enabled;
    int streams;
  };
When and where is this allocated? What does it represent? How do you use it?

Guess what, this is new syntax. No, wait, what, it's just using the regular C grammar, right? How can it be new syntax? The same way that a Lisp program have new syntax if continues to be made out of parentheses, symbols, strings, numbers that conform to a rigid grammar.

The new syntax is in the schemas built with the definition abilities provided in the underlying fixed grammar.

[I don't recall reading this C example first time around. Was the comment edited after I replied?]

In any case, "When and where is this allocated? What does it represent? How do you use it?" is just C. The computational model hasn't changed.

Perhaps less well known are the well-meaning explorations into why isn't Lisp more popular. The absence of a 500 Lisp developers on one project is itself the datapoint being discussed.
The absence of that is because it would require a substantial global recruitment and relocation effort to get that many Lispers into one organization. It speaks nothing to their ability or inability to co-operate on a project.

The vast majority of all software tech ever invented is unpopular today. If we just pick a tech stack, language, editor, OS or anything from the last 70 years at random, it's almost certainly unpopular. That's our first-order effect that forms the bulk of the rational explanation for why anything is unpopular. By definition, not everything can be popular: popularity is the selection of a very small number of artifacts (almost always chronologically recent) to the exclusion of everything else.

The challenge to that prior is that there is substantial overlap in the features and capabilities that were in, say Commmon Lisp a long time ago and yet there was a substantial delay in those features being accumulated in other languages with vastly greater adoption to this point (like Java, although that example might be disingenuous since the releases of Java and CLOS were only a year apart...)

Likewise during the last seventy years some languages saw wild uptakes in popularity for some languages much later in their life-cycle. Who would have expected the modern successes of Ruby?