Re: handling state the database way

Paul Singleton <[email protected]>
Newsgroups gmane.comp.ai.prolog.swi
Organization Jambusters Ltd
Message-ID <[email protected]>
It might be good to have the same interface/API for state in the 
various places state can be, e.g. thread, http session, module,..

I wonder whether Logtalk facilitates this?

Paul Singleton

On 14/02/2014 18:28, Abdallah, Samer wrote:

> I'm trying to port/adapt various bits of code at the moment, and
> I am struck by how often dynamic predicates are used to keep
> state information, and how the same formulaic patterns are used,
> eg to change the state:
>
> 	:- dynamic some_pred/1.
> 	update(Event) :-
> 		retract(some_pred(OldState)),
> 		update_something(Event,OldState,NewState),
> 		assert(some_pred(NewState)).
>
> 	initialise :
> 		retractall(some_pred(_)),
> 		assert(some_pred( <Initial state> )).
>
> etc. Sometimes it is not obvious in the code that a predicate is being
> used this way, i.e., that there should only ever be one clause and it
> should be a fact, until one has gone through the code quite carefully.
> (My new predicate dependency graph drawing library has been quite
> useful for that, I will polish it up and make it into a pack soon…)
>
> The same issues apply to the recorded database.
> It obscures the meaning behind the code, it does not make the
> invariant (that there should only every be one clause) obvious, and
> it creates a risk that the invariant might be violated, e.g. if something
> goes wrong between retract and assert.
>
> The only facility that sort of addresses the issue is the flag/3 predicate,
> but that only works for atomic state values, and also, it's mode does
> not suit update operations, e.g. even to increment a counter, one cannot
> do this:
> 	flag(counter,C1,C2), succ(C1,C2).
> because C2 must be ground on entry to flag/3. As far as I can see, you
> would have to do this:
> 	flag(counter,C1,C1), succ(C1,C2), flag(counter,C1,C2).
> It would be nice if there was an apply_to_flag/2 predicate that would
> be called like this:
> 	apply_to_flag(counter,succ).
> or if you need the previous value:
> 	apply_to_flag(counter, get_succ(N)).
> 	get_succ(N,N,N1) :- succ(N,N1).
> and so on.
>
> I digress, but only slightly, because I think it would be good to have something
> like this that allowed an arbitrary term as state, with an interface something
> like:
> 	get_state(+Key, -Value)
> 	set_state(+Key, +Value)
> 	apply_to_state(+Key, CallableWithTwoArgs)
> 	state(+Key, -OldValue, +NewValue)
> Obviously, one could write a library to do this, but I think there might be
> benefit in performance, atomicity and control over backtracking behaviour
> that might come from it being integrated at a lower level, like flag/3.
>
> What do you think? Is it the case that the cost of doing unification on the
> state means that it is not worth the small gain of making it a built-in?
>
> cheers,
> Samer
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.