Pascal Costanza wrote:
Indentation in Lisp is not clear enough. Let's look at an example from http://www-users.cs.umn.edu/~gini/aiprog/graham/onlisp.lisp:
(defun mostn (fn lst)
(if (null lst)
(values nil nil)
(let ((result (list (car lst)))
(max (funcall fn (car lst))))
(dolist (obj (cdr lst))
(let ((score (funcall fn obj)))
(cond ((> score max)
(setq max score
result (list obj)))
((= score max)
(push obj result)))))
(values (nreverse result) max))))
Note that only one pair of adjacent lines is indented by the same amount. Other alignments are in the middle of lines.
Here is a straightforward translation into my dream language; note that there aren't a lot of parens despite insignificant indentation and despite
using braces (like C) instead of bracketing keywords (like Pascal):
def mostn Fun [] = [], null;
def mostn Fun (First\List) {
var Result = [First];
var Max = Fun First;
each List ?Obj {
let Score = Fun Obj;
if Score > Max {Max = Score; Result = [Obj]}
if Score == Max {Result = Obj\Result}
};
reversed Result, Max
};
Apparently, Paul Graham doesn't like CLOS nor the LOOP macro. Here is another verson in Common Lisp (and this is not a dream language ;):
(defmethod mostn (fn (list (eql nil)))
(declare (ignore fn list))
(values nil nil))
(defmethod mostn (fn list)
(loop with result = (list (car list))
with max = (funcall fn (car list))
for object in (cdr list)
for score = (funcall fn object)
when (> score max) do (setq max score
result (list object))
when (= score max) do (push object result)
finally return (values (nreverse result) max)))
Gauche Scheme
(define (max-by func List)
(fold
(lambda (x best)
(let1 score (func x)
(cond ((or (not (car best)) (> score (car best)))
`(,score (,x)))
((= score (car best)) (push! (cadr best) x) best)
(#t best))))
'(#f ())
List))
(max-by (lambda(x) (modulo x 5)) '(22 23 24 25 26 27 28 29))
===>
(4 (29 24))
Try doing this in C++, Python, or whatever:
(do ((a 1 b) (b 1 (+ a b)))
(nil a)
(print a))
Here's a more realistic example that illustrates exactly theWell..
opposite point. Take the task of finding the sum of the square of a
bunch of numbers.
Do people really think to themselves when they do this task:
Umm first make a variable called sum
then set that variable sum to zero.
Then get the next number in the list,
square it,
add it to the old value of sum,
store the resulting value into sum,
then get the next variable,etc....
No they they think: sum up the square of a bunch of numbers.
This has an almost direct translation to the lisp style:
(apply '+ (mapcar #'(lambda(x)(* x x)) numlist)).
sum (map (\x -> x ** 2) [1..10])
in Haskell, or
sum (map ((lambda x: x ** 2), range(1,11)))
Too much line noise ;-)
sum([x*x for x in range(1,11)])
Then I would say that a clearer way to express what a person think is:
(loop for number in numberlist sum (expt number power))
Indentation in Lisp is not clear enough. Let's look at an example from http://www-users.cs.umn.edu/~gini/aiprog/graham/onlisp.lisp:
(defun mostn (fn lst)
(if (null lst)
(values nil nil)
(let ((result (list (car lst)))
(max (funcall fn (car lst))))
(dolist (obj (cdr lst))
(let ((score (funcall fn obj)))
(cond ((> score max)
(setq max score
result (list obj)))
((= score max)
(push obj result)))))
(values (nreverse result) max))))
Note that only one pair of adjacent lines is indented by the same amount. Other alignments are in the middle of lines.
Here is a straightforward translation into my dream language; note that there aren't a lot of parens despite insignificant indentation and despite using braces (like C) instead of bracketing keywords (like Pascal):
def mostn Fun [] = [], null;
def mostn Fun (First\List) {
var Result = [First];
var Max = Fun First;
each List ?Obj {
let Score = Fun Obj;
if Score > Max {Max = Score; Result = [Obj]}
if Score == Max {Result = Obj\Result}
};
reversed Result, Max
};
Apparently, Paul Graham doesn't like CLOS nor the LOOP macro. Here is
another verson in Common Lisp (and this is not a dream language ;):
(defmethod mostn (fn (list (eql nil)))
(declare (ignore fn list))
(values nil nil))
(defmethod mostn (fn list)
(loop with result = (list (car list))
with max = (funcall fn (car list))
for object in (cdr list)
for score = (funcall fn object)
when (> score max) do (setq max score
result (list object))
when (= score max) do (push object result)
finally return (values (nreverse result) max)))
| Sysop: | Amessyroom |
|---|---|
| Location: | Fayetteville, NC |
| Users: | 74 |
| Nodes: | 6 (0 / 6) |
| Uptime: | 22:19:57 |
| Calls: | 1,026 |
| Files: | 1,332 |
| Messages: | 290,354 |