From: Joseph Fahey
Subject: Lists of functions
Date: 
Message-ID: <87y7np4ywf.fsf@fabula.org>
Hi All,

I've been teaching myself CL over the past few months (PCL, ANSI CL,
and On Lisp; SBCL+slime), and usually I end up figuring out the
answers to whatever problems I encounter, but this time I am stumped.

I would like to have a function that looks like this, where the &rest
arguments get sorted by type, functions or dl structures:

(defun build-tree (page-fn entry-fn link-fn &rest dls-or-fns)
  (let ((body-fns (remove-if-not #'functionp dls-or-fns))
        (dls (remove-if-not #'dl-p dls-or-fns)))
        ...do stuff...))

This does not work, because both remove-if-not statements return
NIL. So I start playing around with the REPL and I get confused. It
seems that you can't get functions back out of a list.

(dolist (x '(1 2 #'atom))
        (format t "~A : type ~A~%" x (type-of x)))
1 : type BIT
2 : type (INTEGER 0 536870911)
#'ATOM : type CONS
NIL

Why is #'atom showing up as a cons? So then I do:

CL-USER> (type-of (second '(1 #'atom)))
CONS
CL-USER> (type-of (car (second '(1 #'atom))))
SYMBOL
CL-USER> (type-of (cdr (second '(1 #'atom))))
CONS
CL-USER> (type-of (car (cdr (second '(1 #'atom)))))
SYMBOL
CL-USER> (type-of (cdr  (cdr (second '(1 #'atom)))))
NULL

So it looks like #'atom is represented, in this list, as a list: 
(symbol . (symbol . nil)). I understand that #'atom really means
(function atom), but why does that show up as a cons...?

Or am I barking up the wrong tree and should I just use optional lists
as arguments?

Thanks for any insight.

Joe

From: Harald Hanche-Olsen
Subject: Re: Lists of functions
Date: 
Message-ID: <pcolkjpu8fv.fsf@shuttle.math.ntnu.no>
+ Joseph Fahey <fahey(do_not_spam_me)@fabula.org>:

| (dolist (x '(1 2 #'atom))
|         (format t "~A : type ~A~%" x (type-of x)))
| 1 : type BIT
| 2 : type (INTEGER 0 536870911)
| #'ATOM : type CONS
| NIL
|
| Why is #'atom showing up as a cons? So then I do:

Because it is a cons.  Namely, shorthand for (function atom).

Your problem is that the quoting on the outer list stopped this from
being evaluated.  Try instead:

