Page 1 of 1

flat enough?

Posted: Sun Jun 22, 2014 11:32 am
by ralph.ronnquist
I just ran into this pebble on the beach, that the "flat" function doesn't flatten quoted sub lists.

Code: Select all

> (flat '('(1 2) (3 4)))
('(1 2) 3 4)
Perhaps it's worth mentioning it in the doc, or fix it, if it's a mistake. By my inuition, the flat function should traverse into quoted lists the way it traverses into lambda expressions.

Re: flat enough?

Posted: Thu Jun 26, 2014 8:52 am
by ssqq
If other dialect of lisp could match your expect?

Common Lisp or Clojure?

Code: Select all

cljs.user> (flatten '('(1 2) (3 4)))
(quote 1 2 3 4)
Common Lisp have not buil-in flatten function:

Code: Select all

(defun flatten (obj)
  (do* ((result (list obj))
        (node result))
       ((null node) (delete nil result))
    (cond ((consp (car node))
           (when (cdar node) (push (cdar node) (cdr node)))
           (setf (car node) (caar node)))
          (t (setf node (cdr node))))))
Output:
CL-USER> (flatten '((1) 2 ((3 4) 5) ((())) (((6))) 7 8 ()))
(1 2 3 4 5 6 7 8)

Re: flat enough?

Posted: Thu Jun 26, 2014 10:19 pm
by Astrobe
That's because '(1 2) is a quoted expression, not a list:

Code: Select all

(list? (nth 0 '('(1 2) (3 4)))) ; --> nil (id est, false)

Code: Select all

(quote? (nth 0 '('(1 2) (3 4)))) ; --> true

Re: flat enough?

Posted: Sat Jun 28, 2014 1:20 am
by ralph.ronnquist
Yes, I discovered that, and really it's probably not an issue, except perhaps for writing interospective analysis code, where you might end up spending an extra ten minutes or so wondering why certain code associations are missing. But then, you'll probably spend more time on figuring out why (first '(lambda () (println "hello")) is an empty list.

Re: flat enough?

Posted: Sat Jun 28, 2014 2:15 pm
by Lutz
In newLISP, the lambda word on its own as a symbol does not exist, it only indicates a special list type, the lambda list. It is the only keyword together with lambda-macro recognized during source parsing. The word lambda indicates a specialized type of a list which can be used and applied like a function or operator.

Code: Select all

> (length (lambda))  ; the lambda indicates, it’s a lambda list
0
> (lambda) ; lambda is not a symbol, lambda lists evaluate to themselves
(lambda )
> (list? (lambda)) 
true
> (lambda? (lambda)) ; a lambda list is a sub-type of the list type
true
When composing lambda lists from scratch make sure to start with a lambda type list, e.g:

Code: Select all

> (append (lambda) '((x) (+ x x)))
(lambda (x) (+ x x))
> (set 'double (append (lambda) '((x) (+ x x)))) ; same as using define
(lambda (x) (+ x x))
> (double 123)
246
Ps: instead of lambda and lambda-macro the words fn and fn-macro can be used too.