Google Mail Calendar Documents Reader Web more »
Recently Visited Groups | Help | Sign in
Google Groups Home
Alternatives to values/call-with-values
There are currently too many topics in this group that display first. To make this topic appear first, remove this option from another topic.
There was an error processing your request. Please try again.
flag
  Messages 26 - 50 of 100 - Collapse all  -  Translate all to Translated (View all originals) < Older  Newer >
The group you are posting to is a Usenet group. Messages posted to this group will make your email address visible to anyone on the Internet.
Your reply message has not been sent.
Your post was successful
 
From:
To:
Cc:
Follow-up To:
Add Cc | Add Follow-up to | Edit Subject
Subject:
Validation:
For verification purposes please type the characters you see in the picture below or the numbers you hear by clicking the accessibility icon. Listen and type the numbers that you hear
 
Anton van Straaten  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 08:10
Newsgroups: comp.lang.scheme
From: "Anton van Straaten" <an...@appsolutions.com>
Date: Tue, 12 Aug 2003 07:07:51 GMT
Local: Tues 12 Aug 2003 08:07
Subject: Re: Alternatives to values/call-with-values

Anthony Carrico wrote:
> From Clinger:
>   (eq? '[[[[foo]]]] 'foo)  =>  #t

SML/NJ says:  ((((4)))) = 4    => true : bool

> I'm currently in the camp that thinks R5RS multiple values already
> make perfect sense. They seem to jive 100% with my intuition that
> Scheme is really just a convenient direct style syntax for CPS. From
> that point of view continuations can have multiple results because
> continuations are just lambdas and lambdas can have multiple
> parameters.  How could this be controversial?

The first controversial issue there is "lambdas can have multiple
parameters".  You suggest (later in your post) that an error might have been
made extending compose to multiple values - but perhaps the error is made in
the way multiple values are thought about and handled in the first place.

Anyway, by the same token, how could it be controversial to treat a sequence
of multiple values as a first-class entity?  The R5RS formal semantics does
it internally:

If you look at the definition for 'cwv' in the R5RS formal semantics (end of
sec 7.2.4), translated into something more Scheme-like, and factoring out
some of the CPS and helper procedures like twoarg (which checks arg count)
and applicate (essentially 'apply'), it looks like the code below (note if
you compare to R5RS, you might notice an extra 'k' in my version, because
R5RS has an omission in the definition of cwv - there should be a kappa
after the last occurrence of e*, otherwise call-with-values would terminate
a program):

