Hacker Newsnew | past | comments | ask | show | jobs | submitlogin
The Elm Architecture (elm-lang.org)
119 points by tosh on Aug 26, 2018 | hide | past | favorite | 79 comments


The bit I love about the Elm Architecture that I really wish existed in other frameworks is the "Command" system, by which the "Update" step can dispatch further changes. Basically, imagine if a Redux reducer could dispatch further actions.

I've tried building Redux apps with bidirectional real-time communication (re: networked video games), and found myself having to pull almost all of the logic up to the action layer, as I often needed to dispatch further side effects based on changes that happened as the result of an action. It made my reducer into nothing more than a dumb setter, and caused me to have to write complex mocked tests for my action layer instead of my reducer layer.

I know there's been some attempts at bringing this to Redux (such as https://github.com/redux-loop/redux-loop), but from what I've seen it isn't quite as easy to use.

OTOH, I will say, as an outside observer, it sounds like Elm has run into problems with this approach (see: the removal of WebSockets from this guide, pending a rewrite), so I am curious to know more about what issues arose.


The re-frame effects in ClojureScript are a similar idea https://github.com/Day8/re-frame/blob/master/docs/Effects.md


>Basically, imagine if a Redux reducer could dispatch further actions.

You can achieve the same by using redux-saga[0], then writing a generator function ("saga") that inspects dispatched actions, and potentially triggers a side effect, dispatches another action, waits for another action to get dispatched in a certain time, etc.

[0] https://github.com/redux-saga/redux-saga


I really wish the React ecosystem had less dependencies. Things that are included in other libraries are always met with “You can always install X” as if it were a good thing to add more dependencies.


Maybe you want to use react with something other than redux, or saga. Now you say: it doesn't matter, if there is any dead/unused code it will be removed during bundling. That's indeed true. But then, shouldn't we simply install all packages that are available on npmjs.com, and never think about dependencies again? Or don't install any and let our editor or bundler install dependencies automatically? If installing dependencies happens automatically as soon as you write an import statement, does it matter anymore whether you write `import Redux from "redux"` or `import Redux from "react/redux"`? Hardly…


I wish NPM were more secure, but I'm glad that the ecosystem uses small libraries. Many people don't need library X for their React/FrameworkX/VueJS project, so including it in the framework just results in additional bloat for them.

Extra bytes are not a trivial issue for frontend web development, like they are for many server projects.


Some people's package.json is the stuff of nightmares


I think Redux middleware is the answer to this. My preferred approach is to keep all my actions as simple serializable objects, and have (potentially many) small middlewares that listen for certain action types and perform async tasks and dispatch further simple action objects.

There are also more fully-baked middlewares like Redux Saga, but I find that those are a bit too heavy-handed and result in too much “lock-in” for implementing your actions and action creators.


To be fair, the websocket package's design problems are unrelated to the Elm Architecture - just plain old run-of-the-mill API challenges. :)


"Imagine if a Redux reducer could dispatch further actions." I use a technique called "actors" that are like non-UI components that listen to store events and dispatch additional actions if necessary, using setTimeout so they're pushed to the end of the event loop.

Some pedants online continually claim this - or something like it - is an "anti-pattern" but I'm trying to get stuff done, and this is the way to do it.


NGRX (the redux inspired state management library for angular) has a concept called 'effects', which lets you subscribe to the action stream (actions and the state in ngrx are both rxjs observables) and trigger side effects in response to certain actions. The effects themselves map to one or more actions (or zero if you want side-effects only) when they are finished that get dispatched.

Since you're dealing with them from within an observable stream you have access to all the rxjs operators, so you can do things like waiting for multiple actions to be dispatched before doing something, etc.


Hyperapp can do something like this. You can have an action that sends a message for another action. This is how it handles asynchronous HTTP requests for instance: the http() function takes both the URL/params for the request, and the name of an action that will receive the response as an argument.

The result feels very Elm-like, albeit sans the assurances of the typing.


You should take a look at mobx-state-tree. It provides this capability in a straightforward way and is more approachable in general.


redux-observable can give you something rather akin to that type of behavior. It sees each action after it has already been applied to update state. This also separates out the reducer from those side-effects, which you really want anyhowto keep your reducers as pure functions.


redux-saga makes implementing a pattern like this pretty straight-forward.

