aboutsummaryrefslogtreecommitdiffhomepage
path: root/notes/type_inference.txt
blob: e21ac058beada79bacf8aaf66b76723f1b1bac71 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

Type inference
==============

I think that there are some major disadvantages with type inference:

* It can make code harder to reason about (variables can have "mystery types"
  that only the compiler knows for sure about)
* It can force values to have types instead. E.g. "var i = 0i64",
  in which case it doesn't really do any type inference
  (so it is rather pointless in these cases)

Here is middle ground, that gives type inference only in cases where it is
obvious to the reader what the type is:

1. Infer types from the name. Just flip the first letter to uppercase to
   get the type. This does NOT work with generic types, e.g. List<T>
2. Optionally, have domain specific definitions of type inference based
   on names.
3. Maybe have some fixed-type identifiers such as i,j (int), b (byte)
4. Maybe allow "ret" to have the type inferred from the return type?
5. Allow only type inferrence for immutable, effect-free/pure-data objects?

Domain-specific name-based type inference
-----------------------------------------

    \infer Vector vec       # only applies to the module where it is given!
    ...

    func read_entries(arena) -> List<string>
    {
        val file = .open(arena, "file.txt", .read)      # (1): type: File
        val vec = .[1,0,0]                              # (2): type: Vector
        var i = 0                                       # (3): type: int
        ref var ret = .new(arena)
        ret.add("test")
        return ret
    }

Tricky parts:
- Distinguishing between "var-ref-to-immutable" and "immutable-ref-to-var"


Multiple-immutable-assignment
-----------------------------

In some cases, one might want to do this:

    let y
    if x > 0 {
        y = somefunc(x)
    } else {
        y = otherfunc(x)
    }

I haven't seen any solution to this.


Syntax
------

There are many syntaxes in use by other languages for type inferrence:

    let
    val
    var
    auto
    def

"val" is easy to mix up with "var", so it might not be such a good idea.
"auto" is longer than the others.
In multiple-immutable-assignment (above), "let" does not "sound" good.

Another option would be to allow only types of *references* to be inferred,
and use the "ref" keyword:

    ref list = get_list()

Perhaps this could be combined with the "domain-specific name-based type
inference" above.