all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
* Elisp threading macros
@ 2024-08-28 14:08 Garklein
  2024-08-28 15:51 ` Robert Pluim
                   ` (5 more replies)
  0 siblings, 6 replies; 24+ messages in thread
From: Garklein @ 2024-08-28 14:08 UTC (permalink / raw)
  To: emacs-devel

Hello,

Would it be possible to have the dash.el macros `->', `->>', `-->',
and `-some->' in subr-x.el? I find them to be really useful, and would
love to see them in the base language.

I know that `thread-first' and `thread-last' exist, but I find that my
eyes can recognize `->' and `->>' much easier. `-->' is really nice
for more complex threading.

`-some->' is useful in cases like this:

(let (foo (function-which-may-return-nil))
  (when foo
    (bar foo)))

which can be rewritten, much cleaner, as

(-some-> foo function-which-may-return-nil bar)

Thank you,
Garklein



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 14:08 Elisp threading macros Garklein
@ 2024-08-28 15:51 ` Robert Pluim
  2024-08-28 16:42   ` Visuwesh
  2024-08-28 15:55 ` Eli Zaretskii
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 24+ messages in thread
From: Robert Pluim @ 2024-08-28 15:51 UTC (permalink / raw)
  To: Garklein; +Cc: emacs-devel

>>>>> On Wed, 28 Aug 2024 10:08:05 -0400, Garklein <garklein97@gmail.com> said:

    Garklein> Hello,
    Garklein> Would it be possible to have the dash.el macros `->', `->>', `-->',
    Garklein> and `-some->' in subr-x.el? I find them to be really useful, and would
    Garklein> love to see them in the base language.

    Garklein> I know that `thread-first' and `thread-last' exist, but I find that my
    Garklein> eyes can recognize `->' and `->>' much easier. `-->' is really nice
    Garklein> for more complex threading.

    Garklein> `-some->' is useful in cases like this:

    Garklein> (let (foo (function-which-may-return-nil))
    Garklein>   (when foo
    Garklein>     (bar foo)))

    Garklein> which can be rewritten, much cleaner, as

    Garklein> (-some-> foo function-which-may-return-nil bar)

Beauty is in the eye of the beholder:

(when-let ((foo (function-which-may-return-nil)))
  (bar foo))

Robert
-- 



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 14:08 Elisp threading macros Garklein
  2024-08-28 15:51 ` Robert Pluim
@ 2024-08-28 15:55 ` Eli Zaretskii
  2024-08-28 18:23   ` Basil L. Contovounesios
  2024-08-31 12:50   ` Augusto Stoffel
  2024-08-28 18:05 ` Philip Kaludercic
                   ` (3 subsequent siblings)
  5 siblings, 2 replies; 24+ messages in thread
From: Eli Zaretskii @ 2024-08-28 15:55 UTC (permalink / raw)
  To: Garklein; +Cc: emacs-devel

> From: Garklein <garklein97@gmail.com>
> Date: Wed, 28 Aug 2024 10:08:05 -0400
> 
> Would it be possible to have the dash.el macros `->', `->>', `-->',
> and `-some->' in subr-x.el? I find them to be really useful, and would
> love to see them in the base language.

We might, but probably not using the names dash.el uses.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 15:51 ` Robert Pluim
@ 2024-08-28 16:42   ` Visuwesh
  2024-08-28 17:13     ` Henrik Kjerringvåg
  0 siblings, 1 reply; 24+ messages in thread
From: Visuwesh @ 2024-08-28 16:42 UTC (permalink / raw)
  To: Robert Pluim; +Cc: Garklein, emacs-devel

[புதன் ஆகஸ்ட் 28, 2024] Robert Pluim wrote:

> Beauty is in the eye of the beholder:
>
> (when-let ((foo (function-which-may-return-nil)))
>   (bar foo))
>

Not to mention, eldoc does not really work for these threading macros
which is a real annoyance when trying to read code that heavily uses
such macros.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 16:42   ` Visuwesh
@ 2024-08-28 17:13     ` Henrik Kjerringvåg
  0 siblings, 0 replies; 24+ messages in thread
From: Henrik Kjerringvåg @ 2024-08-28 17:13 UTC (permalink / raw)
  To: Visuwesh; +Cc: Robert Pluim, Garklein, emacs-devel

When-let is just functionally the same in the example provided. I think the point was actually about threading. I’m with Garklein on this subject. In my day job I program in Clojure and can attest to these threading macros being very valuable. 
If Eldoc doesn’t work well with these macros, it sounds like some improvements can be made to Eldoc as well.

Sendt fra min iPhone

> 28. aug. 2024 kl. 18:43 skrev Visuwesh <visuweshm@gmail.com>:
> [புதன் ஆகஸ்ட் 28, 2024] Robert Pluim wrote:
> 
>> Beauty is in the eye of the beholder:
>> 
>> (when-let ((foo (function-which-may-return-nil)))
>>  (bar foo))
> 
> Not to mention, eldoc does not really work for these threading macros
> which is a real annoyance when trying to read code that heavily uses
> such macros.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 14:08 Elisp threading macros Garklein
  2024-08-28 15:51 ` Robert Pluim
  2024-08-28 15:55 ` Eli Zaretskii
@ 2024-08-28 18:05 ` Philip Kaludercic
  2024-08-28 19:43   ` Garklein
  2024-08-29 21:19   ` Sean Whitton
  2024-08-28 18:29 ` Thierry Volpiatto
                   ` (2 subsequent siblings)
  5 siblings, 2 replies; 24+ messages in thread
