Wednesday, 30 April 2014

New conditional expressions in Groovy

Many times I've heard someone to say it would be great to have some more control expressions. The good thing in Groovy is that because its syntax you can build your own expressions like if they were already part of the language.

I've created a couple of my own inspired by some other languages out there:

Unless


Unless is a typical expression in other languages like Ruby and sometimes in Groovy it's just annoying to use the not operator. Let's say for example we had this piece of code:

if (!companyIsBankrupt) {
     invest()
}

Wouldn't be nicer to see...

unless(companyIsBankrupt()) {
     invest()
}

Of course it may depend on the context but I think is more readable and clearer than the first attempt. Also this expression not only serves as conditional but because it's been implemented as a method it could return a value, so the latest example could become:
def investment = unless(companyIsBankrupt()) {
     invest()
}

Where


This expression is more complex because it has an internal state and more embedded conditional expressions. It is inspired by the where expression in Haskell.

check(weight: 60) {
    when { weight <= underweight } then { "You're underweight" }
    when { weight <= normal }      then { "You're normal" }
    when { weight <= fat }         then { "You're fat" }
    otherwise { "You have a strange composition" }
    where {
       underweight = 50
       normal = 70
       fat  = 90
    }
}


You can initialize the whole expression with a map and then use the when-then branches to execute the right one taking into account set values within the where clause.

When-then clauses are half way between if-else expressions and switch-case expressions but there is something unique about this type of expression, pre-set values within the scope of the expression and shared among all when-then expressions.

My initial implementation is still a proof of concep and still lacks of some desirable constraints:
  • Initialization values at check() method should be immutable values
  • Values created within the where block should be immutable too
I forgot to mention that the same way unless expression could return a value this check-where expression can do it as well so it won't be any problem to assign the execution of the where clause to a given variable:
def message = check(weight: 60) {
    when { weight <= underweight } then { "You're underweight" }
    when { weight <= normal }      then { "You're normal" }
    when { weight <= fat }         then { "You're fat" }
    otherwise { "You have a strange composition" }
    where {
       underweight = 50
       normal = 70
       fat  = 90
    }
}

Resources


6 comments:

  1. That's neat!

    Although I wouldn't call them expressions, right? According to your description, they are just convenience "functions" (aka static methods :) added to the default language APIs... aren't they?

    ReplyDelete
    Replies
    1. I'm stupid enough to have read your post in a way that I understood it as "new expressions added to the language" rather than "I implemented methods for new expressions I'd like to see" :-/ rush is never a good adviser...

      Delete
  2. No worries. Maybe I should have been more concise. You're right they're methods acting like expressions but not expressions in a formal way. Still you can use them to control the flow of your code as if they were actually control structures.

    Thanks for the feedback :)

    ReplyDelete
  3. Yep, to be honest I'd rather have more expressions built the way you did with the two proposed methods - I'm more fond of languages with a small grammar and a powerful API built on top of it than of languages with dozens of reserved words :-).

    It is that since I was mistaken about the origin of the expressions, I wanted to be sure they were just methods. When I realized they were provided by your own library it was clear there were methods (I'm assuming here that you can't add "native" expressions to groovy, but maybe I'm mistaken again... I hope not :-D).

    ReplyDelete
  4. This content is really too useful and has got more ideas from your blog. Keep sharing more blogs like this thank you.................. R12 Project Accounting Training

    ReplyDelete
  5. I truly like reading this article because it is really beneficial to us. It provides useful information.
    Oracle Fusion Financials Training

    ReplyDelete