ReasonML vs. Elm
A Reasonable Compromise
A
Persistent
Dilemma
State
A value at a moment in time. This could be UI status, data from endpoints, configuration, user input, or any number of other variables.
Shared state
As complexity grows, so does shared state. Design patterns like OOP and FP are a way to manage that complexity.
OOP
Object-Oriented Programming segregates shared state into object instances with interface methods, allowing each object to manage state independently.
State Intensifies
How to manage state in Object-Oriented code?
- Create more objects
- Group objects into packages
- Make some methods private
- Use more abstract interfaces
- SOLIDly embrace Uncle Bob
Eventually, your code is only expressing a portion of the logic involved.
A
Sound
Solution
FP
Functional Programming seeks to minimize state and restrict it to carefully controlled portions of your application.
Mathematical!
It embraces strategies from category theory to enable compositional programming. Complex abstractions are built up from smaller, pure operations that can be combined in solid and predictable ways.
Type Safety
Ensures that a variable’s value always matches the variable’s static type.
This can be accomplished at compile time, runtime, or a combination.
Type inference allows annotations to be omitted.
Polymorphism allows types to vary.
Soundness
Ensures your program can’t get into certain invalid states. A sound type system means you can never get into a state where an expression evaluates to a value that doesn’t match the expression’s static type.
Pay off technical
debt up-front.
- Less time testing and refactoring.
- When things break down, it's often
easy to see false assumptions. - Sound completeness of the type
checker aids in finding bugs. - Code needs to be more thoroughly
thought out before it will type check. - More time needs to be invested
up-front to handle edge cases.
What could go wrong??
Performance
Functional programming was introduced in the 1950s with LISP. It actually came before OOP!
At the time, memory was very expensive. OOP required less memory.
Even today, mutation gives Object-Oriented code a performance advantage while sacrificing predictability.
Wizardry
In practice, it works! Errors and unpredictable side effects are much less of an issue. Complexity remains a constant foe, however, especially in languages with terse syntax and user-defined operators.
Where does Elm fit in?
Front End
What started as a simple document markup language has grown into a full-scale, cross-platform, accessible, realtime engine for rich applications.
The browser is turning into an embedded operating system, built around JavaScript - a very loose and dynamically typed environment.
Chaos Reigns
An object-oriented focus inherited from Java coupled with very loose and often-silent error handling resulted in the proliferation of buggy, difficult-to-maintain front end applications.
Race conditions and runtime errors became the bane of browser-based development.
Soundness with Clarity
Elm focuses on strict, sound type safety coupled with a strong emphasis on developer experience, with features like friendly error messages and rich tooling.
Interop is restricted to JSON messaging, allowing for exhaustive validation to ensure soundness.
Powerful Performance
Benchmarking shows that Elm's opinionated implementation of the virtual DOM is extremely performant, outdoing competitors with room to spare.
We're Saved!
🎉
Limited Abstraction
The lack of polymorphism and higher-kinded types leads to some frustration when trying to avoid boilerplate and repetition.
Narrow Focus
Because Elm code is built for the browser, code sharing across environments is not well-supported.
Projects to bring Elm to the server or to native clients like iOS or Android are experimental, and not ready for prime time.
Terse Syntax
The unfamiliar representation of HTML presents challenges for collaboration.
Enter
OCaml
OCaml...
- ...is a multi-paradigm (FP & OOP) language with an emphasis on expressiveness and safety.
- ...has a sound type system with rich inference, user-defined algebraic data types, and pattern matching.
- ...has a sophisticated module system with support for type-level programming.
- ...has automatic memory management (garbage collection).
- ...has a rich build system enabling different targets, syntaxes, and extensions.
Elm
Monomorphic Types
Abstraction by convention -
Restrictive Interop
Via JSON message-passing -
Single Environment
Currently browser-only -
Strict Immutability
Values change through - events
OCaml
Polymorphic Types
- Generic types
- Extensible records
- Higher-kinded types
Foreign Function Interface
- BuckleScript
- Convenience macros
Flexible Build Targets
- Windows, Linux, Mac, JavaScript, iOS, Android
Optional Mutability
- Refs to differentiate mutable values explicitly
OCaml
For the Masses
ReasonML...
- ...uses a very familiar syntax, similar to JavaScript
- ...targets native platforms like Mac and Windows, and web-based platforms like browsers and React Native.
- ...uses a toolchain that provides an npm-style workflow whether you’re compiling to JavaScript or native platforms.
- ...allows for gradual conversion of JavaScript codebases.
Pattern Matching
"Codify" your domain knowledge as custom types, and use a switch statement to make decisions based on them.
Exhaustive checking ensures you don't miss a case. Type arguments allow you to pass additional data with a variety of uses.
Reason-React
Polymorphic Variants
Custom, flexible types that don't have to be defined and imported in order to be used. The types can be used interchangeably in many situations.
Compositional Programming
The sound type system allows for powerful abstractions based on category theory.
Extension Points
Allows you to pre-process your OCaml code, transforming it before it is compiled.
Thank you!
ReasonML vs. Elm
By Brandon Konkle
ReasonML vs. Elm
A Reasonable Compromise
- 1,859