Re: New revision of SRFI 26 available
Al Petrofsky 04 Jun 2002 18:57 UTC
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))))