Val vs var?

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