unofficial mirror of help-gnu-emacs@gnu.org
 help / color / mirror / Atom feed
From: Jean Louis <bugs@gnu.support>
To: Eduardo Ochs <eduardoochs@gmail.com>
Cc: help-gnu-emacs <help-gnu-emacs@gnu.org>
Subject: Eval in templates - Re: How to tame compiler?
Date: Mon, 3 May 2021 09:51:35 +0300	[thread overview]
Message-ID: <YI+dd0m8N+gx8C7S@protected.localdomain> (raw)
In-Reply-To: <CADs++6jD3+vApjjMUfpHHRPqR18Dj1WKfVmi4GSyZyTJcjepYQ@mail.gmail.com>

* Eduardo Ochs <eduardoochs@gmail.com> [2021-05-03 04:59]:
> just as a curiosity, here is how eev implements template
> interpolation:
> 
>   http://angg.twu.net/eev-current/eev-template0.el.html
>   http://angg.twu.net/eev-current/eev-template0.el
> 
> I tried several other implementations of template interpolation
> functions before that one, and from time to time I would find another
> way that would be both simpler and more powerful than the previous
> one... the one above is so simple that in one of the times that I gave
> a minicourse on LaTeX and Emacs I followed the code of `ee-template0'
> with the students in the third day of the minicourse - one day after
> teaching them briefly how to understand code with `defun's and
> `let's.

That is so interesting. This templating system has slightly different
concept. In my eval-ing, I have to get some value no matter what, I am
also thinking I have freedom to make errors, to the system is not
allowed to fail.

(setq rcd-template-delimiter-open "(") ⇒ "("
(setq rcd-template-delimiter-close ")") ⇒ ")"
(setq text1 "We will evaluate (+ 2 2) to result ((+ 2 2))") ;; won't interpolate
(setq text2 "We will evaluate (+ 2 2) to result ( (+ 2 2) )")
(setq text3 "We will evaluate (+ 2 2) to result ( (+ 2 2 )") ;; error allowed

This does not interpolate, as I demand spaces after delimiters:
(rcd-template-eval text1) ⇒ "We will evaluate (+ 2 2) to result ((+ 2 2))"

This does interpolate:
(rcd-template-eval text2) ⇒ "We will evaluate (+ 2 2) to result 4"

Error is interpolated to "", but I could log it in future:
(rcd-template-eval text3) ⇒ "We will evaluate (+ 2 2) to result "

Compared to this that works:
(ee-template0 "{<} a{(+ 2 3)} {>}") ⇒ "{ a5 }"

And this one giving error:
(ee-template0 "{<} a{(+ 2 3} {>}")

Concept is the same. You also do not use dynamic binding, which
is quite clear why.

In the sense of teaching is fine. I guess you almost never had a
problem when evaluation fails for some reason.

In the sense of generation of hundreds of emails for people, or
generation of thousands of HTML pages, the template system IMHO
is not allowed to fail. Errors however, could be reported,
templating system could then tell me in which page or email the
error has been found. But it has to move silently over the failure.

Thus I would expect also this one, to produce following:
(ee-template0 "{<} a{(+ 2 3} {>}")  ⇒ "{ a }"

And more perfect would be if error would be reported somewhere in silent.

> My trick to handle lexical binding was to tell the students that
> dynamic binding is much easier to understand than lexical binding, and
> that they should treat dynamic binding as an advanced topic that would
> make more sense when they had at least one week of experience with
> Emacs - and my minicourse was only five days long, from monday to
> friday... but the students in that minicourse were mathematicians with
> little experience in programming, not compsci people who would see
> immediately that dynamic binding is "wrong".

Thus you had the luck to have a different type of audience.

Here is also demonstrated how eev tools have different context,
programs are invoked from within text manuall. Your tools are in
general, beyond templating, meant to be evaluated in the text or
within the text and in that concept there is also no need for
lexical binding. Small snippets are evaluated one after each
other by user's demand, functions evaluated may come originally
from programs with lexical binding.

Thus I have improved my function to evalute with errors reported,
as it makes so much more sense. It is made to interpolate
thousands of times within minutes automatically.

Source: https://gnu.support/files/sources/rcd-template.el

(defun rcd-template-eval (string &optional delimiters)
  "Evaluates Emacs Lisp enclosed by `rcd-template-delimiter-open' and `rcd-template-delimiter-close'.

