1. 25

    I’d like to provide a more sympathetic outside perspective.

    There are a few common complaints about Elm and Elm community:

    • Blocking discussion (locking threads etc.)
    • Insufficient communication about Elm development
    • Things getting removed from the language.

    With regards to blocking discussion, I think the logic is something like this:

    • The core developers have a roadmap for Elm development and they want to stick to it
    • They tried including more developers but haven’t found an effective way to deal with more contributors
    • Therefore, they have limited time
    • They can spend this time rehashing the same arguments and debating half-baked ideas, or they can spend this time following their roadmap, but not both.

    I would prefer that the discussions weren’t removed or locked, but on the other hand, it’s got to be grating to deal with the same entitled, uninformed or complaining comments all the time. I’ve read most of these discussions, and other than people venting, nothing is ever achieved in them. My reflexive reaction is to be uncomfortable (like a lot of other people) but then, there is also a certain clarity when people just say that they will not engage in a discussion.

    With regards to insufficient communication, I think the main things to understand is that Elm is an experiment in doing things differently, and it’s causing a clash with conventional understanding. Elm is about getting off the upgrade treadmill. So, for example, when a new release like Elm 0.19 comes out, it happens without a public alpha and beta phases, and it’s not actually the point where you go and immediately migrate your production code to it! It’s only the point to start experimenting with it, it’s the point where library and tool authors can upgrade and so on. (There was quite a bit of activity prior to release anyway, it just wasn’t advertised publicly.)

    Finally, the most contentious example of a “feature” getting removed is the so called native modules (which basically means the ability to have impure functions written in JS in your Elm code base). As far as I can tell (having followed Elm since 0.16), native modules were always an internal implementation detail and their use was never encouraged. Nevertheless, some people started using them as a shortcut anyway. However, they were a barrier to enabling function-level dead code elimination which is the main feature of the 0.19 release, so the loophole was finally closed. Sure, it’s inconvenient for people who used them, but does anyone complain when, say, Apple removes an internal API?

    Ultimately, Elm is just an open source project and the core maintainers don’t really owe anybody anything - no contracts are entered into and no funds are exchanged. They can do whatever they want.

    Of course, there is a question of the long term effects this approach is going to have on the community. Will it alienate too many people and cause Elm to wither? Will Elm remain a niche language for a narrow class of applications? That remains to be seen.

    1. 19

      but on the other hand, it’s got to be grating to deal with the same entitled, uninformed or complaining comments all the time.

      Over the years, I have come to believe this is a vital part of building a community. Using draconian tactics to stomp out annoying comments is using power unwisely and worse yet – cripples your community in multiple ways.

      The first thing to remember is that when a comment (entitled, uninformed or otherwise) comes up repeatedly – that is a failure of the community to provide a resource to answer/counter/assist with that comment. That resource can be a meme, a link, an image, a FAQ, a full on detailed spec document, whatever. This type of thing is part of how a community gets a personality. I think a lot of the reason there are a bunch of dead discourse servers for projects is too stringent policing. You should have a place for people to goof off and you have to let the community self police and become a real community. Not entirely, obviously, but on relevant topics.

      This constant repetition of questions/comments is healthy, normal, it is the entrance of new people to the community. More importantly, if gives people who are just slightly deeper in the community someone to help, someone to police, someone to create resources for, even to a degree someone to mock (reminding them they aren’t THAT green anymore) – a way to be useful! This is a way to encourage growth, each “generation” of people helps the one that comes after them – and it is VITAL for building up a healthy community. In a healthy community the elders will only wade in occasionally and sporadically to set the tone and will focus on the more high minded, reusable solutions that move the project forward. Leave the minor stuff be done by the minor players, let them shine!

      Beyond being vital to build the community – it is a signal of where newcomers are hurting. Now if documentation fixes the problem, or a meme… terrific! But if it doesn’t, and if it persists … that is a pain point to look at – that is a metric – that is worth knowing.

      1.  

        Yeah, each one of these people gives you a chance to improve how well you communicate, and to strengthen your message. But shutting down those voices then run the risk of surrounding yourself with ‘yes people’ who don’t challenge your preconceptions. Now, it’s entirely up to the Elm people to do this, but I think they are going to find it harder to be mainstream with this style of community.

        Note that I’m perfectly fine with blocking and sidelining people who violate a CoC, or are posting hurtful, nonconstructive comments. You do have to tread a fine line in your moderation though. Being overly zealous in ‘controlling the message’ can backfire in unpredictable ways.

        Anyway, I continue to follow Elm because I think the designer has some excellent ideas and approaches, even if I do disagree with some of the ways the way the community is managed.

        1.  

          even if I do disagree with some of the ways the way the community is managed.

          I don’t think the two jobs (managing the community and managing the project) should necessarily be done by the same person. I actually think it probably shouldn’t. Each job is phenomenally challenging on its own – trying to do both is too much.

          1.  

            Yeah, completely agree! I think it would take a huge weight of that person’s shoulders too! :)

            1.  

              I don’t think Evan personally moderates the forums. Other people do it these days.

              1.  

                But, they do it on his behalf? This policy of locking and shutting down discussions comes from somewhere. That person directly or indirectly is the person who “manages” the community, the person who sets the policies/tone around such things.

                I personally have no idea, I am not active in the Elm community.

                1.  

                  I’m not sure who sets the policy and how.

          2.  

            That’s a very interesting perspective, thanks.

          3. 10

            I’ll add the perspective of someone who loved Elm and will never touch it again. We’re rewriting in PureScript right now :) I’m happy I learned Elm, it was a nice way of doing things while it lasted.

            In Elm you may eventually hit a case where you can’t easily wrap your functionality in ports, the alternative to native modules. We did, many times. The response on the forum and other places is often to shut down your message, to give you a partial version of that functionality that isn’t quite what you need, to tell you to wait until that functionality is ready in Elm (a schedule that might be years!), or until recently to point you at native modules. This isn’t very nice. It’s actually very curious how nice the Elm community is unless you’re talking about this feature, in which case it feels pretty hostile. But that’s how open source rolls.

            Look at the response to message linked in the story: “We recently used a custom element to replace a native modules dealing with inputs in production at NoRedInk. I can’t link to it because it’s in a proprietary code base but I’ll be writing an speaking about it over the next couple months.”

            This is great! But I can’t wait months in the hope that someone will talk about a solution to a problem I have today. Never mind releasing one.

            Many people did not see native modules as a shortcut or a secret internal API. They were an escape valve. You would hit something that was impossible without large efforts that would make you give up on Elm as not being viable. Then you would overcome the issues using native modules which many people in the community made clear was the only alternative. Now, after you invest effort you’re told that there’s actually no way to work around any of these issues without “doing them the right way” which turns out to be so complicated that companies keep them proprietary. :(

            I feel like many people are negative about this change because it was part of how Elm was sold to people. “We’re not there yet, but here, if we’re falling short in any way you can rely on this thing. So keep using Elm.”

            That being said, it feels like people are treating this like an apocalypse, probably because they got emotionally invested in something they like and they feel like it’s being changed in a way that excludes them.

            You’re right though. Maybe in the long term this will help the language. Maybe it will not. Some people will enjoy the change because it does lead to a cleaner ecosystem and it will push people to develop libraries to round out missing functionality. In the short term, I have to get things done. The two perspectives often aren’t compatible.

            I’m personally more worried about what will happen with the next major change where Elm decides to jettison part of its community. I don’t want to be around for that.

            1.  

              If people encouraged you to use native modules, then that was unfortunate.

              I’m not sure I understand the issue with custom elements. Sure, they’re a bit complicated and half baked but it certainly doesn’t require a research lab to use them (in fact, I’ve just implemented one now).

              I would agree, however, that the Elm developers have a bit of a hardline approach to backward compatibility. Perhaps there is a misunderstanding around the state of Elm - ie whether it’s still an experiment that can break compatibility or a stable system that shouldn’t.

              I’m not sure how I feel about backward compatibility. As a user, it’s very convenient. As a developer, it’s so easy to drown in the resulting complexity.

            2. 9

              I would prefer that the discussions weren’t removed or locked, but on the other hand, it’s got to be grating to deal with the same entitled, uninformed or complaining comments all the time. I’ve read most of these discussions, and other than people venting, nothing is ever achieved in them. My reflexive reaction is to be uncomfortable (like a lot of other people) but then, there is also a certain clarity when people just say that they will not engage in a discussion.

              I’ll go one further and say I’m quite glad those discussions get locked. Once the core team has made a decision, there’s no point in having angry developers fill the communication channels the community uses with unproductive venting. I like the decisions the core team is making, and if those threads didn’t get locked, I’d feel semi-obligated to respond and say that I’m in favor of the decision, or I’d feel guilty not supporting the core devs because I have other obligations. I’m glad I don’t have to wade through that stuff. FWIW, it seems like the community is really good at saying “We’re not going to re-hash this decision a million times, but if you create a thread about a specific problem you’re trying to solve, we’ll help you find an approach that works” and they follow through on that.

              I don’t have a lot of sympathy for folks who are unhappy with the removal of the ability to compile packages that include direct JS bindings to the Elm runtime. For as long as I’ve been using Elm the messaging around that has consistently been that it’s not supported, it’s just an accidental side effect of how things are built, and you shouldn’t do it or you’re going to have a bad time. Now it’s broken and they’re having a bad time. This should not be a surprise. I also think it’s good decision to actively prohibit it. If people started using that approach widely, it would cause a lot of headaches for both the community and hamstring the core team’s ability to evolve the language.

              1. 6

                I’m quite glad those discussions get locked

                and

                I like the decisions the core team is making

                Do you believe your perspective would change if you didn’t agree with the developers decisions? Obviously I have a different perspective but I am curious if think you would still have this perspective if you were on the other side?

                Additionally, just because the core team has “made a decision” doesn’t mean it wasn’t a mistake, nor that it is permanent. Software projects make mistakes all the time, and sometimes the only way to really realize the mistake is the hear the howls of your users.

                1.  

                  I’m pretty confident I wouldn’t change my position on this if I wasn’t in agreement with the core team’s choices. I might switch to PureScript or ReasonML, if I think the trade-offs are worth it, but I can’t see myself continuing to complain/vent after the decision has been made. I think appropriate user input is “I have this specific case, here’s what the code look like, here’s the specific challenge with any suggested alternative” If the core team decides to go another way after seeing their use cases, it’s clear we don’t have the same perspective on the trade-offs for those decisions. I can live with that. I don’t expect everybody to share my opinion on every single technical decision.

                  As an example, I use Clojure extensively at work, and I very much disagree with Rich Hickey’s opinions about type systems, but it’s pretty clear he’s thought through his position and random folks on the internet screaming differently isn’t going to change it, it’ll just make his job more difficult. I can’t imagine ever wanting to do that to someone.

                  sometimes the only way to really realize the mistake is the hear the howls of your users

                  It’s been my experience that the folks who can provide helpful feedback about mistaken technical decisions rarely howl. They can usually speak pretty clearly about how decisions impact their work and are able to move on when it’s clear there’s a fundamental difference in goals.

                  1.  

                    It’s been my experience that the folks who can provide helpful feedback about mistaken technical decisions rarely howl.

                    We fundamentally disagree on this point (and the value of the noisy new users), and I don’t think either of us is going to convince the other. So, I think this is a classic case of agree to disagree.

              2. 10

                I think what bothers me the most about the core team’s approach to features is not that they keep removing them, but that for some they do not provide a valid alternative.

                They’ll take away the current implementation of native modules, but coming up with a replacement is too hard, so even though the core libraries can use native code, us peasants will have to do without.

                They won’t add a mechanism for higher rank polymorphism because coming up with a good way to do it is hard, so even though the base library has a few magic typeclasses for its convenience, us peasants will have to make do with mountains of almost duplicated code and maybe some code generation tool.

                So where does that leave Elm right now? Should it be considered a production-ready tool just by virtue of not having very frequent releases? Or should it be regarded as an incomplete toy language, because of all the breaking changes between releases, all the things that haven’t been figured out yet, and how the response to requests for ways to do things that are necessary in real code is either “you don’t need that”, which I can live with most of the time, or “deal with it for the moment”, which is unacceptable.

                I think Elm should make it more clear that it’s ostensibly an unfinished project.

                1.  

                  They’ll take away the current implementation of native modules, but coming up with a replacement is too hard

                  They won’t add a mechanism for higher rank polymorphism because coming up with a good way to do it is hard

                  I don’t think this is a fair characterization of the core team’s reasons for not supporting those features. I’ve read/watched/listened to a lot of the posts/videos/podcasts where Evan and other folks discuss these issues, and I don’t think I’ve ever heard anyone say “We can’t do it because it’s too difficult.” There’s almost always a pretty clear position about the trade-offs and motivations behind those decisions. You might not agree with those motivations, or weigh the trade-offs the same way, but it’s disingenuous to characterize them as “it’s too hard”

                  1.  

                    I exaggerate in my comment, but what I understood from the discussions around rank n polymorphism I’ve followed is basically that Evan doesn’t think any of the existing solutions fit Elm.

                    I understand that language design, especially involving more complex features like this, is a hard issue, and I’m sure Evan and the core team have thought long and hard about this and have good reasons for not having a good solution yet, but the problem remains that hard things are hard and in the meantime the compiler can take an escape hatch and the users cannot.

                  2.  

                    Should it be considered a production-ready tool just by virtue of not having very frequent releases? Or should it be regarded as an incomplete toy language

                    I always struggle with this line of questioning because “incomplete and broken” describes pretty much all of the web platform in the sense that whenever you do non-trivial things, you’re going to run into framework limitations, bugs, browser incompatibilities and so on.

                    All you can do is evaluate particular technologies in the context of your specific projects. For certain classes of problems, Elm works well and is indeed better than other options. For others, you’ll have to implement workarounds with various degrees of effort. But again, I can say the same thing for any language and framework.

                    Is it good that it’s so easy to bump up against bugs and limitations? No. But at least Elm is no worse than anything else.

                    Taking a tangent, the main problem is that Elm is being built on top of the horrifically complex and broken foundation that is the web platform. It’s mostly amazing to me that anything works at all.

                    1. 7

                      To me the problem is that Elm is not conceptually complete. I listed those issues specifically because they’re both things that the compiler and the core libraries can do internally, but the users of the language cannot.

                      But at least Elm is no worse than anything else.

                      No, Elm is a language, and not being able to do things in a language with so few metaprogramming capabilities is a pretty big deal compared to a missing feature in a library or a framework, which can easily be added in your own code or worked around.

                      1.  

                        But how is this different from any other ecosystem? The compiler always has more freedom internally. There are always internal functions that platform APIs can use but your library cannot. Following your logic, we should condemn the Apple core APIs and Windows APIs too.

                        1.  

                          No, what I meant is that the core libraries use their “blessed” status to solve those problems only for themselves, thus recognizing that those problems effectively exist, but the users aren’t given any way to deal with them.

                          1.  

                            But there are actually solutions on offer: ports and custom elements. What’s wrong with using them?

                            1.  

                              Ports are very limiting and require much more work to set up than a normal library, and I haven’t used custom elements so I can’t speak for those.

                              There’s also no workaround for the lack of ad-hoc polymorphism. One of the complaints I hear the most about Elm is that writing json encoders and decoders is tedious and that they quickly become monstrously big and hard to maintain; often the json deserialization modules end up being the biggest modules in an Elm project.

                              This is clearly a feature the language needs (and already uses with some compiler magic, in the form of comparable, appendable, and so on).

                      2. 7

                        Is it good that it’s so easy to bump up against bugs and limitations? No. But at least Elm is no worse than anything else.

                        Having worked with ClojureScript on the front-end for the past 3 years, I strongly disagree with this statement. My team has built a number of large applications using Reagent and whenever new versions of ClojureScript or Reagent come out all we’ve had to do was bump up the versions. We haven’t had to rewrite any code to accommodate the language or Reagent updates. My experience is that it’s perfectly possible to build robust and stable tools on top of the web platform despite its shortcomings.

                        1.  

                          I think the ease of upgrades is a different discussion. There is a tool called elm-upgrade which provides automated code modifications where possible. That’s pretty nice, I haven’t seen a lot of languages with similar assistance.

                          My point was, you cannot escape the problems of the web platform when building web applications. Does ClojureScript fully insulate you from the web platform while providing all of its functionality? Do you never run into cross-browser issues? Do you never have to interoperate with JavaScript libraries? Genuinely asking - I don’t know anything about ClojureScript.

                          1.  

                            My experience is that vast majority of issues I had with the web platform went away when my team started using ClojureScript. We run into cross-browser issues now and then, but it’s not all that common since React and Google Closure do a good job handling cross-browser compatibility. Typically, most of the issues that we run into are CSS related.

                            We interoperate with Js libraries where it makes sense, however the interop is generally kept at the edges and wrapped into libraries providing idiomatic data driven APIs. For example, we have a widgets library that provides all kinds of controls like data pickers, charts, etc. The API for the library looks similar to this to our internal widgets API.

                            1.  

                              Sounds like a great development experience!

                              Let me clarify my thinking a bit. For a certain class of problems, Elm is like that as well. But it certainly has limitations - not a huge number of libraries etc.

                              However, I think that pretty much everything web related is like that - limitations are everywhere, and they’re much tighter than I’d like. For example, every time I needed to add a date picker, it was complicated, no matter the language/framework. But perhaps your widgets library has finally solved it - that would be cool!

                              So I researched Elm and got a feel for it’s limitations, and then I could apply it (or not) appropriately.

                              I would agree, however, that the Elm developers have a bit of a hardline approach to backward compatibility. Perhaps there is a misunderstanding around the state of Elm - ie whether it’s still an experiment that can break compatibility or a stable system that shouldn’t.

                              I’m not sure how I feel about backward compatibility. As a user, it’s very convenient. As a developer, it’s so easy to drown in the resulting complexity.

                              1.  

                                Yeah, I agree that the main question is around the state of Elm. If the message is that Elm isn’t finished, and don’t invest into it unless you’re prepared to invest time into keeping up, that’s perfectly fine. However, if people are being sold on a production ready language that just works there appears to be a bit of a disconnect there.

                                It’s obviously important to get things right up front, and if something turns out not to work well it’s better to change it before people get attached to it. On the other hand, if you’re a user of a platform then stability is really important. You’re trying to deliver a solution to your customers, and any breaking changes can become a serious cost to your business.

                                I also think it is important to be pragmatic when it comes to API design. The language should guide you to do things the intended way, but it also needs to accommodate you when you have to do something different. Interop is incredibly important for a young language that’s leveraging a large existing ecosystem, and removing the ability for people to use native modules in their own projects without an alternative is a bit bewildering to me.

                          2.  

                            I have the opposite experience. Team at day job has some large CLJS projects (also 2-3 years old) on Reagent and Re-Frame. We’re stuck on older versions because we can’t update without breaking things, and by nature of the language it’s hard to change things with much confidence that we aren’t also inadvertently breaking things.

                            These projects are also far more needlessly complex than their Elm equivalents, and also take far longer to compile so development is a real chore.

                            1.  

                              Could you explain what specifically breaks things in your project, or what makes it more complex than the Elm equivalent. Reagent API had no regressions in it that I’m aware of, and re-frame had a single breaking change where the original reg-sub was renamed to reg-sub-raw in v 0.7 as I recall. I’m also baffled by your point regarding compiling. The way you develop ClojureScript is by having Figwheel or shadow-cljs running in the background and hotloading code as you change it. The changes are reflected instantly as you make them. Pretty much the only time you need to recompile the whole project is when you change dependencies. The projects we have at work are around 50K lines of ClojureScript on average, and we’ve not experienced the problems you’re describing.

                      3.  

                        I was hoping to read other points of view on that matter, thanks for taking the time writing down yours!

                      1. 3

                        I don’t know if language choice has anything to do with it, but the fact remains: the service is now dead. ;)

                        I agree in 2012 the state of Python3 support was a valid concern, and I have to admit actively discouraging people from learning it at the time, but luckily that part hasn’t aged well. I still want better FP support in Python of course.

                        My biggest problem with Common Lisp is that it’s a Lisp-2. Why would anyone want different namespaces for functions and other bindings in an ostensibly functional language?

                        1. 3

                          Why would anyone want different namespaces for functions and other bindings in an ostensibly functional language?

                          According to this site, one of the arguments was “backwards compatibility”:

                          Common Lisp was the result of a compromise between a number of dialects of Lisp, most of which had separate namespaces.. [transitioning to a single namespace] would introduce a considerable amount of incompatibility..” There are really more than two namespaces, reducing either the benefit of collapsing these two or the cost of collapsing them all

                          which I don’t find that convincing, since there were plenty of lisps using dynamic scoping, despite CL using lexical scopes. But I agree, things like these together with, frankly wierd function names always annoy me. I’d guess that in the end, CL shouldn’t be seen as a functional language, since Lisp wasn’t even originally conceived as functional language.

                          1. 9

                            I’d guess that in the end, CL shouldn’t be seen as a functional language, since Lisp wasn’t even originally conceived as functional language.

                            There’s a page which I can’t find now which makes the case that the term “functional programming language” evolves over time to mean “the most functional programming language which currently exists”, so different features rotate in and out of defining what it effectively means to be a functional programming language.

                            (I’d add that each generation has a different boogeyman idea, an idea which the Average Programmer regards as being “too complex” and which others write blog posts or the local equivalent to explain.)

                            The first generation was when Algol introduced recursion. Recursion is also the boogeyman idea of this era.

                            The second generation begins with “mature” Lisp (that is, Lisp implementations like MACLISP and Lisp Machine Lisps, not LISP 1.5) and, later, Scheme, where the defining feature is first-class functions and closures, and the boogeyman idea is Scheme’s continuations. Common features are strong dynamic typing and a universal feature is garbage collection. The new-school scripting languages (Perl, Python, Ruby) are languages of this type with object systems bolted on, and Java’s getting there, slowly.

                            (Some pre-Common Lisp Lisps didn’t have closures. They had the upwards funarg problem, instead.)

                            The third generation is ML and everything after, including OCaml and Haskell. Now, functional programming includes strong, static type systems with algebraic types, Hindley-Milner type inference, and, at a syntactic level, pattern-matching as flow control. The boogeyman idea is monads, and, more specifically, requiring the use of monads to mark out side-effecting code, as Haskell does.

                            The underlying point is that “Functional programming is whatever your language of choice doesn’t have yet”: Recursion is now universal. It wasn’t when FORTRAN IV was “your language of choice” for a lot of programmers. Strong dynamic typing and garbage collection aren’t universal, but they’re not weird and wacky ideas only long-haired MIT AI Lab types can make sense of. Marking your side-effecting code in a machine-readable way is still weird and wacky… for now.

                            1. 1

                              I wonder why backwards compatibility was a concern if CL could not run any of that old code unmodified. Ot could it?

                              1. 2

                                Common Lisp could be implemented in terms of the Old Lisps with a library of functions and macros. That’s the kind of compatibility they were after.

                                1. 1

                                  I’m pretty sure backwards compatibility with most existing implementations was exactly the goal. I’ve heard you can run early Lisp programs on CL with minimal modifications to this day, but I’ve never tried it myself.

                              2. 2

                                It might be slightly easier to write tooling when you know what’s a function and what’s a variable.

                                On the other hand, if you use a Lisp-2 in functional style (which poorly suits Common Lisp), you still have the problem of full analysis between the boundary of namespaces + awkward syntax. It looks like Common Lisp is meant to be used in imperative style, without juggling functions as values.

                                1.  

                                  Yeah, I guess it’s my expecation that the language is supposed to be functional that makes lisp-2 look so disappointing for me. It technically has everything for FP to work, so I feel cheated. ;)

                                2. 1

                                  Does it really pose a significant problem?