Live data from Hacker News

A Farewell to FRP

elm-lang.org

231–240 of 246 posts

Re: A Farewell to FRP

#231
post #93

What I really want is a language with Elm's type system, simplicity, and syntax, but aimed for backend software instead of HTML apps and with strong support for an Erlang-style actor model of multicore, distributed concurrency. Basically something like Elixir, but with Elm's syntax and type safety. In the meantime Elixir will do for me, but I'd really like more type safety without going full Haskell.

Bite the bullet and go full Haskell, it's not that hard, although it seems to appear that way from the outside.

Re: A Farewell to FRP

#232
post #160

Has the elm installation on Linux improved in recent months? Last time I tried my system's GHC was too new to install it from source and the node installation went kablooey in weird parts(too recent ncurses, the automatic "reactor" browser repl not finding the Html package etc...)

You can install elm with npm.

Re: A Farewell to FRP

#233
post #188

I found that while things worked once it compiled, I spend most of my time staring at compilation errors, especially as I refactored. So I'm mostly trading time spend debugging subtle state errors with fixing compile type errors. It feels not as productive, since I'm usually looking at errors. Also, I'm still new to FP, so if you go outside of the Elm architecture, you're going to run into problems, which you're use…

> So I'm mostly trading time spend debugging subtle state errors with fixing compile type errors. It feels not as productive, since I'm usually looking at errors. Strange, because debugging subtle state errors seems far more time consuming to me than fixing compile-time errors. You have to launch debugging sessions or insert logging commands and step through reams of code, where compile-time errors tell you exactly w…

Yeah, it's true. Logically, I know it's better to catch it all at compile time. But it just feels things are broken all the time, since I don't get to watch my program run nearly as much as I use to.

However, when it runs, it usually does work. I think I'm just not as use to structuring my programs in FP yet.

Re: A Farewell to FRP

#234

Earlier quoted context omitted.

Rust does sound interesting, but it doesn't seem to be focused on the areas that I need right now. Go has GoRoutines, which are light threads; they can be executed on multiple CPU threads, but by default Go only allocates one CPU thread per physical CPU, even if you allocate tens of thousands of GoRoutines. For the kind of networking server code I'm writing, light threading is far more efficient than using an OS thre…

Ah, sounds like Erlang/Elixir would be a better fit since the BEAM is the king of lightweight threads/processes. You said C++ so that's why I suggested Rust, generally a GC tends to preclude spaces where C++ excels which is why I would think you'd want to try something other than Go. On the Rust side there's things like mio for fast io but coroutine/light threads aren't really a focus afaik. I would still think you c…

I've been reading about Elixir recently, yes. Thanks for mentioning it, though. I'll have to look at it at some point, but since my code is primarily run-in-a-browser, I'm currently stuck with compile-to-JavaScript languages. I'm concerned that Elixir is too functional for my tastes (I find Haskell to be too pure (and slow) to be really usable for most tasks I work on, for instance), but I will give it a look at some point.

The entire point of writing in Go or Elixir would be to avoid needing to write an event based system in Rust (or C). Writing code as if it's imperative but getting the speed of an event-based system is what I'm looking for. Event-based systems are notoriously hard to reason about and debug.

Re: A Farewell to FRP

#235

I haven't dabbled in Elm much, but subscriptions look a lot like ordinary JS event handlers: Time.every second Tick vs. Time.on('everySecond', tick) Beyond baking an event emitter into the Time module and having a nice looking API, is there something I'm missing?

I don't know anything about Elm subscriptions yet. But there is a lot more to this stuff then just event emitters. Things like: * When an event/action/etc comes through, does it always call listeners synchronously? Can you change that and schedule events manually? * How do you compose subscriptions/event handlers? This is usually the hardest part, and where simple event emitters really start breaking * What about the…

It looks like Subscriptions are just Signals with another name. I don't see any difference except that functions like map, foldp, etc. have been removed to discourage first-order use of them.

Re: A Farewell to FRP

#236

Earlier quoted context omitted.

The type systems in modern languages like Swift, Rust, Scala, Haskell, and even Kotlin go way beyond classical Hindley-Milner. Classical Hindley-Milner gives you parametric polymorphism over algebraic data types, along with an inference algorithm. No subtyping, no casts, no coercions, no overloading, no polymorphic literals, no interfaces. You basically get SML. Consider that in 2006, MPTCs with fundeps was the prefe…

> You basically get SML. SML is still more usable than the statically type languages in use the most today (C++ and Java).

Yes, but by "modern static typing" I think we're talking about the latest generation of languages that have come out since 2010 (Swift, Rust, Kotlin, etc.)

Re: A Farewell to FRP

#237

Earlier quoted context omitted.

