Lisp is a fun language to program in. I learned Lisp after already being familiar with Java / Python and some other languages, which maybe made it even more beautiful.
One of my favourite pieces of code is a Lisp REPL in Lisp:
as-> is great for when you have to mix thread-first and thread-last.
cond-> is great for building maps where some keys might not be needed:
(cond-> {:k1 v1}
v2 (assoc :k2 v2)
...)
some-> and some->> I don't use as often, but when mixing in some java code that could throw an NPE, these will avoid that and just return nil early (they short-circuit when getting a nil value).
`input` isn't READ, it's READ-LINE. READ reads one Lisp form, even if it's more than one line, and even if there are more than one on one line.
Python's `eval` also isn't sufficient here. For example, you cannot enter that loop you wrote at the prompt it provides when you run it, even if you write it on one line. You could use `exec`, but then everything would print as `None`.
There's the larger point about forms vs strings and printing readably and such, but this doesn't even provide the same basic functionality that a Python programmer would expect from a REPL.
I guess I just prefer Ruby for general legibility. The same type of bracket everywhere makes pairing them mentally an error-prone chore. At least for yours truly.
puts and gets are string functions. read and print are code deserializers and serializers.
eval is a function that takes a data structure representing code (as deserialized by read) and computes its value as a data structure, and serializes it.
While you might get the same effect as a user, the mechanics and metacircularity are lost.
One of my favourite pieces of code is a Lisp REPL in Lisp: