* if-let and when-let: parallel or sequential
@ 2014-08-10 2:44 John Mastro
2014-08-10 15:22 ` Stefan Monnier
0 siblings, 1 reply; 11+ messages in thread
From: John Mastro @ 2014-08-10 2:44 UTC (permalink / raw)
To: emacs-devel
Hi,
I noticed that the new `if-let' and `when-let' in trunk's subr-x create
their bindings sequentially (like `let*' rather than `let'). Would there
be any interest in renaming these to `if-let*' and `when-let*', and
adding parallel-binding versions under the current names?
It's obviously a tiny matter in the scheme of things, but I do think
it's worth sticking to the existing naming convention given the history
and context.
(If this change would be welcome, and nobody beats me to it, I would be
happy to submit a patch and copyright assignment.)
Thanks
--
John Mastro
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-10 2:44 if-let and when-let: parallel or sequential John Mastro
@ 2014-08-10 15:22 ` Stefan Monnier
2014-08-11 12:01 ` Bozhidar Batsov
0 siblings, 1 reply; 11+ messages in thread
From: Stefan Monnier @ 2014-08-10 15:22 UTC (permalink / raw)
To: John Mastro; +Cc: emacs-devel
> I noticed that the new `if-let' and `when-let' in trunk's subr-x create
> their bindings sequentially (like `let*' rather than `let'). Would there
> be any interest in renaming these to `if-let*' and `when-let*', and
> adding parallel-binding versions under the current names?
I have a hard time imagining a situation where the "parallel" version
would be useful.
Stefan
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-10 15:22 ` Stefan Monnier
@ 2014-08-11 12:01 ` Bozhidar Batsov
2014-08-11 14:42 ` Stefan Monnier
0 siblings, 1 reply; 11+ messages in thread
From: Bozhidar Batsov @ 2014-08-11 12:01 UTC (permalink / raw)
To: Stefan Monnier, John Mastro; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 836 bytes --]
On August 10, 2014 at 6:23:25 PM, Stefan Monnier (monnier@iro.umontreal.ca) wrote:
> I noticed that the new `if-let' and `when-let' in trunk's subr-x create
> their bindings sequentially (like `let*' rather than `let'). Would there
> be any interest in renaming these to `if-let*' and `when-let*', and
> adding parallel-binding versions under the current names?
I have a hard time imagining a situation where the "parallel" version
would be useful.
Stefan
if-let and when-let don’t make much sense with more than one binding form. Other lisps (like Clojure) would raise
an exception if you try to bind more than a single form.
;; good
(if-let ((x (something)))
…)
;; error
(if-let ((x (something))
(y (something-else)))
…)
I’d suggest we do the same.
[-- Attachment #2: Type: text/html, Size: 1547 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-11 12:01 ` Bozhidar Batsov
@ 2014-08-11 14:42 ` Stefan Monnier
2014-08-11 16:40 ` Harald Hanche-Olsen
` (3 more replies)
0 siblings, 4 replies; 11+ messages in thread
From: Stefan Monnier @ 2014-08-11 14:42 UTC (permalink / raw)
To: Bozhidar Batsov; +Cc: John Mastro, emacs-devel
> if-let and when-let don’t make much sense with more than one binding
> form.
Why do you think so? If they only work for a single binding, the
benefit is really minor. It's only when you use several bindings that
the benefit becomes more significant (the alternative being either
a very deeply nested code, or separating the var's declarations from
their initialization).
Stefan
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-11 14:42 ` Stefan Monnier
@ 2014-08-11 16:40 ` Harald Hanche-Olsen
2014-08-11 17:49 ` Bozhidar Batsov
` (2 subsequent siblings)
3 siblings, 0 replies; 11+ messages in thread
From: Harald Hanche-Olsen @ 2014-08-11 16:40 UTC (permalink / raw)
To: monnier; +Cc: john.b.mastro, bozhidar.batsov, emacs-devel
[Stefan Monnier <monnier@iro.umontreal.ca> (2014-08-11 14:42:19 UTC)]
> > if-let and when-let don’t make much sense with more than one binding
> > form.
>
> Why do you think so? If they only work for a single binding, the
> benefit is really minor. It's only when you use several bindings that
> the benefit becomes more significant (the alternative being either
> a very deeply nested code, or separating the var's declarations from
> their initialization).
Indeed, it looks useful. But may I point out that the docstring seems
deficient? From the source code, I see that the the evaluation
short-circuits, so that evaluating
(defun foo () (insert "called foo\n") nil)
(defun bar () (insert "called bar\n") t)
(if-let ((FOO (foo))
(BAR (bar)))
(insert "aye\n")
(insert (format "nope: %s\n" BAR)))
produces
called foo
nope: nil
I can see how that is useful, but it needs to be documented better.
I'm afraid the resulting docstring may end up longer than the code,
but then so be it.
– Harald
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-11 14:42 ` Stefan Monnier
2014-08-11 16:40 ` Harald Hanche-Olsen
@ 2014-08-11 17:49 ` Bozhidar Batsov
2014-08-11 20:55 ` Harald Hanche-Olsen
2014-08-12 2:43 ` Lars Magne Ingebrigtsen
2014-08-12 3:15 ` Richard Stallman
3 siblings, 1 reply; 11+ messages in thread
From: Bozhidar Batsov @ 2014-08-11 17:49 UTC (permalink / raw)
To: Stefan Monnier; +Cc: John Mastro, emacs-devel
[-- Attachment #1: Type: text/plain, Size: 1098 bytes --]
On August 11, 2014 at 17:42:20, Stefan Monnier (monnier@iro.umontreal.ca) wrote:
> if-let and when-let don’t make much sense with more than one binding
> form.
Why do you think so? If they only work for a single binding, the
benefit is really minor. It's only when you use several bindings that
the benefit becomes more significant (the alternative being either
a very deeply nested code, or separating the var's declarations from
their initialization).
Stefan
Practically speaking, the most common case people run into is checking whether a single object is nil
and binding it to some local if it’s not. Binding multiple locals in such a form reduces the clarity of the code because the
semantics are not that clear anymore - should all the forms produce non-nil or should only the first form produce non-nil? Obviously
people can (and should) read the documentation, but I’m a huge believer in intuitive APIs. That said, I’m fine with whatever
behavior you decide upon, as I believe those functions are valuable additions regardless.
[-- Attachment #2: Type: text/html, Size: 2429 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-11 17:49 ` Bozhidar Batsov
@ 2014-08-11 20:55 ` Harald Hanche-Olsen
0 siblings, 0 replies; 11+ messages in thread
From: Harald Hanche-Olsen @ 2014-08-11 20:55 UTC (permalink / raw)
To: bozhidar.batsov; +Cc: john.b.mastro, monnier, emacs-devel
[Bozhidar Batsov <bozhidar.batsov@gmail.com> (2014-08-11 17:49:29 UTC)]
> Binding multiple locals in such a form reduces the clarity of the
> code because the semantics are not that clear anymore - should all
> the forms produce non-nil or should only the first form produce
> non-nil?
This is a valid point, I think. The macros need better nams.
I suggest if-every-let and when-every-let to make it clearer.
There, that's enough bikeshedding for one day.
I'll go back to lurking now.
– Harald
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-11 14:42 ` Stefan Monnier
2014-08-11 16:40 ` Harald Hanche-Olsen
2014-08-11 17:49 ` Bozhidar Batsov
@ 2014-08-12 2:43 ` Lars Magne Ingebrigtsen
2014-08-12 3:15 ` Richard Stallman
3 siblings, 0 replies; 11+ messages in thread
From: Lars Magne Ingebrigtsen @ 2014-08-12 2:43 UTC (permalink / raw)
To: Stefan Monnier; +Cc: emacs-devel
Stefan Monnier <monnier@iro.umontreal.ca> writes:
> Why do you think so? If they only work for a single binding, the
> benefit is really minor. It's only when you use several bindings that
> the benefit becomes more significant (the alternative being either
> a very deeply nested code, or separating the var's declarations from
> their initialization).
I use lw:when-let all the time in Common Lisp. It only takes a single
binding. I find it very clear and nice -- mostly used as a kinda "early
return" thing, but without the return.
(defun foo (zot)
(when-let (bar (compute-something zot))
...))
I grepped through a random directory in our code base, and out of 146
uses of when-let, 6 had nested when-lets.
There's lw:when-let*, though, which is like Emacs' when-let (i.e.,
several bindings), which is used two times.
Anyway, I think Emacs' when-let is a good addition as it is now. Even
if the multiple-let-binding version doesn't get used much, it's nice
when you need it.
--
(domestic pets only, the antidote for overdose, milk.)
bloggy blog: http://lars.ingebrigtsen.no
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-11 14:42 ` Stefan Monnier
` (2 preceding siblings ...)
2014-08-12 2:43 ` Lars Magne Ingebrigtsen
@ 2014-08-12 3:15 ` Richard Stallman
2014-08-12 3:30 ` John Mastro
3 siblings, 1 reply; 11+ messages in thread
From: Richard Stallman @ 2014-08-12 3:15 UTC (permalink / raw)
To: Stefan Monnier; +Cc: john.b.mastro, bozhidar.batsov, emacs-devel
[[[ To any NSA and FBI agents reading my email: please consider ]]]
[[[ whether defending the US Constitution against all enemies, ]]]
[[[ foreign or domestic, requires you to follow Snowden's example. ]]]
> if-let and when-let don t make much sense with more than one binding
> form.
Why do you think so? If they only work for a single binding, the
benefit is really minor. It's only when you use several bindings that
the benefit becomes more significant (the alternative being either
a very deeply nested code, or separating the var's declarations from
their initialization).
With several sequential bindings, the alternative is
(let* ...bindings...
(if ...))
Thus, if-let saves just one level of nesting
even if there are several bindings.
--
Dr Richard Stallman
President, Free Software Foundation
51 Franklin St
Boston MA 02110
USA
www.fsf.org www.gnu.org
Skype: No way! That's nonfree (freedom-denying) software.
Use Ekiga or an ordinary phone call.
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-12 3:15 ` Richard Stallman
@ 2014-08-12 3:30 ` John Mastro
2014-08-12 14:32 ` Elias Mårtenson
0 siblings, 1 reply; 11+ messages in thread
From: John Mastro @ 2014-08-12 3:30 UTC (permalink / raw)
To: emacs-devel
Richard Stallman <rms@gnu.org> wrote:
> With several sequential bindings, the alternative is
>
> (let* ...bindings...
> (if ...))
>
> Thus, if-let saves just one level of nesting
> even if there are several bindings.
The current implementation in trunk is actually short-circuiting. So the
equivalent to:
(when-let ((a (foo))
(b (bar)))
b)
Would be:
(let ((a (foo)))
(when a
(let ((b (bar)))
b)))
And so on.
The only non-Clojure variant of these that I'm really familiar with is
Alexandria's[1]. It has both `-let' and `-let*' versions, allows
multiple bindings, and is not short circuiting. (I don't say this to
suggest we should mimic them, just to expose "where I'm coming from").
Anyway, I agree with Bozhidar that they'll be nice to have regardless of
the particulars, so I'll gracefully bow out :)
[1] http://common-lisp.net/gitweb?p=projects/alexandria/alexandria.git;a=blob;f=binding.lisp
--
john
^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: if-let and when-let: parallel or sequential
2014-08-12 3:30 ` John Mastro
@ 2014-08-12 14:32 ` Elias Mårtenson
0 siblings, 0 replies; 11+ messages in thread
From: Elias Mårtenson @ 2014-08-12 14:32 UTC (permalink / raw)
To: John Mastro; +Cc: emacs-devel
[-- Attachment #1: Type: text/plain, Size: 451 bytes --]
On 12 August 2014 11:30, John Mastro <john.b.mastro@gmail.com> wrote:
The only non-Clojure variant of these that I'm really familiar with is
> Alexandria's[1]. It has both `-let' and `-let*' versions, allows
> multiple bindings, and is not short circuiting. (I don't say this to
> suggest we should mimic them, just to expose "where I'm coming from").
>
Actually, in Alexandria, WHEN-LET is not short-circuiting, while WHEN-LET*
is.
Regards,
Elias
[-- Attachment #2: Type: text/html, Size: 890 bytes --]
^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2014-08-12 14:32 UTC | newest]
Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-08-10 2:44 if-let and when-let: parallel or sequential John Mastro
2014-08-10 15:22 ` Stefan Monnier
2014-08-11 12:01 ` Bozhidar Batsov
2014-08-11 14:42 ` Stefan Monnier
2014-08-11 16:40 ` Harald Hanche-Olsen
2014-08-11 17:49 ` Bozhidar Batsov
2014-08-11 20:55 ` Harald Hanche-Olsen
2014-08-12 2:43 ` Lars Magne Ingebrigtsen
2014-08-12 3:15 ` Richard Stallman
2014-08-12 3:30 ` John Mastro
2014-08-12 14:32 ` Elias Mårtenson
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
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).