From: Philip Kaludercic @ 2024-08-28 18:05 UTC (permalink / raw)
  To: Garklein; +Cc: emacs-devel

Garklein <garklein97@gmail.com> writes:

> Hello,
>
> Would it be possible to have the dash.el macros `->', `->>', `-->',
> and `-some->' in subr-x.el? I find them to be really useful, and would
> love to see them in the base language.
>
> I know that `thread-first' and `thread-last' exist, but I find that my
> eyes can recognize `->' and `->>' much easier. `-->' is really nice
> for more complex threading.

This sounds more like a matter of habit.  FWIW I find a symbol like ->>
or --> very unusual for Elisp.  All in all, there are not that many if I
run this snippet

(mapatoms
 (lambda (sym)
   (when (string-match-p (rx bos (+ (not alnum)) eos)
			 (symbol-name sym))
     (message "Note %S" sym))))

and most of the appear to be part of some DSL like rx, and not Lisp
functions (in my case only 18 out of 57).

> `-some->' is useful in cases like this:

Can you explain what, ->>, --> and -some-> do generally?
>
> (let (foo (function-which-may-return-nil))
>   (when foo
>     (bar foo)))
>
> which can be rewritten, much cleaner, as
>
> (-some-> foo function-which-may-return-nil bar)

[citation needed]

> Thank you,
> Garklein
>
>

-- 
	Philip Kaludercic on peregrine



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 15:55 ` Eli Zaretskii
@ 2024-08-28 18:23   ` Basil L. Contovounesios
  2024-08-31 12:50   ` Augusto Stoffel
  1 sibling, 0 replies; 24+ messages in thread
From: Basil L. Contovounesios @ 2024-08-28 18:23 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Garklein, emacs-devel

Eli Zaretskii [2024-08-28 18:55 +0300] wrote:

>> From: Garklein <garklein97@gmail.com>
>> Date: Wed, 28 Aug 2024 10:08:05 -0400
>> 
>> Would it be possible to have the dash.el macros `->', `->>', `-->',
>> and `-some->' in subr-x.el? I find them to be really useful, and would
>> love to see them in the base language.
>
> We might, but probably not using the names dash.el uses.

Just for context, dash.el inherited these names from the Clojure
programming language.

-- 
Basil



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 14:08 Elisp threading macros Garklein
                   ` (2 preceding siblings ...)
  2024-08-28 18:05 ` Philip Kaludercic
@ 2024-08-28 18:29 ` Thierry Volpiatto
  2024-08-28 19:35   ` Garklein
  2024-08-29  0:48 ` Po Lu
  2024-08-29  5:19 ` Alfred M. Szmidt
  5 siblings, 1 reply; 24+ messages in thread
From: Thierry Volpiatto @ 2024-08-28 18:29 UTC (permalink / raw)
  To: Garklein; +Cc: emacs-devel

Garklein <garklein97@gmail.com> writes:

> Hello,
>
> Would it be possible to have the dash.el macros `->', `->>', `-->',
> and `-some->' in subr-x.el? I find them to be really useful, and would
> love to see them in the base language.

Personally, I have stopped using packages wrote with dash.el, the code is
unreadable, at least for me.
I hope we will not have to suffer of this in Emacs.

> I know that `thread-first' and `thread-last' exist, but I find that my
> eyes can recognize `->' and `->>' much easier. `-->' is really nice
> for more complex threading.
>
> `-some->' is useful in cases like this:
>
> (let (foo (function-which-may-return-nil))
>   (when foo
>     (bar foo)))
>
> which can be rewritten, much cleaner, as
>
> (-some-> foo function-which-may-return-nil bar)

And now we have no idea of what this code does, not speaking of the
diverse ->, --> etc... that are a mystery.

-- 
Thierry



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 18:29 ` Thierry Volpiatto
@ 2024-08-28 19:35   ` Garklein
  2024-08-30 12:26     ` Rudolf Adamkovič
  0 siblings, 1 reply; 24+ messages in thread
From: Garklein @ 2024-08-28 19:35 UTC (permalink / raw)
  To: Thierry Volpiatto; +Cc: emacs-devel

> And now we have no idea of what this code does, not speaking of the
> diverse ->, --> etc... that are a mystery.

