4 ms·
Just look at some simple uses of closures and you'll see they open a world of possibilities. (and there's so much more to it than this!) They also let you make
by Hexstream 18y ago
Just look at some simple uses of closures and you'll see they open a world of possibilities. (and there's so much more to it than this!)
They also let you make compilers easily but I won't get into that here.
CL-USER> (sort (list 1 8 3 2 5) #'<) ; sort just needs a function of 2 arguments that tells if the first parameter is strictly less than the second
=> (1 2 3 5 8)
CL-USER> (sort (list 1 8 3 2 5) #'>)
=> (8 5 3 2 1)
CL-USER> (sort (list "hello" "HELLO" "hey" "bye") #'string<)
=> ("HELLO" "bye" "hello" "hey")
CL-USER> (mapcar #'1+ '(1 7 3 9))
;mapcar applies a function to each element of the lists passed as arguments and returns a new list with the results
=> (2 8 4 10)
CL-USER> (cons 1 2)
=> (1 . 2)
CL-USER> (mapcar #'cons '(A B C) '(1 2 3))
=> ((A . 1) (B . 2) (C . 3))
CL-USER> (defun make-adder (how-much-to-add)
(lambda (initial-value)
(+ initial-value how-much-to-add)))
=> MAKE-ADDER
CL-USER> (mapcar (make-adder 10) '(1 7 3 9))
=> (11 17 13 19)
CL-USER> (defvar *my-favorite-adder* (make-adder 42))
=> *MY-FAVORITE-ADDER*
CL-USER> (mapcar *my-favorite-adder* '(1 7 3 9))
=> (43 49 45 51)
CL-USER> (defun make-modifier (operator operand) ; a bit more general than make-adder
(lambda (initial-value)
(funcall operator initial-value operand)))
=> MAKE-MODIFIER
CL-USER> (mapcar (make-modifier #'expt 3) '(1 7 3 9))
=> (1 343 27 729)
CL-USER> (find-if #'numberp '(a "hi" nil 8 "test" 100))
=> 8
CL-USER> (find-if #'numberp '(a "hi" nil 8 "test" 100) :from-end t)
=> 100
CL-USER> (apply #'+ (remove-if-not #'numberp '(a "hi" nil 8 "test" 100)))
=> 108
That's not even (by a long shot) the tip of the iceberg.
- 13ren 18y agoHere's the equivalent (of some) in Python: def make_adder (how_much_to_add): return lambda initial_value: initial_value + how_much_to_add print map ( make_adder(10), [1, 7, 3, 9] ) # [11, 17, 13, 19] my_favorite_adder = make_adder(42) print map ( my_favorite_adder, [1, 7, 3, 9] ) # [43, 49, 45, 51] def make_modifier (operator, operand): # a bit more general than make_adder return lambda (initial_value): operator(initial_value, operand) print map ( make_modifier(pow, 3), [1, 7, 3, 9] ) # [1, 343, 27, 729] note: The lisp syntax looks weird to me, but in converting this, I really noticed the convenience of lisp's (1). symbols (not needing quotes); and (2). lists (not needing commas). Interesting.
- yters 18y agoIt's simple to compile because lisp is essentially a parse tree, which eliminates the parsing stage in compilation.
- Hexstream 18y agoI was referring to the ability to traverse a tree structure (made of conses or objects) and generate a tree of closures from that. Instead of interpreting the tree structure, you make a first pass where you do a lot of dispatching in advance (at runtime you'll just do what you must do instead of first figuring out what to do and then do it), generating a tree of closures. Then you call your "top-level" closure for a nice optimized run. You can optimize your source tree before compiling this way, for some crazy speed. All this without having to read advanced books about low-level compilers, parsing, machine architecture and optimization!
- yters 18y agoV. interesting, thanks:)