[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.