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: Stefan Monnier
Subject: Re: [PATCH] * src/eval.c: Stop checking for nvars, and use only CONSP
Date: Tue, 02 Mar 2021 18:48:12 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

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

I'd be happy to have a "low-level" `let` and then macros on top, yes.
But some kind of let-like thingy at the lowest level is largely
unavoidable for practical reasons (falling back on funcall+lambda is
cute for the theory, but to get acceptable performance you need to
treat that combination specially).

> 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 can't see any trouble defining such a macro nor in which way it's
influenced by whether `let` itself is a macro or a special form.

> I think this applies to debugging invalid code, too.

What do you mean by "debugging invalid code"?

> 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))

I find this horrible, like Scheme's `define`.
The semantics of such things tends to be quite intricate.

I think what I find ugly about it is that it means an expression affects
the set of variables bound in the surrounding context.

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

You can emulate it with a new macro `progn-with-lets` which looks for
`letq` in its body.  It's an interesting exercise, indeed, and its
complexity is a good part of why I dislike such features.

> So those are the emacs-devel-relevant questions: Can you implement
> letq in ELisp?

You can, but by its very nature it can't be implemented "as is": it has
to be done within the context of some other element (like
`progn-with-lets`).

> And why does it feel so wrong in ELisp when it's how
> most other languages do this?

Basically those other languages define their functions (and other forms)
to take bodies implicitly wrapped in `progn-with-lets`.

> 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))

I'm afraid I have no idea what this code means.
[ I must admit, I'm not familiar with your "most other languages" ;-)  ]


        Stefan




reply via email to

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