Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

lambda list in MULTIPLE-VALUE-BIND?

42 views
Skip to first unread message

Erik Naggum

unread,
Mar 7, 1998, 3:00:00 AM3/7/98
to

lately, I have been annoyed by a what I think is a limitation in the
usability of multiple values. in particular, I need to know whether I
got a NIL back as a value or didn't get anything. MULTIPLE-VALUE-BIND is
insufficient in keeping track of the number of values involed. in my
view, it is as much an error for a function to return too few or too many
values as it was to pass it the wrong number of arguments -- when those
values are actually needed.

now I wonder -- why was MULTIPLE-VALUE-BIND defined so simplistically?
with just a list of symbols to be bound, it sort of defeats the purpose
of a variable number of returned values, doesn't it?

I can obtain the desired behavior with either of these macros (except
that MULTIPLE-VALUE-DESTRUCTURING-BIND is a bad name):

(defmacro multiple-value-destructuring-bind (lambda-list value-form &body body)
`(destructuring-bind ,lambda-list (multiple-value-list ,value-form)
,@body))

(defmacro multiple-value-destructuring-bind (lambda-list value-form &body body)
`(multiple-value-call (lambda ,lambda-list ,@body) ,value-form))

these are fairly expensive when the function receiving multiple values
from some other function _already_ knows how many values it receives and
could signal an error when the number doesn't match expectations.

is there a better way to check the number of returned values than with
MULTIPLE-VALUE-CALL, or is that the only special operator of consequence?

#:Erik
--
God grant me serenity to accept the code I cannot change,
courage to change the code I can, and wisdom to know the difference.

Lyman S. Taylor

unread,
Mar 7, 1998, 3:00:00 AM3/7/98
to

In short I'd say that the list of variables in MULTIPLE-VALUE-BIND is
just that a list of variables. It isn't a lambda list...... nor
was it intended to be a lambda list.

In article <30982886...@naggum.no>, Erik Naggum <cle...@naggum.no> wrote:

> insufficient in keeping track of the number of values involed. in my
> view, it is as much an error for a function to return too few or too many

^^^^^^^^^^^^^^^^^^^^^^^^^^^^


> values as it was to pass it the wrong number of arguments -- when those
> values are actually needed.
>
> now I wonder -- why was MULTIPLE-VALUE-BIND defined so simplistically?
> with just a list of symbols to be bound, it sort of defeats the purpose
> of a variable number of returned values, doesn't it?

^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

In many places in Common Lisp, semantics is to try to
"fail gracefully" in certain circumstances. For instance:

(cond ) ==> NIL

Shouldn't that be an error???? There are no conditions to select...
doesn't that mean something is remiss?

I think MULTIPLE-VALUE-BIND was designed to be used in the
context that the total number of "interesting" return values are known.
It "fails gracefully" when the "values-form" doesn't supply
enough. If it should be strict then it should signal an error, period.
You can do one or the other.

[ "interesting" return values meaning that you can skip those values
you're not interested in getting if they appear at the end.
So it isn't quite following the notion of having to match the
exact number. ]

Here nil should distinguish as the value was unset (or doesn't matter).
NIL is ambiguous or if there is a need to count the return values that
is not the context in which the contruct is applicable.
You'll probably have to use the other appoarches outlined in the macros.

Not every Common Lisp construct has to be infinitely applicable in
all situations. :-)

If you make the "vars" take on the form of an optional lambda list
you can clutter up the syntax.

(new-multiple-value-bind ( a (b nil b-supplied-p) c ) value-form ...)

so it isn't just a list of variables to be bound anymore. And you
have supplied a default value if you want to provide a supplied
parameter. Why are variables being bound to value being given
default values??? I know... there are really being used as the
lambda list to multiple-value-call... but why utilize the
"syntactical sugar" of multiple-value-bind if you force that
realization upon the user....


> these are fairly expensive when the function receiving multiple values
> from some other function _already_ knows how many values it receives and
> could signal an error when the number doesn't match expectations.

How can a function "already" know? There is no restrictions placed
upon the values form. It could be any expression.

> is there a better way to check the number of returned values than with
> MULTIPLE-VALUE-CALL, or is that the only special operator of consequence?

In three of the environments I tried the following example in utilized
mutliple-value-call in the expansion of multiple-value-bind....
However, one did the following....