To me, the `-some->' form is clearer than the `let'. (I am very happy
to learn about `when-let' though, useful!) I can easily read it left
to right, as if it were English and not code.

I don't see what's so bad about the names `->', `-->' etc. After all,
we commonly use functions with such cryptic names as `car', `cdr', and
`cons'  :)

On Wed, Aug 28, 2024 at 2:25 PM Thierry Volpiatto <thievol@posteo.net> wrote:
>
> Garklein <garklein97@gmail.com> writes:
>
> > Hello,
> >
> > Would it be possible to have the dash.el macros `->', `->>', `-->',
> > and `-some->' in subr-x.el? I find them to be really useful, and would
> > love to see them in the base language.
>
> Personally, I have stopped using packages wrote with dash.el, the code is
> unreadable, at least for me.
> I hope we will not have to suffer of this in Emacs.
>
> > I know that `thread-first' and `thread-last' exist, but I find that my
> > eyes can recognize `->' and `->>' much easier. `-->' is really nice
> > for more complex threading.
> >
> > `-some->' is useful in cases like this:
> >
> > (let (foo (function-which-may-return-nil))
> >   (when foo
> >     (bar foo)))
> >
> > which can be rewritten, much cleaner, as
> >
> > (-some-> foo function-which-may-return-nil bar)
>
> And now we have no idea of what this code does, not speaking of the
> diverse ->, --> etc... that are a mystery.
>
> --
> Thierry



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 18:05 ` Philip Kaludercic
@ 2024-08-28 19:43   ` Garklein
  2024-08-28 19:54     ` Philip Kaludercic
  2024-08-29 21:19   ` Sean Whitton
  1 sibling, 1 reply; 24+ messages in thread
From: Garklein @ 2024-08-28 19:43 UTC (permalink / raw)
  To: Philip Kaludercic; +Cc: emacs-devel

> Can you explain what, ->>, --> and -some-> do generally?

Of course!

`->' takes in a value and a variable amount of forms, "threading" the
value through them by inserting it as the first argument in the first
form, inserting the result of that as the first argument in the next
form, etc.

For example, `(-> foo x (y 3) z)' is equivalent to `(z (y (x foo) 3))'.

`->>' does the same thing, but inserts each value as the last argument
of each form, instead of the first.

`-->' substitutes the symbol `it' in each form as the previous value.
`(-> x (* it it) (+ it 9) (sqrt it))' is equivalent to `(sqrt (+ (* x
x) 9))', and can be read as "take `x', multiply it by itself, add nine
to it, and take its square root".

`-some->' is like `->', except that it will short-circuit the whole
`-some->' expression with `nil' whenever any form returns `nil'.

On Wed, Aug 28, 2024 at 2:05 PM Philip Kaludercic <philipk@posteo.net> wrote:
>
> Garklein <garklein97@gmail.com> writes:
>
> > Hello,
> >
> > Would it be possible to have the dash.el macros `->', `->>', `-->',
> > and `-some->' in subr-x.el? I find them to be really useful, and would
> > love to see them in the base language.
> >
> > I know that `thread-first' and `thread-last' exist, but I find that my
> > eyes can recognize `->' and `->>' much easier. `-->' is really nice
> > for more complex threading.
>
> This sounds more like a matter of habit.  FWIW I find a symbol like ->>
> or --> very unusual for Elisp.  All in all, there are not that many if I
> run this snippet
>
> (mapatoms
>  (lambda (sym)
>    (when (string-match-p (rx bos (+ (not alnum)) eos)
>                          (symbol-name sym))
>      (message "Note %S" sym))))
>
> and most of the appear to be part of some DSL like rx, and not Lisp
> functions (in my case only 18 out of 57).
>
> > `-some->' is useful in cases like this:
>
> Can you explain what, ->>, --> and -some-> do generally?
> >
> > (let (foo (function-which-may-return-nil))
> >   (when foo
> >     (bar foo)))
> >
> > which can be rewritten, much cleaner, as
> >
> > (-some-> foo function-which-may-return-nil bar)
>
> [citation needed]
>
> > Thank you,
> > Garklein
> >
> >
>
> --
>         Philip Kaludercic on peregrine



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 19:43   ` Garklein
@ 2024-08-28 19:54     ` Philip Kaludercic
  2024-08-29  4:45       ` tomas
  0 siblings, 1 reply; 24+ messages in thread
From: Philip Kaludercic @ 2024-08-28 19:54 UTC (permalink / raw)
  To: Garklein; +Cc: emacs-devel

Garklein <garklein97@gmail.com> writes:

>> Can you explain what, ->>, --> and -some-> do generally?
>
> Of course!
>
> `->' takes in a value and a variable amount of forms, "threading" the
> value through them by inserting it as the first argument in the first
> form, inserting the result of that as the first argument in the next
> form, etc.
>
> For example, `(-> foo x (y 3) z)' is equivalent to `(z (y (x foo) 3))'.

