Dictionaries and polymorphism

I’m looking for pointers on how to achieve the following behaviour. I want to have a dictionary that has a key type and an atom value denoting the “implementation module”. Now, in the dictionary tag module, I would define a function that needs to do some kind of dynamic dispatch - first check if type:function is defined, if yes, call it - and if not fall back to a default implementation.

Example:

inventory{type: book, ...}.url() would look for url function in the book module first and call it if it’s defined, otherwise just call some default implementation.

I know that pce offers objects and inheritance but I don’t need OOP-like state, as the state is already in the dictionary.

I think I got something working using wrap_predicate/4!

subtype(Name/Arity) :-
  functor(Head, Name, Arity),
  Head =.. [_|Args],
  append(_, [Dict, _Value], Args),
  wrap_predicate(Head, subtype, Wrapped,(
    ((get_dict(type, Dict, M2),predicate_property(M2:Head, defined)) -> call(M2:Head) ; call(Wrapped))
  )).

Now I can just call use :- subtype(url/2) to get the desired behaviour.

1 Like

I think you should be able to define a module called inventory, with a url predicate in it, using the user defined operations on dicts.

1 Like

@jamesnvc I wanted the url predicate in inventory module to actually call url in book (or whatever is the type key of my inventory dictionary holds) if defined - for a very simple inheritance-like behaviour. That’s why I did the wrapper solution above.

1 Like