This is the mail archive of the kawa@sourceware.org mailing list for the Kawa project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: syntax-rules problem


On 03/10/2017 01:35 AM, Sascha Ziemann wrote:
I have the following macro.

(define-syntax define-facts
  (syntax-rules ()
    ((_ (name a0 a1 ...) ((v00 v01 ...) (v10 v11 ...) ...))
     '(define (name a0 a1 ...)
        (conde
          ((== a0 v00) (== a1 v01) ...)
          ((== a0 v10) (== a1 v11) ...)
          ...)))))

This got mangled a bit, but definition is clearly wrong.
I cleaned it up:

(define-syntax define-facts
  (syntax-rules ()
    ((_ (name arg ...) ((value key ...) ...))
     (define (name arg ...)
       (cond
        ((and (equal? arg key) ...) value)
        ...)))))

However, this is still not valid R7RS Scheme:

    Pattern variables that occur in subpatterns followed by one or more
    instances of the identifier h<ellipsis> are allowed only in subtemplates
    that are followed by as many instances of <ellipsis>.

The problem is that arg is singly-nested in the pattern, but
doubly-nested in the template.

Kawa does support an extension for different nesting levels, meant to support
things like (x (y ...) ...)  => (((x y) ...) ...).  However, in that case the x
varies by the outer "index":
((x0 (y00 y01)) (x1 (y10 y11 y12)))
 ==> (((x0 y00) (x0 y01)) ((x1 y10) (x1 y11) (x1 y12)))
But for define-facts the single-nested arg needs to vary with the
*inner* index. I.e. you would need Kawa to expand the example to:
 ==> (((x0 y00) (x1 y01)) ((x0 y10) (x1 y11) (x2 y12))) ; Oops no x2
But Kawa doesn't do that.

A solution that does work uses a list:

(define-syntax define-facts
  (syntax-rules ()
    ((_ name ((value . keys) ...))
     (define (name . args)
       (cond ((equal? args 'keys) value) ...)))))

(define-facts father-of
  (("Abraham" "Ismael")
   ("Abraham" "Isaac")
   ("Isaac"   "Jacob")
   ("Jacob"   "Benjamin")))

Obviously, Kawa should not throw ArrayIndexOutOfBoundsException,
but should instead report an error. So that is a Kawa bug.
--
	--Per Bothner
per@bothner.com   http://per.bothner.com/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]