5 ms·
I didn't say Haskell's error messages are bad. If you stick with explicit types on your functions and no language extension they are absolutely great. I wanted
by sbergot 7y ago
I didn't say Haskell's error messages are bad. If you stick with explicit types on your functions and no language extension they are absolutely great. I wanted to point out that type checking errors with lens are hard unless you really know how all the different type aliases relate to each other. It was a few years ago so maybe things are better.
C++ also had this problem with the standard containers. However it is much easier to get what is a dictionary compared to a random "optic".
- dymk 7y ago> However it is much easier to get what is a dictionary compared to a random "optic". This is exactly what I disagree with. We come from a prior understanding of mutable/imperative dictionary/shared_ptr/std::pair, because that's what we started out with. Had we been initially been trained on monads, functors, lenses, those would be the familiar tools, and we'd go "Huh, that's an... interesting way to write code" when faced with C++ for the first time.
- smallnamespace 7y ago> because that's what we started out with Yes, but not from programming, but from general life experience. Everyone knows what an actual dictionary is, and even non-programmers can easily grasp how a one-way 'map' works. Mutation is also how the real world works. If you want to record something, you write it down—you've just mutated the world, not encapsulated your operation in the WorldState monad. You need to build a pile of mathematical abstractions in your head before you can really get off the ground with lenses. Not everyone has that aptitude or interest.
- dymk 7y agoHaskell has maps. You 100% do not need to build a "pile of mathematical abstractions in your head" to use lenses. It's a handful of types and functions. Do you need to build a pile of abstractions in your head to use `std::unordered_map` or getters/setters in C++?
- smallnamespace 7y agoYes to both? C++ is not a simple language by any means. For context, I was introduced to FP (SML in this case) around the same time I learned Java, and I still think for the vast majority of coders, an imperative map is much easier to grok than lenses. The former only requires understanding how values are manipulated and mutated. You're going to need to understand this anyway to write software, since your machine is mutating values in memory. Lenses however require complex type-level reasoning, so now you must learn both the value language and the type-level metalanguage at once, and your language also deliberately obscures the machine model. That might be powerful, but it is still an additional mental model to learn. I mean, just look at the Haskell wiki reference: https://en.wikibooks.org/wiki/Haskell/Lenses_and_functional_references https://en.wikibooks.org/wiki/Haskell/Lenses_and_functional_... The route to understanding them goes through Applicative and Traversals, which means have a solid understanding of typeclasses.
- rkrzr 7y ago> Mutation is also how the real world works. If you want to record something, you write it down—you've just mutated the world, not encapsulated your operation in the WorldState monad. But is it, though? Perhaps you just appended something to the world-log in a purely functional way. Time seems to always go in one direction (at least in my experience, YMMV), kind of like a DB primary key that is monotonously increasing. It really depends on how you look at this.
- foldr 7y agoLenses don't really give you anything that you can't get from (a) a sensible syntax for record updates and (b) intrusive pointers. Lenses only exist because of Haskell 98's uniquely bad support for record types. Record access and update in most other languages just is simpler.
- fmap 7y agoLenses are more than reified record labels though. There is a hierarchy of concepts that can be freely composed based on which features your data structure actually supports. In particular, lenses can be composed with traversals ("lenses" pointing at multiple fields) yielding "LINQ" like features without introducing new syntax or concepts. The main problem with lenses is that common lens libraries look extremely complicated at first glance and seem to be solving a very simple problem. That rightfully puts most people off of learning what all the fuss is about.
- mlthoughts2018 7y agofmap replying to foldr in a subjective argument about functional lenses... what have I done to deserve this hell.
- 0xab 7y agoIf you use lens as just a way to access records like you do in other languages, then there is absolutely nothing hard about it. Literally all you need to know is: Name your records like "data Prefix = Prefix { prefixFieldName :: ... }" call "makeFields ''Prefix" once at the bottom of your file and use "obj ^. fieldName" to access and "obj & fieldName .~ value" to set. That's it. You now have 100% of the capabilities of record update in any other language. This doesn't get any simpler in any other language. It even pretty much looks like what you would do in other languages. I'll grant you, Haskell and lens do a terrible job of explaining subsets of functionality that are simple and let you get the job done before jumping in the deep end.
- foldr 7y agoYeah, so it's a less good way of accessing record fields than the one present in 99% of other programming languages. Your own description makes this plain. Let's compare to Javascript: * I don't need to import a module to make available the syntax for getting and setting fields of an object. * I can use the same syntax for any object, and don't have to worry about doing a bunch of code generation via a badly-designed metaprogramming hack. * I don't have to worry about adding prefixes to all my field names. * The syntax uses familiar operators that I won't have to look up again on hackage if I stop writing Javascript for a few months. * No-one modifying my code can get "clever" and use one of ~50 obscure and unnecessary operators to save a couple of lines of code. What bugs me is when Haskell advocates try to use all the additional esoteric features of the lens library as an excuse for this fundamental baseline crappiness. Haskell really just needs proper support for record types. Then people could use lenses when they actually need lenses (never?). At the moment, they're using lenses because they want something that looks almost like a sane syntax for record updates.