Skip to main content

Strange Sequences

Posted by malenkov on January 13, 2009 at 2:00 AM PST

If you come across square brackets in JavaFX script, do not think that JavaFX supports arrays. These are sequences. Sequences are not arrays although they are similar. Before reading this blog post I recommend that you familiarize yourself with the lesson about Sequences in Learning the JavaFX Script Programming Language.

If a variable is already declared as a sequence variable, square brackets are not necessary when declaring this variable as a sequence with a single element. For example, many of my samples usually contain the following construction.

Stage {
  ...
  scene: Scene {
    ...
    content: MyCustomNode {
      ...
    }
  }
}

It is rather convenient that comma-separators are also not required. This way the content creation looks more accurate:

    content: [
      Rectangle {
        ...
      }
      Circle {
        ...
      }
      ...
    ]

But do not repeat my mistakes and always use separators with built-in types including strings. As a matter of fact, the [1 2 3] declaration creates a sequence as expected. But if you use negative numbers, the result will be unexpected, since the script evaluates all expressions before it creates a sequence. With strings, you can get even more interesting behavior. Several string literals will be concatenated by a compiler. This is a very useful feature that allows splitting long string literals among several lines, but if you create a sequence you might get a confusing result.

println([  1     2     3  ]); // prints [ 1, 2, 3 ]
println([ -1     2    -3  ]); // prints [ -1, -1 ]
println([ "1"   "2"   "3" ]); // prints [ 123 ]

You can determine the size of a sequence by using the sizeof operator followed by the name of the sequence. Sometimes you need to determine the index of an element in a sequence, but JavaFX only supports the foreach modification of the for-cycle. In this case, instead of creating an auxiliary sequence with indices, you can use the indexof operator followed by the name of the for-variable.

var values = [1 2 3];
println(sizeof values); // prints 3
for (value in values)
  println(indexof value); // prints 0, then 1, etc...

Note that the for-cycle is not a statement but an expression which returns a sequence. Each element in this sequence is a result of the last expression in a cycle body. This fact also simplifies sequence creation.

    content: for (index in [0..9]) {
      var i = 10 + 40 * index;
      var j =  5 + 20 * index;
      Rectangle {
        x: i
        y: j
        ...
      }
    }

Another difference between sequences and arrays is that you cannot add a null value to a sequence. On the one hand, it slightly reduces memory overhead. On the other hand, it impedes the creation of sparse arrays. A direct insert of a null value is prohibited by the compiler. When inserted indirectly, the null value is ignored at runtime.

println(["first",null,"last"]); // compilation error

var zero: String = null;
println(["first",zero,"last"]); // prints [ first, last ]

In addition, JavaFX does not support multidimensional sequences. Even if you declare a sequence of sequences, all elements of inner sequences will be added to the top-level sequence.

println([[1,2],[3,4]]); // prints [ 1, 2, 3, 4 ]

var one = [1 2];
var two = [3 4];
println([one two]); // prints [ 1, 2, 3, 4 ]

In whole, sequences have both advantages and drawbacks. Programmers should get accustomed to the sequence notation and its limitations.

Related Topics >>

Comments

Allowing spaces as delimiter in sequence literals is simply a bug.

Osvaldo, milestone build M8 has the following features as listed on the mailing list: On Dec 31, we tagged compiler milestone build "M8", which marked the end of our first Franza-targeted sprint. The build can be downloaded from Hudson at http://openjfx.java.sun.com/hudson/job/openjfx-compiler/3266/ or sources from SVN at https://openjfx-compiler.dev.java.net/svn/openjfx-compiler/tags/m8 Features and improvements incorporated in this sprint: - Addition of all Java primitive numeric types (float, double, long, int, short, byte, char) to the type system - Addition of "lazy bind" - Dynamic footprint (heap utilization) reduction in binding runtime -- achieved total 40% reduction on "stretchy grid" sample app - Sequence performance and footprint optimizations - Dynamic footprint optimizations in animations - More consistent treatment of Duration type - Allow iteration over java arrays, collections, iterables - More consistent treatment of null values in String and Duration-valued expressions Among them you will see, is support for iterating over java arrays, collections, iterables. Is this along the lines of what you have been looking for as far java interop is concerned?

Support for Maps, and also for primitive arrays (important for efficient Java interop to say the least) are high on my list too. Most scripting languages make a big tradeoff where they make easy syntax for a few collections... but then, they only make these few collections available, in a one-size-fits-all situation. The Java platform offers a amazing set of collections and it would suck not being able to use them. So, I imagined some syntax like this: var map = HashMap [ k1:v1, k2:v2 ] var list = CopyOnWriteArrayList [ a, b, c ] ...allowing two basic syntaxes, for keyed and non-keyed collections. And allowing the concrete collection type to be optionally specified before the '['. The problem here is that you don't want to hardwire a class name for JavaSE-specific APIs, because JavaFX runs on Java ME too. So, we could have this implemented as some sort of hint/annotation, with the meaning "if this particular class is available, please use it to hold this collection, otherwise use JavaFX's default for that". It's not the most elegant language design ever, but I think it's very important - for performance, AND features, AND easy interop with the colossal amount of Java APIs and code out there - that JavaFX develops top-notch collections support.

Nope. Collections utils are not implemented yet...

After a long time, now I understand why JavaFX was thrust upon poor programmers. What led to the understanding is the old joke that they call it 'refried beans' because they didn't get it right the first time. Only in this case the first time was just fine, and the bean just needed a tinge of salt.

Do you know when Sun will pull the trigger on a hash/map syntax? it seems fundamental to a scripting language and I was somewhat surprised it wasn't in the initial release.