Visage

6 views
Skip to first unread message

christophe...@gmail.com

unread,
Oct 5, 2010, 12:14:24 PM10/5/10
to Visage Developers
Hello,

The JavaFX compiler team did a lot of good work, and it would be a
shame to see it go to waste. So thanks for starting this project.

I can't speak publicly about JavaFX 2.0 or other Oracle internal
projects, so until such are publicly released, for the sake of
discussion here, I'll have to pretend they don't exist.

Although there are many things that could be improved, from my
observations of the presidio compiler from which I assume this project
forked, the most significant problem imo is the incomplete design/
implementation of lazy binding.

Lazy evaluation of binding is a strategy to avoid exponential
recomputation costs.

The basic idea is pretty simple. namely that when an update to a
variable is performed, dependent bound variables are not immediately
recomputed, but rather, such variables are transitively marked
(potentially) invalid. It is only when such invalidated variables are
subsequently read, that their bindings _may_ be evaluated, namely if
and only if the inputs to the variable's binding expression have
changed.

Although, the presidio compiler does contain most of the
infrastructure to perform lazy binding, it currently fails in (at
least) several important cases, namely sequence variables, and
function calls.

In addition, the current design dictates that triggers are called
eagerly (from the update site), and thus forces eager evaluation of
bindings they depend on.

AFAICT the current compiler design visits the variable dependency
graph in two passes on each update. The first pass performs
invalidation, the second pass is to execute triggers. Having two
passes is inefficient.

I believe these issues primarily stem from the compiler team's
attempts to optimize sequence slice triggers - but given the
prohibitive cost of eager binding in the presence triggers, such would
be to be avoided in the first place.

Lazy sequence triggers are conceptually possible, but would have their
own costs, namely application of Myers algorithm to compute the deltas
to feed the trigger.

The first step imo is to ensure the invalidation pass operates
correctly in the absence of triggers, and secondly to examine the
trade-offs of lazy and eager triggers.

James Weaver

unread,
Oct 5, 2010, 6:19:44 PM10/5/10
to visag...@googlegroups.com
Good to hear from you, Chris.  The Visage project welcomes your help!

Thanks,
Jim Weaver

Stephen Chin

unread,
Oct 5, 2010, 6:37:05 PM10/5/10
to visag...@googlegroups.com
I second Jim's welcome.  Great to hear form you, Chris!

I hope you don't mind, but I added you as an honorary project committer.  :-)

On lazy binding, I always wondered how the replace triggers worked...  I guess that answers my question (they break the model).  I added an enhancement request for this:
http://code.google.com/p/visage/issues/detail?id=11

Cheers,
--Steve
--
--Steve
blog: http://steveonjava.com/

Mark Storer

unread,
Oct 5, 2010, 6:54:57 PM10/5/10
to visag...@googlegroups.com
It sounds like we could use a keyword to help lazy binding with function return values that only change when that function's parameters change.

foo = bind bar.baz(qux,quux);

foo is dirty if qux || quux are dirty.  Changes to bar are irrelevant.

The only key word I'm coming up with for this is "deterministic", which is a mouthful.

Within such a function accessing any outside data (member variables, whatever) would be a compiler error.  Ditto for calling non-deterministic methods of any parameters that were passed in.

"simple" isn't bad.   A simple function:

public simple function add( a:Integer, b:Integer ) : Integer  {
  return a + b;
}

or two

public simple function multiply( a:Integer, b:Integer ) : Integer  {
  return a * b;
}

public simple function square( a:Integer ) : Integer {
  return multiply( a, a ); // kosher, if contrived.
}

From a linguistic perspective, the down side of simple is that someone Someone seeing it for the first time almost certainly won't understand what it means.  Not as bad as ye olde for( ; ; ) syntax, but not intuitive either.

From a technical perspective, I really haven't dug into the source anywhere near enough to comment.

--Mark Storer
  Professional Geek

Osvaldo Pinali Doederlein

unread,
Oct 5, 2010, 7:52:07 PM10/5/10
to visag...@googlegroups.com
Repeating my opinion from my first post, another vote for prioritize
the completion of the current language, before considering wild new
features :) I've been tracking the binding functionality with great
interest, but all currently planned binding improvements/optimizations
were interrupted by the JavaFX 2.0 roadmap (at least if Oracle would
complete JFXC Presidio...). The problem with triggers is hard, may need
some substantial design effort before any code is touched; so, maybe
it's a better idea to start with the low-hanging fruit, like the pending
items of JFXC-3557.

