The Principles of PureScript


I think it would be good to try to nail down the principles which have guided the development of PureScript so far, so that we can reference them.

After some discussion on Slack, we came up with these principles:

1. The compiler is not the place for preferences. That’s what tooling is for.

This principle could be rephrased as “be as unopinionated as possible about the way in which users use our tools”. It encourages us to push decisions downstream to tools and libraries, and to avoid a runtime or an enforced standard library.

2. The meaning of a composition of programs is the composition of their meanings.

This principle is nabbed from Conal Elliott’s type class morphisms work, but it is a nice way of summarizing “predictable codegen”. It also enables things like incremental compilation.

3. Prefer fewer, more powerful features, to many special-purpose ones.

Do you agree with these? What other principles do we want to keep?

Edit: here are some more, collected from the comments:

4. It is better if the compiler implementation is simple and easily understood, than to add many features of limited utility which might complicate the implementation.


Is there an example where this fails?


I think for our purposes, it’s a nicer way of saying “no magic in the compiler”, in the sense that the compiler should, if possible, determine its output only from the output of the function on the immediate subexpressions of an expression. It can’t go digging deep inside an expression to determine what it should do.

This is maybe less of a principle and more of a necessity, actually, in that almost any violation of it will probably result in a bug.


I think a major part of the guiding development and success of the PureScript compiler is that the output of the compiler is relatively understandable. Maybe you should add that as a principle?

Also, I’m curious to know which principle, or if you’d like to add a new one, would affect decisions when considering adding relatively unfamiliar features to Haskell-like languages, like first-class modules.


How the language evolves from here on is somewhat separate I think. I think it is possible to add new features which are consistent with any principles we might decide on. Whether we should at this point, or how quickly, is another question. I think it is almost essential that we stop adding new features now, and let documentation catch up, including a language spec.

PS future - new features vs documentation & spec

I think a principle which we have followed - at least in how we approach development of the compiler - is that we want to keep the implementation simple and understandable. If something seems like it would be nice but not essential, and it’s not clear how to do it without adding lots of complex code or complicating some existing API, I think we have generally opted not to do it.


Yes, good point. I’m going to keep track of these at the top.


I think “opinions” isn’t quite right, but rather “preferences”. If some knob or switch boils down to a user preference, we try to push it on tooling.