Fast Backward!
Lisp is worth learning for the profound enlightenment experience you will have when you finally get it; that experience will make you a better programmer for the rest of your days, even if you never actually use Lisp itself a lot. – http://www.paulgraham.com/avg.html
So let's code like it's 1963, and explore the modernity and expressive power that the symbolic expression (s-expression) constraint offers!
- https://www.google.fr/search?q=1963+computer&tbm=isch
- https://en.wikipedia.org/wiki/S-expression
- Recursive Functions of Symbolic Expressions and Their Computation by Machine, Part I
To do that, let's try to extend the language expressivity by defining a pipe
macro that, by rearranging the s-expressions given in input, allows us to write:
(pipe x
(+ 6)
(sqrt)
(number-to-string))
instead of:
(number-to-string (sqrt (+ 6 x)))
Note to self: open Emacs, and code & explain the kata. See file below to read an implementation example.
Note to self: C-x C-+
to enlarge font (or C-M-=
and C-M--
with default-text-scale
).
Today, we can get pretty close to this expressivity in languages like JS with syntaxic sugar for lambdas & Python with operator metaprogramming, or even better in curry-by-default ML-type languages (Haskell &all).
JavaScript:
_.flow(x => 6 + x,
x => Math.sqrt(x),
x => console.log(x))(5);
Haskell:
Data.Function> 3 & succ & recip & negate
-0.25
But starting in 1959, Lisp was already closer to today's standards in expressivity than to the other languages of its time that I know of (think FORTRAN, COBOL).
Strong & well chosen constraints can sometimes yield strong leverage.
Some old languages still have gems & lessons that we can still benefit & learn from even today.
Other inspiring languages with strong constraints that I know of:
- Forth (1968)
- Stack based
- => Portable, small & efficient, easy to extend & maintain
- Smalltalk (1972)
- 100 % objects & messages only
- => Easy syntax, very low code complexity, modern realtime debugging tools
- SQL (1974)
- Strong structure based on the relational model
- => Easy to make cross products & data projections
- Erlang (1986)
- 100 % message passing, share-nothing between processes
- => Easier to write fault tolerant distributed systems
- Haskell (1990)
- Pure mathematical functions, no mutations, curry by default
- => Super easy to compose functions, really expressive type system