6 ms·
Algebraic data types (ADTs) help a lot when expressing business logic. It's hard to go back once you've tried it in Haskell (or presumably in other languages).
by cosmic_quanta 5y ago
Algebraic data types (ADTs) help a lot when expressing business logic. It's hard to go back once you've tried it in Haskell (or presumably in other languages).
I often try to replicate ADTs in Python at $DAYJOB, because they're so damn convenient. I end up with dataclasses which have the same interface, and I disambiguate between them using `isinstance`. It's not perfect but it's useable.
- LeanderK 5y ago> I often try to replicate ADTs in Python at $DAYJOB, because they're so damn convenient. I end up with dataclasses which have the same interface, and I disambiguate between them using `isinstance`. It's not perfect but it's useable. I also do this! It is so painful not to have real ADTs.
- rfw300 5y agoHave you seen Python 3.10's pattern matching? https://peps.python.org/pep-0636/ https://peps.python.org/pep-0636/ While it doesn't bring you Haskell ADTs, it sounds like it could make your `isinstance`-style code a lot cleaner.
- cosmic_quanta 5y agoThat's great! Unfortunately, at the pace our stack is moving, I don't think I'll be using Python 3.10 for some time
- klysm 5y agoMy brain is 100% polluted by the power of ADTs. I can’t think about modeling problems without them anymore and it makes development in languages where it’s not ergonomic difficult.
- anoctopus 5y agoCompletely agree, although I'm often put off by the comparatively worse ergonomics for the python emulation, to the point that I sometimes miss obvious-in-retrospect places I should be modeling the domain with more variants, even in code I'm already using unions of dataclasses. The ergonomics and clarity of `data Foo = Foo Int | Bar` are incredible.
- xwowsersx 5y agoCan you share some examples, please?
- BoiledCabbage 5y agoFunny enough someone actually wrote a book on it. Data Modeling Made Functional https://www.amazon.com/Domain-Modeling-Made-Functional-Domain-Driven/dp/1680502549 https://www.amazon.com/Domain-Modeling-Made-Functional-Domai... It's one of the better and more useful software engineering books I've read. Even if you don't use a functional programming langauge. It's about using Algebraic Data Types do model common problems in the day-to-day business domain (not typical academic problems). It's a really simple and awesome presentation, and by the end you're dying for the ability to use this more so in the day to day job. Honestly after reading through it, trying to model problems in OOP just seems so unnecessarily obtuse. The Scott Wlaschin also runs https://fsharpforfunandprofit.com https://fsharpforfunandprofit.com https://fsharpforfunandprofit.com/ddd/ https://fsharpforfunandprofit.com/ddd/ - a link to a talk on it which is decent, but the book is much better.
- xwowsersx 5y agoThanks. I was asking specifically about accomplishing this in Python.
- Gadiguibou 5y agoI have had the exact same problem with Go recently. I have just started using it and have been disappointed to see that, for a language that claims to be modern, it doesn't have proper sum types/enums OR convenient product types/tuples. Tuples can be emulated using structs but it can generate a lot of boilerplate for a single function. The only alternative to express iterating over "zipped" lists is to have the two lists side by side and iterate using an integer. However, sum types are just plain missing. I guess interfaces help, but they're really limiting in what they allow and even regular C-style enums are painful and can't be checked for exhaustivity at compile time. Does anyone have tips on what the "idiomatic" solutions are for these problems?
- jerf 5y agoThere are times when sum types are the best solution, but in many cases, interfaces are the solution. But, interfaces as they are designed to be used, not just interfaces used to label a set of types that you then constantly type switch between. See: http://www.jerf.org/iri/post/2960 http://www.jerf.org/iri/post/2960 This is true of OO languages in general, not just Go.
- bobbylarrybobby 5y agoIn practice this doesn't seem to work. In theory, Go should have a Result interface and two types Data and Error that implement it, and then functions that could error would return a Data or an Error and then... you'd have to call a function like `my_result.Do(callback)`? The fact that idiomatic Go code actually returns (data, err) and checks if err == nil -- and that it's not an error to forget this check -- suggests that the interface paradigm just doesn't work that well.
- jerf 5y agoI have programmed Go for around 8 years now. This is not a problem in practice. I am familiar with Haskell. I know the gospel of sum types. But I don't think it's good engineering to force an inferior solution in to solve a problem I don't have. There are times when it solves problems. It is sort of ironic that as this conversation was occurring here on HN, I was programming with a sum type at work and doing a lot of type switches today. But it was solving a problem for me. Either/Result doesn't solve a problem I have in Go. The vast majority of time a person bashes a sum type into Go, they should be using polymorphism instead of switches. It is a well-known error to try to use a functional programming language as an OO language. It is the exact same error to use an OO language as if it's a functional language. One may be more in line with the zeitgeist, but that just makes it more popular, not a better idea. It's just as silly and just as gauche as the guy who runs to a Haskell community to complain about how they can't figure out how to implement inheritance in a nice way.
- prionassembly 5y agoTuples (or namedtuples/dataclasses if you must have named fields, which in Haskell too is additional syntax) are product types, enums are sum types. You should look into functools.singledispatch if you're doing business logic with isinstance. But you should also learn about object-oriented programming, inheritance vs composition, mixins, etc. People get sour on OOP because they should have learned FP first and then imitate/translate FP idioms -- instead of doing something like modeling domain ontologies in object graphs. Likewise, people get sour on FP yadda yadda instead of trying to literally write their programs as proofs to theorems.
- couchand 5y agoOOP is not an alternative to ADT, and a language lacking an expressive system of value types will stunt your development regardless of what flavor the rest of the language follows.
- pid-1 5y agoPython does have Union types and pattern matching tho.
- garethrowlands 5y agoPython has types?
- matyasrichter 5y agoUh, yes?
- pid-1 5y agoSure. The best type of types - the ones you can choose when to use.
- tiew9Vii 5y agoThis may be a useful pattern to you. The example is in Java but you should be able to achieve the same in Python https://apocalisp.wordpress.com/2009/08/21/structural-pattern-matching-in-java/ https://apocalisp.wordpress.com/2009/08/21/structural-patter.... It’ll get rid of the ‘isinstance’ and give exhaustive matching. I used to use this pattern a lot when wanting ADT’s in a language without ADT’’s.