in this mail (</.> code ...) == (<lambda> () code ...)
The following is a pretty unique feature for guile-log. Assume that we would like to implement a collect like feature for guile log that has the property that it at any time in the computation can leave it, returning to the shell
store the state rerun it, retrieve the old state etc. This is what you could do,
(<define> (<collect> Lam X L) (<letg> ((l '())) (<or> (<and> (<funcall> Lam)
(<code> (set! l (cons (gp->scm X S) l))) <fail>) (<=> l L))))
Notice how we introduce a special local variable l, that we update functionally. The difference with letg and let
is that we handle state in a nice manner lam can return from it's excecution and we can store the state then l is saved automagically and although we are using set! we can later retrieve it and restart the calculation again.
Quick and simple!
We get, scheme@(guile-user)> (<run> * (l) (<var> (x) (<collect> (</.> (<or> (<=> x 1) (<=> x 2))) x l))) $2 = ((2 1))
Also with, (<define> (<uniq> Lam Y)
(<letg> ((l '())) (<funcall> Lam) (<when> (not (member (gp->scm Y S) l))) (<code> (set! l (cons (gp->scm Y S) l)))))
scheme@(guile-user)> (<run> * (x) (<uniq> (</.> (<or> (<=> x 1) (<=> x 1) (<=> x 2))) x))
$1 = (1 2)
In prolog and racklog we can in a collect specify a variable that need to be fixed and vary another one here is the logic,
(<define> (<collect-2> Lam X Y L) (<uniq> (</.> (<funcall> Lam X Y)) Y)
(<var> (XX) (<collect> (</.> (<funcall> Lam XX Y)) XX L)))
What I find very interesting is that by mixing functional and set!-like programming one produces a very powerful notation.
With this we have a very powerful with respect to state management that beats racklog and prolog with respect to features.
Note that the collection is dynamic and how it's possible to treat infinite tables in a nice manner. Of cause the above scheme can be inefficient though.