[erlang-questions] [Dialyser] Type parametrized behaviours

Kostis Sagonas kostis@REDACTED
Thu Apr 26 00:57:19 CEST 2012


On 04/24/2012 04:42 PM, Francesco Mazzoli wrote:
> Hi,
>
> I have recently updated some code to use the new callback signatures for
> behaviours. Before that, we simply used a .hrl file that we included in
> each implementing module.
>
> While hacky, the old approach had an advantage: we could include in the
> .hrl specs some types that were to be defined in the including file, and
> then used in type signatures.
>
> It would be useful to be able to parametrize behaviours by type more
> nicely, since most behaviours specs are dominated by 1 or 2 types
> (classically some kind of state) and as of now no typechecking takes
> place on those types. That might be achieved with some pre-processor
> directive, e.g. -behaviour_type(whatever).
>
> What do you think?

The first thing I think is that you have not fully understood the need 
for having both a -callback and a -spec.  In the general case, the 
behaviour module needs to have a way to define what the callback module 
*can* have as implementation of callbacks, not what it *should* have as 
its implementation. For example, it's perfectly ok for the behaviour 
module to say that there needs to be a callback function f/1 which can 
return 'foo' and 'bar' and for the callback module to implement a 
function that just returns 'bar'. So, we do need both these attributes 
since they serve different purposes. This also means that the "header 
file approach" does not work / is not flexible enough in general.


Now, regarding parameterized behaviours, I think that you need to 
explain more concretely what you have in mind. Perhaps it's something 
interesting but the example you gave in another mail of yours:

 > To give a small example of what I want to do, a behaviour might define
 >
 > -callback step(state()) -> state().
 >
 > where `state()' is not define locally in the behaviour, but in each
 > implementing module.
 >
 > I hope I made myself more clear.

unfortunately does not make matters any clearer...

If I understand what you are sketching correctly, the problem I see is 
that since there will be no definition for state() in the behaviour 
module, that module will impose no constraints on what state() can be. 
Thus, your example is semantically equivalent to:

	-callback step(X) -> Y.

for some arbitrary types X and Y. (Just take state() to be their union.)

The point is that the callback module is allowed to provide the 
following implementation of step/1

step(foo) -> 42.

and dialyzer (*) is obliged to keep silent in this case. As I wrote this 
case is actually fine. The callback module is allowed to implement only 
a portion of what the callback spec specifies. How is that different 
than what currently takes place other than perhaps requiring that the 
callback module contains a definition for state()? (Perhaps as liberal 
as -type state() :: 'foo' | 42.)

Anyway, can you provide a *precise* proposal for how you want things to 
look and what checks dialyzer should perform in your opinion?

Kostis

(*) Please use the correct spelling for dialyzer.



More information about the erlang-questions mailing list