So I put kenny's code into master and made it work with the hunchentoot server. I changed the example a little so that it only makes requests when focus is removed from the text box (hit tab or click somewhere else in the window).
I just wanted to see it working before reading up on aserve's webobjects and adding support for them so kenny can see this in action.
Admittedly, it does seem a little buggy. If the apropos-list is too large, it seems to hang the server (although refreshing the page and starting again is allowed because hunch just starts a new thread).
To try it for yourself...
If you haven't cloned the repo already...
$ git clone git://gitorious.org/hunchncells/mainline.git openair
...otherwise update your repo
$ git pull origin
...then after adusting your asdf locations accordingly...
(require :openair) (start-server :port 8080) (reload)
then point your browser to http://localhost:8080/apropos
type something into the text box and hit Tab.
-- Andy
Awesome subject. :)
Andy Chambers wrote:
So I put kenny's code into master and made it work with the hunchentoot server. I changed the example a little so that it only makes requests when focus is removed from the text box (hit tab or click somewhere else in the window).
I just wanted to see it working before reading up on aserve's webobjects and adding support for them so kenny can see this in action.
OK, so I should wait?
Admittedly, it does seem a little buggy. If the apropos-list is too large, it seems to hang the server (although refreshing the page and starting again is allowed because hunch just starts a new thread).
To try it for yourself...
If you haven't cloned the repo already...
$ git clone git://gitorious.org/hunchncells/mainline.git openair
...otherwise update your repo
$ git pull origin
...then after adusting your asdf locations accordingly...
(require :openair) (start-server :port 8080) (reload)
then point your browser to http://localhost:8080/apropos
type something into the text box and hit Tab.
I have been thinking about that edge case with a grandparent and grandchild changing but not the parent. One thing to do (besides what I think we should do, viz. xlookup) would be to extend cells to allow something like, ok, this reference to another cell is a dependency, but make it a lazy (non-propagating) dependency. This, btw, could be achieved by recording the other cell as /used/ but not recording me as a user. Which makes me wonder if a synaptic cell might not do, one that simply never says "yes" to the question "should this new value be propagated?". The key here is that we want this to be dependency-specific. If it were rule-wide, we already have lazy cells. But the only dependency we want lazy is when we go after a child node's xml. It would be cool if a synapse Just Worked, but it would be more efficient to extend Cells to have lazy dependencies.
Another approach would be to change the html generating macros to return functions which will when invoked generate the XML, including child XML by calling /those/ nodes xhtml generators. Deferred evaluation and all that. Then when the grandparent rule got reran and a new function generated, when that got called it would call its child's function (the parent in the kid-parent-grandparent use case at hand) and it would call the kids and get the latest xhtml. I guess this is like the Lisp trick of letting us change a function at runtime and then have the new version called by an old and un-reompiled caller, the function being resolved at runtime.
And then the final approach is the xlookup thing, really deferring dispatch until /browser/ run-time.
btw, those were presented in increasing order of superiority. :) The first might be easiest and I will explore it a little now, the second might be tough or might not, and I have no clue how hard xlookup would be (but I am pretty sure that is not a good name for it <g>).
Anyway, looking forward to the aserve version.
Congrats!
kenny
kt
Ken Tilton wrote:
Awesome subject. :)
Andy Chambers wrote:
So I put kenny's code into master and made it work with the hunchentoot server. I changed the example a little so that it only makes requests when focus is removed from the text box (hit tab or click somewhere else in the window).
I just wanted to see it working before reading up on aserve's webobjects and adding support for them so kenny can see this in action.
OK, so I should wait?
Admittedly, it does seem a little buggy. If the apropos-list is too large, it seems to hang the server (although refreshing the page and starting again is allowed because hunch just starts a new thread).
To try it for yourself...
If you haven't cloned the repo already...
$ git clone git://gitorious.org/hunchncells/mainline.git openair
...otherwise update your repo
$ git pull origin
...then after adusting your asdf locations accordingly...
(require :openair) (start-server :port 8080) (reload)
then point your browser to http://localhost:8080/apropos
type something into the text box and hit Tab.
I have been thinking about that edge case with a grandparent and grandchild changing but not the parent. One thing to do (besides what I think we should do, viz. xlookup) would be to extend cells to allow something like, ok, this reference to another cell is a dependency, but make it a lazy (non-propagating) dependency. This, btw, could be achieved by recording the other cell as /used/ but not recording me as a user. Which makes me wonder if a synaptic cell might not do, one that simply never says "yes" to the question "should this new value be propagated?". The key here is that we want this to be dependency-specific. If it were rule-wide, we already have lazy cells. But the only dependency we want lazy is when we go after a child node's xml. It would be cool if a synapse Just Worked, but it would be more efficient to extend Cells to have lazy dependencies.
Another approach would be to change the html generating macros to return functions which will when invoked generate the XML, including child XML by calling /those/ nodes xhtml generators. Deferred evaluation and all that. Then when the grandparent rule got reran and a new function generated, when that got called it would call its child's function (the parent in the kid-parent-grandparent use case at hand) and it would call the kids and get the latest xhtml. I guess this is like the Lisp trick of letting us change a function at runtime and then have the new version called by an old and un-reompiled caller, the function being resolved at runtime.
And then the final approach is the xlookup thing, really deferring dispatch until /browser/ run-time.
btw, those were presented in increasing order of superiority. :) The first might be easiest and I will explore it a little now, the second might be tough or might not, and I have no clue how hard xlookup would be (but I am pretty sure that is not a good name for it <g>).
It occurs to me that this apropos example would benefit another way from something like xlookup. Suppose can only guess a chunk of name that is very common, so there are a lot of matches. That's OK, now they just click various check boxes that limit the matching. But each time they click on a selection criteria a round-trip is needed to ask Common Lisp which symbols are, say, exported. Suppose a third are.
Without xlookup, the xhtml for that one third must be resent. With xlookup, the parent just resends itself listing so many terse little xlookup tags. GC on the client side could be handled during "not-to-be" processing.
When that is working we can look at implementing this bit wholly on the client side, with Cells/js.
jes thinkin out loud.... but it does make me less interested in exploring other ways to fix the edge case.
kenny
Ken Tilton writes:
Ken Tilton wrote:
Awesome subject. :)
:-)
I just wanted to see it working before reading up on aserve's webobjects and adding support for them so kenny can see this in action.
OK, so I should wait?
Yeah. I'm working on that now so I'll let you know later this goes.
I have been thinking about that edge case with a grandparent and grandchild changing but not the parent. One thing to do (besides what I think we should do, viz. xlookup) would be to extend cells to allow something like, ok, this reference to another cell is a dependency, but make it a lazy (non-propagating) dependency. This, btw, could be achieved by recording the other cell as /used/ but not recording me as a user. Which makes me wonder if a synaptic cell might not do, one that simply never says "yes" to the question "should this new value be propagated?". The key here is that we want this to be dependency-specific. If it were rule-wide, we already have lazy cells. But the only dependency we want lazy is when we go after a child node's xml. It would be cool if a synapse Just Worked, but it would be more efficient to extend Cells to have lazy dependencies.
Another approach would be to change the html generating macros to return functions which will when invoked generate the XML, including child XML by calling /those/ nodes xhtml generators. Deferred evaluation and all that. Then when the grandparent rule got reran and a new function generated, when that got called it would call its child's function (the parent in the kid-parent-grandparent use case at hand) and it would call the kids and get the latest xhtml. I guess this is like the Lisp trick of letting us change a function at runtime and then have the new version called by an old and un-reompiled caller, the function being resolved at runtime.
And then the final approach is the xlookup thing, really deferring dispatch until /browser/ run-time.
btw, those were presented in increasing order of superiority. :) The first might be easiest and I will explore it a little now, the second might be tough or might not, and I have no clue how hard xlookup would be (but I am pretty sure that is not a good name for it <g>).
How about xref, or just ref. I don't think the name matters really much since xml has namespaces to avoid collisions. We just put it in the http://openair.net/ (or whatever) namespace.
I'm going to read through the previous stuff you've posted about lookups since I'm still not clear about how it would work. Here's my understanding at the minute. Does it sound ok?
All the actual xml would have to be stored somewhere, presumably a javascript associative array. Then, whenever something is sent to the browser, we find all xlookup elements and replace them with their associated content.
It occurs to me that this apropos example would benefit another way from something like xlookup. Suppose can only guess a chunk of name that is very common, so there are a lot of matches. That's OK, now they just click various check boxes that limit the matching. But each time they click on a selection criteria a round-trip is needed to ask Common Lisp which symbols are, say, exported. Suppose a third are.
Without xlookup, the xhtml for that one third must be resent. With xlookup, the parent just resends itself listing so many terse little xlookup tags. GC on the client side could be handled during "not-to-be" processing.
Just to make sure I'm not missing anything, is the comparison below what you consider the difference to be?
<xlookup ref="s123">
Here's the equivalent
<li id="l123"><span id="s123">progv</span></li>
When that is working we can look at implementing this bit wholly on the client side, with Cells/js.
jes thinkin out loud.... but it does make me less interested in exploring other ways to fix the edge case.
No problem. We should do it right.
andy wrote:
Ken Tilton writes:
Ken Tilton wrote:
Awesome subject. :)
:-)
I just wanted to see it working before reading up on aserve's webobjects and adding support for them so kenny can see this in action.
OK, so I should wait?
Yeah. I'm working on that now so I'll let you know later this goes.
Cool. I am working on Cells.js. :)
I have been thinking about that edge case with a grandparent and grandchild changing but not the parent. One thing to do (besides what I think we should do, viz. xlookup) would be to extend cells to allow something like, ok, this reference to another cell is a dependency, but make it a lazy (non-propagating) dependency. This, btw, could be achieved by recording the other cell as /used/ but not recording me as a user. Which makes me wonder if a synaptic cell might not do, one that simply never says "yes" to the question "should this new value be propagated?". The key here is that we want this to be dependency-specific. If it were rule-wide, we already have lazy cells. But the only dependency we want lazy is when we go after a child node's xml. It would be cool if a synapse Just Worked, but it would be more efficient to extend Cells to have lazy dependencies.
Another approach would be to change the html generating macros to return functions which will when invoked generate the XML, including child XML by calling /those/ nodes xhtml generators. Deferred evaluation and all that. Then when the grandparent rule got reran and a new function generated, when that got called it would call its child's function (the parent in the kid-parent-grandparent use case at hand) and it would call the kids and get the latest xhtml. I guess this is like the Lisp trick of letting us change a function at runtime and then have the new version called by an old and un-reompiled caller, the function being resolved at runtime.
And then the final approach is the xlookup thing, really deferring dispatch until /browser/ run-time.
btw, those were presented in increasing order of superiority. :) The first might be easiest and I will explore it a little now, the second might be tough or might not, and I have no clue how hard xlookup would be (but I am pretty sure that is not a good name for it <g>).
How about xref, or just ref.
Awesome. I kept thinking "xref" but I kept worrying about a clash, altho I think it was href I remembered.
It is so much fun doing this without a clue on the domain (and the more I look at it the less I feel bad about having missed all this <g>).
I don't think the name matters really much since xml has namespaces to avoid collisions. We just put it in the http://openair.net/ (or whatever) namespace.
Ah, snazzy.
I'm going to read through the previous stuff you've posted about lookups since I'm still not clear about how it would work. Here's my understanding at the minute. Does it sound ok?
All the actual xml would have to be stored somewhere, presumably a javascript associative array. Then, whenever something is sent to the browser, we find all xlookup elements and replace them with their associated content.
Yep. I am hoping that when you said the "x" was for extensible that this will work.
The crazy thing is that where browsers cache pages and images and other things we are taking caching to a new (is it new?) level.
I mentioned GC being a concern. Possibly we have a fallback mechanism if we screw that up whereby xref can -- should something requested not be found -- make one last try by asking the server. Of course I am hoping the existing not-to-be mechanism will let us keep the client-side dictionary (where xref looks, the js associative array) tidy, but a few lines of code for a fallback might be smart.
Or am I being silly about even needing GC? Well, if we are building RIAs then we might well end up with users hanging out for a long time on the same page -- that by the way is me guessing the dictionary will get tossed when they leave a page. Getting ahead of myself as usual...
It occurs to me that this apropos example would benefit another way from something like xlookup. Suppose can only guess a chunk of name that is very common, so there are a lot of matches. That's OK, now they just click various check boxes that limit the matching. But each time they click on a selection criteria a round-trip is needed to ask Common Lisp which symbols are, say, exported. Suppose a third are.
Without xlookup, the xhtml for that one third must be resent. With xlookup, the parent just resends itself listing so many terse little xlookup tags. GC on the client side could be handled during "not-to-be" processing.
Just to make sure I'm not missing anything, is the comparison below what you consider the difference to be?
<xlookup ref="s123">
Here's the equivalent
<li id="l123"><span id="s123">progv</span></li>
No, but I am guessing it's a typo, you meant to compare with (using the burgeoining new name and throwing in another slash just to see if I am learning anything):
<xref ref="l123"/>
ie, it's the line that does not need resending -- in general, we want to go as high up as possible. In fact, technically that might be (introducing a syntax for email discussions in which dictionary entries are signified thus:
l123 : <li id="l123"><xref ref="s123"/></li>
...with this as a separate entry:
s123 : <span id="s123">progv</span>
Overkill? Actually, overkill is usually a Good Thing, always turns out handy later. If we end up bogging down clients with the burden of forever reassembling the xhtml, we can probably do something...omigod! Cells may help.
Cells already has a mechanism by which it nnotices and optimizes the case in which a cell slot of an instance will never change, either because it was initialized to a non-cell value like "42" or because the rule ended up with no dependencies after running.
In our case, the line can see the span will never change and "in-line" the span instead of doing the dynamic xref thing.
Hmmm. So can the line be in-lined? It will never change, but this would be no good, the parent div will vary in which lines to show... well, maybe that is OK and I am getting ahead of myself again -- probably cells-js can handle this on the client side (tho a small voice tells me whatever guidance the Lisp side can be sure of should be offered). We'll see. I would go for the xref overkill unless you see some problem with it and let performance prove that it is a problem.
When that is working we can look at implementing this bit wholly on the client side, with Cells/js.
jes thinkin out loud.... but it does make me less interested in exploring other ways to fix the edge case.
No problem. We should do it right.
Ah, a man after my heart. Yeah, doing it right generally means thinking harder, working less, and producing something way cooler and in the end pragmatically much better. Most programmers duck the hard stuff and do things the easy way and end up in a death march.
Right now I am having fun with regex replace in netbeans transforming the Cells lisp code to JS. This is the first time I took this approach, usually I do Cells 1.0 in a new language, then 2.0, then 3.0 -- with triple-cells (RDF and Cells) I broke down and just transliterated the integrity stuff after realizing doing 1.0 was silly because I have to turn straight around and do 3.0 -- it is fun seeing quick results, but I am getting used to seeing Cells work in other languages so let's see how hard it is slogging thru the whole thing in one go.
kenny