Skip to content

Type representation #563

@erszcz

Description

@erszcz

This module and its types, all modelled after Gradualizer code and erl_parse, show why packing AST node attributes into a list leads to unnecessarily convoluted code:

     1	-module(abstract_type_node_attributes).
     2
     3	-export([g/1]).
     4	-export([h/1]).
     5
     6	-include("include/gradualizer.hrl").
     7
     8	-type simple_type() :: {type, list | nonempty_list, [a | simple_type()]}
     9	                     | {type, atom, {b}}.
    10
    11	-type simple_type_fixed() :: {type, list | nonempty_list, {a, simple_type()}}
    12	                           | {type, atom, {b}}.
    13
    14	-spec g(simple_type()) -> b | simple_type().
    15	g({type, L, []}) when L =:= list; L =:= nonempty_list ->
    16	    b;
    17	g({type, list, [a]}) ->
    18	    b;
    19	g({type, nonempty_list, [a]}) ->
    20	    b;
    21	g({type, list, [a, SimpleTy]}) ->
    22	    %% This requires an ?assert_type(SimpleTy, simple_type()) or leads to an error
    23	    SimpleTy;
    24	g({type, atom, {_InnerNode}}) ->
    25	    b.
    26
    27	-spec h(simple_type_fixed()) -> b | simple_type().
    28	h({type, nonempty_list, {a, _}}) ->
    29	    b;
    30	h({type, list, {a, SimpleTy}}) ->
    31	    SimpleTy;
    32	h({type, atom, {_InnerNode}}) ->
    33	    b.
$ ./bin/gradualizer abstract_type_node_attributes.erl
abstract_type_node_attributes.erl: The variable on line 23 at column 5 is expected to have type b | simple_type() but it has type a | simple_type()

g({type, list, [a, SimpleTy]}) ->
    %% This requires an ?assert_type(SimpleTy, simple_type()) or leads to an error
    SimpleTy;
    ^^^^^^^^

The warning is generated because without an extra hint from the programmer, the typechecker has no way to realise the convention by which [a | simple_type()] means that the first type in the list is going to be a and the second simple_type(). Using a tuple {a, simple_type()} instead of the list would encode that information directly in the type.

Gradualizer commit: 81385f6

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions