From achambers.home at googlemail.com Tue Apr 1 22:03:35 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Tue, 1 Apr 2008 23:03:35 +0100 Subject: [cells-devel] openair now works on my mac Message-ID: So I've been working sideways a bit the last few days to get openair working on my new mac (my girlfriend actually prefers the Linux and doesn't want me spending all day coding on it. How cool is that!!?). Openair (and all its dependancies) actually didn't take much effort. Most of the time was spent getting emacs setup the way I like it (and getting used to the MAC keyboard). I'm still working on that hello world. I think I've got the ajax side working but that's highlighted the fact that the updates slot isn't working correctly. From achambers.home at googlemail.com Wed Apr 2 09:40:06 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Wed, 2 Apr 2008 10:40:06 +0100 Subject: [cells-devel] undersold aspect of cells Message-ID: Hey Kenny, Here's an aspect of cells that I haven't seen highlighted before. The html macros I made pretty much constitute a schema for html. Not only does it concisely say what attributes are allowed on each element, but it gives you the object model for dealing with instances of these elements, and a nice set of macros for easily creating them. A couple of "validation" defmethods and I think we've got something that may be better even than relax-ng (the unstated assumption here is that its not hard to be better than xml schema). I know that lispers generally aren't that fond of xml but I bet there are a few that use it on their day job (as someone who's day job involves dealing with CDISC's various models it certainly is important for me). Since you're using your blog as a lisp/cells advocacy platform, maybe you could demonstrate this by creating a few macros that do a similar thing for RSS. I'd do it myself but I don't have a blog (I've never really felt that I've had enough to say to merit it but I am starting to get itchy fingers these days, hence the ramblings on cells-devel). -- Andy From kennytilton at optonline.net Wed Apr 2 14:02:30 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Wed, 02 Apr 2008 10:02:30 -0400 Subject: [cells-devel] undersold aspect of cells In-Reply-To: References: Message-ID: <47F391F6.7040405@optonline.net> Now there's a subject line to wake up to in the morning! :) Andy Chambers wrote: > Hey Kenny, > > Here's an aspect of cells that I haven't seen highlighted before. > > The html macros I made pretty much constitute a schema for html. Not > only does it > concisely say what attributes are allowed on each element, but it gives you the > object model for dealing with instances of these elements, and a nice set of > macros for easily creating them. > > A couple of "validation" defmethods and I think we've got something that may be > better even than relax-ng (the unstated assumption here is that its > not hard to be > better than xml schema). I took a look at relax-ng. Pretty scary. And fascinating, that XML has conditioned them such that relax-ng is considered concise. :) No Real Lisper would look at that stuff for more than two seconds before dashing off some macrology. > I know that lispers generally aren't that fond of xml but I bet there > are a few that > use it on their day job (as someone who's day job involves dealing with CDISC's > various models it certainly is important for me). Ah, CDISC! I guess you saw my blog entry on that clinical trial management software I did in Lisp. Too bad we could not sell it. Yes, Lispers do a lot of this stuff. I appreciate the kind words on Cells, but I think in this case the credit goes to lisp and macrology -- I think whenever a Lisper wraps X they do not just wrap it, they also add value by making X easier to generate and harder to get wrong. If you look at cl-opengl they went too far, IMHO, but it gives an idea anyway of the Lisp ethic: Don't Just Wrap! > > Since you're using your blog as a lisp/cells advocacy platform, maybe you could > demonstrate this by creating a few macros that do a similar thing for > RSS. That's Interwebby stuff, right? :) I am going to see if I can get Hunchentoot built -- think we'll have something for me to show to ECLM 2008? kenny From kennytilton at optonline.net Wed Apr 2 17:53:15 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Wed, 02 Apr 2008 13:53:15 -0400 Subject: [cells-devel] undersold aspect of cells In-Reply-To: References: <47F391F6.7040405@optonline.net> Message-ID: <47F3C80B.3030803@optonline.net> Andy Chambers wrote: > On Wed, Apr 2, 2008 at 3:02 PM, Ken Tilton wrote: > > >> Yes, Lispers do a lot of this stuff. I appreciate the kind words on Cells, >>but I think in this case the credit goes to lisp and macrology -- I think >>whenever a Lisper wraps X they do not just wrap it, they also add value by >>making X easier to generate and harder to get wrong. > > > I suppose so. The only cells-specific bit is the way the xhtml is constantly > kept in sync with the model. And hopefully this combined with the Lispy hiding/generation of a lot of unpleasant wiring will translate into a substantial qualitative leap forward for RIA authoring, in turn leading to wilder and cooler RIAs. But looking at my Algebra software I can see I let the ease of adding astonishing whiz-bang stuff definitely distracted me from Actually Shipping. Yes, it was easy, but then there is no end to the fun one can drawn into -- better to get the thing into people's hands and then easily implement things they actually ask me for. Lesson learned. :) Well, it took some hammer and chisel work but I have somewhat of a clean build of Hunchentoot, leaving we wondering how hard it would be to run against AllegroServe. :) Do I need a new release of o/a? kt From achambers.home at googlemail.com Thu Apr 3 13:27:58 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Thu, 3 Apr 2008 13:27:58 +0000 Subject: [cells-devel] undersold aspect of cells In-Reply-To: <47F3F7AF.4010003@optonline.net> References: <47F391F6.7040405@optonline.net> <47F3C80B.3030803@optonline.net> <47F3F7AF.4010003@optonline.net> Message-ID: > Thanks. I built your stuff against aserve, and the build looks OK. I did > change a few 'request' references to be 'req' which was used other places, > hope that was right. Ooops > > (defun test-page-allegro (path resource-class) > (lambda (req ent) > (with-http-response (req ent) > (with-http-body (req ent) > (let ((root (or (cdr (get-cookie-values req "root")) > (not (print "creating new web-app...")) > (mk-web-app (:prefix path > :request (c-in req)) > (make-instance > resource-class > :fm-parent *parent*))))) > (set-cookie-header req > :name "root" > :value root) > (funcall (handler root))))))) > > I also had a bunch of errors on RELOAD, but I am guessing that one is for > hunchentoot. > > I can start allegroserve OK and I have gone thru their tutorial and got > those to work anyway. > > I ran this function: > > (defun reload-allegro () > (publish-prefix > :prefix "/apropos" > :function (test-page-allegro > "/apropos" > 'web-apropos))) > > Went well. > > Guessing based on the aserve tutorial, I went to my browser and went to > > http://localhost:8000/apropos > > No error but no result, no print messages. > > What would be the sequence you would expect to work? Do I have to create a > particular directory structure and put different things different places > and/or modify any of the test code to point different places? I'd have been surprised if it did work actually. Until last night, I didn't have aserve installed. I did that last night and can confirm the lack of output you were seeing. I was getting some errors being written to standard out though so I worked through a couple of these. By default, aserve catches errors so to turn debugging on, you've got to (net.aserve::debug-on :notrap) If you want to hang on till later tonight, I'll give you another zip that should work (that's also been updated to use the name openair rather than hunchncells). -- Andy From frgo at mac.com Thu Apr 3 20:36:18 2008 From: frgo at mac.com (Frank Goenninger) Date: Thu, 3 Apr 2008 22:36:18 +0200 Subject: [cells-devel] OpenAir: Where, what, how ? - I want it ... Message-ID: Gentlemen (hi Andy, hi Kenny) - would like to try this (don't feel like going to bed yet, so ...). RIA is what I need for my next bigger project: A Master Data Management system for a semiconductor manufacturing company. If we can do this with a RIA based on Lisp, Cells, etc I'd be very excited to start in about 6 weeks with this project... So - How, where, etc (I haven't been able to follow all the emails on this one) Any short intro, what to install etc available? Thanks for info. Best, Frank From achambers.home at googlemail.com Thu Apr 3 20:53:45 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Thu, 3 Apr 2008 21:53:45 +0100 Subject: [cells-devel] OpenAir: Where, what, how ? - I want it ... In-Reply-To: References: Message-ID: On Thu, Apr 3, 2008 at 9:36 PM, Frank Goenninger wrote: > Gentlemen (hi Andy, hi Kenny) - > > would like to try this (don't feel like going to bed yet, so ...). RIA is > what I need for my next bigger project: A Master Data Management system for > a semiconductor manufacturing company. Its in a bit of a state at the moment because I've been trying to make it work with allegroserve. I've fixed a couple of things but just noticed that allegro doesn't have sessions like hunchentoot. That might be a bit of work. I'll have to check and see what hunch does. Do you have git? If so, the best bet is to clone the repo at gitorious git clone git://gitorious.org/hunchncells/mainline.git If the version you get doesn't work, try successively checking out previous versions by git checkout HEAD^ git checkout HEAD^^ ... I've been committing even if stuff doesn't work and am going to use tags to mark known good points (of which there haven't really been many so far) If you don't have git, I'll find a version that works and zip it up -- Andy From achambers.home at googlemail.com Fri Apr 4 10:08:59 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Fri, 4 Apr 2008 10:08:59 +0000 Subject: [cells-devel] openair progress Message-ID: I got the js-escape working better last night and went on to try and fill out the apropos demo but ran into some difficulties. I may need to rethink the macrology because when I put the following into the web-apropos model, I just got a list of progvs. (mk-div () (mk-ul () (loop for func in (apropos-list "prog") collect (mk-li () (mk-text func))))) Also, only changes to attributes are getting propagated to the updates slot, not changes to kids. In short, I'm still plugging away at this but I might be further away from producing something useful than it has seemed so far. Sorry if I've got people's hopes up. Its just the typical time estimates of an inexperienced programmer. I'm going to go back to celtk and try to understand the way it does things a bit better and see if there's anything fundamental I've missed. I should maybe code the apropos thing in celtk to check how the user code should look and make similar sort of code work for the web. Here's a quick question. If you want to make the kids of a mk-stack dependant on some other field in celtk, do you have to explicitly (make-instance 'stack :kids (c? ...) or should you still be able to use (mk-stack () ...) Cheers, Andy From kennytilton at optonline.net Fri Apr 4 13:46:51 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 04 Apr 2008 09:46:51 -0400 Subject: [cells-devel] openair progress In-Reply-To: References: Message-ID: <47F6314B.6010903@optonline.net> Andy Chambers wrote: > I got the js-escape working better last night and went on to try and > fill out the apropos demo but ran into > some difficulties. > > I may need to rethink the macrology because when I put the following > into the web-apropos model, I just got > a list of progvs. > > (mk-div () > (mk-ul () > (loop for func in (apropos-list "prog") > collect (mk-li () > (mk-text func))))) Don't feel bad, that is frequent "gotcha" even for loop veterans (and it is loop, not macrology, slowing you down (somewhat abbreviated): (loop for x in (apropos-list "prog") collect (let ((x x)) ;; shadow the "x" abused by loop (mk-text x))) > Also, only changes to attributes are getting propagated to the updates > slot, not changes to kids. Hey, just send me the latest code and I'll figure it out. If you do not have aserve working, we can probably figure it out with a test harness that writes updates to the console. I would make a top-level class: (defmd xh-driver () search-string (exported-only ...other input slots and really any slot you need to make this go... (xml (driven-xml))) (defun driven-xml (mk-page (loop for match in (apropos-list (search-string (u^ xh-driver))) when (or (exportedp match) (not (exported-only (u^ xh-driver)))) collect [xml for this symbol]))) Then (just typed in, polish required): (defun test-xh () (let ((d (make-instance 'xh-driver :search-string "prog" ;; no changes intended :exported-only (c-in nil)))) ;; changes intended (with-oa-updates-to-stream t ;; or "test.txt" (loop repeat 2 do (setf (exported-only d) (not (exported-only d)))))) with-oa-updates-to-stream is left as an exercise. It needs OA to always work by writing to some stream (*browser*? *xml-updates*?) and then you just bind that to t or some *sys-something* or an open file stream. I toggled both ways to test both /starting/ with nil and /changing/ to nil. > > In short, I'm still plugging away at this but I might be further away > from producing something > useful than it has seemed so far. Sorry if I've got people's hopes > up. Its just the typical time estimates of > an inexperienced programmer. haha, I think you are closer than you realize. Just send up flares early and often. > > I'm going to go back to celtk and try to understand the way it does > things a bit better and see if there's > anything fundamental I've missed. I should maybe code the apropos > thing in celtk to check how the user > code should look and make similar sort of code work for the web. > > Here's a quick question. If you want to make the kids of a mk-stack > dependant on some other field in celtk, > do you have to explicitly (make-instance 'stack :kids (c? ...) or > should you still be able to use (mk-stack () ...) mk-stack by default wraps what follows in a recalculating rule: (defmacro def-mk-inline (name (unlabelled labelled)) `(defmacro ,name ((&rest initargs) &rest kids) (if (evenp (length initargs)) `(make-instance ',',unlabelled :fm-parent *parent* , at initargs :kids (c? (the-kids , at kids))) `(make-instance ',',labelled :fm-parent *parent* :text ,(car initargs) ,@(cdr initargs) :kids (c? (the-kids , at kids)))))) (def-mk-inline mk-row (frame-row labelframe-row)) (def-mk-inline mk-stack (frame-stack labelframe-stack)) kt From kennytilton at optonline.net Fri Apr 4 14:42:13 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 04 Apr 2008 10:42:13 -0400 Subject: [cells-devel] openair progress In-Reply-To: References: Message-ID: <47F63E45.7070805@optonline.net> More thoughts... Andy Chambers wrote: > I'm going to go back to celtk and try to understand the way it does > things a bit better and see if there's > anything fundamental I've missed. I should maybe code the apropos > thing in celtk to check how the user > code should look and make similar sort of code work for the web. That's a good idea, btw. A bit of work but I guess all the widgets are there and it would be a good learning experience. But first send me a zip of your latest/greatest so I can stare at it in parallel. > > Here's a quick question. If you want to make the kids of a mk-stack > dependant on some other field in celtk, > do you have to explicitly (make-instance 'stack :kids (c? ...) or > should you still be able to use (mk-stack () ...) As I said, that should work and a very quick glance at the example you sent last time looks reasonable, so send me what you have now and we can sort it out pretty quickly. One general pointer, to be remembered especially when nothing seems to be working: always call cells-reset at the start of any test. It's a long story, but there is a global *stop* that gets set when things go wrong that cells code checks before doing anything, as a way of getting the thing to actually stop in a situation where a process keeps feeding us events even after we have backtraced, putting us in a loop as we try to handle the new events and backtrace again. It happens pretty often that I roll some little test thing and get lazy and do not include the call to cells-reset, leading to some pretty serious head-scratching until I notice /nothing/ works and then remember cells-reset. kt From kennytilton at optonline.net Fri Apr 4 15:18:29 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 04 Apr 2008 11:18:29 -0400 Subject: [cells-devel] Cells debugging In-Reply-To: References: Message-ID: <47F646C5.9020101@optonline.net> Another thought and generally useful Cells debugging tips... Andy Chambers wrote: > Here's a quick question. If you want to make the kids of a mk-stack > dependant on some other field in celtk, > do you have to explicitly (make-instance 'stack :kids (c? ...) or > should you still be able to use (mk-stack () ...) If something is not changing even though I wrote a rule for it, the first thing I might do is add a print statement inside the rule itself to (a) make sure it runs at least once and then (b) to see if it is running even though I thought it was not. Two different investigations might get spawned there. If a rule runs once and does not run again I inspect the instance that owns the slot and look to see if the cell struct is in the .cells slot or the .cells-flushed slot. If it is in the latter it means that the rule did not read any other slot that met all these requirements: 1. it is a cell slot (the default, overridden by saying :cell nil) 2. the slot of the instance read was mediated by a cell which... 3. ...itself had not been flushed. If a rule does not read any such slot it will never get run again so Cells pulls it out of action (but keeps it in the flushed list for debugging). btw, if you inspect a ruled cell you will discover that the code for the cell gets captured in a slot of the cell struct, again for debugging purposes. You can also inspect the slots for callers and useds (silly name, I know, I do that sometimes). If all is well you should see a cell for the slot .kids in the .cells list. That alone tells you it depends on /something/ and is still in the game. My next question would be to look at the captured code for the rule, and also look to see if the expected used other cell is in the useds list. Other investigations flow from that. If I am flushed, why are the slots I used not Cells or why did they get flushed. If I am not flushed and I have the right dependencies, why aren't they talking to me? Are /they/ changing? Debug observers on input cells can confirm they are changing. btw, I just thought of something going in the other direction that would make things /overactive/: I guess you will be handing a lot of strings, and the default "unchanged" test is EQL. You might want to specify: :unchanged-if 'string= ...or something. More as I thnk of it. kt From achambers.home at googlemail.com Fri Apr 4 17:35:35 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Fri, 4 Apr 2008 18:35:35 +0100 Subject: [cells-devel] openair progress In-Reply-To: <47F66371.4010301@optonline.net> References: <47F66371.4010301@optonline.net> Message-ID: On Fri, Apr 4, 2008 at 6:20 PM, Ken Tilton wrote: Here's the latest source. I went back to making it work with hunchentoot becuase of the sessions thing. Is there a nice way to optionally depend on some library. The best I came up with was to put :use-hunch, or :use-aserve in *features* before loading and then have different defsystem forms for each case (like Edi does with cl-ppcre sort of). I suppose allegro users would probably always want to use aserve so maybe we'd just use #+allegro. So what's up with that loop gotcha. Is that because of we're collecting a macro form? I'll see if that's the problem. -- Andy -------------- next part -------------- A non-text attachment was scrubbed... Name: openair.zip Type: application/zip Size: 44422 bytes Desc: not available URL: From achambers.home at googlemail.com Fri Apr 4 19:16:07 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Fri, 4 Apr 2008 20:16:07 +0100 Subject: [cells-devel] openair progress In-Reply-To: <47F679F6.5060800@optonline.net> References: <47F66371.4010301@optonline.net> <47F679F6.5060800@optonline.net> Message-ID: On 4 Apr 2008, at 19:56, Ken Tilton wrote: > Andy Chambers wrote: >> On Fri, Apr 4, 2008 at 6:20 PM, Ken Tilton >> wrote: >> Here's the latest source. I went back to making it work with >> hunchentoot becuase >> of the sessions thing. > > Bummer. Remind me: this is because aserve does that differently, not > because it cannot handle them, right? At first I thought we'd have to implement the whole idea of sessions but someone pointed out yesterday that allegroserve has "webactions". I just wanted to see it working before I ported it to webactions. > > Yep. Some allegro users will want to develop portably and use > hunchentoot -- I do that for production work to avoid an ACL lock-in. But am I correct in thinking that real allegroserve has just the same interface as portable aserve (or at least a superset of features). > > >> So what's up with that loop gotcha. Is that because of we're >> collecting a macro >> form? > > No, it has to do with all closures capturing the same lexical which > gets rebound until the loop ends so at the end all closures see the > same value (the last). > > I have looked closer at how you minimize updates using the content- > rule to do your own change detection. I think I am going to have a > bunch of Ajax questions soon. :) > > Do you think there is any way we can implement my idea of a browser- > less test harness in which we just... hmmm, ideally we setf the REQ > slot with something valid. That's a good idea. Not sure about the best way to create the request objects but one way would be to just save them for later when they come from the browser. All we're interested in at the moment is the GET parameters so that approach should be fine. -- Andy From kennytilton at optonline.net Fri Apr 4 19:18:15 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 04 Apr 2008 15:18:15 -0400 Subject: [cells-devel] openair progress In-Reply-To: References: <47F66371.4010301@optonline.net> Message-ID: <47F67EF7.9010901@optonline.net> Andy, Just a quick note to say one of the source files (macros?) still had the hunchncells as the in-package form. Is it possible you sent the wrong source or were having problems because of a package mismatch? kt From frgo at mac.com Fri Apr 4 20:24:03 2008 From: frgo at mac.com (Frank Goenninger) Date: Fri, 4 Apr 2008 22:24:03 +0200 Subject: [cells-devel] openair progress In-Reply-To: <47F67EF7.9010901@optonline.net> References: <47F66371.4010301@optonline.net> <47F67EF7.9010901@optonline.net> Message-ID: <7759878C-5CCE-4DB2-BFDE-2D42098FB00B@mac.com> Git source also has the :hunchencells package reference. No mentioning of an :openair package definition. // Frank Am 04.04.2008 um 21:18 schrieb Ken Tilton: > Andy, > > Just a quick note to say one of the source files (macros?) still had > the hunchncells as the in-package form. Is it possible you sent the > wrong source or were having problems because of a package mismatch? > > kt > _______________________________________________ > cells-devel site list > cells-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cells-devel From kennytilton at optonline.net Fri Apr 4 20:31:36 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 04 Apr 2008 16:31:36 -0400 Subject: [cells-devel] openair progress In-Reply-To: <7759878C-5CCE-4DB2-BFDE-2D42098FB00B@mac.com> References: <47F66371.4010301@optonline.net> <47F67EF7.9010901@optonline.net> <7759878C-5CCE-4DB2-BFDE-2D42098FB00B@mac.com> Message-ID: <47F69028.2000908@optonline.net> Frank Goenninger wrote: > Git source also has the :hunchencells package reference. No mentioning > of an :openair package definition. Thx. If none then Andy just has not committed, cuz I only saw one :hunchncells (no "e" in this hunchen) all else was :openair. And it was my screw-up, somehow /I/ got a file mixed up in there. Unfortunately I am on win32 and getting git there looks a little paingul, so Andy is being kind enough to spoonfeed me ZIPs. :) kt From ibormuth at efil.de Fri Apr 4 21:23:15 2008 From: ibormuth at efil.de (Ingo Bormuth) Date: Fri, 4 Apr 2008 23:23:15 +0200 Subject: [cells-devel] openair progress In-Reply-To: <47F69028.2000908@optonline.net> References: <47F66371.4010301@optonline.net> <47F67EF7.9010901@optonline.net> <7759878C-5CCE-4DB2-BFDE-2D42098FB00B@mac.com> <47F69028.2000908@optonline.net> Message-ID: <20080404212315.GA28448@efil.de> On 2008-04-04 16:31, Ken Tilton wrote: > Unfortunately I am on win32 and getting git there looks a little paingul, There is a quite simple installer including all important dependencies: http://msysgit.googlecode.com/files/Git-1.5.4-preview20080202.exe It is said to be merged with mainline git in near future. -- Ingo Bormuth, voicebox & fax: +49-(0)-12125-10226517 public key 86326EC9, http://ibormuth.efil.de/contact From kennytilton at optonline.net Fri Apr 4 21:24:12 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 04 Apr 2008 17:24:12 -0400 Subject: [cells-devel] openair progress In-Reply-To: <47F67EF7.9010901@optonline.net> References: <47F66371.4010301@optonline.net> <47F67EF7.9010901@optonline.net> Message-ID: <47F69C7C.6000802@optonline.net> I am wondering if we even need the content trick to detect what needs transmitting. Consider this very slightly modified (and untested) xml rule: (defun xmlrule (class html-attrs) `(c? (with-output-to-string (s) (with-html-output (s nil :prologue nil) (,(intern (symbol-name class) :keyword) ,@(loop for (cl-meth attr) in html-attrs append `(,(intern (symbol-name attr) :keyword) (,cl-meth self))) ;; (^x) -> (x self) ,@(loop for (cl-meth attr) in '((id id) (cls class) (title title) (style style)) append `(,(intern (symbol-name attr) :keyword) (,cl-meth self))) ;; (^x) -> (x self) (str (apply #'concatenate 'string (loop for k in (^kids) ;; got to see kids change ;; but not if same kid changes its xml: collecting (without-c-dependency (xhtml k)))))))))) Now the observer on xmlrule just pushes the string onto the updates slot as an assoc of (cons self (^xhtml)) and the transmitter simply skips any entry who has any ascendant also in the updates list. What would be fun would be the custom xget or xlookup extension I suggested. Then we let the browser do the work of assembling the xhtml and then simply have an observer that transmits xhtml when it changes, because all references to kids would look like: (loop for k in (^kids) collecting `()) ... or whatever the syntax would be. The nice thing here is the added efficiency. What if the apropos search parameters are changed to say "exported only"? Instead of sending over the whole list of exported functions afresh, we send over only a new list of xlookups because their xhtml bodies are all over there already. How cool is that? And once the demp gets fleshed out and a single match is its own div with multiple columns we are seriously reducing traffic. Thoughts? kt From kennytilton at optonline.net Fri Apr 4 21:48:03 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 04 Apr 2008 17:48:03 -0400 Subject: [cells-devel] openair progress In-Reply-To: <20080404212315.GA28448@efil.de> References: <47F66371.4010301@optonline.net> <47F67EF7.9010901@optonline.net> <7759878C-5CCE-4DB2-BFDE-2D42098FB00B@mac.com> <47F69028.2000908@optonline.net> <20080404212315.GA28448@efil.de> Message-ID: <47F6A213.4060400@optonline.net> Ingo Bormuth wrote: > On 2008-04-04 16:31, Ken Tilton wrote: > >>Unfortunately I am on win32 and getting git there looks a little paingul, > > > > There is a quite simple installer including all important dependencies: > > http://msysgit.googlecode.com/files/Git-1.5.4-preview20080202.exe > > It is said to be merged with mainline git in near future. > > Brilliant! Thanks so much, and it is a nice installer indeed, lots of very good detail over what gets created and easily controlled. Andy, I have now downloaded what you had using this command: git clone git://gitorious.org/hunchncells/mainline.git ...while in my working directory of openair, so I now have all your code in \openair\mainline. We can leave the zips behind any time you are ready to commit. Lemme know when that is done and I will bravely try to update. The on-line git doc actually looks pretty good, but any tips on the following would help: picking up your latest version in toto committing anything I do so (a) it does not tromp on everything and (b) you can merge with it thx again, Ingo. kenny From frgo at mac.com Fri Apr 4 22:01:26 2008 From: frgo at mac.com (Frank Goenninger) Date: Sat, 5 Apr 2008 00:01:26 +0200 Subject: [cells-devel] Openair: How to get a rule fired on every single change in the browser ? Message-ID: <37F22D4C-F0DA-498B-B463-3C4EA84583F4@mac.com> Hi Andy, Kenny, in my apps I often rely on the fact that for every single keypress of the user I have a changed cell and therefore I get my dependencies updated on every single user action. Now ... I just don't see how I can achieve this with Openair (I am not a Javascript expert - not even a beginner ;-) Thanks for input ... Best, Frank From kennytilton at optonline.net Sat Apr 5 00:07:16 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 04 Apr 2008 20:07:16 -0400 Subject: [cells-devel] openair progress In-Reply-To: References: <47F66371.4010301@optonline.net> <47F67EF7.9010901@optonline.net> <7759878C-5CCE-4DB2-BFDE-2D42098FB00B@mac.com> <47F69028.2000908@optonline.net> <20080404212315.GA28448@efil.de> <47F6A213.4060400@optonline.net> Message-ID: <47F6C2B4.7070002@optonline.net> Andy Chambers wrote: > On Fri, Apr 4, 2008 at 10:48 PM, Ken Tilton wrote: > > >> Lemme know when that is done and I will bravely try to update. The on-line > > > I'll send emails to cells-devel whenever I push to the repo. I've > also posted a feature request to the gitorious guy to add mailing list > support whenever a push is made so maybe some time in the future, > that'll happen automatically. > > >>git doc actually looks pretty good, but any tips on the following would >>help: >> >> picking up your latest version in toto >> committing anything I do so (a) it does not tromp on everything and (b) >>you can merge with it > > > picking up the latest version: > > git pull origin > > > In git, branches are really easy, so... > > git checkout -b kenny Very cool: mkdir openair cd openair git clone git://gitorious.org/hunchncells/mainline.git cd mainline git pull origin -> Already up-to-date. git checkout -b kenny -> Switched to a new branch "kenny" Cool. Now I do not see a new directory or anything, so I guess I just start whacking on the code in mainline? Hmmm... I guess it gets interesting after we both have made changes and I want to pick up your newest stuff... well, I guess I can just hack away and commit under the kenny branch and when /you/ decide to add anything I did to the mainline I can just start over with a fresh copy. We can cross these hairier bridges as needed. I get the feeling Linus has done it again and git is taking over. Should I move all my stuff to git do you think? And is this something common-lisp.net can do, or am I headed for gitorious? > > creates the kenny branch and checks it out. > > hack, hack, hack > > git commit -a -m "fixed some stuff" > > If you and Frank add yourself as users to gitorious, I'll add you both > as commiters to hunchncells. I have signed up as "kennytilton". thx for the tutorial! kt From frgo at mac.com Sat Apr 5 07:19:37 2008 From: frgo at mac.com (Frank Goenninger) Date: Sat, 5 Apr 2008 09:19:37 +0200 Subject: [cells-devel] Openair: How to get a rule fired on every single change in the browser ? In-Reply-To: <37F22D4C-F0DA-498B-B463-3C4EA84583F4@mac.com> References: <37F22D4C-F0DA-498B-B463-3C4EA84583F4@mac.com> Message-ID: Am 05.04.2008 um 00:01 schrieb Frank Goenninger: > Hi Andy, Kenny, > > in my apps I often rely on the fact that for every single keypress > of the user I have a changed cell and therefore I get my > dependencies updated on every single user action. > > Now ... I just don't see how I can achieve this with Openair (I am > not a Javascript expert - not even a beginner ;-) > > Thanks for input ... Based on Andy's feedback I got it working now. Cool! And jQuery offers quite a lot ... Now I only need to adapt Marco Antoniotti's cool automatic html generation via MOP just from a defclass ... Andy, please keep it going ;-) Thanks again - Frank From achambers.home at googlemail.com Sat Apr 5 10:23:28 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Sat, 5 Apr 2008 11:23:28 +0100 Subject: [cells-devel] following progress Message-ID: Ken asked a while ago about being notified about commits. I asked about a commit mailing list on the gitorious message board. They told me I can follow an RSS feed for each branch. There was also some mutterings about making the post-commit-hook available in some way (this is just a script that git runs after commiting). Do you guys use rss? On a MAC, you can get it to show up in your email. -- Andy From achambers.home at googlemail.com Sat Apr 5 12:50:03 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Sat, 5 Apr 2008 13:50:03 +0100 Subject: [cells-devel] Booyah!! openair off the ground Message-ID: 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 From kennytilton at optonline.net Sat Apr 5 18:33:58 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Sat, 05 Apr 2008 14:33:58 -0400 Subject: [cells-devel] Booyah!! openair off the ground In-Reply-To: References: Message-ID: <47F7C616.6010004@optonline.net> 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 ). Anyway, looking forward to the aserve version. Congrats! kenny kt From kennytilton at optonline.net Sat Apr 5 20:59:52 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Sat, 05 Apr 2008 16:59:52 -0400 Subject: [cells-devel] Booyah!! openair off the ground In-Reply-To: <47F7C616.6010004@optonline.net> References: <47F7C616.6010004@optonline.net> Message-ID: <47F7E848.2070504@optonline.net> 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 ). > 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 From achambers.home at googlemail.com Sun Apr 6 16:11:21 2008 From: achambers.home at googlemail.com (andy) Date: Sun, 6 Apr 2008 17:11:21 +0100 Subject: [cells-devel] Booyah!! openair off the ground In-Reply-To: <47F7E848.2070504@optonline.net> References: <47F7C616.6010004@optonline.net> <47F7E848.2070504@optonline.net> Message-ID: <18424.63017.660090.684646@martin.lyndoch.net> 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 ). 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? Here's the equivalent
  • progv
  • > > 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. From kennytilton at optonline.net Sun Apr 6 18:24:52 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Sun, 06 Apr 2008 14:24:52 -0400 Subject: [cells-devel] Booyah!! openair off the ground In-Reply-To: <18424.63017.660090.684646@martin.lyndoch.net> References: <47F7C616.6010004@optonline.net> <47F7E848.2070504@optonline.net> <18424.63017.660090.684646@martin.lyndoch.net> Message-ID: <47F91574.8040608@optonline.net> 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 ). > > 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 ). > 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? > > > > Here's the equivalent > >
  • progv
  • 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): 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 :
  • ...with this as a separate entry: s123 : progv 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 From achambers.home at googlemail.com Sun Apr 6 20:50:39 2008 From: achambers.home at googlemail.com (andy) Date: Sun, 6 Apr 2008 21:50:39 +0100 Subject: [cells-devel] (no subject) Message-ID: <18425.14239.980791.811785@martin.lyndoch.net> Subject: Re: [cells-devel] Booyah!! openair off the ground In-Reply-To: <47F91574.8040608 at optonline.net> References: <47F7C616.6010004 at optonline.net> <47F7E848.2070504 at optonline.net> <18424.63017.660090.684646 at martin.lyndoch.net> <47F91574.8040608 at optonline.net> X-Mailer: VM 8.0.9 under Emacs 22.1.1 (i486-pc-linux-gnu) Ken Tilton writes: > andy wrote: > > > >> 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. Mmm. Not going too well here. webactions seems to require something called :sock that doesn't appear anywhere on cliki.net. Does this come pre-installed with allegro? > Cool. I am working on Cells.js. :) > > 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 ). > > > 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. google does a fair amount of clever stuff with javascript. I'm sure there must be some fairly advanced caching going on there. > 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... I've heard of cases where it isn't. Not quite sure how that happens though. I think the GC is a good idea and it doesn't sound like it'll be that hard. > > > 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? > > > > > > > > Here's the equivalent > > > >
  • progv
  • > > 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): > > You can now put XML on your resume :-) > 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 :
  • > > ...with this as a separate entry: > > s123 : progv We don't even have to invent a new syntax. You can define javascript objects using a syntax almost exactly like that... var cache = { l123 : "
  • " s123 : "progv" }; then if we need to update it... cache["l123"] = "
  • "; -- Andy From achambers.home at googlemail.com Mon Apr 7 20:42:06 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Mon, 7 Apr 2008 21:42:06 +0100 Subject: [cells-devel] another redundant update Message-ID: Hi, This was mentioned a while ago and is causing a problem now. When an ajax request comes in, one of the things that gets updated is the input value. For example... old: ...user types in "progv" and hits TAB new: We want the model on the server to update itself to reflect this change but we don't need to send it down to the browser because the browser already knows. The problem this is causing (and this is something we'll need to take a mental note of for the future) is that the event binding for the input element is lost when that element is replaced. That means any actions after the first don't trigger an ajax request. We could rebind the event on the new element but I think its better not to send it in the first place. I think this would apply to all UI elements so if that's the case, the solution is probably to filter updates containing these elements the same way that ascendant and redundant nodes get filtered in the code below. (let ((updt (loop for (h . xh) in (updates self) unless (loop for (h2 . nil) in (updates self) thereis (unless (eq h h2) (when (fm-ascendant-p h2 h) (trc nil "suppressing redundant" h :seeing-ascendant h2 (id h2)) t))) collect xh))) I've pushed a new version out to the repo but haven't dealt with this problem yet. Another thing you might notice if you look at commented out code in the example is that the radio button at the bottom seems a bit verbose. Radiobuttons could probably do with a layer on top providing a nicer way of creating them. At the moment, user code has to create labels, manage the checked/unchecked status, and the value for each input. It should provide something like celtk's mk-radio -- Andy From kennytilton at optonline.net Mon Apr 7 21:16:13 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 07 Apr 2008 17:16:13 -0400 Subject: [cells-devel] another redundant update In-Reply-To: References: Message-ID: <47FA8F1D.4060402@optonline.net> Andy Chambers wrote: > Hi, > > This was mentioned a while ago and is causing a problem now. When an > ajax request comes in, one of the things that gets updated is the > input value. For example... > > old: > > ...user types in "progv" and hits TAB > > new: > > We want the model on the server to update itself to reflect this > change but we don't need to send it down to the browser because the > browser already knows. The problem this is causing (and this is > something we'll need to take a mental note of for the future) is that > the event binding for the input element is lost when that element is > replaced. That means any actions after the first don't trigger an > ajax request. > > We could rebind the event on the new element but I think its better > not to send it in the first place. > > I think this would apply to all UI elements so if that's the case, the > solution is probably to filter updates containing these elements the > same way that ascendant and redundant nodes get filtered in the code > below. > > (let ((updt (loop for (h . xh) in (updates self) > unless (loop for (h2 . nil) in (updates self) > thereis (unless (eq h h2) > (when (fm-ascendant-p h2 h) > (trc nil "suppressing redundant" h :seeing-ascendant h2 (id h2)) > t))) > collect xh))) > > I've pushed a new version out to the repo but haven't dealt with this > problem yet. Lessee. The update happens in the observer on the xhtml slot, which is passed the clos instance for the node along with the old and new values, inter alia. (defobserver xhtml ((self html)) (when new-value (trc nil "new xhtml for" self) (assert (u^ web-app)) (push (cons self (format nil "$(\"#~a\").html(\"~a\")" (^id) (js-escape new-value))) (updates (u^ web-app))))) I suggest you have an option or options on the clos node that controls whether the update gets sent: (mk-input (:name "s" :id "s" :-type "text" :send :once ;; default t (other constraints possible, ;; including a closure over other variables ;; that returns t to send, nil not :any-more-info 'needed-t-control :value (c? (term (u^ web-apropos))))) And then: (defobserver xhtml ((self html)) (when (and new-value (do-send self new-value old-vale)) (trc nil "new xhtml for" self) (assert (u^ web-app)) (push (cons self (format nil "$(\"#~a\").html(\"~a\")" (^id) (js-escape new-value))) (updates (u^ web-app))))) And: (defmethod do-send (self new-value old-value) (bwhen (s (send self)) (case s ((t) t) ; parens needed, long story (:once (not old-value)) (otherwise ; better be a function :) (funcall s self new-value old-value))))) Note I made it a method so one could just do: (defmethod ((self input) new old) (not old)) That might be too extreme -- perhaps we /do/ sometimes need to get an input field out there again, perhaps with a different binding, or even to do symbol-completion (weird in apropos, but just as an example) -- but the flexibility might help someday. Maybe start with a defun and see if a GF is ever needed. > > Another thing you might notice if you look at commented out code in > the example is that the radio button at the bottom seems a bit > verbose. Radiobuttons could probably do with a layer on top providing > a nicer way of creating them. At the moment, user code has to create > labels, manage the checked/unchecked status, and the value for each > input. It should provide something like celtk's mk-radio I'll look at this next. kt From kennytilton at optonline.net Mon Apr 7 21:30:26 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 07 Apr 2008 17:30:26 -0400 Subject: [cells-devel] another redundant update In-Reply-To: <47FA8F1D.4060402@optonline.net> References: <47FA8F1D.4060402@optonline.net> Message-ID: <47FA9272.7060306@optonline.net> Ken Tilton wrote: > Andy Chambers wrote: > >> Hi, >> >> This was mentioned a while ago and is causing a problem now. When an >> ajax request comes in, one of the things that gets updated is the >> input value. For example... >> >> old: >> >> ...user types in "progv" and hits TAB >> >> new: >> >> We want the model on the server to update itself to reflect this >> change but we don't need to send it down to the browser because the >> browser already knows. The problem this is causing (and this is >> something we'll need to take a mental note of for the future) is that >> the event binding for the input element is lost when that element is >> replaced. That means any actions after the first don't trigger an >> ajax request. >> >> We could rebind the event on the new element but I think its better >> not to send it in the first place. >> >> I think this would apply to all UI elements so if that's the case, the >> solution is probably to filter updates containing these elements the >> same way that ascendant and redundant nodes get filtered in the code >> below. >> >> (let ((updt (loop for (h . xh) in (updates self) >> unless (loop for (h2 . nil) in (updates self) >> thereis (unless (eq h h2) >> (when (fm-ascendant-p h2 h) >> (trc nil "suppressing >> redundant" h :seeing-ascendant h2 (id h2)) >> t))) >> collect xh))) >> >> I've pushed a new version out to the repo but haven't dealt with this >> problem yet. > > > Lessee. The update happens in the observer on the xhtml slot, which is > passed the clos instance for the node along with the old and new values, > inter alia. > > (defobserver xhtml ((self html)) > (when new-value > (trc nil "new xhtml for" self) > (assert (u^ web-app)) > (push (cons self (format nil "$(\"#~a\").html(\"~a\")" (^id) > (js-escape new-value))) > (updates (u^ web-app))))) > > I suggest you have an option or options on the clos node that controls > whether the update gets sent: > > (mk-input (:name "s" :id "s" > :-type "text" > :send :once ;; default t (other constraints possible, > ;; including a closure over other variables > ;; that returns t to send, nil not > :any-more-info 'needed-t-control > :value (c? (term (u^ web-apropos))))) > > And then: > > (defobserver xhtml ((self html)) > (when (and new-value (do-send self new-value old-vale)) > (trc nil "new xhtml for" self) > (assert (u^ web-app)) > (push (cons self (format nil "$(\"#~a\").html(\"~a\")" (^id) > (js-escape new-value))) > (updates (u^ web-app))))) > > And: > > (defmethod do-send (self new-value old-value) > (bwhen (s (send self)) > (case s > ((t) t) ; parens needed, long story > (:once (not old-value)) > (otherwise ; better be a function :) > (funcall s self new-value old-value))))) > > Note I made it a method so one could just do: > > (defmethod ((self input) new old) > (not old)) > > That might be too extreme -- perhaps we /do/ sometimes need to get an > input field out there again, perhaps with a different binding, or even > to do symbol-completion (weird in apropos, but just as an example) -- > but the flexibility might help someday. Maybe start with a defun and see > if a GF is ever needed. Hmmm, I just realized you are making a library that should be long on ease of use. Perhaps you /do/ want to have the user specifying a minimum as the default, in which case you might well want to special do-send on the input field, also have a 'send' parameter default to :once for input, t for most other things, and then have it all Just Work with fancy black belt behavior available by actually coding values for the :send option including closures, or subclassing input if they have lots of inputs that will have the same odd behavior. kt From kennytilton at optonline.net Tue Apr 8 01:23:10 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 07 Apr 2008 21:23:10 -0400 Subject: [cells-devel] another redundant update In-Reply-To: References: Message-ID: <47FAC8FE.7000701@optonline.net> Andy Chambers wrote: > Hi, > > This was mentioned a while ago and is causing a problem now. When an > ajax request comes in, one of the things that gets updated is the > input value. For example... > > old: > > ...user types in "progv" and hits TAB > > new: > > We want the model on the server to update itself to reflect this > change but we don't need to send it down to the browser because the > browser already knows. The problem this is causing (and this is > something we'll need to take a mental note of for the future) is that > the event binding for the input element is lost when that element is > replaced. That means any actions after the first don't trigger an > ajax request. > > We could rebind the event on the new element but I think its better > not to send it in the first place. > > I think this would apply to all UI elements so if that's the case, the > solution is probably to filter updates containing these elements the > same way that ascendant and redundant nodes get filtered in the code > below. > > (let ((updt (loop for (h . xh) in (updates self) > unless (loop for (h2 . nil) in (updates self) > thereis (unless (eq h h2) > (when (fm-ascendant-p h2 h) > (trc nil "suppressing redundant" h :seeing-ascendant h2 (id h2)) > t))) > collect xh))) > > I've pushed a new version out to the repo but haven't dealt with this > problem yet. > > Another thing you might notice if you look at commented out code in > the example is that the radio button at the bottom seems a bit > verbose. Radiobuttons could probably do with a layer on top providing > a nicer way of creating them. Here is what I did for the exported-only checkbox (untested): (defmacro mk-checkbox (label attribute &key top-args label-args input-args) `(mk-div (, at topargs) (mk-label (, at label-args :for ,(symbol-name attribute)) ,label) (mk-input (, at input-args :name ,(symbol-name attribute) :id ,(symbol-name attribute) :-type "checkbox" :checked (c? (,attribute (u^ page))) ; parameterize? :value (c? (,attribute (u^ page))))))) And then you can just do: (mk-checkbox "Exported Only" exported-only-p :top-args (:one 1 :two 2)) And to think they banned even a preprocessor from Java. :) Notes: 0. I mentioned first the idea of having a 'watched-parameter' slot on the checkbox. Above macrology lets me achieve even more succinctness without complicating the checkbox implementation which stays as minimal as possible. Who does not get macros?!!! :) 1. Observe that parameters for any node must be in their own list. 2. I added a common parent (an extra mk-div) but hopefully that is OK, seemes right anyway. If not, I have a work-around in mind, but macros only emit one form so it would take (probably) a "flatten" call ... hmmm, I suspect I am being daft: do these things end up going thru a the-kids form anyway, which would flatten any list so the outer mk-div could just be (list...)? Probably. 3. Will the top always be a page? Perhaps that is another parameter. 4. I started with an initial-value parameter then realized that is being set at the page level. Then I noticed both checked and value mirroring that. What I believe I have done (check Celtk) is have an intial-value slot whose observer sets the parameter of whatever node is being controlled (here the page). Actions on the checkbox likewise set the parameter of the controlled node. Then the checkbox value (as you have it) watches the parameter, but we at least author the parameter completely (including initialization) from the authoring of the checkbox. But I can see it going the other way, with the checkbox being, say, an optional interface to a page value that would possibly be maintained/originate elsewhere. Anyway, I am still curious about the checkbox/value redundancy. kt From kennytilton at optonline.net Tue Apr 8 12:20:11 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Tue, 08 Apr 2008 08:20:11 -0400 Subject: [cells-devel] another redundant update In-Reply-To: References: <47FAC8FE.7000701@optonline.net> Message-ID: <47FB62FB.1000807@optonline.net> Andy Chambers wrote: > On Tue, Apr 8, 2008 at 1:23 AM, Ken Tilton wrote: > >> Here is what I did for the exported-only checkbox (untested): >> >> (defmacro mk-checkbox (label attribute &key top-args label-args input-args) >> `(mk-div (, at topargs) >> (mk-label (, at label-args :for ,(symbol-name attribute)) >> ,label) >> (mk-input (, at input-args >> :name ,(symbol-name attribute) :id ,(symbol-name attribute) >> :-type "checkbox" >> :checked (c? (,attribute (u^ page))) ; parameterize? >> :value (c? (,attribute (u^ page))))))) > > > Cool. I wasn't trying to get you to do all the work but admittedly I > don't think I'd have come up with something so neat straight away. > Something similar should work for radiobuttons too. No work, really. I just took your code and turned it into a template by swapping out anything that would vary from use to use, throwing in backquotes and commas here and there. The tricky part is a CLOS issue: I can never remember whether to splice in additional initargs before or after the ones the macro wants to auto-provide. As I mentioned a while ago, auto is good but complete control for the user is also good, so we want them to be able to override something like :-type. You might think a second reference overrides the first. Nope, it is ignored. But I always forget between occasions when I am doing this and end up doing (describe (make-instance 'xxx :aa 1 :aa 2)) after defining the appropriate class to remind myself. > > >> And then you can just do: >> >> (mk-checkbox "Exported Only" exported-only-p >> :top-args (:one 1 :two 2)) >> >> And to think they banned even a preprocessor from Java. :) >> >> Notes: >> 0. I mentioned first the idea of having a 'watched-parameter' slot on the >>checkbox. Above macrology lets me achieve even more succinctness without >>complicating the checkbox implementation which stays as minimal as possible. >>Who does not get macros?!!! :) >> >> 1. Observe that parameters for any node must be in their own list. >> >> 2. I added a common parent (an extra mk-div) but hopefully that is OK, >>seemes right anyway. If not, I have a work-around in mind, but macros only >>emit one form so it would take (probably) a "flatten" call ... hmmm, I >>suspect I am being daft: do these things end up going thru a the-kids form >>anyway, which would flatten any list so the outer mk-div could just be >>(list...)? Probably. > > > Extra grouping elements never do any harm and are sometimes required > for fancy CSS. All those rounded corner tricks you see in "Web 2.0" > require the contained elements to be wrapped in at least one div and > depending on the technique used, sometimes 2 or 3. Great. > > >> 3. Will the top always be a page? Perhaps that is another parameter. > > > Probably. I'll try to think of an occasion where that wouldn't be the case. Maybe on an ecommerce page there would be a lits of items and for each the user has to select "size" or "color"? So the parameter "size" is for some sub-node, not the page? > > >> 4. I started with an initial-value parameter then realized that is being >>set at the page level. Then I noticed both checked and value mirroring that. >>What I believe I have done (check Celtk) is have an intial-value slot whose >>observer sets the parameter of whatever node is being controlled (here the >>page). Actions on the checkbox likewise set the parameter of the controlled >>node. Then the checkbox value (as you have it) watches the parameter, but we >>at least author the parameter completely (including initialization) from the >>authoring of the checkbox. But I can see it going the other way, with the >>checkbox being, say, an optional interface to a page value that would >>possibly be maintained/originate elsewhere. Anyway, I am still curious about >>the checkbox/value redundancy. > > > Sorry. That bit wasn't working correctly in the full version anyway > so I need to check that more thoroughly. As I understand it, > > value: is the initial value for the control > checked: is a "boolean" attribute > > In html, the mere presence of boolean attributes says that they're > true. Madness! > I think cl-who is clever about this so if we set it to nil, the > xml rule should just remove checked entirely from the attribute list. > In traditional web apps, when a user clicks the "submit" button, the > notion of "successful" forms is introduced to identify which controls > should be sent. A checkbox is successful if it has been checked. > When its successful, its added on to the request as a (key, value). > The key is the checkbox's :name. The value is its value. On the > server, you can tell by the absence of exported-only-p that the > control is unchecked. The nice thing is that future generations will never have to see this unpleasantness, they will think OpenAIR is reality. > > With our fine-grained control of what we're sending back though, we > may as well just send back "on"/"off" values for our checkboxes (or > 0/1 whatever). We can update the value on the js side (in fact, we > can just ignore the value completely and just decide what to send back > based on the checked state). I shall leave this to you. :) Lemme know if you get stuck. kt ps. As long as we are discussing Cells or macrology or OpenAIR or Lisp I think we should spam this list until you are ready to start a project on c-l.net for OpenAIR. I am thinking you need more than git, you want mailing list services as well. Or can gitorious do that? Or could c-l.net do git? I might ask later, git looks like fun. k From kennytilton at optonline.net Tue Apr 8 12:29:32 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Tue, 08 Apr 2008 08:29:32 -0400 Subject: [cells-devel] another redundant update In-Reply-To: <47FB62FB.1000807@optonline.net> References: <47FAC8FE.7000701@optonline.net> <47FB62FB.1000807@optonline.net> Message-ID: <47FB652C.20900@optonline.net> Ken Tilton wrote: > The tricky part is a CLOS issue: I can never remember whether to splice > in additional initargs before or after the ones the macro wants to > auto-provide. As I mentioned a while ago, auto is good but complete > control for the user is also good, so we want them to be able to > override something like :-type. > > You might think a second reference overrides the first. Nope, it is > ignored. But I always forget between occasions when I am doing this and > end up doing (describe (make-instance 'xxx :aa 1 :aa 2)) after defining > the appropriate class to remind myself. I just thought of a mnemonic: the initarg list is probably being treated as a plist, so the first of duplicates is the only one seen. kt From kennytilton at optonline.net Tue Apr 8 14:14:43 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Tue, 08 Apr 2008 10:14:43 -0400 Subject: [cells-devel] [openair] another redundant update In-Reply-To: References: <47FAC8FE.7000701@optonline.net> <47FB62FB.1000807@optonline.net> Message-ID: <47FB7DD3.30108@optonline.net> Andy Chambers wrote: > On Tue, Apr 8, 2008 at 12:20 PM, Ken Tilton wrote: > > >> ps. As long as we are discussing Cells or macrology or OpenAIR or Lisp I >>think we should spam this list until you are ready to start a project on >>c-l.net for OpenAIR. I am thinking you need more than git, you want mailing >>list services as well. Or can gitorious do that? Or could c-l.net do git? I >>might ask later, git looks like fun. > > > I wondered about that. Sorry to everyone who's on this list but not > interested openAIR. I think by the time the apropos demo is ready, > I'll start a c.l.net project. Until then, I'll prefix all my openair > questions with [openair] on the subject line so you can send them > straight to /dev/null if your not interested. Good idea. But this is a great thread for Cells -- folks subscribed are here only because I won't stop ranting about Cells on c.l.l. Meanwhile almost no one understands the point. Even Peter Seibel said he did not see the point. A project like OpenAIR is a practical application (Peter should understand "practical" ) and ideal because it shows Cells doing two things: the usual declarative dataflow between widgets and, two, driving a parallel framework, in this case web browsers. As for pure Cells afficionados, again, driving a hostile framework (I mean simply one that has a mind of its own so we have to adjust to its world view) will lead to some nice blackbelt Cells. eg, the way we used without-c-dependency to minimize output and then did further optimization in the observers was Good Stuff. Then noticing the flaw (grandparent-grandkid) and the ways of resolving it purely with Cells was more blackbeltery, tho with luck we can duck that with an XREF hack to imbue browsers with html object identity. Still, astute observers will get a kick out of how object identity (something any Lisper will honor and cherish) makes the excessive output problem go away (speaking of which, once you do that you can take out the without-c-dependency). kt From achambers.home at googlemail.com Tue Apr 8 22:20:47 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Tue, 8 Apr 2008 23:20:47 +0100 Subject: [cells-devel] [openair] redundant updates and mk-checkbox Message-ID: Hi Kenny, Just a quick note to mention various updates.... - reinstated the serverless test suite so that it works alongside hunch http://gitorious.org/projects/hunchncells/repos/mainline/commits/4c7bb90927 - added the mk-checkbox macro http://gitorious.org/projects/hunchncells/repos/mainline/commits/4a0795cb3 - prevention of redundant updates http://gitorious.org/projects/hunchncells/repos/mainline/commits/aa110dfe069 Cheers, Andy From kennytilton at optonline.net Wed Apr 9 06:58:51 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Wed, 09 Apr 2008 02:58:51 -0400 Subject: [cells-devel] [openair] redundant updates and mk-checkbox In-Reply-To: References: Message-ID: <47FC692B.6010906@optonline.net> Andy Chambers wrote: > Hi Kenny, > > Just a quick note to mention various updates.... > > - reinstated the serverless test suite so that it works alongside hunch > http://gitorious.org/projects/hunchncells/repos/mainline/commits/4c7bb90927 > > - added the mk-checkbox macro > http://gitorious.org/projects/hunchncells/repos/mainline/commits/4a0795cb3 > > - prevention of redundant updates > http://gitorious.org/projects/hunchncells/repos/mainline/commits/aa110dfe069 > > If I do this to move into aserve mode: (eval-when (compile load eval) (require :aserve) (pushnew :aserve *features*)) ;;;#+:use-hunch ;;;(defpackage :openair ;;; (:use :cl :utils-kt :cells :hunchentoot :cl-who)) (progn (print "using aserve...") (defpackage :openair (:use :cl :utils-kt :cells :net.aserve :net.uri :cl-who))) ;; (defpackage :openair ;; (:use :cl :utils-kt :cells :net.aserve :net.uri :cl-who)) ... I end up doing a series of quick patches every time, this time might have been worse but it is late and I am not really trying. :) btw, one solid esception to Lisp's flexibility: you cannot define do-send on the input class until after the compiler has encountered the class definition for input. I am out allll day tomorrow perhaps into thursday, catch you then. kt From kennytilton at optonline.net Wed Apr 9 07:28:24 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Wed, 09 Apr 2008 03:28:24 -0400 Subject: [cells-devel] [openair] redundant updates and mk-checkbox In-Reply-To: References: Message-ID: <47FC7018.6000107@optonline.net> I took a minute to look at what you were doing before crashing. Overall I gots to say you are coming up to speed on Lisp, macros, and Cells very nicely. :) The bad news is that I am not going to look too losely unless you yell for help, I gotta start getting ready for ECLM and the small matter of shipping my damn app. :) (defmd web-apropos (page) (term (c? (param? "term"))) (pkg (c? (param? "pkg"))) (exported-only-p (c? (let ((rslt (param? "EXPORTED-ONLY-P"))) (trc "exported" rslt) rslt))) (filter (c? (param? "filter"))) (result (c? (progn (trc "calculating result" (^term) (^pkg) (^exported-only-p) (^filter)) (bwhen (search (^term)) (apropos-list search (^pkg) (^exported-only-p)))))) (title "Lisp Apropos") (style "style.css") (kids (c? (the-kids (mk-div () (mk-form (:action "get") (mk-label (:for "term") "Apropos: ") (mk-input (:name "term" :id "term" :-type "text" :value (c? (term (u^ web-apropos))))) (mk-checkbox "Exported: " exported-only-p) (mk-text (c? (exported-only-p (u^ web-apropos)))) (mk-div (:id :result) (mk-ul () (list (loop for match in (result (u^ web-apropos)) collect (let ((match match)) (mk-li () (mk-text match))))))))))))) I just wanted to mention that once we implement XREF (object identity) this last rule for the kids can look like this: (loop for match in (result (u^ web-apropos)) collect (let ((m match)) (or (find m .cache :key 'value) (mk-li (:value m) (mk-text (value .parent)))))) [Note btw that by this time all the mk-whatevers will be returning the OID, not the xhtml. And I am sure I am messing things up. I do a lot of self-clarification as I code. ] The idea above is that there is a symbol-macro .cache (I think it is a symbol macro) that evaluates to the value calculated by the rule the last time, nil if there was no last time. So it is pretty easy to avoid regenerating the same kids. We could go even further and have one slot that takes the union of the cache and any new items that need to be created, while the kids slot then takes what it needs from that slot. That way if they winnow the list too much and then unwinnow all the xhtml will already exist. And once we do Cells/js, damn, it all can happen on the client side. Which raises the question of whether we love Parenscript. If not, hey, this is Lisp, we never use anyone else's code, we'll do our own. What I am envisioning is something like Franz's implementation of Prolog. We start in CL, then say (prolog... and now we are doing prolog, in the middle of which we can say (lisp... and do a computation in Lisp. I'd love to see rules default to server-side, but be able to say (client... blah blah stuff that needs to xlate to JS and cells-js and then possibly within that (server ... and now we are making a trip to the server to get some info. What would be scary would be to be able to some compiler-style analysis and determine the above automatically at run-time without requiring the developer to stop and think about which side of the broadband should be doing the job. kt From kennytilton at optonline.net Fri Apr 11 11:03:02 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 07:03:02 -0400 Subject: [cells-devel] Re: [cells-gtk-devel] Re: Anything new for me to show off at ECLM 2008? In-Reply-To: <7758b2680804110152k737d478fj8aed42b32f50a24c@mail.gmail.com> References: <47FE56B9.3070404@sentex.ca> <7758b2680804101211s5f9660dfhc056da5b72297894@mail.gmail.com> <47FE796D.6@optonline.net> <7758b2680804110152k737d478fj8aed42b32f50a24c@mail.gmail.com> Message-ID: <47FF4566.4080605@optonline.net> Peter Hildebrandt wrote: > Well, there's something wrong with the cells cvs again, so it would > not let me commit my latest changes. You can grab the latest version > here: > > http://www.washbear-network.de/fritz/pub/cells-gtk3.zip Hmmm, a little trouble there. PicoZip on WinXP cannot read it, WinZip on Vista (my new laptop for the eclm talk) complains but then seems to open it. The complaint looks like winzip just is not handling Vista. Maybe just tar.gz it? I appreciate the trouble you took making a zip, btw. Question 2: the above does not include a Cells directory (unless the expansion broke). I will be trying to build it (looks like I have to hack the ACL .lpr files for a while) in the meantime. > > My suggestions: > > (1) Cairo Drawing Area > > I have the cairo drawing area thing working by now and put in a simple > example (creates boxes and circles and random positions, then they > react on mouse over, can be selected, dragged around, and you can use > a select box (like in windows explorer) to select and move many shapes > at once). I finally took the time and get the kids slot to work > properly, so you can have ruled kids slots on your drawing primitives > and have cells create other shapes for you (say, you want to draw a > sun -- then you start with a yellow filled circle and have a kids rule > creating some lines for the rays. The number of rays may depend on a > widget (and so can the length), and you have a "declarative drawing"). Isn't that fun? I remember when we made kids a Cell (almost immediately). I was sure the wheels would fall off. It Just Worked(tm) and I started to suspect Cells would scale pretty well. > > (2) Tree View > >>From the stuff present in the demo I personally like the tree view > example, since it lets you explore the actual object hierarchy of the > demo. I don't even know whethe something like this could be done in C > at all. Omigod! I did an inspector at one point and used it to inspect the inspector window itself. Then I navigated down to the actual widgets in view and watched as the inspector showed things like the mouse-over state dynamically (without asking the inspector to refresh). I seem to recall adding some Cells internals to make it work, tho. In this screenshot: http://www.tilton-technology.com/cloucell.jpg ...the widget being inspected is the four-widget row just above "Class: Ixrow". > > (3) Cells Tree View > > Works like a charm -- as long as you don't delete stuff from the > observed structure (I ran into a conceptual problem with cells3 here, > gonna ask you on the cells list when I have the time to deal with > that). Anyway, I deactivated the delete button, and the rest is still > pretty nice. I look forward to the IR, maybe you have run into something I want to add to Cells to better handle things going away (a frequent problem). In my latest app I am running into a lot of problems with what is generally called referential integrity, specifically external references to kids that have been not-to-be'd. eg, my window's keep a reference to the "focus", which might be in a math problem the student decides to delete. uh-oh. Sprinkling (setf (focus w) nil) all over the place broke down when it ended up erasing a new value that had been set by code that tried to handle the problem by, say, moving the focus to the next problem when deleting the current problem. Man, imperative programming sucks. :) > > (4) Threading > > It is relly nice and lispy to use the repl to change properties of the > windows currently displayed and to add and remove widgets > interactively (especially if you have a background in C) -- but I > don't know whether that works in MS Windows. Just checked, > bordeaux-threads on windows does not support Allegro. Bummer. I will be doing repl stuff during my talk -- ACL runs a separate process from the IDE to execute Lisp. We just need to have a breather in the event loop handling to give the IDE enough cycles to be responsive. > > (5) MAYBE: cells-ode + open gl > > That'd be really neat -- if I figure out the opengl drawing area and > port my current physics simulator code to cells-ode as a backend plus > gtk-gl as a front end. They say there's a weekend coming up, so stay > tuned. OK, don't make yourself crazy on my account. In fact, I already have Cells-gtk as I had it last running on my laptop, I might just leave it at that. I am going to try to get to Celtk, Cello, TripleCells (lite integration with an RDF triple-store), Cells-Gtk, and OpenAIR (the cells/ajax bit andy is doing). Whew! cheers, ken From achambers.home at googlemail.com Fri Apr 11 11:22:00 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Fri, 11 Apr 2008 11:22:00 +0000 Subject: [cells-devel] Re: [cells-gtk-devel] Re: Anything new for me to show off at ECLM 2008? In-Reply-To: <47FF4566.4080605@optonline.net> References: <47FE56B9.3070404@sentex.ca> <7758b2680804101211s5f9660dfhc056da5b72297894@mail.gmail.com> <47FE796D.6@optonline.net> <7758b2680804110152k737d478fj8aed42b32f50a24c@mail.gmail.com> <47FF4566.4080605@optonline.net> Message-ID: > OK, don't make yourself crazy on my account. In fact, I already have > Cells-gtk as I had it last running on my laptop, I might just leave it at > that. I am going to try to get to Celtk, Cello, TripleCells (lite > integration with an RDF triple-store), Cells-Gtk, and OpenAIR (the > cells/ajax bit andy is doing). Whew! Will they be recording this stuff? I've seen you mention the TripleCells stuff before and am intrigued. Is it basically automatic serialization of cells instances? That would be the best database ever! You could define a lispy report language that had access to a directory full of cells families. -- ac From kennytilton at optonline.net Fri Apr 11 11:49:41 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 07:49:41 -0400 Subject: [cells-devel] Re: [cells-gtk-devel] Re: Anything new for me to show off at ECLM 2008? In-Reply-To: References: <47FE56B9.3070404@sentex.ca> <7758b2680804101211s5f9660dfhc056da5b72297894@mail.gmail.com> <47FE796D.6@optonline.net> <7758b2680804110152k737d478fj8aed42b32f50a24c@mail.gmail.com> <47FF4566.4080605@optonline.net> Message-ID: <47FF5055.1050302@optonline.net> Andy Chambers wrote: >> OK, don't make yourself crazy on my account. In fact, I already have >>Cells-gtk as I had it last running on my laptop, I might just leave it at >>that. I am going to try to get to Celtk, Cello, TripleCells (lite >>integration with an RDF triple-store), Cells-Gtk, and OpenAIR (the >>cells/ajax bit andy is doing). Whew! > > > Will they be recording this stuff? We'll be trying. :) > I've seen you mention the > TripleCells stuff before and am intrigued. Is it basically automatic > serialization of cells instances? That would be the best database > ever! Scary right? The database -- it's alive!!! I actually did that on the trial management project, which was different because that itself was persistent CLOS. RDF is just this lower-level deal, but as such could readily adapt to being a persistent CLOS-alike. But on the CTM project we had Franz's full-blown persistent CLOS implementation dancing to the Cells: a persistent slot could depend on other persistent slots of the same or other persistent instances. s dynamic slot of a persistent instance could depend on persistent or non-persistent slots. dynamic instances could depend on persistent or dynamic slots of persistent instances And then I added a couple of things, one of which was depending on the /population/ of a peristent class, kind of like depending on a dynamic kids slot. Then we added a little IPC so one process could scan in a new document and then another process showing a GUI list widget of documents would suddenly show a new one -- no "refresh view" required. Only took a couple of weeks, IIRC, in part because Franz did a nice job on their metaclass and Cells at the time was metaclass based. > You could define a lispy report language that had access to a > directory full of cells families. Sure. You could do something like have the report itself be a DB object and have it automatically updated when its inputs changed, with suitable laziness so it does not regenerate itself on every I/O. A lot of times one gets batches of reports that require a common view of the DB and shops write extraction programs to generate a pre-digested breakdown off which several reports can run. And it is a great way to get tons of business logic into the database. Our favorite trick was to scan in two pages of a three page form. 2dbarcodes linked a page back to the DB form (we generated documents from the DB as well as scanned and ICRed them) so we knew how many pages to expect. The code to scan just wrote out what it found, but the Cells logic said "there is a missing page error" on this form simply with a rule that looked like: (cond ((< ) (make-instance 'user-error .... etc etc where user-error was a persistent class. Slot-values linked it to the form in question, so anyone opening the application immediately saw a hot list of problems. It was trivial then to add code to show them the form with the problem and the scan history related to that form, and because of our audit trail we could also tell them which user had done the scanning on which machine. Made for great demo. :) So far the RDF version is just very light proof of concept, I do not really need it, just thought it would be fun to do and only took a couple of days. Back to OpenAIR... kt From frgo at mac.com Fri Apr 11 14:51:53 2008 From: frgo at mac.com (Frank Goenninger) Date: Fri, 11 Apr 2008 16:51:53 +0200 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... Message-ID: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> Andy, I have tried to get this to work: --- BEGIN OF FILE --- (in-package #:openair) (defvar *web-app*) (defparameter *server* nil) (defun ht-monitor-page (path resource-class) (lambda (request) (start-session) (let ((root (or (session-value 'root) (mk-web-app (:prefix path :request (c-in request)) (make-instance resource-class :fm-parent *parent*))))) (setf *web-app* root) (setf (session-value 'root) root) (setf (request root) request) (handler root)))) (defmd ht-monitor (page) name ip-address term :title ":: HUNCHENTOOT MONITOR ::" :style "/css/ht-monitor.css" :name (c? (server-name *server*)) :ip-address (c_? (server-address *server*)) :term (c-in "") :kids (c? (the-kids (mk-div () (mk-text (c? (conc$ "Name: " (name (u^ ht-monitor))))) (mk-div () (mk-text (c? (conc$ "IP Address: " (ip-address (u^ ht- monitor))))))) (mk-form (:action "get") (mk-label (:for "i") (mk-text "Input: ")) (mk-input (:name "i" :id "i" :-type "text" :value (c? (reverse (term (u^ ht- monitor))))))) (mk-div () (mk-text (c? (conc$ "Reversed: " (reverse (term (u^ ht-monitor))))))) ))) (defun start-ht-monitor () (cells-reset) (reset-sessions) (setf *catch-errors-p* nil) (setf *print-circle* nil) (setf *dispatch-table* (list (ht-monitor-page "/ht-monitor" 'ht-monitor) (create-static-file-dispatcher-and-handler "/index.html" "/Users/frgo/projects/gt/app/ht-monitor/index.html") (create-folder-dispatcher-and-handler "/css/" "/Users/frgo/projects/gt/app/ht-monitor/css/") (create-folder-dispatcher-and-handler "/js/" "/opt/common-lisp/openair/js/"))) (when *server* (hunchentoot:stop-server *server*)) (setq *server* (hunchentoot:start-server :name "frgo's HT MONITOR" :port 4242 :dispatch-table *dispatch-table* ))) (export! start-ht-monitor) --- END OF FILE --- Symptoms: 1. No updates received from Web browser 2. When trying to update a slot on a page model I do not get any update of the Web page ... Is the git repo somehow in an "intermediate state" ? - I seem to remember you saying so in some email. Appreciate your feedback. Best, Frank From achambers.home at googlemail.com Fri Apr 11 15:11:55 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Fri, 11 Apr 2008 15:11:55 +0000 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> Message-ID: On Fri, Apr 11, 2008 at 2:51 PM, Frank Goenninger wrote: > Andy, > Symptoms: > > 1. No updates received from Web browser > 2. When trying to update a slot on a page model I do not get any update of > the Web page ... > > Is the git repo somehow in an "intermediate state" ? - I seem to remember > you saying so in some email. > Appreciate your feedback. I thought that what I pushed last night would have worked but Kenny seems to be having problems too. What's your platform? Do you have firebug running? Maybe there's some javascript errors that could give us a clue. I'll load your example up and take a closer look when I get home this evening. In the meantime, can you post the output of "git show" Cheers, Andy From frgo at mac.com Fri Apr 11 15:53:13 2008 From: frgo at mac.com (Frank Goenninger) Date: Fri, 11 Apr 2008 17:53:13 +0200 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> Message-ID: <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> Andy, thanks for quick feedback. Details you requested see below. Am 11.04.2008 um 17:11 schrieb Andy Chambers: > On Fri, Apr 11, 2008 at 2:51 PM, Frank Goenninger > wrote: >> Andy, > >> Symptoms: >> >> 1. No updates received from Web browser >> 2. When trying to update a slot on a page model I do not get any >> update of >> the Web page ... >> >> Is the git repo somehow in an "intermediate state" ? - I seem to >> remember >> you saying so in some email. >> Appreciate your feedback. > > I thought that what I pushed last night would have worked but Kenny > seems to be having problems too. What's your platform? Mac OS X 10.5.2 > Do you have > firebug running? Maybe there's some javascript errors that could give > us a clue. Firebug is running. Does not show javascript errors. > I'll load your example up and take a closer look when I get home > this evening. Thanks! > > > In the meantime, can you post the output of "git show" Sure: 1.) Did a git fetch again to make sure I have latest sources. 2.) Git show produces: commit 4a0795cb335d226c51c61e82edc342d01e26e14d Author: Andy Chambers Date: Tue Apr 8 22:59:09 2008 +0100 added high-level macro to help making checkboxes diff --git a/example.lisp b/example.lisp index 2f6b2d9..030f7d3 100755 --- a/example.lisp +++ b/example.lisp @@ -57,17 +57,28 @@ See the Lisp Lesser GNU Public License for more details. (progn (declaim (optimize (debug 3) (speed 0) (safety 1) (compilation- speed 0)))) +(defmd web-checkbox (page) + (status (c? (param? "STATUS"))) + (kids (c? (the-kids + (mk-div () + (mk-form (:action "get") + (mk-checkbox "Status: " status) + (mk-div () + (mk-text (status (u^ web-checkbox)))))))))) + (defmd web-apropos (page) (term (c? (param? "term"))) (pkg (c? (param? "pkg"))) - (exports-onlyp (c? (param? "exports-onlyp"))) + (exported-only-p (c? (let ((rslt (param? "EXPORTED-ONLY-P"))) + (trc "exported" rslt) + rslt))) (filter (c? (param? "filter"))) (result (c? (progn - (trc "calculating result" (^term) (^pkg) (^exports- onlyp) (^filter)) + (trc "calculating result" (^term) (^pkg) (^exported- only-p) (^filter) ) (bwhen (search (^term)) (apropos-list search (^pkg) - (^exports-onlyp)))))) + (^exported-only-p)))))) (title "Lisp Apropos") (style "style.css") (kids (c? (the-kids @@ -79,6 +90,10 @@ See the Lisp Lesser GNU Public License for more details. :-type "text" :value (c? (term (u^ web-apropos))))) + (mk-checkbox "Exported: " exported-only-p) + + (mk-text (c? (exported-only-p (u^ web-apropos)))) + (mk-div (:id :result) (mk-ul () (list @@ -244,6 +259,7 @@ See the Lisp Lesser GNU Public License for more details. (setf *catch-errors-p* nil *dispatch-table* (list + (test-page "/check-test" 'web-checkbox) (test-page "/apropos" 'web-apropos) (create-folder-dispatcher-and-handler "/js/" "/home/andy/asdf/ hunchncells/js/")))) diff --git a/forms.lisp b/forms.lisp index 4f64383..5b73012 100755 --- a/forms.lisp +++ b/forms.lisp @@ -21,6 +21,8 @@ See the Lisp Lesser GNU Public License for more details. (progn (declaim (optimize (debug 3) (speed 0) (safety 1) (compilation- speed 0)))) +;;; Vanilla HTML + (defhtml form () () (:attrs form @@ -63,3 +65,18 @@ See the Lisp Lesser GNU Public License for more details. (:attrs button :name :value (:-type :type) :disabled :tabindex :accesskey :onfocus :onblur)) + + +;;; Higher Level Widgets + +(defmacro mk-checkbox (label attribute &key top-args label-args input- args) + `(mk-div (, at top-args) + (mk-label (, at label-args :for ,(symbol-name attribute)) + ,label) + (mk-input (, at input-args + :name ,(symbol-name attribute) :id ,(symbol-name attribute) + :-type "checkbox" + :checked (c? (,attribute (u^ page))) ; parameterize? + :value (c? (if (,attribute (u^ page)) + "on" + "off")))))) diff --git a/js/openair.js b/js/openair.js index d753879..c2e5c7f 100644 --- a/js/openair.js +++ b/js/openair.js @@ -6,7 +6,16 @@ function recv (data) { } } -function send (obj, e) { +function send_checkbox (obj, e) { + var request = {}; + var msg = obj.checked ? "on": "off"; + request[obj.id] = msg; + $.get(location.href + "/" + obj.id, + request, + recv); +} + +function send_text (obj, e) { var request = {}; switch(e.type) { case "keyup": @@ -29,8 +38,11 @@ $(document).ready(function(){ // $(":input").keyup(function(e) { // send(this, e); // }); - $(":input").change(function(e) { - send(this, e); + $(":input[type='text'").change(function(e) { + send_text(this, e); + }); + $(":input[type='checkbox']").change(function(e) { + send_checkbox(this, e); }); }); Oh - now I see the potential problem: These "//" ... I will test... Best, Frank > > Cheers, > Andy > _______________________________________________ > cells-devel site list > cells-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cells-devel From kennytilton at optonline.net Fri Apr 11 15:57:31 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 11:57:31 -0400 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> Message-ID: <47FF8A6B.2090101@optonline.net> Andy Chambers wrote: > On Fri, Apr 11, 2008 at 2:51 PM, Frank Goenninger wrote: > >>Andy, > > >> Symptoms: >> >> 1. No updates received from Web browser >> 2. When trying to update a slot on a page model I do not get any update of >>the Web page ... >> >> Is the git repo somehow in an "intermediate state" ? - I seem to remember >>you saying so in some email. >> Appreciate your feedback. > > > I thought that what I pushed last night would have worked but Kenny > seems to be having problems too. !!!!!!!!!!! Woo-hoo !!!!!!!!!!!!!!! (it's working. more soon.) (I had to mode the js directory to the toplevel of my drive and rename the jsquery...js as you suggested. kt What's your platform? Do you have > firebug running? Maybe there's some javascript errors that could give > us a clue. > > I'll load your example up and take a closer look when I get home this evening. > > In the meantime, can you post the output of "git show" > > Cheers, > Andy > _______________________________________________ > cells-devel site list > cells-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cells-devel > From frgo at mac.com Fri Apr 11 16:16:32 2008 From: frgo at mac.com (Frank Goenninger) Date: Fri, 11 Apr 2008 18:16:32 +0200 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> Message-ID: Found something: Am 11.04.2008 um 17:53 schrieb Frank Goenninger: > +function send_text (obj, e) { > var request = {}; > switch(e.type) { > case "keyup": > @@ -29,8 +38,11 @@ $(document).ready(function(){ > // $(":input").keyup(function(e) { > // send(this, e); > // }); > - $(":input").change(function(e) { > - send(this, e); > + $(":input[type='text'").change(function(e) { > + send_text(this, e); > + }); > + $(":input[type='checkbox']").change(function(e) { > + send_checkbox(this, e); > }); > }); > > Oh - now I see the potential problem: These "//" ... I will test... And right there it is: $(document).ready(function(){ // $(":input").keyup(function(e) { // send(this, e); // }); $(":input[type='text']").keyup(function(e) { send_text(this, e); }); $(":input[type='checkbox']").change(function(e) { send_checkbox(this, e); }); }); Two things: 1.) I had to change the line $(":input[type='text']").keyup(function(e) { the "]" was missing after 'text' ... 2.) I had to change the event type to "keyup" for the text input in order to really get every key stroke sent over to the server. That's the behaviour I am used to from using Celtk and Cello... Now I am back in the game again. Cheers, Frank From kennytilton at optonline.net Fri Apr 11 16:19:36 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 12:19:36 -0400 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> Message-ID: <47FF8F98.4050905@optonline.net> Frank Goenninger wrote: > Andy, > > thanks for quick feedback. Details you requested see below. > > Am 11.04.2008 um 17:11 schrieb Andy Chambers: > >> On Fri, Apr 11, 2008 at 2:51 PM, Frank Goenninger wrote: >> >>> Andy, >> >> >>> Symptoms: >>> >>> 1. No updates received from Web browser >>> 2. When trying to update a slot on a page model I do not get any >>> update of >>> the Web page ... >>> >>> Is the git repo somehow in an "intermediate state" ? - I seem to >>> remember >>> you saying so in some email. >>> Appreciate your feedback. >> >> >> I thought that what I pushed last night would have worked but Kenny >> seems to be having problems too. [Typo fixed and Frank CCed] "I had to /move/ the js directory to the toplevel of my drive and rename the jsquery.what.ever.js as you suggested because of the symlink issue." FG probably does not have the symlink issue. How about a toplevel /js? kt ps. damn, andy, you have to hire a support team already. :) kt From achambers.home at googlemail.com Fri Apr 11 16:22:23 2008 From: achambers.home at googlemail.com (Andy Chambers) Date: Fri, 11 Apr 2008 16:22:23 +0000 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: <47FF8F98.4050905@optonline.net> References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> <47FF8F98.4050905@optonline.net> Message-ID: > ps. damn, andy, you have to hire a support team already. :) kt Isn't that you guys :-) -- ac From frgo at mac.com Fri Apr 11 16:26:25 2008 From: frgo at mac.com (Frank Goenninger) Date: Fri, 11 Apr 2008 18:26:25 +0200 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: <47FF8F98.4050905@optonline.net> References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> <47FF8F98.4050905@optonline.net> Message-ID: Am 11.04.2008 um 18:19 schrieb Ken Tilton: > > "I had to /move/ the js directory to the toplevel of my drive and > rename the jsquery.what.ever.js as you suggested because of the > symlink issue." > > FG probably does not have the symlink issue. How about a toplevel /js? No, I don't have the issue (I am using a mature OS here ;-). Please don't introduce a toplevel /js - this "pollutes" the directory structure... I am installing apps under "/opt/app-name/" - so OpenAIR lives in /opt/common-lisp/openair and the JS directory is /opt/common- lisp/openair/js - works really well. Best, Frank From kennytilton at optonline.net Fri Apr 11 16:28:53 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 12:28:53 -0400 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> Message-ID: <47FF91C5.6@optonline.net> Frank Goenninger wrote: > Found something: > > Am 11.04.2008 um 17:53 schrieb Frank Goenninger: > >> +function send_text (obj, e) { >> var request = {}; >> switch(e.type) { >> case "keyup": >> @@ -29,8 +38,11 @@ $(document).ready(function(){ >> // $(":input").keyup(function(e) { >> // send(this, e); >> // }); >> - $(":input").change(function(e) { >> - send(this, e); >> + $(":input[type='text'").change(function(e) { >> + send_text(this, e); >> + }); >> + $(":input[type='checkbox']").change(function(e) { >> + send_checkbox(this, e); >> }); >> }); >> >> Oh - now I see the potential problem: These "//" ... I will test... > > > And right there it is: Woo-hoo! > > $(document).ready(function(){ > // $(":input").keyup(function(e) { > // send(this, e); > // }); > $(":input[type='text']").keyup(function(e) { > send_text(this, e); > }); > $(":input[type='checkbox']").change(function(e) { > send_checkbox(this, e); > }); > }); > > Two things: > > 1.) I had to change the line > > $(":input[type='text']").keyup(function(e) { > > the "]" was missing after 'text' ... > > 2.) I had to change the event type to "keyup" for the text input in > order to really get every key stroke sent over to the server. That's > the behaviour I am used to from using Celtk and Cello... Oh, cool, I'll try that, makes for great demo! But the behavior you observed might derive from the spec I gave Andy, shown atop the example.lisp file. The salient part: ";; Oh, and the input field is also a pop-up of the query history (which ;; would not make sense if each keystroke was treated as a new query." ie, it would be a pretty big pop-up if each keystroke was a new query. (I am just guessing at Franz's rationale.) kt From kennytilton at optonline.net Fri Apr 11 16:44:38 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 12:44:38 -0400 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> Message-ID: <47FF9576.6030301@optonline.net> Frank Goenninger wrote: > Found something: > > Am 11.04.2008 um 17:53 schrieb Frank Goenninger: > >> +function send_text (obj, e) { >> var request = {}; >> switch(e.type) { >> case "keyup": >> @@ -29,8 +38,11 @@ $(document).ready(function(){ >> // $(":input").keyup(function(e) { >> // send(this, e); >> // }); >> - $(":input").change(function(e) { >> - send(this, e); >> + $(":input[type='text'").change(function(e) { >> + send_text(this, e); >> + }); >> + $(":input[type='checkbox']").change(function(e) { >> + send_checkbox(this, e); >> }); >> }); >> >> Oh - now I see the potential problem: These "//" ... I will test... > > > And right there it is: > > $(document).ready(function(){ > // $(":input").keyup(function(e) { > // send(this, e); > // }); > $(":input[type='text']").keyup(function(e) { > send_text(this, e); > }); > $(":input[type='checkbox']").change(function(e) { > send_checkbox(this, e); > }); > }); > > Two things: > > 1.) I had to change the line > > $(":input[type='text']").keyup(function(e) { > > the "]" was missing after 'text' ... Hunh, did you have the latest openair.js? Mine looks OK in that regard. > > 2.) I had to change the event type to "keyup" for the text input in > order to really get every key stroke sent over to the server. I tried with no luck: $(document).ready(function(){ // $(":input").keyup(function(e) { // send(this, e); // }); $(":input[type='text']").keyup(function(e) { // kt: keyup was change send_text(this, e); }); $(":input[type='checkbox']").change(function(e) { send_checkbox(this, e); }); $("select").change(function(e) { send_select(this,e); }); }); I did a reload from the browser as well, I am just not sure that means the browser thinks to get a new openair.js as well. Or did I miss something else? I will be bouncing things over here trying to get my browser's attention.... kt From frgo at mac.com Fri Apr 11 16:53:25 2008 From: frgo at mac.com (Frank Goenninger) Date: Fri, 11 Apr 2008 18:53:25 +0200 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: <47FF91C5.6@optonline.net> References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> <47FF91C5.6@optonline.net> Message-ID: <8F105FB1-164F-4830-8695-86F32ED5476C@mac.com> Am 11.04.2008 um 18:28 schrieb Ken Tilton: > Oh, cool, I'll try that, makes for great demo! But the behavior you > observed might derive from the spec I gave Andy, shown atop the > example.lisp file. The salient part: > > ";; Oh, and the input field is also a pop-up of the query history > (which > ;; would not make sense if each keystroke was treated as a new query." > > ie, it would be a pretty big pop-up if each keystroke was a new > query. (I am just guessing at Franz's rationale.) Which brings up a very good point: Do we try to mimic Celtk and Cello really just as a RIA ? Or not? If not then what actually is the goal beyond having fun with some new technology - which is good in itself, no question about that... Just that I know what we will aim at ... Cheers - Frank From kennytilton at optonline.net Fri Apr 11 17:08:27 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 13:08:27 -0400 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: <8F105FB1-164F-4830-8695-86F32ED5476C@mac.com> References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> <47FF91C5.6@optonline.net> <8F105FB1-164F-4830-8695-86F32ED5476C@mac.com> Message-ID: <47FF9B0B.4000305@optonline.net> Frank Goenninger wrote: > > Am 11.04.2008 um 18:28 schrieb Ken Tilton: > >> Oh, cool, I'll try that, makes for great demo! But the behavior you >> observed might derive from the spec I gave Andy, shown atop the >> example.lisp file. The salient part: >> >> ";; Oh, and the input field is also a pop-up of the query history (which >> ;; would not make sense if each keystroke was treated as a new query." >> >> ie, it would be a pretty big pop-up if each keystroke was a new >> query. (I am just guessing at Franz's rationale.) > > > Which brings up a very good point: > > Do we try to mimic Celtk and Cello really just as a RIA ? Or not? If > not then what actually is the goal beyond having fun with some new > technology - which is good in itself, no question about that... > > Just that I know what we will aim at ... I am not clear on the choices/distinctions you see, and I do not mean that in the funny way academics use it to say "Nonsense!", I mean that I really am not sure about what you mean. Let me just clarify and expand on what I said to move the ball along -- I thought of another reason keystroke-by-keystroke on the apropos field would not work after I made your change and was about to type "m" and (had it worked and with the exported-only option off) was braced to see, what? a third of the symbols in my Lisp environment? :) Actually, we could do that if we did a scrolling list of, oh, twenty items and was lazy about generating the html, a definite future direction. But! I was just talking about this one design decision, not saying every text input field should work this way. Clearly we want a field by field choice. We can go OO and create a class of input field (er, can we?) and have an eager field or a lazier field, or maybe we can add an attribute such as eager or lazy and extend openair.js to look for that, or maybe there is some even more powerful way that would not require forver extending openair.js, such as optionally providing on- handlers for any event for any widget. I am thinking coding rules on the Lisp side that get Parenscripted into JS and sent over witht he widget. Note that I am making this all up, I do not know what is possible, but in answer to the general question I am hearing,... ... no. No compromises in functionality. Whatever Ajax/browsers can handle we should be able to provide to the web author with the kind of fine-grained control I hand-waved about above. cheers, kenny From peter.hildebrandt at gmail.com Fri Apr 11 18:00:19 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Fri, 11 Apr 2008 20:00:19 +0200 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids Message-ID: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> Ken, as discussed in the ECLM thread: > I look forward to the IR, maybe you have run into something I want to add > to Cells to better handle things going away (a frequent problem). In my > latest app I am running into a lot of problems with what is generally called > referential integrity, specifically external references to kids that have > been not-to-be'd. eg, my window's keep a reference to the "focus", which > might be in a math problem the student decides to delete. uh-oh. Sprinkling > (setf (focus w) nil) all over the place broke down when it ended up erasing > a new value that had been set by code that tried to handle the problem by, > say, moving the focus to the next problem when deleting the current problem. What happens in my case is that I have one family observing another like (defmodel observer (family) () (:default-initargs :kids (kids-list? (loop for kid in (kids (value self)) collecting (make-instance 'observer :value kid :fm-parent *parent*))))) Then, when we remove a kid in the observed tree, its kids are declared md-dead *before* the observers on those are disposed of, and immediately cells complains about accessing a dead cell. I am at a loss here, so any insight is greatly appreciated. My second question sounds really simple: I want to define a list of kids in an input slot, like (make-instance 'node :kids (c-in (list (make-instance 'node)))) Obviously I am missing the :fm-parent initarg here, so it won't work. But: How do I get the :fm-parent properly assigned for a (c-in initform)? Thanks, Peter From kennytilton at optonline.net Fri Apr 11 19:05:37 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 15:05:37 -0400 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> Message-ID: <47FFB681.8040106@optonline.net> Peter Hildebrandt wrote: > Ken, > > as discussed in the ECLM thread: > > >> I look forward to the IR, maybe you have run into something I want to add >>to Cells to better handle things going away (a frequent problem). In my >>latest app I am running into a lot of problems with what is generally called >>referential integrity, specifically external references to kids that have >>been not-to-be'd. eg, my window's keep a reference to the "focus", which >>might be in a math problem the student decides to delete. uh-oh. Sprinkling >>(setf (focus w) nil) all over the place broke down when it ended up erasing >>a new value that had been set by code that tried to handle the problem by, >>say, moving the focus to the next problem when deleting the current problem. > > > What happens in my case is that I have one family observing another like > > (defmodel observer (family) > () > (:default-initargs :kids (kids-list? (loop for kid in (kids (value > self)) collecting (make-instance 'observer :value kid :fm-parent > *parent*))))) > > Then, when we remove a kid in the observed tree, its kids are declared > md-dead *before* the observers on those are disposed of, and > immediately cells complains about accessing a dead cell. > > I am at a loss here, so any insight is greatly appreciated. I was thinking while doing the dishes. I can image the observer class being interesting in its own right, and slots over there ending up dependent on the same original kids-list in some way, as well of course as the value of the observer. Propagation would then try to update this slot and when it got to the value of the observer find a dead instance. Any rule that got to the value of the observer by accessing the list of observers (say something iterating over them) would not encounter such an observer/value, but rules lower down that get at the value directly will. Now normally this is not a problem because such lower down rules would tend not to depend also on the original list, and indeed the reason I have left this unaddressed is that in most cases I have seen a simple way to rewrite my rules that was even better and which did not end up with these widespread dependencies (if you have followed me so far on that, and if I hasten to add all this guesswork is on the money). I like to hold out for Real Problems before whacking away at the code, I think that is a slippery slope. btw, all that stuff in their that worries about dead instances is preemptive safeguard stuff -- I think if you disable that most things will just work. The rules that are failing now will run harmlessly and in a few cycles everything gets cleaned up anyway. Cells ran for /years/ with this happening to no ill effect (until RoboCup, of all things). If you want to send me your whole project I will look to see how I would rewrite the rules if that is even possible, and if not take a look at solving this formally. fyi, in the past I have done silly things like having Cells just return nil on slot-value access to dead cells, but we may want to find something more elegant. :) kt From kennytilton at optonline.net Fri Apr 11 19:45:04 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 15:45:04 -0400 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> <47FF8F98.4050905@optonline.net> Message-ID: <47FFBFC0.1050006@optonline.net> Frank Goenninger wrote: > > Am 11.04.2008 um 18:19 schrieb Ken Tilton: > >> >> "I had to /move/ the js directory to the toplevel of my drive and >> rename the jsquery.what.ever.js as you suggested because of the >> symlink issue." >> >> FG probably does not have the symlink issue. How about a toplevel /js? > > > No, I don't have the issue (I am using a mature OS here ;-). Please > don't introduce a toplevel /js - this "pollutes" the directory > structure... I am installing apps under "/opt/app-name/" - so OpenAIR > lives in /opt/common-lisp/openair and the JS directory is /opt/common- > lisp/openair/js - works really well. Hey, I am in monkey-mode over here, I saw the browser asking for "/js/openair.js" and I made it happen, I am just dying to see (+ cells ajax). Left for another day was whether I could have changed one of a dozen parameters incomprehensible to my monkey mind in order to get the browser to ask for a different file. How /are/ your browser/js skills, btw? I will start CCing you on questions that arise in that area in case you are on-line sooner than Andy and can throw me a banana. kt From frgo at mac.com Fri Apr 11 19:53:48 2008 From: frgo at mac.com (Frank Goenninger) Date: Fri, 11 Apr 2008 21:53:48 +0200 Subject: [cells-devel] OpenAIR: Doesn't work for me any more ... In-Reply-To: <47FFBFC0.1050006@optonline.net> References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> <47FF8F98.4050905@optonline.net> <47FFBFC0.1050006@optonline.net> Message-ID: <93B6AB85-6A45-4C3D-88C9-7B9C4F35A844@mac.com> Am 11.04.2008 um 21:45 schrieb Ken Tilton: > Frank Goenninger wrote: >> Am 11.04.2008 um 18:19 schrieb Ken Tilton: >>> >>> "I had to /move/ the js directory to the toplevel of my drive and >>> rename the jsquery.what.ever.js as you suggested because of the >>> symlink issue." >>> >>> FG probably does not have the symlink issue. How about a toplevel / >>> js? >> No, I don't have the issue (I am using a mature OS here ;-). >> Please don't introduce a toplevel /js - this "pollutes" the >> directory structure... I am installing apps under "/opt/app-name/" >> - so OpenAIR lives in /opt/common-lisp/openair and the JS >> directory is /opt/common- lisp/openair/js - works really well. > > Hey, I am in monkey-mode over here, I saw the browser asking for "/ > js/openair.js" and I made it happen, I am just dying to see (+ cells > ajax). Left for another day was whether I could have changed one of > a dozen parameters incomprehensible to my monkey mind in order to > get the browser to ask for a different file. Real easy in hunchentoot. Eddi did it again, you know. ;-) > > > How /are/ your browser/js skills, btw? I will start CCing you on > questions that arise in that area in case you are on-line sooner > than Andy and can throw me a banana. Shoot! - Those skills are getting better every hour ... I have done tabs in jQuery now in monkey style and digesting a ton of JS code today... I /am/ a beginner, though. So, you are warned - there will not be an answer for each of your questions... But hey, never too old to have some fun ! ;-) Frank From kennytilton at optonline.net Fri Apr 11 21:00:35 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 17:00:35 -0400 Subject: [cells-devel] Re: Problem with request In-Reply-To: <47FFBFFB.4040705@optonline.net> References: <47FE9FBD.5050208@optonline.net> <47FEA63D.40400@optonline.net> <47FEABF8.3060407@optonline.net> <47FEAF72.8030609@optonline.net> <47FF3EED.2030005@optonline.net> <47FF5955.8000009@optonline.net> <47FFBFFB.4040705@optonline.net> Message-ID: <47FFD173.2090609@optonline.net> Ken Tilton wrote: > I made the change so the little indicator to the right of the package > pop-up says either "on" or "all" and that worked when I selected a > package. But then I clicked on exported-only and the tag reverted to > all. I had a lisp (describe request) in the processing stream and can > see why: > > # is an instance of > #: > The following slots have :INSTANCE allocation: > HEADERS-IN ((:USER-AGENT > . "Mozilla/5.0 (Windows; U; Windows NT 5.1; > en-US) AppleWebKit/525.13 (KHTML, like Gecko) Version/3.1 Safari/525.13") > (:CACHE-CONTROL . "max-age=0") > (:X-REQUESTED-WITH . "XMLHttpRequest") > (:ACCEPT-LANGUAGE . "en-US") > (:ACCEPT-ENCODING . "gzip, deflate") > (:REFERER . "http://localhost:8000/apropos") > (:ACCEPT . "*/*") > (:COOKIE > . > "hunchentoot-session=3%3a0b9ec45ad30835f959590b891dc5ddee") > (:CONNECTION . "keep-alive") > (:HOST . "localhost:8000")) > METHOD :GET > URI "/apropos/EXPORTED-ONLY-P?EXPORTED-ONLY-P=on" > SERVER-PROTOCOL :HTTP/1.1 > CONTENT-STREAM # #x219f7132> > COOKIES-IN (("hunchentoot-session" > . "3:0b9ec45ad30835f959590b891dc5ddee")) > GET-PARAMETERS (("EXPORTED-ONLY-P" . "on")) > POST-PARAMETERS NIL > SCRIPT-NAME "/apropos/EXPORTED-ONLY-P" > QUERY-STRING "EXPORTED-ONLY-P=on" > SESSION # > AUX-DATA NIL > RAW-POST-DATA NIL > > The get-parameters just shows the effected field. Is that something we > are doing? I would say we could change rules to say (or (param?...) > .cache), but I recall you said... well, that was attributes, nothing is > said if the attibute goes away or something. OK, I have been thinking. We like the granularity, so these get-parameters -- er, why aren't they post parameters? -- should not be treated as they are now as definitive of all the data, they just signify specific updates to the model. So I am thinking we take a different approach and simply loop over the values received and SETF the model slots, which should be c-in or c?n if they need to calculate an interesting initial value for a field based on other info. I will play with this. Meanwhile, I see a parameter on the server that says output-chunking is true -- in the request handler instead of bunging them all into a single string can we just write them one at a time to page and trust hunch to chunk them? kt From kennytilton at optonline.net Fri Apr 11 21:47:16 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 17:47:16 -0400 Subject: [cells-devel] [OpenAIR] Escape velocity? In-Reply-To: <47FFD173.2090609@optonline.net> References: <47FE9FBD.5050208@optonline.net> <47FEA63D.40400@optonline.net> <47FEABF8.3060407@optonline.net> <47FEAF72.8030609@optonline.net> <47FF3EED.2030005@optonline.net> <47FF5955.8000009@optonline.net> <47FFBFFB.4040705@optonline.net> <47FFD173.2090609@optonline.net> Message-ID: <47FFDC64.4030906@optonline.net> Ken Tilton wrote: > I will play with this. I get it! Hopefully this will be a great weekend, I am really going to tear into what Andy has accomplished and see if I can rig up something just a little more transparent. What I see is a pattern with a page having an attribute of X and then a widget for X that has a rule watching the parameter X. That works well (again my deliberate withholding of Cells doc fails to stop an adopter!) but I want to see if we can simply create a widget named X and have it all Just Work, eliminating what is not all that bad, viz., creating a parallel slot on the page instance. But that trick might get exciting if we get into arrays/lists where a page has two Xs as children -- well, it could be handled, but why not automate that? It gets trickier because we want a two-way exchange here -- maybe we have a c?n rule which when suitably provoked calculates a new initial default based on the user selecting an entirely new something-else in some other field. So sometimes when a value changes the Lisp model must be told, and sometimes the ajax model must be told. I think sorting /this/ out will make for a more interesting weekend and possibly have me extending Cells a little. kt From frgo at mac.com Fri Apr 11 22:27:59 2008 From: frgo at mac.com (Frank Goenninger) Date: Sat, 12 Apr 2008 00:27:59 +0200 Subject: [cells-devel] [OpenAIR] Escape velocity? In-Reply-To: <47FFDC64.4030906@optonline.net> References: <47FE9FBD.5050208@optonline.net> <47FEA63D.40400@optonline.net> <47FEABF8.3060407@optonline.net> <47FEAF72.8030609@optonline.net> <47FF3EED.2030005@optonline.net> <47FF5955.8000009@optonline.net> <47FFBFFB.4040705@optonline.net> <47FFD173.2090609@optonline.net> <47FFDC64.4030906@optonline.net> Message-ID: Am 11.04.2008 um 23:47 schrieb Ken Tilton: > Ken Tilton wrote: >> I will play with this. > > I get it! Hopefully this will be a great weekend, I am really going > to tear into what Andy has accomplished and see if I can rig up > something just a little more transparent. > > What I see is a pattern with a page having an attribute of X and > then a widget for X that has a rule watching the parameter X. That > works well (again my deliberate withholding of Cells doc fails to > stop an adopter!) but I want to see if we can simply create a widget > named X and have it all Just Work, eliminating what is not all that > bad, viz., creating a parallel slot on the page instance. But that > trick might get exciting if we get into arrays/lists where a page > has two Xs as children -- well, it could be handled, but why not > automate that? > > It gets trickier because we want a two-way exchange here -- maybe we > have a c?n rule which when suitably provoked calculates a new > initial default based on the user selecting an entirely new > something-else in some other field. So sometimes when a value > changes the Lisp model must be told, and sometimes the ajax model > must be told. > > I think sorting /this/ out will make for a more interesting weekend > and possibly have me extending Cells a little. Exactly what I'm after - man, if we can get this done then we have THE killer app for Cells! Yup - so let's hack away ... Frank From frgo at mac.com Fri Apr 11 23:47:25 2008 From: frgo at mac.com (Frank Goenninger) Date: Sat, 12 Apr 2008 01:47:25 +0200 Subject: [cells-devel] [openair] Changes to get CSS styles working ... Message-ID: <38F0FAE2-8A75-4163-B326-A96FC20D408F@mac.com> Needed to make a small change in defmodel page: The lines with the :style got changed to: (:link :rel "stylesheet" :type "text/css" :href (^style)) Now CSS file loading works for me ... Cheers, Frank From kennytilton at optonline.net Sat Apr 12 00:16:30 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Fri, 11 Apr 2008 20:16:30 -0400 Subject: [cells-devel] Re: How do I do this in JS? In-Reply-To: References: <3027E3D2-B679-4BFE-AF87-F9535487B5BE@mac.com> <5E04AF90-14DE-4E94-9677-FB2D87FE7C64@mac.com> <47FF8F98.4050905@optonline.net> <47FFBFC0.1050006@optonline.net> <93B6AB85-6A45-4C3D-88C9-7B9C4F35A844@mac.com> <47FFC400.9080808@optonline.net> <33B1223F-161B-48A9-9771-3CE44D72712D@mac.com> <47FFE610.7010700@optonline.net> Message-ID: <47FFFF5E.4010504@optonline.net> Andy Chambers wrote: > On Fri, Apr 11, 2008 at 11:28 PM, Ken Tilton wrote: > >>Instead of using gensyms to name (ID) interesting fields (not DIVs) I want >>to use their names, and do so as a path down from the page, so the id for >>the term input element would be, eg, "apropos.term" or "apropos/term". Then >>the Lisp-side tree of instances becomes its own dictionary (no need for >>mirroring slots on the page instance) and then we'll never have a problem >>with duplicates -- well, if we have a list of identical structures we'll get >>into a subscript as well, so how would I encode that? Suppose instead of >>just listing matches each match contained a checkbox to indicate (I don't >>know) show CLHS entry and then boom they hit enter and multiple entries >>appear. Well, they need the checkbox to have a path: >>apropos/match[42]/show-clhs. Is this where we do "apropos/match.42/clhs" as >>an ID? I guess I am asking what are the limitations on the id name >>characters. > > >>From the spec... > > ID and NAME tokens must begin with a letter ([A-Za-z]) and may be > followed by any number of letters, digits ([0-9]), hyphens ("-"), > underscores ("_"), colons (":"), and periods ("."). > > I hadn't actually noticed this before and assumed that anything would > be ok but went ahead and checked. > > However, this might not matter so much because you can do the thing > you want with jquery selectors and filters. Instead of a slash, you > use ">", and instead of [42], you use :nth-child(42) > > apropos/match[42]/show-clhs would then be > $("#apropos > #match :nth-child(42) > #show-clhs) Cool. Maybe I can leave this idea to you to implement? The idea would be to have a path slot on every node that for things which wold never change was nil and for anything else searched up to the first parent with a path and used that plus the symbol-name of its own :md-name which can be coded as a Lisp symbol such as 'term or :term (formatted into a JQ-acceptable selector as a string). One instance can reference another with (fm-other :term) or (fm^ :term) if the node is not a child (I can clean up all that whacky inter-model referencing syntax like fm-other and dm^), the only one who has to worry about the JQ names on the Lisp side is the bit that pipes things over to the browser and handles the (now) POSTs. I think widget values can be handled as usual in Cells apps: if it is an input field, just say c-in or c-input or c?n. We will only get POSTs from input fields, and Cells will allow those to be setf'ed when they come in. The page can have an equal hashtable to speed location of a CLOS instance given its JQ ID. An observer on the JQ path can stuff this dictionary, or just have the rule itself do it before returning the value: :jq-selector (c? (let ((n (symbol-name (md-name self))) (sa (jq-selector-above self)) (s (if sa (conc$ sa " > " sa) n)))) (setf (gethash s (jq-dict (u^ web-app))) self) s)) Something like that. > >> This may be easier than I thought! I was feeling the caffeine, now I am not. Better you than me if you like where I am going with this. My one question is the same we had with cl-ode -- observers do not know which way a value is going. Observers now get passed the Cell (a very recent change) so we can use that: only ruled cells are headed outbound. I am just not sure that holds up -- what of we have an input Cell reserved for setting in reponse to things happening on the server? Well, we could say those still do not get propagated out to the browser -- those should be slots on the model, not widgets in the DOM. If we want a widget in the DOM to reflect that value (yes, this feels right) we just have a widget with a rule that says: (mk-text (c? (server-load (u^ web-app)))) Well, in that case I guess we would have a server instance as the parent of the web-app (remember when I said fm-top might not hold up?) but you get the idea. And even if this input=inbound, ruled=outbound breaks down we have the trick we are doing with cl-ode: simply flag the cell itself for direction. Hmmm, pardon the rambling, but we do have c?n slots. They run whenever something global changes to provide a default the user can override by typing, but meant to be re-defaulted if they go back and change this overarching other parameter. ie, I have changed the item selection so the size and color get re-defaulted, I am starting over. So this would be a two-way slot... it would mostly work except that the observer on xhtml will see a ruled /and/ input cell and not know if it should push it onto the updates. Hmmm. This is to be expected, we are once removed from the action. The first thing that pops into my head is a second dictionary, this time keying the jq selector to the value we know is over on the client side. The observer on xhtml can simply check that the new-value is not already on the client side. When we get posts, the first thing we do is record that that value is already on the client-side, before injecting the value into the Lisp model. Speaking of which, I guess inputs will come over one at a time as you have things set up, but if you think you'll ever get into bundling them up and sending over multiple inputs, we should apply another trick from cl-ode and control propagation (so multiple setf's look like one to the model). whew. I would gone back and edited all that but it may help for you to see my thought path (and maybe something in there sounds better to you than where I ended up). Man, you jumped in at the deep end, eh? :) kt ps. I CCed Peter H because he is the mover behind cl-ode and I thought he'd enjoy seeing the cross-pollenation. k From peter.hildebrandt at gmail.com Sat Apr 12 16:35:39 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Sat, 12 Apr 2008 18:35:39 +0200 Subject: [cells-devel] Re: [cells-gtk-devel] Re: Anything new for me to show off at ECLM 2008? In-Reply-To: <47FF4566.4080605@optonline.net> References: <47FE56B9.3070404@sentex.ca> <7758b2680804101211s5f9660dfhc056da5b72297894@mail.gmail.com> <47FE796D.6@optonline.net> <7758b2680804110152k737d478fj8aed42b32f50a24c@mail.gmail.com> <47FF4566.4080605@optonline.net> Message-ID: <7758b2680804120935y2426cee2mbfcbfb707339fed4@mail.gmail.com> Ken, On Fri, Apr 11, 2008 at 1:03 PM, Ken Tilton wrote: > Hmmm, a little trouble there. PicoZip on WinXP cannot read it, WinZip on > Vista (my new laptop for the eclm talk) complains but then seems to open it. > The complaint looks like winzip just is not handling Vista. Weird. I used the built-in zipper in ubuntu. But since cvs now magically works for me again, this has become obsolete fortunately. > Question 2: the above does not include a Cells directory (unless the > expansion broke). I will be trying to build it (looks like I have to hack > the ACL .lpr files for a while) in the meantime. Yep, I think we never had cells3 be part of cells-gtk3 (I guess part of why we did cells-gtk3 is so that we don't have to include out own fork of cells anymore). BTW, do you have strong feelings about how to structure the cells-gtk tree? you had flattened it in cvs, I had it restructured to match the old cells-gtk (so I could merge in my patches). Which one do you prefer if any? If you don't care either way I will try and restructure cvs to match the old cells-gtk tree structure for the sake of consistency. > > (2) Tree View > Omigod! I did an inspector at one point and used it to inspect the > inspector window itself. Then I navigated down to the actual widgets in view > and watched as the inspector showed things like the mouse-over state > dynamically (without asking the inspector to refresh). I seem to recall > adding some Cells internals to make it work, tho. In this screenshot: Gotta love (+ lisp cells). test-gtk has had that feature for a while, I think (at least longer than I have been on board). I remeber it took me a while to understand what was *really* going on when I saw it first. > > (4) Threading > > > > It is relly nice and lispy to use the repl to change properties of the > > windows currently displayed and to add and remove widgets > > interactively (especially if you have a background in C) -- but I > > don't know whether that works in MS Windows. Just checked, > > bordeaux-threads on windows does not support Allegro. Bummer. > > > > I will be doing repl stuff during my talk -- ACL runs a separate process > from the IDE to execute Lisp. We just need to have a breather in the event > loop handling to give the IDE enough cycles to be responsive. Cooperative scheduling, heh? Apparently cells-gtk on Lispworks/Windows has similar issues (there's a work around somewhere in cells-gtk). So far I haven't seen that with sbcl/linux. Maybe threading works better over here, maybe gtk does a better job of keeping the load in the main loop know. Those issues aside, doing repl stuff while having a gui up is really neat, isn't it? > OK, don't make yourself crazy on my account. Well, I'd love to have these things up and running in my thesis talk two months from now, so it won't hurt to be a little ahead of schedule. > In fact, I already have > Cells-gtk as I had it last running on my laptop, I might just leave it at > that. I am going to try to get to Celtk, Cello, TripleCells (lite > integration with an RDF triple-store), Cells-Gtk, and OpenAIR (the > cells/ajax bit andy is doing). Whew! Wow, sounds like a great program. It seems next time they could save the trouble of inviting other speakers, and just let you talk for the whole two days. :-) Anyway, good luck with all of it, and I am looking forward to watching the recording. Cheers, Peter From kennytilton at optonline.net Sat Apr 12 16:51:31 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Sat, 12 Apr 2008 12:51:31 -0400 Subject: [cells-devel] Re: [cells-gtk-devel] Re: Anything new for me to show off at ECLM 2008? In-Reply-To: <7758b2680804120935y2426cee2mbfcbfb707339fed4@mail.gmail.com> References: <47FE56B9.3070404@sentex.ca> <7758b2680804101211s5f9660dfhc056da5b72297894@mail.gmail.com> <47FE796D.6@optonline.net> <7758b2680804110152k737d478fj8aed42b32f50a24c@mail.gmail.com> <47FF4566.4080605@optonline.net> <7758b2680804120935y2426cee2mbfcbfb707339fed4@mail.gmail.com> Message-ID: <4800E893.2030306@optonline.net> Peter Hildebrandt wrote: > BTW, do you have strong feelings about how to structure the cells-gtk > tree? It's all yours. Maybe see if Peter Denno has some thoughts. > > Those issues aside, doing repl stuff while having a gui up is really > neat, isn't it? "indistinguishable from magic" springs to mind. I was really happy when someone opened my eyes to special variables and let me make dependency transparent, mostly for ease of coding, partly to baffle the unitiated. :) > Wow, sounds like a great program. It seems next time they could save > the trouble of inviting other speakers, and just let you talk for the > whole two days. :-) That or two minutes, long enough to say, "Listen, just try it, there is no way I can get this across to you." :) Well, I saw a cool demo for JQuery or OpenLaszlo or something that built something gee-whiz from scratch, I think I want to do that so they do get more of a feel for the beast. kt From peter.denno at nist.gov Sat Apr 12 17:29:49 2008 From: peter.denno at nist.gov (Peter Denno) Date: Sat, 12 Apr 2008 13:29:49 -0400 Subject: [cells-devel] Re: [cells-gtk-devel] Re: Anything new for me to show off at ECLM 2008? In-Reply-To: <4800E893.2030306@optonline.net> References: <47FE56B9.3070404@sentex.ca> <7758b2680804120935y2426cee2mbfcbfb707339fed4@mail.gmail.com> <4800E893.2030306@optonline.net> Message-ID: <200804121329.49659.peter.denno@nist.gov> On Saturday 12 April 2008 12:51, Ken Tilton wrote: > Peter Hildebrandt wrote: > > BTW, do you have strong feelings about how to structure the > > cells-gtk tree? > > It's all yours. Maybe see if Peter Denno has some thoughts. Hi Kenny, What do you have in mind? -- Best regards, - Peter From peter.hildebrandt at gmail.com Sat Apr 12 19:42:24 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Sat, 12 Apr 2008 21:42:24 +0200 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <47FFB681.8040106@optonline.net> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> Message-ID: <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> Ken, thanks a lot for all the insight. First things first, using c?n for the kids works like a charm. setf on a c? cell still produces an error, suggesting to initialize the cell with c-in. Anyway, that's settled now. As to the not-to-be issue, everything can be reproduced using test-gtk. I can share that in the cells cvs, just let me know whether it would be ok to restructure the cvs to match the old cells-gtk directory structure (I'd rather keep it the way it is in the old cells-gtk, so that I can commit it in there one day). I did some narrowing it down and going through the back trace. So let us look at an example: root node 1 ---- observer 1 node 1.1 ---- observer 1.1 node 2 ---- observer 2 The basic code for the observer is (defmodel family-observer (family) ;; we'll use the "value" slot for the observed ((row :reader row :initarg :row) (:default-initargs :kids (kids-list? (bwhen (val (^value)) (mapcar #'(lambda (src) (mk-observer self src)) (kids val)))))))) :row (c? (when-bind* ((parent (upper self)) (pos (position self (kids parent)))) (let ((new-row (tree-row-create (row parent) (id parent)))) (when (tree-row-valid new-row) (tree-row-set-path new-row (row parent) pos) new-row))))) Where mk-observer is a method specializing on both parameters, so that we can have different kinds of observers on the same type of targets. The row is some gui object to be kept in sync. Now we remove node1: (with-integrity (:change 'tv-del-node) (setf (kids (upper node1)) (remove node1 (kids (upper node1))))) Then first node2 and observer2 die, ok. Then node1 dies, and so does observer1. The interesting part: not-to-be :before on observer 1.1 is called -- and at this point observer 1.1 itself is already :eternal-rest, in other words, not-to-be is called on a dead object. Now not-to-be of the observer wishes to do something, so it accesses a (ruled) slot of the passed object: (defmethod not-to-be :before ((self cells-tree-node)) (tree-row-destroy (row self)) The call to the accessor (row self) with the dead self triggers a bunch of cells calls: Backtrace: 0: (CELLS::ENSURE-VALUE-IS-CURRENT NIL # #) 1: ((LABELS CELLS::CHECK-REVERSED) (NIL)) 2: (CELLS::ENSURE-VALUE-IS-CURRENT (NIL . )=492/OPTIMIZED-AWAY/ROW/DEAD!NODE-TREE-NODE3440] # #) 3: ((LAMBDA (CELLS::OPCODE CELLS::DEFER-INFO)) # #) 4: (CELLS::CALL-WITH-INTEGRITY NIL NIL #) 5: (CELLS::CELL-READ (NIL . )=492/OPTIMIZED-AWAY/ROW/DEAD!NODE-TREE-NODE3440]) 6: (CELLS::MD-SLOT-VALUE DEAD!NODE-TREE-NODE3440 CELLS-GTK::ROW) The last call is in (defun ensure-value-is-current (c debug-id ensurer) (declare (ignorable debug-id ensurer)) (count-it :ensure-value-is-current) (when (and (not (symbolp (c-model c)))(eq :eternal-rest (md-state (c-model c)))) (break "model ~a of cell ~a is dead" (c-model c) c)) .... in particular the form: (c-model c) which breaks with: The value NIL is not of type CELL. [Condition of type TYPE-ERROR] To sum up, I believe the problem is that at a change of the kids list - First the kids are declared dead - Then not-to-be is called recursively and thus not-to-be is passed a dead self. However, I wish to do some cleanup work when kids are kicked out, and for this I need to access a few slots. What I'd like to have is - not-to-be being called before the object is declared dead or - another method (last-will?) to be executed right before the kids die or - an interims state (:zombie?) in which cell slots are still accessible with their last cached value Or is the solution to have an observer on the kids slot instead of a not-to-be-method, which does the cleanup work for the kids? > I was thinking while doing the dishes. I can image the observer class being > interesting in its own right, and slots over there ending up dependent on > the same original kids-list in some way, as well of course as the value of > the observer. Propagation would then try to update this slot and when it got > to the value of the observer find a dead instance. Any rule that got to the > value of the observer by accessing the list of observers (say something > iterating over them) would not encounter such an observer/value, but rules > lower down that get at the value directly will. This is an interesting idea, but I doubt that this is my problem here. It really seems to be the relation between ruled kids slots, declaring cells dead, and not-to-be. > Now normally this is not a problem because such lower down rules would tend > not to depend also on the original list, and indeed the reason I have left > this unaddressed is that in most cases I have seen a simple way to rewrite > my rules that was even better and which did not end up with these widespread > dependencies (if you have followed me so far on that, and if I hasten to add > all this guesswork is on the money). I like to hold out for Real Problems > before whacking away at the code, I think that is a slippery slope. That is surely true, as this case proves. I feel what we're looking for here is something like family-finalizers which are specified to be called everytime a kid dies. > btw, all that stuff in their that worries about dead instances is > preemptive safeguard stuff -- I think if you disable that most things will > just work. The rules that are failing now will run harmlessly and in a few > cycles everything gets cleaned up anyway. Cells ran for /years/ with this > happening to no ill effect (until RoboCup, of all things). Yep, which is why it broke after introducing cells3 :-) OTOH, I see why it is good to have these safe guards. I hacked a solution today to the fm-other tree searches which were all over cells-gtk -- now we have with-widget and with-widget-value which do the right thing without kicking off tree searches (I introduced an automatically maintained hashtable of active instances hashing by md-name, like I did in cells-ode). > If you want to send me your whole project I will look to see how I would > rewrite the rules if that is even possible, and if not take a look at > solving this formally. As I said, I like to try things out in test-gtk first, so that I can isolate the error (and create a nice demo on the way). I will work through cvs and commit it tomorrow, I hope. I just don't want to force you to have to deal with my whole project -- and all the other issues it has. > fyi, in the past I have done silly things like having Cells just return nil > on slot-value access to dead cells, but we may want to find something more > elegant. :) I have such code in my project, too: (defun deadp (cell) (eql (slot-value cell 'cells::.md-state) :eternal-rest)) However, since I need the slot-value in my case, this does not help ;-) Thanks again, Peter From kennytilton at optonline.net Sat Apr 12 22:16:23 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Sat, 12 Apr 2008 18:16:23 -0400 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> Message-ID: <480134B7.9010209@optonline.net> Peter Hildebrandt wrote: [A great article! ] > Ken, > > thanks a lot for all the insight. First things first, using c?n for > the kids works like a charm. setf on a c? cell still produces an > error, suggesting to initialize the cell with c-in. OK, I thought that was only in debug mode, but I did not actually check. > Anyway, that's > settled now. > > As to the not-to-be issue,... Ohhhh, it's in the not-to-be. Understood. Meanwhile over here working on OpenAIR I ended up trying to read dead instances. Have not figured out why, but I have a guess. Still, this comes up so often I think we might want to make this less painful for developers. >... everything can be reproduced using > test-gtk. I can share that in the cells cvs, just let me know whether > it would be ok to restructure the cvs to match the old cells-gtk > directory structure (I'd rather keep it the way it is in the old > cells-gtk, so that I can commit it in there one day). Sure, go for it. > > I did some narrowing it down and going through the back trace. So let > us look at an example: > > root > node 1 ---- observer 1 > node 1.1 ---- observer 1.1 > node 2 ---- observer 2 > > The basic code for the observer is > > (defmodel family-observer (family) > ;; we'll use the "value" slot for the observed > ((row :reader row :initarg :row) > (:default-initargs > :kids (kids-list? > (bwhen (val (^value)) > (mapcar #'(lambda (src) (mk-observer self src)) > (kids val)))))))) > :row > (c? (when-bind* ((parent (upper self)) (pos (position self > (kids parent)))) > (let ((new-row (tree-row-create (row parent) (id parent)))) > (when (tree-row-valid new-row) > (tree-row-set-path new-row (row parent) pos) > new-row))))) > > Where mk-observer is a method specializing on both parameters, so that > we can have different kinds of observers on the same type of targets. May I just observe at this juncture that I wish you had chosen a name other than observer for this class given that Cells already has the observer name in play. :) > > The row is some gui object to be kept in sync. > > Now we remove node1: > > (with-integrity (:change 'tv-del-node) > (setf (kids (upper node1)) (remove node1 (kids (upper node1))))) > > Then first node2 and observer2 die, ok. Then node1 dies, and so does > observer1. > > The interesting part: > > not-to-be :before on observer 1.1 is called -- and at this point > observer 1.1 itself is already :eternal-rest, in other words, > not-to-be is called on a dead object. Now not-to-be of the observer > wishes to do something, so it accesses a (ruled) slot of the passed > object: > > (defmethod not-to-be :before ((self cells-tree-node)) > (tree-row-destroy (row self)) > > The call to the accessor (row self) with the dead self triggers a > bunch of cells calls: > > Backtrace: > 0: (CELLS::ENSURE-VALUE-IS-CURRENT NIL # #) > 1: ((LABELS CELLS::CHECK-REVERSED) (NIL)) > 2: (CELLS::ENSURE-VALUE-IS-CURRENT (NIL . > )=492/OPTIMIZED-AWAY/ROW/DEAD!NODE-TREE-NODE3440] # argument> #) > 3: ((LAMBDA (CELLS::OPCODE CELLS::DEFER-INFO)) # > #) > 4: (CELLS::CALL-WITH-INTEGRITY NIL NIL # (CELLS::OPCODE CELLS::DEFER-INFO)) {BBBD3DD}>) > 5: (CELLS::CELL-READ (NIL . > )=492/OPTIMIZED-AWAY/ROW/DEAD!NODE-TREE-NODE3440]) > 6: (CELLS::MD-SLOT-VALUE DEAD!NODE-TREE-NODE3440 CELLS-GTK::ROW) > > The last call is in > > (defun ensure-value-is-current (c debug-id ensurer) > (declare (ignorable debug-id ensurer)) > (count-it :ensure-value-is-current) > (when (and (not (symbolp (c-model c)))(eq :eternal-rest (md-state > (c-model c)))) > (break "model ~a of cell ~a is dead" (c-model c) c)) > > .... in particular the form: > > (c-model c) > > which breaks with: > > The value NIL is not of type CELL. > [Condition of type TYPE-ERROR] > > To sum up, I believe the problem is that at a change of the kids list > - First the kids are declared dead > - Then not-to-be is called recursively > and thus not-to-be is passed a dead self. Yeah, I ran into this once in an observer. > > However, I wish to do some cleanup work when kids are kicked out, and > for this I need to access a few slots. Yep. > > What I'd like to have is > - not-to-be being called before the object is declared dead > or > - another method (last-will?) to be executed right before the kids die > or > - an interims state (:zombie?) in which cell slots are still > accessible with their last cached value > > Or is the solution to have an observer on the kids slot instead of a > not-to-be-method, which does the cleanup work for the kids? I used to do that with kids, but not-to-be is a good place for it. I might have just made a mistake declaring instances dead before not-to-be. And I am not even sure why I am so unpleasant about allowing access to slot-values of dead stuff. More on this below (you guessed right). > > >> I was thinking while doing the dishes. I can image the observer class being >>interesting in its own right, and slots over there ending up dependent on > > > the same original kids-list in some way, as well of course as the value of > >>the observer. Propagation would then try to update this slot and when it got >>to the value of the observer find a dead instance. Any rule that got to the > > > value of the observer by accessing the list of observers (say something > >>iterating over them) would not encounter such an observer/value, but rules >>lower down that get at the value directly will. > > > This is an interesting idea, but I doubt that this is my problem here. > It really seems to be the relation between ruled kids slots, > declaring cells dead, and not-to-be. Yeah, I did not know it was a not-to-be. > > > Now normally this is not a problem because such lower down rules would tend > >>not to depend also on the original list, and indeed the reason I have left >>this unaddressed is that in most cases I have seen a simple way to rewrite > > > my rules that was even better and which did not end up with these widespread > >>dependencies (if you have followed me so far on that, and if I hasten to add >>all this guesswork is on the money). I like to hold out for Real Problems > > > before whacking away at the code, I think that is a slippery slope. > > That is surely true, as this case proves. I feel what we're looking > for here is something like family-finalizers which are specified to be > called everytime a kid dies. > > >> btw, all that stuff in their that worries about dead instances is >>preemptive safeguard stuff -- I think if you disable that most things will > > > just work. The rules that are failing now will run harmlessly and in a few > >>cycles everything gets cleaned up anyway. Cells ran for /years/ with this >>happening to no ill effect (until RoboCup, of all things). > > > Yep, which is why it broke after introducing cells3 :-) > > OTOH, I see why it is good to have these safe guards. When this all happened I was days away from having to demo RoboCells at an ILC and I just did what I had to to deal with the many attempts to get to dead instances under Cells2. I think some consequent paranoia carried over to this code. In 2001, Hal when challenged on his determination of a fault in some device suggests putting it back in and allowing it to fail. I suggest we do the same, but not use the opportunity to send an astronaut drifting off into space to eventually suffocate. > I hacked a > solution today to the fm-other tree searches which were all over > cells-gtk -- now we have with-widget and with-widget-value which do > the right thing without kicking off tree searches (I introduced an > automatically maintained hashtable of active instances hashing by > md-name, like I did in cells-ode). haha, almost every day now I think about implementing namespace search that way. :) It is kind of cool to have this automatic location-relative search that Just Works when we have repeating structures and lots of widgets with the same name, but so often a simple hash lookup would suffice. Part of the magic of the existing scheme, btw, is that it does not matter that some widget might get awakened before the other widget it seeks has even been created. The navigation works by hitting kids slots, which get run JIT to spawn the thing being looked for. When I saw that working without having been planned for I had a feeling I had stumbled onto something. >> If you want to send me your whole project I will look to see how I would >>rewrite the rules if that is even possible, and if not take a look at >>solving this formally. > > > As I said, I like to try things out in test-gtk first, so that I can > isolate the error (and create a nice demo on the way). I will work > through cvs and commit it tomorrow, I hope. I just don't want to > force you to have to deal with my whole project -- and all the other > issues it has. Oh, no need for a reproducible. Now that I know it was in not-to-be it is an understood issue. > > >> fyi, in the past I have done silly things like having Cells just return nil > > > on slot-value access to dead cells, but we may want to find something more > >>elegant. :) > > > I have such code in my project, too: > > (defun deadp (cell) > (eql (slot-value cell 'cells::.md-state) :eternal-rest)) > > However, since I need the slot-value in my case, this does not help ;-) Funny you should mention slot-value. :) That's what I used to get at the slots of dead instances in my not-to-be situation. Well... I am hesitating. There /is/ an evil variant of corpse access to be blocked as an aid to the developer, a form of access wholly unjustifiable. I think we need to yell if these happen. As for deferring the death certificate, well, what if your not-to-be wants access to a sibling or parent or child who is also being interred? Perhaps they get not-to-be'd, declared dead, and now it is your turn and you try to read them? We ran but could not hide? ie, I am not sure then where to put the certification of death, tho it occurs to be that the unfinished-business queue (if you have read that far) is exactly where this should go, ie we queue instances up for death certification to run after full propagation (including not-to-be processing) after which point it will be safe to say slot access is an absolute bug. The neat thing is that we do have a distinct "awaken" stage in ufb processing, why not a distinct "ex-parrot" stage? Another very quick fix would be simply to do something like with-integrity, which explicitly says "I know this may not run right away". We could wrap the not-to-be call in a with-post-mortem macro dynamically binding *dead-is-cool* to t and then any access anywhere to dead things would be allowed. This would avoid the runtime cost of queueing things up for annihilation (but then I do not think that would be a big runtime burden at all). Anyway, let me implement *dead-is-cool* and have that bound to t before calling not-to-be so there is no need to wrap not-to-be code at all and see what happens. I'll commit something soon, lemme know if it works. :) kt From kennytilton at optonline.net Sat Apr 12 22:57:19 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Sat, 12 Apr 2008 18:57:19 -0400 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <480134B7.9010209@optonline.net> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> <480134B7.9010209@optonline.net> Message-ID: <48013E4F.2090104@optonline.net> fixes... >> To sum up, I believe the problem is that at a change of the kids list >> - First the kids are declared dead >> - Then not-to-be is called recursively >> and thus not-to-be is passed a dead self. > > > Yeah, I ran into this once in an observer. Sorry, meant to say "in a not-to-be". > Anyway, let me implement *dead-is-cool* and have that bound to t before > calling not-to-be so there is no need to wrap not-to-be code at all and > see what happens. I'll commit something soon, lemme know if it works. :) Done. The special is *not-to-be*. Cells regression test passes but did not exercise any tests of mortality. kt From kennytilton at optonline.net Sun Apr 13 02:21:03 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Sat, 12 Apr 2008 22:21:03 -0400 Subject: [cells-devel] baby steps Message-ID: <48016E0F.3000303@optonline.net> The attached works a tiny little bit. Running hunch, starting the server with the snippet at the top of example.lisp, running (reload), and then navigating to 8000/apropos I see three symbols matching the initial value of "md-slot-v". Deleting the "v" and then tabbing I see eight values matching "md-slot-". This required especially telling the handler creater not to expect "/apropos" as the prefix to subsequent messages (in fact ( i just defaulted if the name did not match apropos. Oh, you will also see hijinx where I store nodes by name as well as by ID, because I got back (("term" . "md-slot-")...) not (("i1234" . etc)) even though I see openair.js returns the id. Go figger. Oh. I may have really screwed up. At one point it seemed only the changed field (the search term) was being sent, suddenly I see the "pkg" as well, perhaps meaning there is no need to keep a copy of the client-side-data as you will see I am maintaining. Obviously I have no idea what is going on, perhaps I am seeing "pkg" only as a fluke behavior of pop-up menus (maybe if they are uninitialized they choose the first value and then that looks like a change to be transmitted?) I am clueless. If browsers always send all non-nil attributes with every request (a) that sounds like a waste and (b) we can lose the client-side-data hash table. Hopefully (a) is not the case (and anyway I thought /we/ were deciding what to send...hmmm, I am starting to like my theory about pop-up menus). whew! learning curves are exhausting, but fun. This seems to be working. I would love to feature this at eclm 2008 beacuse it shows how Cells interconnect values, how Cells facilitate the driving of an alien framework by a Lisp framework, and finally because it is Web 2.0, something folks might actually be interested in. Hang on. I just edited in some "<-kt" prefixed comments, and am attaching again example.lisp. I decided to retest and, whoa, a problem resurfaced: the whole thing simply stops working. I got stuck on this earlier and was just recompiling here and there with new debug statements and it started working again. That suggests, btw, that there is a defparameter or something that gets reset by the file being recompiled and reloaded (but I tried a full recompile and that did not help). Anyway, I am sure it is something stupid, and it is too late for me to stare at. kt -------------- next part -------------- A non-text attachment was scrubbed... Name: mainline.zip Type: application/x-zip-compressed Size: 42992 bytes Desc: not available URL: -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: example.lisp URL: From ylvcaka at common-lisp.net Sun Apr 13 08:08:00 2008 From: ylvcaka at common-lisp.net (Frieda) Date: Sun, 13 Apr 2008 16:08:00 +0800 Subject: [cells-devel] Research has revealed! Message-ID: <4801BF60.9010404@common-lisp.net> Recent discoveries in herbal science have shed new light on the subject of penis enlargement. Research has revealed that your penis has the ability to grow beyond its current size when fully erect. Like all the other muscles in your body, your penis is actually designed to grow! http://www.qunebtoh.com/ From peter.hildebrandt at gmail.com Sun Apr 13 10:40:30 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Sun, 13 Apr 2008 12:40:30 +0200 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <48013E4F.2090104@optonline.net> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> <480134B7.9010209@optonline.net> <48013E4F.2090104@optonline.net> Message-ID: <7758b2680804130340h4016eefck4b3debd09ab12c3c@mail.gmail.com> Ken, First of all, thanks for the quick fix. However, it does not behave quite as it should: cell slots now return t during not-to-be. I think the reason is in md-slot-value.lisp:ensure-value-is-current, more exactly: (when *not-to-be* (return-from ensure-value-is-current t)) While the function returns otherwise: (bwhen (v (c-value c)) (if (mdead v) (progn #+shhh (format t "~&on pulse ~a ensure-value still got and still not returning ~a dead value ~a" *data-pulse-id* c v) nil) v))) That is, (c-value c). I changed it accordingly: (when *not-to-be* (return-from ensure-value-is-current (c-value c))) Which works fine with my example code (that is, the cells-tree-view). I checked it into cvs. I am not quite sure about the implications, though. I think what I am doing here is return the value of a cell without recalculating it -- That is, I get the value calculated the last time the cell was accessed alive. That means -- if I am right -- the value I work on might be quite old, and a more granular check of the *not-to-be* special might be appropriate. However, I did a quick test: ;; make two nodes to create a cell dependency CTEST> (defparameter *val* (make-instance 'node :value (c-in 1))) *VAL* CTEST> (defparameter *root* (make-instance 'node :kids (c?n (list (make-kid 'node :value (c? (value *val*))))))) *ROOT* ;; check whether it works CTEST> (value (first (kids *root*))) 1 CTEST> (setf (value *val*) 2) 2 CTEST> (value (first (kids *root*))) 2 ;; yep ;; look at not-to-be, CTEST> (defmethod not-to-be :before ((self node)) (trc "not-to-be :before" (value self))) # ;; make a change CTEST> (setf (value *val*) 3) 3 ;; and see ... CTEST> (setf (kids *root*) nil) 0> not-to-be :before 3 0> not-to-be :before 3 NIL ;; wonderful! So maybe that's it :-) Cheers, Peter On Sun, Apr 13, 2008 at 12:57 AM, Ken Tilton wrote: > fixes... > > > > > > > > To sum up, I believe the problem is that at a change of the kids list > > > - First the kids are declared dead > > > - Then not-to-be is called recursively > > > and thus not-to-be is passed a dead self. > > > > > > > > > Yeah, I ran into this once in an observer. > > > > Sorry, meant to say "in a not-to-be". > > > > > Anyway, let me implement *dead-is-cool* and have that bound to t before > calling not-to-be so there is no need to wrap not-to-be code at all and see > what happens. I'll commit something soon, lemme know if it works. :) > > > > Done. The special is *not-to-be*. > > Cells regression test passes but did not exercise any tests of mortality. > > kt > From peter.hildebrandt at gmail.com Sun Apr 13 11:53:32 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Sun, 13 Apr 2008 13:53:32 +0200 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <480134B7.9010209@optonline.net> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> <480134B7.9010209@optonline.net> Message-ID: <7758b2680804130453i4042bd55k2948b8964bc87270@mail.gmail.com> Ken, as I said, my cells-tree-view works now -- wonderful. Gotta get going with (+ cells-ode open-gl) right away :-) > Meanwhile over here working on OpenAIR I ended up trying to read dead > instances. Have not figured out why, but I have a guess. Still, this comes > up so often I think we might want to make this less painful for developers. I see what you mean. It cost me quite a bit of time to track down those instances, especially since the problem is mostly transient, i.e the references to dead objects usually disappear quickly after the objects itself die. That's why I suggested the zombie state. You talk about it in more detail below, so I will hold my comments until then. > Sure, go for it. Ok, I created a new module for cells-gtk3 in the cells repository, called cells-gtk3. It is up to date, the demo includes the cells-tree-view and two cairo demos, and it runs fairly stable (i.e. I did not manage to break it) both in threading and non-threading mode. > May I just observe at this juncture that I wish you had chosen a name other > than observer for this class given that Cells already has the observer name > in play. :) Well, it was your suggestion :) I asked for something "like an observer on a whole family" a while ago on cells-devel, and you suggested the family-observer. In the code, I call it f-observer, because, well, it is something like an observer, only that it observer a whole family, not just a single cell. > > What I'd like to have is > > - not-to-be being called before the object is declared dead > > or > > - another method (last-will?) to be executed right before the kids die > > or > > - an interims state (:zombie?) in which cell slots are still > > accessible with their last cached value > > > > Or is the solution to have an observer on the kids slot instead of a > > not-to-be-method, which does the cleanup work for the kids? > > > > I used to do that with kids, but not-to-be is a good place for it. Agreed. It makes sense for the object to clean up after itself. > > I hacked a > > solution today to the fm-other tree searches which were all over > > cells-gtk -- now we have with-widget and with-widget-value which do > > the right thing without kicking off tree searches (I introduced an > > automatically maintained hashtable of active instances hashing by > > md-name, like I did in cells-ode). > > > > haha, almost every day now I think about implementing namespace search that > way. :) It is kind of cool to have this automatic location-relative search > that Just Works when we have repeating structures and lots of widgets with > the same name, but so often a simple hash lookup would suffice. So I guess we're attacking different problems here. Both in cells-ode and in the cells-gtk cases I was dealing with, I do not have equal names, and the dependencies might very well be wide spread -- in particular I needed that when I wanted to have primitves in the canvas slot of the cairo-drawing-area get their parameters from gtk-widgets. The primitves cannot reside in the kids of the drawing area since cells-gtk assumes that kids of widgets are widgets, and so the family structure breaks there. Maybe I should make the canvas slot :owning t. We'll see. > Part of the magic of the existing scheme, btw, is that it does not matter > that some widget might get awakened before the other widget it seeks has > even been created. The navigation works by hitting kids slots, which get run > JIT to spawn the thing being looked for. Yep, we talked about that when tracking down evil failures with (+ cells-gtk cells3). I figured that on average a hash table look up will suffice. My macro handles the case of the target nor exisitng (or not being initialized) by returning a specified default value. This way the dependent cell will first default to 0/nil/"" (or whatever specified), then switch to the "real" value once the initialization of the source widget is being propagated. > When I saw that working without having been planned for I had a feeling I > had stumbled onto something. :) > Well... I am hesitating. There /is/ an evil variant of corpse access to be > blocked as an aid to the developer, a form of access wholly unjustifiable. I > think we need to yell if these happen. As for deferring the death > certificate, well, what if your not-to-be wants access to a sibling or > parent or child who is also being interred? Perhaps they get not-to-be'd, > declared dead, and now it is your turn and you try to read them? We ran but > could not hide? Maybe it is a reasonable limitation to limit access in not-to-be to slots of the passed self object. I see how one could need to update other things, but I also see how this could be solved more elegantly with cells rules (i.e. doing too much in not-to-be looks like imparative programming through the backdoor -- this is not Java, after all ;-)). > ie, I am not sure then where to put the certification of death, tho it > occurs to be that the unfinished-business queue (if you have read that far) > is exactly where this should go, ie we queue instances up for death > certification to run after full propagation (including not-to-be processing) > after which point it will be safe to say slot access is an absolute bug. > > The neat thing is that we do have a distinct "awaken" stage in ufb > processing, why not a distinct "ex-parrot" stage? Sounds like the ultimate fix (somewhat like the zombie state I suggested), but I wonder whether it is overkill, given that your fix just works. > Another very quick fix would be simply to do something like with-integrity, > which explicitly says "I know this may not run right away". We could wrap > the not-to-be call in a with-post-mortem macro dynamically binding > *dead-is-cool* to t and then any access anywhere to dead things would be > allowed. This would avoid the runtime cost of queueing things up for > annihilation (but then I do not think that would be a big runtime burden at > all). > > Anyway, let me implement *dead-is-cool* and have that bound to t before > calling not-to-be so there is no need to wrap not-to-be code at all and see > what happens. I'll commit something soon, lemme know if it works. :) As I wrote before, I fixed one form in ensure-value-is-current, and it works beautifully :-) Cheers, Peter From kennytilton at optonline.net Sun Apr 13 15:21:10 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Sun, 13 Apr 2008 11:21:10 -0400 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <7758b2680804130340h4016eefck4b3debd09ab12c3c@mail.gmail.com> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> <480134B7.9010209@optonline.net> <48013E4F.2090104@optonline.net> <7758b2680804130340h4016eefck4b3debd09ab12c3c@mail.gmail.com> Message-ID: <480224E6.9090104@optonline.net> Peter Hildebrandt wrote: > Ken, > > First of all, thanks for the quick fix. However, it does not behave > quite as it should: cell slots now return t during not-to-be. I > think the reason is in md-slot-value.lisp:ensure-value-is-current, > more exactly: > > (when *not-to-be* > (return-from ensure-value-is-current t)) > > While the function returns otherwise: > > (bwhen (v (c-value c)) > (if (mdead v) > (progn > #+shhh (format t "~&on pulse ~a ensure-value still got and > still not returning ~a dead value ~a" *data-pulse-id* c v) > nil) > v))) > > That is, (c-value c). > > I changed it accordingly: > > (when *not-to-be* > (return-from ensure-value-is-current (c-value c))) Right, thanks, sorry for the head fake. Eventually something should be added to the regression test. > > Which works fine with my example code (that is, the cells-tree-view). > I checked it into cvs. > > I am not quite sure about the implications, though. Yeah, it is not clear what to do. The instance is no longer part of the model, so some rules will outright fail and those that do not would possibly be circular or at least form crazy dependencies of things no longer extant on those that are. > I think what I am > doing here is return the value of a cell without recalculating it -- > That is, I get the value calculated the last time the cell was > accessed alive. That means -- if I am right -- the value I work on > might be quite old, and a more granular check of the *not-to-be* > special might be appropriate. > > However, I did a quick test: > > ;; make two nodes to create a cell dependency > CTEST> (defparameter *val* (make-instance 'node :value (c-in 1))) > *VAL* > CTEST> (defparameter *root* (make-instance 'node :kids (c?n (list > (make-kid 'node :value (c? (value *val*))))))) > *ROOT* > > ;; check whether it works > CTEST> (value (first (kids *root*))) > 1 > CTEST> (setf (value *val*) 2) > 2 > CTEST> (value (first (kids *root*))) > 2 > ;; yep > > ;; look at not-to-be, > CTEST> (defmethod not-to-be :before ((self node)) > (trc "not-to-be :before" (value self))) > # > > ;; make a change > CTEST> (setf (value *val*) 3) > 3 > > ;; and see ... > CTEST> (setf (kids *root*) nil) > 0> not-to-be :before 3 > 0> not-to-be :before 3 > NIL > ;; wonderful! Hmmm. I see 'not-to-be gets called pretty early, pretty much as soon as a slot value has changed and owned things are seen to be no longer in that slot, right during propagation. So where a dying instance reads slot X and slot X is still alive and would normally update when read (and still will later during this same propagation (I think )) then the dying instance will see either an obsolete value or (I just realized) a new value if propagation got to X first by another path. Nothing like a little non-determinism to start the day. :) Well, The Lisp Way is to let people shoot themselves in the foot, we can probably just leave it as it is and see what happens. If there was any documentation we could document not-to-be and point all this out and remind them that code in not-to-be should not be doing things in or with the model, it should be, eg, notifying C libraries that blocks they allocated can be scavenged. Hmmm, those /could/ be the result of Cell rules, I guess it is good to return the old value. kt From kennytilton at optonline.net Mon Apr 14 11:09:45 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 14 Apr 2008 07:09:45 -0400 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <7758b2680804130340h4016eefck4b3debd09ab12c3c@mail.gmail.com> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> <480134B7.9010209@optonline.net> <48013E4F.2090104@optonline.net> <7758b2680804130340h4016eefck4b3debd09ab12c3c@mail.gmail.com> Message-ID: <48033B79.3040309@optonline.net> One hallmark of a good fix is when it makes comments and kludges go away. Just spotted this in Cello: (defmethod not-to-be :after ((self ogl-node)) (bwhen (dl (slot-value self 'dsp-list)) ;; don't trigger lazy cell (gl-delete-lists dl 1))) :) kt From peter.hildebrandt at gmail.com Mon Apr 14 12:34:08 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Mon, 14 Apr 2008 14:34:08 +0200 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <480224E6.9090104@optonline.net> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> <480134B7.9010209@optonline.net> <48013E4F.2090104@optonline.net> <7758b2680804130340h4016eefck4b3debd09ab12c3c@mail.gmail.com> <480224E6.9090104@optonline.net> Message-ID: <7758b2680804140534j3922d180u20ba21b10345cf0c@mail.gmail.com> On Sun, Apr 13, 2008 at 5:21 PM, Ken Tilton wrote: > Right, thanks, sorry for the head fake. Eventually something should be > added to the regression test. Well, we don't want to end up with more lines of test code than program code. So I'd leave that to the debugger for now ;-) > > I am not quite sure about the implications, though. > > Yeah, it is not clear what to do. The instance is no longer part of the > model, so some rules will outright fail and those that do not would possibly > be circular or at least form crazy dependencies of things no longer extant > on those that are. I assume that c-value is at least safe (that is, it is bound to return *something*) to do, so the only issue we're facing is that the value might be old. So my question becomes: How old can the value in the c-value slot become? I do not understand cells well enough to know whether we can safely assume that every change (setf) from before the changing of the kids list has trickled down to every ruled cell *before* not-to-be gets called as a result of a (distinct) change to the kids slot. I assume it would, though. It is trickier if the change to one input cell through a bunch of dependencies leads to a change in the kids list of some family member. Then not-to-be gets called, and we have no way of being sure which consequences of the original change have already been propagated and which haven't. But then, again, the value in c-value should be a max of one change old, that is, it should reflect the correct value from before the change which affected the kid to get thrown out. And now I realize I have just reinvented what you wrote. Damn, I should read the whole message *before* responding. > Hmmm. I see 'not-to-be gets called pretty early, pretty much as soon as a > slot value has changed and owned things are seen to be no longer in that > slot, right during propagation. So where a dying instance reads slot X and > slot X is still alive and would normally update when read (and still will > later during this same propagation (I think )) then the dying instance > will see either an obsolete value or (I just realized) a new value if > propagation got to X first by another path. > > Nothing like a little non-determinism to start the day. :) > > Well, The Lisp Way is to let people shoot themselves in the foot, we can > probably just leave it as it is and see what happens. Agreed. Especially since I feel the situations in which that could cause a problem are academic in nature. Usually not-to-be will only be concerned with cleanup stuff, and the cell values which are needed therefore would normally be somewhat stable, I assume. So if it will actually become an issue, we can still go back and invent the :death-bed stage in which not-to-be's are called after all changes have been propagated. > If there was any documentation we could document not-to-be and point all > this out and remind them that code in not-to-be should not be doing things > in or with the model, it should be, eg, notifying C libraries that blocks > they allocated can be scavenged. I guess the cells-devel archives serve as a doc in some way, so by that logic it is already part of the documentation. > Hmmm, those /could/ be the result of Cell rules, I guess it is good to > return the old value. This is hard now. Because it implies that *no* changes should be propagate dbefore not-to-be is called. But how to do that? Build a queue for *all* changes, filter out the changes to the kids, call not-to-be on the old, intact model, then propagate the changes from the queue? And what if not-to-be inflicts changes? My head is spinning ... I have to wait until after I have finished that bottle of wine. Cheers, Peter From kennytilton at optonline.net Mon Apr 14 13:04:02 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 14 Apr 2008 09:04:02 -0400 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <7758b2680804140534j3922d180u20ba21b10345cf0c@mail.gmail.com> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> <480134B7.9010209@optonline.net> <48013E4F.2090104@optonline.net> <7758b2680804130340h4016eefck4b3debd09ab12c3c@mail.gmail.com> <480224E6.9090104@optonline.net> <7758b2680804140534j3922d180u20ba21b10345cf0c@mail.gmail.com> Message-ID: <48035642.6090309@optonline.net> Peter Hildebrandt wrote: > On Sun, Apr 13, 2008 at 5:21 PM, Ken Tilton wrote: > > >> Right, thanks, sorry for the head fake. Eventually something should be >>added to the regression test. > > > Well, we don't want to end up with more lines of test code than > program code. So I'd leave that to the debugger for now ;-) Not an XP fan? :) Cells is pretty stable (but that will come unglued if people like you and Andy keep showing up) but I love taking things that go wrong and throwing them into a regression test suite precisely so I can continue hacking like a cowboy and then just re-running the test to see what broke, and if nothing breaks the code is declared perfect cuz if there is any behavior one does not like one has to get into the regression test. I know the XP guys write the tests first -- that might be a good policy for RFEs: if someone wants something changed they have to specify it in the form of a test that will not pass now. Just a great exercise for clarifying what one wants, seeing if it might already be there, and doing so in a way that guarantees no future change will back it out. (Sorry, just thinking out loud here.) > > >>>I am not quite sure about the implications, though. >> >> Yeah, it is not clear what to do. The instance is no longer part of the >>model, so some rules will outright fail and those that do not would possibly >>be circular or at least form crazy dependencies of things no longer extant >>on those that are. > > > I assume that c-value is at least safe (that is, it is bound to return > *something*) to do, so the only issue we're facing is that the value > might be old. > > So my question becomes: How old can the value in the c-value slot > become? I do not understand cells well enough to know whether we can > safely assume that every change (setf) from before the changing of the > kids list has trickled down to every ruled cell *before* not-to-be > gets called as a result of a (distinct) change to the kids slot. I > assume it would, though. Ah, I was wondering why you were surprised that 3 had gotten through. A naked SETF ends up wrapped in a within-integrity call that ensures data integrity as defined in cells-manifesto.txt (half-way in look for a list of a half-dozen things defining "integrity"). I think that will clarify things greatly. > > It is trickier if the change to one input cell through a bunch of > dependencies leads to a change in the kids list of some family member. > Then not-to-be gets called, and we have no way of being sure which > consequences of the original change have already been propagated and > which haven't. > > But then, again, the value in c-value should be a max of one change > old, that is, it should reflect the correct value from before the > change which affected the kid to get thrown out. > > And now I realize I have just reinvented what you wrote. Damn, I > should read the whole message *before* responding. > > >> Hmmm. I see 'not-to-be gets called pretty early, pretty much as soon as a >>slot value has changed and owned things are seen to be no longer in that >>slot, right during propagation. So where a dying instance reads slot X and >>slot X is still alive and would normally update when read (and still will >>later during this same propagation (I think )) then the dying instance >>will see either an obsolete value or (I just realized) a new value if >>propagation got to X first by another path. >> >> Nothing like a little non-determinism to start the day. :) >> >> Well, The Lisp Way is to let people shoot themselves in the foot, we can >>probably just leave it as it is and see what happens. > > > Agreed. Especially since I feel the situations in which that could > cause a problem are academic in nature. Usually not-to-be will only > be concerned with cleanup stuff, and the cell values which are needed > therefore would normally be somewhat stable, I assume. > > So if it will actually become an issue, we can still go back and > invent the :death-bed stage in which not-to-be's are called after all > changes have been propagated. Right, a new :ex-parrot unfinished-business queue to be processed before (I suppose) looking for a new change perhaps kicked off by an observer. > > >> If there was any documentation we could document not-to-be and point all >>this out and remind them that code in not-to-be should not be doing things >>in or with the model, it should be, eg, notifying C libraries that blocks >>they allocated can be scavenged. > > > I guess the cells-devel archives serve as a doc in some way, so by > that logic it is already part of the documentation. > > >> Hmmm, those /could/ be the result of Cell rules, I guess it is good to >>return the old value. > > > This is hard now. Because it implies that *no* changes should be > propagate dbefore not-to-be is called. But how to do that? Build a > queue for *all* changes, filter out the changes to the kids,... > call > not-to-be on the old, intact model, then propagate the changes from > the queue? And what if not-to-be inflicts changes? My head is > spinning ... I have to wait until after I have finished that bottle of > wine. Right, it's a lost cause. The Real Problem is not clearly dividing model-time from non-model-time by doing anything modelly during not-to-be. It was a bit extreme (as I once had it and did again by mistake) to force... ha, maybe that /is/ the way to go, force them to use slot-value. I like things like that that say to the user "I do not think you will forget you are in not-to-be as long as only slot-value works. Anyway... kt From peter.hildebrandt at gmail.com Mon Apr 14 14:29:35 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Mon, 14 Apr 2008 16:29:35 +0200 Subject: [cells-devel] Handling not-to-be'd kids and how to do an input slot for kids In-Reply-To: <48035642.6090309@optonline.net> References: <7758b2680804111100n6264d63du11469a5e07f7f180@mail.gmail.com> <47FFB681.8040106@optonline.net> <7758b2680804121242s5ab2642ex93986a83744c3c19@mail.gmail.com> <480134B7.9010209@optonline.net> <48013E4F.2090104@optonline.net> <7758b2680804130340h4016eefck4b3debd09ab12c3c@mail.gmail.com> <480224E6.9090104@optonline.net> <7758b2680804140534j3922d180u20ba21b10345cf0c@mail.gmail.com> <48035642.6090309@optonline.net> Message-ID: <7758b2680804140729v11a4f1dp9a6844473d072a9d@mail.gmail.com> > > Well, we don't want to end up with more lines of test code than > > program code. So I'd leave that to the debugger for now ;-) > > Not an XP fan? :) Cells is pretty stable (but that will come unglued if > people like you and Andy keep showing up) but I love taking things that go > wrong and throwing them into a regression test suite precisely so I can > continue hacking like a cowboy and then just re-running the test to see what > broke, and if nothing breaks the code is declared perfect cuz if there is > any behavior one does not like one has to get into the regression test. You got a point here: It does make hacking safer. In general, XP always sounded kinda strange to me, though; I feel I trust a function more when it looks well-written than when it passes *some* test. Maybe that's just because I am not good at writing solid tests. When I write test code it usually only reflects the angle I am looking from at the time of writing and thus becomes rather one-sided. Toss the code in a real world scenario, and the requirements are everything but what I wrote in the tests. And knowing my defencies at writing tests, I rather try to write sound code in the first place than to rely on my (tainted) tests. It looks quite different in the case you point out, however: > I know the XP guys write the tests first -- that might be a good policy for > RFEs: if someone wants something changed they have to specify it in the form > of a test that will not pass now. Just a great exercise for clarifying what > one wants, seeing if it might already be there, and doing so in a way that > guarantees no future change will back it out. i.e. when the person writing the test is the user of the functionality, not the one who implements it. That makes perfect sense to me, then. I will try to adapt this idea and post future requests here in the form of a stand-alone piece of code which would work if cells worked the way I want it to. > (Sorry, just thinking out loud here.) Nothing better than that on a rainy afternoon. :) > > So my question becomes: How old can the value in the c-value slot > Ah, I was wondering why you were surprised that 3 had gotten through. A > naked SETF ends up wrapped in a within-integrity call that ensures data > integrity as defined in cells-manifesto.txt (half-way in look for a list of > a half-dozen things defining "integrity"). I think that will clarify things > greatly. Thanks for the pointer! I have read the manifesto a while ago (when I got started with cells), but it makes a lot more sense now :) > > So if it will actually become an issue, we can still go back and > > invent the :death-bed stage in which not-to-be's are called after all > > changes have been propagated. > > Right, a new :ex-parrot unfinished-business queue to be processed before > (I suppose) looking for a new change perhaps kicked off by an observer. Yep, I guess the perfect order would be along these lines: - a change occurs - build dependency tree - find one or more changes of kids slots in the tree - do a *dry run* of the propagation to figure out what the new kids would be - call all relevant not-to-be's (which need to defer calls to setf with with-integrity) - then do the actual propagation - call observers - run the defered stuff i.e. one would need to figure out the changes to kids slots, but the n run not-to-be while the system is still in pre-propagation state, so that not-to-be code can use stuff "as if it was still alive". As I said before, I doubt that the effort for this kind of modification is justified. Let's hack on until we really need that. > Right, it's a lost cause. The Real Problem is not clearly dividing > model-time from non-model-time by doing anything modelly during not-to-be. > It was a bit extreme (as I once had it and did again by mistake) to force... > ha, maybe that /is/ the way to go, force them to use slot-value. I like > things like that that say to the user "I do not think you will forget you > are in not-to-be as long as only slot-value works. While we are at it, maybe we should introduce mandatory type declarations for ruled and input cells? :-> Cheers Peter From kennytilton at optonline.net Mon Apr 14 16:38:35 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 14 Apr 2008 12:38:35 -0400 Subject: [cells-devel] Re: [cells-gtk-devel] lots of circular cells in cells-gtk3? In-Reply-To: <7758b2680804140854w1ba92dd6l1150b50bc14c7ed5@mail.gmail.com> References: <7758b2680804140854w1ba92dd6l1150b50bc14c7ed5@mail.gmail.com> Message-ID: <4803888B.9090900@optonline.net> Peter Hildebrandt wrote: > Ken, did you change anything in cells as to how circular references > are dealt with? ps. while I am looking, look for a comment dated 2008-03-15 in cells.lisp k From peter.hildebrandt at gmail.com Mon Apr 14 16:43:14 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Mon, 14 Apr 2008 18:43:14 +0200 Subject: [cells-devel] Re: [cells-gtk-devel] lots of circular cells in cells-gtk3? In-Reply-To: <4803888B.9090900@optonline.net> References: <7758b2680804140854w1ba92dd6l1150b50bc14c7ed5@mail.gmail.com> <4803888B.9090900@optonline.net> Message-ID: <7758b2680804140943l7a796f48jdb3d8799b0e406b9@mail.gmail.com> As you saw in my other mail, I found the intermediate cause of the problem: I had included a reference to (id self) in initialize-instance of widget. For some reason that causes the circularity detection to raise its voice. What I don't understand, however, is why a reference to the slot in initialize-instance :after brings out circularity. For now, I moved the stuff into the rule for the id slot itself, so when the id is calculated, I use it right away, and don't have to worry about cell access. slot-value would have been another option, I suppose. But still: why??? Peter (oh, and yes, my cells from cvs is brand new) On Mon, Apr 14, 2008 at 6:38 PM, Ken Tilton wrote: > Peter Hildebrandt wrote: > > > Ken, did you change anything in cells as to how circular references > > are dealt with? > > > > ps. while I am looking, look for a comment dated 2008-03-15 in cells.lisp k > From kennytilton at optonline.net Mon Apr 14 16:47:09 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 14 Apr 2008 12:47:09 -0400 Subject: [cells-devel] Re: [cells-gtk-devel] lots of circular cells in cells-gtk3? In-Reply-To: <7758b2680804140939s7ec6ac36gc0ff26340242336@mail.gmail.com> References: <7758b2680804140854w1ba92dd6l1150b50bc14c7ed5@mail.gmail.com> <48038828.7070307@optonline.net> <7758b2680804140939s7ec6ac36gc0ff26340242336@mail.gmail.com> Message-ID: <48038A8D.3060308@optonline.net> Peter Hildebrandt wrote: > Mea culpa, just found the culprit in my own code. > > So the problem arises when I access (id self) in initialize-instance > :after of the widget class. > > No idea why, but removing that reference solves it. LOL. I was just looking at this and scratching my head: (defmodel gtk-object (family) (..... (id :initarg :id :accessor id :initform (c? (without-c-dependency .... (let ((id (apply (symbol-function (new-function-name self)) (new-args self)))) (gtk-object-store id self) id)))) Oh, I see. The applied function of course is collecting slot values for object creation, many mediated by rules. I guess the easiest fix would be a quick: (let ((cells::*call-stack* nil)) (without-c-dependency ...all else the same...)) But you are still a sinner going after a celled slot in initialize-instance. Can you move that to md-awaken? (Then I have not had enough coffee since my nap to figure out if you will still need the fix.) kt From kennytilton at optonline.net Mon Apr 14 16:57:37 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 14 Apr 2008 12:57:37 -0400 Subject: [cells-devel] Re: [cells-gtk-devel] lots of circular cells in cells-gtk3? In-Reply-To: <7758b2680804140943l7a796f48jdb3d8799b0e406b9@mail.gmail.com> References: <7758b2680804140854w1ba92dd6l1150b50bc14c7ed5@mail.gmail.com> <4803888B.9090900@optonline.net> <7758b2680804140943l7a796f48jdb3d8799b0e406b9@mail.gmail.com> Message-ID: <48038D01.1050804@optonline.net> Peter Hildebrandt wrote: > As you saw in my other mail, I found the intermediate cause of the > problem: I had included a reference to (id self) in > initialize-instance of widget. For some reason that causes the > circularity detection to raise its voice. > > What I don't understand, however, is why a reference to the slot in > initialize-instance :after brings out circularity. > > For now, I moved the stuff into the rule for the id slot itself, so > when the id is calculated, I use it right away, and don't have to > worry about cell access. slot-value would have been another option, I > suppose. > > But still: why??? Recently some evil programming took forever to debug because I was re-entering a rule without realizing it. After figuring out that that was happening and fixing the cause of that, I looked to see why rule re-entrance had not been detected, which I seemed to recall it always had been. Turns out the rule began with without-c-dependency as a trick to run only once. That macro simply: `(let ((cells::*call-stack* nil)) , at body) And that worked because the dependent cell was always identifed as (car cells::*call-stack*). Well, I like early bug detection you may have noticed recently , so I decided the macro without-c-dependency should leave the *call-stack* intact and instead bind a separate new *depender* special to nil, with *depender* being the, well, depender honored by the Cells machinery. You should not have been doing cells-y stuff in i-i, but you got away with it because of the old without-c-dependency behavior, so... ...congratulations, you are the first victim to fall into my new bug trap. :) kt From kennytilton at optonline.net Mon Apr 14 17:04:31 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 14 Apr 2008 13:04:31 -0400 Subject: [cells-devel] Re: [cells-gtk-devel] lots of circular cells in cells-gtk3? In-Reply-To: <48038D01.1050804@optonline.net> References: <7758b2680804140854w1ba92dd6l1150b50bc14c7ed5@mail.gmail.com> <4803888B.9090900@optonline.net> <7758b2680804140943l7a796f48jdb3d8799b0e406b9@mail.gmail.com> <48038D01.1050804@optonline.net> Message-ID: <48038E9F.1010401@optonline.net> Ken Tilton wrote: > Recently some evil programming took forever to debug because I was > re-entering a rule without realizing it. After figuring out that that > was happening and fixing the cause of that, I looked to see why rule > re-entrance had not been detected, which I seemed to recall it always > had been. > > Turns out the rule began with without-c-dependency as a trick to run > only once. That macro simply: > > `(let ((cells::*call-stack* nil)) > , at body) > > And that worked because the dependent cell was always identifed as (car > cells::*call-stack*). In case that last bit is not clear, what I meant was "That worked [to avoid dependency] because the dependent cell was identified by taking the car of the *call-stack*" btw, note that this undetected re-entrance would happen if /any/ rule in the chain leading back to the same cell did a without-c-dependency. kt From peter.hildebrandt at gmail.com Mon Apr 14 17:04:50 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Mon, 14 Apr 2008 19:04:50 +0200 Subject: [cells-devel] Re: [cells-gtk-devel] lots of circular cells in cells-gtk3? In-Reply-To: <48038D01.1050804@optonline.net> References: <7758b2680804140854w1ba92dd6l1150b50bc14c7ed5@mail.gmail.com> <4803888B.9090900@optonline.net> <7758b2680804140943l7a796f48jdb3d8799b0e406b9@mail.gmail.com> <48038D01.1050804@optonline.net> Message-ID: <7758b2680804141004q4f4a9dbfvc6c080cb97fc1b80@mail.gmail.com> Ken, thanks for shadding some light on the issue. I think I found a decent solution to the problem by abusing (what a contradiction) the rule for the id slot and dropping in my two lines: #+libcellsgtk (gtk-signal-connect-swap id "configure-event" (cffi:get-callback 'reshape-widget-handler) :data id) (gtk-signal-connect-swap id "delete-event" (cffi:get-callback 'delete-widget-handler) :data id) This way I can use id -- the local lexical variable holding the brand new id -- and work with it without any cells dependency. And one could argue that I do the required stuff right where it belongs. Cheers, Peter On Mon, Apr 14, 2008 at 6:57 PM, Ken Tilton wrote: > Peter Hildebrandt wrote: > > > As you saw in my other mail, I found the intermediate cause of the > > problem: I had included a reference to (id self) in > > initialize-instance of widget. For some reason that causes the > > circularity detection to raise its voice. > > > > What I don't understand, however, is why a reference to the slot in > > initialize-instance :after brings out circularity. > > > > For now, I moved the stuff into the rule for the id slot itself, so > > when the id is calculated, I use it right away, and don't have to > > worry about cell access. slot-value would have been another option, I > > suppose. > > > > But still: why??? > > > > Recently some evil programming took forever to debug because I was > re-entering a rule without realizing it. After figuring out that that was > happening and fixing the cause of that, I looked to see why rule re-entrance > had not been detected, which I seemed to recall it always had been. > > Turns out the rule began with without-c-dependency as a trick to run only > once. That macro simply: > > `(let ((cells::*call-stack* nil)) > , at body) > > And that worked because the dependent cell was always identifed as (car > cells::*call-stack*). > > Well, I like early bug detection you may have noticed recently , so I > decided the macro without-c-dependency should leave the *call-stack* intact > and instead bind a separate new *depender* special to nil, with *depender* > being the, well, depender honored by the Cells machinery. > > You should not have been doing cells-y stuff in i-i, but you got away with > it because of the old without-c-dependency behavior, so... > > ...congratulations, you are the first victim to fall into my new bug trap. > :) > > kt > From peter.hildebrandt at gmail.com Mon Apr 14 17:08:58 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Mon, 14 Apr 2008 19:08:58 +0200 Subject: [cells-devel] Re: [cells-gtk-devel] lots of circular cells in cells-gtk3? In-Reply-To: <48038D01.1050804@optonline.net> References: <7758b2680804140854w1ba92dd6l1150b50bc14c7ed5@mail.gmail.com> <4803888B.9090900@optonline.net> <7758b2680804140943l7a796f48jdb3d8799b0e406b9@mail.gmail.com> <48038D01.1050804@optonline.net> Message-ID: <7758b2680804141008x1322d00dxd34872f8dae3a4c@mail.gmail.com> On Mon, Apr 14, 2008 at 6:57 PM, Ken Tilton wrote: > Recently some evil programming took forever to debug because I was > re-entering a rule without realizing it. After figuring out that that was > happening and fixing the cause of that, I looked to see why rule re-entrance > had not been detected, which I seemed to recall it always had been. > > Turns out the rule began with without-c-dependency as a trick to run only > once. That macro simply: > > `(let ((cells::*call-stack* nil)) > , at body) > > And that worked because the dependent cell was always identifed as (car > cells::*call-stack*). Wow, congrats for figuring that out. Sounds like one of these things that take forever ... > Well, I like early bug detection you may have noticed recently , so I > decided the macro without-c-dependency should leave the *call-stack* intact > and instead bind a separate new *depender* special to nil, with *depender* > being the, well, depender honored by the Cells machinery. Sounds good. And you obviously found some "unclean" stuff I was doing. > You should not have been doing cells-y stuff in i-i, but you got away with > it because of the old without-c-dependency behavior, so... Actually, the drawing area widget still gets away with it. Maybe because it does not have kids ... I don't know. > ...congratulations, you are the first victim to fall into my new bug trap. > :) I'm proud :) Peter From peter.hildebrandt at gmail.com Mon Apr 14 17:12:23 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Mon, 14 Apr 2008 19:12:23 +0200 Subject: [cells-devel] Re: [cells-gtk-devel] lots of circular cells in cells-gtk3? In-Reply-To: <48038E9F.1010401@optonline.net> References: <7758b2680804140854w1ba92dd6l1150b50bc14c7ed5@mail.gmail.com> <4803888B.9090900@optonline.net> <7758b2680804140943l7a796f48jdb3d8799b0e406b9@mail.gmail.com> <48038D01.1050804@optonline.net> <48038E9F.1010401@optonline.net> Message-ID: <7758b2680804141012u7d455faeh4086061dd694a929@mail.gmail.com> On Mon, Apr 14, 2008 at 7:04 PM, Ken Tilton wrote: > btw, note that this undetected re-entrance would happen if /any/ rule in > the chain leading back to the same cell did a without-c-dependency. If you write it like that, it's pretty clear given the scope. But for real world code, this must have been a pretty big loop hole -- allowing for dangerous code to pass through and break badly further down the road. So I'm glad we're on the safe side now. :-) Peter From frgo at mac.com Mon Apr 14 18:56:39 2008 From: frgo at mac.com (Frank Goenninger) Date: Mon, 14 Apr 2008 20:56:39 +0200 Subject: [cells-devel] [openair] recv function ?! Message-ID: <6621A1C1-F622-4AAC-9451-B911F44C83C1@mac.com> Andy, I am currently trying to figure out why I don't get any update on my browser of, if any, just once. When looking at the recv function in openair.js I see: function recv (data) { var response = eval("[" + data + "]"); for(var i=0; i References: <6621A1C1-F622-4AAC-9451-B911F44C83C1@mac.com> Message-ID: <4803AF29.1000909@optonline.net> Frank Goenninger wrote: > Andy, > > I am currently trying to figure out why I don't get any update on my > browser of, if any, just once. > When looking at the recv function in openair.js I see: > > function recv (data) { > var response = eval("[" + data + "]"); > for(var i=0; i eval(response[i]); > } > } > > Kind of weird to me... I'd understand if it read: > > function recv (data) { > var response = eval("[" + data + "]"); > for(var i=0; i eval(response[i]); > } > } Hmmm, if that was a typo then the loop would iterate once for each character in the response evaluating (eventually) non-existent responses which should be fast but... we have been wondering my the thing was hugely slow at times, I will try this fix later. Nice catch, Frank! (It looks like a catch to me.) btw, JS goes into the loop even when the conditionis false initially? Hard to believe they got that wrong. I will add a preemptive strike anyway, cannot hurt. kt From frgo at mac.com Mon Apr 14 21:01:55 2008 From: frgo at mac.com (Frank Goenninger) Date: Mon, 14 Apr 2008 23:01:55 +0200 Subject: [cells-devel] [openair] recv function ?! In-Reply-To: <4803AF29.1000909@optonline.net> References: <6621A1C1-F622-4AAC-9451-B911F44C83C1@mac.com> <4803AF29.1000909@optonline.net> Message-ID: <18BA8839-5E79-43D9-908D-E630F475DA1C@mac.com> Am 14.04.2008 um 21:23 schrieb Ken Tilton: > Frank Goenninger wrote: >> Andy, >> I am currently trying to figure out why I don't get any update on >> my browser of, if any, just once. >> When looking at the recv function in openair.js I see: >> function recv (data) { >> var response = eval("[" + data + "]"); >> for(var i=0; i> eval(response[i]); >> } >> } >> Kind of weird to me... I'd understand if it read: >> function recv (data) { >> var response = eval("[" + data + "]"); >> for(var i=0; i> eval(response[i]); >> } >> } > > Hmmm, if that was a typo then the loop would iterate once for each > character in the response evaluating (eventually) non-existent > responses which should be fast but... we have been wondering my the > thing was hugely slow at times, I will try this fix later. > > Nice catch, Frank! (It looks like a catch to me.) btw, JS goes into > the loop even when the conditionis false initially? Hard to believe > they got that wrong. I will add a preemptive strike anyway, cannot > hurt. Showed up in the Firebug Debugger (Firefox *really* is /the/ choice for Web developers ...) - I will check again if this really happens - wait a minute ... Yep - it is entering the for loop: response.length is 0 and it executes the eval in the loop... Cheers (that nice brown liquid right beside me is yelling "Drink me" - well, it's been in the cask for 18 year so let's swallow it sloooowly ... mmmmh ...) Frank From kentilton at gmail.com Tue Apr 15 13:37:31 2008 From: kentilton at gmail.com (Ken Tilton) Date: Tue, 15 Apr 2008 09:37:31 -0400 Subject: [cells-devel] [openair] recv function ?! In-Reply-To: <6621A1C1-F622-4AAC-9451-B911F44C83C1@mac.com> References: <6621A1C1-F622-4AAC-9451-B911F44C83C1@mac.com> Message-ID: Hey,all. Now my ISP considers uptime optional. :( Chatting from starbucks. :) Anydody want to email me a new-improved openair.js and/or source tree before I head home? This is there second outage in as many days, I guess their sys admin is thrashing. Anyway, generally only down for a few hours at a time, but.... well, there is always starbucks! kt -------------- next part -------------- An HTML attachment was scrubbed... URL: From frgo at mac.com Tue Apr 15 21:06:44 2008 From: frgo at mac.com (Frank Goenninger) Date: Tue, 15 Apr 2008 23:06:44 +0200 Subject: [cells-devel] [openair] Scratching my head ... Message-ID: <71F3D6E6-3524-47AA-AF05-79552E0B9706@mac.com> Hmmm. So there's this function I "borrowed" from Kenny's code: (defun ht-monitor-page (path resource-class) (lambda (request) (trc "bingo request!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" request path resource-class) (start-session) (let ((root (or (bwhen (r (session-value 'root)) (trc "clearing updates on re-used root!!!!!!!" r) (setf (updates r) nil) r) (progn (trc "creating new web-app...") (mk-web-app (:prefix path :request (c-in request)) ;; was (c-in request) but we set that below so ??? (make-instance resource-class :fm-parent *parent*)))))) (trc "ROOT = " root) (setf (session-value 'root) root) (setf (request root) request) #+test-ht-monitor (break) ;; <<<<<<<-- See here ;; (assert (handler root)) ;; <<<<<<<-- AND HERE ! ALWAYS FAILS ! (trc "Handler is: " (describe (handler root))) (trc "******* Calling handler ") (handler root)))) My model is quite simple: (defmd ht-monitor (page) name ip-address term :title ":: HUNCHENTOOT MONITOR ::" :style "/css/ht-monitor.css" :name (c? (server-name *server*)) :ip-address (c? (server-address *server*)) :term (c-in "") :kids (c? (the-kids (mk-div () (mk-text (c? (conc$ "Name: " (name (u^ ht-monitor)))))) (mk-div () (mk-text (c? (conc$ "IP Address: " (ip-address (u^ ht- monitor)))))) (mk-div () (mk-form (:action :get) (mk-text "Input: ") (mk-input (:name "i" :id "i" :-type "text" :value (c?n (term (u^ ht-monitor))))) (mk-text (c? (conc$ "Reversed: " (reverse (term (u^ ht-monitor))))))))))) Handler is always NIL. The assertion always fails. I could not figure out why... Any ideas ??? Thx! Best, Frank From kennytilton at optonline.net Tue Apr 15 22:52:34 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Tue, 15 Apr 2008 18:52:34 -0400 Subject: [cells-devel] [openair] Scratching my head ... In-Reply-To: <71F3D6E6-3524-47AA-AF05-79552E0B9706@mac.com> References: <71F3D6E6-3524-47AA-AF05-79552E0B9706@mac.com> Message-ID: <480531B2.30106@optonline.net> Frank Goenninger wrote: > Hmmm. So there's this function I "borrowed" from Kenny's code: > > > (defun ht-monitor-page (path resource-class) > (lambda (request) > (trc "bingo request!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" request path > resource-class) > (start-session) > (let ((root (or (bwhen (r (session-value 'root)) > (trc "clearing updates on re-used root!!!!!!!" r) > (setf (updates r) nil) > r) > (progn > (trc "creating new web-app...") > (mk-web-app (:prefix path > :request (c-in request)) ;; > was (c-in request) but we set that below so ??? I noticed that as well, never got a chance to pursue the question. I believe I tried supplying (c-in nil) as the initarg and things did not go well so I restored it to what is shown. The setf below is then an NOP when we make a new web-app because of how Cells handles non-change. I guessed that things happened during initialization that depended on having the intial request in hand. Andy will know better. > (make-instance > resource-class > :fm-parent *parent*)))))) > (trc "ROOT = " root) > (setf (session-value 'root) root) > (setf (request root) request) > #+test-ht-monitor (break) ;; <<<<<<<-- See here > ;; (assert (handler root)) ;; <<<<<<<-- AND HERE ! ALWAYS FAILS ! That might be a bug I inserted, not understanding that some requests go to jquery and in that case openair should return nil. I took out a bit that looked for the "apropos" prefix and changed it to something ... well, I was just thrashing and reacted badly to something that looked wrong but probably was nominal. kt > (trc "Handler is: " (describe (handler root))) > (trc "******* Calling handler ") > (handler root)))) > > My model is quite simple: > > (defmd ht-monitor (page) > name > ip-address > term > > :title ":: HUNCHENTOOT MONITOR ::" > :style "/css/ht-monitor.css" > > :name (c? (server-name *server*)) > :ip-address (c? (server-address *server*)) > :term (c-in "") > > :kids (c? (the-kids > (mk-div () > (mk-text (c? (conc$ "Name: " (name (u^ ht-monitor)))))) > (mk-div () > (mk-text (c? (conc$ "IP Address: " (ip-address (u^ ht- > monitor)))))) > (mk-div () > (mk-form (:action :get) > (mk-text "Input: ") > (mk-input (:name "i" > :id "i" > :-type "text" > :value (c?n (term (u^ ht-monitor))))) > (mk-text (c? (conc$ "Reversed: " (reverse (term (u^ > ht-monitor))))))))))) > > Handler is always NIL. The assertion always fails. I could not figure > out why... > > Any ideas ??? > > Thx! > > Best, > Frank > > _______________________________________________ > cells-devel site list > cells-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cells-devel > From peter.hildebrandt at gmail.com Wed Apr 16 15:26:05 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Wed, 16 Apr 2008 17:26:05 +0200 Subject: [cells-devel] Optimized away/dying rules Message-ID: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> While working on the hash-table lookup for md-names (as an alternative to fm-other) I came across an interesting phenomenon: Some rules die, others don't. Following the XP idea for RFEs, I'll try to present a test case: (defpackage :c-test (:use :cl :cells :utils-kt)) (in-package :c-test) (defparameter *hash* (make-hash-table)) (defun val (name) (bwhen (obj (gethash name *hash*)) (value obj))) (defparameter *m1* (make-instance 'model :value (c? (bif (v (val :foo)) (1+ v) 'nothing)))) (assert (eql (value *m1*) 'nothing)) (setf (gethash :foo *hash*) (make-instance 'model :value (c-in nil))) (defparameter *m2* (make-instance 'model :value (c? (bif (v (val :foo)) (1+ v) 'nothing)))) (assert (eql (value *m1*) 'nothing)) (assert (eql (value *m2*) 'nothing)) (setf (value (gethash :foo *hash*)) 42) (assert (eql (value *m1*) 43)) ;;; #### FAILS #### (assert (eql (value *m2*) 43)) ;;; ok (setf (value (gethash :foo *hash*)) 17) (assert (eql (value *m1*) 18)) ;;; #### FAILS #### (assert (eql (value *m2*) 18)) ;;; ok ;;; or with a list (defparameter *list* nil) (defun valb (name) (bwhen (obj (assocd name *list*)) (value obj))) (defparameter *m1b* (make-instance 'model :value (c? (bif (v (valb :foo)) (1+ v) 'nothing)))) (assert (eql (value *m1b*) 'nothing)) (push (cons :foo (make-instance 'model :value (c-in nil))) *list*) (defparameter *m2b* (make-instance 'model :value (c? (bif (v (valb :foo)) (1+ v) 'nothing)))) (assert (eql (value *m1b*) 'nothing)) (assert (eql (value *m2b*) 'nothing)) (setf (value (assocd :foo *list*)) 17) (assert (eql (value *m1b*) 18)) ;;; #### FAILS #### (assert (eql (value *m2b*) 18)) ;;; ok (setf (value (assocd :foo *list*)) 42) (assert (eql (value *m1b*) 43)) ;;; #### FAILS #### (assert (eql (value *m2b*) 43)) ;;; ok -------- An interesting indicator might be that the first call to (value *m1*) returns two values, 'nothing and nil -- does that mean that cells somehow realizes there that this cell can be optimized out? And -- more importantly -- how can I tell cells not to optimize away the ruled cell in *m1*/*m1b*? Thanks, Peter From peter.hildebrandt at gmail.com Wed Apr 16 17:13:55 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Wed, 16 Apr 2008 19:13:55 +0200 Subject: [cells-devel] Re: Optimized away/dying rules In-Reply-To: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> References: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> Message-ID: <7758b2680804161013y35b0e443w9857caeaec0b2082@mail.gmail.com> Ok, hold on, I just realize there was no way this could work: At the time the (c? ...) is evaluated, the (c-in ..) cell it is supposed to depend on does not even exist, so how should c? possibly establish a dependency to that? Since I am still looking for a cell-aware store, I suggest something like this: (c?-with (obj :foo *store* 'nothing) (value obj)) with (defmacro c?-with ((obj key store &optional default) &body body) ...) where key is looked up in store; if it exists, body is executed with obj bound to the corresponding object. If not, default is returned. The trick is to delay the execution of body until key in store is created, only then executing the body, and having cells pick up the dependencies. So basically we want *store* to be defined before c?-with is evaluated -- and once it is, it will check whether key is already present in there. If it is not, it pushes a closure into a hash table on key in store. Then, if whenever an object is added to store, store will check whether something is in the c-with-queue hash table, and evaluate the stored closures if any. These in turn will kick their c?-with ruled cells, which can then be initialized just like normal cells. The big question will be: How do we do the delay so that the cell does not get optimized away prematurely? That is, how do we make sure, that the cell first duly registers itself with store, then returns the default, and finally establish the proper dependencies when the stored closure gets kicked by the store? Ideas welcome. Cheers, Peter On Wed, Apr 16, 2008 at 5:26 PM, Peter Hildebrandt wrote: > While working on the hash-table lookup for md-names (as an alternative > to fm-other) I came across an interesting phenomenon: Some rules die, > others don't. Following the XP idea for RFEs, I'll try to present a > test case: > > (defpackage :c-test (:use :cl :cells :utils-kt)) > (in-package :c-test) > > (defparameter *hash* (make-hash-table)) > (defun val (name) (bwhen (obj (gethash name *hash*)) > (value obj))) > > (defparameter *m1* (make-instance 'model :value (c? (bif (v (val > :foo)) (1+ v) 'nothing)))) > (assert (eql (value *m1*) 'nothing)) > > (setf (gethash :foo *hash*) (make-instance 'model :value (c-in nil))) > > (defparameter *m2* (make-instance 'model :value (c? (bif (v (val > :foo)) (1+ v) 'nothing)))) > > (assert (eql (value *m1*) 'nothing)) > (assert (eql (value *m2*) 'nothing)) > > (setf (value (gethash :foo *hash*)) 42) > (assert (eql (value *m1*) 43)) ;;; #### FAILS #### > (assert (eql (value *m2*) 43)) ;;; ok > > (setf (value (gethash :foo *hash*)) 17) > (assert (eql (value *m1*) 18)) ;;; #### FAILS #### > (assert (eql (value *m2*) 18)) ;;; ok > > ;;; or with a list > > (defparameter *list* nil) > (defun valb (name) (bwhen (obj (assocd name *list*)) > (value obj))) > (defparameter *m1b* (make-instance 'model :value (c? (bif (v (valb > :foo)) (1+ v) 'nothing)))) > > (assert (eql (value *m1b*) 'nothing)) > > (push (cons :foo (make-instance 'model :value (c-in nil))) *list*) > > (defparameter *m2b* (make-instance 'model :value (c? (bif (v (valb > :foo)) (1+ v) 'nothing)))) > > (assert (eql (value *m1b*) 'nothing)) > (assert (eql (value *m2b*) 'nothing)) > > (setf (value (assocd :foo *list*)) 17) > (assert (eql (value *m1b*) 18)) ;;; #### FAILS #### > (assert (eql (value *m2b*) 18)) ;;; ok > > (setf (value (assocd :foo *list*)) 42) > (assert (eql (value *m1b*) 43)) ;;; #### FAILS #### > (assert (eql (value *m2b*) 43)) ;;; ok > > -------- > > An interesting indicator might be that the first call to (value *m1*) > returns two values, 'nothing and nil -- does that mean that cells > somehow realizes there that this cell can be optimized out? > > And -- more importantly -- how can I tell cells not to optimize away > the ruled cell in *m1*/*m1b*? > > Thanks, > Peter > From frgo at mac.com Wed Apr 16 19:24:22 2008 From: frgo at mac.com (Frank Goenninger) Date: Wed, 16 Apr 2008 21:24:22 +0200 Subject: [cells-devel] [openair] web-app still :NASCENT after make-instance Message-ID: <33E5F2FB-270D-4722-B38F-F5AB2EBA7E4B@mac.com> Ok, so I am still trying to find out why the handler slot of the web app is always NIL. That's what I get after creating the instance with make-instance: 0> 72657 *** BINGO request !!! # "/ht- monitor" "/ht-monitor" openair::ht-monitor 0> 0 *** Entering page handling ... 0> 0 creating new web-app... 0> 0 ROOT = web-app6 WEB-APP6 is an instance of #: The following slots have :INSTANCE allocation: .MD-STATE :NASCENT .AWAKEN-ON-INIT-P NIL .CELLS ((OPENAIR::HANDLER . ) (OPENAIR::RESOURCE . ) (OPENAIR::UPDATES . ) (OPENAIR::MESSAGE . ) (OPENAIR::REQUEST . ) (CELLS:.KIDS . )) .CELLS-FLUSHED NIL ADOPT-CT 0 .MD-NAME WEB-APP6 .FM-PARENT NIL .VALUE NIL ZDBG NIL .KID-SLOTS NIL .KIDS NIL PREFIX "/ht-monitor" REQUEST NIL MESSAGE NIL UPDATES NIL RESOURCE NIL HANDLER NIL Now, as we can see, the .MD-STATE is :NASCENT - so Cell's machinery hasn't done its job conpletely yet... Kenny, how can we force Cells to finish its business ?! Or is there any other way to do this? Thanks for any help! (see below for the full function) Best, Frank -X- CODE -X- (defun ht-monitor-page (prefix resource-class) (lambda (request) (trc "*** BINGO request !!!" request (script-name request) prefix resource-class) ;; New here: only go into the actual function if we are really meant ... (let ((mismatch (mismatch (script-name request) prefix :test #'char=))) (and (or (null mismatch) (>= mismatch (length prefix))) (progn (trc "*** Entering page handling ...") (start-session) (let ((root (or (bwhen (r (session-value 'root)) (trc "clearing updates on re-used root!!!!!!!" r) (with-integrity () (setf (updates r) nil)) r) (progn (trc "creating new web-app...") (mk-web-app (:prefix prefix :request (c-in nil)) (make-instance resource-class :fm-parent *parent*)))))) (trc "ROOT = " root) (describe root) (setf (session-value 'root) root) (setf (request root) request) (assert (handler root)) (trc "Handler is: " (describe (handler root))) (handler root))))))) From peter.hildebrandt at gmail.com Thu Apr 17 13:52:40 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Thu, 17 Apr 2008 15:52:40 +0200 Subject: [cells-devel] Added cells-store to cells Message-ID: <7758b2680804170652r6980d181ideacb454723eaf42@mail.gmail.com> As promised yesterday I added a cells-store facility to cells. The code can be found at the bottom of md-utilities in CVS. Basically, this is a cells-aware hash table with some syntactic sugar. Here's part of the test function included in md-utilities: (defun test-cells-store () (trc "testing cells-store -- making objects") (let* ((store (make-instance 'cells-store)) (foo (make-instance 'test-store-item :value (c?-with-stored (v :foo store 'nothing) (bwhen (val (value v)) val)))) (foo+1 (make-instance 'test-store-item :value (c?-with-stored (v :foo store 'nothing) (bwhen (val (value v)) (1+ val)))))) (store-add :foo store (make-instance 'family :value (c-in nil))) (setf (value (store-lookup :foo store)) 1) (store-remove :foo store)) So you create a ruled cell with c?-with-stored. This can happen before or after key is added to the cells-store. When the rule is the executed, when an object is added or removed from key in the hash table *or* when any of the cells on the object change. The rule is not executed, if other stuff in the hash table changes. The (c?-with-stored (var key store &optional default) &body body) macro works like bwhen -- that is, if key is present, body is executed with var bound to the object identified by key -- and if not, default is returned. That means, body can assume that var is bound to a valid object (like in the example, it is safe to call value on it, if you know that you only store family instances in the store) Calling store-remove will reset all dependent cells to their default. The change is propagated as soon as store-add, setf, or store-remove are called -- meaning that observers will do the expected thing. Maybe someone will find it useful. Peter From kennytilton at optonline.net Thu Apr 17 14:52:25 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Thu, 17 Apr 2008 10:52:25 -0400 Subject: [cells-devel] Added cells-store to cells In-Reply-To: <7758b2680804170652r6980d181ideacb454723eaf42@mail.gmail.com> References: <7758b2680804170652r6980d181ideacb454723eaf42@mail.gmail.com> Message-ID: <48076429.3030201@optonline.net> Peter Hildebrandt wrote: > As promised yesterday I added a cells-store facility to cells. The > code can be found at the bottom of md-utilities in CVS. Cool. I am curious what application requirement led to this. Not that it is not a good idea. Being able to reach inside other structures for dependency is a natural fleshing-out of Cells -- why stop at the slot, or force everything to /be/ a slot to depend on it? Meta-cool is that you are the first Cells user to do something like this, IIRC, altho there are several who took the more typical Lisper approach of dashing off to do their own versions of the entire package. :) > > Basically, this is a cells-aware hash table with some syntactic sugar. > > Here's part of the test function included in md-utilities: > > (defun test-cells-store () > (trc "testing cells-store -- making objects") > (let* ((store (make-instance 'cells-store)) > (foo (make-instance 'test-store-item :value (c?-with-stored (v :foo > store 'nothing) > (bwhen (val (value v)) val)))) > (foo+1 (make-instance 'test-store-item :value (c?-with-stored (v > :foo store 'nothing) > (bwhen (val (value v)) (1+ val)))))) > (store-add :foo store (make-instance 'family :value (c-in nil))) > > (setf (value (store-lookup :foo store)) 1) > > (store-remove :foo store)) > > So you create a ruled cell with c?-with-stored. This can happen > before or after key is added to the cells-store. When the rule is the > executed, when an object is added or removed from key in the hash > table *or* when any of the cells on the object change. The rule is > not executed, if other stuff in the hash table changes. > > The (c?-with-stored (var key store &optional default) &body body) I have not looked at the code so maybe what I am about to suggest is already possible, but would this also be useful (just to confuse things I changed with-stored to bwhen-c-gethash: (c? (if (^whatever) 42 (bwhen-c-gethash (user login-id *user-logins*) .....))) The above might be easily done (just a tweak or two) by looking at how synapses work. They are like local and/or anonymous Cells. "Anonymous" because they do not mediate a slot, they mediate an arbitrary sub-form of a rule. "Local" because only the Cell envalued by the containing form depends on the synaptic Cell. Historical note: synapses used to be a completely different data structure with distinct code supporting them, now we just have a "synaptic" attribute to guide the general Cells logic in a few places. Anyway, then c?-with-stored is just the special case where this appears as the entire form: (c? (bwhen-c-gethash (...) ...)) Hmmm, you know, I almost never use synapses and yet I have always suspected that a lot of fun would be had with them in re expanding the semantics one could express with Cells. But this exchange has me wondering if I missed something: will new kinds of Cells tend to be synapses because the semantics will be useful within rules? Or maybe I am just confused: should all cells be synapses now? I might be in the land of distinctions without differences now. :) Well, I am off to Amsterdam shortly and will play with this when I get back. Not sure how much time I will be on-line, btw, until Monday. Thanks for a cool contrib. kt > macro works like bwhen -- that is, if key is present, body is executed > with var bound to the object identified by key -- and if not, default > is returned. That means, body can assume that var is bound to a valid > object (like in the example, it is safe to call value on it, if you > know that you only store family instances in the store) > > Calling store-remove will reset all dependent cells to their default. > > The change is propagated as soon as store-add, setf, or store-remove > are called -- meaning that observers will do the expected thing. > > Maybe someone will find it useful. > > Peter > _______________________________________________ > cells-devel site list > cells-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cells-devel > From peter.hildebrandt at gmail.com Thu Apr 17 15:56:50 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Thu, 17 Apr 2008 17:56:50 +0200 Subject: [cells-devel] Added cells-store to cells In-Reply-To: <48076429.3030201@optonline.net> References: <7758b2680804170652r6980d181ideacb454723eaf42@mail.gmail.com> <48076429.3030201@optonline.net> Message-ID: <7758b2680804170856s19aef71cq3cf9728dcc666ac7@mail.gmail.com> Ken, thanks for the quick response. I'll try to illuminate things a bit. > Cool. I am curious what application requirement led to this. I've been looking for a while for a way to store a (possibly large) number of model objects in a way that makes it easy and fast both to iterate over them and to access individual ones. In principle this can all be done with the fm-utilities, e.g. kids and fm-other. However, when things get big, I feel bad constantly traversing trees with fm-other and keeping tons of instances in the kids slot. There are three reasons I was looking for an alternative: - My current research app models some type of human learning, which involves huge numbers of interlinked nodes in a network. I was looking for a data structure which has O(1) access. - fm-other traverses the tree at initialization time looking for the target. I was looking for a way to reference instances to be created in the future. (For example, this is interesting when loading a network from file - either you have an acyclic graph and save it in a topological order, or you need some way to forward reference to-be-loaded nodes) - I am afraid (correct me if this is wrong) that ruled cells using fm-other are calculated more often than necessary -- e.g. you have a cell depending on (fm-other :something). Then every time a new kids is added somewhere in the tree, this rule should be run to check whether there is a :something now somewhere. My cells-store hash table makes sure that only those rules are run that are actually necessary. The immediate reason is that when debugging some cells-gtk stuff, I was confronted with a thick knot of fm-other initiated tree traversals, and I wished I had something more linear and predictable. So I tried to use simple hash table look ups, but that did not work since the cells did not learn when new items were added to the table (i.e. forward references broke). Thus I needed a cells-aware hash table. And now I'll use that in my app and in cells-ode, too. > Not that it is > not a good idea. Being able to reach inside other structures for dependency > is a natural fleshing-out of Cells -- why stop at the slot, or force > everything to /be/ a slot to depend on it? Yep, there might be other cases -- even though I can't think of anything besides a hash table where I ever missed cells-awareness. > Meta-cool is that you are the first Cells user to do something like this, > IIRC, altho there are several who took the more typical Lisper approach of > dashing off to do their own versions of the entire package. :) Thanks, I take it as a compliment. > > The (c?-with-stored (var key store &optional default) &body body) > > > > I have not looked at the code so maybe what I am about to suggest is > already possible, but would this also be useful (just to confuse things I > changed with-stored to bwhen-c-gethash: > > (c? (if (^whatever) > 42 > (bwhen-c-gethash (user login-id *user-logins*) > .....))) Funny you picked that name. At first, I called it c?-bwhen-hash. Then I figured that with fit the semantics better. Maybe I was right the first time, tho. As to you point, no, this is not possible right now since c?-with-stored expands into (c? ...). This is not necessary, though, because all my macro does is establish a dependency on an intermediate object which gets modified if the corresponding hash table entry is manipulated (i.e. an object added/removed). So indeed we could have this (w/o the c? part) as a standalone macro. I changed it in CVS. The following works now, too: (make-instance 'test-store-item :value (c? (if (value bypass-lookup?) 'no-lookup (bwhen-gethash (v :bar store 'nothing) (value v))))) I included it in the test func at the bottom of md-utilities. If you feel like it, you can integrate it with the test suite. (You're the maintainer, after all *g*) I added a few macros for easier writing of unit tests, btw. There is assert-values, which takes instance-value pairs and with-assert-observers, which checks whether all and only the specified observers run. > The above might be easily done (just a tweak or two) by looking at how > synapses work. They are like local and/or anonymous Cells. "Anonymous" > because they do not mediate a slot, they mediate an arbitrary sub-form of a > rule. "Local" because only the Cell envalued by the containing form depends > on the synaptic Cell. Ooops, I should read ahead. Haven't looked at synapses. Well, next time. ;-) > Historical note: synapses used to be a completely different data structure > with distinct code supporting them, now we just have a "synaptic" attribute > to guide the general Cells logic in a few places. > > Anyway, then c?-with-stored is just the special case where this appears as > the entire form: > > (c? (bwhen-c-gethash (...) ...)) Yep, I'm with you. Just reimplemnented c?-with-stored in terms of bwhen-gethash. > Hmmm, you know, I almost never use synapses and yet I have always suspected > that a lot of fun would be had with them in re expanding the semantics one > could express with Cells. But this exchange has me wondering if I missed > something: will new kinds of Cells tend to be synapses because the semantics > will be useful within rules? Ok, now you lost me. I'll have to look at synapses before I can tell. For now, I need to go back to my actual work and put the new store to work. > Or maybe I am just confused: should all cells be synapses now? I might be > in the land of distinctions without differences now. :) So I guess you are well prepared for Amsterdam :) > Well, I am off to Amsterdam shortly and will play with this when I get > back. Not sure how much time I will be on-line, btw, until Monday. Ok, have fun over here in old Europe :) > Thanks for a cool contrib. You're welcome. Thanks for a cool library :) Cheers, Peter From kennytilton at optonline.net Thu Apr 17 17:55:28 2008 From: kennytilton at optonline.net (Kenny Tilton) Date: Thu, 17 Apr 2008 13:55:28 -0400 Subject: [cells-devel] Added cells-store to cells In-Reply-To: <7758b2680804170856s19aef71cq3cf9728dcc666ac7@mail.gmail.com> References: <7758b2680804170652r6980d181ideacb454723eaf42@mail.gmail.com> <48076429.3030201@optonline.net> <7758b2680804170856s19aef71cq3cf9728dcc666ac7@mail.gmail.com> Message-ID: <48078F10.8000505@optonline.net> Peter Hildebrandt wrote: > Ken, > > thanks for the quick response. I'll try to illuminate things a bit. > >> Cool. I am curious what application requirement led to this. > > I've been looking for a while for a way to store a (possibly large) > number of model objects in a way that makes it easy and fast both to > iterate over them and to access individual ones. In principle this > can all be done with the fm-utilities, e.g. kids and fm-other. > However, when things get big, I feel bad constantly traversing trees > with fm-other and keeping tons of instances in the kids slot. Understood. I have been thinking along the same lines lately, but I generally wait until I have a use case because (a) I am lazy and (b) I think without an actual use case one puts in too many bells and whistles or guesses wrong at what is needed and how it should work or all of the above. Sounds like you have a Real Application to do. A nice extension, btw, would be an option for JIT creation should the thing not yet exist, but I gather you have Actual Work(tm) to do. When it comes up. I guess you would want the lookup then to be the key plus the argument list for make-instance. btw, one of the things I sometimes think to point out is that Cells merely benefits (albeit greatly) from being used within a namespace of other objects to depend on, and even more when that namespace has Cells Inside(tm). I probably did Family only because I started with a GUI hierarchy, tho on second thought the tree is generally a powerful data structure. All just a long way of saying "good idea". :) > > There are three reasons I was looking for an alternative: > - My current research app models some type of human learning, which > involves huge numbers of interlinked nodes in a network. I was > looking for a data structure which has O(1) access. > - fm-other traverses the tree at initialization time looking for the > target. I was looking for a way to reference instances to be created > in the future. (For example, this is interesting when loading a > network from file - either you have an acyclic graph and save it in a > topological order, or you need some way to forward reference > to-be-loaded nodes) > - I am afraid (correct me if this is wrong) that ruled cells using > fm-other are calculated more often than necessary -- e.g. you have a > cell depending on (fm-other :something). Then every time a new kids > is added somewhere in the tree, this rule should be run to check > whether there is a :something now somewhere. My cells-store hash > table makes sure that only those rules are run that are actually > necessary. The /potential/ for kicking off kids rules too often is there, but generally when rules are written sensibly the dependency on :something's existence ends up in the rule for an attribute, not in the rule that would make kids elsewhere get recalculated. In a sense we have the typical proble with Lisp: one false step and you can just hose your application. But as with Lisp, one quickly develops an instinct for things that are slow by mistake. > > The immediate reason is that when debugging some cells-gtk stuff, I > was confronted with a thick knot of fm-other initiated tree > traversals, and I wished I had something more linear and predictable. Understood. > So I tried to use simple hash table look ups, but that did not work > since the cells did not learn when new items were added to the table > (i.e. forward references broke). Thus I needed a cells-aware hash > table. And now I'll use that in my app and in cells-ode, too. > >> Not that it is >> not a good idea. Being able to reach inside other structures for dependency >> is a natural fleshing-out of Cells -- why stop at the slot, or force >> everything to /be/ a slot to depend on it? > > Yep, there might be other cases -- even though I can't think of > anything besides a hash table where I ever missed cells-awareness. > >> Meta-cool is that you are the first Cells user to do something like this, >> IIRC, altho there are several who took the more typical Lisper approach of >> dashing off to do their own versions of the entire package. :) > > Thanks, I take it as a compliment. > >>> The (c?-with-stored (var key store &optional default) &body body) >>> >> I have not looked at the code so maybe what I am about to suggest is >> already possible, but would this also be useful (just to confuse things I >> changed with-stored to bwhen-c-gethash: >> >> (c? (if (^whatever) >> 42 >> (bwhen-c-gethash (user login-id *user-logins*) >> .....))) > > Funny you picked that name. At first, I called it c?-bwhen-hash. > Then I figured that with fit the semantics better. Maybe I was right > the first time, tho. > > As to you point, no, this is not possible right now since > c?-with-stored expands into (c? ...). This is not necessary, though, > because all my macro does is establish a dependency on an intermediate > object which gets modified if the corresponding hash table entry is > manipulated (i.e. an object added/removed). So indeed we could have > this (w/o the c? part) as a standalone macro. > > I changed it in CVS. The following works now, too: > > (make-instance 'test-store-item :value (c? (if (value bypass-lookup?) > 'no-lookup > (bwhen-gethash (v :bar store 'nothing) > (value v))))) > > I included it in the test func at the bottom of md-utilities. If you > feel like it, you can integrate it with the test suite. (You're the > maintainer, after all *g*) One of my blog articles details my enthusiasm for testing. :) > > I added a few macros for easier writing of unit tests, btw. There is > assert-values, which takes instance-value pairs and > with-assert-observers, which checks whether all and only the specified > observers run. > >> The above might be easily done (just a tweak or two) by looking at how >> synapses work. They are like local and/or anonymous Cells. "Anonymous" >> because they do not mediate a slot, they mediate an arbitrary sub-form of a >> rule. "Local" because only the Cell envalued by the containing form depends >> on the synaptic Cell. > > Ooops, I should read ahead. Haven't looked at synapses. Well, next time. ;-) > >> Historical note: synapses used to be a completely different data structure >> with distinct code supporting them, now we just have a "synaptic" attribute >> to guide the general Cells logic in a few places. >> >> Anyway, then c?-with-stored is just the special case where this appears as >> the entire form: >> >> (c? (bwhen-c-gethash (...) ...)) > > Yep, I'm with you. Just reimplemnented c?-with-stored in terms of > bwhen-gethash. I think you need a -c- in there because i can imagine a bwhen-gethash as pure CL, nothing cells-y. btw, using bwhen-store vs gethash might be a good idea (not expose implementation) but sometimes I like to do exactly that just to make code more approachable. This one is a coin-toss for me. > >> Hmmm, you know, I almost never use synapses and yet I have always suspected >> that a lot of fun would be had with them in re expanding the semantics one >> could express with Cells. But this exchange has me wondering if I missed >> something: will new kinds of Cells tend to be synapses because the semantics >> will be useful within rules? > > Ok, now you lost me. I'll have to look at synapses before I can tell. > For now, I need to go back to my actual work and put the new store to > work. > >> Or maybe I am just confused: should all cells be synapses now? I might be >> in the land of distinctions without differences now. :) > > So I guess you are well prepared for Amsterdam :) > >> Well, I am off to Amsterdam shortly and will play with this when I get >> back. Not sure how much time I will be on-line, btw, until Monday. > > Ok, have fun over here in old Europe :) > >> Thanks for a cool contrib. > > You're welcome. Thanks for a cool library :) > > Cheers, > Peter > > From kentilton at gmail.com Fri Apr 18 15:06:49 2008 From: kentilton at gmail.com (Ken Tilton) Date: Fri, 18 Apr 2008 11:06:49 -0400 Subject: [cells-devel] Optimized away/dying rules In-Reply-To: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> References: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> Message-ID: First, just a point of information: do I understand correctly that the original example below uses an assoc instead of your store just to simplify the problem and highlight the key issue? I am guessing yes, so I will charge ahead with my thoughts: basically you need to make the lookup itself establish a dependency. I had assumed that this what you had done when you said you had created a cells-aware store. I was guessing that behind the scenes there was a second hashtable with the same key but a value that was a list of the cells that had looked it up. (Or you could try stuffing the thing stored with a list of asking cells in the one hash-value.) That would have gotten you into c-link, c-unlink, and other good stuff. And then you are done. Everything (including sensible optimization) just flows from that. Sorry if I am all wet or if not for not examining your code earlier. I'd look now but jet lag beckons. I'll try later or just let me know if this is making sense. cheers, kenny ps. I did not stare too hard either at your deferred optimizarion or something idea because I saw this other more standard approach to the problem, but again if it turns out I missed something I'll stare at that too when I recover a little. k pps. Interesting idea: if things never go away you can lose the dependency of the seeker on the store once the sought key appears. Not sure how to express that, unless we tackle the not-to-be issue by doing something I have toyed with before (and might even still be out there): a rule that says when an instance dies. In the case where that is a hardcoded nil or a rule that produced nil and then got optimized away, the cells-store could drop the dependency from its side after propagating to the asker. k On Wed, Apr 16, 2008 at 11:26 AM, Peter Hildebrandt < peter.hildebrandt at gmail.com> wrote: > While working on the hash-table lookup for md-names (as an alternative > to fm-other) I came across an interesting phenomenon: Some rules die, > others don't. Following the XP idea for RFEs, I'll try to present a > test case: > > (defpackage :c-test (:use :cl :cells :utils-kt)) > (in-package :c-test) > > (defparameter *hash* (make-hash-table)) > (defun val (name) (bwhen (obj (gethash name *hash*)) > (value obj))) > > (defparameter *m1* (make-instance 'model :value (c? (bif (v (val > :foo)) (1+ v) 'nothing)))) > (assert (eql (value *m1*) 'nothing)) > > (setf (gethash :foo *hash*) (make-instance 'model :value (c-in nil))) > > (defparameter *m2* (make-instance 'model :value (c? (bif (v (val > :foo)) (1+ v) 'nothing)))) > > (assert (eql (value *m1*) 'nothing)) > (assert (eql (value *m2*) 'nothing)) > > (setf (value (gethash :foo *hash*)) 42) > (assert (eql (value *m1*) 43)) ;;; #### FAILS #### > (assert (eql (value *m2*) 43)) ;;; ok > > (setf (value (gethash :foo *hash*)) 17) > (assert (eql (value *m1*) 18)) ;;; #### FAILS #### > (assert (eql (value *m2*) 18)) ;;; ok > > ;;; or with a list > > (defparameter *list* nil) > (defun valb (name) (bwhen (obj (assocd name *list*)) > (value obj))) > (defparameter *m1b* (make-instance 'model :value (c? (bif (v (valb > :foo)) (1+ v) 'nothing)))) > > (assert (eql (value *m1b*) 'nothing)) > > (push (cons :foo (make-instance 'model :value (c-in nil))) *list*) > > (defparameter *m2b* (make-instance 'model :value (c? (bif (v (valb > :foo)) (1+ v) 'nothing)))) > > (assert (eql (value *m1b*) 'nothing)) > (assert (eql (value *m2b*) 'nothing)) > > (setf (value (assocd :foo *list*)) 17) > (assert (eql (value *m1b*) 18)) ;;; #### FAILS #### > (assert (eql (value *m2b*) 18)) ;;; ok > > (setf (value (assocd :foo *list*)) 42) > (assert (eql (value *m1b*) 43)) ;;; #### FAILS #### > (assert (eql (value *m2b*) 43)) ;;; ok > > -------- > > An interesting indicator might be that the first call to (value *m1*) > returns two values, 'nothing and nil -- does that mean that cells > somehow realizes there that this cell can be optimized out? > > And -- more importantly -- how can I tell cells not to optimize away > the ruled cell in *m1*/*m1b*? > > Thanks, > Peter > _______________________________________________ > cells-devel site list > cells-devel at common-lisp.net > http://common-lisp.net/mailman/listinfo/cells-devel > -------------- next part -------------- An HTML attachment was scrubbed... URL: From kentilton at gmail.com Sat Apr 19 00:02:57 2008 From: kentilton at gmail.com (Ken Tilton) Date: Sat, 19 Apr 2008 02:02:57 +0200 Subject: [cells-devel] [openair] web-app still :NASCENT after make-instance In-Reply-To: <33E5F2FB-270D-4722-B38F-F5AB2EBA7E4B@mac.com> References: <33E5F2FB-270D-4722-B38F-F5AB2EBA7E4B@mac.com> Message-ID: On Wed, Apr 16, 2008 at 9:24 PM, Frank Goenninger wrote: > Ok, so I am still trying to find out why the handler slot of the web app > is always NIL. > > That's what I get after creating the instance with make-instance: That should work. Back in the day we had to call to-be on a new instance, but integrity-handling managed to eliminate that (or I just got smarter). What happens is that even with an apparent raw make-instance there is a check (in the shared-initialize method on model-object) to see if integrity is being managed and if not the old to-be handling gets invoked. If it isbeing managed md-awaken gets kicked off by the handling of "owned" slots (formerly special-case handled for the kids slot). What can stop this from happening is testing without calling cells-reset after a crash during which the *stop* (*c-stop*?) special gets set to t. Assuming that is not the case, all you can do is cut=paste the shared-init to make a custom copy specialized on web-app and add a kazillion print statements. In desperation, bounce your Lisp and start afresh as a sanity check. We have been banging on Cells internals lately, maybe something is broken. kt -------------- next part -------------- An HTML attachment was scrubbed... URL: From peter.hildebrandt at gmail.com Sat Apr 19 10:36:55 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Sat, 19 Apr 2008 12:36:55 +0200 Subject: [cells-devel] Optimized away/dying rules In-Reply-To: References: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> Message-ID: <7758b2680804190336q32ef982bye54875f6a3f91d47@mail.gmail.com> Ken, thanks again for the info. I guess some stuff got out of order here: > First, just a point of information: do I understand correctly that the > original example below uses an assoc instead of your store just to simplify > the problem and highlight the key issue? Yes and no. Yes, the list stuff was my attempt of singling out what was going on. But! -- I wrote the stuff *before* I understood the issue; in other words, this is how I tried (!) to do it before I made the cells store. > I am guessing yes, so I will charge ahead with my thoughts: basically you > need to make the lookup itself establish a dependency. I had assumed that > this what you had done when you said you had created a cells-aware store. And you were assuming right -- That is, I hope what I did is what you mean. Indeed bwen-(c-)gethash (which I will rename to bwhen-in-c-store or sth like that) expands into some code that creates a dependency on a listener object in the store, which then in turn is kicked when the hash table is updated. > I > was guessing that behind the scenes there was a second hashtable with the > same key but a value that was a list of the cells that had looked it up. (Or > you could try stuffing the thing stored with a list of asking cells in the > one hash-value.) Indeed there are two hash tables, one with the actual stored stuff and one with auxiliary objects that are uses to toggle the update. This way we have two hash table lookups for every access, so maybe it would make sense to keep the two in a cons in one table. But hold on, I hear "premature optimization". > That would have gotten you into c-link, c-unlink, and other > good stuff. Not sure whether we are on the same page. I have register-listener, kick-listener, and unregister-listener as internal methods on the store. I assume we're talking similar ideas here. I like your naming convention, tho. > And then you are done. Everything (including sensible optimization) just > flows from that. True. > Sorry if I am all wet or if not for not examining your code earlier. I'd > look now but jet lag beckons. I'll try later or just let me know if this is > making sense. Just for clarification: I assume you have not yet looked at the code in md-utilities, but were just going from what I had described here, right? I'lll put in a few changes based on what I ran into in test-gtk and on what you wrote here and commit later today. > ps. I did not stare too hard either at your deferred optimizarion or > something idea because I saw this other more standard approach to the > problem, but again if it turns out I missed something I'll stare at that too > when I recover a little. k Deferred optimization? Now you lost me. Not quite sure what you are referring too. > pps. Interesting idea: if things never go away you can lose the dependency > of the seeker on the store once the sought key appears. Not sure how to > express that, unless we tackle the not-to-be issue by doing something I have > toyed with before (and might even still be out there): a rule that says when > an instance dies. In the case where that is a hardcoded nil or a rule that > produced nil and then got optimized away, the cells-store could drop the > dependency from its side after propagating to the asker. k That is interesting indeed. I thought about that before, but I am not sure my scheme will provide for that, it might need some major change to what I do so far. OTOH, the good news is that my idea of listener or link cells reduces the overhead through this -- even if we have a dependency on the link, this does not matter as long as we don't touch the link. Just random thought, Peter > On Wed, Apr 16, 2008 at 11:26 AM, Peter Hildebrandt > wrote: > > > > > > > > While working on the hash-table lookup for md-names (as an alternative > > to fm-other) I came across an interesting phenomenon: Some rules die, > > others don't. Following the XP idea for RFEs, I'll try to present a > > test case: > > > > (defpackage :c-test (:use :cl :cells :utils-kt)) > > (in-package :c-test) > > > > (defparameter *hash* (make-hash-table)) > > (defun val (name) (bwhen (obj (gethash name *hash*)) > > (value obj))) > > > > (defparameter *m1* (make-instance 'model :value (c? (bif (v (val > > :foo)) (1+ v) 'nothing)))) > > (assert (eql (value *m1*) 'nothing)) > > > > (setf (gethash :foo *hash*) (make-instance 'model :value (c-in nil))) > > > > (defparameter *m2* (make-instance 'model :value (c? (bif (v (val > > :foo)) (1+ v) 'nothing)))) > > > > (assert (eql (value *m1*) 'nothing)) > > (assert (eql (value *m2*) 'nothing)) > > > > (setf (value (gethash :foo *hash*)) 42) > > (assert (eql (value *m1*) 43)) ;;; #### FAILS #### > > (assert (eql (value *m2*) 43)) ;;; ok > > > > (setf (value (gethash :foo *hash*)) 17) > > (assert (eql (value *m1*) 18)) ;;; #### FAILS #### > > (assert (eql (value *m2*) 18)) ;;; ok > > > > ;;; or with a list > > > > (defparameter *list* nil) > > (defun valb (name) (bwhen (obj (assocd name *list*)) > > (value obj))) > > (defparameter *m1b* (make-instance 'model :value (c? (bif (v (valb > > :foo)) (1+ v) 'nothing)))) > > > > (assert (eql (value *m1b*) 'nothing)) > > > > (push (cons :foo (make-instance 'model :value (c-in nil))) *list*) > > > > (defparameter *m2b* (make-instance 'model :value (c? (bif (v (valb > > :foo)) (1+ v) 'nothing)))) > > > > (assert (eql (value *m1b*) 'nothing)) > > (assert (eql (value *m2b*) 'nothing)) > > > > (setf (value (assocd :foo *list*)) 17) > > (assert (eql (value *m1b*) 18)) ;;; #### FAILS #### > > (assert (eql (value *m2b*) 18)) ;;; ok > > > > (setf (value (assocd :foo *list*)) 42) > > (assert (eql (value *m1b*) 43)) ;;; #### FAILS #### > > (assert (eql (value *m2b*) 43)) ;;; ok > > > > -------- > > > > An interesting indicator might be that the first call to (value *m1*) > > returns two values, 'nothing and nil -- does that mean that cells > > somehow realizes there that this cell can be optimized out? > > > > And -- more importantly -- how can I tell cells not to optimize away > > the ruled cell in *m1*/*m1b*? > > > > Thanks, > > Peter > > _______________________________________________ > > cells-devel site list > > cells-devel at common-lisp.net > > http://common-lisp.net/mailman/listinfo/cells-devel > > > > From peter.hildebrandt at gmail.com Mon Apr 21 08:12:04 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Mon, 21 Apr 2008 10:12:04 +0200 Subject: [cells-devel] not-to-be and owning slots Message-ID: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> I came across something, which seem odd to me: - If I remove an instance from a kids slot, not-to-be is called on that instance - If I remove an instance form any :owning t slot, not-to-be is called on that instance - If not-to-be is called on an instance, it is also called on all its kids BUT If not-to-be is called on an instance, it is NOT called on all instances its :owning t slots. Is this desired behavior, or dfid it get overlooked when owning was introduced? What is the recommended way to deal with it? - write a not-to-be method for my specific class which setfs the owned slots to nil to trigger not-to-be? - write a not-to-be method for my specific class which mapcs not-to-be over its owned slots? or - fix it in cells and change not-to-be there so it does not only recurse down kids, but all owned slots? Thanks for any advice, Peter From peter.hildebrandt at gmail.com Mon Apr 21 08:38:21 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Mon, 21 Apr 2008 10:38:21 +0200 Subject: [cells-devel] Re: not-to-be and owning slots In-Reply-To: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> Message-ID: <7758b2680804210138hc5206ecyb1efb69e40e3b55f@mail.gmail.com> On Mon, Apr 21, 2008 at 10:12 AM, Peter Hildebrandt wrote: > - fix it in cells and change not-to-be there so it does not only > recurse down kids, but all owned slots? As a proof of concept, I changed not-to-be to be (defmethod not-to-be :before ((fm family)) (loop for (slot . nil) in (get (type-of fm) :ownings) do (let ((owned (slot-value fm slot))) (when (listp owned) (mapc #'not-to-be owned))))) It used to be: (defmethod not-to-be :before ((fm family)) (let ((sv-kids (slot-value fm '.kids))) (when (listp sv-kids) (dolist ( kid sv-kids) (not-to-be kid)))) I haven't committed it yet, because I'd like to hear your opinion, especially on what this might break :-) Peter From peter.hildebrandt at gmail.com Mon Apr 21 08:54:38 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Mon, 21 Apr 2008 10:54:38 +0200 Subject: [cells-devel] Re: not-to-be and owning slots In-Reply-To: <7758b2680804210138hc5206ecyb1efb69e40e3b55f@mail.gmail.com> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> <7758b2680804210138hc5206ecyb1efb69e40e3b55f@mail.gmail.com> Message-ID: <7758b2680804210154p34e74478n5cc0be1b7b3c64a9@mail.gmail.com> On Mon, Apr 21, 2008 at 10:38 AM, Peter Hildebrandt wrote: > As a proof of concept, I changed not-to-be to be There's something weird going on, i.e. it is not called reliably on the kids slot. The follwoing works better: (defmethod not-to-be :before ((fm family)) (let ((sv-kids (slot-value fm '.kids))) (when (listp sv-kids) (dolist ( kid sv-kids) (not-to-be kid)))) (bwhen (ownings (get (type-of fm) :ownings) ) (loop for (slot . nil) in ownings do (unless (eql slot '.kids) (bwhen (owned (slot-value fm slot)) (if (listp owned) (mapc #'not-to-be owned) (not-to-be owned))))))) > It used to be: > > (defmethod not-to-be :before ((fm family)) > (let ((sv-kids (slot-value fm '.kids))) > (when (listp sv-kids) > (dolist ( kid sv-kids) > (not-to-be kid)))) > > I haven't committed it yet, because I'd like to hear your opinion, > especially on what this might break :-) > > Peter > From kennytilton at optonline.net Tue Apr 22 00:31:13 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Mon, 21 Apr 2008 20:31:13 -0400 Subject: [cells-devel] Optimized away/dying rules In-Reply-To: <7758b2680804190336q32ef982bye54875f6a3f91d47@mail.gmail.com> References: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> <7758b2680804190336q32ef982bye54875f6a3f91d47@mail.gmail.com> Message-ID: <480D31D1.9080103@optonline.net> Peter Hildebrandt wrote: > Ken, > > thanks again for the info. I guess some stuff got out of order here: > > >>First, just a point of information: do I understand correctly that the >>original example below uses an assoc instead of your store just to simplify >>the problem and highlight the key issue? > > > Yes and no. Yes, the list stuff was my attempt of singling out what > was going on. But! -- I wrote the stuff *before* I understood the > issue; in other words, this is how I tried (!) to do it before I made > the cells store. > > > >>I am guessing yes, so I will charge ahead with my thoughts: basically you >>need to make the lookup itself establish a dependency. I had assumed that >>this what you had done when you said you had created a cells-aware store. > > > And you were assuming right -- That is, I hope what I did is what you > mean. Indeed bwen-(c-)gethash (which I will rename to > bwhen-in-c-store or sth like that) expands into some code that creates > a dependency on a listener object in the store, which then in turn is > kicked when the hash table is updated. > > >>I >>was guessing that behind the scenes there was a second hashtable with the >>same key but a value that was a list of the cells that had looked it up. (Or >>you could try stuffing the thing stored with a list of asking cells in the >>one hash-value.) > > > Indeed there are two hash tables, one with the actual stored stuff and > one with auxiliary objects that are uses to toggle the update. This > way we have two hash table lookups for every access, so maybe it would > make sense to keep the two in a cons in one table. But hold on, I > hear "premature optimization". I was not thinking about efficiency, I was thinking about (possibly!) cleaner design less likely to be midcoded: I want to get all the information about this hash key as a single logically related chunk, not pull in the properties of the logical chunk one at a time from different hash tables per property. Then I can pass this chunk around to other functions as one parameter, for example. But that is beside the point. > > >>That would have gotten you into c-link, c-unlink, and other >>good stuff. > > > Not sure whether we are on the same page. I have register-listener, > kick-listener, and unregister-listener as internal methods on the > store. I assume we're talking similar ideas here. I like your naming > convention, tho. We might be on the same page talking different languages and that is the problem: cells get optimized away when they are "unlinked" to a dependency. You created dependency links in another language if you will and something got lost in translation (great movie). Can you re-implement such that the linking API Just Works(tm)? kt From kentilton at gmail.com Tue Apr 22 00:44:29 2008 From: kentilton at gmail.com (Ken Tilton) Date: Mon, 21 Apr 2008 20:44:29 -0400 Subject: [cells-devel] Optimized away/dying rules In-Reply-To: <480D31D1.9080103@optonline.net> References: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> <7758b2680804190336q32ef982bye54875f6a3f91d47@mail.gmail.com> <480D31D1.9080103@optonline.net> Message-ID: That was fuzzy. Clarifications below... On Mon, Apr 21, 2008 at 8:31 PM, Ken Tilton wrote: > Peter Hildebrandt wrote: > > > Ken, > > > > thanks again for the info. I guess some stuff got out of order here: > > > > > > First, just a point of information: do I understand correctly that the > > > original example below uses an assoc instead of your store just to > > > simplify > > > the problem and highlight the key issue? > > > > > > > > > Yes and no. Yes, the list stuff was my attempt of singling out what > > was going on. But! -- I wrote the stuff *before* I understood the > > issue; in other words, this is how I tried (!) to do it before I made > > the cells store. > > > > > > > > I am guessing yes, so I will charge ahead with my thoughts: basically > > > you > > > need to make the lookup itself establish a dependency. I had assumed > > > that > > > this what you had done when you said you had created a cells-aware > > > store. > > > > > > > > > And you were assuming right -- That is, I hope what I did is what you > > mean. Indeed bwen-(c-)gethash (which I will rename to > > bwhen-in-c-store or sth like that) expands into some code that creates > > a dependency on a listener object in the store, which then in turn is > > kicked when the hash table is updated. > > > > > > I > > > was guessing that behind the scenes there was a second hashtable with > > > the > > > same key but a value that was a list of the cells that had looked it > > > up. (Or > > > you could try stuffing the thing stored with a list of asking cells in > > > the > > > one hash-value.) > > > > > > > > > Indeed there are two hash tables, one with the actual stored stuff and > > one with auxiliary objects that are uses to toggle the update. This > > way we have two hash table lookups for every access, so maybe it would > > make sense to keep the two in a cons in one table. But hold on, I > > hear "premature optimization". > > > > I was not thinking about efficiency, I was thinking about (possibly!) > cleaner design less likely to be midcoded: I want to get all the information > about this hash key as a single logically related chunk, not pull in the > properties of the logical chunk one at a time from different hash tables per > property. Then I can pass this chunk around to other functions as one > parameter, for example. But that is beside the point. > > > > > > That would have gotten you into c-link, c-unlink, and other > > > good stuff. > > > > > > > > > Not sure whether we are on the same page. I have register-listener, > > kick-listener, and unregister-listener as internal methods on the > > store. I assume we're talking similar ideas here. I like your naming > > convention, tho. > > > > We might be on the same page talking different languages and that is > the problem: cells get optimized away when they are "unlinked" to a > dependency. You created dependency links in another language if you will and > something got lost in translation (great movie). The "other language" was that of "registered listener", which of course c-optimize-way knows not about. > > > Can you re-implement such that the linking API Just Works(tm)? Here I left unstated my preference for re-engineering around link/unlink and the alternative of telling c-optimize-away about an alternative way of encoding inter-cell dependency. That preference will change rapidly if there is some way c-link/unlink will not work for a hashtable-based namespace. kt -------------- next part -------------- An HTML attachment was scrubbed... URL: From kentilton at gmail.com Tue Apr 22 00:46:13 2008 From: kentilton at gmail.com (Ken Tilton) Date: Mon, 21 Apr 2008 20:46:13 -0400 Subject: [cells-devel] Optimized away/dying rules In-Reply-To: References: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> <7758b2680804190336q32ef982bye54875f6a3f91d47@mail.gmail.com> <480D31D1.9080103@optonline.net> Message-ID: Oh christ.... On Mon, Apr 21, 2008 at 8:44 PM, Ken Tilton wrote: > That was fuzzy. Clarifications below... > > On Mon, Apr 21, 2008 at 8:31 PM, Ken Tilton > wrote: > > > Peter Hildebrandt wrote: > > > > > Ken, > > > > > > thanks again for the info. I guess some stuff got out of order here: > > > > > > > > > First, just a point of information: do I understand correctly that > > > > the > > > > original example below uses an assoc instead of your store just to > > > > simplify > > > > the problem and highlight the key issue? > > > > > > > > > > > > > Yes and no. Yes, the list stuff was my attempt of singling out what > > > was going on. But! -- I wrote the stuff *before* I understood the > > > issue; in other words, this is how I tried (!) to do it before I made > > > the cells store. > > > > > > > > > > > > I am guessing yes, so I will charge ahead with my thoughts: basically > > > > you > > > > need to make the lookup itself establish a dependency. I had assumed > > > > that > > > > this what you had done when you said you had created a cells-aware > > > > store. > > > > > > > > > > > > > And you were assuming right -- That is, I hope what I did is what you > > > mean. Indeed bwen-(c-)gethash (which I will rename to > > > bwhen-in-c-store or sth like that) expands into some code that creates > > > a dependency on a listener object in the store, which then in turn is > > > kicked when the hash table is updated. > > > > > > > > > I > > > > was guessing that behind the scenes there was a second hashtable > > > > with the > > > > same key but a value that was a list of the cells that had looked it > > > > up. (Or > > > > you could try stuffing the thing stored with a list of asking cells > > > > in the > > > > one hash-value.) > > > > > > > > > > > > > Indeed there are two hash tables, one with the actual stored stuff and > > > one with auxiliary objects that are uses to toggle the update. This > > > way we have two hash table lookups for every access, so maybe it would > > > make sense to keep the two in a cons in one table. But hold on, I > > > hear "premature optimization". > > > > > > > I was not thinking about efficiency, I was thinking about (possibly!) > > cleaner design less likely to be midcoded: I want to get all the information > > about this hash key as a single logically related chunk, not pull in the > > properties of the logical chunk one at a time from different hash tables per > > property. Then I can pass this chunk around to other functions as one > > parameter, for example. But that is beside the point. > > > > > > > > > > That would have gotten you into c-link, c-unlink, and other > > > > good stuff. > > > > > > > > > > > > > Not sure whether we are on the same page. I have register-listener, > > > kick-listener, and unregister-listener as internal methods on the > > > store. I assume we're talking similar ideas here. I like your naming > > > convention, tho. > > > > > > > We might be on the same page talking different languages and that is > > the problem: cells get optimized away when they are "unlinked" to a > > dependency. You created dependency links in another language if you will and > > something got lost in translation (great movie). > > > The "other language" was that of "registered listener", which of course > c-optimize-way knows not about. > > > > > > > > Can you re-implement such that the linking API Just Works(tm)? > > > Here I left unstated my preference for re-engineering around link/unlink > and the alternative of telling c-optimize- > /over/ the alternative!!!!!!!!!!!!!!!!!! :) kt > away about an alternative way of encoding inter-cell dependency. That > preference will change rapidly if there is some way c-link/unlink will not > work for a hashtable-based namespace. > > kt > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From peter.hildebrandt at gmail.com Tue Apr 22 08:49:52 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Tue, 22 Apr 2008 10:49:52 +0200 Subject: [cells-devel] not-to-be and owning slots In-Reply-To: <480D3276.6090801@optonline.net> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> <480D3276.6090801@optonline.net> Message-ID: <7758b2680804220149s546bc57fn17c2f3ad1c460dbe@mail.gmail.com> On Tue, Apr 22, 2008 at 2:33 AM, Ken Tilton wrote: > Later on I saw you reporting something weird about .kids not getting > reliably handled. I' d like to run down the "weird" rather than just throw > in parallel code to make .kids work. After I commit lemme know when the > weirdness returns. Sounds good. I wasn't sure as to whether I understood what I was doing. I just saw that not-to-be did not propagate to kids *at all* if I did it the way I suggested. Hold on, one idea: Maybe the problem is with (get (type-of fm) :ownings), i.e. this only picks up the owning defined on the actual class of fm, not the inherited ones? To be honest, I am just doing wild guesswork here, so I better shut up :-) Hope you guys had a good time in Amsterdam. Hopefully next year I will actually make it :-) Cheers, Peter From peter.hildebrandt at gmail.com Tue Apr 22 08:55:18 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Tue, 22 Apr 2008 10:55:18 +0200 Subject: [cells-devel] Optimized away/dying rules In-Reply-To: <480D31D1.9080103@optonline.net> References: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> <7758b2680804190336q32ef982bye54875f6a3f91d47@mail.gmail.com> <480D31D1.9080103@optonline.net> Message-ID: <7758b2680804220155s621ba397tb95c0bcd225e7d40@mail.gmail.com> On Tue, Apr 22, 2008 at 2:31 AM, Ken Tilton wrote: > I was not thinking about efficiency, I was thinking about (possibly!) > cleaner design less likely to be midcoded: I want to get all the information > about this hash key as a single logically related chunk, not pull in the > properties of the logical chunk one at a time from different hash tables per > property. Then I can pass this chunk around to other functions as one > parameter, for example. But that is beside the point. I came to understand that before I even read your mail -- and committed the change yesterday already. Now we're having a cons of the link and the stored data in the hash table and a bunch of accessor/setf functions which do the right thing. I'll respond to the other points in a second. Peter From peter.hildebrandt at gmail.com Tue Apr 22 09:12:19 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Tue, 22 Apr 2008 11:12:19 +0200 Subject: [cells-devel] Optimized away/dying rules In-Reply-To: <480D31D1.9080103@optonline.net> References: <7758b2680804160826w70fa4bcdp4601495dfc880fde@mail.gmail.com> <7758b2680804190336q32ef982bye54875f6a3f91d47@mail.gmail.com> <480D31D1.9080103@optonline.net> Message-ID: <7758b2680804220212j68c3abcai884fb3fc04ab9ef4@mail.gmail.com> On Tue, Apr 22, 2008 at 2:31 AM, Ken Tilton wrote: > We might be on the same page talking different languages and that is > the problem: cells get optimized away when they are "unlinked" to a > dependency. You created dependency links in another language if you will and > something got lost in translation (great movie). > > Can you re-implement such that the linking API Just Works(tm)? Now I see what you mean (and what I was afraid of when I wrote "not on the same page") -- I had a dim feeling that there must be some sort of linking mechanism in cells already, and that I was pretty much duplicating existing machinery. But my approach worked so nicely (and was so easy to code) that I did not want to bother learning too much about cells internals. Oh well, I have lots of Real Work to do this week (gotta move along with my thesis writing. Now that I have a job waiting for me in July, I better make sure I'm done by then) -- but I'll try and see whether I can figure out how it *should* work. Then, of course, this leads us to different kinds of links - "c_when": Link if there is something in the store associated with :key at the time the cell is evaluated. If the linked object is removed from the store, the link dies. If not, just die silently. - "c_1": Like c_when, but if there is nothing stored, wait until the slot is filled the first time, then establish the link. - "c?": Like c_1, but if the linked object is removed, revert to default,and wait until the slot is filled the next time. c_1 would be what is needed in GUI stuff -- i.e. we wish to forward reference another GUI element and link when it is instantiatied, but we don't really need to do anything when the whole GUI is discarded. Well, hopefully writing goes well the next couple days and I'll have some time to play with this. Cheers, Peter From kennytilton at optonline.net Tue Apr 22 09:15:07 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Tue, 22 Apr 2008 05:15:07 -0400 Subject: [cells-devel] not-to-be and owning slots In-Reply-To: <7758b2680804220149s546bc57fn17c2f3ad1c460dbe@mail.gmail.com> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> <480D3276.6090801@optonline.net> <7758b2680804220149s546bc57fn17c2f3ad1c460dbe@mail.gmail.com> Message-ID: <480DAC9B.3090406@optonline.net> Peter Hildebrandt wrote: > On Tue, Apr 22, 2008 at 2:33 AM, Ken Tilton wrote: > > >> Later on I saw you reporting something weird about .kids not getting >>reliably handled. I' d like to run down the "weird" rather than just throw >>in parallel code to make .kids work. After I commit lemme know when the >>weirdness returns. > > > Sounds good. I wasn't sure as to whether I understood what I was > doing. I just saw that not-to-be did not propagate to kids *at all* > if I did it the way I suggested. OK. > > Hold on, one idea: Maybe the problem is with > > (get (type-of fm) :ownings), i.e. this only picks up the owning > defined on the actual class of fm, not the inherited ones? > > To be honest, I am just doing wild guesswork here, so I better shut up :-) No, you are hot on the trail. I have code which tries to propagate the :owning declaration up and down the class hierarchy, so I wager there is a bug in there. And having revisited this, I find myself not liking the idea of propagating a slot attribute that way, tho I guess propagating down is what other slot attributes do when a slot is reiterated but with some attributes not specified. I may ask the c.l.l yobbo language lawyers what they think. > > Hope you guys had a good time in Amsterdam. Hopefully next year I > will actually make it :-) Everything but the talk itself was a blast. It is so great hanging out with Lispers in large quantities. As for the talk, I am tempted to set up my camcorder and do the talk again for YouTube. :( But based on post-talk reaction at least I was understood. A Lispworks guy wanted to talk about how hard it must be to debug the damn things. I said, No and yes, the yes being that I have always antancipated that as non-experts get involved better diagnostics/debug/trace tools would be needed. I'll be revising the not-to-be thing and look at why kids did not get handled -- good to have a smoking gun to debug. Oh, wait -- what was the class? My guess is one that reiterated the kids slot instead of just supplying a default initarg. kt From peter.hildebrandt at gmail.com Tue Apr 22 09:33:29 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Tue, 22 Apr 2008 11:33:29 +0200 Subject: [cells-devel] not-to-be and owning slots In-Reply-To: <480DAC9B.3090406@optonline.net> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> <480D3276.6090801@optonline.net> <7758b2680804220149s546bc57fn17c2f3ad1c460dbe@mail.gmail.com> <480DAC9B.3090406@optonline.net> Message-ID: <7758b2680804220233s3f471506ld0e8dfa7de344000@mail.gmail.com> > > Sounds good. I wasn't sure as to whether I understood what I was > > doing. I just saw that not-to-be did not propagate to kids *at all* > > if I did it the way I suggested. > > OK. That was with test-gtk -- my favorite test case. Upon a not-to-be on test-gtk nothing gets propagated. the class hierarchy is test-gtk->gtk-app->window->container->widget->gtk-object->family. But, no, there is no kids slot redefined anywhere. > > Hold on, one idea: Maybe the problem is with > > > > (get (type-of fm) :ownings), i.e. this only picks up the owning > > defined on the actual class of fm, not the inherited ones? > > > > To be honest, I am just doing wild guesswork here, so I better shut up :-) > > > > No, you are hot on the trail. I have code which tries to propagate the > :owning declaration up and down the class hierarchy, so I wager there is a > bug in there. And having revisited this, I find myself not liking the idea > of propagating a slot attribute that way, tho I guess propagating down is > what other slot attributes do when a slot is reiterated but with some > attributes not specified. I may ask the c.l.l yobbo language lawyers what > they think. Sounds like the sensible thing to do (for I have no idea what is the right way to do this. Traversing the whole hierarchy every time a not-to-be is called in order to collect the list of slots seems wrong ;-)) > > Hope you guys had a good time in Amsterdam. Hopefully next year I > > will actually make it :-) > > > > Everything but the talk itself was a blast. It is so great hanging out with > Lispers in large quantities. As for the talk, I am tempted to set up my > camcorder and do the talk again for YouTube. That'd be great :-) > :( But based on post-talk > reaction at least I was understood. A Lispworks guy wanted to talk about how > hard it must be to debug the damn things. I said, No and yes, the yes being > that I have always antancipated that as non-experts get involved better > diagnostics/debug/trace tools would be needed. Agreed. It took me a while to make sense of the cells heavy backtraces I get if I make a silly mistake in a cells rule. OTOH, trc/wtrc do a good job for me (I learned programming ona Commodore 64, so I don't mind print statements as my prime debugging tool. I still maintain that a sensible number of print statements is often a better debugging tool than all the stuff the IDE has to offer -- that is, my emacs/slime/sbcl yobbo IDE ;)) > I'll be revising the not-to-be thing and look at why kids did not get > handled -- good to have a smoking gun to debug. Oh, wait -- what was the > class? My guess is one that reiterated the kids slot instead of just > supplying a default initarg. As I said before, I did not see anything like that between family and test-gtk. Hmmm. I'll try and single out a test case. Thanks, Peter From kennytilton at optonline.net Tue Apr 22 11:17:07 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Tue, 22 Apr 2008 07:17:07 -0400 Subject: [cells-devel] not-to-be and owning slots In-Reply-To: <7758b2680804220233s3f471506ld0e8dfa7de344000@mail.gmail.com> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> <480D3276.6090801@optonline.net> <7758b2680804220149s546bc57fn17c2f3ad1c460dbe@mail.gmail.com> <480DAC9B.3090406@optonline.net> <7758b2680804220233s3f471506ld0e8dfa7de344000@mail.gmail.com> Message-ID: <480DC933.70003@optonline.net> Peter Hildebrandt wrote: >>>Sounds good. I wasn't sure as to whether I understood what I was >>>doing. I just saw that not-to-be did not propagate to kids *at all* >>>if I did it the way I suggested. >> >> OK. > > > That was with test-gtk -- my favorite test case. I hacked up not-to-be a little (tho nothing fundamentally different than what I recall of your efforts which I cannot find in my email), moved cells-store out into its own source file (update your asd!), reran the cells regression test and test-gtk -- everything works. Mind you there may not be a non-.kids owning test anywhere in there, or even anything that verifies that the .kids are getting quiesced, but your report above of "I just saw that not-to-be did not propagate to kids *at all*" does not say /how/ you saw that, so maybe there is still non-propagation which is not being exposed by the test suite and still needs to be cured. kt From peter.hildebrandt at gmail.com Tue Apr 22 11:41:28 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Tue, 22 Apr 2008 13:41:28 +0200 Subject: [cells-devel] not-to-be and owning slots In-Reply-To: <480DC933.70003@optonline.net> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> <480D3276.6090801@optonline.net> <7758b2680804220149s546bc57fn17c2f3ad1c460dbe@mail.gmail.com> <480DAC9B.3090406@optonline.net> <7758b2680804220233s3f471506ld0e8dfa7de344000@mail.gmail.com> <480DC933.70003@optonline.net> Message-ID: <7758b2680804220441n56bb86b0qf3de515d3b6beca3@mail.gmail.com> On Tue, Apr 22, 2008 at 1:17 PM, Ken Tilton wrote: > Peter Hildebrandt wrote: > > > > > > > > > > Sounds good. I wasn't sure as to whether I understood what I was > > > > doing. I just saw that not-to-be did not propagate to kids *at all* > > > > if I did it the way I suggested. > > > > > > > > > > OK. > > > > > > > > > That was with test-gtk -- my favorite test case. > > > > I hacked up not-to-be a little (tho nothing fundamentally different than > what I recall of your efforts which I cannot find in my email), moved > cells-store out into its own source file (update your asd!), reran the cells > regression test and test-gtk -- everything works. Hmmm -- I don't see the new source file anywhere. What's its name? Did you add it to CVS before you did the commit? Btw, I've updated the cells-gtk3 stuff every now and then -- did you update from CVS recently? I added a bunch of trcs to see what gets quiesced when. > Mind you there may not be a non-.kids owning test anywhere in there, or > even anything that verifies that the .kids are getting quiesced, but your > report above of "I just saw that not-to-be did not propagate to kids *at > all*" does not say /how/ you saw that, so maybe there is still > non-propagation which is not being exposed by the test suite and still needs > to be cured. I'd like to provide test cases. Where would be a good place to put them? Then I'd seize the opportunity and merge in my with-assert-observers macrology somewhere :) That would also prove useful to check what gets not-to-be'd. Thanks, Peter From kennytilton at optonline.net Tue Apr 22 23:45:54 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Tue, 22 Apr 2008 19:45:54 -0400 Subject: [cells-devel] not-to-be and owning slots In-Reply-To: <480DC933.70003@optonline.net> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> <480D3276.6090801@optonline.net> <7758b2680804220149s546bc57fn17c2f3ad1c460dbe@mail.gmail.com> <480DAC9B.3090406@optonline.net> <7758b2680804220233s3f471506ld0e8dfa7de344000@mail.gmail.com> <480DC933.70003@optonline.net> Message-ID: <480E78B2.2040002@optonline.net> Ken Tilton wrote: > Peter Hildebrandt wrote: > >>>> Sounds good. I wasn't sure as to whether I understood what I was >>>> doing. I just saw that not-to-be did not propagate to kids *at all* >>>> if I did it the way I suggested. >>> >>> >>> OK. >> >> >> >> That was with test-gtk -- my favorite test case. > > > I hacked up not-to-be a little (tho nothing fundamentally different than > what I recall of your efforts which I cannot find in my email), moved > cells-store out into its own source file (update your asd!), reran the > cells regression test and test-gtk -- everything works. > > Mind you there may not be a non-.kids owning test anywhere in there, or > even anything that verifies that the .kids are getting quiesced, but > your report above of "I just saw that not-to-be did not propagate to > kids *at all*" does not say /how/ you saw that, so maybe there is still > non-propagation which is not being exposed by the test suite and still > needs to be cured. yep. I think I am seeing it myself. stay tuned. this is probably, btw, something about load-time vs compile-time, with me propagating :ownings at compile-time and not getting those on a reload... nope, just a total mess from the beginning, hairy rewrite underway. kt From kennytilton at optonline.net Wed Apr 23 04:04:20 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Wed, 23 Apr 2008 00:04:20 -0400 Subject: [cells-devel] not-to-be fix, better diagnostics Message-ID: <480EB544.2020701@optonline.net> Thx to Peter for noticing not-to-be was not propagating to "owned" stuff --that seems to be working better now, but we'll keep a watch on that. Along the way I added a helpful debugging tool. If one specifies :cells-debug t ...to cells-reset the integrity dataflow propagation records what it does and then in the event of a backtrace prints it all out before doing a describe on the error condition. One can also specify a function as the :cells-debug value. Here is the one I used to debug a problem today: (a1-reset :cells-debug (lambda (c is) (loop for (id . info) in is unless (find id '(:ephemeral-reset :awaken)) do (format t "~&a1> ~(~a > ~a~) " id info) finally (describe c) (break "integ backtrace: see listener for deets")))) The info is just whatever gets supplied as the "defer-info" when something gets queued up for integrity handling, ie, the second parameter to the with-integrity macro. kt From peter.hildebrandt at gmail.com Wed Apr 23 06:08:10 2008 From: peter.hildebrandt at gmail.com (Peter Hildebrandt) Date: Wed, 23 Apr 2008 08:08:10 +0200 Subject: [cells-devel] not-to-be and owning slots In-Reply-To: <480E78B2.2040002@optonline.net> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> <480D3276.6090801@optonline.net> <7758b2680804220149s546bc57fn17c2f3ad1c460dbe@mail.gmail.com> <480DAC9B.3090406@optonline.net> <7758b2680804220233s3f471506ld0e8dfa7de344000@mail.gmail.com> <480DC933.70003@optonline.net> <480E78B2.2040002@optonline.net> Message-ID: <7758b2680804222308y73bab339k198b6e7e4a8b25d6@mail.gmail.com> On Wed, Apr 23, 2008 at 1:45 AM, Ken Tilton wrote: > yep. I think I am seeing it myself. stay tuned. > > this is probably, btw, something about load-time vs compile-time, with me > propagating :ownings at compile-time and not getting those on a reload... > nope, just a total mess from the beginning, hairy rewrite underway. Great, thanks! Btw, I updated the .asd and committed that to CVS. Will work on the test for not-to-be soon. Peter From kennytilton at optonline.net Wed Apr 23 08:27:44 2008 From: kennytilton at optonline.net (Ken Tilton) Date: Wed, 23 Apr 2008 04:27:44 -0400 Subject: [cells-devel] not-to-be and owning slots In-Reply-To: <7758b2680804222308y73bab339k198b6e7e4a8b25d6@mail.gmail.com> References: <7758b2680804210112l6f960390l1982b507382e0c34@mail.gmail.com> <480D3276.6090801@optonline.net> <7758b2680804220149s546bc57fn17c2f3ad1c460dbe@mail.gmail.com> <480DAC9B.3090406@optonline.net> <7758b2680804220233s3f471506ld0e8dfa7de344000@mail.gmail.com> <480DC933.70003@optonline.net> <480E78B2.2040002@optonline.net> <7758b2680804222308y73bab339k198b6e7e4a8b25d6@mail.gmail.com> Message-ID: <480EF300.6060702@optonline.net> Peter Hildebrandt wrote: > On Wed, Apr 23, 2008 at 1:45 AM, Ken Tilton wrote: > >> yep. I think I am seeing it myself. stay tuned. >> >> this is probably, btw, something about load-time vs compile-time, with me >>propagating :ownings at compile-time and not getting those on a reload... >>nope, just a total mess from the beginning, hairy rewrite underway. > > > Great, thanks! Btw, I updated the .asd and committed that to CVS. > Will work on the test for not-to-be soon. Great. The good news is that I accidentally started with a test case: I was having yet another one of those errors I may have mentioned when a math problem step holds the keyboard focus and I delete the problem. I ended up tracing not-to-be and noticed what you had just reported (small world) about not-to-be so took a break to fix that. Focus problem went away. :) kt From sspxbyv at common-lisp.net Fri Apr 25 10:46:02 2008 From: sspxbyv at common-lisp.net (Noreen) Date: Fri, 25 Apr 2008 11:46:02 +0100 Subject: [cells-devel] penetrate deeper Message-ID: <4811A85A.3040303@common-lisp.net> GAIN YOUR PENIS 2 INCH - SIMPLE AS NEVER. NATURAL HERBAL PRODUCT 100% SATISFACTION GUARANTEE! http://babbuyae.com