Language debates: Ocaml
Oct. 5th, 2022 05:04 pmA few years ago, I went on a "best language for home development" hunt. I sorted through pretty much all I knew and came out the other side with "Ocaml".
Some 1100 lines of Ocaml later, I terminated the project.
Couple reasons.
- Generics without type specialization are painful. At some point, you have to concretize, and different types are, actually, different.
- Similarly, the lack of good generics meant things like printing was painful[1].
- The libraries for web interaction were very much inadequate, and tended to be async. I don't like or want async in my codebases, so that was aggravating.
- Similarly, the libraries for interacting with postgres weren't great.
- Build system initially was horrible; eventually things moved to a more stable point, but the hand was really burnt.
- Modules fried my hair. Powerful and deeply opaque - even after reading most of the docs.
- Docs were bad
I'd like to believe it's better now. I invested a lot of time into that code. The concision was fantastic. That said, the friction was very high.
I went and did things with Scala after that...
- See Go.
golang std lib deficiency
Sep. 1st, 2022 01:37 pmSuppose one is writing Go - not the worst fate, but not exactly the best fate. One problem -
https://go.dev/play/p/po5A8KG6Zpv?v=goprev
there's no reason why a generic Merge1 and MergeRecursive function shouldn't be implemented.
Note that this essentially requires `interface{}` as the value type.
The actual V type should be the unification of both input types: if that can't be resolved intelligibly, then barf.
Part of the issue here is that the type system _should_ (but doesn't) have tagged union types. That would be a reasonably elegant solution to this.
https://go.dev/play/p/po5A8KG6Zpv?v=goprev
package main import "fmt" func MapMerge1[K comparable, V any](a map[K]V, b map[K]V) map[K]V { m := map[K]V{} for k, v := range a { m[k] = v } for k, v := range b { m[k] = v } return m } func main() { disabledThing := map[string]interface{}{ "enabled": false, } other := map[string]interface{}{ "options": map[string]interface{}{ "thungus": false, }, } merged := MapMerge1(disabledThing, other) fmt.Println(merged) }
there's no reason why a generic Merge1 and MergeRecursive function shouldn't be implemented.
Note that this essentially requires `interface{}` as the value type.
The actual V type should be the unification of both input types: if that can't be resolved intelligibly, then barf.
Part of the issue here is that the type system _should_ (but doesn't) have tagged union types. That would be a reasonably elegant solution to this.