5 ms·
This is a common misconception non-lispers believes exist. Once you've written Lisp for a couple of months these problems disappear. The trick is not to try rea
by hacker_9 9y ago
This is a common misconception non-lispers believes exist. Once you've written Lisp for a couple of months these problems disappear. The trick is not to try reading it like an English sentence, but see it as a collapsing tree of functions:
(< 1 (+ 2 3))
collapses to
(< 1 5)
collapses to
true
Mentally when scanning Lisp code, I only hold the data in my headed needed for the current function, then I 'collapse' into the return value and swap out the old data in my working memory for the new data. It's worth noting that this collapsible style is why Lisp code can be so consistantly concise:
(let [a 1
b 2
c 3])
Or updating multiple items in a dictionary in one go:
(assoc dict :key1 val1
:k2 5
:k3 "value"))
So while the prefix notation seems odd at first, if you stick with it you can see how it really makes your life easier in the long run.
- randallsquared 9y agoLisp has a lot of things going for it. Being "concise" is not one I've seen argued, much. In (let [a 1 b 2 c 3]) vs let a = 1, b = 2, c = 3 or let a = 1, b = 2, c = 3 or even let a = 1 let b = 2 let c = 3 there's a saving in the lisp version of a token or two, at the expense of having additional meaningful structure / nesting. This isn't inherent to lisp, of course; there could well be a lisp that treats commas or some other visual separator as whitespace and thereby allows (let [a 1, b 2, c 3]) or (let a 1, b 2, c 3) ...but in general the benefits of lisp are about power, not formatting, in my opinion.
- hacker_9 9y ago> Being "concise" is not one I've seen argued Really? Lisp is the most concise and clear language I've ever used. There is almost zero boilerplate when writing it. The example was a simple one to get the idea across, you can create your own functions and do the same too: (my-let [a 1 b 2 c 3]) my-let could be a macro that compiles to a normal 'let', while also recording all variable names for some other use, or adding logging, or whatever you want. Another concise example is the -> macro to pass the result of a function in as the first arg of the next function: (-> a b c d e f) instead of (f(e(d(c(b(a)))))) These can all be argued against I'm sure as they are still simple. Check out some example code written in Clojure for a better view of conciseness [1] [1] https://github.com/oakes/play-clj-examples/blob/master/breakout/desktop/src-common/breakout/core.clj https://github.com/oakes/play-clj-examples/blob/master/break...
- kazinator 9y ago> there's a saving in the lisp version of a token or two, at the expense of having additional meaningful structure / nesting. You mean at the expense of losing the meaningful structure? I.e. the token count is one token smaller between these examples, in favor of the Lisp: (let [a 1 b 2 c 3]) ;; 11 tokens let a = 1, b = 2, c = 3 // 12 tokens but this comes from flattening the expression for the variable bindings.
- ohyes 9y agoThe lisp version includes the scoping of the variables. We have no idea if/when the variables in the second version go out of scope. This is a huge problem in languages that aren't lisp.
- urethrafranklin 9y agoNone of what you said is true. You might be so used to it that it seems fundamental, but lisp's scoping is as arbitrary as any language.
- ohyes 9y agoin any reasonable implementation of lisp the let is implemented with lexical scoping. This is because it is the transformation of a closed over lambda, and lambda arguments have lexical scoping akin to a stack push/pop. If it weren't it would just be a def/setf/defvar/defparameter. In the example given, assuming let has the same properties, we have no idea when the second 'let' statement ends, you would need something to signify the end of the block... there isn't anything in the given example. It could be implicit whitespace or something, but that isn't clear.
- deleted 9y ago[deleted]
- urethrafranklin 9y agoThis is something other languages do as well. Lisp zealots seem to think every other language is banging rocks together. Lexical scoping/closures/whatever are traditions independent of language or implementation. Nobody but you is having trouble understanding the scope of the algol example.