4 ms·
> it's often highly interactive, and value oriented. You get to "touch" the data a bit like material. Nowadays repl's are common, so it doesn't seem special but
by kbp 9y ago
> it's often highly interactive, and value oriented. You get to "touch" the data a bit like material. Nowadays repl's are common, so it doesn't seem special but it was so for 30years.
REPL's are common, but they're rarely as useful in other languages. Even relatively basic (to Lisp programmers) things are almost universally missing, for example:
[1]> (defun f (x) (1+ (g x)))
F
[2]> (f 4)
*** - EVAL: undefined function G
The following restarts are available:
USE-VALUE :R1 Input a value to be used instead of (FDEFINITION 'G).
RETRY :R2 Retry
STORE-VALUE :R3 Input a new value for (FDEFINITION 'G).
ABORT :R4 Abort main loop
Break 1 [3]> :r3
New (FDEFINITION 'G)> (lambda (x) (* x 2))
;; Now that we gave an fdefinition for G, our (f 4) call can continue, so it
;; resumes execution and completes. Until now, it was just paused--no stack
;; unwinding unless we ask for it.
9
[4]> (g 10)
;; Because we used STORE-VALUE, it went ahead and saved the value we gave in
;; G for future use. If we had used USE-VALUE, it would have finished the (f
;; 4) call using that definition, but G still wouldn't be fbound after.
20
> lists mindset is different from mutable arrays
Mutable arrays are ubiquitous in Lisp. Explicitly cdring down lists is mostly only done in introductory textbooks; in practice, most people will use MAP, REDUCE, REMOVE-IF-NOT, etc instead, which all work just as well on arrays or lists, or they might use an imperative construct like DO, LOOP, or ITER (also note that conses are mutable as well; it's not at all unusual to setf a car or cdr or call NCONC). It's not terribly different from what you would do in eg modern Java (aside from the part where none of it requires special support from the implementation and it could all be implemented in user code).
I would also add that learning Lisp will teach you a lot about object-oriented programming. Even things that Java programmers use extensions for and give names like aspect-oriented programming just come built in as part of Lisp's stock object system. But then, Lisp's stock object system is also extremely flexible, especially given the pseudo-standard metaobject protocol. Quoting from Wikipedia about the MOP book:
"In his 1997 talk at OOPSLA, Alan Kay called [The Art of the Metaobject Protocol] "the best book anybody's written in ten years", and contended that it contained "some of the most profound insights, and the most practical insights about OOP", but was dismayed that it was written in a highly Lisp-centric and CLOS-specific fashion, calling it "a hard book for most people to read; if you don't know the Lisp culture, it's very hard to read"."
- agumonkey 9y agomap / filter over list is different from arrays. Even in the 2000s we had to hand write Java Iterators and fear mutation while iterating .. that sort of things.
- kbp 9y ago> map / filter over list is different from arrays. How? CL-USER> (remove-if-not #'evenp '(1 2 3 4 5)) (2 4) CL-USER> (remove-if-not #'evenp #(1 2 3 4 5)) #(2 4) CL-USER> (loop for x in '(1 2 3 4 5) when (evenp x) do (format t "~&~a~%" x)) 2 4 NIL CL-USER> (loop for x across #(1 2 3 4 5) when (evenp x) do (format t "~&~a~%" x)) 2 4 NIL Even a function like: (defun print-evens (sequence) (loop for i below (length sequence) for x = (elt sequence i) when (evenp x) do (format t "~&~a~%" x))) Works for both, although it's considerably more efficient for arrays. > Even in the 2000s we had to hand write Java Iterators and fear mutation while iterating .. that sort of things. And even in Lisp, the standard specifies "The consequences are undefined when code executed during an object-traversing operation destructively modifies the object in a way that might affect the ongoing traversal operation."
- agumonkey 9y agoIn non lisp languages, the mutable array often came without map / filter, weren't generic, didn't have lambdas so you end up writing imperative loops and potentially mutating elements in place because it's tempting; changing the paradigm right away
- kbp 9y ago> In non lisp languages, the mutable array often came without map / filter What languages do you know that have map and filter for lists, but not for arrays? Lisp has them for both, C++ has them for both, Java has them for both; Java didn't used to have lambdas or map, but it had standard lists long before it got either of them. Several decades before Java existed, Lisp had mutable arrays with map and filter. Supporting higher order functions has nothing at all to do with arrays vs lists. > didn't have lambdas so you end up writing imperative loops Lisp does have lambdas and imperative loops are still extremely common in Lisp code.