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

Re: New revision of SRFI 26 available




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: sebastian.egner@xxxxxxxxxxx



srfi-26-request@xxxxxxxxxxxxxxxxx

06/04/02 20:58

       
        To:        srfi-26@xxxxxxxxxxxxxxxxx
        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))))