Does Prolog have static or dynamic typing?

Asked

Viewed 698 times

8

Although I’m quite familiar with the concept of static vs. dynamic types - can easily recognize if a certain language fits in one or the other - I never knew exactly what the Prolog typing is: whether it is one, another, both or neither of the two...

The article on Prolog in Wikipedia says:

Prolog does not employ data types in the same way that the most common programming languages normally do. All data is treated as being of a single type, Term, whose nature depends on how that term was declared. That is, the lexical elements used in your statement determine whether that term will be a number, a text, a variable, a complex structure and so on.

That didn’t clarify much... Like, what’s the difference between saying "everything is a Prolog Term" vs. "everything is a Javascript Object"? Obviously, exist types in Prolog - at least there is a difference between Atoms, Variables and Compound Terms. Or am I mistaken, and this cannot be considered a "type"? A Wikipedia in English states the same thing:

Prolog’s single data type is the term. Terms are either Atoms, Numbers, variables or compound Terms.

Anyway, the way the data is used in Prolog is substantially different from anything else I’ve ever studied (even imperative and functional languages have much more in common with each other than between them and logic programming).

Example 1:

foo(42).
foo('bar').
foo([_,_,_|_]).

Here I defined a function (strictly speaking, a relationship) foo which succeeds if its parameter is the number 42, the string bar or a list with at least 3 elements. And fails otherwise. Only. This does not mean that it "accepts the whole types, string and list" - in fact it accepts anything:

?- foo(42).
true.
?- foo(10).
false.
?- foo(1.23).
false.
?- foo([1,2,3,4,5]).
true.
?- foo([1,2]).
false.
?- foo(qualquer_coisa).
false.
?- foo(QualquerCoisa).
QualquerCoisa = 42 ;
QualquerCoisa = bar ;
QualquerCoisa = [_G3014, _G3017, _G3020|_G3021].

This "accept anything" is what confuses me: usually a language with dynamic types checks at runtime whether a given value can be used in an X operation, by making an exception if an incorrect type value is being used. But as here there is no verification at all - all operations are applicable to all values and types, and unification (comparison, marriage, matching) at all times is held - would be correct the statement that "there is only one type"?

Example 2:

bar(X,Y,Z) :-
    X = Y,
    foo(X),
    X = Z.

Seems like that we are attributing to X first the value of Y and then the value of Z, but in Prolog there is no concept of "assigning a value to a variable", there is only unification. For example:

?- bar(X, [1,A,3], [B,2,C]).
X = [1, 2, 3],
A = 2,
B = 1,
C = 3.

But that doesn’t mean that X has only one type, unchangeable:

?- bar(X,_,Z), writeln(X), Z = 'bar'.
42
bar
X = Z, Z = bar ;
[_G112,_G115,_G118|_G119]
false.

On each "branch" of the search tree, X had a single value (in the first era 42, and the call returned false; in the second era bar, and the call returned true; when asking for an alternative, in the third era [_,_,_|_] and the call returned false). But during the setback X no longer has a numeric value to have a string value. It has changed value, changed type. This means that typing is dynamic?

Example 3:

distancia(ponto(X1,Y1), ponto(X2,Y2), D) :-
    !,
    D is sqrt((X1-X2)**2 + (Y1-Y2)**2).
distancia(_,_,_) :- throw('Tipo inválido!').

Unlike example 1, here an exception will be thrown if the first or second parameter is [concrete and] of a different type of ponto. Otherwise the function will succeed or fail (i.e. normal behavior, not exceptional). At first I could (but I’m not obliged to) program in this style all the time - or even create a "macro" (term_expansion) to "translate" my entire program to this style, as if it were a "help" pro compiler. It would mean that although Prolog does not be it statically typed, she supports programming via static typing?

  • Clarifying: in the example above the verification of fact occurs at runtime, being a clear case of dynamic typing; however, being Prolog a language homoiconic, creating macros of this type is a simple task, one could not only do the translation but also require each variable to have its declared type - all this without ceasing to "be Prolog" (i.e. would not be "modifying language" or "creating a dialect" - would do so within the capabilities natively supported by the language).

    And these macros run at load time (part of the build process), not execution time; it’s a check on the program’s static structure, not its runtime values. So, in my opinion, this counts as static typing. (example, example)

Not to get too broad or based on opinions...

I am looking for an answer that analyzes these characteristics mentioned according to the definition of what are static and dynamic types. Without deviating too much to "gray territory" (e.g.: Java is statically typed, but using reflection one can program dynamically; however, no one in sound consciousness would use this as an argument to dispute the classification of Java as static...).

In particular, I want to understand whether a type that is not Static automatically is dynamic, or if there is a third rating (or beyond). Or if, in fact, by the way Prolog treats data it can be considered that it "does not employ types".

P.S. Examples above in ideone (adapted).

1 answer

4


The typing used in Prolog is dynamic in the same way as most dynamic languages, for example Python. (And yes, all nonstatic languages are dynamic as long as there is variable typing)

Extending a little to the strength in the typing of variables:

Prolog is a language in which most cases there are no defined types, ie can pass any type to any predicate and usually the worst case is that such predicate (proposition) will be false.

For Prolog accept most types in virtually every case make a language more weakly typed than Python. However the arithmetic predicates as =:= wait for numbers and prove there are guys in the Prolog. (so whether there is typing should be dynamic or static)

For more details I suggest you read this comparison: What is the difference between a static and dynamic programming language?

  • In fact, the arithmetic part even assumes a distinct numerical type. As for being weakly typed, I don’t know if I agree: Python also accepts any value in any call (when using, yes, there may be an exception), and both reject if the number of parameters is incorrect. Similarly, both reject transactions in incompatible types (ex.: 10 + "20"). Moreover, depending on how the predicate is defined, the head does not unify if the input term is incompatible. That is, in relation to the force, I wouldn’t classify Prolog as "weakly typed".

  • 1

    @mgibsonbr, note the expression used: "plus weakly typed"

Browser other questions tagged

You are not signed in. Login or sign up in order to post.