You can have sagas subscribing to actions and processing them in arbitrary ways, including dispatching new actions.


Check out Undux effects - they're exactly that. https://undux.org


redux-loop is harder to use, but so is Redux itself. They are both having to fight the language (JS) to do what is so simple in elm.


If you want to use TEA but with easier interop with JavaScript libraries, you can use ReasonML/OCaml with bucklescript-tea[1] instead

[1]: https://github.com/OvermindDL1/bucklescript-tea


Just pulled an all-nighter deciding what to use instead of Elm. We have a 45kloc codebase in Elm and, despite having some big pros, the closed source development it goes through, along with the 0.19 debacle, just pushed us over the edge. The team is very motivated to ditch elm over something else.

So, Bucklescript seems great (and it's wonderful how OvermindDL1 explains in the open his design decisions. An openness that I've missed in Elm), and IMO superior than Typescript, and comparable with Fable (in that case being mostly a matter of personal taste: F# vs ocaml).

But, as long as we are trying new stuff, I've decided to use Clojurescript with Reagent and re-frame. The tooling around it seems very mature (even more so than Elm, but I may be wrong), with a good community and macros!

For anyone in a similar position, several good options out there, but the best two that I've found, in my opinion, are Bucklescript (ReasonML/Ocaml) and Clojurescript. Cheers!


Why lose sleep over this considering that 0.18 still works? (Genuine question, not criticism.)


0.18 works, but compilation takes too long - and apparently that was fixed in 0.19.

We've waited for this fix a long time (over a year), but we can't upgrade because the only (AFAIK) library that connects to Elixir's Phoenix Channels stopped working. In fact the language (0.19) currently has no websocket support.

During this whole year of development, we could not compile the 0.19-dev. It was somewhere closed. We couldn't even see the commits. Pretty sure there's a nice and long post somewhere explaining how "outsiders" would slow down the progress by giving, how dare them, feedback.

We could wait a little bit more, but, even though I was deeply in love with elm, the language that made me not dread frontend development anymore, I am now totally uninterested at it, driven away by 1) lack of transparency and 2) total blocking of genuine and constructive user feedback, which feels like censorship - or simply a closed-source, proprietary software.

The language is good though. Has some minor flaws, but I believe over time they will get fixed. Though it lacks some powerful features that will never be implemented. But ovoverall, we were able to tackle complexity quite nicely. I guess we - me and my team - just got tired of how it is handled.

Oh, and Elm is way too verbose. Pretty sure that 45kloc codebase will be about 15-20kloc in cljs!


I'm sorry to hear that you are unhappy with Elm, but I hear great things about CLJS and wish you the best with it.

I have one comment and one question, if you have time to respond.

> During this whole year of development, we could not compile the 0.19-dev. It was somewhere closed.

It was on GitHub under elm/compiler on the "dev" branch, which is the branch name Evan uses for in-progress work. Many people compiled and tried it out during this time, and some left comments directly on GitHub.

This was not a secret, but I can understand that maybe it felt like one since it was not on the "master" branch.

> total blocking of genuine and constructive user feedback, which feels like censorship - or simply a closed-source, proprietary software.

I understand that you've moved on, but it would help us out if you could link to an example of genuine and constructive user feedback being blocked like this, so we can learn from it.

We've tried to lock topics that have a well-known history of devolving into unconstructive flame wars, but I'm always open to the idea that we might have missed the mark.


This is a great response. I've only recently started learning Elm (and webdev in general... coming from a systems programming background). I chose ElmConf for the preconf to strange loop this year. Why not learn a new language.

I've seen quite a few people with fairly negative things to say about the community. I had my very first thread locked on elm just a couple of days ago. Apparently there were some deleted comments that were not so nice. Unfortunately, by the time I saw my posting locked, that meant it was too late for me to engage in any sort of conversation to figure out exactly what went wrong.

Let me be clear; the core of a community are the ones responsible for creating and maintaining the culture of the community, and of course protecting the community members from abuse. I understand this... But I don't understand how stopping conversations that "have a well-known history of devolving into unconstructive flame wars". It seems that is punishing people before they've actually done anything that violates that rules of the community. At least, that's certainly how I feel.

Regardless, I'm looking forward to my journey of learning Elm and using it to build some UI's my teams are going to be needing.

As I said, I'm attending ElmConf. I look forward to meeting you and others in the Elm community.