Right, this is what we already have with thread-first, right?

> `->>' does the same thing, but inserts each value as the last argument
> of each form, instead of the first.

Oh, I wouldn't have guessed that from the symbol name.

> `-->' substitutes the symbol `it' in each form as the previous value.
> `(-> x (* it it) (+ it 9) (sqrt it))' is equivalent to `(sqrt (+ (* x
> x) 9))', and can be read as "take `x', multiply it by itself, add nine
> to it, and take its square root".

Hmm, anaphoric macros are somewhat controversial they have an even
greater cognitive overhead than every day macros, let alone threading
macros.

> `-some->' is like `->', except that it will short-circuit the whole
> `-some->' expression with `nil' whenever any form returns `nil'.

Here I have to agree with others in the thread that when-let* seems more
maintainable, as it forces the programmer to introduce names that
hopefully indicate what is being done.

---

Generally this seems like a cultural clash between traditional Lisps and
newer languages like Clojure that derive some inspired from Lisps, but
have intentionally broken with the existing "Lisp tradition".
Backporting concepts like these is certainly technically feasible, but
it feels forced and foreign for people like me who don't work with
Closure or related languages.

> On Wed, Aug 28, 2024 at 2:05 PM Philip Kaludercic <philipk@posteo.net> wrote:
>>
>> Garklein <garklein97@gmail.com> writes:
>>
>> > Hello,
>> >
>> > Would it be possible to have the dash.el macros `->', `->>', `-->',
>> > and `-some->' in subr-x.el? I find them to be really useful, and would
>> > love to see them in the base language.
>> >
>> > I know that `thread-first' and `thread-last' exist, but I find that my
>> > eyes can recognize `->' and `->>' much easier. `-->' is really nice
>> > for more complex threading.
>>
>> This sounds more like a matter of habit.  FWIW I find a symbol like ->>
>> or --> very unusual for Elisp.  All in all, there are not that many if I
>> run this snippet
>>
>> (mapatoms
>>  (lambda (sym)
>>    (when (string-match-p (rx bos (+ (not alnum)) eos)
>>                          (symbol-name sym))
>>      (message "Note %S" sym))))
>>
>> and most of the appear to be part of some DSL like rx, and not Lisp
>> functions (in my case only 18 out of 57).
>>
>> > `-some->' is useful in cases like this:
>>
>> Can you explain what, ->>, --> and -some-> do generally?
>> >
>> > (let (foo (function-which-may-return-nil))
>> >   (when foo
>> >     (bar foo)))
>> >
>> > which can be rewritten, much cleaner, as
>> >
>> > (-some-> foo function-which-may-return-nil bar)
>>
>> [citation needed]
>>
>> > Thank you,
>> > Garklein
>> >
>> >
>>
>> --
>>         Philip Kaludercic on peregrine

-- 
	Philip Kaludercic on peregrine



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 14:08 Elisp threading macros Garklein
                   ` (3 preceding siblings ...)
  2024-08-28 18:29 ` Thierry Volpiatto
@ 2024-08-29  0:48 ` Po Lu
  2024-08-29  5:19 ` Alfred M. Szmidt
  5 siblings, 0 replies; 24+ messages in thread
From: Po Lu @ 2024-08-29  0:48 UTC (permalink / raw)
  To: Garklein; +Cc: emacs-devel

Garklein <garklein97@gmail.com> writes:

> Hello,
> `-some->' is useful in cases like this:
>
> (let (foo (function-which-may-return-nil))
>   (when foo
>     (bar foo)))
>
> which can be rewritten, much cleaner, as
>
> (-some-> foo function-which-may-return-nil bar)

I think very few people will agree, but "-some->" is not an acceptable
name for a preloaded function.  Or any function, come to that.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 19:54     ` Philip Kaludercic
@ 2024-08-29  4:45       ` tomas
  2024-08-30  7:30         ` Joost Kremers
  0 siblings, 1 reply; 24+ messages in thread
From: tomas @ 2024-08-29  4:45 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1572 bytes --]

On Wed, Aug 28, 2024 at 07:54:04PM +0000, Philip Kaludercic wrote:

[...]

> Generally this seems like a cultural clash between traditional Lisps and
> newer languages like Clojure that derive some inspired from Lisps, but
> have intentionally broken with the existing "Lisp tradition".
> Backporting concepts like these is certainly technically feasible, but
> it feels forced and foreign for people like me who don't work with
> Closure or related languages.

I think this is a very important point. Emacs Lisp (any language) isn't
"just" a set of rules, but a whole set of applications and a community
(or perhaps a set of interconnected communities) [0]. Each time someone
with big enthusiasm comes along and "hey, let's change everything, this
looks so much better", things tend to degrade into strange identity wars.

On the one hand, you can't just change the whole community "just like that":
people gravitate towards languages for reasons (I must admit I cringe myself
when I see those threaded macros, but then, my excursions into those newer
functional languages have never really worked). Most people are here because
they like things as they are.

On the other hand, for my taste at least, the reactions (my [1] reaction,
at that!) to those ideas feels sometimes more hostile than necessary.

I'd like (for myself!) to have better answers to that.

Cheers

[0] And a means of communication. And of identification. And...
[1] That's why I often shut up in those cases. But hostile silence
   is hostile, too. Oh, well.
-- 
t

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 14:08 Elisp threading macros Garklein
                   ` (4 preceding siblings ...)
  2024-08-29  0:48 ` Po Lu
@ 2024-08-29  5:19 ` Alfred M. Szmidt
  2024-08-30  0:57   ` Garklein
  5 siblings, 1 reply; 24+ messages in thread
From: Alfred M. Szmidt @ 2024-08-29  5:19 UTC (permalink / raw)
  To: Garklein; +Cc: emacs-devel

   `-some->' is useful in cases like this:

   (let (foo (function-which-may-return-nil))
     (when foo
       (bar foo)))

   which can be rewritten, much cleaner, as

   (-some-> foo function-which-may-return-nil bar)

