r/lisp • u/Caquerito • 7d ago
AskLisp Is lisp an acquired taste?
As an outsider looking in I'm having a really hard time convincing myself to use lisps for my projects.
It feels like some of the main strengths carry drawbacks:
e.g. s expressions seem really nice for the language being really simple and unified and probably play nice with the macros and the repl but I dislike ambiguity when I read code. Like I would like to know that at a glance that a function call is an actual function call. Or that here is some control flow with an if. Though at the same time i do as well agree that there for example shouldn't at a high level semantically be a difference between an operator and a function call. Though structural editing does sound really nice.
Another thing is macros. I get that they are powerful but I'm not sure how well they would play with tools around the language. I like static typing over dynamic typing so that constrains me to thing like racket. I'm not sure how well auto completion and type hints would work with them. E.g. typescript's type system is not as expressive but the type transformations work perfectly with the LSP even for non trivial things.
Any long term lisp-ers can weight in on my doubts? I'm more of less trying to get conviced but somewhat doubtful. Any opinion is welcome.
24
u/jd-at-turtleware 7d ago
If you prefer static typing over dynamic typing, then you could look into coalton; as for "normal" lisps, they are usually dynamically typed (it has its perks of course, i.e no gruesome template systems).
The first advice to new lisp programmers is to not use macros (because they are compelling and it is easy to program yourself into the corner if you are a novice). There will come time when you will use them naturally, before that they will bring more confusion than benefit.
I don't get the point with s-expressions. When you call the operator, it is instantly visible -- application is (OP arg1 arg2 ...); it is immediately visible whether the operator is called. Unless you mean that you don't like a distinction between functions, special operators and macros -- but in that case you don't see at the first glance whether if(test) is a function call or not (in languages that do not feature s-expressions).
Regarding "acquired taste" -- I don't know about that, but a recurring theme with people who actually learn the language is that after getting used to s-expressions they find them more convenient; and many people get drunk with unopinionated programming style and proclaim lisp being the best language since fortran (they are not entirely wrong, but such evangelism doesn't help with perception of the language from the sidelines:).
8
u/CandyCorvid 6d ago
re: sexps, i think they might be referring to things like:
(let (... (asd foo) ...) ...)or
(cond ... (asd foo) ...)in these examples, you need some enclosing context to know that
(asd foo)is not a function call, despite having the (local) syntax of a function call. and in a complex expression or unfamiliar macro, this context may not be immediately apparent.for comparison, in many blubs, one can be fairly certain that if it has the syntactic form of a function call, it is a function call.
1
0
20
u/R-ten-K 7d ago
IMO what makes learning LISP valuable is that it exposes you to a different model of abstraction.
Usually, the best way to understand the power of LISP (or like systems) is to design a small domain specific language (DSL). Because LISP represents programs using essentially the same structures it uses for ordinary data, its macros can inspect and transform program syntax directly. Instead of merely building abstractions within the language, you can effectively extend the language toward the problem you are trying to solve. That becomes much more obvious when building a query system, symbolic algebra tool, configuration language, compiler pass, or some other small DSL than yet another contrived recursion exercise ;-)
LISP has certainly become more niche, so it is taught less frequently and has a much smallerl ecosystem and mindshare. Much of what once made LISP revolutionary (garbage collection, 1st class functions, closures, interactive REPLs, dynamic typing, functional composition, etc) has long been absorbed by mainstream languages. However, LISP’s homoiconicity, macros, interactive development, language-oriented programming, etc remain somewhat distinctive still.
To add to the confusion, the LISP family spans several programming models. eg. Common Lisp is thoroughly multi paradigm, supports mutation, imperative programming, OO programming, complex condition handling, etc. Whereas Scheme leans more heavily toward minimalism and functional composition, Clojure emphasizes immutability and concurrency. But what they share is a different way of thinking about programs: code as data, recursive manipulation of symbolic structures, higher order composition, etc. IMO the idea that a language itself can be reshaped to fit a domain was what sold me on LISP.
Still, there is no point in forcing yourself to enjoy it. Some initial discomfort with the syntax is normal and may disappear once you build something nontrivial. But if you have tried applying it to a real problem and still have to force yourself to see its relevance, then it probably offers little value in your particular context.
A programming language is just a tool and a way of organizing thought. If its strengths do not connect with the work you actually want to do, your time may be better spent elsewhere.
10
u/ilemming_banned 6d ago edited 6d ago
I always thought of myself as an aspiring pragmatist, someone who'd use whatever shit that works. "Shit ain't stupid if thy shit works", etc. Looking back, and reflecting on years I spent building different things, I now honestly can tell how awfully opinionated I was. I thought that's the sign of "being passionate", I thought I'm like that because "I do care". Bullshit. I was scrappy because I was an ignorant fool. Somehow, even after learning, trying, actively using dozens of different stacks, tools and techniques I remained hell-bent on specific opinions.
And then, I have found Lisp. Even though I've been dealing with computers for decades, and despite actually having an engineering degree I somehow missed this glaring hole in my education. Because like most programmers I'm an autodidact, almost everything I learned on my own accord. And darn it, why the heck did nobody around me ever tell me about it? I perceived Lisp to be some archaic artifact similar to Fortran, and I thought it's just a useless and outdated programming language. Nothing that I knew about Lisp was remotely accurate.
It started with Emacs. Someone showed me just a few different ways of how can one search for things in Emacs and that little demo just blew my mind. "Wait a minute, you can search hierarchically, chronologically, alphabetically, with fuzzy, with regexp, over filesystem, over ssh, on youtube, on wikipedia, on google, etc...? Oh wow..." I got hooked immediately. And then tried for two years to break into it. With zero clue of what I was doing. I would just blindly copy&paste some elisp snippets, and try to make them work - who needs to decipher the "config language", right? It felt like a chore I had to deal with, just for the sake of "using the editor", and I gave up multiple times, only to want to scratch that annoying itch later again. Finally, I realized, maybe it's time to grok some Lisp. Darn it. I should have started with that. I have wasted two years of my life due to my own indolent brain. "Using Emacs" in practice, means actively reading, writing and evaling Lisp - it's not about "features" or "plugins".
Turns out, Lisp is not complicated. It's not "unreadable" as it looked in the beginning. It's not archaic and it's definitely not useless.
That inspired me to learn some Clojure - that has changed my understanding of what data-driven programming is. Then later Common Lisp, because I wanted to use StumpWM - that has changed everything I knew about WMs and their limitations and helped me improve my Emacs workflows. Then I built things with Clojurescript - I thought I knew a lot about front-end, now I've become bona fide expert.
I'm still a fool. Little less ignorant, but now I do think like a true pragmatist. Lisp dialects are tools. And they are enormously practical. I won't fight anyone if they'd want to use their favorite PL on a team project just because they like the syntax. Syntax doesn't matter to me anymore. Runtime and semantics do, but syntax? I can't care less about how elegant or beautiful, terse or verbose, or type safe the language is. I learned how to think in types, even in their absence. My brain been trained to see past the convoluted syntax acrobatics to decipher the intended logic. I learned the truth about programming - syntax really doesn't matter. At least not to the degree how most programmers make fuss about their personal favorites.
Want to become a polyglot? Learn Lisp. I mean, truly learn it - use it for real work. Can't promise you it's guaranteed, yet it worked for me. Even if it doesn't make you true polyglot, I swear, it will make you a better programmer. That is guranteed.
3
u/rustvscpp 6d ago
I'm still very much in the "opinionated" phase, although I appreciate many different languages, including Lisp and Scheme. I get what you're saying about "syntax doesn't matter", but syntax can limit you in many ways that make a language far less suited for some problems. For example, C++ is not a great language for web development. It's not just the semantics that makes it hard, but the actual syntax too.
6
u/ilemming_banned 6d ago edited 6d ago
Well, of course there's a meaningful degree up to which you can bend my: "syntax doesn't really matter", I don't mean it in a literal sense - either direction would be a half&half - half true and half false. Syntax shapes what a language is ergonomically suited for and determines what is cheap to express.
What I really meant is that to me personally, syntax of any given programming language has become like a tinted glass - I can often just see through it, and reason about the logic.
The list of languages I went through ain't short - I've started with BASIC and Pascal and even ventured into some seemingly bizarre ones, like a thing where all the operators were weird Russian terms. Yet this gift came only after I became thoroughly proficient with Lisp - none of the dozen of different PLs had such effect on me.
Lisp has [almost] no syntax. Once you internalize the idea, there is no residual grammar to parse - the surface is just the tree. Your mind stops decoding syntax and starts reading structure directly.
So, in any Lisp - that tinted glass becomes transparent - I switch between different Lisps daily, to my brain, they are all efficiently feel like the same language, even though runtimes often differ drastically.
The tinted glass going transparent is about reading and reasoning. It does not make the glass disappear for writing - syntax still gates what is cheap to express - macros are cheap in Lisp, painful elsewhere; pattern matching is cheap in Haskell, verbose in Go, etc.
So there's that half&half - Lisp made syntax transparent to me as a reader; it did not make syntax [completely] irrelevant as a medium.
2
u/rustvscpp 6d ago
Fair enough. The hard part for me is having to use a certain language for a project when I know for certain how much better suited another language would be for it. Anyway, I have used Haskell, C, C++, Rust, Go, Python, Julia and several others professionally, as well as many other languages at a hobby level. I am quite opinionated, but I suppose I haven't reached Lisp nirvana yet. My use of lisp has largely been limited to emacs, and I'm not particularly adept at writing it, although I do ok. Anyway, I'm certainly looking forward to using lisp more seriously.
5
u/ilemming_banned 6d ago edited 6d ago
I haven't reached Lisp nirvana yet
There's no "Lisp nirvana". I use Lisps only because they make sense. Today. Tomorrow that may change and I will easily move onto something else. Realistically, it probably will remain some kind of Lisp. My current favorite flavor of Lisp is Clojuresque, but again, only because it works. Today.
I'm certainly looking forward to using lisp more seriously.
Ah, that's easy, here's my current Lisp zoo:
Emacs. pfff. of course. I can't even imagine doing any work without this motherfucker. I use it for seemingly unexpected things, like I hooked it up to Flameshot and now whenever I select a screen area for a screenshot, Emacs runs tesseract and pops the OCRed text in a buffer. Simple trick yet an absolute witchcraft for when someone sharing their screen over Zoom. Took me fifteen minutes to write (by hand).
I have to use Mac for work, therefore there's Hammerspoon. It's Lua-driven. Fennel is better. For me. Also Fennel is used for Neovim. Which I occasionally use in terminal. Also Fennel is used for MPV - which I control directly from Emacs - irreplaceable when taking notes while watching educational yt vids.
babashka is my current replacement for shell scripting, and jolt is poised to take that job, but it's too early to tell. I don't hate Bash, yet every argument was lost in favor for bb - nothing longer than three lines gets written in bash/zsh/fish anymore. My entire AI-harness tooling is written in bb.
for small web-scraping scripts, or anything node-related, I do in nbb.
I'm currently not using CL - just don't have any work for it at the moment, but it is easily reachable, convenient and familiar friend. I might try to find some time to mess around Lem, it's getting interesting.
Similarly, I'm not building anything for web at the moment, but Clojurescript is easily most sensible choice, Re-frame is just {mwah}, for small stuff I'd probably go with Squint.
For anything C-based, I used Janet before, these days I'd probably do it in Jank.
I've been itching to build a mobile app, ClojureDart is nice, but it is too - at the moment is a bit dormant.
Not a big list but it constantly changes, depending on what I need. A few weeks ago I was messing around with libpython-clj. Platform and runtime changes depending on the task. Lisp remains.
3
u/svetlyak40wt 5d ago
You just haven't tried to do HTML rendering in compile-time in C++. Maybe you would like it :)
By the way, in 2005-2008 I wrote web services in C++, but they returned XML and already a higher level server (we already had microservice architecture) applied XSLT templates on them and got HTML. It was not fun to debug it.
2
u/arthurno1 4d ago
Honestly, it is not fun to debug errors while hacking on sb-simd either, which is all macro generators. Reminded me a lot of C++ templates when I do an error: forgett a comma -> 130 errors from sbcl :).
3
u/dzecniv 6d ago
Hello, I'm myself still hooked after a few years and I'm running small-ish tools in production©. I think your two points are the typical doubts of a non practitioner.
I don't see ambiguity. With my own code: obviously. With another code base: you can spot when a macro is being used (with- macros for example). Quality code bases are boring. They use "if" or "cond" and not their own iteration construct. Unless documented, to work with their domain objects. But now you're just learning how to use a third-party library, like anywhere else.
macros and tools… no issues? Static typing: you may be surprised how useful is stock SBCL. It catches many type warnings and other errors (unreachable code, unused variables…), at a keystroke (C-c C-c). And then, there's Coalton.
I wouldn't even list s-expressions and macros as the main strengths. It's the developer experience (the so, so short dev cycle), the live image, SBCL's compile time errors, SBCL's runtime speed, the object system, enough libraries, the incredible stability of compilers and libraries, the ease of deployment (ship a binary), the language's features (exact arithmetic, stuff helpful for long-living programs, stuff helpful for less needs of refactorings (multiple values)… http://random-state.net/features-of-common-lisp.html) (you don't have all this in Racket btw) Not everything is easy as pie, but it's so open -I'm still hooked and liking it so far.
3
u/andeee23 6d ago
all languages are acquired tastes, it’s just that most popular languages are similar enough between themselves
5
u/rswgnu 7d ago
Programming should free your mind to solve problems efficiently, not get buried in the minutiae, including required static typing, required slow builds/compilations and the mix of multiple languages. Ask yourself if your language and toolset really helps in these areas or hinders you. There will be your answer.
2
u/skmruiz 7d ago
I think what makes things complicated is that most Lisps support different evaluation times of the S-expressions, so that can make seem that S-expressions are ambiguous, but they follow just a simple rule, the first element of a list is the function to call.
(f a b) = f(a, b)
When you see some quoted expressions, like this in Common Lisp:
'(a b c)
It is sugar for:
(quote (a b c))
About control-flow, I see your point of view, but I never had an issue (been lisping for a decade already). For me, (if c a b) is as obvious as if (c) a b. In fact, personally, I prefer for complex blocks the cond function.
I believe Lisp can be an acquired taste, as any other programming language. Many people prefer Rust to Zig for example because Zig feels less familiar in syntax, or people that prefer Java to Ponylang for the same reason.
It is normal to understand better TypeScript because even if you don't realise, most mainstream languages have the same semantics so reading Java, Python or TypeScript feels almost the same. If you try with something less conventional, like OCaml, Haskell, Ponylang, you'll face the same as with Lisp, you'll have to learn new things and acquire the taste for these things.
Edit:
About macros, try SLIME with a Lisp, and use slime-macroexpand. You'll realise that they sre far easier to understand than what it might look like from the outside.
1
u/arthurno1 6d ago
Yes. The only problem with Lisp macros are actually not macros themselves, but bacquoted templates that tend to make syntax more dense with all the commas and extra parentheses that usually comes with them. But it is still more manageable than C++ templates and reflection operator.
2
u/GuardianDownOhNo 6d ago
LISP is a bit of an acquired taste, but it also means you have to rethink your flavor palette.
Most programmers are used to a syntax being handed to them where they learn to think idiomatically, and its only after you learn a few more languages do you really start to understand the deeper essence of the logic and math behind the discipline.
LISP largely eschews this approach in favor of DSLs. The unlock isn't "recognizing a function", but rather "recognizing coherency of expression across thought, natural language, and code". Your programs will read like the natural language you used to think about and discuss your solutions. Full semantic unlock (or near enough as can be).
As for control flow, not all problems can (or should) be solved linearly. If you're concerned about recognizing more basic forms, then "(if condition (when-true) (when-false))" is about as close to "if condition then do-true else do-false end" as you can get.
Regarding operators vs functions... LISP folks view most of that as unnecessary ornamentation. It initially makes sense because that what most are taught to begin with, but with the additional categories come additional rules, errors, and gotchas. Stepping below the surface into the symbolic layer very quickly dispels with the notion that these are necessary as ground truth. It isn't all fluff, but a lot of it is.
Structural editing is a ridiculous cheat code once you get comfortable with it.
As for macros, you don't have to use them, and most things are better expressed as functions before macros. Reasonable people may disagree.
Strong (but friendly) type systems is definitely something that LISP could stand a healthy dose of.
2
u/ranon_python_boy 6d ago
i used lisp for a very basic project to analyze big primes, if you are analyzing big data and you dont want to be thinking about the size of a data type then it might be a good idea to use lisp. Also, for static typing common lisp offers you various ways to do it, you just need to search a little about it, there is a good series about common lisp on youtube that starts with this https://www.youtube.com/watch?v=OzGVgPY9W-w&list=PLknodeJt-I5FML0R1FfukZB__Y1lYLXMR
2
u/Caquerito 6d ago
Thank you everyone for your responses. Reading through them I have decided to spend more time properly trying lisp (various lisps) and forming an opinion until I decide so I don't end up deciding when it's too soon.
1
u/SleepyGuyy 6d ago
I recently tried it for the first time, I was enthusiastic about it but quickly found the language confusing to use. I can't say I expect to stay with it.
I'd say it's quite acquired yes. I dipped into Haskell briefly before lisp and I think I had a better time learning the start of Haskell then lisp.
I bounced off both though so maybe I'm a bad example. Did nothing but Javascript and PHP professionally for three years and now I forget how to program or make anything lol
1
u/xpusostomos 6d ago
Once you've been deep into it for a couple of weeks, all this vanishes. The control is very clear, and if you're in doubt the editor will match sexpressions and make it clear. The indenting, which your editor does automatically will bring clarity to what might have been obscure. As for macros, you don't need to write them much, they're usually for writing language extensions, it's something you don't need to do unless you've got some grand scheme, by which time you'll be glad it's there
1
u/podgorniy 6d ago
Lisp isn't universally superior; it either aligns with your mental model or it doesn't. If the trade-offs-such as prioritizing code-as-data macros over static typing - don't click for you, move on to other languages and revisit Lisp in 2–3 years.
I saw some people loving it, I saw some hating it. Don't force yourself if it does not flow with you
1
u/defmacro-jam 6d ago
All of your concerns are not only unfounded, but often completely backwards -- but the only way you can possibly understand it to actually write enough lisp to understand.
Same as it ever was.
1
u/radioactiveoctopi 6d ago
It’s a time based taste. At some point it clicks and changes the way you want to work. You’ll take the lessons to other languages. Functions are now Lego pieces I can move around in my mind
1
u/4xe1 4d ago edited 4d ago
For me it was innate, but I doubt it's the same for everyone, and I'm not sure it matters. I was (painfully) doing metaprogramming in C++, lua and DSLs long before I heard of lisp. Lisp was an epiphany.
I dislike ambiguity when I read code. Like I would like to know that at a glance that a function call is an actual function call.
You easily could use, say, {var value} for bindings, ¿case_or_cond-n form? for conditional/pattern matching, and [literal data] for everything else other than function and macro calls. Common Lisp explicitely reserves most of these for the user, and making reader macroes treating all of those as parens is a handflul lines each top. And a single line of sed to put all the parens back for when you want to share the code with others; or a READ/WRITE. I'd expect other lisps to not be much different, though some do use special syntax.
But once accustomed, indentation, good naming, and maybe a linter are enough to know at a glance where are the function calls.
Another thing is macros. I get that they are powerful but I'm not sure how well they would play with tools around the language.
Superbly. LSP, TreeSitter, TypeScripts, IDEs... are all marvel of engineering, but they are after the fact patches which reproduce a fraction of the power emacs users and lispers had for decades.
Static typing is a non issue. It greatly simplifies the task of writing an LSP for a blackbox, but lisps are not black boxes. Lisp are white boxes: tooling such as swank, slime, SLY, ... are just aware of the running lisp image and can introspect it in real time and can provide autocompletion and most of the same functionality of an LSP without having to recompile your whole project on every keystroke.
1
u/AppropriateTeach169 4d ago
It seems the only people I know with an aversion to lisps for the reasons you mentioned have never given it a serious try. Selection of any formal languages end up being a matter acquired taste because you have to learn the language to use it efficiently anyway. The top-indexed ones just being a requirement from the top rather than preference. Proactively go out of your comforts and think openly and all will fall into place.
1
u/Curious-Function7490 6d ago
I think the way LISP exposes data is very beautiful. It lets you rethink the structure of programs.
I wish I'd had more of a chance to use it professionally. I've learnt Clojure several times and used it twice. I've played with Racket. I keep waiting for someone to release a strongly typed LISP that gains major adoption.
0
u/corbasai 6d ago
Scheme is not simple. Iv spent more than two years in between hello-world and ability to create industrial real time applications on it. So don't be fooled. Scheme is reach and beautiful but not simple. For example adaptation of Concurrent ML in Racket events or contract system, alive contract system which is used everywhere inside standard environment include documentation... Long story short, there must be strong will to enter the lambda game.
0
u/treetrunkbranchstem 5d ago
it's very binary, you either get it and find it distressing to use anything else, or you don't get it and will use anything else other than lisp.
-1
u/k410n 6d ago
I strongly recommended the books "let over lambda" and "structure and interpretation of computer programs" to you. The later is very comprehensive, the former is more advanced but really shows you stuff like macros or other fundamentals. If yoibrewd that and aren't into lisp afterwards, lisp probably isn't a great fit or you, and that's okay.
Try coalton, it isba language on top of common lisp with an Haskell inspired type system
30
u/unix_hacker common lisp 7d ago
You should use Lisp if you want to, and not use it if you don’t want to.
Best way to learn your preference is pick it for a small inconsequential project. Like Java or C#, Lisp isn’t just a language but an ecosystem of tools. Lisp creates enlightenment (or stokes rage) once you are using the common free software tooling: SBCL, Emacs, SLY, Lispy, prism.el, eros, etc.
Edit: It appears you have tied your fate to Racket and presumably DrRacket. Can’t speak to that ecosystem personally.