Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

please allow value definitions before the first generator in a for comprehension #907

Closed
scabug opened this issue May 14, 2008 · 18 comments
Closed

Comments

@scabug
Copy link

scabug commented May 14, 2008

I would like to be able to write this:

for{x = foo(bar); y <- x} ...

the language spec (6.19) says "An enumerator sequence always starts with
a generator", but why? From time to time I would find it convenient to put
a value definition first. I realize that in the above code I only use x once,
but I've hit this in real code where I want to use x more than once.

(Perhaps "if" should be allowed too?)

@scabug
Copy link
Author

scabug commented May 14, 2008

Imported From: https://issues.scala-lang.org/browse/SI-907?orig=1
Reporter: @SethTisue

@scabug
Copy link
Author

scabug commented Feb 19, 2009

@paulp said:
While I agree with the sentiment on an aesthetic level, the overhead of such a change (in implementation and testing as well as updating the language spec, documentation, and etc.) has been deemed too high to justify it, as the known use cases are marginal. So I'm closing this as wontfix, but please update the ticket if you come across a compelling motivation.

@scabug scabug closed this as completed May 18, 2011
@scabug
Copy link
Author

scabug commented Dec 11, 2016

@som-snytt said:
It's pretty compelling that Seth is now in a position to do whatever he likes with a three-digit issue.

@scabug
Copy link
Author

scabug commented Apr 2, 2017

Samuel Halliday (fommil) said:
Is there any reason this couldn't be implemented as a parser rewrite to move the value definition out of the for?

e.g. rewrite Seth's original example as

val x = foo(bar)
for {y <- x}

@fommil
Copy link

fommil commented Apr 25, 2017

I'd really like to see this ticket reopened.

@jvican
Copy link
Member

jvican commented Apr 25, 2017

I'm not sure this workaround:

val x = foo(bar)
for {y <- x}

is worth it. I think we have already enough desugarings in parser. Putting more would force all the Scala tooling to catch up and I don't think it's a neat solution overall, but rather a hack.

@fommil
Copy link

fommil commented Apr 25, 2017

for FP code this is definitely worth it. This comes up all the time when for is your main language structure for sequential code.

@fommil
Copy link

fommil commented Apr 25, 2017

btw, apparently we should be discussing at https://contributors.scala-lang.org/t/ressurrect-assignment-as-first-line-of-for/808

@SethTisue
Copy link
Member

it appears this was closed because the core team at the time didn't intend to tackle it, not because it would necessarily be rejected if it came in as a community contribution (including the necessary spec work and so forth)

@SethTisue SethTisue reopened this May 9, 2017
@SethTisue
Copy link
Member

an example usage with Future via @viktorklang: https://twitter.com/viktorklang/status/861982357800308737

@SethTisue
Copy link
Member

further food for thought in this area at https://contributors.scala-lang.org/t/pre-sip-let-expressions-in-scala/1391/1

@SethTisue
Copy link
Member

@nafg
Copy link

nafg commented Aug 28, 2022

I would like to go even further and allow for comprehensions with only value definitions and no generators. It would be like defining a bunch of vals without having to write val each time.

One of the really nice things about Scala is that changing code in a limited way often involves few edits. For instance to change a binding from immediately-evaluate-once to deferred-evaluate-every-time you just change val to def while in say Java you'd have to change a whole bunch of syntax (add parentheses, curly braces, and return). To make a function's scope persist (a.k.a. change a method to a class) is a bit more work but not nearly as much as in say Java, because it's still basically just keyword-name-arguments-body. And so on.

Additionally, most constructs don't have a very strict, conservative set of ways to apply it. Constructs are usually limited only for very good reasons. For instance you can nest methods inside classes inside pattern matches etc. Vals can have block statements on their right-hand side. And there isn't different syntax for class members vs. local bindings.

Together this means that you can take a more "agile" approach to writing code, not worrying up front what form things will take because you can easily evolve code over time with little effort.

By the same token, to me it makes sense that since for comprehension already supports value definitions, there's no good reason to prohibit them as the first item. And once you accept that, there's no good reason to require it to be followed by a generator.

Because suppose you're editing a for comprehension and you end up deleting the first generator, which has value definitions after it. As it is, now you may have to suddenly create curly braces around it and move the definitions there and add the val keyword. There's no reason to force that busy work when the meaning is clear.

And if you do that, then by the same token if later you delete the subsequent generator, leaving only value definitions, there's no reason the compiler has to force the busy work of converting all the value definitions to explicit vals.

As an added bonus, there are contexts where using for to define a bunch of bindings without val would make a lot of sense and make the code more readable.

@fommil
Copy link

fommil commented Sep 6, 2022

Naftoli touches a zombie thread

@som-snytt
Copy link

came up again at https://contributors.scala-lang.org/t/pre-sip-comprehensive-function-applications/5902/12

where initial args are precomputed.

@SethTisue
Copy link
Member

closing since this would need to happen in Scala 3 first before we could do it here

@SethTisue SethTisue removed this from the Backlog milestone Oct 17, 2023
@som-snytt
Copy link

Closing because the ticket has 22 thumbs-up, which is the limit for Scala 2.

Since it is an enhancement, not a bug, feature proposals with implementations and backports are always welcome.

@som-snytt som-snytt closed this as not planned Won't fix, can't repro, duplicate, stale Oct 18, 2023
@SethTisue
Copy link
Member

scala/improvement-proposals#79 proposes to fix this in Scala 3

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants