This was a conscious implementation decision, to keep our constraint system bounded. We
experimented with automatically handling (what I call) "path" expressions, but
the overhead was too great (simply because it created so many delegates). Most use-cases
seem to be covered by the simple implementation of constraints.
I was afraid this might be the case.
Another proof why declarative programming is still better left for the
future world.
Usually, you can work around issues like your example by making your constraint
a little more careful:
height="${this.program ? (this.program.duration * x + y) : 0}"
Yes, I have done that sometimes. Eg if you call a method to evaluate
constraint you just add everything as argument that you want to listen
to like
height="${calcHeight(this.program, this.program.duration)}"
even if you only use the duration inside the method.
But for complex dependencies, you do just have to write them out by hand.
Another thing to consider is that constraints are wonderful for prototyping,
but they can end up bogging things down if you get too many going at once.
Often after you have your system prototyped and working, it is worthwhile going
over it to see if there is a more imperative way to cast the solution, perhaps
by inverting the logic: rather than a constraining to b, have b tell a when it
needs to update. Sometimes b can make a much better decision on when a should
update than a can by watching b for changes.
That's a good reminder. I have had performance problems with my
application as I imported a big body of data into it.
Have to start the optimization by removing the constraints in bottleneck
areas.
As always thanks for the knowledge.
- rami