Mikko Ahonen wrote:
On Wed, Jul 9, 2008 at 4:04 AM, Kenny Tilton <kennytilton@optonline.net mailto:kennytilton@optonline.net> wrote:
Go with model, the family class and lots of other good stuff assumes that. You might be able to leverage some of that code.
OK.
OK, that is the second explanation: with Cells we really have to build an abstraction that hides the callbacks, so in my GUI work the first three days are spent hiding the callbacks so I forget they are there. :)
I ended up writing some wrappers around CAPI already to simplify some setf-ery, so this is not a biggie. This way setf-every was not too bad, but when I extrapolated the work that needs to be done, the vision was callback hell.
Yes. Brooks identified this as the big problem with software development in general: an exponential explosion of complexity as the number and kinds of data points grows in ever larger applications, because these data points tend to be interdependent. Any one change must be propagated reliably to all the right other data points, in the right order. That is not only hard, it is also not fun, nice to have that managed automatically just as modern languages manage memeory automatically.
If you look at Celtk or Cells-Gtk you'll see how I feed information from callbacks into the cells web so I can forget they are there. (Cello is just a wrapper for celtk.)
I'll look into them more deeply.
Not an important feature <g>, just an amazing manifestation of the power of the paradigm: a behavior like that /by accident/!
Sounds very cool. So far the biggest mind-fuck with my limited experience of cells is how it completely turns programming on its' head. Almost everything turns into dataflow, ...
Yes, programming reverses direction. Instead of a programmer sitting there handling a state change figuring out how to push the change throughout the rest of the application, they just write standalone black-box rules and the Cells engine tkes any change and pulls the change thru the rest of the application.
And it is hard to do just a little dataflow, because once you start on this the cells is where the action is, so to see a change other things must be cells, too. The good news is that cells are more fun anyway, so it is OK that one gets forced into using cells everywhere. :)
which seems to at least
temporarily increase the number of cells.
I won't have time to write it up, but I inadvertently stress-tested Cells. My app got a little sluggish on some things when I had about five thousand instances and over eighty thousand Cells. I fixed my bug and got it down to a couple thousand instances and (IIRC) twenty thousand Cells and things are quite zippy. They absolutely screamed when I activated OpenGL display lists a couple of places, but then i got into some imaging bugs and I really do not have time to mess with OpenGL right now.
Anyway, I was surprised and made a mental note to stop thinking about Cells as expensive. They may even be faster: i did another benchmark to see how much work was being done on each change to ensure the Cells integrity and it was much less than I thought. I knew cells guaranteed that only rules that needed to run would run and that that would make things optimal, but what I also saw was that the integrity rules did not force Cells to visit almost every cell to see if it should run, as I had feared.
So i would wait for performance to become a problem. If/when it does, you can probably uses synaptic Cells to minimize recomputation, or perhaps the application will suggest a new cells trick -- recent work on a Cells-ODE had me implement user control over propagation so one could do a bunch of state changes and propagate just once. ie, where the user knows multiple state changes can safely be treated as one, they can now get that by wrapping them in with-user-propagation (or whatever I called it).
The thought process is interesting. For example, I denote the selection of preview by flipping background and foreground colors. The parent container knows the selected child. In setf-ery, the (setf selected) method of the child would change the colors. First idea is to make each child have selected cell watching the selected cell of parent.
Then define observer on the selected of the child to actually change the colors. When I did that, I realized the need to ask for the colors from the parent, and setf them to local variables. Next, I noticed that hey, maybe foreground and background could be cells instead of local variables, and watching for the selected cell of the child. I ended up with one-line and 3 line observers for background and foreground, instead of single 15-line observer for the selected.
Welcome to the club. Feels like a free lunch, eh? :)
Now the next thought is that perhaps I could get rid of some of the intermediate cells, in this case the selected cell of the child. I guess when you turn programming on its' head, the dataflow becomes the "difficult part". My intuition says that at least to some point more intermediate cells makes dataflow more visible and reusable. So I kept the selected. But this may be because my background is in C shop where code readability was emphasized.
btw, if you are going to stick with CAPI the way to go is replicate the Celtk/Cells-Gtk/OpenAIR family of wrappers with sufficient glue to more or less make CAPI disappear. I am pretty busy these days, but I have an obscure interest in seeing that happen, and it is not all that hard, I'd be happy to help. Otoh, Cells-Gtk or Celtk free you from a Lispworks lock-in (not that that is a bad thing).
Great.
On this project I work with an user interface designer who is very visually oriented. Tk is a non-starter because the controls do not have a polished look. (Yeah, I know.).
Do you know about the Tile package? I believe they are trying to be more native on the widgets. There is Tile support in Celtk, just not sure how robust it is -- I make all my own widgets using OpenGL.
Does your designer need "native", or do they just need "beautiful"? Perhaps they would get off on designing their own widgets.
CAPI provides native GUI controls that are barely sufficient. But CAPI already limits us, however. For example, OS X Cocoa supports three sizes of controls, whereas CAPI has only one.
I also don't like vendor lock-ins. What I would prefer would be an open-sourced version of something like CAPI, and cells-CAPI to go along with it. I think splitting this into two different projects is better than single one, because you can get those cells skeptics involved, too. I think open source CAPI could be one of the biggest things missing from Lisp right now.
The first step into that direction would be to develop open source cells-CAPI. Perhaps it would also get more people interested in cells.
I think that will require OpenAIR, the web 2.0 incarnation of cells.
As for getting more people interested: Cells picks up one new user every year, and it looks like you are the one for 2008 -- I have six months before I have to worry about finding another user.
I am ready to incrementally work towards something like this during this project, but of course, my deadline is impossible (like always).
Talk to your designer, and check out my beach rants on Google video. What I am sensing is that widget sets are terribly constraining when it comes to building fluent GUI experiences for users. Does your designer also have an interest in the user experience, as well as the visual quality? In cello I have core classes like view and control and then i just make up an interactive screen element as i need it, with whatever rendering and event handling I have in mind. Instead of forcing my design into the pigeonholes determined by a fixed widget set, I just follow the application and the GUI elements follow me. :)
cheers, ken