flat enough?

Started by rrq, June 22, 2014, 04:32:36 AM

Previous topic - Next topic

rrq

I just ran into this pebble on the beach, that the "flat" function doesn't flatten quoted sub lists.
> (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

#1
If other dialect of lisp could match your expect?



    Common Lisp or Clojure?


cljs.user> (flatten '('(1 2) (3 4)))
(quote 1 2 3 4)


Common Lisp have not buil-in flatten function:
(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

#2
That's because '(1 2) is a quoted expression, not a list:


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

rrq

#3
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

#4
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.



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



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