Those two forms aren't the same.  This is the macroexpand-all version:

(let ((result (let ((result foo))
		(if result
		    (progn (function-which-may-return-nil result))))))
  (if result
      (progn (bar result))))

Notice how e.g., function-which-may-return-nil actually gets the foo
argument.  And the semantics are also different.

While the above might seam cleaner, since it is shorter, it is much
harder to modify, maintain and reason about.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 18:05 ` Philip Kaludercic
  2024-08-28 19:43   ` Garklein
@ 2024-08-29 21:19   ` Sean Whitton
  2024-08-29 21:46     ` Philip Kaludercic
  1 sibling, 1 reply; 24+ messages in thread
From: Sean Whitton @ 2024-08-29 21:19 UTC (permalink / raw)
  To: Philip Kaludercic, Garklein, emacs-devel

Hello,

On Wed 28 Aug 2024 at 06:05pm GMT, Philip Kaludercic wrote:

> Garklein <garklein97@gmail.com> writes:
>
>> Hello,
>>
>> Would it be possible to have the dash.el macros `->', `->>', `-->',
>> and `-some->' in subr-x.el? I find them to be really useful, and would
>> love to see them in the base language.
>>
>> I know that `thread-first' and `thread-last' exist, but I find that my
>> eyes can recognize `->' and `->>' much easier. `-->' is really nice
>> for more complex threading.
>
> This sounds more like a matter of habit.  FWIW I find a symbol like ->>
> or --> very unusual for Elisp.  All in all, there are not that many if I
> run this snippet

Right, it's not Elisp/MacLisp/Common Lisp style to use names like that.
Similar to how we use '-q' for predicates, and not '?', like Scheme does.

Elisp is a classic Lisp, which gives it a coherent aesthetic, which
helps with readability, I think.

-- 
Sean Whitton



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-29 21:19   ` Sean Whitton
@ 2024-08-29 21:46     ` Philip Kaludercic
  0 siblings, 0 replies; 24+ messages in thread
From: Philip Kaludercic @ 2024-08-29 21:46 UTC (permalink / raw)
  To: Sean Whitton; +Cc: Garklein, emacs-devel

Sean Whitton <spwhitton@spwhitton.name> writes:

> Hello,
>
> On Wed 28 Aug 2024 at 06:05pm GMT, Philip Kaludercic wrote:
>
>> Garklein <garklein97@gmail.com> writes:
>>
>>> Hello,
>>>
>>> Would it be possible to have the dash.el macros `->', `->>', `-->',
>>> and `-some->' in subr-x.el? I find them to be really useful, and would
>>> love to see them in the base language.
>>>
>>> I know that `thread-first' and `thread-last' exist, but I find that my
>>> eyes can recognize `->' and `->>' much easier. `-->' is really nice
>>> for more complex threading.
>>
>> This sounds more like a matter of habit.  FWIW I find a symbol like ->>
>> or --> very unusual for Elisp.  All in all, there are not that many if I
>> run this snippet
>
> Right, it's not Elisp/MacLisp/Common Lisp style to use names like that.
> Similar to how we use '-q' for predicates, and not '?', like Scheme does.
                         ^
                nitpick: -p

> Elisp is a classic Lisp, which gives it a coherent aesthetic, which
> helps with readability, I think.

I agree!  Elisp might have inconsistencies, but we can try to avoid
adding even more.

-- 
	Philip Kaludercic on peregrine



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-29  5:19 ` Alfred M. Szmidt
@ 2024-08-30  0:57   ` Garklein
  0 siblings, 0 replies; 24+ messages in thread
From: Garklein @ 2024-08-30  0:57 UTC (permalink / raw)
  To: Alfred M. Szmidt; +Cc: emacs-devel

