TODO * document what works and what doesn't * document all those functions, classes, etc., that do work. * export all the symbols correctly. * import trie from pangram thingie * DECLAIM - distributed execution of common-lisp agents with intent and mobility * move stateful datastructures to a stateful: package. Question: should I use separate interfaces as in the pure: package, or dispatch directly on objects as in usual OO style? * have generic state-passing updaters in the style of setf. (updatef (lookup i m k) v) ==> ((update-expander lookup) v i m k) ==> (insert i m k v) OK, but how does it compose??? should updatef "magically" recurse through all functions that have an updater defined? Fare: what do you mean? i.e. (updatef (car (cdr '(1 2 3)) 4) ==> (4 3) OR (1 4 3) oh Fare: no Fare: I would say yes. * drewc is on the fence * `3b votes 4 so (let ((x (cdr '(1 2 3)))) (updatef (car x) 4)) will give different results? * Fare wonders. `3b: your answer defeats the whole purpose of updatef! mm.. true. That is an issue. <`3b> Fare: yeah, that was sort of the intent :) (updatef (car (cdr '(1 2 3)) 4) => (4 3) seems mystifying * Fare obviously hadn't thunk it through before implementing <`3b> Fare: seems like it might be more useful as a binding form or something `3b: OK. gimme a syntax for it. binding? it's a monad <`3b> Fare: if i tried, i'd probably fall into some DSL pit trying to build the ability to do multiple changes at once :) drewc: what is your take (updatef (compose 'car 'cdr) '(1 2 3)) 4) ==> (1 4 3) ? (update (cadr '(1 2 3)) 4) ==> (1 4 3) :) Fare: i'm not sure really. magically composing things seems a little too magical to me so how am I to specify that I'm updating something deep? Fare: nested updatef. (update-accessor (x) (car (cdr x)) 1) ? meh. I think you really do want to update deeply, and even setq variables. (updatef (x #((a 1) (b 2) (c 3))) (car (aref x 1)) 'd) ? ==> #((a 1) (d 2)(c 3)) drewc: (update (car (aref (updating #((a b) (c d))) 2)) 'e) ==> #((a b) (c d) (e nil)) ? Fare: now, do you want to default to setq on variables? no, no setq - the whole point is that it should be pure * Fare wonders about abawden's quasiquote idea - then it would be (update `(car (cdr ,'(1 2 3))) 4) ==> (1 4 3) Fare: i kind of like the quasiquote idea easiest way to recurse: go through the first arg and if it's a known accessor, recurse. other way to recurse: find the (updating ) quasiquote-like, and there better be only one, and make that the thing to return updated. give a depth argument, recursing through the first arguments. I guess the way to decide is to rewrite a few imperative algorithms in functional style and see what works best... Fare: ime, for that, it's either allowing assignment to locals, or tail recursion everywhere. pkhuong_, so the updatef things would typically be as arguments to the tail call. right. or as something bound in a monad ... something like a local binding. the next thing would be writing a generic updatef protocol for updating the slots of a struct or a class which I suppose means a protocol for extracting initargs to copy an instance, or something. though going through keywords would be... yuck (let ((x '(1 2 3)) (let-update ((x (car (cdr x)) 4)) x)) ==> (1 4 3) ? (defstruct foo a b) (updatef (foo-a (make-foo :a 1 :b 2)) 3) ==> #S(FOO :A 3 :B 2) ? of course, recursing going through the first argument isn't friendly to IPS updatef [...] my pure answer to setf except the current version doesn't compose well enough. a *real* updatef should take three+ arguments: a "zipper" interface, a "state" object, and one (or many) values to purely insert at the place(s) indicated by the zipper into the structure. or maybe four. An interface, an object, a key, and values. (splitting the key from the interface)