guile-devel
[Top][All Lists]
Advanced

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

Re: Why not support (begin), (cond), (case-lambda), etc?


From: Alex Shinn
Subject: Re: Why not support (begin), (cond), (case-lambda), etc?
Date: Fri, 6 Jan 2012 21:08:57 +0900

On Fri, Jan 6, 2012 at 5:03 PM, Mark H Weaver <address@hidden> wrote:
>
> For example, consider a convenience macro to define a structure type.
> It expands to a sequence of definitions, one of which is the
> constructor.  In the structure specification, each field may provide an
> optional `valid?' predicate.  One of the jobs of the constructor is to
> make sure that its arguments are valid.
>
> One reasonable way to do this is to include a `cond' in the expansion of
> the constructor which contains one clause for each field that provides
> the optional `valid?' predicate.  This `cond' would be evaluated solely
> for its effect, namely to raise an error if any predicate fails.
>
> However, the structure specification may not have included any field
> predicates, in which case the macro would most naturally generate
> (cond).

Please take this to the scheme-reports list if you really
want the standard changed.

However, you would need actual macro examples to
convince me.  I can't see how you could arrive at the
scenario you're describing.  Assuming you've filtered
out the fields that have predicates into pred-fields,
then you would expand into something like:

  (define (constructor fields ...)
    (begin
      (expand-validate-field pred-fields) ...
      <normal-body>))

where each expand-validate-field would be something
like

  (unless predicate (error "field predicate failed"))

and possibly this would be inlined above instead of
a separate macro.  Alternately, if you don't want
individual error messages but a single error then
you expand into

  (define (constructor fields ...)
    (unless (and (expand-predicate pred-fields) ...)
       (error "some predicates failed"))
    <normal-body>)

where again there's no problem because the empty
(and) is valid.

I think the only reason to use cond would be the
aesthetics of _not_ having any side-effecting expressions,
i.e. you could expand into

  (define (constructor fields ...)
    (cond
      ((expand-predicate pred-fields) (error "invalid field")) ...
      (else <normal-body>)))

where the normal body is the "else" clause
of the cond when no errors occurred, but in
this case the cond is never empty (and always
returns a value or errors).

But I repeat, take this to the list, and polish up
your arguments because you have to convince
the whole group.

> Of course, it is not hard to work around these seemingly pointless
> prohibitions, just as it would not be hard to write
>
>  (if (null? xs) 0 (apply + xs))
>
> instead of
>
>  (apply + xs)
>
> but I don't understand why we should have to.  What's the compelling
> argument on the other side that justifies these annoyances?

This analogy is meaningless, but for the record
you should be using fold or reduce here.

-- 
Alex



reply via email to

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