• Re: Why don't people like lisp?

    From B. Pym@21:1/5 to Pascal Costanza on Fri Jun 28 21:54:10 2024
    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

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeff Barnett@21:1/5 to All on Fri Jun 28 21:11:58 2024
    T24gNi8yOC8yMDI0IDg6NDggUE0sIEhlbkhhbm5hIHdyb3RlOg0KPiBPbiA2LzI4LzIwMjQg Mjo1NCBQTSwgQi4gUHltIHdyb3RlOg0KPj4gUGFzY2FsIENvc3RhbnphIHdyb3RlOg0KPj4N Cj4+Pj4gSW5kZW50YXRpb24gaW4gTGlzcCBpcyBub3QgY2xlYXIgZW5vdWdoLiBMZXQncyBs b29rIGF0IGFuIGV4YW1wbGUgZnJvbQ0KPj4+PiBodHRwOi8vd3d3LXVzZXJzLmNzLnVtbi5l ZHUvfmdpbmkvYWlwcm9nL2dyYWhhbS9vbmxpc3AubGlzcDoNCj4+Pj4NCj4+Pj4gKGRlZnVu IG1vc3RuIChmbiBsc3QpDQo+Pj4+IMKgwqAgKGlmIChudWxsIGxzdCkNCj4+Pj4gwqDCoMKg wqDCoMKgICh2YWx1ZXMgbmlsIG5pbCkNCj4+Pj4gwqDCoMKgwqDCoMKgIChsZXQgKChyZXN1 bHQgKGxpc3QgKGNhciBsc3QpKSkNCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICht YXggKGZ1bmNhbGwgZm4gKGNhciBsc3QpKSkpDQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqAgKGRv bGlzdCAob2JqIChjZHIgbHN0KSkNCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqAgKGxldCAo KHNjb3JlIChmdW5jYWxsIGZuIG9iaikpKQ0KPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgKGNvbmQgKCg+IHNjb3JlIG1heCkNCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgKHNldHEgbWF4wqDCoMKgIHNjb3JlDQo+Pj4+IMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJlc3VsdCAobGlzdCBv YmopKSkNCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgICgoPSBz Y29yZSBtYXgpDQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IChwdXNoIG9iaiByZXN1bHQpKSkpKQ0KPj4+PiDCoMKgwqDCoMKgwqDCoMKgICh2YWx1ZXMg KG5yZXZlcnNlIHJlc3VsdCkgbWF4KSkpKQ0KPj4+Pg0KPj4+PiBOb3RlIHRoYXQgb25seSBv bmUgcGFpciBvZiBhZGphY2VudCBsaW5lcyBpcyBpbmRlbnRlZCBieSB0aGUgc2FtZSANCj4+ Pj4gYW1vdW50Lg0KPj4+PiBPdGhlciBhbGlnbm1lbnRzIGFyZSBpbiB0aGUgbWlkZGxlIG9m IGxpbmVzLg0KPj4+Pg0KPj4+PiBIZXJlIGlzIGEgc3RyYWlnaHRmb3J3YXJkIHRyYW5zbGF0 aW9uIGludG8gbXkgZHJlYW0gbGFuZ3VhZ2U7IG5vdGUgdGhhdA0KPj4+PiB0aGVyZSBhcmVu J3QgYSBsb3Qgb2YgcGFyZW5zIGRlc3BpdGUgaW5zaWduaWZpY2FudCBpbmRlbnRhdGlvbiBh bmQgDQo+Pj4+IGRlc3BpdGUNCj4+Pj4gdXNpbmcgYnJhY2VzIChsaWtlIEMpIGluc3RlYWQg b2YgYnJhY2tldGluZyBrZXl3b3JkcyAobGlrZSBQYXNjYWwpOg0KPj4+Pg0KPj4+PiBkZWYg bW9zdG4gRnVuIFtdID0gW10sIG51bGw7DQo+Pj4+IGRlZiBtb3N0biBGdW4gKEZpcnN0XExp c3QpIHsNCj4+Pj4gwqDCoMKgIHZhciBSZXN1bHQgPSBbRmlyc3RdOw0KPj4+PiDCoMKgwqAg dmFyIE1heCA9IEZ1biBGaXJzdDsNCj4+Pj4gwqDCoMKgIGVhY2ggTGlzdCA/T2JqIHsNCj4+ Pj4gwqDCoMKgwqDCoMKgIGxldCBTY29yZSA9IEZ1biBPYmo7DQo+Pj4+IMKgwqDCoMKgwqDC oCBpZiBTY29yZSA+wqAgTWF4IHtNYXggPSBTY29yZTsgUmVzdWx0ID0gW09ial19DQo+Pj4+ IMKgwqDCoMKgwqDCoCBpZiBTY29yZSA9PSBNYXgge1Jlc3VsdCA9IE9ialxSZXN1bHR9DQo+ Pj4+IMKgwqDCoCB9Ow0KPj4+PiDCoMKgwqAgcmV2ZXJzZWQgUmVzdWx0LCBNYXgNCj4+Pj4g fTsNCj4+Pg0KPj4+IEFwcGFyZW50bHksIFBhdWwgR3JhaGFtIGRvZXNuJ3QgbGlrZSBDTE9T IG5vciB0aGUgTE9PUCBtYWNyby4gSGVyZSBpcw0KPj4+IGFub3RoZXIgdmVyc29uIGluIENv bW1vbiBMaXNwIChhbmQgdGhpcyBpcyBub3QgYSBkcmVhbSBsYW5ndWFnZSA7KToNCj4+Pg0K Pj4+IChkZWZtZXRob2QgbW9zdG4gKGZuIChsaXN0IChlcWwgbmlsKSkpDQo+Pj4gwqDCoMKg IChkZWNsYXJlIChpZ25vcmUgZm4gbGlzdCkpDQo+Pj4gwqDCoMKgICh2YWx1ZXMgbmlsIG5p bCkpDQo+Pj4NCj4+PiAoZGVmbWV0aG9kIG1vc3RuIChmbiBsaXN0KQ0KPj4+IMKgwqDCoCAo bG9vcCB3aXRoIHJlc3VsdCA9IChsaXN0IChjYXIgbGlzdCkpDQo+Pj4gwqDCoMKgwqDCoMKg wqDCoMKgIHdpdGggbWF4ID0gKGZ1bmNhbGwgZm4gKGNhciBsaXN0KSkNCj4+PiDCoMKgwqDC oMKgwqDCoMKgwqAgZm9yIG9iamVjdCBpbiAoY2RyIGxpc3QpDQo+Pj4gwqDCoMKgwqDCoMKg wqDCoMKgIGZvciBzY29yZSA9IChmdW5jYWxsIGZuIG9iamVjdCkNCj4+PiDCoMKgwqDCoMKg wqDCoMKgwqAgd2hlbiAoPiBzY29yZSBtYXgpIGRvIChzZXRxIG1heCBzY29yZQ0KPj4+IMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIHJlc3VsdCAobGlzdCBvYmplY3QpKQ0KPj4+IMKgwqDCoMKg wqDCoMKgwqDCoCB3aGVuICg9IHNjb3JlIG1heCkgZG8gKHB1c2ggb2JqZWN0IHJlc3VsdCkN Cj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgZmluYWxseSByZXR1cm4gKHZhbHVlcyAobnJldmVy c2UgcmVzdWx0KSBtYXgpKSkNCj4+DQo+PiBHYXVjaGUgU2NoZW1lDQo+Pg0KPj4gKHVzZSBn YXVjaGUuY29sbGVjdGlvbikgOzsgZm9sZDINCj4+DQo+PiAoZGVmaW5lIChtYXgtYnkgZm4g bHN0KQ0KPj4gwqDCoCAoaWYgKG51bGw/IGxzdCkNCj4+IMKgwqDCoMKgICh2YWx1ZXMgJygp ICNmKQ0KPj4gwqDCoMKgwqAgKGZvbGQyDQo+PiDCoMKgwqDCoMKgwqAgKGxhbWJkYSAoeCBi ZXN0IHdvcnRoKQ0KPj4gwqDCoMKgwqDCoMKgwqDCoCAobGV0ICgoc2NvcmUgKGZuIHgpKSkN Cj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgIChjb25kICgoPiBzY29yZSB3b3J0aCkgKHZhbHVl cyAobGlzdCB4KSBzY29yZSkpDQo+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCAoKD0gc2NvcmUgd29ydGgpICh2YWx1ZXMgKGNvbnMgeCBiZXN0KSB3b3J0aCkpDQo+PiDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCAoI3QgKHZhbHVlcyBiZXN0IHdvcnRo KSkpKSkNCj4+IMKgwqDCoMKgwqDCoCAodGFrZSBsc3QgMSkgKGZuIChjYXIgbHN0KSkNCj4+ IMKgwqDCoMKgwqDCoCAoY2RyIGxzdCkpKSkNCj4+DQo+PiAobWF4LWJ5IChsYW1iZGEoeCkg KG1vZHVsbyB4IDUpKSAnKDIyIDIzIDI0IDI1IDI2IDI3IDI4IDI5KSkNCj4+DQo+PiDCoMKg ID09PT4NCj4+ICgyOSAyNCkNCj4+IDQNCj4gDQo+IA0KPiANCj4gSG93IGRvIGkgYXZvaWQg dXNpbmfCoMKgIC05OTk5OcKgwqAgPz8/DQo+IA0KPiANCj4gKGRlZmluZSAocHJpbnQgeCkg KG5ld2xpbmUpICh3cml0ZSB4KSAobmV3bGluZSkpDQo+IA0KPiAoZGVmaW5lIChtYXgtYnkg Zm4gTGlzKcKgwqDCoCAobWF4QnkgZm4gTGlzICcoKSAtOTk5OTkpKQ0KPiANCj4gKGRlZmlu ZSAobWF4QnkgZm4geCBjTGlzIGNNYXgpDQo+ICDCoChjb25kDQo+ICDCoCAoKG51bGw/IHgp wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChjb25zIChyZXZlcnNlIHgpIGNNYXgpKQ0KPiAg wqAgKCg9IChmbiAoY2FyIHgpKSBjTWF4KSAobWF4QnkgZm4gKGNkciB4KSAoY29ucyAoY2Fy IHgpIGNMaXMpIGNNYXgpKQ0KPiAgwqAgKCg+IChmbiAoY2FyIHgpKSBjTWF4KSAobWF4Qnkg Zm4gKGNkciB4KSAobGlzdCAoY2FyIHgpKSAoZm4gKGNhciB4KSkpKQ0KPiAgwqAgKGVsc2XC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIChtYXhCeSBmbiAoY2RyIHgpIGNM aXMgY01heCkpKSkNCj4gDQo+IChwcmludCAobWF4LWJ5IChsYW1iZGEoeCkgKG1vZHVsbyB4 IDUpKSAnKDQgNSA2IDcgOCA5IDMgNDQpKSkNCj4gKHByaW50IChtYXgtYnkgKGxhbWJkYSh4 KSAobW9kdWxvIHggNSkpICcoMjQgMjUgMjYgMjcgMjggMjkgMzMgNDQpKSkNCg0KSW4gQ29t bW9uIExpc3AsIHN5bWJvbGljIGNvbnN0YW50cyB3ZXJlIGRlZmluZWQgZm9yIHRoZSBJRUVF IHBsdXMgYW5kIA0KbWludXMgaW5maW5pdGllcy4gSSBkb24ndCByZWNhbGwgdGhlIHN5bnRh eCBhdCB0aGUgbW9tZW50IGJ1dCBkbyANCnJlbWVtYmVyIHRoZXkgd2VyZSBxdWl0ZSB1c2Vm dWwgaW4gbWFraW5nIGNlcnRhaW4gY29kZXMgZWFzaWVyIHRvIHJlYWQgDQphbmQgdW5kZXJz dGFuZC4NCi0tIA0KSmVmZiBCYXJuZXR0DQoNCg==

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From HenHanna@21:1/5 to B. Pym on Fri Jun 28 19:48:46 2024
    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)))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From HenHanna@21:1/5 to Jeff Barnett on Sun Jun 30 00:31:44 2024
    XPost: sci.lang

    On 6/28/2024 8:11 PM, Jeff Barnett wrote:
    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.


    Thanks!!!


    Yes, some Scheme implementations support negative infinity, often
    denoted as -inf.0.

    Here's a breakdown:

    Concept: Negative infinity represents a value on the number line
    that is infinitely far in the negative direction.

    Representation: The specific notation for negative infinity can
    vary depending on the Scheme implementation. However, -inf.0 is a common representation, where:


    -inf signifies negative infinity.

    .0 indicates that it's an inexact number (as opposed to an exact
    mathematical concept of negative infinity).


    Not all Scheme implementations are guaranteed to support negative
    infinity.

    The latest Scheme standard, R7RS-small, recommends the use of +inf.0,
    -inf.0, and +nan.0 for positive infinity, negative infinity, and
    Not-a-Number, respectively.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Paul Rubin on Tue Jul 2 23:59:36 2024
    On Tue, 02 Jul 2024 16:49:33 -0700, Paul Rubin wrote:

    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.

    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 the
    minimum should be +∞. Being numbers, they can be compared with other
    numbers in the usual way, and a lot of special cases no longer become
    special.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Jeff Barnett on Tue Jul 2 16:49:33 2024
    Jeff Barnett <[email protected]> writes:
    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.

    That's pretty horrendous either way (-99999 or -INF) . Better to return
    an empty list in the event that that the input is empty. Also if I
    understand the intention of that function, you really have to make two
    passes through the list, which is simpler anyway.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Lawrence D'Oliveiro on Tue Jul 2 17:15:56 2024
    Lawrence D'Oliveiro <[email protected]d> writes:
    If a function like “max” or “min” is defined to return a number,

    They are defined to return the larger or smaller of two members of any
    datatype with an order relation, e.g. lexicographic order on strings.
    There is no infinity for strings. There's also none for integers, for
    that matter.

    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.

    and a lot of special cases no longer become special.

    More likely a lot of errors go undetected. Better to handle the special
    cases in some sane way, if they can happen in the program and need
    handling.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeff Barnett@21:1/5 to All on Tue Jul 2 20:59:24 2024
    T24gNy8yLzIwMjQgNjoxNSBQTSwgUGF1bCBSdWJpbiB3cm90ZToNCj4gTGF3cmVuY2UgRCdP bGl2ZWlybyA8bGRvQG56LmludmFsaWQ+IHdyaXRlczoNCj4+IElmIGEgZnVuY3Rpb24gbGlr ZSDigJxtYXjigJ0gb3Ig4oCcbWlu4oCdIGlzIGRlZmluZWQgdG8gcmV0dXJuIGEgbnVtYmVy LA0KPiANCj4gVGhleSBhcmUgZGVmaW5lZCB0byByZXR1cm4gdGhlIGxhcmdlciBvciBzbWFs bGVyIG9mIHR3byBtZW1iZXJzIG9mIGFueQ0KPiBkYXRhdHlwZSB3aXRoIGFuIG9yZGVyIHJl bGF0aW9uLCBlLmcuIGxleGljb2dyYXBoaWMgb3JkZXIgb24gc3RyaW5ncy4NCj4gVGhlcmUg aXMgbm8gaW5maW5pdHkgZm9yIHN0cmluZ3MuICBUaGVyZSdzIGFsc28gbm9uZSBmb3IgaW50 ZWdlcnMsIGZvcg0KPiB0aGF0IG1hdHRlci4NCj4gDQo+PiB0aGVuIGl0IG1ha2VzIHNlbnNl IHRoYXQgdGhlIG1heGltdW0gb2YgYW4gZW1wdHkgbGlzdCBzaG91bGQgYmUgLeKIniwNCj4g DQo+IE1laCwgaXQncyBqdXN0IHVuZGVmaW5lZC4gIE90aGVyd2lzZSB5b3UgY2FuJ3QgdGVs bCB3aGV0aGVyIHRoZSBsaXN0IGlzDQo+IGVtcHR5IG9yIGFjdHVhbGx5IGNvbnRhaW5zIC3i iJ4gYXMgYSB2YWx1ZS4NCg0KQ29uc2lkZXIgYSBTVU0gb2YgYSBzZXQgb2YgaW50ZWdlcnM6 IG1hdGhlbWF0aWNpYW5zIGRlZmluZSB0aGF0IG9wZXJhdG9yIA0KdG8gcmV0dXJuIDAgZm9y IHRoZSBlbXB0eSBzZXQNCg0KU2ltaWxhcmx5Og0KTUFYIGVtcHR5LXNldCA9IC1vbw0KTUlO IGVtcHR5LXNldCA9ICtvbw0KUFJPRFVDVCBlbXB0eS1zZXQgPSAxDQphbmQsIGluIGdlbmVy YWwsDQpHUk9VUCBPUEVSQVRPUiBlbXB0eS1zZXQgPSBncm91cC1pZGVudGl0eS1lbGVtZW50 DQoNClRoaXMgY29udmVudGlvbiBtYWtlcyBhIHdob2xlIGxvdCBvZiBzZW5zZSBiZWNhdXNl LCBmb3Igb25lIHRoaW5nLCBpdCANCm1ha2VzIGRlZmluaXRpb24gb2YgaW5kZWZpbml0ZSBu dW1iZXIgb2YgYXJndW1lbnQgZnVuY3Rpb25zIHZlcnkgZWFzeS4NCg0KRm9yIGV4YW1wbGUg U1VNIG5pbCA9IDANCmFuZCBTVU0gKENPTlMgeCBsaXN0KSA9IHggKyBTVU0gbGlzdA0KDQpJ ZiB5b3UgdHJ5IHRoaXMgc29ydCBvZiBkZWZpbml0aW9uIGZvciBNQVgsIHRoZSBvbmx5IHZh bHVlIGluIGFsbCBrbm93biANCm1hdGhlbWF0aWNzIHRoYXQgY2FuIHJlcGxhY2UgMCBpbiB0 aGUgYWJvdmUgaXMgLW9vLg0KDQpJZiB5b3Ugd2FudCB0byBnZXQgaW50byBkZXRhaWxzLCB3 aGF0IEkndmUgc2FpZCBoZXJlIGFwcGxpZXMgdG8gYWJlbGlhbiANCmdyb3Vwczsgd2UgbmVl ZCB0byBiZSBjYXJlZnVsIGFib3V0IG9yZGVyIGluIG90aGVyIHNldHRpbmdzLg0KDQo+PiBh bmQgYSBsb3Qgb2Ygc3BlY2lhbCBjYXNlcyBubyBsb25nZXIgYmVjb21lIHNwZWNpYWwuDQo+ IA0KPiBNb3JlIGxpa2VseSBhIGxvdCBvZiBlcnJvcnMgZ28gdW5kZXRlY3RlZC4gIEJldHRl ciB0byBoYW5kbGUgdGhlIHNwZWNpYWwNCj4gY2FzZXMgaW4gc29tZSBzYW5lIHdheSwgaWYg dGhleSBjYW4gaGFwcGVuIGluIHRoZSBwcm9ncmFtIGFuZCBuZWVkDQo+IGhhbmRsaW5nLg0K DQpQUyBvbyBpcyBtZWFudCB0byBzdGFuZCBmb3IgbnVtZXJpY2FsIGluZmluaXR5Lg0KLS0g DQpKZWZmIEJhcm5ldHQNCg0K

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Paul Rubin on Wed Jul 3 05:21:53 2024
    On Tue, 02 Jul 2024 17:15:56 -0700, Paul Rubin wrote:

    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.

    If it does contain that as a value, then it obviously doesn’t contain any other values. 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?

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Lawrence D'Oliveiro on Wed Jul 3 13:29:21 2024
    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 +. If you don't have two args
    to give it, there is no result.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Paul Rubin on Wed Jul 3 23:49:28 2024
    On Wed, 03 Jul 2024 13:29:21 -0700, Paul Rubin wrote:

    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 +.

    Not in all the good languages.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Lawrence D'Oliveiro on Wed Jul 3 18:11:35 2024
    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.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence D'Oliveiro@21:1/5 to Paul Rubin on Thu Jul 4 01:47:17 2024
    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.

    ... for the variadic versions in CL and Scheme, (max 2) gives 2
    but (max) throws a wrong-number-of-args error.

    I will admit, Python doesn’t like an empty argument list for max and min either.

    But then, Python max and min work for things besides numbers.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Jeff Barnett@21:1/5 to Paul Rubin on Thu Jul 4 00:12:02 2024
    On 7/3/2024 7:11 PM, Paul Rubin wrote:
    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.
    --
    Jeff Barnett

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Kaz Kylheku@21:1/5 to Jeff Barnett on Thu Jul 4 06:57:05 2024
    On 2024-07-04, Jeff Barnett <[email protected]> wrote:
    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.

    (reduce #'+ list :initial-value 0)

    - If :initial-value is present it's as if it is prepended to the list.

    - When the effective list (main input plus any initial value)
    contains only one element, that element is returned without the
    function being called.

    - When the effective list is empty (main input is empty and no
    initial value is specified), reduce calls the function with
    no arguments to obtain the identity element, which is returned.
    This obviously works for + and *.

    - :from-end t can be used to obtain a right reduction.

    --
    TXR Programming Language: http://nongnu.org/txr
    Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
    Mastodon: @[email protected]

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ben Bacarisse@21:1/5 to Lawrence D'Oliveiro on Thu Jul 4 20:52:33 2024
    Lawrence D'Oliveiro <[email protected]d> writes:

    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.

    Haskell is a typed language so the two functions are quite different,
    though the list version can be trivially defined from the binary
    function.

    --
    Ben.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Paul Rubin@21:1/5 to Lawrence D'Oliveiro on Thu Jul 4 12:41:52 2024
    Lawrence D'Oliveiro <[email protected]d> writes:
    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.

    In Haskell that doesn't really make sense. Haskell functions actually
    all take only one arg. Multi-arg functions work by currying. So
    "max [1,2,3]" gives a function that compares [1,2,3] to a list you
    supply. The default order relation on lists compares lexicographically.

    But then, Python max and min work for things besides numbers.

    Yeah I was surprised to find that in Lisp and Scheme, they only work on numbers. Haskell has an Ord typeclass, which is like an interface for datatypes that support comparison. max and min work for any type that implements Ord.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to Raffael Cavallaro on Fri Sep 13 01:34:06 2024
    Raffael Cavallaro wrote:

    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

    In CL (COBOL-Like), in order to print an endless sequence of fibonacci
    numbers, one has to use a macro whose source code is over 60 kilobytes
    in size.

    In Scheme, he can simply use recursion.
    (This is actually shorter than the "loop" version.)

    (let fib ((a 1) (b 1))
    (print a)
    (fib b (+ a b)))

    Since CL (COBOL-Like) is not a Lispy language, it does not have
    much support for recursion.

    A "do" loop is shorter than the "loop" loop.

    (do ((a 1 b)
    (b 1 (+ a b)))
    (#f)
    (write (list a)))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to All on Fri Sep 13 01:31:52 2024
    XPost: comp.lang.scheme

    Here's a more realistic example that illustrates exactly the
    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)).
    Well..
    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)])



    It's shorter in Gauche Scheme.

    (use srfi-42) ;; sum-ec

    (sum-ec (: n 11) (* n n))
    ===>
    385

    Less condensed:

    (sum-ec (:range n 1 11) (* n n))





    Then I would say that a clearer way to express what a person think is:
    (loop for number in numberlist sum (expt number power))


    Gauche Scheme

    (use srfi-42) ;; sum-ec

    (sum-ec (:list n '(3 4 5 6)) (* n n))
    ===>
    86

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to Pascal Costanza on Tue Jul 1 15:10:56 2025
    XPost: comp.lang.scheme

    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))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to B. Pym on Sat Jul 5 12:44:29 2025
    XPost: comp.lang.scheme

    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

    (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))

    Shorter:

    (max-by (cut modulo <> 5) '(22 23 24 25 26 27 28 29))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to David Steuber on Wed Jul 9 19:37:43 2025
    XPost: comp.lang.scheme

    David Steuber wrote:

    Try doing this in C++, Python, or whatever:

    (do ((a 1 b) (b 1 (+ a b)))
    (nil a)
    (print a))

    That ought to be:

    (do ((a 0 b) (b 1 (+ a b)))
    (nil)
    (print b))

    In Gauche Scheme using do_:

    (do_ ((a 0 b) (b 1 (+ a b)))
    ()
    (print b))

    Another way:

    (do_ (: a 0 b b 1 (+ a b))
    ()
    (print b))

    Given:

    (define-syntax do_-aux
    (syntax-rules ( <> @ :in :collect :below :to : )
    [ (do_-aux ((x what <>) more ...) (seen ...) stuff ...)
    (do_-aux (more ...) (seen ... (x what what)) stuff ...) ]
    [ (do_-aux ((x a :below b) more ...) seen lets (bool z ...) stuff ...)
    (do_-aux ((top b)
    (x a (+ x 1)) more ...) seen lets
    ((or (>= x top) bool) z ...) stuff ...) ]
    [ (do_-aux ((x a :to b) more ...) stuff ...)
    (do_-aux ((x a :below (+ 1 b)) more ...) stuff ...) ]
    [ (do_-aux ((x :in seq) more ...) seen (lets ...) (bool z ...) stuff ...)
    (do_-aux ((x (and (pair? the-list) (car the-list)) <>) more ...)
    seen
    (lets ... (the-list seq))
    ((or (null? the-list) (begin (pop! the-list) #f) bool) z ...)
    stuff ...) ]
    [ (do_-aux ((accum :collect x) more ...) stuff ...)
    (do_-aux ((accum '() (cons x accum)) more ...) stuff ...) ]
    [ (do_-aux (: v init update more ...) (seen ...) stuff ...)
    (do_-aux (: more ...) (seen ... (v init update)) stuff ...) ]
    [ (do_-aux (:) stuff ...)
    (do_-aux () stuff ...) ]
    [ (do_-aux (spec more ...) (seen ...) stuff ...)
    (do_-aux (more ...) (seen ... spec) stuff ...) ]
    [ (do_-aux () seen lets (bool y ... @ result) stuff ...)
    (do_-aux () seen lets (bool y ... (reverse result)) stuff ...) ]
    [ (do_-aux () seen (lets ...) more ...)
    (let (lets ...)
    (do seen more ...))
    ] ))
    (define-syntax do_
    (syntax-rules ()
    [ (do_ specs () more ...)
    (do_ specs (#f) more ...) ]
    [ (do_ specs more ...)
    (do_-aux specs () () more ...) ] ))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)