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.
A Farewell to FRP
231–240 of 246 posts
Re: A Farewell to FRP
#232Has 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...)
Re: A Farewell to FRP
#233I 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…
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
#234Earlier 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…
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
#235I 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…
Re: A Farewell to FRP
#236Earlier 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).
Re: A Farewell to FRP
#237Earlier 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…
> 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
#238Earlier 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?
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
Re: A Farewell to FRP
#239Earlier 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.
I really think this is the best option out there.
Re: A Farewell to FRP
#240Earlier 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.
Though I sure do wish I could have lisp (or clojure, specifically) syntax in OCaml-land.