Val vs var?

Hi.
I feel stupid having to ask this, but what is the difference between “val” and “var” in rules files? I see sometimes variables being declared with val and sometimes with var and I can’t seem to find the logic in it…

2 Likes

var = varible
val=value
A “val” is final meaning once you set it to somthing you can never change it.

4 Likes

If you want to learn more about the details: https://www.eclipse.org/xtend/documentation/203_xtend_expressions.html#variable-declaration

1 Like

Never stupid, it is actually a very important distinction.

I’ll elaborate on opus’s answer to try and make it make sense for non-programmers.

When one wants to create a name to store a value one creates a variable. In the Rules Domain Specific Language (DSL) this is done by starting a line with val or var. But why are there two ways?

Well, sometimes someone wants to create a name for something that doesn’t change while other times one wants to create a name for something that does change.

  • val - short for “value”, gets initialized with a value and the Rules DSL will prevent you reassigning another value to that name
  • var - short for “variable” , can remain uninitialized (will be null), can be assigned new values, and can be reassigned to another value

I wish I knew how to create tables in forum postings…

I use the following rule of thumb. If I have a varaible/value named foo and there is never a foo = anywhere else besides the line the variable is created, use val. If you forget and try to reassign foo to some new value later on, you will get an error which will force you to think whether what you are doing is the correct thing and remind you to look at all the other places that foo is used to make sure what you are reassigning to foo doesn’t mess up the other places foo is used.

If I have a variable that does get reassigned I have to use var.

There are certain advantages to using val instead of var. For one, you cannot reference vars from inside certain lambdas, most notably, the foreach lambda when you are looping through the members of a Group. val gives you that little bit of extra checking which can prevent you from introducing a bug when you reassign something that should be reassigned (this is called defensive programming).

But there are times when you have to use var. Common examples are Timers, timestamps, and partial calculations.

There may be cases where you see val being used that do not make sense because the contents of the val are always being updated. Some examples:

  • val Map<String, Timer> timers = newHashMap
  • val StringBuilder message = new StringBuilder
  • val List<String> names = newArrayList

In each of the above examples, timers, message, and names are pointing to a datastructure, not just a value. val will prevent you from making a call like timers = null or timers = newHashMap but it doesn’t prevent you from making calls like timers.put(myItem.name, createTimer(now.plusSeconds(2), [| logInfo("Timer", "Timer expired")]).

In short, val only prevents one reassigning timers to a new Map, but it doesn’t prevent you from changing the Map itself.

I hope this makes sense. Let me know if you have any questions.

EDIT: Fixed a major typo where I used val but meant var.

4 Likes

Oh, as simple as that. A constant. Thanks!

Thanks to @rlkoshak too for the long explanation. I am a trained programmer though (just not in this particular languge), so the short explanation told me everything I needed to know :wink:

And thanks @ThomDietrich for the link. I’ve been looking for a good reference manual for the language being used. Is Xtend the language being used (ie is everything on that page valid here)?

You can ignore that last question, I’ve been reading up on http://docs.openhab.org/configuration/rules-dsl.html now, which I guess I should have done in the first place :slight_smile: A note however: The Xbase link (pointing to http://www.eclipse.org/Xtext/#xbase doesn’t work, the anchor it’s pointing to doesn’t seem to exist.

1 Like
thats how
it works
second row
| thats | how   |
|-------|-------|
| it    | works |
|second | row |

or you could use smth like this: http://www.tablesgenerator.com/markdown_tables# :wink:

Almost all of my responses like this are directed less at you the OP and more at the users who come along later and find this posting through a search.

I knew from your other postings that you had at least some programming skills. :slight_smile:

Not quite. There are a number of key differences, most importantly the Rule’s DSL:

  • doesn’t have classes
  • doesn’t have arrays (does have array lists though so you can reference things using .get(1) but not [1])
  • not all of the variations of for loops are supported
  • the rule “name”/when triggers/then code/ end and globals stuff is unique to the Rule’s DSL

Those are the major differences I’ve encountered. Consequently, you need only pay close attention to the Expressions section of the Xtext docs. the Classes and Members section is not applicable.

@Nicolas, Thanks! I knew it was possible.

2 Likes

I realize and appreciate that! When I searched for the var/val difference I came up empty, I hope others will end up at this thread :wink:

Thanks a lot for the list. Great!