> It seems that is punishing people before they've actually done anything that violates that rules of the community. At least, that's certainly how I feel.

That's really good feedback, thank you! I have passed this along to the moderator team.

> As I said, I'm attending ElmConf. I look forward to meeting you and others in the Elm community.

Likewise - looking forward to meeting you!

I'll be there a few days before the conference, so if you'd like to meet up ahead of time, send me a DM!


> 2) total blocking of genuine and constructive user feedback, which feels like censorship - or simply a closed-source, proprietary software.

For those looking for examples, check out the recent post on /r/elm: https://www.reddit.com/r/elm/comments/9a0hc6/elm_019_broke_u...

It was locked and deleted from the front page within hours. There are many many more such posts that have been deleted. The only posts allowed on /r/elm are those praising Elm.

They always invite the users to discuss this in the Elm Discourse which is not constructive because threads about the "forbidden" topics (Native Code) are either locked or completely deleted within hours.


> The only posts allowed on /r/elm are those praising Elm.

The Reddit thread you linked shows many posts that are critical of Elm, so this can't be the explanation.

As others have noted, you can see what was deleted using this link:

https://snew.github.io/r/elm/comments/9a0hc6/elm_019_broke_u...

Removed posts included both praise and criticism. What they have in common is that they broke other rules, e.g. personal attacks.


Thanks, I'll let everyone decide for themselves whether the deleted posts were personal attacks or not. Personally I don't see anything wrong with at least half of them.

Why do the moderators invite everyone to discuss on Discourse when you know you'll delete or lock a thread as soon as it's posted?


> Thanks, I'll let everyone decide for themselves whether the deleted posts were personal attacks or not. Personally I don't see anything wrong with at least half of them.

Okay, but "personally I would have only deleted half of those posts" is a much different claim than "The only posts allowed on /r/elm are those praising Elm," which is what you said above.

You really shouldn't make such serious claims if you don't mean them.

> Why do the moderators invite everyone to discuss on Discourse when you know you'll delete or lock a thread as soon as it's posted?

I understand that you're trolling me, but just for the record - of course we don't do that.


Ok, it's not literally "only" but most. /r/rust is a great example of healthy community. They only delete obvious troll/personal attack comments. You can go there right now and post a post similar to what you deleted on /r/elm and I bet it won't be deleted or locked.

> I understand that you're trolling me, but just for the record - of course we don't do that.

I'm not trolling. I'll bet $100 that you've at least deleted 3 threads about native code and locked at least 5. Latest example: https://discourse.elm-lang.org/t/elm-0-19-released-what-has-...

Moderator quote:

> Finally, a moderation note: I’m going to lock this thread since discussions on this topic have the unfortunate tendency to spiral out of control and we have already debated this past the point of productive return. If you have things you need to upgrade, we’re of course happy to help… let’s just do them in separate threads. :slight_smile:

Please don't suggest users of locked Reddit threads that they're welcome on Discourse. Just say the truth - you don't want any discussions about this anymore. There's no harm in being honest.


I see where you're coming from!

To me, those two mod notes are consistent and sincere. Both are saying "this particular topic has been debated to the point where discussions no longer make progress, they just take up people's time and energy. That said, by all means please feel free to start a new thread about something more specific if you'd like to discuss that."

I see this as analogous to React and JSX. When React came out, many people said "putting HTML in JavaScript is Wrong, and React shouldn't do this."

At first, whether React should use JSX was a reasonable thing to debate. In 2018, this has long since been settled. A 2018 thread arguing that React should abandon JSX is going to take up people's time but it's not going to change the outcome of a decision that was settled years ago.

This is how it is with things like Native and typeclasses in Elm. Maybe you disagree, but I think there comes a point where it's reasonable to say "it is not a good use of everyone's time to re-litigate an issue that has been settled for years. You may still disagree with the final decision, but that ship has long since sailed."

I can understand the argument that "people must be free to waste everyone's time, because anything else is tyranny" and I can also understand the argument that "the Internet is full of places to post whatever you please, but this forum is focused on collaboration, sharing, and learning, not wasting time." It seems reasonable to me for a given forum to embrace either one of those moderation philosophies.

This is why I see the two mod notes as consistent and sincere. They are both saying "these broader design decisions have long since been settled, and we're locking the topic because they are a magnet for contentious discussions that don't go anywhere. That said, you are genuinely welcome to start a fresh thread about a more specific topic to your particular situation."

