Live data from Hacker News

Why I still reach for Lisp and Scheme instead of Haskell

jointhefreeworld.org

101–110 of 172 posts

Re: Why I still reach for Lisp and Scheme instead of Haskell

#101
post #43

> You can pause, inspect objects, change values, and even redefine a broken function on the fly to test a fix in any environment (yes even in production, while running). I see this mentioned often, and it sounds amazingly useful (especially the part about fixing in production!). But how truly widespread is it among the Lisp dialects to be able to connect to a running program, debug, and hotfix it? I understand Common…

Yes but I don’t know how someone familiar with a Jetbrains IDE can claim that only Lisp has that feature. I love Common Lisp and SLIME, but most of what it can do, I can also do in Java with the IDE. Change a method definition while it’s running and then restart the method? No problem. Run any code within the context of the running method? Yes, Java can do it. Change local variables values in the middle of a method? Easy!

The Lisp REPLcis still superior because it comes with more stuff, like DECOMPILE, INSPECT and so on that can only exist because the language is essentially a compiler even at runtime, which can also be a problem for sensitive domains… but in Java you can do all those things using the IDE so the distance between what is possible in Lisp and a language with good IDE support like Java and Kotlin is now negligible in my opinion.

Re: Why I still reach for Lisp and Scheme instead of Haskell

#102
post #42
post #39

Earlier quoted context omitted.

Haskell: fac n = product [1 .. n]

Obligatory "The Evolution of a Haskell Programmer": https://people.willamette.edu/~fruehr/haskell/evolution.html

That's an odd way to rewrite most of the SfICPICP exercises for scheme.

Re: Why I still reach for Lisp and Scheme instead of Haskell

#103
post #43

> You can pause, inspect objects, change values, and even redefine a broken function on the fly to test a fix in any environment (yes even in production, while running). I see this mentioned often, and it sounds amazingly useful (especially the part about fixing in production!). But how truly widespread is it among the Lisp dialects to be able to connect to a running program, debug, and hotfix it? I understand Common…

It’s trivially easy to do in Clojure (literally one line of code to start an nREPL server, after deps/requires), and often very useful in dev and personal, local projects. In practice, I’ve never once used it in a user-facing production system, in 16 years of writing Clojure.

Out of the box, there’s zero security or audit trail. Building that properly isn’t trivial and, even with it in place, many corporate infosec teams would have fits if you suggested that engineers can make arbitrary inspections/modifications to a running production system.

Where it could be appropriate, often you’re running the code in autoscaling containers or something similar. Modifying one instance then is rarely anything but a terrible idea.

Where I have used it is for things like long-running internal batch systems that run a single instance and never touch any sensitive data. Connecting a REPL in those cases is much more flexible and powerful than, say, building a dashboard UI or a control API over http, and you get it for free.

Re: Why I still reach for Lisp and Scheme instead of Haskell

#104
post #35

I don't believe monads are a "heavy handed abstraction" and that's what prevents people from prototyping in Haskell. What really prevents people from writing in Haskell at a reasonable speed is the poor language design. Programming languages are supposed to aid in reading by emphasizing structure. It's important to emphasize that a particular group of "words" constitutes a function call, or a variable definition, or…

From your last paragraph, I am curious which languages / paradigms you advocate for. Sorry it wasn't clear to me except that you like SWANK, which I'm not familiar with.

I wish there was some sort of a single metric that would allow measuring languages against each other and thus determining the best one. Unfortunately, there are multiple variables and the relationship between the variables is unclear. But, going totally with my gut feeling, some examples of good languages (in terms of ease of reading) include:

* Prolog (and, by extension, Erlang).

* Pascal.

* Java 5 and earlier (and Go, as it's almost a Java's twin).