Sorry, you're absolutely right! I had a massive brainfart.

What I meant to write was `(-some-> (function-which-may-return-nil) bar)'

On Thu, Aug 29, 2024 at 1:19 AM Alfred M. Szmidt <ams@gnu.org> wrote:
>
>    `-some->' is useful in cases like this:
>
>    (let (foo (function-which-may-return-nil))
>      (when foo
>        (bar foo)))
>
>    which can be rewritten, much cleaner, as
>
>    (-some-> foo function-which-may-return-nil bar)
>
> Those two forms aren't the same.  This is the macroexpand-all version:
>
> (let ((result (let ((result foo))
>                 (if result
>                     (progn (function-which-may-return-nil result))))))
>   (if result
>       (progn (bar result))))
>
> Notice how e.g., function-which-may-return-nil actually gets the foo
> argument.  And the semantics are also different.
>
> While the above might seam cleaner, since it is shorter, it is much
> harder to modify, maintain and reason about.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-29  4:45       ` tomas
@ 2024-08-30  7:30         ` Joost Kremers
  0 siblings, 0 replies; 24+ messages in thread
From: Joost Kremers @ 2024-08-30  7:30 UTC (permalink / raw)
  To: tomas; +Cc: emacs-devel

On Thu, Aug 29 2024, tomas@tuxteam.de wrote:
> On the one hand, you can't just change the whole community "just like that":
> people gravitate towards languages for reasons (I must admit I cringe myself
> when I see those threaded macros, but then, my excursions into those newer
> functional languages have never really worked). Most people are here because
> they like things as they are.

Yes, I think that's very much the point. It's more a matter of taste than
anything else. And taste for a large part depends on what one is used to.
When I first encountered Clojure, I quite disliked it. And threading
macros? You'd have to be out of your mind to write code like that...

But at some point, I decided to learn Clojure and I must admit, I really
like the language. It's different than Elisp for sure, but things that
irked me initially, I came to like eventually, because I started to see why
they were designed the way they are. (I'd actually love to do more with
Clojure, TBH...)

