From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 92463 invoked by alias); 10 Mar 2017 19:04:37 -0000 Mailing-List: contact kawa-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: kawa-owner@sourceware.org Received: (qmail 92432 invoked by uid 89); 10 Mar 2017 19:04:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.5 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 spammy=Jacob, v01, y00, Sascha X-HELO: aibo.runbox.com Received: from aibo.runbox.com (HELO aibo.runbox.com) (91.220.196.211) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 10 Mar 2017 19:04:35 +0000 Received: from [10.9.9.211] (helo=mailfront11.runbox.com) by mailtransmit02.runbox with esmtp (Exim 4.86_2) (envelope-from ) id 1cmPq5-0002ph-66; Fri, 10 Mar 2017 20:04:33 +0100 Received: from 70-36-239-163.dsl.dynamic.fusionbroadband.com ([70.36.239.163] helo=localhost.localdomain) by mailfront11.runbox.com with esmtpsa (uid:757155 ) (TLS1.2:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.82) id 1cmPpw-0002ox-4P; Fri, 10 Mar 2017 20:04:24 +0100 Subject: Re: syntax-rules problem To: Sascha Ziemann , kawa mailing list References: From: Per Bothner Message-ID: Date: Fri, 10 Mar 2017 19:04:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.7.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-IsSubscribed: yes X-SW-Source: 2017-q1/txt/msg00068.txt.bz2 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 are allowed only in subtemplates that are followed by as many instances of . 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/