[erlang-questions] Erlang is an education

Richard O'Keefe ok@REDACTED
Wed Jan 23 06:02:13 CET 2013


The SWI Prolog and ISO Prolog revision mailing lists have
recently been full of discussion about a proposed change
to a built-in predicate.  Skip to <<HERE>> if you don't
want the background.

Prolog is a lot like Erlang in many ways, but
 a term is a variable (variables exist at run time)
 or not, and if it is not a variable it has
   a function symbol,
   an arity,
   and arity many arguments.
A number is a nonvariable term whose function symbol
is the number itself.

Back in about 1984, there were type tests 'is this a variable',
'is this not a variable', 'is this a number', 'is this a term
with no arguments', and a de facto 'is this a term with some
arguments'.  What there wasn't was 'is this a term that has
a function symbol that is an atom', and that was a pity because
that's the data structure that represented a function call.
So a predicate
   callable(Term) :-
      "Term is not a variable and its function symbol is an atom".
was introduced.

There was a _different_ predicate
    current_predicate(Name, Term) :-
       "Term represents a call to some defined predicate
        and Name is the name of that predicate sans arity".
that you could use to ask "is it OK to call this".  It's not
a type test, it has to check whether there is an actual
loaded definition.

The ISO standard removed current_predicate/2, replacing it by
a significantly less usable current_predicate/1 that takes a
Name/Arity pair and no Term.

Then along came modules.  Prolog uses the same Module:Name(Args)
syntax as Erlang, and as a data structure it means ':'(Module,Name(Args)).

What happened was people forgot about current_predicate/2 (although
SWI Prolog has it) and complained because callable/1 didn't do anything
special with module prefixes.  The complaint was that code doing

p(G, ...) :-
    callable(G),
    ...
    call(G),
    ...

could go wrong because callable/1 wasn't looking inside the module
prefix.  (Although current_predicate/2 _would_, and was actually
documented as being usable for this purpose.)  So the cry went up,
"change callable/1!"

<<HERE>>

When people were pressed about the use cases, one person said that
he was sending goals from one thread to another, which might be on
another machine.

From long exposure to Erlang and this mailing list, it was
_instantly_ obvious that this was a bad idea.  In fact it was
_such_ a bad idea that I don't believe I am able to
spontaneously think of doing that any more.  Erlang and this
mailing list have taught me that if you want another thread
or machine to do something for you, you DEFINE A PROTOCOL whose
elements are data structures and that's what you verify.

As I pointed out, do you _really_ want an 'it's safe to call
this' test that _passes_ fun () -> halt() end?

Erlang.  It's an education.




More information about the erlang-questions mailing list