From: "pelzflorian (Florian Pelz)" <pelzflorian@pelzflorian.de>
To: Mark H Weaver <mhw@netris.org>
Cc: guile-user@gnu.org
Subject: Re: How to use-modules within macro?
Date: Fri, 30 Aug 2019 08:47:34 +0200 [thread overview]
Message-ID: <20190830064734.n5kmpqzyypmcxhkt@pelzflorian.localdomain> (raw)
In-Reply-To: <875zmflgjh.fsf@netris.org>
On Thu, Aug 29, 2019 at 07:04:07PM -0400, Mark H Weaver wrote:
> This approach is misguided and unnecessary. You don't need to include
> 'use-modules' in your macro expansion, and it's best avoided.
>
:) I suspected I was doing something very wrong.
> FYI, the way this works internally is that the macro expander operates
> on "syntax objects" instead of plain S-expressions. The main difference
> is that "syntax objects" keep additional information about the lexical
> environments where the embedded identifiers were originally found. So
> when a use of (O) expands into (local-eval 42 (the-environment)), the
> identifiers 'local-eval' and 'the-environment' are looked up in the
> proper environment.
>
I had read but not understood that syntax carries references, but of
course it does because of hygiene. Thank you!
> By the way, another consequence of hygiene, which you probably don't
> want here, is that the (the-environment) above will capture the lexical
> environment where 'O' was *defined*, instead of the environment where
> (O) is used. In other words, in (let ((x 5)) (O)), the captured lexical
> environment will not include 'x'.
>
> I should also mention that using (the-environment) will pretty much
> disable most compiler optimizations that would otherwise occur with that
> top-level form. That entire mechanism is best avoided if at all
> possible.
>
> Can you tell me more broadly what you are trying to accomplish here?
> I may be able to suggest an alternate approach.
>
> Best,
> Mark
What I am actually trying to do is rewriting S-expressions based on a
translated gettext MO file for localization. I have a gettext POT
file which contains:
#: apps/packages/templates/components.scm:104$
msgid " issue"
msgid_plural " issues"
msgstr[0] ""
msgstr[1] ""
(define (sngettext x)
"After choosing an identifier for behavior similar to ngettext:1,2,
make it usable like (define-syntax N_ sngettext). sngettext takes
into account that not all languages have only singular and plural
forms."
(syntax-case x ()
((_ msgid1 msgid2 n) ;three sexps
;; sexp->msgid computes a gettext msgid for lookup with gettext
(let* ((msgstr1 (sexp->msgid (syntax->datum #'msgid1)))
(msgstr2 (sexp->msgid (syntax->datum #'msgid2))))
#`(begin
(use-modules (ice-9 local-eval))
(local-eval (let ((applicable (if (= #'n 1) #'msgid1 #'msgid2)))
;; deconstruct builds a new sexp from either
;; msgid1 or msgid2 and the translation from
;; the gettext MO file, i.e. it deconstructs
;; the translation to an sexp.
(deconstruct (syntax->datum applicable)
(ngettext #,msgstr1 #,msgstr2 n)))
(the-environment)))))))
The first argument of sexp->msgid and deconstruct must be the msgid,
which can be a complicated nested sexp. Macros must not have been
expanded there. For ngettext, it is important that the n s-expression
be evaluated by ngettext in the evaluation phase and not at expansion
time.
The corresponding sgettext works fine with deconstruct moved to macro
expansion time, therefore there is no need for local-eval. Moving
deconstruct to macro expansion time would mean I would need to
deconstruct all singular, plural etc. forms, because I do not yet know
the value of n. I could do this by evaluating the Plural-Forms line
from the MO file, I just wanted to avoid this and let ngettext do the
work.
Thank you!! I now understand macros better.
Regards,
Florian
next prev parent reply other threads:[~2019-08-30 6:47 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-08-29 14:41 How to use-modules within macro? pelzflorian (Florian Pelz)
2019-08-29 23:04 ` Mark H Weaver
2019-08-30 6:47 ` pelzflorian (Florian Pelz) [this message]
2019-09-04 11:24 ` pelzflorian (Florian Pelz)
2019-09-04 19:54 ` Mark H Weaver
2019-09-04 21:55 ` Mark H Weaver
2019-09-04 22:58 ` pelzflorian (Florian Pelz)
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190830064734.n5kmpqzyypmcxhkt@pelzflorian.localdomain \
--to=pelzflorian@pelzflorian.de \
--cc=guile-user@gnu.org \
--cc=mhw@netris.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).