(define call-with-values
  (lambda (producer consumer k)
    ((lambda (e*) (k (consumer e*))) (producer))

Now, e* is a "sequence" in the formal semantics.  All that's being done here
is that the sequence of multiple values produced by the producer function,
is passed to an anonymous procedure which passes them to the consumer
function.  In fact, if you factor out all the CPS except for the provided
continuation k, it looks like this:

(define call-with-values
  (lambda (producer consumer k)
    (k (consumer (producer)))))

So one question is, if this is what's happening in the formal semantics,
mightn't it be a good idea to be able to do something similar in Scheme?
Why are we forced to do something so simple using a very special procedure,
call-with-values, and if we write code like the above, it is an error?

From my own perspective, I've always found multiple values not to fit
intuitively with the rest of Scheme.  This has nothing to do with any of the
political history or the fact that they didn't exist in earlier versions of
Scheme: I learned Scheme post-R5RS, so to me, multiple values have always
been there.  But they never really seemed to fit.

It was about a year ago that I first read the 1995 discussion about this
first-class sequence proposal.  I found Matthias B's arguments convincing,
and I had enough familiarity with ML at that point that it was instantly
attractive to me.

The first-class sequence proposal seems to provide at least three benefits
which I consider worthwhile:

1.  Allow a multiple-value return result to be treated as a first-class
value.  While I understand that Scheme is not necessarily about making
everything first class, I find the non-first-classness of multiple-values
unpleasant.  It limits how functions which return multiple values can be
invoked.  I find that to be against the spirit of Scheme.  I could expand on
that, but in brief, the inability to reliably use an expression of the form
(let ((x (f ...))...  for any function f is hard for me to understand,
although I do understand the continuation justification.  The fact that the
primary motivating factor seems to be efficiency/performance for
multiple-value return only makes things worse, for me - surely there are
ways to achieve performance without requiring special and somewhat unwieldy
non-first-class constructs.

2.  Expose a more efficient structure for argument-passing than lists.
Smart compilers already do this under the hood.  The formal semantics
already treats arguments as "sequences", for some of the same reasons as
compilers do, afaict: because lists are an unnecessarily complex &
inefficient structure for argument passing.  But at the Scheme level, if you
don't bind all a function's arguments to individual variables, you get a
list, which isn't always what's wanted.  The same argument that argues for
multiple value return for performance/efficiency reasons, argues for
something other than lists as a way to package arguments.

3.  Create consistency between argument passing and multiple value return.
Repeating part of point 2, right now we have what looks like real lists for
arguments at the Scheme level, which can be too heavy; and we have values
which can't be dealt with directly and have to be funnelled through a
procedure's argument list via call-with-values (talking about features
defined by R5RS).  The first-class sequence proposal seems to provide a
middle ground which cleans things up and improves flexibility.

> The only value I see in the "whacked-tuples" model is it makes things
> nice for people who happen to want to write a procedure whose mode of
> operation is to pass along an arbitrary number of results from one
> procedure to the corresponding parameters of another. This particular
> control flow isn't even possible in the functional world, so why is
> anyone interested in calling it "compose"?

The end result of the first-class sequence proposal would be something very
similar to ML, so it's hardly at variance with the functional world,
depending on what you mean by "functional world".  One definition of the
functional world has lambdas only taking one parameter...

> It seems to me that people are trying to generalize something
> simple (compose in the world of functions with one parameter
> and one result) into a context where it
> doesn't make any sense. So let's call that compose-with-a-twist. Now,
> What makes compose-with-a-twist so important that we should worry
> about it?

> The logic:
> 1. Scheme has multiple values.
> 2. Let's extend compose to multiple values.
> 3. Hmm... this seems a little strange.
> 4. Let's redesign Scheme's call mechanism.

> I submit that the error may have been made in step 2!

Or step 1!  My logic doesn't start with step 1.  It starts with wanting a
consistent and usable solution to the issue of passing multiple values
around: whether to functions, or from functions.

> If people still want to continue with step 4, at least consider the
> following: Clinger showed that there is no price to be payed for
> multiple values (when you aren't using them).

But some people find them to be a less-than-useful or attractive mechanism,
whereas the problem they are supposed to solve does exist.  The sequence
proposal (arguably) provides a more complete & elegant solution.

> To my knowledge he didn't show that there is no price
> to be payed for sequences (aka tuples).

True.  That would need to be investigated, as would the usability within
Scheme of the proposal (IMO).

> In particular, who's job is it to unwind all those tuples (aka
> sequences) of one? The tuple constructors? The accessors? During the
> normal course of program flow, who's job is it to make sure they don't
> build up in the first place? Are they a space leak in certain
> unfortunate code?

Maybe Matthias B. could describe that.  Appel's book says (ch 5.3), talking
about primops: "Each [primop] category is converted into [CPS] in one of two
ways, depending on whether the operator takes one argument or more than
one."  It makes sense that it would happen at function call sites and other
tuple construction locations.

> The other thing I find strange about tuples is that tuple constructors
> must be "special" procedures since they take more than one argument in
> a one argument only world.

Every procedure call would implicitly construct a tuple, wouldn't it?  An
explicit tuple constructor would only be needed in certain situations.  In
many respects, it simply seems like exposing something that already happens
internally.  Multiple values are already very "special".  One way to look at
this proposal is it makes them less special.

Note that I'm not claiming I'm "right" about all this.  I don't think my
understanding is in-depth enough to make that judgement.  But the proposal
sounds worthwhile to me, and I haven't yet seen any reasons that, to me,
argue for rejecting it.

Anton


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Rush  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 11:25
Newsgroups: comp.lang.scheme
From: David Rush <dr...@aol.net>
Date: Tue, 12 Aug 2003 10:22:52 +0000 (UTC)
Local: Tues 12 Aug 2003 11:22
Subject: Re: Alternatives to values/call-with-values
"Anton van Straaten" <an...@appsolutions.com> writes:

> Note that I'm not claiming I'm "right" about all this.  I don't think my
> understanding is in-depth enough to make that judgement.  But the proposal
> sounds worthwhile to me, and I haven't yet seen any reasons that, to me,
> argue for rejecting it.

Actually, I think you've argued the point very well. Indeed, it cuts
to the heart of my difficulties with call/values (aside from R4RS
incompatibility). I certainly could live with Matthias Blume's
proposal. Will Clinger's proposal seems to be very concerned with the
eq?-ness of sequence/tuple objects which Matthias Blume seems to have
engineered out of the systemm by making tuples immutable.

So what are we mere users missing here?

david rush
--
He who would make his own liberty secure, must guard even his enemy
from repression
        -- Thomas Paine


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Michael Sperber  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 14:01
Newsgroups: comp.lang.scheme
From: Michael Sperber <sper...@informatik.uni-tuebingen.de>
Date: Tue, 12 Aug 2003 15:01:37 +0200
Local: Tues 12 Aug 2003 14:01
Subject: Re: Alternatives to values/call-with-values

>>>>> "bear" == Ray Dillinger <b...@sonic.net> writes:

bear> But the ability to pass arbitrary multiple results directly in
bear> as parameters to another function would make scheme into a better
bear> DD language than any now extant.  

Huh?  That's *exacty* what CALL-WITH-VALUES does.  Could you clarify
what you mean?

--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lauri Alanko  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 14:10
Newsgroups: comp.lang.scheme
From: Lauri Alanko <l...@iki.fi>
Date: Tue, 12 Aug 2003 13:09:08 +0000 (UTC)
Local: Tues 12 Aug 2003 14:09
Subject: Re: Alternatives to values/call-with-values
Michael Sperber <sper...@informatik.uni-tuebingen.de> virkkoi:

> >>>>> "bear" == Ray Dillinger <b...@sonic.net> writes:

> bear> But the ability to pass arbitrary multiple results directly in
> bear> as parameters to another function would make scheme into a better
> bear> DD language than any now extant.  

> Huh?  That's *exacty* what CALL-WITH-VALUES does.  Could you clarify
> what you mean?

I'd hazard a guess that the essential difference is in the convenience
between:

(call-with-values (lambda () e) f)

and

(f e)

Lauri Alanko
l...@iki.fi


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Matthias Blume  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 15:35
Newsgroups: comp.lang.scheme
From: Matthias Blume <matth...@shimizu-blume.com>
Date: 12 Aug 2003 09:35:37 -0500
Local: Tues 12 Aug 2003 15:35
Subject: Re: Alternatives to values/call-with-values

Michael Sperber <sper...@informatik.uni-tuebingen.de> writes:
> >>>>> "bear" == Ray Dillinger <b...@sonic.net> writes:

> bear> But the ability to pass arbitrary multiple results directly in
> bear> as parameters to another function would make scheme into a better
> bear> DD language than any now extant.  

> Huh?  That's *exacty* what CALL-WITH-VALUES does.  Could you clarify
> what you mean?

"directly" as opposed to "via CALL-WITH-VALUES"

(Just a guess.)

Matthias


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Matthias Blume  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 15:41
Newsgroups: comp.lang.scheme
From: Matthias Blume <matth...@shimizu-blume.com>
Date: 12 Aug 2003 09:41:28 -0500
Local: Tues 12 Aug 2003 15:41
Subject: Re: Alternatives to values/call-with-values
"Anton van Straaten" <an...@appsolutions.com> writes:

> Anthony Carrico wrote:
> > From Clinger:
> >   (eq? '[[[[foo]]]] 'foo)  =>  #t

> SML/NJ says:  ((((4)))) = 4    => true : bool

Yes.  And any mathematicias will agree that

   (x) = x

and therefore, by extension,

   ((((x)))) = x

I really don't see why people would get bent out of shape by something
like that.  Also, notice that (as I mentioned before several times)
you can already define such a bracketing construct (call it TUPLE)
with these properties it RnRS Scheme, so it can't be all that "strange":

   (define (tuple . l)
      (if (= (length l) 1) (car l) l))

> > In particular, who's job is it to unwind all those tuples (aka
> > sequences) of one? The tuple constructors? The accessors? During the
> > normal course of program flow, who's job is it to make sure they don't
> > build up in the first place? Are they a space leak in certain
> > unfortunate code?

> Maybe Matthias B. could describe that.

I already did.

> > The other thing I find strange about tuples is that tuple constructors
> > must be "special" procedures since they take more than one argument in
> > a one argument only world.

> Every procedure call would implicitly construct a tuple, wouldn't it?  An
> explicit tuple constructor would only be needed in certain situations.

Exactly.  In fact, you can define your explicit tuple constructor
(assuming my proposal) as, the rest of the machinery is in how LAMBDA
and function application works:

   (define (tuple l) l)

Now, is that neat, or what? :-)

Matthias


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Matthias Blume  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 15:44
Newsgroups: comp.lang.scheme
From: Matthias Blume <matth...@shimizu-blume.com>
Date: 12 Aug 2003 09:44:06 -0500
Local: Tues 12 Aug 2003 15:44
Subject: Re: Alternatives to values/call-with-values

Matthias Blume <matth...@shimizu-blume.com> writes:
> Exactly.  In fact, you can define your explicit tuple constructor
> (assuming my proposal) as, the rest of the machinery is in how LAMBDA
> and function application works:

Oops, this sentence got garbled.  Read as:

"In fact, you can define your explicit tuple constructor
(assuming my proposal) as:

    (define (tuple l) l)

(The rest of the machinery is in how LAMBDA and function application works.)"

Matthias


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Michael Sperber  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 15:47
Newsgroups: comp.lang.scheme
From: Michael Sperber <sper...@informatik.uni-tuebingen.de>
Date: Tue, 12 Aug 2003 16:47:05 +0200
Local: Tues 12 Aug 2003 15:47
Subject: Re: Alternatives to values/call-with-values

>>>>> "Matthias" == Matthias Blume <matth...@shimizu-blume.com> writes:

Matthias> Michael Sperber <sper...@informatik.uni-tuebingen.de> writes:

>> >>>>> "bear" == Ray Dillinger <b...@sonic.net> writes:

bear> But the ability to pass arbitrary multiple results directly in
bear> as parameters to another function would make scheme into a better
bear> DD language than any now extant.  

>> Huh?  That's *exacty* what CALL-WITH-VALUES does.  Could you clarify
>> what you mean?

Matthias> "directly" as opposed to "via CALL-WITH-VALUES"

Matthias> (Just a guess.)

Probably right, though.

I don't see a totally baby-bottom-smooth way to paper over the
distinction between procedures and continuations, I guess.  Scheme
uses CALL-WITH-VALUES to paper over the gap, ML uses tuples.  Both are
cool in some contexts, awkward in others.

--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
bear  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 16:20
Newsgroups: comp.lang.scheme
From: b...@sonic.net
Date: Tue, 12 Aug 2003 15:17:36 GMT
Local: Tues 12 Aug 2003 16:17
Subject: Re: Alternatives to values/call-with-values

Yeah.  Or more to the point being able to say

(f (e (j (i param1 param2 param3 .... param20))))

to compose a bunch of procedures that each take 20 arguments
and return 20 results.

                        Bear


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Anthony Carrico  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 20:06
Newsgroups: comp.lang.scheme
From: Anthony Carrico <acarr...@memebeam.org>
Date: Tue, 12 Aug 2003 19:03:28 GMT
Local: Tues 12 Aug 2003 20:03
Subject: Re: Alternatives to values/call-with-values

Michael Sperber <sper...@informatik.uni-tuebingen.de> wrote:
> I don't see a totally baby-bottom-smooth way to paper over the
> distinction between procedures and continuations, I guess.  Scheme
> uses CALL-WITH-VALUES to paper over the gap, ML uses tuples.  Both are
> cool in some contexts, awkward in others.

Amen brother! The only baby-bottom-smooth resolution is to prevent
functions from returning at all. Too bad it's such a pain in the
baby's bottom.

Second class parameter/values are a control construct; that's
Scheme. Ignoring parameters/values and just passing/returning a single
first class vectors/list/sequence/tuple and calling its elements your
"parameters/results" is also an option inside of Scheme.

If you ditch the second class parameters/values, you no longer have
Scheme. In that case, the lambda-the-ultimate goto-with-parameters
mental model is gone. Let's just call it "MLisp" and see if it can
prove itself on its own merits (rather than just downplaying the
merits of the Scheme model).

I'll certainly admit that the Scheme rest parameter is an artifact of
some by-gone interpreter's implementation, so allow the Scheme rest
parameter to be bound to something opaque which can be implemented as
a list of arguments, set of registers, a tuple, etc. Now, with some
functions and macros, it ought to be possible define a Scheme in
native MLisp, and a Mlisp in native Scheme. Then we get some
answers.

I'd welcome the chance to learn about ML concepts with a lisp syntax
and syntax-case macros, I just wouldn't call it a logical extension of
what I understand Scheme to be.

--
Anthony Carrico


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Matthias Blume  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 21:57
Newsgroups: comp.lang.scheme
From: Matthias Blume <matth...@shimizu-blume.com>
Date: 12 Aug 2003 15:57:30 -0500
Local: Tues 12 Aug 2003 21:57
Subject: Re: Alternatives to values/call-with-values

Anthony Carrico <acarr...@memebeam.org> writes:
> If you ditch the second class parameters/values, you no longer have
> Scheme.

I don't see why that would be so.  In fact, most (all?) Scheme
programs would still run, so what's the problem?

> In that case, the lambda-the-ultimate goto-with-parameters
> mental model is gone.

Again, I don't understand this statement at all.  What does one have
to do with the other?

> Let's just call it "MLisp" and see if it can
> prove itself on its own merits (rather than just downplaying the
> merits of the Scheme model).

Remind me: what are those merits of the "Scheme model" (whatever
*that* is), and how do they rely on the second-class-ness of
parameters and values?

I always thought that if there is a "Scheme model", then it is all
about making as many things as possible first-class.  (Not that that's
necessarily a good thing.  In many cases I'd argue that it is not.
Parameters and values, though, aren't one of these cases.)

Matthias


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Tom Lord  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 22:00
Newsgroups: comp.lang.scheme
From: l...@emf.emf.net (Tom Lord)
Date: Tue, 12 Aug 2003 21:00:27 -0000
Local: Tues 12 Aug 2003 22:00
Subject: Re: Alternatives to values/call-with-values

I'm with Anthony Carrico, and then some:

        Anthony:

        Second class parameter/values are a control construct; that's
        Scheme. [....]

        If you ditch the second class parameters/values, you no longer
        have Scheme. In that case, the lambda-the-ultimate
        goto-with-parameters mental model is gone. Let's just call it
        "MLisp" and see if it can prove itself on its own merits
        (rather than just downplaying the merits of the Scheme model).

I'm not so sure about this tuple stuff fitting in with "the spirit of
Scheme" -- or even making much sense.

I'm looking at this form of proposal:

http://groups.google.com/groups?q=g:thl776716467d&selm=fo1ydnbnx8.fsf...

I've divided this possibly too long post into three parts:

* questions unanswered in the proposal
* some surprising behaviors implied by the proposal
* the spirit of scheme and its implications here

* questions unanswered in the proposal

Matthias wrote the proposal in a very informal style which makes it
hard to tell precisely what it says.  Informally, I get the gist, but
when I try to imagine how the details should be filled in, I don't
quite see it.

One example: the propsal tells us that

        (lambda (x1 ... xN) <body>)

is syntactic sugar for:

        (lambda (arg)
           (let ((x1 (project arg 1))
                 ...
                 (xN (project arg N)))

              <body>))

where `(project arg <N>)' is a "form expressing projection for tuples".

I've long regarded `let' as syntactic sugar for lambda.   That is,
in the manner of rabbit or R5RS (7.3), one can define:

        (let ((<name1> <exp1>)
               ...
              (<nameN> <expN>))
          <body1>
          <body2> ...)

to be syntactic sugar for:

  ((lambda (<name1> ... <nameN>) <body1> <body2>...) <exp1> ... <expN>)

and so I don't see how Matthias' definition isn't circular.  Is part
of the proposal here that `let' is no longer what R5RS calles a
"Derived expresion type"?   Does this proposal entail an extensive
rewrite of the definition?   Can we see that report?

People in this thread have been asking questions which I'll paraphrase
as "Why not do this?  What's the impact?"   I think that to really
answer those questions, minimally, one ought to produce the proposed
changes for R6RS in detail;  ideally, work out its implications
for various compilation and interpretation strategies.    

* some surprising behaviors implied by the proposal

The proposal tells us that:

        (f 1 2 3)

is just syntax for:

        (f (tuple 1 2 3))

and also that tuples are to be "good old-fashioned first-class values
like everything else in Scheme".

Taking these proposals at their word, and putting them together, we
get some suprises, like:

        (length (list (tuple 1 2 3))) => 3

and so, for example, unlike R5RS, it is no longer certain that (absent
errors):

        (let ((x <any value>))
          (eq? 1 (length (list x))))
        => 1

I suppose that one could _partly_ "rescue" the tuple propsal by
asserting that:

        (let ((x (tuple 1 2 3)))
          <body>)

is an error and that only a multi-binding construct such as:

        (let ((x y z (tuple 1 2 3)))
          <body>)

is permissable, but then in what sense is it that tuples are
"first class values" again?

* the spirit of scheme and its implications here

I don't think there's any real definition of the "spirit of scheme"
but I do think it's a topic that can be discussed meaningfully.

I look for evidence of "the spirit of Scheme" in a few places: the
rabbit thesis, the "Lambda: The Ultimate..." papers, the RnRS series,
my own experience as implementor and user, the experience of other
implementors and users.  I also like to look at some of the influences
floating around in the early days of Scheme, such as work of
Christopher Strachey, et al.

I seem to recall seeing many spirit-oriented discussions on this list
focus intensely on just one sentence which can be found in R5RS, the
first sentence of the introduction:

      Programming languages should be designed not by piling feature
      on top of feature, but by removing the weaknesses and
      restrictions that make additional features appear necessary.

That's an important sentence, but I like the next one too (emphasis
added):

        Scheme demonstrates that a very small number of rules for
        forming expressions, with no restrictions on how they are
        composed, suffice to form a _practical_ and efficient
        programming language that is flexible enough to support most
        of the major programming paradigms in use today.

And these two from the summary:

        It was designed to have an exceptionally _clear_and_simple_
        semantics and few different ways to form expressions. A _wide_
        variety_of_programming_paradigms_, including _imperative_,
        functional, and _message_passing_styles_, _find_convenient_
        expression_ in Scheme.

So the first observation I want to make is that the tuples proposal,
at least arguably, removes a clear and simple semantics for lambda
and procedure application and replaces them with a somewhat opaque
and complicated semantics.   It's not at all obvious to me that
tuples really make the math of the semantics any easier -- it is clear
to me that tuples and single-argument-lambda introduce a serious
indirection between procedures and procedure application, and that
other important view: that procedure application corresponds to a
machine-language "goto while passing parameters".

And the second observation I want to make is that it is not obviously
in keeping with the spirit of scheme to try to turn it into a
particular lambda calculus of interest to ML fans.  You'd want to at
least demonstrate, say, a really simple yet kick-ass compiler and
interpreter grounded in that approach first.  (I'm using "not
obviously" advisedly -- I'd also say "not obviously not".  I'm just
trying to say that saying "call-with-values doesn't _feel_ right to
me; tuples feel better" isn't enough.  It was the suprising
harmonization of theory with practice that caused Scheme to resonate
so loudly when it appeared.)

I'll dig a little deeper into two points in particular.  First, the
"goto with parameters" view; second, the question "what is the
scheme-spirit take on functional languages".

** goto with parameters

I thought that part of the "spirit of scheme" is that one
interpretation of function application is that is a "goto with
parameters".

Another part of the "spirit of scheme" is that "returning a value"
is an example of function application.

A third part of the "spririt of scheme" is to avoid unecessary
restrictions on how expressions may be composed.

Putting those three parts of the "spirit of Scheme" together, it is
clear that R4RS was missing some generality.  It contained the
arbitrary restriction that one could pass multiple parameters in most
function applications, but not in the function applications implied by
"returning".  All continuations took precisely one parameter.

The "goto with parameters" idea makes sense at several levels.
Operationally, it's a vague but useful way to characterize some
important properties the kinds of computers we know how to build best
-- so when we're programming in those terms we are, in some sense,
programming "close to the hardware".  Pragmatically, the goto idea
leads to very simple compilation and interpretation strategies --
strategies very clearly related to the surface language.
Mathematically, the goto idea is expressible in a minimally augmented
example of an applicative-order lambda calculus.  The goto idea, along
with first-class continuations, very concisely provides, explains, and
generalizes all important control flow constructs found in similar
languages.  Those four levels can all be grasped comparatively easily
by intuition.  Physics, the practice of programming, math, and
explicative power all converging and harmonizing over a very intuitive
abstract structure --- with five-part harmonies like that, do you
really wonder why I sometimes say "space aliens program in scheme"?

The tuples idea doesn't exactly abandon the idea of the "goto with
parameters" idea -- but it does throw in some new layers of
indirection there.   Intuition is told, "don't worry, this all gets
put back together in a reasonable way by the compiler".   I think
something is lost in this proposal.

One way to view the idea of "first class tuples" is that it is the
idea of reifying the parameter passing conventions as values which
represent the intention to pass a particular set of parameters.

One way to view the idea of "call-with-values" and "values" is that it
is based on exactly the opposite idea: of avoiding creating values
which represent the intention to pass a particular set of parameters.

Paradoxes like the `length' examples shown above illustrate that there
is a distinction to be made between applying a procedure to a single
first-class value which can be interpreted as a reified "intention to
pass a particular list of parameters" and a procedure application to
that list of parameters.   Scheme already has a mechanism for making
that distinction: `apply'.

** the scheme-spirit take on functinoal languages

The interesting, foundational work on implementing functional
languages bears a lot of resemblence to the rabbit thesis.   A
compiler for a tiny core language is exhibited, and then many
high-level concepts are expressed as transformations into that
language.

The static-typing work done by functional language researchers clearly
does not apply to Scheme as a whole.  Certainly it could be
reinterpreted as a compilation/linting strategy for a subset of Scheme
programs.  (R5RS 1.1: "Scheme has latent as opposed to manifest
types."  and R5RS Summary: "Scheme is [...] a dialect of the Lisp
program language [....]")

Where I think Scheme research _might_ pay off with language
changes/extensions is from consideration of implementations of the
normal-order lambda calculus.  Does graph
...

read more »


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Anton van Straaten  
View profile   Translate to Translated (View Original)
 More options 12 Aug 2003, 23:30
Newsgroups: comp.lang.scheme
From: "Anton van Straaten" <an...@appsolutions.com>
Date: Tue, 12 Aug 2003 22:27:54 GMT
Local: Tues 12 Aug 2003 23:27
Subject: Re: Alternatives to values/call-with-values

Anthony Carrico wrote:
> Second class parameter/values are a control construct; that's
> Scheme.

Although, until R5RS, there was no issue about multiple values because they
didn't exist.  Then multiple values were added, and as a result, that part
of Scheme became something that's not considered completely Scheme by some
people - a view I have some sympathy with.

> If you ditch the second class parameters/values, you no longer have
> Scheme.

I'm sure we all have different ideas about what makes Scheme Scheme.  That
one hasn't ever occurred to me, except as a sort of restriction - minor in
the case of parameters, but rearing its head more with multiple value
return.  "Ditching" second class parameters/values makes it sound as though
something is lost - but what?  I listed a number of things I saw as lost
with multiple values, including the very Scheme-like ability to reliably
store the results of any function in a variable.

> In that case, the lambda-the-ultimate goto-with-parameters
> mental model is gone.

How so?  Can you give an example of a description of some operation, from
the "lambda-the-ultimate goto-with-parameters" model perspective, which is
somehow unreasonable or broken with first-class sequences?

If we want to relate this discussion to lambda-the-ultimate-ness, one
problem is that real lambdas only take one parameter (that should be read in
the same way as "real men don't eat quiche".)  So where do we look for
models of how to handle lambdas with multiple parameters?  I don't know, and
would appreciate any pointers.  Scheme provides one model, but as I've
argued, to me its multiple values handling seems out of place.  ML provides
another model, which *in ML* I certainly like, and don't have that out of
place feeling about.  I'm less familiar with Haskell, but its model seems
quite similar to ML's - in particular, (4) == 4, and f (x,y) passes a single
tuple (x,y) to the function f.

Given this, the idea that we're talking about the ML'izing of Scheme here
seems invalid.  We may be talking about bringing Scheme more in line with
other lambda-based functional languages with pattern-matched argument
binding, though.

> Let's just call it "MLisp" and see if it can
> prove itself on its own merits (rather than just downplaying the
> merits of the Scheme model).

I see the proposal as essentially a kind of extension, although one that
removes the need for some existing core constructs.  In a Scheme with
sequences, you'll be able to use (f (g)) where g returns multiple values,
instead of (call-with-values g f).  The former seems much more like "the
Scheme model" to me.  call-with-values can be implemented in terms of that,
but not vice versa.

So, I'm not understanding the big problem here, and I don't see which merits
of the Scheme model are being downplayed.  I'm willing to try to understand,
given or pointed to an explanation.

> I'll certainly admit that the Scheme rest parameter is an artifact of
> some by-gone interpreter's implementation, so allow the Scheme rest
> parameter to be bound to something opaque which can be implemented as
> a list of arguments, set of registers, a tuple, etc. Now, with some
> functions and macros, it ought to be possible define a Scheme in
> native MLisp, and a Mlisp in native Scheme. Then we get some
> answers.

Something that addressed the concerns of both sides would obviously be
ideal.  RnRS seems capable of straddling almost any line, what's one more?
;)

> I'd welcome the chance to learn about ML concepts with a lisp syntax
> and syntax-case macros, I just wouldn't call it a logical extension of
> what I understand Scheme to be.

I certainly don't see the proposal as a way to migrate Scheme towards ML.  I
wouldn't be in favor of that.  I like ML for some kinds of applications, but
I value the flexibility that Scheme provides.  I'm just not seeing how this
proposal takes anything away from that flexibility.

Instead of "MLisp", may I suggest "2Scheme", as a contraction of
TupleScheme.  This also has parallels with Lisp1 & Lisp2, which may be the
kind of split we're beginning to create here...  :^}

Anton


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Anthony Carrico  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 03:11
Newsgroups: comp.lang.scheme
From: Anthony Carrico <acarr...@memebeam.org>
Date: Wed, 13 Aug 2003 02:08:43 GMT
Local: Wed 13 Aug 2003 03:08
Subject: Re: Alternatives to values/call-with-values
Wow! All I can say is thank you Tom Lord for doing such a great job of
expressing my concern. Most of the questions Matthias Blume and Anton
van Straaten asked back to me are best answered in your post.

I think Tom did a great job of expressing how (people like me)
understand the Scheme model in terms of goto with parameters, and how
(for people like me) the "tuple" model seems one step removed from the
machine. If I may argue-by-irony, in "Compiling with Continuations",
Andrew Appel takes the output from ML front end and maps it to
Scheme's goto with parameters model. A lot of the optimizations he
describes involve cleaning up all those tuple accesses!

Anton van Straaten <an...@appsolutions.com> wrote:

> Although, until R5RS, there was no issue about multiple values because they
> didn't exist.  Then multiple values were added, and as a result, that part
> of Scheme became something that's not considered completely Scheme by some
> people - a view I have some sympathy with.

I feel just opposite way. Until R5RS, it felt like there was a hole in
Scheme because you you couldn't inject a continuation with an
arbitrary signature. R5RS didn't add something new to the picture, it
filled that curious hole in the existing mechanics. In fact, it made
the kind of function composition that you desire possible.

> How so?  Can you give an example of a description of some operation, from
> the "lambda-the-ultimate goto-with-parameters" model perspective, which is
> somehow unreasonable or broken with first-class sequences?

> If we want to relate this discussion to lambda-the-ultimate-ness, one
> problem is that real lambdas only take one parameter (that should be read in
> the same way as "real men don't eat quiche".)  So where do we look for
> models of how to handle lambdas with multiple parameters?  I don't know, and
> would appreciate any pointers.

Ah. I apologize, as you say we are coming from very different points
of view. I am not talking about those "real lambdas". Not at
all. Those lambdas have little to do with what I'm talking about, it's
a different mechanism, they just happen to have the same alias by some
accident of history. I'm talking about the Steele/Sussman
ultimate-lambdas. See "The Original 'Lambda Papers' by Guy Steele and
Gerald Sussman" at http://library.readscheme.org/page1.html. Sorry for
the confusion.

> In a Scheme with sequences, you'll be able to use (f (g)) where g
> returns multiple values, instead of (call-with-values g f).  The
> former seems much more like "the Scheme model" to me.
> call-with-values can be implemented in terms of that, but not vice
> versa.

> So, I'm not understanding the big problem here, and I don't see which merits
> of the Scheme model are being downplayed.  I'm willing to try to understand,
> given or pointed to an explanation.

Ok, the big problem is that, in my world, "(f (g)) where g returns
multiple values" is an error, not a virtue! This is what I was trying
to point out when I said that maybe this whole discussion fell off the
Scheme wagon back at "compose". On the other hand, if in some
circumstance I do want f to take all of g's values as parameters, I
have an easy way to do it: make f into the continuation of g. How do I
do that? The call-with-values procedure.

There is a big huge difference between "(g) initializing the first
argument of f" and "f being the continuation of (g)". The proponents
of this idea conflate the two situations, "what's the big deal?, its
the same thing!". In my world, it's not the same thing, it's very
different!

In your world, the operator is indeed the continuation of the first
and only argument. It sort of makes every call into a
call-with-values.

I understand that you all aren't in my world, and there is probably
some value in your world, but I hope you can understand that it
sometimes seems like you guys are trying to sweep some very
fundamental issues under the rug. Again, read Tom's post (well, except
the final paragraph :). I'm sure it is more coherent than mine.

--
Anthony Carrico


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
oleg@pobox.com  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 03:49
Newsgroups: comp.lang.scheme
From: o...@pobox.com (o...@pobox.com)
Date: 12 Aug 2003 19:49:15 -0700
Local: Wed 13 Aug 2003 03:49
Subject: Re: Alternatives to values/call-with-values
The Glasgow Haskell Compiler GHC has something _very_ like Scheme multiple
values: unboxed tuples. Unsurprisingly, they are second class. Here's
an excerpt from GHC documentation:

<blockquote>
7.2.2. Unboxed Tuples

Unboxed tuples aren't really exported by GHC.Exts, they're available by default
with -fglasgow-exts. An unboxed tuple looks like this:

(# e_1, ..., e_n #)                                                      

Unboxed tuples are used for functions that need to return multiple values, but
they avoid the heap allocation normally associated with using fully-fledged
tuples. When an unboxed tuple is returned, the components are put directly into
registers or on the stack; the unboxed tuple itself does not have a composite
representation. Many of the primitive operations listed in this section return
unboxed tuples.

 - Unboxed tuples may only be constructed as the direct result of a function,
    and may only be deconstructed with a case expression. eg. the following are
    valid:

    f x y = (# x+1, y-1 #)
    g x = case f x x of { (# a, b #) -> a + b }                        

    but the following are invalid:

    f x y = g (# x, y #)
    g (# x, y #) = x + y

The IO and ST monads use unboxed tuples to avoid unnecessary allocation during
sequences of operations.

</blockquote>

I would not be surprised if Simon Peyton-Jones got that idea from
Scheme.

I must say that I use multiple values and multiple-valued functions a
great deal. OTH, I hardly ever mention call-with-values, directly.
Multiple-valued functions _greatly_ help in writing purely functional
code that involves the threading of a state:

(define (open:input-buffer-layer schema url-rest properties)
  (let*-values
    (((properties parent-duct)
       (find-prop-in-open-properties properties
         'parent-duct #f))
     ((properties buffer buffer-length curr-pos end-pos)
       (let*-values
         (((properties buffer-size)
           (find-prop-in-open-properties properties 'buffer-size #f)))
         (if buffer-size
           (if (not (and (integer? buffer-size) (>= buffer-size 0)))
             (open-error error:bad-args "buffer-size: bad type or range"
               buffer-size)
             (values properties
               (gvector-make-like parent-unit buffer-size) buffer-size 0 0))
           (let*-values
             (((properties buffer read-pos available-read)
               (find-prop-in-open-properties properties
                 'buffer #f 'read-pos #f 'available-read #f))
        ...
        ))))))))

    (or (null? properties)
      (open-error error:excessive-open-properties
        "for input-buffer:" properties))

As you can see, 'properties' is the list of properties that gets
threaded through. Functions like find-prop-in-open-properties search
the list for some keys, return the found values (or the default
values), and the remainder of the list. At the end, the code checks
that all properties given by the user have been taken care of.
The code is purely functional and referentially transparent. This
code should be familiar to some people on this newsgroup. And yes, it
can run on Gambit.

I also found it quite convenient to write

        (let*-values (((v1 v2 v3) (apply values lst))
                      ((x) (+ v1 v2)))
                ...)

For one thing, the code looks like pattern-matching on the list. For
another, the above expression frees me from explicitly checking that
the list lst indeed has exactly three elements. I get deconstruction,
binding, and error checking in one line. Here's a similar example from
the real code:

      (let*-values
        (((prev-bbox areas . products) (apply values seed))
         ((nlat wlon slat elon) (apply values (string-split prev-bbox))))


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Michael Sperber  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 16:05
Newsgroups: comp.lang.scheme
From: Michael Sperber <sper...@informatik.uni-tuebingen.de>
Date: Wed, 13 Aug 2003 17:05:09 +0200
Local: Wed 13 Aug 2003 16:05
Subject: Re: Alternatives to values/call-with-values

>>>>> "Matthias" == Matthias Blume <matth...@shimizu-blume.com> writes:

Matthias> Remind me: what are those merits of the "Scheme model" (whatever
Matthias> *that* is), and how do they rely on the second-class-ness of
Matthias> parameters and values?

The merits are that there is a symmetry between parameters and return
values.

If you're asking for "merits over the ML model"---here are some of my
gripes with it:

- There are two ways of doing multi-parameter functions---via currying
  or tuples, with no clear indication of which one is superior.  (I
  haven't seen a clear discipline written up when to use one or the
  other.)  With currying, "parameter lists" aren't first-class,
  either.

- Zero-parameter functions are not really a problem in practice, but
  they break my notion of baby-bottom-smoothness.

- I'd say implementing tuples without excessive allocation through
  boxing is more difficult than implementing the Scheme model.  (In
  fact, I remember ML implementations that didn't bother in the first
  place.  The result was worse than Emacs.)

--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Matthias Blume  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 16:38
Newsgroups: comp.lang.scheme
From: Matthias Blume <matth...@shimizu-blume.com>
Date: 13 Aug 2003 10:38:20 -0500
Local: Wed 13 Aug 2003 16:38
Subject: Re: Alternatives to values/call-with-values

I am no longer able (nor eager) to invest too much of my time and my
emotional energy in arguing these things, so I will (try to) limit
myself to this one last article on the topic.

At the time it was written, my proposal was not meant as a serious
suggestion for changing the definition of Scheme.  It merely served to
show that there are ways of getting the benefits of multiple return
values without the ballast of having to deal with contortions such as
call-with-values.

Having said this, I will answer your three areas of concern in order.
I'll keep it as brief as I can.

1. It is, obviously, true that one cannot explain the semantics of
   LAMBDA with those of LET if at the same time one is to explain LET
   in terms of LAMBDA.

   My attempt at explaining my new LAMBDA semantics using LET were not
   meant to be formal in any sense. (Why do people always take usenet
   articles and treat them as if they were POPL submissions?  They are
   not.)

   Anyway, I also explained the semantics of my new LAMBDA quite
   clearly without using LET, I think.  Here is a brief summary:

   - all functions (including continuations) take precisely one argument
   - there is a distiguished value, call it "[]", which should be
     though of as an "empty tuple"
   - given two or more values v_1,...,v_k (k >=2), there is a "k-tuple value"
     containing these values (call it "[v_1 ... v_k]")
   - LAMBDA forms:
       * (LAMBDA () ...) evaluates to a procedure whose argument must be
         the empty tuple [].  Passing any other argument is considered a
         runtime error.
       * (LAMBDA (x) ...) evaluates to a procedure whose single argument
         will be bound to the formal parameter x for the purpose of
         evaluating the body.
       * (LAMBDA (x_1 ... x_k) ...) evaluates to a procedure whose single
         argument must be a k-tuple [v_1 ... v_k].  For the purpose
         of evaluating the body, each v_i will be bound to the corresponding
         x_i.
       * (LAMBDA x ...) evaluates to a procedure which inspects its single
         argument.  If the argument is the empty tuple [], then x will
         be bound to the empty list; if the argument v is not a tuple, then
         x will be bound to the freshly allocated singleton list (v);
         if the argument is a k-tuple [v_1 ... v_k], then x will be bound
         to a freshly allocated list (v_1 ... v_k).
   - Application forms:
       * (f) calls the procedure that f evaluates to and passes []
         is the single argument.
       * (f arg) calls the procedure that f evaluates to and passes
         the result of evaluating arg as its single argument.
       * (f arg_1 ... arg_k) with k >= 2 calls the procedure that f
         evaluates to and passes the tuple [v_1 ... v_k] as its single
         argument where each v_i is obtained by evaluating the
         corresponding arg_i.

    A suitable modification of the denotational semantics given in
    RnRS is easy (or so I believe).  I leave it as an exercise to the
    interested reader. :-)

    Remarks:

    * I claim that under the above rules, all Scheme programs that
    currently do not exhibit runtime errors will continue to run and
    behave as they did before.  This should be fairly straightforward
    to prove by a simple case analysis, matching applications with
    corresponding lambdas.

    * One can quibble about the equality properties of tuples.  I
      leave this open here.  If we allow EQ? on tuples, then one
      obvious axiom should be:

        If t is a tuple [v_1 ... v_k] and (EQ? t u) ==> #t, then
        u is a tuple [w_1 ... w_k] and \forall i . (EQ? v_i w_i) ==> #t.

      I would not want to place many (if any) more restrictions than
      that on implementations (see next paragraph).

    * In my original article I also sketched out an implementation
      strategy which could succinctly be described as "lazy tupling".
      In all Scheme programs that are currently legal there would never
      be any tuple that gets physically constructed, so there is no inherent
      cost in using first-class tuples.  (Current implementations already
      have to check for arity mismatches, and tupling can quite easily be
      piggy-backed on  these arity tests.  One can optimize common cases
      by having multiple entry points for each function: one for the
      1-argument case, one for the 0-or-k-argument case.)

    * The R5RS procedure VALUES can be defined as the identity function.
      (This is the same as an explicit tuple constructor.)

    * The R5RS procedure CALL-WITH-VALUES can be defined as

         (define call-with-values (LAMBDA (p c) (c (p ()))))

    * Projections from tuples can be defined as

         (define project_i (LAMBDA (x_1 ... x_{i-1} x_i . rest) x_i))

2. Variable-arity procedures (such as LIST):

Tom has a point here: It may come as a surprise to some that it is no
longer true that regardless of what the value of x we have

  (length (list x)) ==> 1

In fact, if LIST is defined as

  (define LIST (lambda l l))

then it acts as a converter from tuples to lists.  This might even be
more useful than trying to preserve the "expected" behavior above.

In any case, I personally do not see variable-arity functions as
more than gratuituous cuteness.  They are never really necessary.  In
my code, when I use LIST I really want to use records (preferably with
named fields).  Modern dialects of Scheme offer those.  When lists are
used they way they were meant to be used (i.e., as an inductive data
structure), LIST is seldom useful as a function.  Most of the other
built-in variable argument functions (+, *, ...) are even less useful,
in my view.  In my code I rarely use them with anything else than
exactly two arguments.  Having the obvious fold built into the
operator is what I consider "cute" but not terribly helpful.

The bottom line is that I can envision a Scheme which does not rely so
heavily on variable argument lists, so if there is any problem with
those in relation to tuples, it might be a non-issue.

(The syntactic convenience provided by variable-arity functions could
easily be recovered by macros.  Procedure values, however, do not need
to be able to accept a variable number of arguments.  In cases where
one really wants to pass a statically unknown number of values to a
function, one can do that already by explicitly passing a list of
these values.)

3. The "spirit of Scheme".  I will keep this very short since it is
   mostly mumbo-jumbo anyway.

   I have no idea what this lambda-as-goto has to do with tuples.  The
   two things are completely separate issues.  The existence of
   variable-argument lists in RnRS is proof enough that if there is
   any such problem at all, it already exists in present Scheme.

   In any case, this thread is testimony to the fact that different
   people have quite different ideas of what the "sprit of Scheme" is.
   Moreover, they seem to be able to arrive at opposite ends of the
   design spectrum by following their intuition about this "spirit".
   This, if nothing else, shows that "spirit of Scheme" is a
   wishy-washy concept at best.

Matthias


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Matthias Blume  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 16:46
Newsgroups: comp.lang.scheme
From: Matthias Blume <matth...@shimizu-blume.com>
Date: 13 Aug 2003 10:46:15 -0500
Local: Wed 13 Aug 2003 16:46
Subject: Re: Alternatives to values/call-with-values

Michael Sperber <sper...@informatik.uni-tuebingen.de> writes:
> >>>>> "Matthias" == Matthias Blume <matth...@shimizu-blume.com> writes:

> Matthias> Remind me: what are those merits of the "Scheme model" (whatever
> Matthias> *that* is), and how do they rely on the second-class-ness of
> Matthias> parameters and values?

> The merits are that there is a symmetry between parameters and return
> values.

But there isn't, and that's the exact problem.

> If you're asking for "merits over the ML model"---here are some of my
> gripes with it:

> - There are two ways of doing multi-parameter functions---via currying
>   or tuples, with no clear indication of which one is superior.  (I
>   haven't seen a clear discipline written up when to use one or the
>   other.)  With currying, "parameter lists" aren't first-class,
>   either.

The same is true for Scheme (although its awkward syntax will most
likely discourage most programmers from using curried functions).

> - Zero-parameter functions are not really a problem in practice, but
>   they break my notion of baby-bottom-smoothness.

Sorry, but I have no idea of what your "notion of
baby-bottom-smoothness" is.  (Nor do I want to find out. :-)

> - I'd say implementing tuples without excessive allocation through
>   boxing is more difficult than implementing the Scheme model.

No, it is not.  See my other articles on this topic.  In fact, it is
fairly easy to implement the tuple model in such a way that *no*
tuples get constructed for currently legal Scheme programs.  (In other
words, tuples would only get constructed in programs that take
advantage of the new semantics.)

>  (In fact, I remember ML implementations that didn't bother in the first
>   place.  The result was worse than Emacs.)

That may very well be so.  But what does this have to do with the
current debate?  Just because someone somewhere sometime in some
completely different context did a bad job at implementing a feature
does not meant that the feature is bad.

Matthias


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Michael Sperber  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 17:58
Newsgroups: comp.lang.scheme
From: Michael Sperber <sper...@informatik.uni-tuebingen.de>
Date: Wed, 13 Aug 2003 18:58:38 +0200
Local: Wed 13 Aug 2003 17:58
Subject: Re: Alternatives to values/call-with-values

>>>>> "Matthias" == Matthias Blume <matth...@shimizu-blume.com> writes:
>> If you're asking for "merits over the ML model"---here are some of my
>> gripes with it:

>> - There are two ways of doing multi-parameter functions---via currying
>>   or tuples, with no clear indication of which one is superior.  (I
>>   haven't seen a clear discipline written up when to use one or the
>>   other.)  With currying, "parameter lists" aren't first-class,
>>   either.

Matthias> The same is true for Scheme (although its awkward syntax will most
Matthias> likely discourage most programmers from using curried functions).

You're not getting my point: the syntactic overhead in Scheme of
currying over multiple parameters implies a clear discipline.  In ML,
the notational costs are very similar (slightly lower for currying),
which muddies the water and forces people to put protocol conversions
in their program where the essence of what they're doing doesn't imply
them.

>> - I'd say implementing tuples without excessive allocation through
>>   boxing is more difficult than implementing the Scheme model.

Matthias> No, it is not.  See my other articles on this topic.  In fact, it is
Matthias> fairly easy to implement the tuple model in such a way that *no*
Matthias> tuples get constructed for currently legal Scheme programs.

I guess we differ on assessing the relative costs of implementing
these things.

>>  (In fact, I remember ML implementations that didn't bother in the first
>>   place.  The result was worse than Emacs.)

Matthias> That may very well be so.  But what does this have to do with the
Matthias> current debate?

Not much, but at least that somebody else didn't find it as quite as
easy as you do.

Matthias> Just because someone somewhere sometime in some completely
Matthias> different context did a bad job at implementing a feature
Matthias> does not meant that the feature is bad.

I never attributed "badness" to any feature that's part of the
discussion---neither in words nor in intentions.

Note that I also never said I like the "Scheme model" significantly
better than the "ML model."  I like both about the same.  (I *do*
dislike the R4RS model.)  I sure don't see a clear advantage in the ML
model, though.

--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Rush  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 18:18
Newsgroups: comp.lang.scheme
From: David Rush <dr...@aol.net>
Date: Wed, 13 Aug 2003 17:17:40 +0000 (UTC)
Local: Wed 13 Aug 2003 18:17
Subject: Re: Alternatives to values/call-with-values

Michael Sperber <sper...@informatik.uni-tuebingen.de> writes:
> Note that I also never said I like the "Scheme model" significantly
> better than the "ML model."  I like both about the same.  (I *do*
> dislike the R4RS model.)  I sure don't see a clear advantage in the ML
> model, though.

Well, IMNSHO, R5RS is the worst of the solutions. I think I like
Blume/Clinger better than R4RS though.

david rush
--
He who would make his own liberty secure, must guard even his enemy
from repression
        -- Thomas Paine


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Rush  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 18:24
Newsgroups: comp.lang.scheme
From: David Rush <dr...@aol.net>
Date: Wed, 13 Aug 2003 17:24:35 +0000 (UTC)
Local: Wed 13 Aug 2003 18:24
Subject: Re: Alternatives to values/call-with-values

Anthony Carrico <acarr...@memebeam.org> writes:
> Ok, the big problem is that, in my world, "(f (g)) where g returns
> multiple values" is an error, not a virtue! This is what I was trying
> to point out when I said that maybe this whole discussion fell off the
> Scheme wagon back at "compose". On the other hand, if in some
> circumstance I do want f to take all of g's values as parameters, I
> have an easy way to do it: make f into the continuation of g.

I'm sorry but you have just restated the definition of
composition. In (f (g)), f *is* the continnuation of (g). Just what is
it that you consider an error?

> How do I do that? The call-with-values procedure.

Which is arguably a much clunkier syntax than the natural expression
of composition.

david rush
--
He who would make his own liberty secure, must guard even his enemy
from repression
        -- Thomas Paine


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
David Rush  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 18:36
Newsgroups: comp.lang.scheme
From: David Rush <dr...@aol.net>
Date: Wed, 13 Aug 2003 17:36:33 +0000 (UTC)
Local: Wed 13 Aug 2003 18:36
Subject: Re: Alternatives to values/call-with-values

Anthony Carrico <acarr...@memebeam.org> writes:
> Ok, the big problem is that, in my world, "(f (g)) where g returns
> multiple values" is an error, not a virtue! This is what I was trying
> to point out when I said that maybe this whole discussion fell off the
> Scheme wagon back at "compose". On the other hand, if in some
> circumstance I do want f to take all of g's values as parameters, I
> have an easy way to do it: make f into the continuation of g.

I'm sorry but you have just restated the definition of
composition. In (f (g)), f *is* the continnuation of (g). Just what is
it that you consider an error?

> How do I do that? The call-with-values procedure.

Which is arguably a much clunkier syntax than the natural expression
of composition.

> There is a big huge difference between "(g) initializing the first
> argument of f" and "f being the continuation of (g)".

There isn't once you apply the CPS-transform.

> The proponents
> of this idea conflate the two situations, "what's the big deal?, its
> the same thing!". In my world, it's not the same thing, it's very
> different!

I don't understand your world then. In a fully CPS-converted program,
all tail calls are continuations. Passing a parameter to a
continuation is no different from passing a parameter to a `regular'
function. FWIW, this actually causes some difficulties in
CPS-oriented compilers and has given rise to the A-Normal transform,
but even there the main (handwave) difference is in the number of
continuation functions introduced. All functions still use the same
argument application mechanism.

The point is that whatever you think about your world, they really
*are* the same, mathematically. Practically, compiler use various
implementation techniques to optimize function calls depending on the
context. The beauty of Blume's proposal is that it has a minimal
(he asserts zero) run-time cost for existing RnRS programs.

> In your world, the operator is indeed the continuation of the first
> and only argument. It sort of makes every call into a
> call-with-values.

Precisely. This is the basic theory of the _Lambda, the Ultimate_
papers, actually.

david rush
--
He who would make his own liberty secure, must guard even his enemy
from repression
        -- Thomas Paine


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Lauri Alanko  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 18:55
Newsgroups: comp.lang.scheme
From: Lauri Alanko <l...@iki.fi>
Date: Wed, 13 Aug 2003 17:53:33 +0000 (UTC)
Local: Wed 13 Aug 2003 18:53
Subject: Re: Alternatives to values/call-with-values
Matthias Blume <matth...@shimizu-blume.com> virkkoi:
>     * The R5RS procedure CALL-WITH-VALUES can be defined as

>          (define call-with-values (LAMBDA (p c) (c (p ()))))

                                                     ^
I presume this should be                             (p).

Lauri Alanko
l...@iki.fi


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Anthony Carrico  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 19:02
Newsgroups: comp.lang.scheme
From: Anthony Carrico <acarr...@memebeam.org>
Date: Wed, 13 Aug 2003 17:59:50 GMT
Local: Wed 13 Aug 2003 18:59
Subject: Re: Alternatives to values/call-with-values

Matthias Blume <matth...@shimizu-blume.com> wrote:
> I am no longer able (nor eager) to invest too much of my time and my
> emotional energy in arguing these things, so I will (try to) limit
> myself to this one last article on the topic.

I think that you are correct. We have fully explored both sides of the
debate. If some language designers can find users willing to swallow
an application rule for for k=0, 2, 3, 4... with an exception for k=1,
and a paradoxical tuple definition to cover the exception up, then you
have a winning proposal. It's fun to explore crazy ideas, otherwise
we'd make no progress. A successful crazy idea has a big payoff, I
just haven't seen it yet for this one. Turning k=1 into a "free"
call-with-values doesn't seem like any kind of payoff to me, certainly
not something to trade a uniform application rule for. Maybe it will
make sense to me in another context someplace down the road.  Thank
you for the time invested, I always learn a lot from your work.

--
Anthony Carrico


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Anthony Carrico  
View profile   Translate to Translated (View Original)
 More options 13 Aug 2003, 20:00
Newsgroups: comp.lang.scheme
From: Anthony Carrico <acarr...@memebeam.org>
Date: Wed, 13 Aug 2003 18:57:39 GMT
Local: Wed 13 Aug 2003 19:57
Subject: Re: Alternatives to values/call-with-values

David Rush <dr...@aol.net> wrote:
> Anthony Carrico <acarr...@memebeam.org> writes:
>> Ok, the big problem is that, in my world, "(f (g)) where g returns
>> multiple values" is an error, not a virtue! This is what I was trying
>> to point out when I said that maybe this whole discussion fell off the
>> Scheme wagon back at "compose". On the other hand, if in some
>> circumstance I do want f to take all of g's values as parameters, I
>> have an easy way to do it: make f into the continuation of g.

> I'm sorry but you have just restated the definition of
> composition. In (f (g)), f *is* the continnuation of (g). Just what is
> it that you consider an error?

Assume f has two parameters and g has two results.

Consider a loose interpretation of the "what happens to extra values"
question. The error is that the application fails to initialize f's second
argument.

Consider a strict resolution of the "what happens to extra values"
question. The error is that g passes two values to the continuation that
intiailizes f's first argument.

See the cps below for precise details.

>> How do I do that? The call-with-values procedure.

> Which is arguably a much clunkier syntax than the natural expression
> of composition.

The syntax you call the "natural expression of composition" isn't an
expression of composition. G's continuation is the initializer of f's
first argument, not f itself. It is only equivalent if (a) f has only
one parameter, and (b) g has only one result.

>> There is a big huge difference between "(g) initializing the first
>> argument of f" and "f being the continuation of (g)".

> There isn't once you apply the CPS-transform.

Sure there is. Watch:

(define f-ds (lambda (x y) ...))
-CPS>
(define f-cps (lambda (K x y) ...)

(define g-ds (lambda () (values a b)))
-CPS>
(define g-cps (lambda (K) (K a b)))

(f-ds (g-ds))
-CPS>
(g-cps
 (lambda (x-tmp)
   ((lambda (y-tmp)
      (f-cps K x-tmp y-tmp))
    ***MISSING***)))

***MISSING** our first error. To see the other error, just substitute g-cps
into that expression.

((lambda (K) (K a b))
 (lambda (x-tmp)
   ((lambda (y-tmp)
      (f-cps K x-tmp y-tmp))
    ***MISSING***)))

and reduce:

((lambda (x-tmp)
   ((lambda (y-tmp)
      (f-cps K x-tmp y-tmp))
    ***MISSING***))
 a b***EXTRA***)

and so b***EXTRA*** is our second error. Obviously b***EXTRA was supposed
to end up where ***MISSING*** is, so the CPS transform very clearly shows
both how problems that result from the "compose" confusion.

>> In your world, the operator is indeed the continuation of the first
>> and only argument. It sort of makes every call into a
>> call-with-values.

> Precisely. This is the basic theory of the _Lambda, the Ultimate_
> papers, actually.

No, the lambda described in the ultimate papers doesn't work that way, and
it doesn't require magic tuples to fix the mistakes introduced by the
feature. Call-with-values introduces the same feature without any mistakes,
so I can't understand why a few people seem to hate it.

--
Anthony Carrico


    Reply to author    Forward  
You must Sign in before you can post messages.
To post a message, you must first join this group.
Please update your nickname on the subscription settings page before posting.
You do not have the permission required to post.
Messages 26 - 50 of 100 < Older  Newer >
« Back to Discussions « Newer topic     Older topic »

Create a group - Google Groups - Google Home - Terms of Service - Privacy Policy
©2009 Google