Hacker News new | ask | show | jobs
by derdi 501 days ago
I really don't care what you "admit". Now you're saying that it doesn't matter whether Prolog has predicates as first-class values, and yet you keep arguing that it does have them. I don't think you're here anymore to establish what statements about Prolog are true or false. You're here for a fight; I'm not here for a fight. Go fight yourself.

Not for you, but purely for the benefit of unfortunate souls who wander by and are confused what there is to argue about:

    call_direct_and_indirect(IndirectCallTarget, Input, Result) :-
        call_direct(Input, Intermediate),                  % first-class call
        call(IndirectCallTarget, Intermediate, Result).    % second-class call
This predicate calls some other predicate `call_direct/2` in a first-class way. It's a call.

It also calls some predicate identified by whatever the variable IndirectCallTarget may be bound to. This is a second-class call. It's frequently referred to as a "meta-call" to signal that it's not a first-class call. It's important to note that the value passed in for the IndirectCallTarget parameter is not a predicate. It cannot be, since there are no predicate values in Prolog. It's the name of a predicate. (Plus maybe a partial argument list; still not a predicate.) Since the thing being meta-called is not a predicate, it must be meta-called specially using the `call/N` builtin. The user has no realistic way of implementing the `call/N` builtin themselves.

2 comments

> The user has no realistic way of implementing the `call/N` builtin themselves.

Not sure what you mean by realistic, but `call/1` can be implemented by having one simple rule for each existing predicate (now for the sake of the argument ignoring control constructs, which require somewhat more complex processing first) plus a rule for uninstantiated variables and one for an inexistant predicate. And `call/N, N > 1` can now be defined based on it.

Yes, enumerating all predicates in the system and meta-interpreting all control structures seems unrealistic to me. In the sense that no Prolog application developer (as opposed to a Prolog system implementor) would want to do it. Except maybe as an intellectual exercise.

Of course you wouldn't really need to enumerate all predicates in the definition of call/1. You could first run a whole-program abstract interpretation to identify just the ones that can actually be meta-called. Much more appealing :-)

Yes, this technique has been used by several implementations. And any application developer can use `asserta/1` for the very same purpose. Just one rule, that is certainly much more appealing.
I will concede that my tone was not as welcoming or polite as it should be and could rightly be considered combative, so please accept my apologies.

> call_direct_and_indirect(IndirectCallTarget, Input, Result) :- call_direct(Input, Intermediate), % first-class call call(IndirectCallTarget, Intermediate, Result). % second-class call

I see we are at an unfortunate impasse. I assert what you are calling a "second-class call" is usually considered "first-class". I will leave the definition here for readers to decide for themselves. I rest my case and wish you a good day.

https://en.wikipedia.org/wiki/First-class_function

> Higher-order functions: passing functions as arguments

  Further information: Higher-order function
  In languages where functions are first-class citizens, functions can be passed 
  as arguments to other functions in the same way as other values (a function 
  taking another function as argument is called a higher-order function). In the 
  language Haskell:

  map :: (a -> b) -> [a] -> [b]
  map f []     = []
  map f (x:xs) = f x : map f xs