> ( pprint (macroexpand-1
'(mutiple-value-bind ( a b c) (values 1 2 3 )
a)))

(LET* ((#:VALUES96 (MULTIPLE-VALUE-LIST (VALUES 1 2 3 )))
( A ( POP #:VALUES96) )
( B ( POP #:VALUES96) )
( C ( POP #:VALUES96) ))
A)
>

I'm not so sure I'm happy with this. However, if the list of vars
were some sort of lambda list you couldn't expand in this fashion.
I presume there is some rationale for doing it this way...

However, this does lend itself to the approach of a fixed list
of return values.... by just comparing two lengths...

(defmacro fixed-length-mulitiple-value-bind
( var-list value-form &body body )
"Bind the variable in the var-list to the values returned by the
value form. If the number of return arguments do not match
the number of args signal an error."
(let ( (num-vars (length var-list))
(values-list-symbol (gensym "values")) )
(labels ( (var-bindings ( vars )
(if vars
(cons `( ,(first vars)
(pop ,values-list-symbol ))
(var-bindings (rest vars))))))

`(let ( ( ,values-list-symbol
(multiple-value-list ,value-form )))
(unless (= ,num-vars (length ,values-list-symbol))
(error "not enough values returned" ))
(let* ( ,@(var-bindings var-list ) )
,@body )))))


A tad bit longer than the originally presented macros but is rather
rigid about number of return arguments and I don't have to insert
code into the body to do the checking...

--

Lyman S. Taylor "Because no matter where you go,
(ly...@cc.gatech.edu) there you are."
Buckaroo Banzai

Lyman S. Taylor

unread,
Mar 7, 1998, 3:00:00 AM3/7/98
to

In article <6dsm0u$s...@pravda.cc.gatech.edu>,
Lyman S. Taylor <ly...@cc.gatech.edu> wrote:

P.S.

> In short ....

I think of MULTIPLE-VALUE-BIND in the same light as LET.
Is LET deficient?

( let ( a )

a ;; <- is NIL. Because the init form returned NIL or
;; because there was not init form.
)

...
> However, one did the following....
>
> > ( pprint (macroexpand-1
> '(mutiple-value-bind ( a b c) (values 1 2 3 )
> a)))
>
> (LET* ((#:VALUES96 (MULTIPLE-VALUE-LIST (VALUES 1 2 3 )))

I forgot to mention that this was LispWorks for Windows 4 to
give credit/blame ( depending on your viewpoint) were it is due. :-)
[ Which is interesting because 3.2.2 for SunOS used multiple-value-call]

I guess it is a tradeoff between a lambda invocation that takes all
optional args ( likely to form a list of some sort) and directly
forming a list of the results.

Lyman S. Taylor

unread,
Mar 7, 1998, 3:00:00 AM3/7/98
to

In article <6dsm0u$s...@pravda.cc.gatech.edu>,
Lyman S. Taylor <ly...@cc.gatech.edu> wrote:
...
>
> (defmacro fixed-length-mulitiple-value-bind

after some more thought... the following is slightly less rigid
and has a more tractable name. :-)


(defmacro bind-n-values (num-var var-list value-form &body body)
"Bind the variables in the var-list to the values returned by the
value form. The actual number of values returned by the value-form
is bound to the first argument. Like the variables, this one
is lexically scoped to the body of the construct."

(let ( (num-vars (length var-list))
(values-list-symbol (gensym "values")) )
(labels ( (var-bindings ( vars )
(if vars
(cons `( ,(first vars)
(pop ,values-list-symbol ))
(var-bindings (rest vars))))))

`(let ( ( ,values-list-symbol
(multiple-value-list ,value-form )))

(let* ( ( ,num-var (length ,values-list-symbol))


,@(var-bindings var-list ) )
,@body )))))


This way one can decide just how big of an error this is.....
with necessarily introducing symbols to signify whether
a variable as been bound ( as opposed to only invoking
error is they're not exaclty equal... )

Usage:

> (bind-n-values num (a b c ) (values 1 2 3 )
(format t "~A ~A ~A ~A ~A" a b c num))
1 2 3 3
NIL

> (bind-n-values num (a b c ) (values 1 2 )
(format t "~A ~A ~A ~A ~A" a b c num))
1 2 NIL 2
NIL

> (bind-n-values num (a b c ) (values 1 2 3 4 5)
(format t "~A ~A ~A ~A ~A" a b c num))
1 2 3 5
NIL

>


--

Lyman S. Taylor "Twinkie Cream; food of the Gods"
(ly...@cc.gatech.edu) Jarod, "The Pretender"


Erik Naggum

unread,
Mar 8, 1998, 3:00:00 AM3/8/98
to

* ly...@cc.gatech.edu (Lyman S. Taylor)

| In short I'd say that the list of variables in MULTIPLE-VALUE-BIND is
| just that a list of variables. It isn't a lambda list...... nor was it
| intended to be a lambda list.

sigh. I _know_ that, dammit. the question is _why_.

| How can a function "already" know? There is no restrictions placed upon
| the values form. It could be any expression.

sigh. when a function returns a number of values, the receiving code
(remember? there's actually a computer underneath here) _knows_ at that
time how many values it received. it isn't constant, if that's what you
think, but it _has_ to know, one way or the other, because it will take
actions that depend on such knowledge, like binding variables with no
corresponding value to NIL. if it had no clue how many values it
received, it couldn't do that, OK? so when it already has that value, I
want to cause an error if it is not the number I expect, _without_ having
to engage in very expensive operations or cons up the values into a list
-- I might just as well return a list, then, were it not for the fact
that I do need the distinction between the primary value and the
non-primary values in other contexts.

| In three of the environments I tried the following example in utilized
| mutliple-value-call in the expansion of multiple-value-bind.... However,
| one did the following....

the compiler is not obliged to do the same kind of macroexpansion as you
are. you have to look at the compiled code or know your compiler better
to understand how it does its work. compiler-macros do weird stuff.

but aren't you aware that DESTRUCTURING-BIND will barf on the wrong
number of bound variables already? there's no need to reinvent it.

Sunil Mishra

unread,
Mar 8, 1998, 3:00:00 AM3/8/98
to

In article <30983403...@naggum.no> Erik Naggum <cle...@naggum.no> writes:

| How can a function "already" know? There is no restrictions placed upon
| the values form. It could be any expression.

sigh. when a function returns a number of values, the receiving code


(remember? there's actually a computer underneath here) _knows_ at that
time how many values it received. it isn't constant, if that's what you
think, but it _has_ to know, one way or the other, because it will take
actions that depend on such knowledge, like binding variables with no
corresponding value to NIL. if it had no clue how many values it
received, it couldn't do that, OK? so when it already has that value, I

^^^^^^^^^^^^^^^^^^^^^^^

A rather strong claim! I could propose a mechanism by which the system
would not really *count* the number of arguments received. All the system
needs to have is a list of the symbols to be bound, and some way to
differentiate a frame from a return value on the stack. Then, it could pop
values one at a time off the stack, and bind them to the next available
variable.

want to cause an error if it is not the number I expect, _without_ having
to engage in very expensive operations or cons up the values into a list
-- I might just as well return a list, then, were it not for the fact
that I do need the distinction between the primary value and the
non-primary values in other contexts.

I'm afraid you might be stuck with multiple-value-call... This is the best
I could come up with... (which looking back on your original post is
exactly what you had come up with)

(defmacro fixed-length-multiple-value-bind (vars values-form &rest body)
`(multiple-value-call #'(lambda ,vars ,@body) ,values-form))

One way around the efficiency issue is by using the above macro only for
debugging, and using regular multiple-value-bind when you have your program
straightened out.

Sunil

Lyman S. Taylor

unread,
Mar 8, 1998, 3:00:00 AM3/8/98
to

In article <30983403...@naggum.no>, Erik Naggum <cle...@naggum.no> wrote:
>* ly...@cc.gatech.edu (Lyman S. Taylor)
...

>| intended to be a lambda list.
>
> sigh. I _know_ that, dammit. the question is _why_.

A suitable answer is "why not". It is a programming design choice.
I don't see conclusive agrument for why it should have to be a lambda list.
As I stated in one of my follow ups a list of variable names matches
well with LET. LET doesn't have all the optional lambda list constructs.



>
>| How can a function "already" know? There is no restrictions placed upon
>| the values form. It could be any expression.
>

> sigh. when a function returns a number of values, the receiving code

sigh. I was speaking of speaking at the source code level. Since,
the discussion was about common lisp the language and not common
lisp the implementation. I suppose I should have said how can the
programmer know.

There is no way in common lisp to directly retrieve this number.
Therefore, the code (the function) can't reflect knowledge about what
this number is.

If that is your complaint then perhaps there is an argument
for something that would make this number more directly
accessible at the source code level. However, that does NOT
necessitate giving optional lambda list semantics to binding
the multiple values.

What if there were something like (values-and-n .... )

> (values-and-n 'a "b" #\c )
3
A
"b"
#\c
>

Granted optional argument lambda lists have the same sort of
problem ( how many got bound), but doesn't mean that the same
solution need be applied.

If the concept of "either it is the right number or it is wrong"
is being applied, the crux of the problem is "how many" not
"which ones".

>
>| In three of the environments I tried the following example in utilized
>| mutliple-value-call in the expansion of multiple-value-bind.... However,
>| one did the following....
>

> the compiler is not obliged to do the same kind of macroexpansion as you
> are. you have to look at the compiled code or know your compiler better
> to understand how it does its work. compiler-macros do weird stuff.

The point of my ilustration was that there was another approach
to solving the problem that fits the current syntax than those
you presented. If you propose changing the syntax you'd disallow
this approach [ yet another reason why the designer may have chosen
this syntax. ]

I would expect that a good really compiler might recognize that the
resulting list has a very brief lifetime and simply forgo consing up
the list. Which would require no magical compiler macro to do the
job at all. I would suspect that a vendor would write macros
that expanded into idioms that they their compiler works well with.

So looking at the compiler results would seem rather inconclusive
whether a different expansion is delivered to the compiler or the compiler
just did a good job.

> but aren't you aware that DESTRUCTURING-BIND will barf on the wrong
> number of bound variables already? there's no need to reinvent it.

Sure, I get some wierd error message from DESTRUCTING-BIND... Personally
I try to present informative error messages in my code. I spend
portion of my time as a TA explaining what errors messages
typically presented by most common lisp enviroments mean in English.
Especially in this context, the DESTRUCTING-BIND will not be
present in the original source.

Perhaps a personal coding style quirk I guess. ;-)

Seemingly, you have already picked out your "hammer" and are looking
for support in labeling the problem as a "nail". I don't think it is
a "nail" and you don't need the "hammer". However, I wasn't on
committee that designed multiple-value-bind. My intuition says that
someone had the thought of constructing something like LET for
capturing mutliple values. Hence, multiple-value-bind looks like
it does. But that is just my intuition.

In most cases the construct works and isn't a problem. For situations
which require more the more "low level" constructs are there and
"roll your own". Like I said before every construct need not be
universally applicable in all contexts. Gee, you have two solution
macros that require one line to compose...

I also think that filling up of the body of the construct with code
testing supplied-p variables when primarily what I want to know is
how many values got returned isn't the best approach.

Erik Naggum

unread,
Mar 9, 1998, 3:00:00 AM3/9/98
to

* Erik Naggum

| if it had no clue how many values it received, it couldn't do that, OK?

* Sunil Mishra


| A rather strong claim! I could propose a mechanism by which the system
| would not really *count* the number of arguments received.

I did not say it would have to actually _count_ them. my claim stands --
it has to have _some_ clue how many values it received -- your suggestion
only shows that the clue comes in a different way than a count.

however, I still haven't seen an implementation of multiple values that
does not include the number of return values as _another_ return value,
such as in the length field of a multiple-value vector or a separate
register (frequently the same as the one in which the incoming argument
count is passed).

| One way around the efficiency issue is by using the above macro only for
| debugging, and using regular multiple-value-bind when you have your
| program straightened out.

this is a good idea. however, then I'd like a "portable" way of knowing
what the DEBUG optimization declaration is at macro expansion time. (I
say "portable" because I am happy if I can write a macro conditionalized
on the implementation.) I've found COMPILER::.DEBUG. in ACL.

Erik Naggum

unread,
Mar 9, 1998, 3:00:00 AM3/9/98
to

* Lyman S. Taylor

| A suitable answer is "why not".

bzzzzt. thank you for playing. I'd still like to hear from anybody else
who have thought about multiple values and their use.

| I also think that filling up of the body of the construct with code
| testing supplied-p variables when primarily what I want to know is
| how many values got returned isn't the best approach.

whoever talked about supplied-p variables? you can't even have read what
I wrote. no wonder you don't understand what I'm after. primarily, I
want to ensure that the number of returned values is exactly matching the
expectations. I'm sure you can see this point if you think if of the
similarity to passing arguments. somehow, we keep track of those, and
the function also _knows_ how many arguments it received (because the
caller sent that information to it) -- which allows it to bind optional
arguments to their default values, etc.

suppose I write a general interface that expects functions it calls to
return three values. this is not unlike calling functions with three
arguments and expecting them to handle that and to get an error if they
don't. since we already have an elaborate scheme for argument checking
and such, I figured: what do we do to get the same for return values?

fortunately, MULTIPLE-VALUE-CALL can be implemented _really_ efficiently,
but it takes extra care to make it that efficient. consing up a list of
return values is not an option in this case -- if it had been, it would
have been easier to return a list and use DESTRUCTURING-BIND directly.

Lyman S. Taylor

unread,
Mar 9, 1998, 3:00:00 AM3/9/98
to

In article <30983959...@naggum.no>, Erik Naggum <cle...@naggum.no> wrote:
>* Lyman S. Taylor

...
>| I also think that filling up of the body of the construct with code
>| testing supplied-p variables when primarily what I want to know is
>| how many values got returned isn't the best approach.
>
> whoever talked about supplied-p variables? you can't even have read what
> I wrote. no wonder you don't understand what I'm after. primarily, I
> want to ensure that the number of returned values is exactly matching the
> expectations.

Then why ask for a lambda list? It not a lambda list that you
want. You want a list of variable names whose length
has some special connotation. While this is a subset of what
a lambda list is, it isn't whole nature of a lambda list.

Yes I did read your code. And while that might be your intention,
your macros allow ANY lambda list to be specified.... optional
arguments, keywords, etc. etc.

Granted I did fail to realize the primary reason you are trying to
use these is constructs is they happen to invoke an error message
in the condition you are looking for.

If you restrict the usage only to the contexts YOU are intended to
use them ( no optional args, etc. ) then sure a "side effect" is that
a mismatch in the number of args to the values returned will
happen to return an error.

However you've also opened a slippery slope of complexity in what
is the legal syntax. It goes way beyond what was intended or
appropriate.

With the destructing bind implementation the following is
legal as the "list of variables"

( (a b ) c )

Eh? Or
( &optional ( a nil a-supplied-p ) b c )

Are those suppose to be "legal"? I don't think so.
Are they lambda lists? Yes.


> don't. since we already have an elaborate scheme for argument checking
> and such, I figured: what do we do to get the same for return values?

Perhaps the elaborate scheme is too elaborate for the task
at hand.

I suppose the some code could be inserted your macro to constraint
them to only accept this limited notion of a lambda list. However,
since it wasn't present I was misled into thinking any old
lambda list would do.

For the language specificaiton I suppose the designer could add
this more limited form of lambda list to the list of constructs
defined in the language. Since the language is quite large in
its present state I would imagine there is an argument against
this.

Erik Naggum

unread,
Mar 9, 1998, 3:00:00 AM3/9/98
to

* Lyman S. Taylor

| Then why ask for a lambda list? It not a lambda list that you want.

I want &OPTIONAL so I can distinguish a NIL from a missing value.

| You want a list of variable names whose length has some special
| connotation. While this is a subset of what a lambda list is, it isn't
| whole nature of a lambda list.

there is no such thing as _a_ lambda list. there are many of them,
subtly different for the various needs they serve. see the standard.

| Yes I did read your code. And while that might be your intention, your
| macros allow ANY lambda list to be specified.... optional arguments,
| keywords, etc. etc.

yes, my macros are overly permissive and certainly over-kill. why do you
think I asked for a better way to do it?

| Perhaps the elaborate scheme is too elaborate for the task at hand.

I quite agree.

| For the language specificaiton I suppose the designer could add this more
| limited form of lambda list to the list of constructs defined in the
| language. Since the language is quite large in its present state I would
| imagine there is an argument against this.

well, these are easy arguments after the fact. I'd like to hear from
those who designed MULTIPLE-VALUE-BIND what their thoughts were at the
time.

Barry Margolin

unread,
Mar 9, 1998, 3:00:00 AM3/9/98
to

In article <6e04lc$f...@pravda.cc.gatech.edu>,

Lyman S. Taylor <ly...@cc.gatech.edu> wrote:
> However you've also opened a slippery slope of complexity in what
> is the legal syntax. It goes way beyond what was intended or
> appropriate.

And part of his question was why this was intended. I.e. why did we make
argument passing require precise matching against required arguments and
keyword arguments, whereas multiple values do no similar checking?

I wasn't around when multiple values were originally being done (possibly
for Lisp Machines around 1980). But I suspect it was to be consistent with
the way multiple values are handled in ordinary argument positions.
E.g. you can write

(print (round 10.3))

and the second return value from ROUND will be ignored automatically. So
why should

(multiple-value-bind (val) (round 10.3)
(print val))

be any different?

In general, I don't think complex multiple-value structures were expected
to be as pervasive as complex parameter structures, so powerful facilities
for checking and extracting values weren't designed into the language. You
might be surprised how much debate there was before we added the NTH-VALUE
function into ANSI CL. Most of the time, if you're returning complex data,
you should use a structured data type rather than multiple values; the main
intent of multiple values is to allow you to return one or two "extra"
values, which may or may not be needed in particular situations.

--
Barry Margolin, bar...@bbnplanet.com
GTE Internetworking, Powered by BBN, Cambridge, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.

Antonio Leitao

unread,
Mar 9, 1998, 3:00:00 AM3/9/98
to

I want to stress right now that I'm not sufficiently confident about
my own knowledge to continue the discussion but since no one has given
the following argument before, I will give it a try:

IMHO Erik Naggum has made a very good point about multiple-value-bind
and, besides the many good reasons that he found for it, I will just
add another one and answer, at the same time, to a question posed by
Lyman Taylor regarding the let case.

I vaguely remember looking at continuation-passing-style and at an
implementation of multiple-value-bind based on the following
transformation:


(multiple-value-bind (a b c)
(function-delivering-some-values ...)
_code-using-a-b-c_)

is transformed into

(function-delivering-some-values ... #'(lambda (a b c) _code-using-a-b-c_))

Of course, now, function-delivering-some-values has an extra argument
for the continuation. But this only matters for the compiler.

The implementation of (values ...) is just a funcall of the continuation
with the arguments of the values.

Looking at the transformation, it is obvious that using the full power
of CommonLisp lambda lists is a natural extension to
multiple-value-bind.


Now, Lyman's argument concerning let.

Let can be transformed from

(let ((a ...) (b ...) (c ...))
_code-using-a-b-c_)

To

((lambda (a b c) _code-using-a-b-c_) ... ... ...)

Following the same logic, the it is also natural to extend let-bindings
in such a way that they become more like CommonLisp lambda lists,
but...

1. We know, in advance, the arguments for the lambda, so it's strange
to use &optional, &rest and etc in the let case.

2. The syntax of the let bindings already includes an initialization
form which makes it difficult to extend it to become compatible
with lambda lists.

3. This doesn't happen in the multiple-value-bind case.

So, my _real humble opinion_ (and I want to stress that) is that it
would be a good thing to generalize multiple-value-bind and, at least
on compilers that use CPS, it shouldn't cost much.

I hope the guys who really understand CPS can comment on my view of
the problem.

Antonio.


Sunil Mishra

unread,
Mar 9, 1998, 3:00:00 AM3/9/98
to

In article <30983923...@naggum.no> Erik Naggum <cle...@naggum.no> writes:

I did not say it would have to actually _count_ them. my claim stands --
it has to have _some_ clue how many values it received -- your suggestion
only shows that the clue comes in a different way than a count.

Fair enough.

| One way around the efficiency issue is by using the above macro only for
| debugging, and using regular multiple-value-bind when you have your
| program straightened out.

this is a good idea. however, then I'd like a "portable" way of knowing
what the DEBUG optimization declaration is at macro expansion time. (I
say "portable" because I am happy if I can write a macro conditionalized
on the implementation.) I've found COMPILER::.DEBUG. in ACL.

I was thinking of adding a feature at compile time to indicate the debug
level in the system declaration. Well, good luck!

Sunil

Lyman S. Taylor

unread,
Mar 9, 1998, 3:00:00 AM3/9/98
to

In article <30984294...@naggum.no>, Erik Naggum <cle...@naggum.no> wrote:
...

>
> well, these are easy arguments after the fact. I'd like to hear from
> those who designed MULTIPLE-VALUE-BIND what their thoughts were at the
> time.

I wonder if MULTIPLE-VALUE-SETQ ( or the Lisp Machine Lisp MULTIPLE-VALUE)
predates the "bind" version. If I'm not sure the lambda list syntax would
make as much sense when applied to that construct.

Lyman S. Taylor

unread,
Mar 9, 1998, 3:00:00 AM3/9/98
to

In article <wo3egrr...@gia.ist.utl.pt>,

Antonio Leitao <a...@gia.ist.utl.pt> wrote:
>
>Now, Lyman's argument concerning let.
>
>Let can be transformed from
>
>(let ((a ...) (b ...) (c ...))
> _code-using-a-b-c_)
>
>To
>
>((lambda (a b c) _code-using-a-b-c_) ... ... ...)

However,

(let ( a ( b ... ) (c ...) )
_code-using-a-b-c_ )

would transform to

((lambda ( a b c) _code-using-a-b-c_) NIL ... ... )


Which while not difficult, isn't exactly a one-to-one equivalent.


>So, my _real humble opinion_ (and I want to stress that) is that it
>would be a good thing to generalize multiple-value-bind and, at least
>on compilers that use CPS, it shouldn't cost much.

Fine just so long as it is called something other than
MULTIPLE-VALUE-BIND. If you "add features" to standard language
constructs code becomes increasing non portable... which defeats the
purpose of having a standard.

Erik Naggum

unread,
Mar 10, 1998, 3:00:00 AM3/10/98
to

* Lyman S. Taylor

| I wonder if MULTIPLE-VALUE-SETQ ( or the Lisp Machine Lisp
| MULTIPLE-VALUE) predates the "bind" version. If I'm not sure the lambda
| list syntax would make as much sense when applied to that construct.

I prefer (SETF VALUES) to MULTIPLE-VALUE-SETQ, but this is not the issue.
I have no desire to _change_ MULTIPLE-VALUE-BIND; I want something it
does not provide and have been looking for better ways to achieve that
than the inefficient overkill solutions I had found.

frankly, I don't understand your reactions.

Erik Naggum

unread,
Mar 10, 1998, 3:00:00 AM3/10/98
to

* Lyman S. Taylor

| Fine just so long as it is called something other than
| MULTIPLE-VALUE-BIND. If you "add features" to standard language
| constructs code becomes increasing non portable... which defeats the
| purpose of having a standard.

I was about to ask you if you felt that my questions had somehow been
threatening, but you seem to have answered it in this response. look,
nobody is proposing to change MULTIPLE-VALUE-BIND. I asked why it was
the way it was when something I could use would have been so easy to do
instead of what was done. I even went out of my way to define _new_
macros that would handle this, with a _new_ name. what's to fear?

one of the nice things about the Common Lisp package system is that I can
shadow MULTIPLE-VALUE-BIND in the package in which I need this and remove
the shadowing when I'm through debugging. this is what I'll be doing;
it'll look the same and work the same, except that I'll be able to debug
a complex protocol between lots of functions and methods that plug into
eachother in quite non-intuitive ways. thanks to Sunil Mishra for the
basic principle of this design -- it's so simple I had overlooked it.

David D. Smith

unread,
Mar 10, 1998, 3:00:00 AM3/10/98
to

In article <30982886...@naggum.no>, Erik Naggum <cle...@naggum.no> wrote:

> lately, I have been annoyed by a what I think is a limitation in the
> usability of multiple values. in particular, I need to know whether I
> got a NIL back as a value or didn't get anything. MULTIPLE-VALUE-BIND is

...


> is there a better way to check the number of returned values than with
> MULTIPLE-VALUE-CALL, or is that the only special operator of consequence?

I think MVCall is your best option.

(defmacro multiple-value-count&bind ((count-var &rest vars) values-form
&body body)
`(multiple-value-bind (,count-var . ,vars)
(multiple-value-call #'mvc-count ,values-form)
. ,body)
)

(defun mvc-count (&rest values)
;(declare (dynamic-extent values)) ;illegal, but sometimes OK
(apply #'values (length values) values))

(multiple-value-count&bind (a b c) (truncate 3 2) (list a b c))
(2 1 1)
?

(multiple-value-count&bind (a b c) (values) (list a b c))
(0 NIL NIL)
?

(multiple-value-count&bind (a b c) 9 (list a b c))
(1 9 NIL)
?

d

0 new messages