Again, maybe you disagree with this moderation philosophy, but it's simply not true that mods are inviting people to post only to lock whatever the follow up would be. That would be ridiculous.


Here's a quote:

> If you'd like to discuss Elm's trade-offs, both pro and con, there are plenty of people who are willing to talk openly about them in a calm way. I'd recommend opening a thread on Elm Discourse if you're interested in that.

Please edit it to say that discussions about cons like native code will not be tolerated and will be locked or deleted without warning.


One more thing, why did you lock and delete the whole thread instead of just deleting the comments you found offensive? Was the dev.to post also something that shouldn't be discussed in Elm communities?


From what I understood:

10 posts have been deleted. 5 of them are obvious racist/spam. 5 of them are anti elm.

All anti Elm threads get deleted regardless of how much spam is also deleted


> All anti Elm threads get deleted regardless of how much spam is also deleted

From the same thread, here are several posts that are strongly critical of Elm:

1. @Sagan_on_Roids explains what he disliked about Elm and why he stopped using it: https://www.reddit.com/r/elm/comments/9a0hc6/elm_019_broke_u...

2. @eriklott agrees with the criticisms of the OP, and explains what he did after leaving Elm: https://www.reddit.com/r/elm/comments/9a0hc6/elm_019_broke_u...

3. @KittensInc curses about the state of websockets on Elm 0.19's release: https://www.reddit.com/r/elm/comments/9a0hc6/elm_019_broke_u...

4. @HelloAnyong questions why anyone would ever use Elm given its breaking changes: https://www.reddit.com/r/elm/comments/9a0hc6/elm_019_broke_u...

It's debatable whether some of the deleted posts were or weren't over the line, but it can't possibly be true that Elm mods are deleting all content that is critical of Elm.

Critical content is all over that thread, plain as daylight.


I don't think that's an entirely fair argument (although I agree that at some of these comments are easily justified for removal). Yes, there's still critical comments... In a thread that was completely hidden from the subreddit.

So the worst comments were deleted, and everything else, including the link to the blog post, hidden, and the existing participants stopped from continuing their discussion. Technically not being deleted is a small step.


The post itself was removed by moderators and locked for nothing more than being critical of Elm.


> locked for nothing more than being critical of Elm.

Why do you say that? (There was a long note explaining why it was locked.)


Total ousider here. The reason given for locking it are just points of disagreement with the article. The reason doesn't point to anything within the article that is against the subreddits rules.


Oh, I saw those as referring to the thread itself (e.g. the deleted posts). Hm.


You can use Ceddit to see the comments the moderators removed:

https://snew.github.io/r/elm/comments/9a0hc6/elm_019_broke_u...


I'm not that concerned that /r/elm is tightly moderated, given that there are other places to discuss it. (Such as here.)


Ah yes. That was the thread I started and was locked. I was and still am confused.


There are tons of bugs in 0.18 compiler and 0.18 libraries that will never be fixed. Many of those have / had pull requests by the community members open for more than a year but they were never merged. These are tiny fixes, not 200 lines of code adding a new feature. There's no way to fork a package and apply a patch in 0.19 if the package contains native code. All you can do is report the bug and hope Evan fixes it before your deadline (which ranges from 1 week to 3 years).

Edit: Using a throwaway so I don't get banned from Elm Discourse and /r/elm. I still have production applications using Elm.


> There's no way to fork a package and apply a patch in 0.19 if the package contains native code.

Yeah, if for no other reason than this I would never use Elm for a production site. The entire reason for using open source for me is being in control of the code, and not having to depend on a third party for a fix if things get bad enough.


Can someone clarify this? I've seen several references to how only a certain team can write modules using certain code.

If someone else can do it, why can't you?



> Edit: Using a throwaway so I don't get banned from Elm Discourse and /r/elm. I still have production applications using Elm.

It's pretty sad that you have to do this. Any community that has the effect of instilling such fear doesn't seem healthy to me.


I imagine because 0.19 has several backwards-incompatible changes and will probably not see updates or community interest/support.

