"Fexprs more flexible, powerful, easier to learn? (Newlisp vs CL)" @ c.l.l.
Rainer Joswig (with some participation from Kaz Kylheku and Pascal Bourguignon) on a practical example explain, what problems of dynamic scope (still used in the suggested "improved" newLisp, which turns out to be old, actually :) are solved by lexical scope.
Bonus: how to create lisp-style special global variables in C++ (and a discussion of what can be improved in CL in this regard)
Showing posts with label cl. Show all posts
Showing posts with label cl. Show all posts
2009-02-01
2008-12-23
Surprise with Lambdas
Tobias Rittweiler posted an explanation about the difference between (lambda and #'(lambda. The article is really useful, because I remember several times seeing the question in discussions unanswered.
Well, after reading LoL I sticked to using (lambda variant and I consider it to be the right thing: the less tokens, the less questions and confusion.
All I can add is, that Common Lisp continues to surprise me with how well thought it's design is. So, throw away the reader macros — it works by itself :)
Well, after reading LoL I sticked to using (lambda variant and I consider it to be the right thing: the less tokens, the less questions and confusion.
All I can add is, that Common Lisp continues to surprise me with how well thought it's design is. So, throw away the reader macros — it works by itself :)
2008-12-14
1 namespace to rule them all
This thing scares and confuses me:
Is even a function or a var?
Personally I'd prefer:
Common Lisp's n-namespace property is one of the most underestimated features of this most underestimated language. In CL you virtually always know, what you are dealing with, a variable or a function. "Phew!" you say, "in C++ as well". Not so fast. If you try to use callbacks you don't. And when we enter the realm of the functional paradigm, where functions fly all around like daggers in the infamous house, it's really good to know for sure.
Let's restate the rules:
1. Prefix notation: in first position of a form should always be a name of a function/macro/special operator (unless it's an inner form of a macro, which introduces its own structure). So:
* (+ 1 2), not (1 + 2)
* (print 1) -- just like print(1)
* (with-open-file (in "test.txt") ...) -- a structural macro
2. If you want to pass a function somewhere #' is your best friend. Thus you can (fun)call it, apply it, map/filter with it etc.
3. Finally we need to add one more ingredient to the recipe -- the ability to use (lambda ...) forms in function position. We can do it with such a reader macro:
which allows us to write this code:
filter even [1..10]Is even a function or a var?
Personally I'd prefer:
filter #'even [1..10]Common Lisp's n-namespace property is one of the most underestimated features of this most underestimated language. In CL you virtually always know, what you are dealing with, a variable or a function. "Phew!" you say, "in C++ as well". Not so fast. If you try to use callbacks you don't. And when we enter the realm of the functional paradigm, where functions fly all around like daggers in the infamous house, it's really good to know for sure.
Let's restate the rules:
1. Prefix notation: in first position of a form should always be a name of a function/macro/special operator (unless it's an inner form of a macro, which introduces its own structure). So:
* (+ 1 2), not (1 + 2)
* (print 1) -- just like print(1)
* (with-open-file (in "test.txt") ...) -- a structural macro
2. If you want to pass a function somewhere #' is your best friend. Thus you can (fun)call it, apply it, map/filter with it etc.
3. Finally we need to add one more ingredient to the recipe -- the ability to use (lambda ...) forms in function position. We can do it with such a reader macro:
(set-dispatch-macro-character #\# #\f
(lambda (stream subchar arg)
(declare (ignore subchar)
(ignore arg))
(let ((sexp (read stream t nil t)))
(let ((fname (gensym)))
(setf (symbol-function fname) (eval `(lambda ,@sexp)))
fname))))
which allows us to write this code:
CL-USER> (#f((a b) (+ a b)) 1 2)
3
2008-10-26
Monty Hall Paradox
The example of how tackling a problem in a "hacker's hat" can make a paradox trivial to understand.
And the statistics:
CL-USER> (monty-hall 100)
1.5641025
CL-USER> (monty-hall 1000)
1.6455027
CL-USER> (monty-hall 10000)
1.9958059
CL-USER> (monty-hall 100000)
2.0147724
CL-USER> (monty-hall 1000000)
1.9966408
CL-USER> (monty-hall 10000000)
1.9986455
(defun monty-hall (n)
"Returns a ratio of success rate to failure rate, if we follow
the strategy of always switching the initially selected door in
the Monty Hall Problem"
(let ((succ 0.0)
(fail 0.0))
(dotimes (i n)
(let ((choice (random 3))
(prize (random 3)))
(if (= choice prize)
(incf fail) ; we've chosen the right door, but will need to switch
(incf succ)))) ; we've chosen the wrong door and after switching -- the right
(/ succ fail)))And the statistics:
CL-USER> (monty-hall 100)
1.5641025
CL-USER> (monty-hall 1000)
1.6455027
CL-USER> (monty-hall 10000)
1.9958059
CL-USER> (monty-hall 100000)
2.0147724
CL-USER> (monty-hall 1000000)
1.9966408
CL-USER> (monty-hall 10000000)
1.9986455
Subscribe to:
Posts (Atom)
