elm / compiler

Compiler for Elm, a functional language for reliable webapps.
https://elm-lang.org/
BSD 3-Clause "New" or "Revised" License
7.55k stars 662 forks source link

Feature Request: Macro/Template system #1413

Closed Fresheyeball closed 8 years ago

Fresheyeball commented 8 years ago

The amount of code that could benefit is legion. Elm already has quasi-quotes, but only webgl. This could just be expanded to custom code.

Elm-check producers

(the lack of templating means developers need to write onerous repetitive code just to turn a given Union Type into something property testable. This also makes code less flexible)

type Foo = Foo | Bar Int | Baz (String, Int)

$(mkProducer Foo)

Html

There is already elm-html projects out there, as well as .elmx. This could potentially be addressed more elegantly with Macros.

view : HtmlT { foo : String, bar : String } msg
view = [mustache|
<div>
  <h1>{{foo}}</h1>
  <span>{{bar}}</span>
</div>
|]

update forwarding.

There is several projects addressing the boilerplate in update forwarding, sometimes losing assurances or flexibility in the process. Macros could allow developers to specify type relationships without the need for additional typesystem features.

update msg model = case msg of 
    Foo fooMsg -> let 
          (fooModel, fooCmd) = Foo.update fooMsg model.foo
       in ({ model | foo = fooModel }, Cmd.map Foo fooCmd)
-- becomes
update msg model = case msg of 
    $(forward Foo Foo.update model.foo)
process-bot commented 8 years ago

Thanks for the issue! Make sure it satisfies this checklist. My human colleagues will appreciate it!

Here is what to expect next, and if anyone wants to comment, keep these things in mind.

mgold commented 8 years ago

I'm against this.

One of the big selling points is that Elm is one language; there's no erb/haml/handlebars/jsx templating language to learn. Invariably such languages are crippled and you find yourself hacking around not having some control structure or value in scope.

Macro code has to be part of the codebase, and everyone on the project has to learn it.

I think a much better approach is tools that generate tedious-to-write Elm code, which then gets copied and committed as if you wrote it yourself. Yes, it doesn't automatically stay in sync with the other code, but the compiler won't let discrepancies get very far.

This is a huge ask for both implementers and developers, and I don't see the consequentially-required huge payoff.

Fresheyeball commented 8 years ago

How would that work? Do you have an example of code-gen tools out there Elm could emulate? Because so far, code-gen hasn't been a great idea in many cases.

mgold commented 8 years ago

http://noredink.github.io/json-to-elm/

Warry commented 8 years ago

I'm in favour of macros (or equivalent). I think that if macros get the same validation system as Native right now (whitelist), we keep consistency and safety.

IMHO, It's evident to me that macros could bring the worst as the greatest in a code base, but the community is eager to keep a simple and clear environment.

Fresheyeball commented 8 years ago

@mgold If you are suggesting that tedious to write elm code should be addressed by a distributed series of independent browser based online code generators, I'm going to say that's not a real solution. I don't want to go to a different set of browser bookmarks for different common derivable code scenarios. Nor do I want code generation outside of my build process.

If you are suggesting using things like json-to-elm inside of a build process, then we are potentially in some kind of module loader hell. json-to-elm looks like it uses python for generation, so now python is in the stack, and there is no consistent standard for how these distributed set of tools should work. If we wish to address 10+ boilerplate heavy scenarios, we now have to custom install and rig together disparate apis of these different generation tool into our build. And once all that is working, essentially we just invented fraken macros, where macro code is separate outside of .elm files.

A proper macro system seems like the only solution to me atm. That's not to say there is only one way of going about it.

One way that might address the "One Language" and maintainability concern, is to have macros that are outside of Elm. As in elm-make provides a facility to pipe code into an external process for expansion. Then type checks the expanded code. This could also mean that elm-package now needs the ability to let code generator authors package an executable with any surrounding elm files. I feel this could also discourage the abuse that can come from macros, as there are more barriers to set up the external code gen process and wire it in.

evancz commented 8 years ago

I'm aware that folks want this for various problems. I don't think it makes sense to track it here though. Should be a normal community discussion.

Fresheyeball commented 8 years ago

Move to here: https://groups.google.com/forum/#!topic/elm-discuss/im2up0f59qs