But then again, I'm not sure if all these fixes and improvements are a
language problem, or if at least some items may be a runtime problem?
The new binding library for JavaFX 2.0 will be a simple, "non-compiled
bind" (interpreter tree over some EL) like early JavaFX's - with a big
warning "use sparingly or else your app performance will suck"? In that
case, how would a superior binding system from Visage integrate smoothly
with JavaFX 2.0's? Or, if JavaFX 2.0's binding will be a
high-performance system, why should the Visage project burn effort
there, duplicating Oracle's work? Will JavaFX 2.0's binding include some
feature equivalent to triggers?

A+
Osvaldo

Peter Pilgrim

unread,
Oct 6, 2010, 12:03:37 AM10/6/10
to visag...@googlegroups.com
Hello Christopher

I also third it. Great to hear your "voice" from out there in the
Wilderness so to speak.
I am not so surprised that you mentioned binding as you were
researching binding and "lens" in your public blogs over a year ago.

On 5 October 2010 23:37, Stephen Chin <st...@widgetfx.org> wrote:
> I second Jim's welcome.  Great to hear form you, Chris!
>
> I hope you don't mind, but I added you as an honorary project committer.
> :-)
>
> On lazy binding, I always wondered how the replace triggers worked...  I
> guess that answers my question (they break the model).  I added an
> enhancement request for this:
> http://code.google.com/p/visage/issues/detail?id=11
>
> Cheers,
> --Steve
>
> On 10/5/2010 3:19 PM, James Weaver wrote:
>
> Good to hear from you, Chris.  The Visage project welcomes your help!
> Thanks,
> Jim Weaver

--
Peter Pilgrim,
**Java Champion**,
JavaFX / Java EE Software Development / Design / Architect
Certified SCRUM MASTER, Scala Enthusiast

:: http://audio.fm/profile/peter_pilgrim  ::
:: http://jroller.com/peter_pilgrim ::
:: https://java-champions.dev.java.net/ ::
:: http://twitter.com/peter_pilgrim ::

::  A Oracle Certified Enterprise Architect for Java EE 5 platform ::

Stephen Chin

unread,
Oct 6, 2010, 2:39:34 AM10/6/10
to visag...@googlegroups.com
Inline...

On 10/5/2010 4:52 PM, Osvaldo Pinali Doederlein wrote:
> Repeating my opinion from my first post, another vote for prioritize
> the completion of the current language, before considering wild new
> features :) I've been tracking the binding functionality with great
> interest, but all currently planned binding improvements/optimizations
> were interrupted by the JavaFX 2.0 roadmap (at least if Oracle would
> complete JFXC Presidio...). The problem with triggers is hard, may
> need some substantial design effort before any code is touched; so,
> maybe it's a better idea to start with the low-hanging fruit, like the
> pending items of JFXC-3557.

Good suggestion. There is quite a nice list of items there to work on.


> But then again, I'm not sure if all these fixes and improvements are a
> language problem, or if at least some items may be a runtime problem?
> The new binding library for JavaFX 2.0 will be a simple, "non-compiled
> bind" (interpreter tree over some EL) like early JavaFX's - with a big
> warning "use sparingly or else your app performance will suck"? In
> that case, how would a superior binding system from Visage integrate
> smoothly with JavaFX 2.0's? Or, if JavaFX 2.0's binding will be a
> high-performance system, why should the Visage project burn effort
> there, duplicating Oracle's work?

My assumption is that the JavaFX bind mechanism will be limited in
either its expressiveness, performance, or both. I would like to
preserve all the expressiveness of the Visage bind system while also
tuning performance. Without having access to the new bind APIs, I think
the best path is to keep the Visage language binding, and create a
transparent coupling to observable properties as a special case that we
will optimize for.


> Will JavaFX 2.0's binding include some feature equivalent to triggers?

My understanding is that the equivalent to triggers will be observable
properties.

Cheers,

William Billingsley

unread,
Oct 7, 2010, 1:26:37 AM10/7/10
to Visage Developers
Had a daft idea to try to uncover what's hard about all this:

In an idle-but-sleepy moment, I threw together a trivially simple
naive bind library -- Maven project downloadable at
http://www.wbillingsley.com/naivebind.zip

The question I'm trying to answer is "What's hard about implementing
bind?" Why not put in a temporary throwaway bind library that'll let
us bind to non-JavaFX code while we wait for the real thing? So this
tiny library is there not to be successful (it is trivially simple)
but because as you all say why a trivial answer wouldn't work, that
will document on this list what's so hard about writing bind / on
replace / on invalidate for the language.

The code just does the semantics as written (bind is lazy, on
invalidate is lazy, on replace is eager but executed after the dirty-
marking). It does let you do unbind, and bind to an Observable (ie,
for binding to non-Visage code), which JavaFX won't let you do. But
there's no smarts, and I haven't put in anything for sequences. I
didn't want to spend more than an hour or so on it, in spare moments
between doing other things.

