I have spent six hours learning about operators and while I get it for the most part, and apart from DCG → and term_expansion, I can’t really see where operators would add much value to my code other than making a call like this,
is_builtin(X)
be typed into my code as is_builtin X
or X is_builtin
depending upon the op/3 type. So is that “it”, the docs say that:
Operators are defined to improve the readability of source code.
So maybe that’s as far as I need to think about it?! But then I read all my Prolog books about operators and started hacking about and now I am a bit confused about “operators”, “predicates” and “functions”… because I tried to create an operator that would work like +
as in 1+2+3
being internally constructed as +( +(1,2), 3)
but have so far failed. Is it even possible?
As I read the various books I have (COP, AOP, C&M, PPID) I really bottomed out as they don’t cover all the things you can do. I started thinking “monads” like Haskell, all sorts of things but my head just doesn’t seem to get it. There are no return values in Prolog, anything returned is through variables passed in, so how does:
Z is 1 + 2 + 3 => Z is +( +(1,2), 3)
actually work? I am guessing that because it is a built-in function it is handled differently down in the engine room ? I also tried to write an operator that would let me append a “!” to a string, and then I wanted to chain them to add multiple “!” on the end, again just for the learning exercise but again, I couldn’t figure out “the return bit”, is it even possible? Can I write my own “functions” (what makes a function a function? Can I have an operator chain a value down so that my silly operator to append a ! to a string could be written as ~~ ~~ “Hello” and produce “Hello!” etc.
I learned mercury for a while last years and that has “function” but it’s a sugared predicate form anyway so nothing surprising there really AIUI and it also had the notion of state variables that the compiler automatically threads through your code, like DCG-s do for the list manipulation operations.
Basically, I’d dearly love to understand the limitations of “op”. I know it is just telling the compiler how to treat the input for wrt. to associativity and precedence, I am, fine with all of that, I just want to know what can and can’t be done!
Here is some of my rambling efforts, I used listing/1
a lot to see what the compiler had done as well as display/
1 to see how things were being evaluated internally but all to no avail!
:- op(500, yfx, meh).
meh(A1,A2) :- %shell(Arg).
string(A1), string(A2),
string_concat(A1, "\\", Out0),
string_concat(Out0, A2, Out),
debug(ops,'A1: ~s, A2: ~s, Out: ~s~n',[A1,A2,Out]).
% op to add an ! to the end of a string
:- op(500, fy, ~~).
~~(Out,Arg) :-
string(Arg),
string_concat(Arg, "!", Out),
debug(ops, '~~ with ~s => ~s', [Arg, Out]).
:- op(500, fx, ¬).
¬(X) :- format('¬ ~p~n',[X]).
Thanks again for reading my mad rambling question.
Sean.