Optional DELIMITERS list may be provided to change default
delimiters, first list member has to be the opening delimiter and
second the closing delimiter.

Space or new line has to follow `rcd-template-delimiter-open' and
precede `rcd-template-delimiter-close' for evaluation to get
invoked."
  (let* ((delimiters (or delimiters (list rcd-template-delimiter-open rcd-template-delimiter-close)))
	 (open (car delimiters))
	 (close (cadr delimiters))
	 (add (length open))
	 (minus (length close)))
    (with-temp-buffer
      (insert string)
      (goto-char 0)
      (while (re-search-forward (rx (literal open)
				    (one-or-more (or blank "\n"))
				    (group (minimal-match (one-or-more anything)))
				    (one-or-more (or blank "\n"))
				    (literal close))
				nil t)
	(let* ((match-beginning (match-beginning 0))
	       (match-end (match-end 0))
	       (match (buffer-substring-no-properties
		       (+ add match-beginning) (- match-end minus)))
	       (lisp (condition-case error
			 (read-from-string match)
		       (error (princ (format "rcd-template-eval: `read-from-string' error: %s" error))
			      "")))
	       (lisp (if (listp lisp) (car lisp) lisp))
	       (value (condition-case error
			  (eval lisp)
			(error (princ (format "rcd-template-eval: `eval' error: %s" error)))))
	       (value (cond ((null value) "")
			    (t (format "%s" value)))))
	  (delete-region match-beginning match-end)
	  (insert (format "%s" value))))
      (buffer-string))))

