From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.org!not-for-mail From: Panicz Maciej Godek Newsgroups: gmane.lisp.guile.user Subject: Way to control the order of macro expansion Date: Wed, 1 Jan 2014 23:46:57 +0100 Message-ID: NNTP-Posting-Host: plane.gmane.org Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 X-Trace: ger.gmane.org 1388616428 14530 80.91.229.3 (1 Jan 2014 22:47:08 GMT) X-Complaints-To: usenet@ger.gmane.org NNTP-Posting-Date: Wed, 1 Jan 2014 22:47:08 +0000 (UTC) To: "guile-user@gnu.org" Original-X-From: guile-user-bounces+guile-user=m.gmane.org@gnu.org Wed Jan 01 23:47:12 2014 Return-path: Envelope-to: guile-user@m.gmane.org Original-Received: from lists.gnu.org ([208.118.235.17]) by plane.gmane.org with esmtp (Exim 4.69) (envelope-from ) id 1VyUZB-0004cZ-6e for guile-user@m.gmane.org; Wed, 01 Jan 2014 23:47:09 +0100 Original-Received: from localhost ([::1]:42611 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VyUZA-0001vX-Oy for guile-user@m.gmane.org; Wed, 01 Jan 2014 17:47:08 -0500 Original-Received: from eggs.gnu.org ([2001:4830:134:3::10]:37355) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VyUZ2-0001vP-BI for guile-user@gnu.org; Wed, 01 Jan 2014 17:47:01 -0500 Original-Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1VyUZ0-0002EP-Tz for guile-user@gnu.org; Wed, 01 Jan 2014 17:47:00 -0500 Original-Received: from mail-wi0-x22b.google.com ([2a00:1450:400c:c05::22b]:46865) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1VyUZ0-0002EC-O4 for guile-user@gnu.org; Wed, 01 Jan 2014 17:46:58 -0500 Original-Received: by mail-wi0-f171.google.com with SMTP id bz8so18187532wib.16 for ; Wed, 01 Jan 2014 14:46:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:date:message-id:subject:from:to:content-type; bh=MwLPeYFHsY5rQ44EPk06eokupdC3Epln0f+BPFl2uqc=; b=kXKh8AmAvDafWZP7tHgMCIW0f2tsKy58/4GOHhLInRsj0uC2wfthwFWPvMYMZtvOJm vcOdp83wqwmOEJxHMCcSyIaBVitj4BDtjhXpZCvKZHQZD4JF83RjsEm4IY5nT2flfRrG QWz414IdcMuZxlMBArrsnq3Q5eInJRURBf1cjcE3PneKAtrLQ5CV4cq8yIxyoEVA90Ok P+ni2/aMuC9PkyE/xoeXJSSY0fPl7pcwlGzrVzF/tRKV8dz8S0j1c4AMG+PNv33XnOgs TvWBlRG6iKTojNIK4GNyFmcHNhEJokgMdYwHQNBGMHioeyRTBJZLPbqmMaO7G24Ta6Vd ynuw== X-Received: by 10.180.21.244 with SMTP id y20mr53420935wie.37.1388616417719; Wed, 01 Jan 2014 14:46:57 -0800 (PST) Original-Received: by 10.194.178.134 with HTTP; Wed, 1 Jan 2014 14:46:57 -0800 (PST) X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2a00:1450:400c:c05::22b X-BeenThere: guile-user@gnu.org X-Mailman-Version: 2.1.14 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.org@gnu.org Original-Sender: guile-user-bounces+guile-user=m.gmane.org@gnu.org Xref: news.gmane.org gmane.lisp.guile.user:10952 Archived-At: Hi, is there any way to control the order of macro expansion? Let's consider a particular problem. I'm trying to write a macro to control the visibility of certain definitions. I wrote it once, using define-macro, but it seemed to loose some relevant information, so I decided to rewrite it using define-syntax macros. The idea is that the code (publish (define (f x) (+ a x)) (define (g y) (* a y)) where (define a 5)) should expand to (begin (define f (and (defined? 'f) f)) (define g (and (defined? 'g) g)) (let () (define a 5) (set! f (let () (define (f x) (+ a x)) f)) (set! g (let () (define (g x) (* a y)) g)))) The first thing that needs to be done is to split the definitions between the public (before "where") and private ones. It can be done by introducing a helper macro that will be called by our publish macro: (define-syntax-rule (publish definitions ...) (publisher (definitions ...) ())) (define-syntax publisher (syntax-rules (where) ((_ (where private ...) (public ...)) (private+public (private ...) (public ...))) ((_ (new defs ...) (approved ...)) (publisher (defs ...) (approved ... new))))) It works fine, but a simple question arises: how to make publisher visible only within the scope of publish macro? (I have tried many combinations, and all of them failed, although I don't know why) Now, we need the definition for the private+public syntax, that will do the actual conversion. I believe it should look more or less like this: (define-syntax-rule (private+public (private ...) ((df iface body ...) ...)) (letrec-syntax ((name (syntax-rules () ((_ (head . tail)) (name head)) ((_ atom) atom)))) (begin (define (name iface) (and (defined? '(name iface)) iface)) ... (let () private ... (set! (name iface) (let () (df iface body ...) (name iface))) ...)))) Unfortunately, there are some problems with that definition, the most annoying being the fact that it doesn't work ;] There are three problems, namely -- that quote, define and set! are special forms themselves, and as such they prevent the "name" local syntax to expand. (This can be observed easily, because when the names "define" and "set!" and the ' operator are replaced with some unbound identifiers, the macro expands just as I want it to). It seems that the expander works in the order from the outermost to the innermost level, and from left to right. Is there any way to force the expander to evaluate some innermost forms first? regards, M.