Hmmm, kinda.
The pipe operator enables more readable code, so whilst I agree there would be more ways to do things, the average code readability could well go up.
1,015 karma · joined April 8, 2021
Hmmm, kinda.
The pipe operator enables more readable code, so whilst I agree there would be more ways to do things, the average code readability could well go up.
The F# take on Elm coders (Thoth.Json) can use reflection to generate them automatically. This is really useful at the prototyping stage.
- Expression orientated
- Lightweight syntax
- Emphasis on immutable data and pure functions
- do-notation (in F# these are called Computation Expressions)
- Type-safety without too many annotations (global type-inference)
- Mainstream ecosystem of libraries (in this case .NET)
- Compile to JavaScript
I used to think the same, but having now tried FP-style libraries for serializers (Thoth.Json) and HTTP servers (Suave), I think they are far superior to imperative or OOP alternatives. The ability to design these things in a declarative style makes the code much more robust and easier to read.
Looks like a tidy language though, it's just unclear to me what it offers over more established alternatives.
For example, in JS you might put these all over your code-base:
if (typeof x !== 'string') {
throw Error('Expected a string');
}Properly statically typed languages do not need run-time checks because the compiled code is already proven to be valid by the type-checker.
F# is the most mainstream of the 3. If you can live without the fancier type-system features (trust me, you probably can!) it's the easiest ride.
1. Genetics, upbringing and culture all matter
2. Diversity within an ethnic group is extremely large - often similar magnitude to diversity between ethnic groups
3. Therefore, to judge someone on their ethnic average will be inaccurate at best, offensive at worst
I think that this position has been misconstrued by pop-right / alt-right figures to create a false narrative in the culture wars.
match x with
| Some y ->
match y.Foo with
| Some z ->
match z.Bar with
| Some w -> printfn $"{w.Qux}"
| None -> ()
| None -> ()
| None -> ()
Compared to... option {
let! y = x
let! z = y.Foo
let! w = z.Bar
printfn $"{w.Qux}"
}
Funny quirk in Java, the compiler checks that calls to `opt.get()` occur inside an `opt.isPresent()` branch! if (opt.isPresent()) {
println(opt.get());
}1. There is a lot of complexity in building, deploying and maintaining software
2. There is a lot of complexity in understanding a domain and figuring out precise business logic
Often, (1) and (2) are known by different people, from technology and business functions. There is a communication overhead.
We can eliminate the communication overhead if (1) and (2) are known by the same person. But learning to code is hard... so if we make the programming easier (or even "no code") then people who know (2) can easily pick up (1)!
Ultimately though, I'm not convinced that (1) will ever be easy...
Aside from that, the joy of riding is what gets me out. Many cyclists choose tough hill climbs for added fitness gains and challenge. There is a good kind of difficulty (steep grade somewhere picturesque) and a bad kind (unresponsive bike that doesn't roll well)