I wrote a basic implementation for metaobjects in PROLOG, due to the fact that I am always writing PROLOG in an open-polymorphic, example-driven manner, and have to write something of the form fn(ID, Attr) constantly and I just wanted a faster way to do this, especially in live systems, without a bunch of repeating boilerplate.
There is nothing fancy like bitemporality, but perhaps someone might also find this useful. I am very interested in ‘declarative object’ systems.
:- use_module(library(clpfd)).
:- dynamic(slot/3).
call_slot(SlotHead) :-
SlotHead =.. [_, ID|_],
call_slot(ID, SlotHead).
call_slot(CallerID, SlotHead) :-
(slot(CallerID, SlotHead, Body)
-> Body
; (slot(CallerID, inherits(CallerID, InheritsID), Body),
Body,
call_slot(InheritsID, SlotHead))).
%% slot(0, card_name(ID, ren), true).
%% slot(1, inherits(ID, 0), true).
% ?- call_slot(card_name(1, X)).
slot(0, make_obj(Self, Slots, ID),
(gensym(obj_, ID),
call_slot(make_slots(Self, ID, Slots)))).
slot(0, make_slots(_Self, _, []), true).
slot(0, make_slots(Self, ID, [(SlotHead, SlotBody)|Slots]),
(asserta(slot(ID, SlotHead, SlotBody)),
call_slot(make_slots(Self, ID, Slots)))).
% ?- trace(call_slot/1).
% ?- trace(call_slot/2).
% ?- trace(slot/3).
% ?- slot(0, make_slots(0, obj_1, [(card_name(_23816), true)]), Body).
% ?- call_slot(make_obj(0, [(card_name(Self), true)], ID)).
%@ ID = obj_1.
% ?- slot(obj_1, Head, Body).
%@ Head = card_name(_),
%@ Body = true.
I do not use logtalk because I usually make extensive use of qsave and logtalk doesn’t support qsave very well. Last time I checked you have to define a special top-level REPL and then mess w a script for the compiler.
Any feedback welcome.