Subject: Re: Functions in Lisp
From: (Rob Warnock)
Date: Wed, 22 Feb 2006 04:55:40 -0600
Newsgroups: comp.lang.lisp
Message-ID: <>
Espen Vestre  <> wrote:
| (Peder O. Klingenberg) writes:
| > That said, there's probably a reason why I couldn't immediately come
| > up with an example of a function (as opposed to AND) from my own code
| > that relies on the evaluation order of arguments.
| Defaults to keyword arguments are obvious candidates, and I thought I
| used defaults computed from the obligatory parameters all the time,
| but I actually only found one example in recent code.

Oddly enough, I ran across a case of wanting to do exactly that just
last night, when writing a generalization for MAKE-LIST that allows
circular tails [yes, while playing around with the circular lists
mentioned in the "Subject: equal lists" thread] and is also capable
of initialing the elements of the list to a function of their position
[pardon the ugly draft code!]:

    (defun make-list* (size &key initial-element
				 (circular-tail-size 0)
				  (constantly initial-element)))
      (loop with prefix-length = (- size circular-tail-size)
	     and list = (make-list size)
	     and merge = nil
	    for i below size
	     and node on list
	     and last = nil then node
	do (setf (car node) (funcall initial-element-function i))
	when (= i prefix-length)
	  do (setf merge node)
	finally (when (plusp circular-tail-size)
		  (setf (cdr last) merge))
		(return list)))

The idea being that if you stick to MAKE-LIST args you get MAKE-LIST
semantics, but if not, well:

    cmu> (make-list* 5)

    cmu> (make-list* 5 :initial-element 'foo)

    cmu> (make-list* 5 :initial-element-function #'identity)

    (0 1 2 3 4)
    cmu> (make-list* 5 :initial-element-function (lambda (x) (expt 2 x)))

    (1 2 4 8 16)
    cmu> (make-list* 5 :initial-element-function (lambda (x) (expt 2 x))
			 :circular-tail-size 3)

    (1 2 . #1=(4 8 16 . #1#))

Anyway, somewhere along the way I realized that if the
INITIAL-ELEMENT-FUNCTION argument were made to be the primary
source of initialization instead of INITIAL-ELEMENT [which,
as you'll see above is now used *only* by the default for
INITIAL-ELEMENT-FUNCTION], then by putting the keyword args in
the right order with the right defaults then "the right thing"
would simply happen automagically.  ;-}

[But, no, off hand I can't think of any other code I've written
depending on the keyword arg order quite so strongly...]


p.s. Can anyone think of better (shorter, mainly!) names for the
I tried INITIALIZATION-FUNCTION, but that didn't scan as well.

Rob Warnock			<>
627 26th Avenue			<URL:>
San Mateo, CA 94403		(650)572-2607