From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.ciao.gmane.io!not-for-mail From: Taylan Kammer Newsgroups: gmane.lisp.guile.user Subject: Re: Help: equivalent syntax-case to defmacro Date: Wed, 6 May 2020 17:49:08 +0200 Message-ID: <013cb23b-65d6-b7a9-26ca-c5a0319fe87d@gmail.com> References: Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Injection-Info: ciao.gmane.io; posting-host="ciao.gmane.io:159.69.161.202"; logging-data="31837"; mail-complaints-to="usenet@ciao.gmane.io" User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.7.0 To: Dale Mellor , guile-user@gnu.org Original-X-From: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Wed May 06 17:49:30 2020 Return-path: Envelope-to: guile-user@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1jWMIc-0008CG-47 for guile-user@m.gmane-mx.org; Wed, 06 May 2020 17:49:30 +0200 Original-Received: from localhost ([::1]:60822 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jWMIb-0002vC-49 for guile-user@m.gmane-mx.org; Wed, 06 May 2020 11:49:29 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:47636) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1jWMIM-0002tu-GY for guile-user@gnu.org; Wed, 06 May 2020 11:49:14 -0400 Original-Received: from mail-wr1-x42e.google.com ([2a00:1450:4864:20::42e]:45480) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1jWMIL-00061e-KA for guile-user@gnu.org; Wed, 06 May 2020 11:49:14 -0400 Original-Received: by mail-wr1-x42e.google.com with SMTP id v12so1474945wrp.12 for ; Wed, 06 May 2020 08:49:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:references:from:message-id:date:user-agent:mime-version :in-reply-to:content-language:content-transfer-encoding; bh=9HQL7PZ8jI4aa7UwKbESJROcR6x5PfUPegb4KNlO6oU=; b=c9vNs2dvoOOGwO9ZNeT4aVuqo4YKPz5rE6eowE3WK0dATv65idGCQJM3snEfGxKJlW Ap7eksgWZzd+7dcVFV2WsW3K2fVkH4d9P/WElzdzjuAFRzxgsNL/KrTSHDl2psjV8gui tdTJaOkTyFF7WohviSG4va8BhHKSX9MPaU6FgwdbKxdDjH+1Ynkw9i33uCYLdO9fNAfR AH1xYq4CJI1/ymjzg/yzc3jZ3cV9HtRuyFjALP9JAyN2LXhkeuzQWIMbzJX0VXcqBoHq Lic3ZOJYRv5YbClQ31u7UAB6PYIHJUvRH8GoevJmxOLw7loPkw8CSkOX31jDVJlIyRtA lhWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-language :content-transfer-encoding; bh=9HQL7PZ8jI4aa7UwKbESJROcR6x5PfUPegb4KNlO6oU=; b=V+VV3V3wGfooqACVzyfxNJzGZgF4dzuLe3QUg7LSdlWYexGrbgI12vu6Oj799DLXrQ x1ztx2LQsTyf3I/OAe7noDuWS3mPT7jZI3OGQbB5a8zDkAcAF7UMSDt+FttyZ7toXmxa uR0mYik1VZh6EC3+mszLtLl4iV40blJrn03pN20RoU5TOpUZOCM0h2iwjduCQLyNM76K 7bXu16RxKDG0KV0Ptgjp+VwvkWqeB7QnJKy5dDVnypyN5Fo2+xaId1voUgSLw4ErASCE YYoSb8V1syG1qMTLhGIqhAPZT7udS5YI0NHpGJKBTreOzBfVPidZRRbrqQ1wbScyLGtx naXA== X-Gm-Message-State: AGi0PubKM5zy3zz63JR75uhT3o2ZrmqSlzI7TmXwauPZoz1c8O1hhpdW VYPI0R3fpPWrPkB+1uCQQtLIcQc9 X-Google-Smtp-Source: APiQypJtyA3y4Yw9oPnG6ciSYQhKUkSjRjuMUQRKisEh+dRO7fuYRZ3SxGyXCaf5VOQy4q3ESQv7GA== X-Received: by 2002:a5d:69c3:: with SMTP id s3mr9954432wrw.305.1588780150898; Wed, 06 May 2020 08:49:10 -0700 (PDT) Original-Received: from ?IPv6:2a02:908:c70:52c0:8e9:6995:cbb6:6057? ([2a02:908:c70:52c0:8e9:6995:cbb6:6057]) by smtp.gmail.com with ESMTPSA id v131sm3766136wmb.19.2020.05.06.08.49.09 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 06 May 2020 08:49:10 -0700 (PDT) In-Reply-To: Content-Language: en-US Received-SPF: pass client-ip=2a00:1450:4864:20::42e; envelope-from=taylan.kammer@gmail.com; helo=mail-wr1-x42e.google.com X-detected-operating-system: by eggs.gnu.org: No matching host in p0f cache. That's all we know. X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_PASS=-0.001 autolearn=_AUTOLEARN X-Spam_action: no action X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: General Guile related discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guile-user-bounces+guile-user=m.gmane-mx.org@gnu.org Original-Sender: "guile-user" Xref: news.gmane.io gmane.lisp.guile.user:16436 Archived-At: On 05.05.2020 19:34, Dale Mellor wrote: > Been struggling with this for a while, and nothing I try works. > > In test-suite/tests/getopt-long there is > > (defmacro deferr (name-frag re) > (let ((name (symbol-append 'exception: name-frag))) > `(define ,name (cons 'quit ,re)))) > > (deferr no-such-option "no such option") > (display exception:no-such-option) > > and I would like to know how the equivalent with define-syntax... syntax-case would look. (define-syntax deferr (lambda (s) (syntax-case s () ((_ name-frag re) (let* ((name-frag-sym (syntax->datum #'name-frag)) (name-sym (symbol-append 'exception: name-frag-sym)) (name (datum->syntax #'name-frag name-sym))) #`(define #,name (cons 'quit re))))))) Some notes to help understand this: - Syntax-case deals with syntax objects rather than raw symbols. We use syntax->datum to turn 'name-frag' into a symbol and datum->syntax to turn it back into a syntax object. - For some reason, the pattern variables bound via syntax-case (i.e. 'name-frag' and 're' in our case) are forbidden by syntax-case to be referenced outside of a #' or #` form. They must always appear in one of those, period. Hence we have to call (syntax->datum #'name-frag) instead of simply (syntax->datum name-frag). Honestly I still don't know why they designed it this way. - The datum->syntax form requires its first argument to be an existing syntax object, which will tell datum->syntax for which "syntax context" you're creating your new syntax object. In this case I'm passing it #'name-frag because the context where that comes from is the context in which the resulting full name will be used. - In the output form starting with #` the 're' pattern variable can appear naked, whereas the manually created 'name' syntax object must be inserted with the #, form. (This is related to the same design weirdness I mentioned before so don't ask me why.) Hope that helps! Happy to answer further questions. Syntax-case is very tricky but once you get it, it's amazing. - Taylan