guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: nested define syntax


From: Dirk Herrmann
Subject: Re: nested define syntax
Date: Wed, 7 Nov 2001 01:16:07 +0100 (MET)

On Thu, 1 Nov 2001, Matthias Koeppe wrote:

> Dirk Herrmann <address@hidden> writes:
> 
> > currently, guile allows the following:
> >
> > guile> (define (((foo a b) c) d) #f)
> > guile> foo
> > #<procedure foo (a b)>
> > guile> (procedure-source foo)
> > (lambda (a b) (lambda (c) (lambda (d) #f)))
> >
> > This is non-R5RS conformant, and I wonder if anybody uses this style of
> > declaration?  Shouldn't we rather remove it?
> 
> This syntax is *not defined* in R5RS.  Guile provides a convenient
> *extension* to R5RS here.  Why do you claim that supporting this
> extension violates R5RS?

R5RS says ('*' characters added by me):

  5.2 Definitions

  Definitions are valid in some, but not all, contexts where expressions
  are allowed. They are valid only at the top level of a <program> and at
  the beginning of a <body>.

  A definition *should* have one of the following forms: 

       (define <variable> <expression>) 

       (define (<variable> <formals>) <body>)  <Formals> should be either
       a sequence of zero or more variables, or a sequence of one or more
       variables followed by a space-delimited period and another variable
       (as in a lambda expression). This form is equivalent to

       (define <variable>
         (lambda (<formals>) <body>)).

       (define (<variable> . <formal>) <body>) <Formal> should be a single
       variable. This form is equivalent to 

       (define <variable>
         (lambda <formal> <body>)).

Obviously, the (define ((foo x y ...) r s ...) ...) form is none of the
forms a definition _should_ have according to R5RS, although I admittedly
don't know if this means that is strictly correct to speak of 'violation'
or 'being non-conformant'.

It seems that guile itself uses this feature at only three places, namely
psyntax.pp, runq.scm and string-fun.scm in ice-9.

> BTW, this technique is called "currying"; I use it extensively in my
> code.

It is also called currying if you write it as
  (define (foo x y ...)
    (lambda (r s ...)
      ...))
:-)

That is, the syntactic extension does not provide too much of a
convenience, but leads to an incompatibility.  I question that this is a
good idea.  For those who like to use such a feature, it would IMO be
better to provide it as a loadable extension, or to use 'define*' instead.

However, I wonder how people get to know about this feature at all, since
there does not seem to be any documentation about it.  The only faint
reference to it I could find was in the documentation for 'define*':

  "`define*' and `define*-public' support optional arguments with a
   similar syntax to `lambda*'. They also support arbitrary-depth
   currying, just like Guile's define."

I would not consider this a documented feature.  Thus, we should decide
whether we want to keep this extension.  IMO, we should not support it by
default.  Who likes it, can use 'define*'.  If it is still decided to keep
it as an official feature (and thus as a source for incompatibilities),
then it should a) be documented in the manual and b) this should also be
documented in the implementation.

Best regards,
Dirk Herrmann




reply via email to

[Prev in Thread] Current Thread [Next in Thread]