These languages somehow manage to hit the sweet spot of enough system and enough diversity, few unexpected syntax constructs (eg. Pascal or Java have the "dangling else" problem, but it's manageable compared to the problems introduced by optional statement delimiters in Go or JavaScript for example). In every case, a programmer must program defensively against these sorts of language "pathologies".

To give some examples of questionable or outright bad design decisions:

* In Common Lisp (and Scheme as well as a number of similar languages) there's a problem with identifying the open parenthesis that will be closed by typing the closing parenthesis. Programmers must invent tools and techniques to manage this problem.

* In C++, there's a laughable (or, at least was, for a long time) rookie "whoopsie" when it comes to ">>" in templates vs infix operator. And the "solution" offered by the language designer makes you think they were just... lazy (add space).

Here are also examples of some (perhaps, accidentally) good decisions:

* Kebab-case in many Lisp family of languages. In Latin script, the position of the hyphen in the middle of the lower-case letter is a better choice then, eg. underscore (which is tutted to be a "not a typographic character"). Same reason why, eg. in traditional Hebrew hyphens are at the height of a capital letter (Hebrew doesn't have lower-case letters and the shape of letters is better suited for hyphens at the top rather than the middle).

* Clojure as well as Racket (afaik, deliberately) introduced more kinds of parenthesis-like delimiters to make it easier to guess which expression is being terminated by the currently typed delimiter.

* * *

Note that this is a "superficial" metric, because languages are also valuable for concepts they are able to express both in terms of program logic as well as program application to the hardware it manages; the ability to process, modify, generate, analyze the language automatically; the ability to constrain the language to a desired subset of all available operations... Incorporating all of these into a single metric seems like mission impossible :)

Re: Why I still reach for Lisp and Scheme instead of Haskell

#105
post #77

Earlier quoted context omitted.

> It's important to emphasize that a particular group of "words" constitutes a function call, or a variable definition, or a type definition -- whatever the language has to offer. Syntax highlighting? Please take a look at https://play.haskell.org/ I am completely baffled by this comment. Are you missing the parenthesized function calls by any chance? If so then I can relate a bit.

No, it's not syntax highlighting. For background: my first time in college, I was studying typography. An integral part of this trade is figuring out what is easier for people to read by answering questions s.a. what is the best line length, what number of columns per page is the best, what number of ascent elements per font face is the best, considering letter frequencies and coincidence and so on. It also comes wit…

> the programmer can't tell if the program is actually

What do you mean, "can't tell"? If I see this in Python

    (A)(B)(C)
how do I know which of your 9 it means? Well, I'm a Python programmer so I know that it means

    A(B)(C)
which is the function A applied to B, which returns a function that gets applied to C. If you're a Haskell programmer you know that it means the same thing.

I grant you that it is odd to those who are unfamiliar and it took me quite a while to get used to it, but it's much better to write that way in Haskell when writing programs that use higher-order functions.

Re: Why I still reach for Lisp and Scheme instead of Haskell

#106
post #40

I don't believe monads are a "heavy handed abstraction" and that's what prevents people from prototyping in Haskell. What really prevents people from writing in Haskell at a reasonable speed is the poor language design. Programming languages are supposed to aid in reading by emphasizing structure. It's important to emphasize that a particular group of "words" constitutes a function call, or a variable definition, or…

>And then it's also spiced by the most bizarre indentation rules Are you mixing tabs and spaces? Maybe an example here would help. >overloading of literals (heaven, why???) No, this is important, so that default strings don't to have to be something crummy. Even C++ got on this bandwagon. >and requiring parenthesis around function arguments both for definition and for application. ??? Again, an example would be helpf…

> Are you mixing tabs and spaces? Maybe an example here would help.

This is not what "rules" means. Rules aren't about what I do. Rules are about what the language treats as legal or illegal. I don't write in Haskell at all because I don't like it and have no use for it, but Haskell rules don't change because of that, they are still mindbogglingly complex when it comes to telling the programmer if the next line is the right amount of space to the right or not. None of that complexity is necessary and could've been totally avoided if the language used statement delimiters.

> No, this is important, so that default strings don't to have to be something crummy.

My argument is that to get a little accidental convenience you sacrificed a huge amount of routine convenience. The mental load of having to distrust a string when you see it is just not worth the accidental convenience of writing a prepared statement and making it appear as if it was a string. In other words, you are the guy who traded a donkey for three beans, but the beans didn't sprout into a huge ladder that took you to the giant's castle. You just made a very watery soup and that was that.

> Again, an example would be helpful.

Look up the example I gave in the adjacent reply.

> I thought lazy execution was widely agreed to be the worst part of Haskell.

It's good because it's unique and, when it fits the purpose, it's useful for that particular purpose and neigh irreplaceable, because it is unique. It's worth having for the sake of research, to understand how languages can be designed and what tools or techniques can be discovered on this path. This is said from the perspective that Haskell is not the end product, but rather a research attempting to study how languages can work and what concepts they can develop.

Re: Why I still reach for Lisp and Scheme instead of Haskell

#107
post #79

Earlier quoted context omitted.

> (syntax-rules ...) The very first time I tried to use it, I ran into its limitations syntax-case is the general purpose construct to use. syntax-rules is a restricted, easy-things-should-be-easy construct. https://www.scheme.com/tspl2d/syntax.html

It's just not good because you need to work around its limitations, whatever its purpose is. Not good for prototyping because it's the red tape you need to cut to get work done. Red tape isn't, in general, a bad thing, but when it comes to prototyping it is.

I think most people misunderstood syntax rules. It was not meant as the macro system for scheme. It was meant as the template macro system everyone could agree on, while leaving the more powerful low level macro systems to the implementations. Syntax case, or explicit/implicit renaming or syntactic closures or what have you.

Re: Why I still reach for Lisp and Scheme instead of Haskell

#108
post #37

I don't believe monads are a "heavy handed abstraction" and that's what prevents people from prototyping in Haskell. What really prevents people from writing in Haskell at a reasonable speed is the poor language design. Programming languages are supposed to aid in reading by emphasizing structure. It's important to emphasize that a particular group of "words" constitutes a function call, or a variable definition, or…

> Haskell is a word salad. Every line you read, you have to read multiple times, every time trying to guess the structure from the disconnected acronyms. This is a huge roadblock on the way to prototyping as well as any other activity that implies the ability to read code quickly. I couldn't disagree more. Yes, there is more upfront work understanding Haskell code. But it's very dense. Once you understand the pattern…

> I couldn't disagree more

[proceeds to agree on all points]

Not even sure what to tell you... Have more introspection?

Re: Why I still reach for Lisp and Scheme instead of Haskell

#109
Picking a language is a matter of selecting the best fit given the constraints of the project.

For stuff I like to work on on my own time, "how I like to work" is a major forcing constraint. So it's no surprise that I have a large number of Lisp projects sitting around. Maybe it's because I'm auDHD, but the ability to evolve a program through active dialogue with the machine (and not of the sloppotron variety) just fits better with how I think through a problem and its solution.

Re: Why I still reach for Lisp and Scheme instead of Haskell

#110
post #22
post #18

I tried some ML language once, it's difficult even to write a basic factorial example, which in Scheme I could do it iteratively and recursively with ease. Either with S9 Scheme for quick fun (it has Unix sockets and ncurses :D ) or Chicken Scheme for completeneless (R5RS/R7RS-small + modules), I always have fun with both. Oh, and well, Forth, too, but more like a puzzle (altough it shines to teach you that you can d…

Even as simple as fac 1 = 1 fac n = n * (fac (n - 1)) which is a working Haskell implementation? I mean, in Scheme it is longer to write. I enjoy Lisps and use Emacs for everything, but Haskell can be as terse, or even more terse. (Which is not always a good thing.)

I think in terms of token count it comes out to about the same; and Lisp admits fewer kinds of tokens.
Post reply on HN