help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: the (declare special) declaration with lexical scope.


From: Madhu
Subject: Re: the (declare special) declaration with lexical scope.
Date: Mon, 24 Apr 2023 07:46:01 +0530 (IST)

*  Platon Pronko <d4e72287-61c4-129c-9886-c0881237b9da@gmail.com>
Wrote on Sun, 23 Apr 2023 17:47:40 +0800
> However I'm interested why you didn't consider to make the entire
> mustache function into a macro that expands to concat call with
> variables already interpolated?  This way it will work regardless of
> lexical or dynamic binding.

You're right. If I had started that way it lexenv wouldn't have been
an issue and my goal here was mainly to get the "rendering context"
from the (dynamic or lexical) environment.

But I imagined the idea of "templating" involves compiling a template
pattern to a funcallable and calling it repeatedly with different
arguments.


> I suppose this might break if template is dynamically generated
> somewhere, however templates are usually static and thus can be
> embedded at compile time (it will be the fastest-performing option,
> aside from other benefits).
>
> Here's an example of what I mean:
>
> (defun mustache-build (template)
>   (let ((pattern-start (string-match "{{\\(.*?\\)}}" template)))
>     (if (not pattern-start)
>         template
>       `(,(substring template 0 pattern-start)
>         (prin1-to-string ,(intern (match-string 1 template)))
>         ,@(if (>= (match-end 0) (length template)) nil (mustache-build
>         (substring template (match-end 0))))))))
> (defmacro mustache (template)
>   `(concat ,@(mustache-build template)))
>
> (macroexpand '(mustache "a={{a}} b={{b}}"))
> ; (concat "a=" (prin1-to-string a) " b=" (prin1-to-string b))
>
> (let ((a 42) (b '(+ 2 3)))
>   (mustache "a={{a}} b={{b}}"))
> ; "a=42 b=(+ 2 3)"


This is enough for the problem I was working on.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]