I can't blame them - I worked on an SPA where the company used an older version of a javascript framework. After that version's docs went offline completely (they were actually for a slightly newer version with some extra functionality we couldn't use), the only existing docs were a PDF and the source code. Not a great position to be in.


> community interest/support

The community is interested but PRs for 0.18 stopped being merged months before 0.19 alpha was released. I know I'm interested in a couple of patches, I'm also willing to write the code, but I won't because there's no chance they'll be merged and released. I'm using a private fork of those packages in my app for over a year now.


I think it's just that while it works, they don't want to bet on Elm's future and would rather learn new techs.


> We have a 45kloc codebase in Elm and, despite having some big pros, the closed source development it goes through, along with the 0.19 debacle, just pushed us over the edge.

Can you clarify in concrete terms what the closed source development and 0.19 thing had cost you?


I guess I've replied on the sister thread. 0.19 was just the final push. Closed development plus complete blocking of contrary feedback just does not feel like open source. The lack of transparency removed all the trust we had in the project, and although our app is relatively big, it is still viable to change to something else - that we trust.


So it seems that it was just a matter of trust (but it is not clear what trust you were looking for) and frustration with your feedback not getting heard?


ClojureScript with re-frame is fantastic. I also use it on a production app with an Elixir backend, it's a great fit. Be sure to check out re-frisk and re-frame-10x.


I've lost touch with Elm to be honest, (been using Choo)... but hey: wouldn't it be easier (and probably better) to upgrade and use ports?


Could you go into more detail, maybe listing the pros and cons for ReasonML and ClojureScript considering your use case?


first and foremost, you get to experience figwheel, an amazing interactive tool for the repl and browser. you'll see how you and rest of the team get productive in such a short time.


Shameless plug: ocaml-vdom[1] is another implementation of TEA in OCaml (with js_of_ocaml)

[1]: https://github.com/LexiFi/ocaml-vdom


And if anyone is looking for something superior to TEA but in Haskell checkout Reflex.

http://docs.reflex-frp.org/en/latest/

"React and Elm do not offer the same concept of FRP as Reflex. Reflex offers something based on Conal Elliott's push-pull paper. Conal Elliott is the father of FRP (at least of the theory of FRP), and the semantic model he envisioned is similar to Reflex, but quite different from React/Elm. I believe his semantic model is pretty superior, and Reflex implements it quite nicely." https://www.reddit.com/r/haskell/comments/5aksxa/ghcjs_frame...


I like the Elm architecture so much we have tried to do something similar in Swift on iOS. It’s a shame it’s not possible to go all the way in (it’s quite hard to find an analogy for the DOM diffing view part), but after a year of work or so it looks like the principled state management + message-based state changes + principled side effect modelling brought us about 70–80 % of the advantages. It feels _so_ good so see the state of the app change using well-defined messages and not by ad-hoc state changes on some entangled forest of singletons. I look forward to experimenting with the architecture further. I can’t recommend it enough.


So what ties together the model, update, and view? It looks to me like it is this Browser module, is that right? Not knowing Elm or Haskell syntax, I'm guessing that Browser.sandbox is a function you call, passing in the model, update, and view functions.

Assuming that's all correct, how does Browser.sandbox, work exactly? In particular how does it know when to call Update?

At first glance it looks like it might massage the view and detect event listeners such as onClick in the button example, is that correct?


Great question! You're correct, it's the Browser module.

In Elm, the entire application state is a single immutable value, which Browser owns and only changes when it calls `update` and a new value gets returned.

Browser calls `update` in response to these 3 situations:

1. An event handler from view (e.g. `onClick Foo` means Browser will call `update`, passing `Foo` as the message, whenever that element gets clicked)

2. A subscription fires (this is kinda like #1 except for global events instead of per-element handlers)

3. A command completes, and its resulting message needs to get sent to `update`

Every interaction in Elm is modeled in terms of one of these!


Turning Html Msg types into actual Dom nodes means hooking up the event handlers so that they call update with the Msg the event handler is given. Browser.sandbox is building the Dom nodes and has the update function.


Yeah, I got that far. How does it know what it should turn into an Update handler though?


Browser.sandbox, Browser.application etc. are your app's runtimes. (Or they are the doors to the runtime)

Subscriptions or DOM elements can generate Msgs and every Msg causes an update cycle.


You pass it the update function, the one function handles all updates. Typically, you'll have a case statement in that function to dispatch it out to something more specific.


In what ways does the Elm architecture differ from MVC?


Not the Elm Architecture, but I found this a very good article on how MVC differs from unidirectional approaches: https://www.futurice.com/blog/reactive-mvc-and-the-virtual-d...


As usual, that article gets MVC wrong.

In MVC, the model-view communication is not "interactive" as defined by the article (source pushes to sink). Instead, the view pulls data from the model. There is only a general #changed notification to let the view know that the model has changed.

So "unidirectional" approaches fix the problems you get when you don't understand MVC. ¯\_(ツ)_/¯


The problems lie in the way change notifications are managed. Any reasonably complex client application will have multiple data sources feeding into a myriad of components, with a very entangled dependency graph. In MVC, you’ll start sharing models and notifying changes selectively, with a lot of “action at a distance” from component interactions triggering updates. This is usually hard to visualize and debug (worst case, recursive update loops).

In Flux/redux the unidirectional nature comes from all updates targeting and emanating from a single source (store), and being routed to views accordingly. An interaction from one component will never result in a disconnect where you failed to update the correct model(s) or to notify the right components of a change (hi Backbone.js).


> Any reasonably complex client application will

> have multiple data sources feeding into a myriad of components,

Why? Certainly my MVC apps have a single "store" that's the source of truth, and I would say that what you describe is not following the MVC pattern.


You're gonna have to provide a bit more context for that. What part of the MVC pattern?


Various parts. First, the M->V communication should only notify, the View decides if and when to refresh itself, and the action it takes is only to refresh itself.

"In this metaphor, views deal with everything graphical; they request data from their model, and display the data."[1]

Also, the View should only make a note that it needs to be refreshed (Cocoa for example has the convenient "needsDisplay" boolean property on Views), not actually do the refresh on notification. I see the latter a lot, so you have the model effectively calling refresh on the view, so pushing updates. That ain't MVC, in MVC the View pulls from the model.

"The standard interaction cycle in the Model-View-Controller metaphor, then, is that the user takes some input action and the active controller notifies the model to change itself accordingly. The model carries out the prescribed operations, possibly changing its state, and broadcasts to its dependents (views and controllers) that it has changed, possibly telling them the nature of the change. Views can then inquire of the model about its new state, and update their display if necessary."[1]

Once you're down with pushing updates, you tend to also see "optimizations" that also push the data to the view (very much what the linked article describes). Again, not MVC, View pulls, model doesn't push.

If the view only refreshes itself and pulls from the model when notified, it's hard to get an entangled dependency graph, and downright impossible to get loops.

So if you get loops, you're definitely not doing MVC.

As to the "multiple sources" feeding into a "myriad of components", that also doesn't quite match. In MVC, all sources feed into the model. When the model changes, it sends its change notification, and it doesn't really matter where the original change came from, the action afterward is the same. So if "multiple sources" are causing you problems, that is a strong indicator that you are not doing MVC, and "myriad of components" also indicates that you don't have a strongly developed model.

[1] https://web.archive.org/web/20100921030808/http://www.itu.dk...


Don't know why you are getting downvoted, MVC is the combination of the observer and strategy patterns, no more, no less.

All the pieces have a single responsibility, the view reacts to model changes and redraw itself, the controller executes the business logic on UI events and the model to broadcast events when its state has/was changed by the controller. Data flows only in one direction.


How would you compare React to Vue in regards to the linked article? I have not used React, but in Vue I have never run into things like "setState, forceUpdate, setProps, render".

It would seem that React runs quite differently than Vue deep under the hood, am I missing something?

I appreciated the alternative view from the article, as I like to know where things are going, and his criticisms of React seemed valid, but I am new enough to this environment to need clarifications on complex claims.


If anyone wants the Elm architecture in JavaScript there is Raj: https://jew.ski/raj/

I spent over a year building the framework and a set of libraries around it so that the architecture feels natural to JavaScript developers.

There's only a few of us building apps with it right now, but the stories for doing most anything are covered and as of 2 months ago the framework hit 1.0. It is a safe foundation to build on as I don't plan to ever change it.


Huh, I must say I thought there was more to Elm's architecture (I've seen it mentioned in the recent negative article about Elm).

I've written an SPA[1] recently in a framework that is quite flexible and also ended up using a very similar architecture.

1 - https://github.com/nim-lang/nimforum


This is just model-view-controller except Evan is taking credit for inventing it.


Yesterday's submission on Elm with interesting discussion in comments: https://news.ycombinator.com/item?id=17842400




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: