Basic expressions

Bex script has the same syntax for basic expressions as Java. For example:

bex> 1
1
bex> 1+1
2
bex> (1 + 2) * 3 - 4  
5
bex> "bex" + "script"
beescript

There are some differences however. Currently cast expressions are not supported and "==" operator has the same semantics as "equals" in Java (function "same" can be used to compare object identities).

Assignment

In bex script variables are untyped so you can assign anything into any variable. Other than that the assignment operators are the same as in Java. For example:

bex> a = 1
1
bex> a += 1
2
bex> ++a
3

Block expressions

Bex script has no function declaration statements (or any other statements for that matter). To declare a function you need to specify the function with a block expression and then assign it to a variable. For example:

bex> square = |a|{ a * a }
bex.Block@b4d3d5
bex> square(2)
4

The above example assings a block expression to variable square. The block expression has one unbind variable "a" and the value of the expression is the square of the variable. The body of a block expression is a list of expressions enclosed within curly braces. The expressions are separated by a new line or semicolon. The return value of a function is (usually) the value of the last expression within its body.

Argument names are optional. The above function could also be written as follows:

bex> square = { $0 * $0 }
bex.Block@1bf52a5

Block expressions are much more powerful than what the above example suggests. In addition to providing a way to define functions, they can be used to create objects and implement Domain Specific Languages (DSLs). The following section demonstrates their capability to create objects. I've also successfully used them as a human readable replacement for XML configuration files.

Scripted objects

Bex script supports the same way of creating scripted objects as BeanShell does. To create an object you simply write a block expression that returns the special variable "this". The returned object has all the variables assigned during the execution of the block expression body. For example:

bex> makePerson = {
  firstName = $0
  lastName = $1
  this
}
bex.Block@128e20a
bex> juha = makePerson("Juha", "Lindström")
bex.Environment@1100d7a
bex> juha.firstName
Juha
bex> juha.lastName
Lindström

Using Java APIs

Accessing Java APIs from bex script is done for the most part using the same syntax as with Java. For example:

bex> System.out.println("hello world")
hello world
void

There are a few differencies however. For example instead of "new Foo()" objects are created with "Foo.new()".

Extending Java APIs

Bex script allows adding extensions to Java APIs that are accessible from the script. This allows extensions similar to Groovy's Groovy JDK. For example:

bex> File.eachLine = |file,fun|{
  fun = inline(fun)
  this.in = BufferedReader.new(FileReader.new(file))
  try { 
    while { super.line = in.readLine() } { fun(line) } 
  } { in.close() }
}

The above associates a new method "eachLine" to each instance of java.io.File. This new method can then be used just like it was a real method:

bex> File.new("script.bex").eachLine { print($0) }