From: ·······@my-deja.com
Subject: Calling a function directly or via apply
Date: 
Message-ID: <95ufgg$s14$1@nnrp1.deja.com>
I don't understand why this gives different results:

(defvar m '((1 2 3) (1 2 3)))

;; call mapcar directly:
CL-USER 25 > (mapcar #'list m)
(((1 2 3)) ((1 2 3)))

;; call it via apply
CL-USER 26 > (apply #'mapcar #'list m)
((1 1) (2 2) (3 3))

I expected that calling a function via apply or directly, should give
the same result, no?

BTW, can someone point out some practical use of apply?

thanx



Sent via Deja.com
http://www.deja.com/

From: Joe Marshall
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <d7ctqcpm.fsf@content-integrity.com>
·······@my-deja.com writes:

> I don't understand why this gives different results:
> 
> (defvar m '((1 2 3) (1 2 3)))
> 
> ;; call mapcar directly:
> CL-USER 25 > (mapcar #'list m)
> (((1 2 3)) ((1 2 3)))
> 
> ;; call it via apply
> CL-USER 26 > (apply #'mapcar #'list m)
> ((1 1) (2 2) (3 3))
> 
> I expected that calling a function via apply or directly, should give
> the same result, no?

No.

If apply just did what you described above (called a function as if it
were directly supplied), then there would be no practical use for it
(because it would be the same as funcall).

Forget the n-ary version of apply for a moment and let's focus on the
2-argument version.  What we give to apply is a function and a *list*
of the arguments we want to pass to the function.  Here are some
examples:

    (apply #'+ (list 2 3))      =>  5

    (apply #'cons (list 'a 'b)) => (a . b)

    (apply #'log (list 15))     => 2.7080503

    (apply #'subseq (list "The rain in Spain" 4 8)) => "rain"

The effect is as if you had written (+ 2 3), (cons 'a 'b), (log 15),
or (subseq "The rain in Spain" 4 5).

Now consider this:

    (defvar m '((1 2 3) (a b c)))

    (car m)  => (1 2 3)

    (apply #'car m) => error, wrong number of args.

Why?  Well, (apply #'car m) is equivalent to 

    (apply #'car '((1 2 3) (a b c))) which is equivalent to
				     (modulo issues of new structure
				      versus sharing the old structure)


    (apply #'car (list '(1 2 3) '(a b c))) which is equivalent to

    (car '(1 2 3) '(a b c))  which is of course an error.

Let's look at your example.

    (apply #'mapcar #'list m)

When using the n-ary version of apply, it takes everything after the
first argument (the function to apply), and prepends it to the last
argument.  In effect, you have

    (apply #'mapcar (cons #'list m))  which is equivalent to

    (apply #'mapcar (cons #'list (list '(1 2 3) '(a b c))))

       consing an element to a list returns a new list,
       so this is equivalent to 

    (apply #'mapcar (list #'list '(1 2 3) '(a b c)))

       which is equivalent to

    (mapcar #'list '(1 2 3) '(a b c))

       which is a three-argument call to mapcar, so you get

    (list           ;; mapcar returns a list
       (list 1 a)   ;;   function list applied to 1 and a
       (list 2 b)   ;;   function list applied to 2 and b
       (list 3 c))  ;;   function list applied to 3 and c

> BTW, can someone point out some practical use of apply?

I want to make a noisy version of several functions.  Since the number
of arguments the various functions take will vary, I have to use an
&rest argument to collect them all in a list.

I print out the noise, but then I have to invoke the original function
on the list of arguments I have.  So I use apply.


    (defun make-noisy-function (func format-string)
      (lambda (&rest arguments)
	(format *debug-io* format-string func arguments)
	(apply func arguments)))

    (setf (symbol-function 'noisy-cons) (make-noisy-function #'cons  "~&Invoking ~s on ~s"))
    (setf (symbol-function 'noisy-add)  (make-noisy-function #'+  "~&Invoking ~s on ~s"))

    (noisy-cons 2 3)
    Invoking #<Function CONS> on (2 3)
    (2 . 3)

    (noisy-add 3 4 5 6 7 8)
    Invoking #<Function +> on (3 4 5 6 7 8)

It is often the case when you see an &REST arg, an APPLY is not far behind.


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----
From: Hrvoje Niksic
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <sxs66ilf9bi.fsf@florida.arsdigita.de>
·······@my-deja.com writes:

> I don't understand why this gives different results:
> 
> (defvar m '((1 2 3) (1 2 3)))
> 
> ;; call mapcar directly:
> CL-USER 25 > (mapcar #'list m)
> (((1 2 3)) ((1 2 3)))
> 
> ;; call it via apply
> CL-USER 26 > (apply #'mapcar #'list m)
> ((1 1) (2 2) (3 3))

The difference is between:

    (mapcar #'list '((1 2 3) (1 2 3)))

and

    (mapcar #'list '(1 2 3) '(1 2 3))

That is, the last argument of APPLY is used as the *list* of remaining
arguments when calling the function.

> I expected that calling a function via apply or directly, should
> give the same result, no?

What you're looking for is FUNCALL:

    (funcall #'mapcar #'list m)
    ==> (((1 2 3)) ((1 2 3)))

> BTW, can someone point out some practical use of apply?

Sure.  It's often used for flattening lists, like this:

    (apply #'append m)
    ==> (1 2 3 1 2 3)

Or, in its destructive version:

    (apply #'nconc LIST-OF-LISTS)
From: Frode Vatvedt Fjeld
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <2hwvb1f8p9.fsf@dslab7.cs.uit.no>
·······@my-deja.com writes:

> I don't understand why this gives different results:
> 
> (defvar m '((1 2 3) (1 2 3)))
> 
> ;; call mapcar directly:
> CL-USER 25 > (mapcar #'list m)
> (((1 2 3)) ((1 2 3)))
> 
> ;; call it via apply
> CL-USER 26 > (apply #'mapcar #'list m)
> ((1 1) (2 2) (3 3))
> 

> I expected that calling a function via apply or directly, should
> give the same result, no?

APPLY will kind of "unwrap" the list, so that

  (apply #'func (a b c))

is similar to

  (func a b c)

Which means that your

  (apply #'mapcar #'list '((1 2 3) (1 2 3)))

is similar to

  (mapcar #'list '(1 2 3) '(1 2 3))

FUNCALL does what you expected, I guess.

> BTW, can someone point out some practical use of apply?

APPLY and FUNCALL are mostly useful when you have funargs.

-- 
Frode Vatvedt Fjeld
From: Janis Dzerins
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <87bssd2kgh.fsf@asaka.latnet.lv>
·······@my-deja.com writes:

> BTW, can someone point out some practical use of apply?

This is simplified version of what I wrote yesetrday.

I have a struct with some slots, like this:

(defstruct foo
  a b c)

and I save a lot of such structs to file where each instance is saved
like this:

(:foo :a 1 :b 2 :c 3)

Then I can load them all like this:

(with-open-file (in "foos.cl" :direction :input)
  (handler-case
      (loop for def = (read in)
          do (case (first def)
               (:foo (apply #'make-foo (rest def)))
               (t (warn "Unknown item: ~A" def))))
    (end-of-file ()
      t)))

Not that this is very practical. But destructuring-bind is something I
have not used, yet, although this might get close.

Janis Dzerins
-- 
  If million people say a stupid thing it's still a stupid thing.
From: Joe Marshall
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <4ry5qc2x.fsf@content-integrity.com>
Janis Dzerins <·····@latnet.lv> writes:

> ·······@my-deja.com writes:
> 
> > BTW, can someone point out some practical use of apply?
> 
> This is simplified version of what I wrote yesetrday.
> 
> I have a struct with some slots, like this:
> 
> (defstruct foo
>   a b c)
> 
> and I save a lot of such structs to file where each instance is saved
> like this:
> 
> (:foo :a 1 :b 2 :c 3)
> 

If you save them out as:

(make-foo :a 1 :b 2 :c 3)

or 

#.(make-foo :a 1 :b 2 :c 3)

Then you won't have to dispatch on the first item in the list, you can
just use read and eval (or in the latter case, just read).

You may also want to investigate the MAKE-LOAD-FORM function.

> Not that this is very practical. 

Why not?  Dumping objects to files is an interesting thing to do.


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----
From: Janis Dzerins
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <877l312f68.fsf@asaka.latnet.lv>
Joe Marshall <···@content-integrity.com> writes:

> Janis Dzerins <·····@latnet.lv> writes:
> 
> > ·······@my-deja.com writes:
> > 
> > > BTW, can someone point out some practical use of apply?
> > 
> > This is simplified version of what I wrote yesetrday.
> > 
> > I have a struct with some slots, like this:
> > 
> > (defstruct foo
> >   a b c)
> > 
> > and I save a lot of such structs to file where each instance is saved
> > like this:
> > 
> > (:foo :a 1 :b 2 :c 3)
> > 
> 
> If you save them out as:
> 
> (make-foo :a 1 :b 2 :c 3)
> 
> or 
> 
> #.(make-foo :a 1 :b 2 :c 3)
> 
> Then you won't have to dispatch on the first item in the list, you can
> just use read and eval (or in the latter case, just read).
> 
> You may also want to investigate the MAKE-LOAD-FORM function.

What I wrote here was simplified version of what I wrote for my use,
and your remarks are in place.

But what I actually saved was a whole lot more sophisticated
structures (and the file I saved the stuff was about 4.2MB). The
things I saved were not actually structs but stuff to make a lot of
different structs that are linked to one another. I have a function
that will create everything from the [keyword] arguments passed to it.

> > Not that this is very practical. 
> 
> Why not?  Dumping objects to files is an interesting thing to do.

I wrote the stuff to transfer data from trial version of my lisp to
the full version since their images are binary-incompatible and dumped
image could not be used :) Text files full of lisp expressions and
lisp reader are very nice to have in cases like this.

Janis Dzerins
-- 
  If million people say a stupid thing it's still a stupid thing.
From: Vladimir V. Zolotych
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <3A83BDF5.5763CDC2@eurocom.od.ua>
Joe Marshall wrote:
> 
> #.(make-foo :a 1 :b 2 :c 3)

Would you mind explain a bit such notation ( #.(...) )please ?
What does it mean ?

-- 
Vladimir Zolotych                         ······@eurocom.od.ua
From: Janis Dzerins
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <87y9vg19qw.fsf@asaka.latnet.lv>
"Vladimir V. Zolotych" <······@eurocom.od.ua> writes:

> Joe Marshall wrote:
> > 
> > #.(make-foo :a 1 :b 2 :c 3)
> 
> Would you mind explain a bit such notation ( #.(...) )please ?
> What does it mean ?

It means that (make-foo :a 1 :b 2 :c 3) will be evaluated in
read-time, i.e. when doing

(read-from-string "#.(make-foo :a 1 :b 2 :c 3)")

you will not get a list (make-foo :a 1 :b 2 :c 3) (which you would get
if there was not #. in front of the expression), but the value of this
expression being evaluated -- something like #S(foo :a 2 :b 3 :c 5)
(which is a structure object foo).

There are some things that might influence this -- like *read-eval*
and availability of function make-foo at read time.

Janis Dzerins
-- 
  If million people say a stupid thing it's still a stupid thing.
From: Thomas A. Russ
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <ymiofwbsj6u.fsf@sevak.isi.edu>
#. is a reader macro which causes the following S-expression to be
evaluated at read time by the reader.  In the case of

  #.(make-foo :a 1 :b 2 :c 3)

it means that a call to read will return an object (struct) of type foo
rather than a list.  In addition to this particular idiom, it is also
often used to make constants more readable in source code, when you
don't trust to compiler to do constant folding for you:

  (defvar *seconds-per-day* #.(* 24 60 60))


-- 
Thomas A. Russ,  USC/Information Sciences Institute          ···@isi.edu    
From: Joe Marshall
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <ae7v7ltt.fsf@content-integrity.com>
"Vladimir V. Zolotych" <······@eurocom.od.ua> writes:

> Joe Marshall wrote:
> > 
> > #.(make-foo :a 1 :b 2 :c 3)
> 
> Would you mind explain a bit such notation ( #.(...) )please ?
> What does it mean ?

It means `eval at read time'.  As the reader is parsing an expression,
it is creating lisp objects.  When it sees characters like "123", it
decides that is a number.  When it sees "(", it starts accumulating a
list, and when it sees the matching ")", it finishes the list.

The reader knows how to construct many objects from a printed
representation (for example, numbers, lists, symbols, strings, arrays,
characters, etc.), but it doesn't know how to construct *every*
conceivable lisp object, unless you can give it some help.

When the reader sees "#.", it does something special:  It reads the
next expression as usual, but rather than using the result of parsing
that expression, it hands the parsed expression to the interpreter and
uses what the interpreter returns.

Here's a (contrived) example:

Suppose you defined a class or struct to represent URLs.  You may have
defined a print method using  print-unreadable-object so your URL
objects print like this:  

   #<URL 2539428 http://www.foo.com/>

Now suppose you are writing some code that manipulates some urls, and
you have a list with some urls in it:

(favorites 
  (jrm
     #<URL 2539fe7 http://www.bar.com/>
     #<URL 253a114 http://www.baz.com/>)
  (billg
     #<URL 2539fe7 http://www.microsoft.com/>
     #<URL 253a114 http://www.spamomatic.com/>))


If you want to write this list to a file and use READ to reconstruct
it, you will have problems.  The reader doesn't know how to construct
a URL, and the "#<" ">" characters indicate that the reader should
generate an error if it sees them.

You *could* design a file format and write your own parser to
reconstruct the list, 

[jrm]
http://www.bar.com/
http://www.baz.com/

[billg]
http://www.microsoft.com/
http://www.spamomatic.com/

But why write a dumper and parser when there is already one built in
to lisp?

You *could* dump a lisp object with enough information to reconstruct
the original list,

(favorites (jrm (:reconstruct-this-url "http://www.bar.com/")
                (:reconstruct-this-url "http://www.baz.com/"))
           (billg (:reconstruct-this-url "http://www.microsoft.com/")
                  (:reconstruct-this-url "http://www.spamomatic.com/")))

Then write some code that does a pass through the result of reading
the list, converting sublists of the form (:reconstruct-this-url ...)
into url objects.  But if someone uses read and forgets to do the
second pass, or if you are using a utility that uses read, and you
can't easily tell it to perform the second pass, this won't be
reliable.

Or you can use #. when dumping the object:

(favorites
  (jrm #.(parse-url "http://www.bar.com/")
       #.(parse-url "http://www.baz.com/"))
  (billg #.(parse-url "http://www.microsoft.com/")
         #.(parse-url "http://www.spamomatic.com/")))

Now as the reader is assembling the list, when it encounters the
#. expressions, it reads the  (parse-url "http://www.bar.com") form.
But instead of collecting that sublist into the result of the read, it
invokes eval on it.  Presumably parse-url returns a url object, and
it is *this* object that is collected into the result of the read.
Just as if there were some special syntax that the reader understood
to mean URLs.

So you don't have to define a special file format and write your own
parser, you don't have to do a read post-pass to convert objects that
might have URLs in them, you just call the built-in read.

-----

This example is a little contrived as you can dump readable structs
and simple CLOS objects fairly easily, and you should use
MAKE-LOAD-FORM for the trickier cases.  But it is good to have an
escape mechanism within the reader in case you find yourself in a
position where you really need the entire power of lisp as you are
parsing a subexpression, but don't want to implement a new parser.


-----= Posted via Newsfeeds.Com, Uncensored Usenet News =-----
http://www.newsfeeds.com - The #1 Newsgroup Service in the World!
-----==  Over 80,000 Newsgroups - 16 Different Servers! =-----
From: Vladimir V. Zolotych
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <3A8407E9.599275DB@eurocom.od.ua>
Erik Naggum wrote:
> 
>   What kind of reference materials on Common Lisp do you have at your
>   disposal?

CLHS

-- 
Vladimir Zolotych                         ······@eurocom.od.ua
From: Vladimir V. Zolotych
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <3A841D09.6D0ACAAC@eurocom.od.ua>
Erik Naggum wrote:
> 
>   The question you're asking this time is covered in Chapter 2.

Yes, excuse me.

-- 
Vladimir Zolotych                         ······@eurocom.od.ua
From: Hartmann Schaffer
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <slrn9867qp.djk.hs@paradise.nirvananet>
In article <············@nnrp1.deja.com>, ·······@my-deja.com wrote:
>I don't understand why this gives different results:
>
>(defvar m '((1 2 3) (1 2 3)))
>
>;; call mapcar directly:
>CL-USER 25 > (mapcar #'list m)
>(((1 2 3)) ((1 2 3)))
>
>;; call it via apply
>CL-USER 26 > (apply #'mapcar #'list m)
>((1 1) (2 2) (3 3))
>
>I expected that calling a function via apply or directly, should give
>the same result, no?

usually that is the case, but list is a variadic function.

>BTW, can someone point out some practical use of apply?

assume you have constructed a list of numbers, and you want to add them up.
for a constant you can say (+ 1 2 3 4), and it adds all those numbers.  but
try

(setf m '(1 2 3 4))
(+ m)

you'll get an error message telling you that + works only on numbers.  if you
say instead

(apply #'+ m)

your lisp system constructs a function call from the function and the contents
of the list:  (+ 1 2 3 4).

btw:  try this with your example:

(mapcar #'list '(1 2 3) (1 2 3))

hs
From: Kent M Pitman
Subject: Re: Calling a function directly or via apply
Date: 
Message-ID: <sfwwvaq8zn6.fsf@world.std.com>
··@paradise.nirvananet (Hartmann Schaffer) writes:

> >BTW, can someone point out some practical use of apply?
> 
> assume you have constructed a list of numbers, and you want to add them up.
> for a constant you can say (+ 1 2 3 4), and it adds all those numbers.  but
> try
> 
> (setf m '(1 2 3 4))
> (+ m)
>
> you'll get an error message telling you that + works only on numbers.  if you
> say instead
>
> (apply #'+ m)
>
> your lisp system constructs a function call from the function and 
> the contents of the list:  (+ 1 2 3 4).

Often for this kind of thing, reduce will also work (and won't blow out
of stack if the list is very long).

 (reduce #'+ m)

reduce does pairwise application of + as many times as needed.

The case I usually find myself using apply is in keyword argument 
calling when I want to add or remove args. e.g.,

 (defun open-for-input (file &rest open-keys)
   (apply #'open file :direction :input open-keys))

or 

 (defun open-for-input (file &rest open-keys &key verbose &allow-other-keys)
   (when verbose (format t "~&Opening ~S ...~%" file))
   (let ((new-keys (copy-list open-keys)))
     (remf new-keys :verbose)
     (apply #'open file new-keys)))

[N.B. I didn't test these.]