Discussion:
[rust-dev] Rationale on if let
Michael Giagnocavo
2014-10-13 05:41:09 UTC
Permalink
I came across the "if let" syntax, and it's been bothering me a bit.

It seems like a strange thing to elevate to a grammar-level construct.

The example given is:
if let Some(x) = foo() {
doSomethingWith(x)
}

What's wrong with e.g.:

foo().if_some!(|x| { doSomethingWith(x) })?

Can macros not step in here and allow us to write code that looks like a
closure but doesn't actually create a closure or cost any overhead?
(In fact, is a macro even needed? Couldn't a function and it's function
parameters be marked for inlining - wouldn't that take care of it?) This
seems like a handy thing to have in general. I've written code in other
languages where I want the emitted code to be as if I wrote it as a
single function with branches, but want to express it with lambdas
and function calls.

If neither inlining nor macros can handle this, would it not be better
to improve those features, instead of tacking on odd bits of grammar?

I love more features and expressiveness but "if let" seems like
something that shouldn't be baked into the compiler (even if Swift does it).

I'm honestly asking this question, because the Rust team seems to have
pretty good sense and reasoning, so I'm probably misunderstanding something
and would like to know what I'm missing.

Sincerely,
Michael
Steven Fackler
2014-10-13 05:52:34 UTC
Permalink
`if let` acts on *any* refutable pattern, not just `Option`s. The RFC that
proposed the syntax is a good place to look for the rationale of why it was
added: https://github.com/rust-lang/rfcs/pull/160

Steven Fackler

On Sun, Oct 12, 2014 at 10:41 PM, Michael Giagnocavo <mgg at giagnocavo.net>
Post by Michael Giagnocavo
I came across the "if let" syntax, and it's been bothering me a bit.
It seems like a strange thing to elevate to a grammar-level construct.
if let Some(x) = foo() {
doSomethingWith(x)
}
foo().if_some!(|x| { doSomethingWith(x) })?
Can macros not step in here and allow us to write code that looks like a
closure but doesn't actually create a closure or cost any overhead?
(In fact, is a macro even needed? Couldn't a function and it's function
parameters be marked for inlining - wouldn't that take care of it?) This
seems like a handy thing to have in general. I've written code in other
languages where I want the emitted code to be as if I wrote it as a
single function with branches, but want to express it with lambdas
and function calls.
If neither inlining nor macros can handle this, would it not be better
to improve those features, instead of tacking on odd bits of grammar?
I love more features and expressiveness but "if let" seems like
something that shouldn't be baked into the compiler (even if Swift does it).
I'm honestly asking this question, because the Rust team seems to have
pretty good sense and reasoning, so I'm probably misunderstanding something
and would like to know what I'm missing.
Sincerely,
Michael
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20141012/7bb904c1/attachment.html>
Michael Giagnocavo
2014-10-14 15:40:44 UTC
Permalink
The RFC only shows examples with optionals, and Swift, which is the inspiration(?) for this only allows it with optionals. I suppose it might also be useful in matching e.g. lists.

I didn?t see where the RFC states why special grammar is needed, over a closure-like syntax. Just curious.

-Michael

From: Steven Fackler [mailto:sfackler at gmail.com]
Sent: Sunday, October 12, 2014 11:53 PM
To: Michael Giagnocavo
Cc: Rust-dev at mozilla.org
Subject: Re: [rust-dev] Rationale on if let

`if let` acts on *any* refutable pattern, not just `Option`s. The RFC that proposed the syntax is a good place to look for the rationale of why it was added:?https://github.com/rust-lang/rfcs/pull/160


Steven Fackler

On Sun, Oct 12, 2014 at 10:41 PM, Michael Giagnocavo <mgg at giagnocavo.net> wrote:
I came across the "if let" syntax, and it's been bothering me a bit.

It seems like a strange thing to elevate to a grammar-level construct.

The example given is:
if let Some(x) = foo() {
? ? doSomethingWith(x)
}

What's wrong with e.g.:

foo().if_some!(|x| { doSomethingWith(x) })?

Can macros not step in here and allow us to write code that looks like a
closure but doesn't actually create a closure or cost any overhead?
(In fact, is a macro even needed? Couldn't a function and it's function
parameters be marked for inlining - wouldn't that take care of it?) This
seems like a handy thing to have in general. I've written code in other
languages where I want the emitted code to be as if I wrote it as a
single function with branches, but want to express it with lambdas
and function calls.

If neither inlining nor macros can handle this, would it not be better
to improve those features, instead of tacking on odd bits of grammar?

I love more features and expressiveness but "if let" seems like
something that shouldn't be baked into the compiler (even if Swift does it).

I'm honestly asking this question, because the Rust team seems to have
pretty good sense and reasoning, so I'm probably misunderstanding something
and would like to know what I'm missing.

Sincerely,
Michael
Steven Fackler
2014-10-14 16:05:56 UTC
Permalink
A special grammar is not necessary:
```
if let Foo(bar) = baz() {
bar.process();
}
``
is equivalent to
```
match baz() {
Foo(bar) => bar.process(),
_ => {}
}
```
Similarly, `for` and `while` loops do not require a special grammar, since
they can be emulated with `loop`:
```
while thing {
do_bar();
}
```
is equivalent to
```
loop {
if !thing {
break;
}

do_bar();
}
```

We judged that the convenience of the `if let` syntax justified its
inclusion in the language, just like `for` and `while`.


Steven Fackler

On Tue, Oct 14, 2014 at 8:40 AM, Michael Giagnocavo <mgg at giagnocavo.net>
Post by Michael Giagnocavo
The RFC only shows examples with optionals, and Swift, which is the
inspiration(?) for this only allows it with optionals. I suppose it might
also be useful in matching e.g. lists.
I didn?t see where the RFC states why special grammar is needed, over a
closure-like syntax. Just curious.
-Michael
From: Steven Fackler [mailto:sfackler at gmail.com]
Sent: Sunday, October 12, 2014 11:53 PM
To: Michael Giagnocavo
Cc: Rust-dev at mozilla.org
Subject: Re: [rust-dev] Rationale on if let
`if let` acts on *any* refutable pattern, not just `Option`s. The RFC that
proposed the syntax is a good place to look for the rationale of why it was
added: https://github.com/rust-lang/rfcs/pull/160
Steven Fackler
I came across the "if let" syntax, and it's been bothering me a bit.
It seems like a strange thing to elevate to a grammar-level construct.
if let Some(x) = foo() {
doSomethingWith(x)
}
foo().if_some!(|x| { doSomethingWith(x) })?
Can macros not step in here and allow us to write code that looks like a
closure but doesn't actually create a closure or cost any overhead?
(In fact, is a macro even needed? Couldn't a function and it's function
parameters be marked for inlining - wouldn't that take care of it?) This
seems like a handy thing to have in general. I've written code in other
languages where I want the emitted code to be as if I wrote it as a
single function with branches, but want to express it with lambdas
and function calls.
If neither inlining nor macros can handle this, would it not be better
to improve those features, instead of tacking on odd bits of grammar?
I love more features and expressiveness but "if let" seems like
something that shouldn't be baked into the compiler (even if Swift does it).
I'm honestly asking this question, because the Rust team seems to have
pretty good sense and reasoning, so I'm probably misunderstanding something
and would like to know what I'm missing.
Sincerely,
Michael
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/rust-dev/attachments/20141014/a6124b75/attachment.html>
Diggory Hardy
2014-10-15 08:53:37 UTC
Permalink
It was the nesting "else" cases that got me. See
https://github.com/dhardy/rfcs/blob/master/active/0000-with-else.md for some
more examples (slightly different syntax). The equivalent with match is ugly
and I suspect closures would be no better.
Post by Steven Fackler
```
if let Foo(bar) = baz() {
bar.process();
}
``
is equivalent to
```
match baz() {
Foo(bar) => bar.process(),
_ => {}
}
```
Similarly, `for` and `while` loops do not require a special grammar, since
```
while thing {
do_bar();
}
```
is equivalent to
```
loop {
if !thing {
break;
}
do_bar();
}
```
We judged that the convenience of the `if let` syntax justified its
inclusion in the language, just like `for` and `while`.
Steven Fackler
On Tue, Oct 14, 2014 at 8:40 AM, Michael Giagnocavo <mgg at giagnocavo.net>
Post by Michael Giagnocavo
The RFC only shows examples with optionals, and Swift, which is the
inspiration(?) for this only allows it with optionals. I suppose it might
also be useful in matching e.g. lists.
I didn?t see where the RFC states why special grammar is needed, over a
closure-like syntax. Just curious.
-Michael
From: Steven Fackler [mailto:sfackler at gmail.com]
Sent: Sunday, October 12, 2014 11:53 PM
To: Michael Giagnocavo
Cc: Rust-dev at mozilla.org
Subject: Re: [rust-dev] Rationale on if let
`if let` acts on *any* refutable pattern, not just `Option`s. The RFC that
proposed the syntax is a good place to look for the rationale of why it was
added: https://github.com/rust-lang/rfcs/pull/160
Steven Fackler
I came across the "if let" syntax, and it's been bothering me a bit.
It seems like a strange thing to elevate to a grammar-level construct.
if let Some(x) = foo() {
doSomethingWith(x)
}
foo().if_some!(|x| { doSomethingWith(x) })?
Can macros not step in here and allow us to write code that looks like a
closure but doesn't actually create a closure or cost any overhead?
(In fact, is a macro even needed? Couldn't a function and it's function
parameters be marked for inlining - wouldn't that take care of it?) This
seems like a handy thing to have in general. I've written code in other
languages where I want the emitted code to be as if I wrote it as a
single function with branches, but want to express it with lambdas
and function calls.
If neither inlining nor macros can handle this, would it not be better
to improve those features, instead of tacking on odd bits of grammar?
I love more features and expressiveness but "if let" seems like
something that shouldn't be baked into the compiler (even if Swift does it).
I'm honestly asking this question, because the Rust team seems to have
pretty good sense and reasoning, so I'm probably misunderstanding something
and would like to know what I'm missing.
Sincerely,
Michael
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
_______________________________________________
Rust-dev mailing list
Rust-dev at mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
Paul Colomiets
2014-10-13 09:00:13 UTC
Permalink
Hi Michael,
Post by Michael Giagnocavo
I came across the "if let" syntax, and it's been bothering me a bit.
It seems like a strange thing to elevate to a grammar-level construct.
if let Some(x) = foo() {
doSomethingWith(x)
}
foo().if_some!(|x| { doSomethingWith(x) })?
At least you cant "break" or "return" (from outer function). Also
borrow rules sometimes are more complex when using closure.

--
Paul
Michael Giagnocavo
2014-10-14 15:40:42 UTC
Permalink
Post by Michael Giagnocavo
foo().if_some!(|x| { doSomethingWith(x) })?
At least you cant "break" or "return" (from outer function). Also borrow
rules sometimes are more complex when using closure.

Good point; I forgot about flow control.

But this makes me ask: Should there be a way to inline functions including
closure arguments? That'd not only be a performance improvement (from
empirical work with other languages inlining) but allow a lot of
flexibility. It'd allow the syntax of closures, without any tradeoffs.

-Michael
Loading...