New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Inconsistency/unsoundness in type system due to channels #889
Comments
|
Whoa nice catch. Bug with type unification
|
|
Actually calling this a unification bug isn't quite right. It's because the
|
|
This is actually a well understood and solved problem. It's essentially the same issue as would arise with mutable references in SML or OCaml if not for the value restriction (a value restriction does bring issues of its own, but they're not that bad as they can generally be solved by eta expanding). |
|
Is it possible to do this with any other functions in Elm? Am I correct that this is related to functions with effects, but otherwise it is not needed? This is literally the only function in Elm that has side-effects, so if it is tied to effects, then I'd rather just get rid of |
|
I doubt it's possible to do this with anything else in Elm. This issue is generally tied to mutation. One might worry that one could try and pull the same trick with signals, but I guess it shouldn't be possible since there is some kind of pure model for the signature of Elm Things are quite a bit different in Haskell since the only place one "has" something of type (for example) Consider the following program (which is rejected by GHC) for example. import Data.IORef
main = newIORef Nothing >>= \r -> writeIORef r (Just ()) >> writeIORef r (Just "no")The lambda is typed as follows:
If we use Does the current promises proposal provide a way to write, e.g., the TodoMVC program without using channels? |
|
The program still compiles when annotated with |
|
I assume this is well known, but, for reference, here is the same unsoundness exposed using import Signal
import Html exposing (Html)
import Html.Attributes exposing (style)
import Html.Events exposing (..)
import Maybe
c = Signal.mailbox Nothing
s : Signal Int
s = Signal.map (Maybe.withDefault 0) c.signal
draw x =
Html.div
[ onClick c.address (Just "I am not an Int")
, style [("width", "100px"), ("height", "100px")]
]
[ Html.text (toString (x + 1)) ]
|> Html.toElement 100 100
main = Signal.map draw s |
|
I don't think this is well known, but it's definitely a reproducible bug! I pasted that code into the current (0.15.1) Try Elm; it compiled and ran, and when I clicked the "1", it turned into "I am not an Int1". |
|
To rule out a type inference bug, here is a minimal example with complete annotations that reproduces the bug in 0.15.1 if you paste it into Try Elm: import Signal
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
import Maybe
maybeInts : Signal.Mailbox (Maybe a)
maybeInts =
Signal.mailbox Nothing
ints : Signal Int
ints =
Signal.map (Maybe.withDefault 0) maybeInts.signal
view : Int -> Html
view int =
Html.div
[onClick maybeInts.address (Just "I am not an Int")]
[text (toString (int + 1))]
main : Signal Html
main =
Signal.map view intsIf you try to change the type annotation on |
|
It's not a bug in the implementation. It's a bug in the type system resulting from the fact that Elm doesn't have a sort of value restriction, as mentioned above. One solution that I think Evan mentioned at some point would be to require mailboxes to have monomorphic types, which seems quite reasonable. |
|
Yeah, a |
|
A problem with the proposal to require mailboxes to have monomorphic types: What to do about cases like the implementation of |
|
That is monomorphic in the type environment containing the type variable "action".
|
|
I do know that one could make this monomorphic in the sense you mention, if one could write that down as a type annotation. But one cannot, given that Elm has no equivalent of Haskell's And when you cannot write it down, you do get it interpreted as a polymorphic type, and then suffer from the type unsoundness. Happened in the wild, see here. |
|
Yay 0.17! |
Probably this is well known, but I couldn't find an issue on here. Because there's no value restriction on channels in Elm, the type system is unsound (for an appropriate notion of unsoundness) in the usual way. The following incorrect program compiles.
The text was updated successfully, but these errors were encountered: