How to build a generic spreadsheet?

I want to write a program where a user would update a bunch of variables, and everything that depends on those variables (and nothing else) are recalculated. Basically, a spreadsheet, but generalized for any computation. Could someone recommend an elegant way to do it or some good reading material? Thanks, Greg

On Fri, Feb 23, 2007 at 02:33:00PM -0800, Greg Fitzgerald wrote:
I want to write a program where a user would update a bunch of variables, and everything that depends on those variables (and nothing else) are recalculated. Basically, a spreadsheet, but generalized for any computation. Could someone recommend an elegant way to do it or some good reading material?
http://www.cse.ogi.edu/~magnus/Adaptive/
That might be a good place to start.
--
the Edward Blevins

Basically, a spreadsheet, but generalized for any computation
http://www.cse.ogi.edu/~magnus/Adaptive/http://www.cse.ogi.edu/%7Emagnus/Adaptive/ Thanks, this is exactly what I was looking for!
http://www.haskell.org/frp/ Cool, this is probably what I'm attempting to reinvent. :)
http://www.cs.york.ac.uk/fp/darcs/proplang/ What it does lack is much documentation :) If I understand what I'm looking at, seems like PropLang could benefit from Magnus's technique.
http://sigfpe.blogspot.com/2006/11/from-l-theorem-to-spreadsheet.html Here's a before and after shot of my head: Before: "head" After: " h e a d" See how it exploded? :)
Sebastian says: Off the top of my head... when ( newVals /= vals ) retry -- at least one input must've been changed you simply recompute the new value from the inputs Neat idea. I'm not sure if it's quite what I'm looking for, but I like the simplicity of it.
Thanks all for your help! Greg

On 2/23/07, Greg Fitzgerald
I want to write a program where a user would update a bunch of variables, and everything that depends on those variables (and nothing else) are recalculated. Basically, a spreadsheet, but generalized for any computation. Could someone recommend an elegant way to do it or some good reading material?
Off the top of my head, one cool way of doing it would be to have each variable be a separate thread (they're lightweight, so it's okay! :-)), and you would have a list of input connections and output connections, in the form of TVars. In its resting state you would have a transaction which simply reads all of the input variables, and returns the new list of inputs if and only if either of them are changed, something like: -- not compiled, consider it pseudocode :-) getInputs :: (Eq a ) => [( a, TVar a)] -> STM [a] getInputs inp = do let (vals, vars) = unzip inp newVals <- mapM readTVar vars when ( newVals /= vals ) retry -- at least one input must've been changed return vals This takes a list of "current values" zipped with the corresponding TVars, and would block until at least one input has changed. So once you get the values back from the function above, you know one of them has change, and you simply recompute the new value from the inputs, and plug the output into the output TVars and all the dependent "nodes" will automatically be unblocked and propagate its changes by virtue of the GHC scheduler. No coding required! At this stage you'd probably want to update some GUI control as well to display the new state. -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

On 2/23/07, Sebastian Sylvan
On 2/23/07, Greg Fitzgerald
wrote: I want to write a program where a user would update a bunch of variables, and everything that depends on those variables (and nothing else) are recalculated. Basically, a spreadsheet, but generalized for any computation. Could someone recommend an elegant way to do it or some good reading material?
Off the top of my head, one cool way of doing it would be to have each variable be a separate thread (they're lightweight, so it's okay! :-)), and you would have a list of input connections and output connections, in the form of TVars.
In its resting state you would have a transaction which simply reads all of the input variables, and returns the new list of inputs if and only if either of them are changed, something like:
-- not compiled, consider it pseudocode :-) getInputs :: (Eq a ) => [( a, TVar a)] -> STM [a] getInputs inp = do let (vals, vars) = unzip inp newVals <- mapM readTVar vars when ( newVals /= vals ) retry -- at least one input must've been changed
Bah, this should be: when ( newVals == vals ) retry Of course... -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

On 2/23/07, Sebastian Sylvan
On 2/23/07, Sebastian Sylvan
wrote: On 2/23/07, Greg Fitzgerald
wrote: I want to write a program where a user would update a bunch of variables, and everything that depends on those variables (and nothing else) are recalculated. Basically, a spreadsheet, but generalized for any computation. Could someone recommend an elegant way to do it or some good reading material?
Off the top of my head, one cool way of doing it would be to have each variable be a separate thread (they're lightweight, so it's okay! :-)), and you would have a list of input connections and output connections, in the form of TVars.
In its resting state you would have a transaction which simply reads all of the input variables, and returns the new list of inputs if and only if either of them are changed, something like:
-- not compiled, consider it pseudocode :-) getInputs :: (Eq a ) => [( a, TVar a)] -> STM [a] getInputs inp = do let (vals, vars) = unzip inp newVals <- mapM readTVar vars when ( newVals /= vals ) retry -- at least one input must've been changed
Bah, this should be:
when ( newVals == vals ) retry
Of course...
*sigh* and you should return "newVals" not "vals".. It's too late :-) -- Sebastian Sylvan +46(0)736-818655 UIN: 44640862

Greg Fitzgerald wrote:
I want to write a program where a user would update a bunch of variables, and everything that depends on those variables (and nothing else) are recalculated.
http://sigfpe.blogspot.com/2006/11/from-l-theorem-to-spreadsheet.html

Hi
I want to write a program where a user would update a bunch of variables, and everything that depends on those variables (and nothing else) are recalculated. Basically, a spreadsheet, but generalized for any computation. Could someone recommend an elegant way to do it or some good reading material?
PropLang already has the framework to do this: http://www.cs.york.ac.uk/fp/darcs/proplang/ Take a look at the samples, you can say something like: sb!text =< (\x -> "Word count: " ++ show (length $ words x)) =$$= txt!text The status bar's text is the word count, and its automatically updated if the user types. PropLang mainly operates with Gtk, but the framework is more general. What it does lack is much documentation :) Thanks Neil

On 23 Feb, 2007, at 15:33 , Greg Fitzgerald wrote:
I want to write a program where a user would update a bunch of variables, and everything that depends on those variables (and nothing else) are recalculated. Basically, a spreadsheet, but generalized for any computation. Could someone recommend an elegant way to do it or some good reading material? You could look into functional reactive programming, it's much the same as a generic spreadsheet, I think.
http://www.haskell.org/frp/ -chris
participants (6)
-
Bryan O'Sullivan
-
Chris Eidhof
-
Greg Fitzgerald
-
Neil Mitchell
-
Sebastian Sylvan
-
the Edward Blevins