The only unit test does 80,000-ish variables with nested dependencies
(number picked because in a toy example I've used for explanations
before, JavaFX 1.3 struggles with 80,000 triangles if you bind their
locations).

Stephen Chin

unread,
Oct 7, 2010, 2:40:04 AM10/7/10
to visag...@googlegroups.com
That is a nice little sample of what you could do with a bind library in
Java. From what I saw of the JavaFX 1.2 (or earlier) bind code, it is
pretty similar. Using a wrapper object around bindable properties
greatly simplifies the implementation.

In JavaFX 1.3 they changed the implementation to work directly off
instance variables whenever possible, and only add in the bind code when
it is actually used. This gives you a reduction of bytecode size for
the more common case where a variable is never bound. It also reduces
memory usage by reducing the number of property references and improves
performance for calls that go directly to the variables.

While there is always room for improvement, I am a big fan of the
current bind implementation in Visage and would like to keep it for any
Visage to Visage bind references. Once we have a concrete bind library
for Java (Rich said early 2010), we can see how difficult it will be to
wire the two binding systems together so you can bind from Visage to Java.

Cheers,
--Steve

--
--Steve
blog: http://steveonjava.com/

Mark Storer

unread,
Oct 7, 2010, 12:05:18 PM10/7/10
to visag...@googlegroups.com
Do we have any kind of Feature List for the upcoming java bind library?

--Mark Storer
  Professional Geek

Christopher Oliver

unread,
Oct 7, 2010, 12:29:29 PM10/7/10
to visag...@googlegroups.com
Problems are: boxing, and memory use.

1) Naive bind has memory leaks - deps must only weakly reference other variables
2) A conceptual single integer variable has the full overhead of AbstractBindable - shallow footprint of 8 fields.
3) Limitations of java generics introduce boxing of primitive types

The compiler optimizes cases of static variable dependencies within the same compilation unit (no dependency lists) - and is able represent variable values as normal java fields.

This produced a dynamic memory footprint reduction of 5x to 8x from earlier (so-called pre-compiled bind) versions of the compiler/runtime.

In the current compiler runtime, references to variables involved in binding are represented as a pair (FXObject, varIndex) and are not reified as java objects.

Chris

christophe...@gmail.com

unread,
Oct 7, 2010, 1:26:20 PM10/7/10
to Visage Developers
Actually this is the current behavior (modulo compiler bugs). Changes
to bar are indeed relevant however. Consider:

var bar = bind ...
var foo = bind bar.baz(qux, quux);

the baz function depends on the bar instance, as well as qux, and
quux.

Here's another example:

var a = "hello";
var b = bind a.toUpperCase();
println(b); // HELLO
a = "goodbye";
println(b); // GOODBYE

If baz was declared as a bound function, any variables used in its
body would also be included as dependencies. If not, then its similar
to a trigger. Non-bound javafx functions have identical behavior to
Java methods and such called from within a binding are semantically
equivalent to triggers. Only their formal parameters are treated as
dependencies and may "trigger" them to be called.

var y: Integer;
var x: Integer on replace { println(x + y) }

In this case the trigger depends on x, but not y, however its free to
use y when it "fires"

HTH,

Chris

William Billingsley

unread,
Oct 8, 2010, 1:50:40 AM10/8/10
to Visage Developers
Thanks. I appreciate seeing this all get written down. It's not hugely
unexpected or too scary so far, so that's encouraging.

In the 1.3 implementation, where the parent object inherits from
FXBase and handles dependencies for its public and bound fields
(generated setters, getters, invalidators, field numbers, etc) the
generated code makes a lot of conceptual sense, but is named in such a
way that non-Visage calls to Visage objects would be somewhat
awkward.

eg, the field itself really is made public
public float $selectionStart
and could presumably be set by non-Visage code without triggering any
of the triggers. The generated setter and getter have names that are
just as "internal"-sounding (set$selectionStart, get$selectionStart,
invalidate$selectionStart).

Is non-Visage access to classes that are written using Visage
something that would be valuable?

What are the main complications with trying to make the generated code
appear more conventional to non-Visage callers?
- Just name clashes with user-defined methods?
- Risk of user doing nasties like overriding the generated methods in
a subclass?
- Something more subtle?

As it's only the public fields of a class that might need to look
reasonable to non-Visage code, is it feasible to generate slightly
different code for public fields than for bound private or local
variables? Or would that overcomplicate things?

Christopher Oliver

unread,
Oct 8, 2010, 12:23:20 PM10/8/10
to visag...@googlegroups.com
Any field or method with a $ in it is considered internal and not for public consumption. Such fields/methods being public is a bug, but probably a low priority one at this point.
Reply all
Reply to author
Forward
0 new messages