Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign upPhantom Types (contributors, please take note!) #375
Comments
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
tolgap
Feb 20, 2018
Collaborator
@rtfeldman Doesn't this commit elm/compiler@5fb82e2 "break" phantom types?
type Value a -- `a` is now an unbound type variable error?
= Value String|
@rtfeldman Doesn't this commit elm/compiler@5fb82e2 "break" phantom types? type Value a -- `a` is now an unbound type variable error?
= Value String |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rtfeldman
Feb 20, 2018
Owner
according to Evan:
It’s the same as 0.18
type F = A a | B bis the bad thing
buttype F a b = A | Bis still allowed
|
according to Evan:
|
rtfeldman
changed the title from
Phantom Values (contributors, please take note!)
to
Phantom Types (contributors, please take note!)
Mar 22, 2018
This was referenced Mar 30, 2018
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
owanturist
Apr 22, 2018
@rtfeldman could you add link to the issue at README? Maybe on the top that contributors see it first.
owanturist
commented
Apr 22, 2018
|
@rtfeldman could you add link to the issue at README? Maybe on the top that contributors see it first. |
This comment has been minimized.
Show comment
Hide comment
This comment has been minimized.
rtfeldman
Apr 22, 2018
Owner
@owanturist Added to ISSUE_TEMPLATE.md and PULL_REQUEST_TEMPLATE.md in 3fd1142
|
@owanturist Added to |
rtfeldman commentedDec 25, 2017
•
edited
Edited 7 times
-
rtfeldman
edited Mar 22, 2018 (most recent)
-
rtfeldman
edited Dec 28, 2017
-
rtfeldman
edited Dec 28, 2017
-
rtfeldman
edited Dec 25, 2017
-
rtfeldman
edited Dec 25, 2017
-
rtfeldman
edited Dec 25, 2017
-
rtfeldman
edited Dec 25, 2017
I'm working on having
Css.Valueuse phantom types. (More on what this means below.)If you're using
elm-css, you may not even notice this change when it comes out (except that you may notice things running faster), but if you're contributing to currentmaster, this will almost certainly lead to merge conflicts - so watch out! Any large PR will likely need numerous changes once this is finished, and I would strongly recommend opening an issue before making a PR so we can coordinate.You can follow progress on the😅
phantom-typesbranch. This one is gonna take awhile to finish.The Change
On current
master,Css.Valueis defined like this:On the
phantom-valuesbranch it's instead defined like this:A union type with a type variable which doesn't appear in any constructors is known as a phantom type. I'm somewhat annoyed that they have such a cool name, because it makes me feel like I should use them more often...when in reality, they are useful under very rare circumstances.
However,
elm-csshappens to be one of them!What the phantom type lets us do is move our compatibility information from runtime values to compile-time values. For example:
This can now become:
The difference is subtle, but impactful. We still get all the same compile-time verification as before, but whereas before we actually had to instantiate all those fields in real objects, the runtime representation of
Valueis now always a singleStringconstructor:type Value a = Value String. All the compatibility checking information now exists at compile time only.If that were the only part of the refactor, though, that wouldn't be a terribly big change. The big change is shifting around how the extensible records work.
Much Nicer Error Messages
Credit to @ianmackenzie for showing me this. Switching around which records are extensible and which ones are not can result in much nicer documentation and compile-time error messages for
elm-css!For example, let's consider how
colorandrgbinteract.Status Quo
Here's how these are defined right now.
After the Change
Here's how they're defined on the
phantom-valuesbranch.The first benefit of this is that its type signature is much more useful than before.
What can I pass to the
colorfunction? Values returned byrgb,rgba,hsl,hsla, andhex, just like it says incolor's type signature. I can instantly go look up the docs for any of those if I want to know what they do.The second benefit is that we get much more helpful error messages. Before, if we tried to do
color (px 10)here's what we'd get:On the
phantom-valuesbranch, here's what we get instead:With a small bit of learning, we can get a ton more out of this error message. It's telling us that the value we used was constructed with the
pxfunction, and that it was expecting a value constructed usinghex,hsl,hsla,rgb, orrgbainstead.That's way more directly useful than seeing stuff like
lengthOrNumberOrAutoOrNoneOrContentwith the status quo.The Plan
I'm gonna switch everything in the
Cssmodule to use both phantom types as well as this new style of extensible records vs. non-extensible records.Even though things will fit together the same way when it's done—so glad we have an extensive test suite to guard against regressions!—this is not a direct one-to-one transformation. I can't write a script to automate it. It's just gonna take time.😄
Since I have to touch so many functions by hand anyway, while I'm at it, I'm also making sure everything has real documentation (too many
{-| -}docs in the current release), and I'm also knocking out some easy performance optimizations along the way.It's gonna be sweet!😸