josefs / Gradualizer

A Gradual type system for Erlang
MIT License
612 stars 35 forks source link

Making it a real Erlang application #29

Closed Zalastax closed 5 years ago

Zalastax commented 6 years ago

I want to work on making Gradualizer a real Erlang application so I'm wondering what you have in mind. Is it a traditional long-running OTP application you have in mind or a CLI application that starts and stops between each request? Perhaps an implementation using the Language Server Protocol?

zuiderkwast commented 6 years ago

I assume a CLI tool is what Josef had in mind.

If you want to make an LSP "plugin" for Vlad's sourcer, it would be pretty nice I guess. I don't know if there is a plugin mechanism of any sort. It might be some more work...

I would like to see plugins for rebar and erlang.mk as well so that you can run rebar3 gradualize and make gradualize.

It's all up to you!

josefs commented 6 years ago

Initially I imagined having a CLI tool, but I'm very open to other approaches as well. Right now, I load it together with the project I want to typecheck and use gradualize:type_check_module/1 which checks an already loaded module. It works quite well, but it'd clearly be good to have support for project-wide checking also.

Viktor's suggestions are all very good.

Ultimately, I would really like to see integration with the erlang shell/beam so that it would be possible to get typechecking autmatically when modules are loaded. Simon Thompson from University of Kent expressed interest for such a solution. He wanted to use it for teaching type driven development in Erlang.

gomoripeti commented 6 years ago

Just adding to the brainstorming, Gradualizer could also be inserted as a parse transform, which does not actually transform the AST but emits errors in case of a type error. This way it could be part of compiling a module. (In a very futuristic setup it could even modify the AST applying small optimisations based on extra type information it gather during analysis - but I don't think this is the primary goal.)

But before that, I agree, it's better to keep Gradualizer as a standalone step and trigger it via CLI/build tool plugins.

Zalastax commented 6 years ago

Regarding integration with rebar3: it seems like a plugin needs to be its own OTP application (eventual sourcer integration probably needs this as well). I assume that means gradualizer would need to be an umbrella project? Is that fine with you @josefs and can erlang.mk support that?

josefs commented 6 years ago

If making Gradualizer an umbrella project is what it takes to integrate with rebar3, I'm all for it.

As for whether erlang.mk can support umbrella projects, I don't know. @gomoripeti, do you know?

gomoripeti commented 6 years ago

I'm not a big fan of library application as an umbrella. For example rebar3 does not support an umbrella app as a dependency. Also creating a hex package with the old rebar3 hex plugin from apps in an umbrella is problematic.

OTOH Gradualizer is already an OTP application, wouldn't just adding a gradualizer_prv module do the trick? (as a rebar3 plugin - I don't know how erlang.mk plugins work)

Zalastax commented 6 years ago

@gomoripeti yes of course! Let's just case split on when init/1 is passed a rebar_state:t()! That will probably work for erlang.mk and sourcer as well.

Edit: turns out that idea did not work (rebar-state:t() is not exported and it does not seem like a common pattern to case split on records from other modules). Fortunately https://github.com/erlang/rebar3/blob/cd858a45e37f6563f22bf3aebee5911521f3c497/src/rebar_plugins.erl#L157 allows for customizing which modules are considered rebar3 providers! I'll go down this route soon.

zuiderkwast commented 6 years ago

Erlang.mk plugins are GNU Make include files. No Erlang code involved. They can be used to add make targets such as make gradualize. It should be a short piece of code that just runs the cli script IMO.