6 Nov 2008 tampe   » (Journeyer)

My God

What so cool with Internet and forums like advogato is that ideas, words and units of thought is flowing from mind to mind mutating, mixing, replicating, bouncing, In a very subtle way. The communication is many to many and this is indeed important, we must be able to communicate in order to make sure that the world won't fuck up.

Introspection is a nice powerful feature that seems like a hot topic these days. I try to practice this a lot, not only in my code, but on myself. It is kind of cool to dig out the association and logic behind an idea.

One idea I got was to check out scheme. There is some nice food for thought in that community. I've planning to read about lazy evaluations, but here is my current view on delayed evaluations.

If D1,D2 is delayed, basically f(D1,D2) :D3 is delayed as well represented if any of its arguments is delayed. Now this means that D1->D3 and D2->D3 and you see that what you have is a directed acyclic graph (DAG) that represent your overall delayed state with a pointer to a function at each node. So it is not at all a difficult concept. But what about and (if D A B), D is delayed. Here it seems you need to store the value of both A and B in order to be able to use it later, this is actually a difficulty. I will need only one of A and B but I have to get both values in order to later retrieve the correct value. If you have recursion in A or B you may find your way into an infinite loop. So if A = (g C E) you need to store (g C E) and continue so recursively. With no gotos and internal state in your code you will then be safe. If you have state you then need to store the state related to both A and of B. A key issue here is to avoid relation pollution e.g. you do not want to store state that is not needed to retrieve the value later.

In my (switch-if P A B) construct if P A is incremented else B is incremented. I try to avoid using delayed values in the P but storing the state of A and B may seem to solve the problem. will it will be safe? No, there is another problem. A and B will contain signals backwards in the system about yielding values, about finishing iteration and skipping stuff. So depending on the possible signals send back you will have both complicated knots to untie as well as more trivial ones. Some of these questions can be mitigated by simply returning values of special type like a skip value. A quit value which also can be implemented.

Consider that we are under a delay. And now the delay is activated with a skip value. This is the interesting construct. Consider an update of internal state:

(update Var Vals Oldval)
The most simple choice of logic is that if any Val is a skip value, Var is a skip value and equal to Oldval. A function just returns a skip value if any of it's arguments is a skip value. This logic is then transported in the delay graph.

The finish signal is a little more subtle but basically each object as a finish value Vf, and if object Y at an update gets a finish value then it should fire it's finish function to update Vf, the variable representing the finishing value. Else the transportation and action of the finish type is like skip but of higher precedence.

Now the actual iteration is something like

   (make-generator X)
   (loop X))

(define loop X
   Ret = (relate Ret (X.val))
   (if (finish? Ret) 
        goto exit
   goto for:

exit: X.Vf

The relate is just a relation that represents the transport of the finish all the way to the current Ret if this has been delayed and you have to iterate a few iterations more than needed.

Trying to handle the yield signal is delayed. No just kidding. You need to do the following

   (do A B C)
The logic is, take next A, if A is a yield stop! and use value of A. the next time start with A again. Else continue with B and so on. Now if B is delayed and might be a yield you need to store the state of the do e.g. the state of

A,B,C and the internal state of do e.g. a program pointer. Then at the next update of this object if the delayed value have materialized you will then just continue with the evaluation of the do construct and everything would be fine else you will have to just chain the actual updating and return the delayed value.

Can we have infinite loops? Well, At each step you will have a tree of objects that you update in the natural order, when you update subtrees will collapse an new subtrees will be created. A delayed object is returned at a certain object and then transported to objects below it in the order. Hence if you keep a logic where you always will fill in the missing information at the same object that you issued the delay you will be safe.

I didn't realize all this before I started writing. This is why I write, enjoy

Latest blog entries     Older blog entries

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!