[eeps] Multi-Parameter Typechecking BIFs

mats cronqvist <>
Fri Feb 20 08:55:23 CET 2009


"Richard O'Keefe" <> writes:

> There is a major defect in the idea of things like
> 	func({_,X::float,_,Z::float}, [{_,Y::float,A::float} | _]) ->...
>
> I'm finding it astonishingly difficult to explain, but it's
> very important.  The thing is that it misrepresents a relation
> between a collection of variables as a property of each variable
> separately.  This is one of the things that guards get right;
> they make it plain that the *whole* head has to satisfy some
> relationship.

  I think I see what you're saying. Alas, your conclusion seems
  backwards.

> Take again the very common case of "this argument is an
> {M,F,A} triple".
>
> Right now, people write out, every time,
>
> 	f(...{M,F,A}...)
> 	when is_atom(M), is_atom(F), is_integer(A), A >= 0
> 	-> ...
>
> Writing this as
>
> 	f(...{M::atom,F::atom,A::integer}...)
> 	when A >= 0
> 	-> ...
>
> (A) Makes it much much harder to *see* the triple.

  Marginally harder, I'd say. And with syntax haglighting on it would
  be a non-issue.

> (B) Splits the condition on A into two pieces, one of which
>     can be written as an inlined type test and the other of
>     which cannot.  Yes, this can be fixed, but I have never
>     yet seen it done readably.  Without some such extra
>     complexity, the effect on programmers is to encourage
>     them to write less precise conditions.

  But the problem with the current when syntax is exactly that; that
  you have to split all the conditions in pieces (the first condition
  being where in the argument the variable is bound.)


> (C) Kicks abstraction in the teeth, beats it in the head with
>     an iron bar, and steals its notecase.  Where does it say
>     {M,F,A}::names_a_function?  This is a very very low level
>     way of describing what you want.

  You lost me here.

> What we want, of course, is to say that the *whole* triple
> satisfies a named condition.  And we can do that, right now,
> with macros.
>
> 	-define(mod_func_arity(M, F, A),
> 	    is_atom(M), is_atom(F), is_integer(A), A >= 0).
>
> 	f(...{M,F,A}...) when ?mod_func_arity(M,F,A) ->

  But then I have to go looking in a header file somewhere to find the 
-define(mod_func_arity,...). 
  Yuck.

>>  With inline (type) guards there would be no rationale for James' EEP.
>
> Thanks to macros, there isn't right now.

  True enough. 

> Abstract patterns would be better, but macros *can* do the
> job of naming *relations* to be used in guards.
>>
>>
>>> Inline guards are not intended to replace the standard guard syntax,
>>
>>  Type checking in standard guard syntax would be obsolete, and could
>>  (should, in the long run) be removed.
>
> Guards are good.  I have had the misfortunate to have to read
> "Prolog" code written in a dialect that allowed type tests in
> patterns.  Never again.

  Type checking in guards sucks. It splits the match condition into
  pieces, makes it prone to stupid typo errors, and, worst of all,
  presents a barrier to type checking that is high enough to make
  people just skip it altogether.

  mats



More information about the eeps mailing list