6 ms·
My all-Haskell company has avoided the use of Lens whenever possible and I haven't missed it for a second. Its payoff doesn't seem to justify the cognitive ove
by zeendo 4y ago
My all-Haskell company has avoided the use of Lens whenever possible and I haven't missed it for a second.
Its payoff doesn't seem to justify the cognitive overhead (concepts, operators, etc) that it brings.
I'd highly recommend that newcomers to Haskell avoid Lens in their own code for as long as possible. The juice really isn't worth the squeeze.
- djha-skin 4y agoThe whole lens thing was what really turned me off to Haskell in the first place. It seems like I would never get it and it's hard to want to be in a language where you don't get something.
- _huayra_ 4y agoIs there a language where you get everything? (i.e. there's nothing you don't get) Based on the people who have amount of "C++ experts" I've interviewed over the years who don't know much about template metaprogramming or weird rules about initialization and class layout, yet have shipped meaningful code while avoiding most of the weird parts of the language. Even languages like Python can get weird, such as default arg initialization: def add_item_to_list(item, list_to_add=[]): list_to_add.append(item) return item a = add_item_to_list(1) a.append(3) b = add_item_to_list(2) What do `a` and `b` print? This is my go-to Python 1st-round question, and many prolific Python coders don't get through this. From what little I've learned of Haskell so far, it seems like one can eschew the weird PL-heavy parts of the language and just be productive (with the tradeoffs the language contains, e.g. GC).
- goostavos 4y agoYou ask this in interviews...? What makes this a good 1st round question in your mind? What is there to learn about the candidate? It seems to me that it's one of those things you've either encountered (and go "well, that's weird") or... haven't encountered (and go "well, that's weird" upon having it explained). Have pop quizzes about the sharp edges of various languages proved useful as a filtering mechanism?
- anon291 4y agoAs someone who deals in low-level code and has been at several different companies... Absolutely. This stuff can be the difference between a good product and 'leaks customer secrets at runtime'. It is irresponsible to program in a language and ship code when you do not understand. It is scary that software engineers want to be considered professionals, and yet don't want to be held responsible for understanding the tools they use. Would you trust a bridge designer who didn't really understand the intricacies of concrete? Not me, no thank you.
- insanitybit 4y agoI think it'll depend on the role. If you're coming into a role saying "I'm very familiar with Python" and you don't know one of the most famous 'gotchas', that says something. If you're coming into a role and saying "Hey, I'm not so familiar with Python but I have experience in other languages and I'd love to learn it as part of this role" I think that question is not appropriate.
- goostavos 4y agoEven still.. Seems a bit... arbitrary? It's pretty easy to just never bump into certain corners of languages -- even if you use said language extensively. I've used Python for, like, 8(ish) years professionally. I maintain a few moderately popular open source libraries. I honestly don't recall exactly what happens when you do the `list_to_add=[]` thing, because these days I pretty much never pass in a list with the purpose of having it be mutated by something else. I know is that I did try it once, a long time ago, and that it does something unexpected. But I couldn't tell ya more than that just by looking at in. Color me dismayed to discover that I'm actually a hack fraud.
- anon291 4y ago> But I couldn't tell ya more than that just by looking at in. > > Color me dismayed to discover that I'm actually a hack fraud. What I said elsewhere still stands. Yes... this kind of thing is the difference between 'works well' and 'exposes private user data to other users'. I'm glad you don't use such constructs, but realistically, given python's closure rules and when data with interior mutability are captured, this situation arises more than just in this particular situation. And like I said... it can easily lead to exposing private information to other users.
- quibono 4y agoDo you mean ``` def add_item_to_list(item, list_to_add=[]): list_to_add.append(item) return list_to_add a = add_item_to_list(1) a.append(3) b = add_item_to_list(2) ```
- _huayra_ 4y agooh lol yes you're right. I meant to return the list. I should not try to HN comment while running out the door to catch my bus...
- adamwk 4y ago> a.append(3) Trick question it's a type error?
- anon291 4y agoWhat is there to get? If you elide the actual implemetation, and go off of syntax, it's just `struct ^. field1 . field2` to get stuff and `struct # field1 .~ blah` to set stuff. It's syntactical memorization on par with any other language. A bit strange, but just syntax.
- goostavos 4y agoHaskell foot-guns lenses into something awful by doing what so many FP libraries do: over generalizing themselves into impenetrable category theoretic self-indulgence. Why do I need to understand Profunctors to get a value inside of a record?!? Lenses themselves are awesome. The "bad", naive, not-general type is really simple. ``` newtype Lens a b = Lens {get :: (a -> b), set :: (a -> b -> a)} ``` So simple that modifiers can be mechanically generated for your data types. And suddenly, you can express super-duper complex modifications without all the obnoxious boilerplate it'd otherwise take.
- anon291 4y agoThat lens is completely useless. If you are equivocating lenses to struct accessors, then you're adding abstractions for nothing. Lenses are good for things like, extracting all unique values out of deeply nested data structures for example. Say you have two data structures data Struct1 = Struct1 { someStuff: [ Struct2 ] } data Struct2 = Struct2 { otherStuff: HM.HashMap Text Struct3 } data Struct3 = Struct3 { name: Text } And you have a list `[Struct1]` and want a `[Text]` of the `names` of Struct3. How do you do this in an imperative language? Manually accessing the fields, for loops, etc. The van Laarhoven formulation of lens and ekmett's lens library optiocs in Haskell makes this trivial. `myList ^.. someStuff . each . otherStuff . each . name` Now, what if you wanted to modify all the names and prefix them with 'id-'? Again.. trivial. `myList # someStuff . each . otherStuff . each . name %~ ("id-" <>)` Your formulation is just field accessors. Not composable, and ultimately no better than just using the generated field accessors haskell provides.
- Hercuros 4y agoOne thing that does always strike me about such libraries is that they are often relatively easy to use for common scenarios like that, and the mental model is really not so complicated or abstract as to require category theory or something like that. When you use such libraries, I don't think you are really doing deeply category-theoretic thinking. More so just seeing how the types fit together and maybe thinking of some higher-order functions that you want to combine and apply. If you take Haskell and remove all the types (e.g. Scheme or JavaScript), you can have all the same abstractions, with basically the same syntax and operational behavior. But then of course the operational behavior is just applying/composing functions in the end... And because there are no higher-kinded types to deal with, category-theoretic language is less likely to sneak in. I say this as someone who has used Haskell for years and studied category theory / PL theory as well. And I like all of those things, just think it's sometimes not really necessary to get the mental model at all and be able to use those tools. I think that some code duplication is also not always the worst thing. Just because strings can be "combined" through concatenation and numbers can also be "combined" through addition does not necessarily mean you need one general notion/function to capture both, especially because if you take that to an extreme then you end up with some function that "sqoogles the byamyams" (i.e. the abstraction has become so general that the only way people really understand/use it is by looking at its concrete instantiations).