flat enough?

For the Compleat Fan
Locked
ralph.ronnquist
Posts: 228
Joined: Mon Jun 02, 2014 1:40 am
Location: Melbourne, Australia

flat enough?

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

ssqq
Posts: 88
Joined: Sun May 04, 2014 12:49 pm

Re: flat enough?

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

Astrobe
Posts: 43
Joined: Mon Jan 11, 2010 9:41 pm

Re: flat enough?

Post 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

ralph.ronnquist
Posts: 228
Joined: Mon Jun 02, 2014 1:40 am
Location: Melbourne, Australia

Re: flat enough?

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

Lutz
Posts: 5289
Joined: Thu Sep 26, 2002 4:45 pm
Location: Pasadena, California
Contact:

Re: flat enough?

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

Locked