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 
<david.daw...@simplicityitself.com> Datum: 21.03.18  10:07  (GMT+01:00) An: 
dev@groovy.apache.org 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 <blackd...@gmx.org> 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







Reply via email to