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)))
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
(use gauche.collection) ;; fold2
(define (max-by fn lst)
(if (null? lst)
(values '() #f)
(fold2
(lambda (x best worth)
(let ((score (fn x)))
(cond ((> score worth) (values (list x) score))
((= score worth) (values (cons x best) worth))
(#t (values best worth)))))
(take lst 1) (fn (car lst))
(cdr lst))))
(max-by (lambda(x) (modulo x 5)) '(22 23 24 25 26 27 28 29))
===>
(29 24)
4
On 6/28/2024 8:48 PM, HenHanna wrote:
On 6/28/2024 2:54 PM, B. Pym wrote:
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
(use gauche.collection) ;; fold2
(define (max-by fn lst)
(if (null? lst)
(values '() #f)
(fold2
(lambda (x best worth)
(let ((score (fn x)))
(cond ((> score worth) (values (list x) score))
((= score worth) (values (cons x best) worth))
(#t (values best worth)))))
(take lst 1) (fn (car lst))
(cdr lst))))
(max-by (lambda(x) (modulo x 5)) '(22 23 24 25 26 27 28 29))
===>
(29 24)
4
How do i avoid using -99999 ???
(define (print x) (newline) (write x) (newline))
(define (max-by fn Lis) (maxBy fn Lis '() -99999))
(define (maxBy fn x cLis cMax)
(cond
((null? x) (cons (reverse x) cMax))
((= (fn (car x)) cMax) (maxBy fn (cdr x) (cons (car x) cLis) cMax))
((> (fn (car x)) cMax) (maxBy fn (cdr x) (list (car x)) (fn (car x)))) >> (else (maxBy fn (cdr x) cLis cMax)))) >>
(print (max-by (lambda(x) (modulo x 5)) '(4 5 6 7 8 9 3 44)))
(print (max-by (lambda(x) (modulo x 5)) '(24 25 26 27 28 29 33 44)))
In Common Lisp, symbolic constants were defined for the IEEE plus and
minus infinities. I don't recall the syntax at the moment but do
remember they were quite useful in making certain codes easier to read
and understand.
Jeff Barnett <[email protected]> writes:
In Common Lisp, symbolic constants were defined for the IEEE plus and
minus infinities.
That's pretty horrendous either way (-99999 or -INF) . Better to return
an empty list in the event that that the input is empty.
In Common Lisp, symbolic constants were defined for the IEEE plus and
minus infinities. I don't recall the syntax at the moment but do
remember they were quite useful in making certain codes easier to read
and understand.
If a function like “max” or “min” is defined to return a number,
then it makes sense that the maximum of an empty list should be -∞,
and a lot of special cases no longer become special.
Lawrence D'Oliveiro <[email protected]d> writes:
then it makes sense that the maximum of an empty list should be -∞,
Meh, it's just undefined. Otherwise you can't tell whether the list is
empty or actually contains -∞ as a value.
There is an infinity of combinations of arguments to max that give -∞
as the function result; what’s so special about distinguishing the
empty argument list?
Lawrence D'Oliveiro <[email protected]d> writes:
There is an infinity of combinations of arguments to max that give -∞
as the function result; what’s so special about distinguishing the
empty argument list?
max is a two-argument function, just like +.
max is a two-argument function, just like +.Not in all the good languages.
In Haskell, max always
takes two args of an ordered type, and maximum takes a list arg.
maximum [2] gives 2 but maximum [] throws an empty list exception.
maximum just applies max repeatedly, like using reduce in Lisp.
... for the variadic versions in CL and Scheme, (max 2) gives 2
but (max) throws a wrong-number-of-args error.
Lawrence D'Oliveiro <[email protected]d> writes:
max is a two-argument function, just like +.Not in all the good languages.
Ah ok, yeah for the variadic versions in CL and Scheme, (max 2) gives 2
but (max) throws a wrong-number-of-args error. In Haskell, max always
takes two args of an ordered type, and maximum takes a list arg.
maximum [2] gives 2 but maximum [] throws an empty list exception.
maximum just applies max repeatedly, like using reduce in Lisp.
I believe that (max) and (min) would work just fine in CL if including
the IEEE infinities was required to be conforming. Without them or
something similar, it would be hard to make a sensible definition.
Also refresh my memory: doesn't CL define a map-like function that looks
like (MAP! binary-op list identity-element) so that:
(MAP! #'+ list 0) is the sum of the elements in the list
(MAP! #'* list 10 is the product of the elements in list
(MAP! #'max list -oo) is the max element in the list
(MAP! #'min list +oo) is the minimum element in the list
(MAP! #'append list nil) is the list made by appending the sublists
of list
etc.
In all of these if the list argument is nil, the result is the identity element.
On Wed, 03 Jul 2024 18:11:35 -0700, Paul Rubin wrote:
In Haskell, max always
takes two args of an ordered type, and maximum takes a list arg.
maximum [2] gives 2 but maximum [] throws an empty list exception.
maximum just applies max repeatedly, like using reduce in Lisp.
Seems unnecessary to have two functions when one will do.
In Haskell, max always takes two args of an ordered type, and maximum
takes a list arg.
Seems unnecessary to have two functions when one will do.
But then, Python max and min work for things besides numbers.
How about loop for greater clarity than either do or Python?
(loop
for a = 1 then b
and b = 1 then (+ a b)
do (print a))
Which neatly demonstrates the power of macros as well. If there's 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)))
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))
| Sysop: | Keyop |
|---|---|
| Location: | Huddersfield, West Yorkshire, UK |
| Users: | 715 |
| Nodes: | 16 (2 / 14) |
| Uptime: | 152:05:22 |
| Calls: | 12,091 |
| Calls today: | 4 |
| Files: | 15,000 |
| Messages: | 6,517,631 |