emacs-devel
[Top][All Lists]
Advanced

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

Re: [PATCH] * src/eval.c: Stop checking for nvars, and use only CONSP


From: Pip Cet
Subject: Re: [PATCH] * src/eval.c: Stop checking for nvars, and use only CONSP
Date: Tue, 2 Mar 2021 19:50:23 +0000

On Tue, Mar 2, 2021 at 5:44 PM Stefan Monnier <monnier@iro.umontreal.ca> wrote:
> >> > I'm all for a revolution, but it might be a bit early to chop off this
> >> > particular king's head...
> >> Until we have good debugging support for byte-compiled code, the
> >> interpreter isn't going anywhere, indeed.
> > We could rewrite it in ELisp, though :-)
>
> That would mean just replacing the `Flet` in C with another in ELisp, so
> it would largely just move the question (which is about diagnosing
> invalid code).

Two advantages: A macro can be redefined and have its redefinition
apply to compiled code; and, if let were implemented as a macro, other
letlikes would have a starting point.

For example, I'd love

(traced-let ((a 1) (b 2) (c (throw 'out nil)) (d 3)) ...)

to work (and print "a = 1 b = 2 c = <interrupted>"), but every time I
need it it seems more effort to write than just to debug things the
old-fashioned way (did I mention it's my non-integral birthday?)...

I think this applies to debugging invalid code, too.

> > (I dislike the "let" family, mostly for the fact that it is a family.
> > It leads naturally to cl-loop.)
>
> Removing its special-form status wouldn't remove it from the
> language, tho :-(

It would make it live at the same level as cl-loop or pcase.

> [ Personally, I do find `let` important.
>   Partly because of my let-polymorphism upbringing ;-)  ]

I do wonder why other languages have moved to the equivalent of

(defun f (a) (letq x 1) (+ x a))

or

(defun f (a) (+ (letq x 1) a x))

or even

(defun f (a) (if (> a 3) (letq x 1) (letq x 2)) (+ x a x))

while Lisps insist you have to be up front and list all your variables
when it creates the stack frame. And

(letq a 1)
(message "a is %S" a)
(letq b 2)

is easier to read than

(let* ((a 1)
      (_ (message "a is %S" a))
      (b 2))

What seems particularly problematic to me is that other languages can
emulate "let" easily, but implementing "letq" in ELisp is...an
interesting exercise (i.e. I tried and failed).

So those are the emacs-devel-relevant questions: Can you implement
letq in ELisp? And why does it feel so wrong in ELisp when it's how
most other languages do this? For bonus points, make

(defun f ()
  (letq g (lambda () (letq-in g g-counter 0) (letq-in f f-counter 0)
(incf g-counter) (incf f-counter)))
  (cons g (lambda () f-counter))

work.

Pip



reply via email to

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