« Excellent JavaFX Script Presentation by Matthew McCullough | Main | Gosling Q&A Video from JavaPolis 2007 - Has Lots to Say about JavaFX »

February 15, 2008


Chui Tey

A common use case with inverse binding is data entry apps, however, the binding syntax does not provide basic data validation e.g. "July 35, 2008". Why not provide a ValueConverter-style syntactic sugar?

Jim Weaver

t_e_r, EP, Cay, et al,

I received a response to questions about details concerning binding to a function from Per Bothner of the JavaFX Script Compiler team. It is in the mailing list message at the following URL, and for your convenience I've included it in this comment below the URL.


--------------------- Per's Response ---------------------
[While we haven't worked out everything about bind, this
is my understanding of where we are want to be wrt function calls,
and I think there is more-or-less consensus on the following, with a
caveat about some details, such as syntax.]

[Note this does *not* describe the current implementation!]

We distinguish in the data model between "values" and "locations".
A location may "contain" a value, or contain a recipe for
computing a value.

We have two kinds of functions, which are syntactically
distinguished (though we haven't settled on the syntax):

+ A "non-bound function" aka "value function" aka "F3-operation"
takes some number of values, and returns a value.

+ A "bound function" aka "location function" aka "F3-function"
takes some number of locations, and returns a location.
Roughly (we might tweak the details), the body of a bound
function acts like the expression in a bind, and has the
same limitations (if any), to be determined.

(Hybrids are possible, where some but not all of the parameter are
locations or the result isn't a location. However, they're not an
important use-case at this point.)

The default is a non-bound function. Brian has proposed using
the keyword bound to indicate a bound function:

bound function foo (...) { ... }

This add a new keyword, which might be OK, but an alternative
is to either re-use bind, or make bound be context-dependent.
For example

function foo (...) bind { ...}

This has the advantage that it matches the semantic model.

A function call can be either in bind context (roughly, if the call is
lexically inside a bind) or non-bind context (otherwise). (I say
"roughly", because some sub-expression in a bind might "turn off" bind
context. However, this isn't a factor in the current note.)

A "bind context" is loosely something that expects a location.
In bind context, a value is "boxed" to a constant location (or
rather a location initialized to the value).

Calling a non-bound function in non-bind context is trivial.

Calling a bound function in non-bind context does this:
The parameters are evaluated in non-bind context. For
each parameter, a fresh location is created, and it
is initialized with the value resulting from parameter
evaluation. The locations are passed to the function.
When the function returns, the returned location is

Calling a bound function in bind context evaluates
the arguments in bind mode, resulting in locations.
Those are passed to the function, and the resulting
location is the result of the call.

Calling a non-bound function in bind context evaluates
the arguments in bind mode, resulting in locations.
A fresh FunctionalLocation is created. The locations
are de-referenced, the function called with the resulting
values, and the result becomes the current value of the
FunctionalLocation. Furthermore, (weak) triggers are added
to the parameter locations so when any one of them changes,
the function is re-invoked, and the value updated.

Arithmetic operations, like +, are considered syntactic
sugar for (overloaded) non-bound functions.

An anonymous function can also be bound or non-bound.

Question: is "bindingness" part of the type of a function, or just a
property of the function "value"? I think the latter, since
bindingness doesn't really restrict the kind of functions: When the
compiler generates a call to an unknown function, it doesn't really
need to know whether the function is bound or non-bound, since in both
cases the arguments are evaluated in bind context, and locations
created. A function object (that implements the Function) the
interface just needs two methods: invoke and invokeBound. We can, I
think have two abstract sub-classes: BoundFunction and
NonBoundFunction: The compiler generates the invoke methods for a
non-bound function, and the invokeBound method for a bound function.
The BoundFunction abstract class defines invoke in terms of
invokeBound, and vice versa.
--Per Bothner
[email protected] [email protected] http://per.bothner.com/

Hope this helps, and thank you Per Bothner!
Jim Weaver

Jim Weaver

Cay, the current version of the NetBeans plugin is for interpreted JavaFX Script, which serves as a prototype for compiled JavaFX Script (compiles to JVM bytecode). To compile and run this example, see my Obtaining the Compiler post http://learnjavafx.typepad.com/weblog/2007/11/compiler-cheat.html

To all who posted question about specific binding behavior: Binding behavior for compiled JavaFX Script is just now becoming well defined. My understanding of binding to a function is probably too simplistic, which is that if any values in a function change in such a way that causes the function to have a different value, then the bound function is re-evaluated. I posted a request for a succinct description of the behavior of bound functions to the [email protected] mailing list (you can subscribe at the following link: https://openjfx-compiler.dev.java.net/servlets/ProjectMailingListList). When I get an answer I'll post it on this list.
Thanks to all for your great questions.
Jim Weaver

Cay Horstmann

Hi Jim,

I am trying to understand the elusive "bind" operator. I tried compiling your code in the Netbeans 6.0.1 plugin, but that's not been working out. Is the plugin outdated? It is dated 1/24/08.

At any rate, how does "bind" work under the hood? I assume that somehow it collects all possible inputs to the expression that is being bound, and that there are listeners that fire if any of them changes. If any of them does fire, presumably the expression gets re-evaluated, right?

I'd be very grateful for a very specific description of this process. Something that goes beyond "oh, it works just like a spreadsheet".



The comments to this entry are closed.