Al,

1. The HTML typo:

It will be corrected.

2. Semantics for non-expressions in non-slot position:

Ok. I have decided to follow your suggestion. The non-slot
expressions have to be <expressions> in the sense of R5RS.

After considering the pro's and con's of defining the mechanism one
way or the other, I think the mechanism is not important enough to add
another idiosyncrasy to Scheme.

I will change the spec/impl.

3. Explanation of non-slot expressions:

>   <const-or-slot> --> <>              ; a "slot"
>                       | <expression>  ; a constant, not directly dependent
>                                                                           ;  on the slots
>

> The constants aren't indirectly dependent on the slots either.
> Perhaps "a `constant', an expression independent of the slot values"
> would be clearer.


Unfortunately, the problem persists in your formulation: In ((cut + a <>) a) the
non-slot `a' of the cut is certainly dependent on the value of the slot (it's even
identical). Even worse, it is not very clear what is meant by saying "an expression
depends on a value" as the expression is a syntactic object and the value is
a constant in the semantic domain. Hence, we need to talk about the function
being defined by the expression, the variables generated for the slots and
need to unfold the entire semantics of Scheme. However, I doubt that this will
clarify the mechanism a lot.

Unless we really provide a semantics, there will always be some confusion.
However, the name "constant" is not really important for understanding the
mechanism. I will drop the "constant" business altogether and simply call it
"non-slot expression" and replace <const-or-slot> by <slot-or-expr>.

4. Definition of variable arity:

Good observation. The specification will be changed.

5. Evaluation order:

Another good observation. Will be corrected.

---

Apparently, your code does exactly what the reference implementation
is supposed to do and it is very clear.

Any objections if I steal your code and put it forward as the
reference implementation (with <const-or-slot> substituted by
<slot-or-expr> etc. to match with the SRFI-document)?
You will be mentioned as the author, of course.

Sebastian.

----
Dr. Sebastian Egner
Senior Scientist
Philips Research Laboratories
Prof. Holstlaan 4 (WY2)
5656 AA Eindhoven
The Netherlands
tel:       +31 40 27-43309
fax:      +31 40 27-44918
email: xxxxxx@philips.com



srfi-26xxxxxx@srfi.schemers.org

06/04/02 20:58

       
        To:        srfi-26@srfi.schemers.org
        cc:        (bcc: Sebastian Egner/EHV/RESEARCH/PHILIPS)
        Subject:        Re: New revision of SRFI 26 available

        Classification:        




Some issues with the latest draft:

In the code samples within the html, like this:

 <code>(cut cons (+ a 1) <>)</code>

My browser is displaying this as (cut cons (+ a 1) ).  The angle
brackets need to be escaped.

 (apply + (map (cut if <> 0 1) '(#f #t #t #f)))

This is an error according to the specification that "const"s must be
expressions.  I suggest you keep that requirement and drop support for
this usage unless you can come up with a reasonable semantics for (cut
quasiquote <>), or some way to specify which non-expressions are and
are not allowed as "const"s.


  <const-or-slot> --> <>              ; a "slot"
                      | <expression>  ; a constant, not directly dependent
                                                                          ;  on the slots

The constants aren't indirectly dependent on the slots either.
Perhaps "a `constant', an expression independent of the slot values"
would be clearer.

 In case there is a rest-slot symbol for the residual arguments of a
 variable arity procedure, the resulting procedure is also of
 variable arity

If a system provides a variable-arity? procedure, I would expect it to
interact with cut like this:

 (variable-arity? list)             => #t
 (variable-arity? (cut list <>))    => #f
 (variable-arity? cons)             => #f
 (variable-arity? (cut cons <...>)) => #t

Hence, I think it would be simpler and more accurate to say:

 If there is a rest-slot symbol for residual arguments, the resulting
 procedure is of variable arity

The implementation gets the second of these tests wrong:

 (let* ((x 'cute) (y (cut  list x))) (set! x 'cut) (y))  => cut
 (let* ((x 'cute) (y (cute list x))) (set! x 'cut) (y))  => cute

Two non-bug drawbacks to the implementation are that it doesn't catch
errors like (cut if <> 0 1) and it forces an evaluation order for the
"const"s in a cute expression.  Here's one way to address all three
issues:

; (srfi-26-internal-cut slot-names combination . cs)
;   transformer used internally
;     slot-names  : the internal names of the slots
;     combination : procedure being specialized, followed by its arguments
;     cs          : consts-or-slots, the qualifiers of the macro

(define-syntax srfi-26-internal-cut
 (syntax-rules (<> <...>)

   ;; construct fixed- or variable-arity procedure
   ((srfi-26-internal-cut (slot-name ...) (proc arg ...))
    (lambda (slot-name ...) ((begin proc) arg ...)))
   ((srfi-26-internal-cut (slot-name ...) (proc arg ...) <...>)
    (lambda (slot-name ... . rest-slot) (apply proc arg ... rest-slot)))

   ;; process one const-or-slot
   ((srfi-26-internal-cut (slot-name ...)   (position ...)      <>    . cs)
    (srfi-26-internal-cut (slot-name ... x) (position ... x)          . cs))
   ((srfi-26-internal-cut (slot-name ...)   (position ...)      const . cs)
    (srfi-26-internal-cut (slot-name ...)   (position ... const)      . cs))))

; (srfi-26-internal-cute slot-names const-bindings combination . cs)
;   transformer used internally
;     slot-names     : the internal names of the slots
;     const-bindings : let-style bindings for the constants.
;     combination    : procedure being specialized, followed by its arguments
;     cs             : consts-or-slots, the qualifiers of the macro

(define-syntax srfi-26-internal-cute
 (syntax-rules (<> <...>)
   ;; If there are no const-or-slots to process, then:
   ;; construct a fixed-arity procedure,
   ((srfi-26-internal-cute
     (slot-name ...) const-bindings (proc arg ...))
    (let const-bindings (lambda (slot-name ...) (proc arg ...))))
   ;; or a variable-arity procedure
   ((srfi-26-internal-cute
     (slot-name ...) const-bindings (proc arg ...) <...>)
    (let const-bindings (lambda (slot-name ... . x) (apply proc arg ... x))))

   ;; otherwise, process one slot:
   ((srfi-26-internal-cute
     (slot-name ...)         const-bindings  (position ...)   <>    . cs)
    (srfi-26-internal-cute
     (slot-name ... x)       const-bindings  (position ... x)       . cs))
   ;; or one const
   ((srfi-26-internal-cute
     slot-names              const-bindings  (position ...)   const . cs)
    (srfi-26-internal-cute
     slot-names ((x const) . const-bindings) (position ... x)       . cs))))

; exported syntax

(define-syntax cut
 (syntax-rules (<> <...>)
   ((cut . consts-or-slots)
    (srfi-26-internal-cut () () . consts-or-slots))))

(define-syntax cute
 (syntax-rules (<> <...>)
   ((cute . consts-or-slots)

     (srfi-26-internal-cute () () () . consts-or-slots))))