Having control flow statements as expressions in Groovy would feel pretty
natural to me. I had always assumed there were reasons why this was not
supported, so I did not bring it up...I currently use the simulated eval
language extension I proposed for that, i.e.
final foo = eval { if(...) { ... } else if(...) { ... } else if(...) { ... }
else { ... }}
in cases where using "?" would be too complex.
That uses a closure, of course, so not optimal for all applications.
Question: Does a return-statement inside the if-expression leave the
expression, or the enclosing method in Rust ?
Cheers,mg
-------- Ursprüngliche Nachricht --------Von: David Dawson
<[email protected]> Datum: 21.03.18 10:07 (GMT+01:00) An:
[email protected] Betreff: Re: [RFE] Methods as expressions
in Rust, control flow statements are expressions. Partly this was done to
enable the lifetimes to be more concisely controlled, but its a nice structure.
If done in groovy, this would work (toy example, picking the right payment
provider based on a property)
def provider = if(request.name == "paypal") {
paypal()
} else {
other()
}
rather than
def provider
if(request.name == "paypal") {
provider = paypal()
} else {
provider = other()
}
This very quickly becomes natural and makes a certain type of bug harder to
make (assigning the wrong var in one of the branches)
When combined with the method expression syntax, maybe some expressionified
version of the switch syntax (a match?)
class Payments {
Provider provider(request) = switch(request.name) {
case "paypal": paypal()
case "stripe": stripe()
default : fake()
}
}
def provider = new Payments().provider(myPaymentRequest)
// blah
On 21 March 2018 at 08:53, Jochen Theodorou <[email protected]> wrote:
Am 21.03.2018 um 09:27 schrieb Cédric Champeau:
[...]
In any case, I was doubtful as you are here before actually using it in Kotlin.
After a few weeks, it became clear to me this syntax was both more concise and
more self-explanatory.
For me {} was always very clear, for {} starts a new scope, it is a block, that
can return something. I did never even once think about these as expressions.
That is why I really not often speak about closure expressions, but about
attached and open blocks or Closure. And in that matter:
double x
double y
double surface(double x, double y) = x * y
I find it very unclear if the x is the field/property x or the method
parameter. That is because normally = does not create a new scope. And
especially normally = does not allow referencing variables from the left side
declaration. For example:
class X {
def foo = 1
def bar() {
def foo = foo*2
}}
This is allowed in Groovy and Java, because the semantics are very clear. Since
= does not do a forward declaration the local variable foo is not defined on
the RHS. Thus the foo on the RHS can only mean the property/field.
class X {
def foo = 1
def bar(foo) {
def foo = foo*2
}}
This is not allows, because the block already declares a foo and another local
variable of the name foo is not allowed
class X {
def foo = 1
def bar(foo) {
def bar = foo*2
}}
This is allowed and again the semantics are clear, because the parameter is a
local scope that shadows the class scope, thus in the declaration of bar the
foo in RHS means the foo from the method parameter.
double surface(double x, double y) = x * y
breaks with the former declaration and scoping logic. You can try rescue this
by saying the = in the method declaration has nothing to do with the = in a
declaration or assignment otherwise. But if I always have to do the expansion
to the other version to understand what happens, then it is not easier for me.
On top of that I am a real bad fit for this style, because except for demo
purposes I rarely write methods that contains only a single line of code. Maybe
you could show real world examples that show the real coolness of this?
bye Jochen