|
|
|
|
|
by mccosmos
4227 days ago
|
|
Thanks for the replies. A few comments: 1. I might have gotten a bit carried away when writing some parts of the article. 2. "Functors" are the same as functors from Prolog. Note that Prolog lists are functors too. They also may enable the language to have an 'Option' type like in some functional languages. |
|
Stylistic quibbles aside, I have some reservations about the choices you've made in diverging from Prolog.
Your use of 'functor' seems to be different from Prolog's. You are therefore adding a forth or fifth meaning to the term, will have to compete with those already given by of Carnap, Quine, category theory, and OCaml. You are, thus, further muddying the sense of an already over-loaded term (http://pinealservo.com/posts/2014-10-22-ManyFunctionsOfFunct...). You seem to use 'functor' to refer to labeled tuples, or positional records. Prolog 'functors' are rather the atoms used to label such structures, e.g., `p(a)` and `p(a,b)` are different compounds with the same functor, 'p'. As a matter of fact, Prolog's compound structures do also serve as labeled tuples, but that is only a symptom of Prolog's explicit evaluation and homoiconicity. In fact, Prolog functors are "function like" in that we can call a functor on arguments, thereby instantiating a predicate. Your "functors" seem to be inert, and I think it would keep things much clearer if you just called them "records" or something. 'Functor' makes sense in the context of Prolog, where labeled compounds can be both data structures and propositions/propositional functions; for in that case, the atom used for labeling also serves a role akin to the string 'sin' in the function `sin(x)`.
This brings me to my other reservation: one of Prolog's real strengths, in my estimation, is the combination of explicit evaluation, unification, and homoiconicity. That combination gives us many higher order behaviors for free and facilitates meta programming. Thus, explicit evaluation and data-as-code means the compound `p(a)` can be mapped over a list, giving us partial application of `p(a,X)`. We also get the equivalence of first-class functions, allowing predicates to be passed as arguments to other predicates. We are also permitted remarkably deep reflection, including unification-matching on predicates and arbitrary data structures: e.g., I can do `p(X,q(r,S)) = p(2+2, Y)` to get the assignments `X = 2+2, Y = q(r,S)` and then `Sum is X * 2`, to get `Sum = 8`, and `S` will still be free until bound to something later.
This is why we differentiate the unification operator `=/2` from the arithmetic evaluation operator `is/2` and various equality operators. Contrary to your assertion, `X = 1+2` works very well, allowing me to do `X =.. [F|Args]` to get the assignments `F = +, Args = [1,2]`, so I can choose to multiply the arguments instead (e.g., `Y =.. [*|Args], Product is Y` getting `Product = 2`), inspect he functor (in this case, `+`), or simply pattern match to get the values in X (`2+Y = X` yielding the assignment `Y = 2`).
As a Prolog user, I have to say, I wouldn't dream of giving up this flexibility just to save the trouble of writing commas for explicit conjunctions and gain the (dubious) convenience of an operator that conflates assignment and equality.
Lastly, as an SWI-Prolog user, it is disingenuous to ask "where is list.map or string.concat?", as I'm sure you are well aware that both of those predicates (and many more besides) are supplied in the standard library. SWI, great as it is, still wants for features, but basic operations like those are well provided for.
So, there's some criticism from an inexpert enthusiast. Truly, I am inspired by your effort and look forward to trying out your language!