Massive performance issues and unresolved Glitch issues.
KScript and KSWorld: A Time-Aware and
Mostly Declarative Language and Interactive
Toward the Future of Personal Computing System Construction
And the works of Sean McDermid Roly Perera and dm barbour (AWELON Blue)
I am quite aware of KScript and KSWorld, in fact one of the authors shares an office with me, though we are both not in that often. These are highly experimental systems, so they didn't quite fit into my narrative.
I also think that the one-way solvers are the most immediately useful. On the other hand, the linguistic support needed for a pluggable one-way solver seems very similar to that needed for other solvers, and yes, they can be quite useful in more general circumstances. After all there is a whole field and several companies that do this sort of thing commercially.
are one-way dataflow constraints really any different from the observer pattern? i avoid cycles exactly because i implement it myself, and don't even have a solver, per se. even KVO seems not to handle cycles. and when e.g. i am using auto-layout in IB, even then i am careful to avoid over-constrainedness, even though the solver can settle on a "solution."
It was a huge amount of fun to work in, because it made GUI and server programming amazingly productive for a small team. You could get things working super fast, and with very little bugs because so much of the bookkeeping was done for you.
And one of the secrets compared to other systems in this vein was exactly the eager default, with a lazy option. By choosing per-formula which model you wanted, you could use the system that handled the most bookkeeping for you.
The Lisp code is still here:
The old examples and so on are in the Internet Archive:
I like that article is well-researched with references to various papers, there is definetly some good reading material there.
I prefe the approach where dependant values are expressed as functions, and then a caching layer is added where needs for performance.
(On the other hand, if your app is not model-based, I can see how it could get unwieldily.)
1. Suppose we have a model object with 10 properties, which you want drawn on screen. Following KVO pattern you would set values for 10 labels during [viewWillAppear], then you would signup for KVO 10 times, then, in handling KVO notification, you would update one of the 10 labels (10 different update code paths), and then you would unsubscribe from KVO in [viewWillDisappear] and/or in [dealloc] also 10 times. Adding a new property, you have to add code in all of these place, and failing even one could have disastrous consequences - inconsistent data display or a crash.
That was a simple example. Now consider a more complex example:
2. Suppose we have a class Person with firstName and lastName. Now if you signup for KVO for both of these, and I perform a legal name change for that person from "Bill Smith" to "Jane Doe", you will receive two notifications. If you're sending out a welcome email, you will end up sending two emails, one of them for nonexistent person "Jane Smith". KVO notifications expose inconsistent data. You could rectify that problem by creating a method for changing both first and last name at the same time and managing notifications carefully, but then all the elegance went out of the window - you're doing your notifications manually.
Now for a really screwed up situation:
3. Suppose we have the Account class with a list of bank transactions. Separately, we have a Person where you display the person's total wealth as result of those transactions. Normally, I would start by computing the account balance each time on demand, but let's say that computing is expensive and we want to persist/cache the result for speed. To keep the Person.wealth up to date we sign up for KVO notifications for Account.transactions and recompute the balance. Now your UI component is hooked to KVO-observe both the list of transactions and the Person.wealth. I post new transaction, and you get two KVO notifications - one for Account.transactions, and one for Person.wealth. But you get them in random order! You might get the Person.wealth notification before transaction notification, or you may get them in the opposite order - exposing inconsistent data (transactions would show the transaction, but wealth will show the old balance because it didn't receive the notification yet). And unlike the example #2, there is nothing we can do to fix this, because the conflicting data is in different classes.
Yes. From the Fine Article:
"[..] bindings are one-way dataflow constraints, specifically with the equation limited to y = x1. More complex equations can be obtained by using NSValueTransformers. KVO is more of an implicit invocation mechanism that is used primarily to build ad-hoc dataflow constraints."
Bindings: simple one way dataflow constraints.
KVO: implicit invocation.
Not the same thing.