example-based language design

108 views
Skip to first unread message

Jeff Smits

unread,
Apr 30, 2015, 10:46:57 PM4/30/15
to elm-discuss

So far Elm has been developed based on problems/solutions with clear examples showing the before/after. This has been a great help in keeping discussions focussed and the language simple and down-to-earth. But I’m worried.

What if this example based approach will only bring our attention to low hanging fruit? I do think there are problems that are hard to capture in small examples. Like the code duplication vs type system complexity discussion, where showing a real duplication problem will take a huge amount of effort and it’s hard to come up with a proper example that can’t be hacked around. And then also still fit what most people think Elm’s focus is.

Now this may not be the time to start introducing more complex things to the language when the user base isn’t agreeing on whether code duplication is a growing problem. But are we quite sure that if it does become a problem, people will be willing to spend a lot of time to come up with more convincing examples? I’m afraid people might leave because of their impression that Elm is not suitable for larger systems. I think getting new users for Elm is not a huge problem right now. We’re on the right course, people are evangelising etc. But keeping those who gain an interest requires not only a nice ecosystem for larger programs, but also a language that accommodates the right things.

I’m not sure where I’m going with this, but I’m concerned by the general idea that example-driven design will only get us low-hanging fruit. That we should also consider larger and longer-term goals that may not come up in the form of simple examples. So I’m sharing my thoughts. Mostly for Evan’s benefit, but there are other knowledgeable PL people subscribed to this mailing list, so perhaps they can share their thoughts and experiences?

Evan Czaplicki

unread,
May 1, 2015, 12:14:02 AM5/1/15
to elm-d...@googlegroups.com
Let's say there are 10 things I can focus on in varying degrees. Here are some things on my mind at the moment:
  • Better error messages
  • Improvements to elm-package
  • Testing
  • Animations
  • Concurrency
  • More task libraries
  • Writing blog posts
  • Working on documentation
  • Finishing the website overhaul
  • Making improvements to elm-reactor
  • Going to conferences, doing workshops
  • Talking with companies directly
  • HKP and Rank2 types
  • Responding to new users on elm-discuss
How can you prioritize between these things?

One way is to listen to active commercial users. If they run into a certain problem, get an example and figure out how to solve it. Another way is to be driven to make cool blog posts. Feature X will be a great release, it'll drive a lot of traffic and interest! Another way is to listen to people on the list and at conferences, see what they find hard and try to make it easier. Another is to trust my intuition about what I need and what I am excited about. All of these have tradeoffs and must be balanced against each other.

One thing to keep in mind balancing all of this is making sure you don't close any doors by accident. You can't do it all today, but plan such that you can do it all eventually. HKP and Rank2 types are this way. I did that on purpose.

Now let's suppose people run into real issues in large code bases because they really need to say (forall a. a -> b). I don't believe Java has this feature, but they seem to be okay. F# does not have this feature, but they seem to be okay. In any case, let's assume it happens. Their code base is a massive demonstration of the need. This will also be a signal that "now is the right time to do this" because the community will be at a point where we can say "hey, you know that 10,000 line thing you have, this is how you make it 100,000 lines." Suddenly you have a great success story to tell.

Clojure did transducers relatively recently. They are maybe 8 years in and people are writing big stuff. The community saw the value of transducers and thought it was great. The big message here is that solving the problem at the right time is a big deal. It's the difference between a controversial choice, a widely praised choice, and a too-little-too-late choice. By managing timing, you also set the tone of the language. "Clojure is easy, now it has transducers." That could have been "Clojure has always had some tough concepts, but you'll get through it."

Another question to ask is "will adding HKP and Rank2 types solve the problem in the best way?" What exactly will that look like in practice? Will the result feel nicer? What are the secondary effects of adding this feature? Do they feel nicer? None of this is easy to figure out, and it is way way harder when your don't have many concrete problems you are solving. With tasks for example, I knew like 20 concrete things I wanted to do. I could draft those APIs and try to foresee any meta-effects they would have on other parts of the language. I also knew from everyone interested in using Elm professionally that they needed this

So I return to the question, how do you prioritize between the 10 things? We know that the door is open for HKP and Rank2 and that being strategic about timing can be really helpful to how people perceive a language. We know it will probably actively discourage some potential users, and we know that there are tons of other tasks that are widely helpful and attract newcomers.

I don't understand what is confusing about this. I don't see why people think I haven't thought this through.

--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Evan Czaplicki

unread,
May 1, 2015, 12:51:45 AM5/1/15
to elm-d...@googlegroups.com
Sorry to end the email in that way. I am kind of frustrated by this topic, but I should not take that out on other people.

I should say instead, does this reasoning make sense? Does this give you more confidence that the right prioritization decision is being made here? If not, I would like to know if there are risks I do not seem to be taking into account that could drastically change prioritization. One is that "it'll be hard to add later" which I think is false since everything is namespaced nicely. Adding Generic.map is no problem. In any case, maybe there is something else.

Jeff Smits

unread,
May 1, 2015, 1:07:40 AM5/1/15
to elm-discuss

I didn't mean to make this about the fancy types specifically, it's just the point where I started wondering about all of this. It was just an example :P

The reason I was a little worried is because you never explicitly shared this kind of message about how you think things through when you prioritise. You always share bits of the process but never an overview like this. I'm now confident that you know exactly what you're doing.
I mean, obviously you're smart and competent, otherwise Elm wouldn't be such a success. But I also remember how you were still figuring some of this out, this leading of an open source project, around the time I first joined the mailing list. So that image was still in my head somewhere.

Thanks for explaining a little more about how you work. I'm not worried about the example-driven approach any more.

Hassan Hayat

unread,
May 1, 2015, 7:19:32 AM5/1/15
to elm-d...@googlegroups.com
Now let's suppose people run into real issues in large code bases because they really need to say (forall a. a -> b). I don't believe Java has this feature, but they seem to be okay.

I'd just like to point out that Java didn't have closures until really recently and people were "okay" with it mainly cuz they didn't know what they were missing. You know, in Java you don't "really" need them because you can always define a static method of some "utils" class and there's your function.

This is not a criticism but it's just to point out that it may not be that easy to generate example for a feature that may be useful, which mirrors what Jeff said about pointing out only the low hanging fruit.

That said, of that list, were I you, I'd focus on the basics. Testing, animations, task libraries, error messages, tooling... For example, it's easier to improve the error messages while the language features are small. Suppose that you do end up adding rankntypes, higherkindedtypes, and typeclasses and only then decide to improve error messages. That just sounds super super hard. No wonder Haskell has weird error messages. I think they focused too much on the features and very little on the usability. But on the other hand, you do have a chance of producing good error messages if they're worked on now while the type system is simple. Then you can add rankntypes and improve the error messages only for that... and then HKT and add error messages for that, etc...
Reply all
Reply to author
Forward
0 new messages