The idea of having a Prolog-like reference engine in go is brilliant, however I feel that the balance is tilted too much towards the Prolog end. Since the package mainly serves programs in Go, it would actually make more sense to design the interface and APIs more in the way of Go rather than that of Prolog.
Currently I'm building up callables in ways like this:
func NewRule(fact t.Term, conditions ...t.Term) t.Callable {
// build the comma separated callable list
cond := conditions[0]
if len(conditions) > 1 {
for _, c := range conditions[1:] {
cond = t.NewCallable(",", cond, c)
}
}
return t.NewCallable(":-", fact, cond)
}
As you can see this is really awkward. I understand the package is intended to be used by feeding in straight strings written in Prolog, but there is no reason why the underlying API couldn't be restructured to fit a more programmatic approach - that will not only allow the Go language to be used more to its advantage, but also saves the cost of parsing. This would be especially meaningful if one is to build a reference engine of relatively big size.
Some problems will lend themselves to easier solutions if this consideration is taken into account. For example, on the issues of atom representation #14, one can simply allow the user to define custom inherit types of Atom that doesn't contain anything if the user wants to save space. One can even imagine the whole system being opened up for more complicated unification processes - the user can define more custom variables and terms and tailor the unification process however they want.
The implementation of relating different functors to their respective functions inside Go feels a bit awkward to me as well. Currently one has to call registerForeign, and throws away a first class function instead to use a token identity for its representation. If we de-couple parsing from reference-working completely, we can just use the function value inside the engine - the user will then use the same function inside Assertz
. This is more reader-friendly, and again, more efficient.
All in all, what I'm suggesting is to separate the syntax and logic of Prolog - the logic (mainly unification) should open itself up to suit more programming needs of Go programmers, while the syntax can be any form one would like - be it Go, or Prolog.