emacs-elsa / Elsa

Emacs Lisp Static Analyzer and gradual type system.
GNU General Public License v3.0
644 stars 27 forks source link

Add type inference for function signatures. #92

Open Fuco1 opened 6 years ago

Fuco1 commented 6 years ago

Assuming types inside functions is actually harmless because the only place where that can break is if we get supplied wrong argument from outside. So in this function

(defun my-x (str)
  (string-to-number str))

we can safely assume str is a string and not generate an error for string-to-number taking mixed.

However, if we elsewhere

(my-x 1)

we should report an error there saying 1 is not a string. Similarly we know the function should return a number, so doing

(symbol-name (my-x "1"))

should complain that we are trying to get a name of int instead of a symbol.

The inference could at first be contained completely to the function, it can not do worse than just returning mixed anyway.

Fuco1 commented 6 years ago

This is all quite easy to do if we adopt a "single-pass" approach, that is we assume all functions are defined before first use.

I'm not sure how to make this a) fast and b) work in multiple passes, such that

(1+ (x 1 2))

(defun x (a b)
  (if a (format "%s" (< a b))
    (number-to-string b)))

can also understand that the 1+ will error (while x was not yet defined)

Fuco1 commented 6 years ago

Actually, it is really simple because we can do the read-in of all forms into a list, then iterate the list and analyze.

We can have a routine that would just register the interesting things like defuns/defvars during the read phase and puts the forms in a hash or some such on the state so we can then refer to those and eagerly analyze them out of order if there's an earlier reference.

We should probably still warn that the order should be "declare before use" just to make things consistent.