Rust does sound interesting, but it doesn't seem to be focused on the areas that I need right now. Go has GoRoutines, which are light threads; they can be executed on multiple CPU threads, but by default Go only allocates one CPU thread per physical CPU, even if you allocate tens of thousands of GoRoutines. For the kind of networking server code I'm writing, light threading is far more efficient than using an OS thre…

Ah, sounds like Erlang/Elixir would be a better fit since the BEAM is the king of lightweight threads/processes. You said C++ so that's why I suggested Rust, generally a GC tends to preclude spaces where C++ excels which is why I would think you'd want to try something other than Go. On the Rust side there's things like mio for fast io but coroutine/light threads aren't really a focus afaik. I would still think you c…

I am sure that a Rust team member will be here soon to set the record straight, however, my take:

> Rust side there's things like mio for fast io but coroutine/light threads aren't really a focus afaik

IO and concurrency/parallelism models are a very difficult topic to really discuss and quantify performance around.

The highest-known-performance network server architecture revolves around edge-triggered epoll/kqueue (evented, async IO) and state machines (eschewing the stack entirely.)

pthreads (speaking exclusively about POSIX here - Windows threads are far heavier-weight than pthreads) suffer the cost of context switching due to large (by default - this can be configured) stack sizes.

This is one reason why languages like Go and Erlang have their own stack and lightweight process (greenthread) implementations.

For the record: Rust had green threading, and I believe it was removed due to the overhead relating to supporting it. The simple fact that you really cannot control or know when FFI calls will block (libc included) or not makes greenthreading tricky.

The trickier thing, IMO, relating to async IO is just the compatibility aspect:

- Golang/Erlang control compatibility by offering entire ecosystems built around their greenthread models.

  - Golang even goes as far as replacing the vast majority of libc and much of what you would want to call out to C for.
- Rust, being a systems language, cannot dictate "all code must use async IO and this specific reactor/event loop implementation," the stdlib is too small (by design), calls to libc are too pervasive.

With all of that being said:

- I personally believe Rust core should adopt a blessed async IO system (event loop, OS-level abstraction layers, basically mio) that all code could opt into using. - Additionally, it would be lovely if, on top of said system, compiler support for stackless coroutines (a la async/await) and a multithreaded reactor were implemented.

I love Rust, but I can't use it for network server related tasks until this part of the ecosystem is more developed and made more consistent.

mio is the de facto stdlib AIO implementation, but there's still a lot of fragmentation, and many libs still use the blocking networking builtins, rendering them incompatible.

Re: A Farewell to FRP

#238

Earlier quoted context omitted.

"what is the largest high quality elm app you know about and what is the largest high quality elm app that is open-source that you know about?" http://builtwithelm.co is a good place to start. My favourite big example is Dreamwriter ( https://dreamwriter.co ) by Richard Feldman. Warning not updated since e0.15.1 ~ https://github.com/rtfeldman/dreamwriter

Do you know any examples heavy with animations? E.g. similar that can be achieved with CSSTransitionGroup in React. While I can't use Elm in production app, I could dabble on it side projects, but I'm a little bit put off by the examples it has, they seem to not contain complicated appear/leave animations or animation managers. I think it's not yet solved?

Update: No, https://twitter.com/rtfeldman/status/730575929336942593

Probably best to ask this on the elm discuss group @ https://groups.google.com/d/forum/elm-discuss

----

I'll ask @rtfeldman [0] cf https://twitter.com/rtfeldman/status/730433179564179456

[0] https://news.ycombinator.com/user?id=rtfeldman

Re: A Farewell to FRP

#239

Earlier quoted context omitted.

Akka[1] is exactly the library you're looking for. It's available for Scala[2], which lets you use both OOP and FP as needed. (It also runs in Java if you have experience with that.) [1] http://akka.io/ [2] http://www.scala-lang.org/

But Scala is far from a simple language and Akka makes it even less so.

Scala is more forgiving than Haskell and the parent poster asked for something with Erlang-style actors, which are always going to be complex.

I really think this is the best option out there.

Re: A Farewell to FRP

#240
post #85
post #75

Earlier quoted context omitted.

There's Typed Racket [1] and for Clojure there's core.typed [2]which do pretty much that. For Clojure there's also Schema [3], which is a bit lighter weight (it's not a full type system), but still gets you some of the benefits like validation and documentation. [1] https://docs.racket-lang.org/ts-guide/ [2] https://github.com/clojure/core.typed [3] https://github.com/plumatic/schema

Neither fit the bill though - because not every function ever written in the language is annotated. To be nice to use, it should be an all-or-nothing affair. I say this as a huge clojure fan - my clojure programs with dynamic types work great. I rely on predicates (functions ending in -?) in I/O, otherwise I'm sure things work.

Why is annotation important? I agree it needs to be possible, but ultimately I want to push the majority off into inference, and only explicitly annotate when necessary or formalizing interfaces OCaml-style.

Though I sure do wish I could have lisp (or clojure, specifically) syntax in OCaml-land.

Post reply on HN