cl-user> (dolist (x `(1 2 ,#'atom))
	   (format t "~A : type ~A~%" x (type-of x)))

1 : type bit
2 : type (integer 0 536870911)
#<FUNCTION atom> : type function

-- 
* Harald Hanche-Olsen     <URL:http://www.math.ntnu.no/~hanche/>
- It is undesirable to believe a proposition
  when there is no ground whatsoever for supposing it is true.
  -- Bertrand Russell
From: Joseph Fahey
Subject: Re: Lists of functions
Date: 
Message-ID: <87ps914yab.fsf@fabula.org>
>>>>> ">" == Harald Hanche-Olsen <······@math.ntnu.no> writes:

    >> + Joseph Fahey <fahey(do_not_spam_me)@fabula.org>: | (dolist (x
    >> '(1 2 #'atom)) | (format t "~A : type ~A~%" x (type-of x))) | 1
    >> : type BIT | 2 : type (INTEGER 0 536870911) | #'ATOM : type
    >> CONS | NIL
    >> |
    >> | Why is #'atom showing up as a cons? So then I do:

    >> Because it is a cons.  Namely, shorthand for (function atom).

    >> Your problem is that the quoting on the outer list stopped this
    >> from being evaluated.  Try instead:

    cl-user> (dolist (x `(1 2 ,#'atom))
    >> 	   (format t "~A : type ~A~%" x (type-of x)))

    >> 1 : type bit 2 : type (integer 0 536870911) #<FUNCTION atom> :
    >> type function

And suddenly it all becomes (kind of) clear. Thanks!

So I suppose that it is bad style to have functions that require the
functions passed as arguments to be quoted that way?

(my-func ,#atom 123 "blah")

Joe
From: ·············@gmail.com
Subject: Re: Lists of functions
Date: 
Message-ID: <1169826823.268681.119640@v33g2000cwv.googlegroups.com>
>     cl-user> (dolist (x `(1 2 ,#'atom))
>     >>       (format t "~A : type ~A~%" x (type-of x)))
>
>     >> 1 : type bit 2 : type (integer 0 536870911) #<FUNCTION atom> :
>     >> type function
>
> And suddenly it all becomes (kind of) clear. Thanks!
>
> So I suppose that it is bad style to have functions that require the
> functions passed as arguments to be quoted that way?
>
> (my-func ,#atom 123 "blah")
>
> Joe

`(1 2 ,#'atom) is just a shortand for (list (quote 1) (quote 2) #'atom)
i.e. (list 1 2 (function atom)); you cannot use ,<something> outside
backquote syntax. Your call to my-func should just be (my-func #'atom
123 "blah").
It is suspicious though that the problem surfaced using the &rest
lambda keyword, which doesn't automatically quote the function
arguments. Perhaps you didn't use &rest correctly? (Just guessing).

(defun rest-example (&rest args) args)

(rest-example 1 2 #'atom :whatever)
=> (1 2  #<FUNCTION ATOM> :WHATEVER)
From: Joseph Fahey
Subject: Re: Lists of functions
Date: 
Message-ID: <87iret4vi4.fsf@fabula.org>
>>>>> "-" == alessiostalla  <·············@gmail.com> writes:

    >> So I suppose that it is bad style to have functions that
    >> require the functions passed as arguments to be quoted that
    >> way?
    >> 
    >> (my-func ,#atom 123 "blah")

    -> It is suspicious though that the problem surfaced using the
    -> &rest lambda keyword, which doesn't automatically quote the
    -> function arguments. Perhaps you didn't use &rest correctly?
    -> (Just guessing).

    -> (defun rest-example (&rest args) args)

    -> (rest-example 1 2 #'atom :whatever) => (1 2 #<FUNCTION ATOM>
    -> :WHATEVER)

Hmmm. Ok, that shows me that I was not investigating this correctly,
since I was equating the &rest parameters with a simple quoted list.

So you are right to be suspicious. My real problem must be elsewhere.

Thanks

joe
From: ············@googlemail.com
Subject: Re: Lists of functions
Date: 
Message-ID: <1169827764.813968.288710@j27g2000cwj.googlegroups.com>
On Jan 26, 4:12 pm, Joseph Fahey <fahey(do_not_spam_me)@fabula.org>
wrote:
>> Harald Hanche-Olsen <······@math.ntnu.no> writes:
>> Because it is a cons.  Namely, shorthand for (function atom).
>>
>> Your problem is that the quoting on the outer list stopped this
>> from being evaluated.  Try instead:
>>
>>     cl-user> (dolist (x `(1 2 ,#'atom))
>>     (format t "~A : type ~A~%" x (type-of x)))
>
> And suddenly it all becomes (kind of) clear. Thanks!
>
> So I suppose that it is bad style to have functions that require the
> functions passed as arguments to be quoted that way?
>
> (my-func ,#atom 123 "blah")

If I understand your question, I assume you mean:
(my-func ,#'atom 123 "blah")
Unfortunately, it won't work.

Note that the issue is that
#'atom
is transformed by Lisp when reading it into the form
(FUNCTION ATOM)
and when this form is evaluated, it returns the function object named
by the symbol ATOM:
#<FUNCTION ATOM>


;; In my Lisp implementation, a pretty face hides the truth...
CL-USER> *print-pretty*
T
CL-USER> (quote #'atom)
#'ATOM
CL-USER> (setf *print-pretty* nil)
NIL
CL-USER> (quote #'atom)
(FUNCTION ATOM)

Note that (quote #'atom) is the same as '#'atom.


Anyway, what did Harald do above with the comma? Well, there's the
special "backquote" syntax (which uses ` instead of '). Normal quote
simply quotes what comes after it. Backquote is similar, but basically
anything preceded by a comma will be evaluated.

CL-USER> `(1 2 #'atom)
(1 2 (FUNCTION ATOM))
CL-USER> `(1 2 ,#'atom)
(1 2 #<FUNCTION ATOM>)


Tayssir