Still, that doesn't mean I think Elisp should become more like Clojure, of
course. (I'm actually neutral on that point.) I think the current
situation, with the seq library and thread-{first|last} available in core,
and dash.el readily available from GNU ELPA, is a good compromise. (And, to
the OP: from your perspective, probably the "best" you're gonna get. 😉)



-- 
Joost Kremers
Life has its moments



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 19:35   ` Garklein
@ 2024-08-30 12:26     ` Rudolf Adamkovič
  2024-08-30 13:12       ` Robert Pluim
  0 siblings, 1 reply; 24+ messages in thread
From: Rudolf Adamkovič @ 2024-08-30 12:26 UTC (permalink / raw)
  To: Garklein, Thierry Volpiatto; +Cc: emacs-devel

Garklein <garklein97@gmail.com> writes:

> I don't see what's so bad about the names `->', `-->' etc.

I find them cryptic as well (and I say that as a professional Fennel
programmer, using Clojure syntax all day long).

> After all, we commonly use functions with such cryptic names as `car',
> `cdr', and `cons' :)

This is where Emacs Lisp could learn from Clojure and introduce `first',
`next', and `pair' aliases.  Document the new names as preferred and
keep the old "historical curiosities" functional forever.  Of course,
`mapcar' and the like would have to be renamed as well, but all that is
doable if there is a will to move the readability of the "very core" of
Emacs Lisp forward, from 1950s into the 21st century.

Rudy
-- 
"Mathematics takes us still further from what is human into the region
of absolute necessity, to which not only the actual world, but every
possible world, must conform."  --- Bertrand Russell, 1902

Rudolf Adamkovič <rudolf@adamkovic.org> [he/him]
http://adamkovic.org



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-30 12:26     ` Rudolf Adamkovič
@ 2024-08-30 13:12       ` Robert Pluim
  2024-08-30 17:15         ` [External] : " Drew Adams
  0 siblings, 1 reply; 24+ messages in thread
From: Robert Pluim @ 2024-08-30 13:12 UTC (permalink / raw)
  To: Rudolf Adamkovič; +Cc: Garklein, Thierry Volpiatto, emacs-devel

>>>>> On Fri, 30 Aug 2024 14:26:30 +0200, Rudolf Adamkovič <rudolf@adamkovic.org> said:
    Rudolf> This is where Emacs Lisp could learn from Clojure and introduce `first',
    Rudolf> `next', and `pair' aliases.  Document the new names as preferred and
    Rudolf> keep the old "historical curiosities" functional forever.  Of course,
    Rudolf> `mapcar' and the like would have to be renamed as well, but all that is
    Rudolf> doable if there is a will to move the readability of the "very core" of
    Rudolf> Emacs Lisp forward, from 1950s into the 21st century.

emacs lisp already has `first', `rest' and `seq-do' or `dolist'. And
`nth' to replace `caddr' etc.

Robert
-- 



^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: [External] : Re: Elisp threading macros
  2024-08-30 13:12       ` Robert Pluim
@ 2024-08-30 17:15         ` Drew Adams
  2024-09-01 16:43           ` Alfred M. Szmidt
  0 siblings, 1 reply; 24+ messages in thread
From: Drew Adams @ 2024-08-30 17:15 UTC (permalink / raw)
  To: Robert Pluim, Rudolf Adamkovič
  Cc: Garklein, Thierry Volpiatto, emacs-devel@gnu.org

> emacs lisp already has `first', `rest' and
> `seq-do' or `dolist'. And `nth' to replace
> `caddr' etc.

Neither nth nor nthcdr replaces caddr, caar
cdadar, cdddar, etc.  Each of the c[..]r
functions targets a particular part of a
list (tree) in one fell swoop.

And its name is a _picture_ of where that
part is located in the tree.  Direct access,
including mentally/visually.

(Yes, it takes (a little) getting used to.)

That alone is a good reason for not only
keeping car and cdr but having them at the
back of your mind in combination, instead
of just first/rest or head/tails.

Could different chars have been used than
c, a, d, and r?  Of course.  The c and r
aren't needed, and we could have used f for
first and r for rest, or h for head and
t for tails, or | for car and . for cdr, or
- for car and @ for cdr:

 cadaar  =  frff  =  hthh  =  |.||  =  -@--
 caar    =  ff    =  hh    =  ||    =  --
 caaar   =  fff   =  hhh   =  |||   =  ---
 caddar  =  frrf  =  htth  =  |..|  =  -@@-

 cdadar  =  rfrf  =  thth  =  .|.|  =  @-@-
 cdddar  =  rrrf  =  ttth  =  ...|  =  @@@-
 caddr   =  frr   =  htt   =  |..   =  -@@

Or Morse code: .-..  ..  ...  .--.
                L    I    S    P

The point is that there are 2 basic access
functions for the 2 components of a cons,
and accessing their combinations can be
abbreviated in a pictorial way with 2 chars.
___

Of course, no one would suggest that people
should _mostly_ use the more complex c[..]r
abbreviations instead of binding intermediate
vars with meaningful names to uses of smaller
access c[..]r variations (including car/cdr).

Still, when that's not so important, if a
reader is _used_ to the c[..]r pictures, an
occasional (caddar foo) can be handier than
(first (rest (rest (first foo)))) or
(first (nthcdr 1 (first foo))).

IOW, if you're going to use such first/rest
combinations anyway (instead of intermediate
vars), then the c[..]r patterns can be handy
and healthy. ;-)

It kinda depends on what one's used to.

(setq foo  '((1 (2 3) 4 . 5)))

(caar foo)         => 1        ..        I
(caadar foo)       => 2        ..-.      F
(cadar foo)        => (2 3)    .-.       R
(cadr (cadar foo)) => 3        .- (._.)  A(R)
(cddar foo)        => (4 . 5)  --.       G
(caddar foo)       => 4        .--.      P
(cdddar foo)       => 5        ---.      Ó
                                         or O(E)
                                         or M(N)
                                         or T(G)

YMMV.

^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: Elisp threading macros
  2024-08-28 15:55 ` Eli Zaretskii
  2024-08-28 18:23   ` Basil L. Contovounesios
@ 2024-08-31 12:50   ` Augusto Stoffel
  1 sibling, 0 replies; 24+ messages in thread
From: Augusto Stoffel @ 2024-08-31 12:50 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: Garklein, emacs-devel

On Wed, 28 Aug 2024 at 18:55, Eli Zaretskii wrote:

>> From: Garklein <garklein97@gmail.com>
>> Date: Wed, 28 Aug 2024 10:08:05 -0400
>> 
>> Would it be possible to have the dash.el macros `->', `->>', `-->',
>> and `-some->' in subr-x.el? I find them to be really useful, and would
>> love to see them in the base language.
>
> We might, but probably not using the names dash.el uses.

A while back, in bug#56875, I've suggested adding a `thread-as' macro
(like Clojure's -as->).  Given that we already have 2 of the 3 most
useful threading macros, I see no reason not to have the remaining one
(which might in fact be the most useful of all 3).

`-some->` is kinda neat but seems less important to me.



^ permalink raw reply	[flat|nested] 24+ messages in thread

* Re: [External] : Re: Elisp threading macros
  2024-08-30 17:15         ` [External] : " Drew Adams
@ 2024-09-01 16:43           ` Alfred M. Szmidt
  2024-09-01 21:02             ` Drew Adams
  0 siblings, 1 reply; 24+ messages in thread
From: Alfred M. Szmidt @ 2024-09-01 16:43 UTC (permalink / raw)
  To: Drew Adams; +Cc: rpluim, rudolf, garklein97, thievol, emacs-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain, Size: 960 bytes --]

   Could different chars have been used than
   c, a, d, and r?  Of course.  The c and r
   aren't needed, and we could have used f for
   first and r for rest, or h for head and
   t for tails, or | for car and . for cdr, or
   - for car and @ for cdr:

    cadaar  =  frff  =  hthh  =  |.||  =  -@--
    caar    =  ff    =  hh    =  ||    =  --
    caaar   =  fff   =  hhh   =  |||   =  ---
    caddar  =  frrf  =  htth  =  |..|  =  -@@-

    cdadar  =  rfrf  =  thth  =  .|.|  =  @-@-
    cdddar  =  rrrf  =  ttth  =  ...|  =  @@@-
    caddr   =  frr   =  htt   =  |..   =  -@@

How do you pronounce frff? .|.|? or @@@-?

One thing that car, cadr, cdr, cdar .. have going for them is that
they are (semi-)words, with pronounciation rules.  No clue how to
pronounce -some-do-hickey-@-$-> ...  which is immensly useful when
explaning thing, it is much easier to say kə.ˈdɑɹ (CDAR) of a list
then 'the rest of the first' .. or whatever it would become.




^ permalink raw reply	[flat|nested] 24+ messages in thread

* RE: [External] : Re: Elisp threading macros
  2024-09-01 16:43           ` Alfred M. Szmidt
@ 2024-09-01 21:02             ` Drew Adams
  0 siblings, 0 replies; 24+ messages in thread
From: Drew Adams @ 2024-09-01 21:02 UTC (permalink / raw)
  To: Alfred M. Szmidt
  Cc: rpluim@gmail.com, rudolf@adamkovic.org, garklein97@gmail.com,
	thievol@posteo.net, emacs-devel@gnu.org

[-- Attachment #1: Type: text/plain, Size: 1041 bytes --]

>    Could different chars have been used than
>    c, a, d, and r?  Of course.  The c and r
>    aren't needed, and we could have used f for
>    first and r for rest, or h for head and
>    t for tails, or | for car and . for cdr, or
>    - for car and @ for cdr:
> 
>     cadaar  =  frff  =  hthh  =  |.||  =  -@--
>     caar    =  ff    =  hh    =  ||    =  --
>     caaar   =  fff   =  hhh   =  |||   =  ---
>     caddar  =  frrf  =  htth  =  |..|  =  -@@-
> 
>     cdadar  =  rfrf  =  thth  =  .|.|  =  @-@-
>     cdddar  =  rrrf  =  ttth  =  ...|  =  @@@-
>     caddr   =  frr   =  htt   =  |..   =  -@@
> 
> How do you pronounce frff? .|.|? or @@@-?
> 
> One thing that car, cadr, cdr, cdar .. have going for them is that
> they are (semi-)words, with pronounciation rules.  No clue how to
> pronounce -some-do-hickey-@-$-> ...  which is immensly useful when
> explaning thing, it is much easier to say kə.ˈdɑɹ (CDAR) of a list
> then 'the rest of the first' .. or whatever it would become.

;-)

Yes.

[-- Attachment #2: c-icon.gif --]
[-- Type: image/gif, Size: 288 bytes --]

[-- Attachment #3: a-icon.gif --]
[-- Type: image/gif, Size: 282 bytes --]

[-- Attachment #4: d-icon.gif --]
[-- Type: image/gif, Size: 284 bytes --]

[-- Attachment #5: r-icon.gif --]
[-- Type: image/gif, Size: 258 bytes --]

^ permalink raw reply	[flat|nested] 24+ messages in thread

end of thread, other threads:[~2024-09-01 21:02 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-08-28 14:08 Elisp threading macros Garklein
2024-08-28 15:51 ` Robert Pluim
2024-08-28 16:42   ` Visuwesh
2024-08-28 17:13     ` Henrik Kjerringvåg
2024-08-28 15:55 ` Eli Zaretskii
2024-08-28 18:23   ` Basil L. Contovounesios
2024-08-31 12:50   ` Augusto Stoffel
2024-08-28 18:05 ` Philip Kaludercic
2024-08-28 19:43   ` Garklein
2024-08-28 19:54     ` Philip Kaludercic
2024-08-29  4:45       ` tomas
2024-08-30  7:30         ` Joost Kremers
2024-08-29 21:19   ` Sean Whitton
2024-08-29 21:46     ` Philip Kaludercic
2024-08-28 18:29 ` Thierry Volpiatto
2024-08-28 19:35   ` Garklein
2024-08-30 12:26     ` Rudolf Adamkovič
2024-08-30 13:12       ` Robert Pluim
2024-08-30 17:15         ` [External] : " Drew Adams
2024-09-01 16:43           ` Alfred M. Szmidt
2024-09-01 21:02             ` Drew Adams
2024-08-29  0:48 ` Po Lu
2024-08-29  5:19 ` Alfred M. Szmidt
2024-08-30  0:57   ` Garklein

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.