(rcd-template-eval "( (+ 2 2) )" '("(" ")")) ⇒ "4"

(rcd-template-eval "( (+ 2 2 )" '("(" ")")) ⇒ "" 
     with error reporting in *Messages* buffer:
     rcd-template-eval: `read-from-string' error: (end-of-file)

(rcd-template-eval "We expect 4 but fail: ( (+2 2) )" '("(" ")")) ⇒ "We expect 4 but fail: "
     with error reporting in *Messages* buffer:
     rcd-template-eval: `eval' error: (invalid-function 2)

(defun ee-template-test (text)
  (rcd-template-eval text '("{" "}")))

My regexp asks for spaces or new lines between delimiters:

(ee-template-test "{<} a{ (+ 2 3 } {>}") ⇒ "{<} a {>}"
     with error reporting in *Messages* buffer:
     rcd-template-eval: `read-from-string' error: (end-of-file)

but of course, it does not do your trick:
(ee-template-test "{<} a{ (+ 2 3) } {>}") ⇒ "{<} a5 {>}"

If I would like to enclose it with open delimiters in a result, this would work:
(ee-template-test "{ \"{\" } a{ (+ 2 3) } { \"}\" }") ⇒ "{ a5 }"

And I use the habit that people would not tend to write space
after parenthesis.

I could write: (maybe I am wrong), but I would never write 
( maybe I am not wrong ).

That may allow using parenthesis in templates which makes it more
Lisp-like:

(rcd-template-eval "We know that (+ 2 2) evaluates to ( (+ 2 2) )") ⇒ "We know that (+ 2 2) evaluates to 4"

Then `eval' within `eval' help in avoiding repetition of demonstrated code:
(rcd-template-eval "We know that ( (setq code '(+ 2 2)) ) evaluates to ( (eval code) )") ⇒ "We know that (+ 2 2) evaluates to 4"

Regular expression is I see hard coded:
(defvar ee-template00-re "{\\([^{}]+\\)}")

And I have envisioned it to rather have flexible delimiters:

(rcd-template-eval "<% user-login-name %>" '("<%" "%>")) ⇒ "jimmy"

as it emulates some other templating engines and allows re-use of templates:
(rcd-template-eval "<% @var user-login-name %>" '("<% @var" "%>")) ⇒ "jimmy"

Maybe you wish to include error reporting and silent failure as
well, or no?

-- 
Jean

Take action in Free Software Foundation campaigns:
https://www.fsf.org/campaigns

Sign an open letter in support of Richard M. Stallman
https://stallmansupport.org/
https://rms-support-letter.github.io/




  reply	other threads:[~2021-05-03  6:51 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-22 14:43 How to tame compiler? Jean Louis
2021-04-22 14:46 ` Stefan Monnier
2021-04-22 15:47   ` Jean Louis
2021-04-22 16:06   ` Jean Louis
2021-04-30 13:31   ` Jorge P. de Morais Neto
2021-04-30 19:38     ` rcd-template-eval - was " Jean Louis
2021-04-30 19:48     ` rcd-template-eval, much is in Org mode Jean Louis
2021-04-30 20:06       ` Tassilo Horn
2021-04-30 22:08       ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-04-30 23:04         ` Org mode rant Jean Louis
2021-05-01  0:46           ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-01  6:10             ` Jean Louis
2021-05-01  6:34               ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-01  9:41                 ` On markdown images Jean Louis
2021-05-01  9:59                   ` Yuri Khan
2021-05-01 10:18                     ` Jean Louis
2021-05-01 11:09                       ` Yuri Khan
2021-05-01 11:25                         ` Jean Louis
2021-05-02 19:30                         ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-03  5:43                           ` Yuri Khan
2021-05-03 17:08                             ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-03 23:22                               ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-04  2:39                   ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-01  5:00           ` Org mode rant Bastien
2021-05-01  5:10             ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-01  9:16             ` Jean Louis
2021-05-01 10:06               ` Bastien
2021-05-01 10:42                 ` Jean Louis
2021-05-01 10:10               ` Bastien
2021-05-01 11:19                 ` Jean Louis
2021-05-01 13:48                 ` [External] : " Drew Adams
2021-05-01 14:05                   ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-01 10:10               ` Bastien
2021-04-30 20:23     ` eval myths - Re: How to tame compiler? Jean Louis
2021-04-30 22:11       ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-04-30 23:07         ` Jean Louis
2021-05-01  0:28           ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-01  8:13       ` tomas
2021-04-30 22:06     ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-04-30 22:20       ` Stefan Monnier
2021-04-30 22:31         ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-04-30 22:50           ` Stefan Monnier
2021-04-30 22:56             ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-01  0:44 ` Michael Heerdegen
2021-05-01  3:49   ` Stefan Monnier
2021-05-01  4:55     ` Michael Heerdegen
2021-05-01  6:34     ` Jean Louis
2021-05-01 13:38       ` Stefan Monnier
2021-05-01 16:19         ` Jean Louis
2021-05-02  5:41     ` Michael Heerdegen
2021-05-02  7:37       ` Jean Louis
2021-05-02  7:45       ` Jean Louis
2021-05-02  9:06         ` tomas
2021-05-02 11:18           ` Jean Louis
2021-05-02 12:24             ` tomas
2021-05-02 18:17               ` Jean Louis
2021-05-02 12:06           ` Stages of WWW development compared to Emacs Lisp development Jean Louis
2021-05-02 16:51             ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-02 18:37               ` Jean Louis
2021-05-02 16:45       ` How to tame compiler? Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-02 22:29       ` Stefan Monnier
2021-05-02 23:14         ` Jean Louis
2021-05-03  1:58           ` Eduardo Ochs
2021-05-03  6:51             ` Jean Louis [this message]
2021-05-01  4:53   ` Michael Heerdegen
2021-05-01  7:05     ` Jean Louis
2021-05-01  7:59       ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-01  6:03   ` Jean Louis
2021-05-01  6:17     ` Emanuel Berg via Users list for the GNU Emacs text editor
2021-05-02  5:58     ` Michael Heerdegen
2021-05-02  6:54       ` Jean Louis
2021-05-03 21:39       ` Jean Louis

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/emacs/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=YI+dd0m8N+gx8C7S@protected.localdomain \
    --to=bugs@gnu.support \
    --cc=eduardoochs@gmail.com \
    --cc=help-gnu-emacs@gnu.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).