Sorry, but there were many wrong / half truths in here, so I had to respond ;)
Elm does not allow user code to do side effects > This is wrong, that's what Task and ultimately Cmd are for. It's true that there is no way to do *uncontrolled* side effects, e.g. a function that sends an https request without having type Task/Cmd. In Haskell, a function with side-effects is marked as "unsafe" if it > declares IO in it's signature > That's wrong. Functions returning IO are not unsafe, they are equivalent to elms Task. They represent, just as in elm, a description of a *controlled* side effect. Haskell can do IO in an unsafe way (by using unsafePerformIO :: IO a -> a), but then the function no longer returns something of type IO. (unsafePerformIO should only be used in very rare, extraordinary circumstances) There's no `Cmd.andThen` to chain together commands > Thats true, but there is Task.andThen. The Http library has a toTask method for chaining. Most other libraries that perform side effects should also have a way to use them as a Task I agree with point 2, decoders/encoders are a bit tedious. But it's not too bad, you can even generate them automatically: https://eeue56.github.io/json-to-elm/ Back to the topic: I'd also be in favor of the task based Javascript inter op proposal. This could simplify scenarios like these quite a bit. On Monday, 13 March 2017 18:11:15 UTC+1, Kasey Speakman wrote: > > The landscape as I see it: Elm does not allow user code to do side effects > (i.e. communication/IO). In Haskell, a function with side-effects is marked > as "unsafe" if it declares IO in it's signature e.g. `readFileText: string > -> IO string`. Since front-end IO is somewhat narrow in what is allowed, > instead of marking this with IO, Elm provides "safe" wrappers to do the > most common forms of front-end communication (i.e. HTTP). Most of the > libraries mentioned expose an HTTP API. > > The problem then is that Elm's HTTP library is not quite up to par. The > two largest problems I see right now: > > 1) There's no `Cmd.andThen` to chain together commands, so you can't > package up multiple calls as one operation on the client side. This forces > libraries to leak implementation details to the caller (e.g. pushing the > in-between-calls state management to host application) and therefore makes > them tedious to work with. I try not to design APIs where clients should > need to make multiple calls, but it's needed for external APIs like the > ones mentioned. > > 2) Dealing with JSON is too much boilerplate/hassle. Parsers are > intractable for common usage (but perhaps still required for advanced > usage). Elm needs a configurable automatic de/serializer built-in to > support HTTP. Initially, it could just be parsers generated at compile-time > (same as ports) for any declared type alias. > > I think alleviating these two issues would make it far easier and more > desirable to actually create Elm libraries for external services which > could be published on elm-package. I know I do not use Elm's built-in HTTP > library for these reasons, and use ports instead on what could otherwise be > a pure Elm app. > > On Monday, March 13, 2017 at 4:06:44 AM UTC-5, Oliver Searle-Barnes wrote: >> >> (prompted by discussion of firebase integration on elm-dev) >> >> Given that it would be really helpful to have more integration libraries >> available for Elm (auth0, firebase, aws...) I've been wondering if the >> current state of affairs is ideal for achieving: >> >> 1) Maximum number of integration libraries available for Elm >> 2) All of those implemented in pure Elm >> >> Currently the path to get there appears to be: >> >> 1) Use an existing javascript library and wrap it using ports >> 2) Reimplement the library in Elm >> >> 1 to 2 often represents a significant amount of development. Because >> ports preclude a library from being published in >> http://package.elm-lang.org/ and elm package doesn't support installing >> them from anywhere else there's a social pressure to not implement effect >> managers or release libraries that make use of ports. >> >> Another path get to pure Elm libraries might be >> >> 1) Use an existing javascript library and wrap it using ports or native >> functions >> 2) Release it as a library >> 3) Gradually migrate the library over to pure Elm with the help of any >> members of the community that need it >> >> The concern here is obviously that your Elm code can now blow up and >> there's no way of knowing which code is unsafe. >> >> What if unsafe because a first class concept in Elm? You could mark >> functions as "unsafe". Any function that calls an unsafe function would >> also be required to be declared as unsafe e.g. >> >> >> unsafe attemptAuth : LoginDetails -> Task String AuthStatus >> unsafe attemptAuth loginDetails = >> Native.WrappedLibrary.attemptAuth loginDetails >> >> >> >> >> type Msg >> = unsafe AuthResponse (Result String AuthStatus) >> >> >> >> unsafe update : Msg -> Model -> (Model, Cmd Msg) >> unsafe update msg model = >> case msg of >> AuthResponse status -> >> >> >> >> >> This would make it possible to do a first pass on integration by just >> delegating to the javascript implementation. It's now very clear which of >> your Elm code is safe and unsafe. Having that unsafe keyword not only let's >> you know which code carries the Elm safety guarantees (if a function isn't >> marked unsafe) but you now also have this unsafe keyword stinking up your >> code encouraging you to reimplement it in pure Elm. You're using a shared >> library now though so whenever you replace a javascript implementation with >> a safe Elm version everyone benefits. >> >> What do you think, does this offer a practical route to a greater number >> of pure Elm integration libraries? >> >> >> >> >> >> >> >> -- 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 [email protected]. For more options, visit https://groups.google.com/d/optout.
