From: Erik Naggum
Subject: lambda list in MULTIPLE-VALUE-BIND?
Date: 
Message-ID: <3098288658259597@naggum.no>
  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.

From: Lyman S. Taylor
Subject: Re: lambda list in MULTIPLE-VALUE-BIND?
Date: 
Message-ID: <6dsm0u$st3@pravda.cc.gatech.edu>
 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 <················@naggum.no>, Erik Naggum  <······@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,
(·····@cc.gatech.edu)			there you are."
						Buckaroo Banzai
From: Lyman S. Taylor
Subject: Re: lambda list in MULTIPLE-VALUE-BIND?
Date: 
Message-ID: <6dsq4v$t6o@pravda.cc.gatech.edu>
In article <··········@pravda.cc.gatech.edu>,
Lyman S. Taylor <·····@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			"Because no matter where you go,
(·····@cc.gatech.edu)			there you are."
						Buckaroo Banzai
From: Lyman S. Taylor
Subject: Re: lambda list in MULTIPLE-VALUE-BIND?
Date: 
Message-ID: <6dt2td$kb@pravda.cc.gatech.edu>
In article <··········@pravda.cc.gatech.edu>,
Lyman S. Taylor <·····@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" 
(·····@cc.gatech.edu)                     Jarod, "The Pretender" 
From: Erik Naggum
Subject: Re: lambda list in MULTIPLE-VALUE-BIND?
Date: 
Message-ID: <3098340336248874@naggum.no>
* ·····@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.

#: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.
From: Sunil Mishra
Subject: Re: lambda list in MULTIPLE-VALUE-BIND?
Date: 
Message-ID: <efyra4c29f3.fsf@piedmont.cc.gatech.edu>
In article <················@naggum.no> Erik Naggum <······@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
From: Lyman S. Taylor
Subject: Re: lambda list in MULTIPLE-VALUE-BIND?
Date: 
Message-ID: <6dvbqf$6q7@pravda.cc.gatech.edu>
In article <················@naggum.no>, Erik Naggum  <······@naggum.no> wrote:
>* ·····@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. 



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