10 ms·
Functional Programming, Abstraction, and Names
- deleted 10y ago[deleted]
- cousin_it 10y agoSometimes there's no need for too general definitions. All groups can be described as transformation groups, likewise for monoids.
- wrong_variable 10y agoIf you are interested in learning about Algebraic structures and group theory from a very practical standpoint I highly recommend https://github.com/fantasyland/fantasy-land https://github.com/fantasyland/fantasy-land Also - does anyone show me a practical usecase of the reader monad ? cant you just use partial functions ? if I am not mistaken isn't reader monad just : foobar.config ({'name':'hello'}); foobar.run ({'age':'34'});
- girvo 10y agoAnd check out ramda-fantasy while you're there!
- marcosdumay 10y agoYes, you can just use partial functions. But partial functions are not always as clean as you think they are. When composing with pure functions for example, you'll save a lot of boilerplate lambdas if you use the monad.
- runT1ME 10y agowell, a 'reader' monad is a monad over a Function[A, B]. So yes, when you say 'the reader monad', what you (probably?) mean is the instance it operates on, which would be a function. You use the reader monad the thread the same input to multiple functions that may also take additional intput, and also have their own outputs. You have to keep in mind that since Monads are so common and useful, many languages have syntactic support for them. C#'s LINQ query syntax, scala for expressions and haskell 'do' are all 'monadic comprehension'.
- wrong_variable 10y agoSo A reader Monad is similar to class inheritance. Where you provide a dependency ( like a inner class ). The resulting class can also have other variables and inputs. Is that a correct analogy ?
- greydius 10y agoI think a better analogy with OO languages would be a Function object for which you've provided one of the arguments in its constructor. Inheritance is more similar to monad transformers.
- ryani 10y agoReader fulfills a bunch of OO patterns. I like to think of it as "Environment", "Capability", "Configuration", etc., and is related in a way to Dependency Injection. Basically, you have some computation/object that isn't complete without some "setup info" which, from the point of view of the code being written, is "just there". Like if you had a program that needed access to a particular interface, but you didn't want to manually pass it to every function that cares about it; instead you'd make an object with that interface as its state and write your program as methods on that object. That's just Reader in disguise. In fact, C++ methods are basically in the Reader monad; they all have an implicit "this" argument which the compiler plumbs around for you.
- cantankerous 10y agoInterestingly enough "Environment" is another name for the Reader Monad.
- cantankerous 10y agoThe Reader Monad lets you abstract away local state. You're on the right track with partial functions, but using a monad is cleaner (at least in Haskell...and I'd guess anywhere else). Essentially using the monad instead will let you remove all of the redundant function application you'd have to do otherwise. If you've managed to abstract this step away into a library, take a look at your abstraction. It's probably equivalent to Reader.
- spion 10y agoThe reader monad is like read-only thread-local storage. (State or ST would be thread local storage). It provides a command to get the "current state" function f() { var m = getState().chain(state => { // ... }) return m; } or with generators acting like do syntax replacement: var f = wrapped(function* () { var state = yield getState(); // ... return; }); At the end you get an object that contains an unexecuted sequencing of computations that you can run with any state. For example you could run it from a HTTP route handler with the current user contained in the "state": var m = f(); m.runWith({currentUser: request.user}) and now you have access to the user without passing it around everywhere. All the other analogies in this thread are wrong in terms of what the real API looks like. The real API looks almost exactly like Promises, with `chain` instead of `then`. This in turn also explains why monad transformers are so important. Having access to just the current user w/o passing it around isn't very useful if e.g. you can't do IO, but having both - now we're talking!
- wrong_variable 10y agoI do not understand how the reader monad is different than promise. It seems the reader monad just delays execution of some code until you call 'runWith' and you can define state variables throughout your code before calling runWith.
- spion 10y agoThats precisely what it does, yes. Its different than a promise because the implementation is different (everything is done synchronously, and getState() returns an action object which then the implementation works on. The result of doing runWith() is also immediately available (not possible with async IO): var result = m.runWith(...) Other than that its almost exactly the same. And so are other monads. The Array monad (that is, if JS arrays actually had that method, which they don't) var m = [1,2,3] .chain(x => [x, x * 10]) .chain(y => y < 2 ? [] : [y]) result: [10,2,20,3,30] Same API (monad), totally different functionality.
- wrong_variable 10y ago
- JackMorgan 10y agoI wrote a simple post showing the 3 main ways to pass state. Check it out! http://deliberate-software.com/haskell-state/ http://deliberate-software.com/haskell-state/
- yomly 10y agoEven the brightest brain will have been stuck on something which, after the penny has dropped, will seem trivial. I agree with the author that there is a danger of "dumbing down" concepts which risks casting a lower ceiling on our capacity for lofty thoughts. There is another risk, though, that as someone becomes overfamiliar with a subject, they lose the ability to empathise with people who cannot immediately grasp the same concept. See [0] for a mathematician's reflections on revisiting his own DPhil thesis five years on. I would counter that making abstract concepts accessible, broadens the reach of concepts which allows for the greater potential of new concepts being synthesised. Put in another way, the more people that have some grasp of an idea, the more humanity will progress. Using Group Theory (strictly Point Groups) as an example, there are plenty of Chemists out there who are doing great work building catalytic organometallic compounds who use Group Theory. I'm sure plenty of them wouldn't be able to tell you what a Group was nor even express what the general basis of a Group are. So yes, while there is a need to push ourselves our capacity to think increasingly abstract, we should also not be afraid to ruthlessly simplify as the world is big enough that individuals will derive benefit from diluted concepts for generations to come. What's more is that as concepts get simplified, the next generation can short-circuit their learning to achieve greater understanding at an earlier stage in their lives. As I've always thought: if every human is born roughly equal, thank god we haven't had to "re-derive" making fire every generation otherwise how would we ever have time in our lifespans to learn about quantum mechanics and more. [0]https://medium.com/@fjmubeen/ai-no-longer-understand-my-phd-dissertation-and-what-this-means-for-mathematics-education-1d40708f61c#.v3nwdc7uc https://medium.com/@fjmubeen/ai-no-longer-understand-my-phd-...
- hderms 10y agoIndeed. I think the point about allowing people to understand the subject at various stages in their lives very apt. We apply pedagogical simplification to almost everything we teach children anyways, but it's quite possible that we could be much more far reaching in our attempts. It would be interesting to see a world where children are taught basic abstractions of group theory. Mathematics is one of those fields where it is difficult to simplify. Period. But in addition, the practitioners often actively resist this simplification. Mathematics is firmly rooted in proof, but not all mathematics education needs to be firmly rooted in proofs, and for that matter, not all mathematics education must be rooted in mechanistic repetition of solution techniques. There is perhaps a way to endow people with these concepts when they couldn't otherwise arrive at them through rigorous proving.
- szany 10y agoThis is a bit defeatist. Parsing the definition in your head is only the first level of understanding you can have about a mathematical structure. You don't really understand something until you can reinvent it (and in particular give a plausible answer to "why these axioms and not others?") For example, to motivate groups, you could introduce the concept of a symmetry as a mapping from an object to itself that doesn't change its properties, introduce the idea of an isomorphism as a mapping with an inverse (where f and g being inverse means they compose to identity maps), put them together and postulate that a reasonable formalization of a symmetry is an automorphism (isomorphism from an object to itself), note that isomorphisms are closed under composition, and arrive at the definition of a group by considering sets of symmetries closed under finite composition (thinking of identity maps as the composition of 0 morphisms). I'm sure there's a similarly conceptual way to motivate monads in functional programming. Hyland and Power have papers on algebraic theories of "effectful" operations and how they give rise to (finitary) monads, as one starting point.
- nhaliday 10y agoIndeed the typical wisdom in math is that the best way to understand a group (and the reason we usually care about one) is its actions. There's some quote to the effect of: "Just as with men, a group is known by its actions." This was the only reference I could find off the top of my head https://gowers.wordpress.com/2011/11/06/group-actions-i/ https://gowers.wordpress.com/2011/11/06/group-actions-i/, but I've definitely heard the sentiment repeated in a couple different texts. The sentiment expressed in this article might useful to hear if you're solely interested in learning how to use monad transformers or whatever in Haskell, eg, I know a fair amount of math, but very little category theory, and manage use monads just fine without any deep intuition as to why they're an important formalism. But if you want to develop your problem-solving skills, for example, I think "quiet contemplation" of axioms is pretty much always worse than working through several examples and absorbing some good exposition. Here's a recent article that I found very though-provoking: http://cognitivemedium.com/invisible_visible/invisible_visible.html http://cognitivemedium.com/invisible_visible/invisible_visib.... They quote some mathematicians discussing their visual intuition for one property of groups.
- auggierose 10y agoYes and No to this article. Yes, abstraction is important, and yes yes, the point of mathematical abstraction is not to be vague, but to create a level of expression where one can be precise. No, the point of abstraction can be to be vague, and to delimit the boundary of a concept that is not quite clear (yet). It is not a mathematical abstraction then, but something you are experimenting with to find the right kind of laws that are supposed to govern that concept. Most real-world programs contain many such concepts for which either no good mathematical abstraction exists, or for which nobody has had yet the time and money to find a good mathematical abstraction.
- igravious 10y agoMaybe. Maybe not. I am coming to believe that computational thinking != mathematical thinking. I'm able to reason logically in code because I'm able to reason logically about things in the real world and natural language supports that. I was able to code (early teens) and think computationally long before I ever knew there was such a thing as formal logic and truth tables and all that. And let's consider names. In Ruby I knew what the module Enumerable did before I ever read the docs. Monoid? I don't think so. And I have some math background. What about all the potentially very talented programmers that have a non-math background? I don't buy that we need the beginnings of 3rd-level math to be decent programmers. In fact, I'll go further. I think think that the programming landscape is too math-oriented. I know someone who had a curiosity about recursion so I started explaining the concept via factorials as one does. Said person gets little panic attack. Our default explanations oughtn't involve math. Our names should avoid high-level math concepts divorced from everyday speech and concepts. By all means use aliases if you want but give the rest of us something to hang our conceptual hats on.
- cantankerous 10y agoWithout formal methods and math, what does programming do to reason about the mounting complexity of modern systems?
- catnaroek 10y agoTDD obviously. :-p
- igravious 10y agoBetter building blocks. Better programming tools. Understanding the craft of software engineering better. To use a lever do I have to understand physics?
- pka 10y agoIf you are building a bridge or a skyscraper, yes, you absolutely do. If you are building a house for your dog, then no.
- skybrian 10y agoI think the question is why explicitly represent these mathematical concepts in a programming language. Since they're difficult to explain, the cost of including them is high, and they don't seem to have compensating benefits that are worth the cost.
- DigitalJack 10y agoI don't know how to read the monoid equations. <> to me means not equal. Is that what they meanin the article?
- dpratt71 10y ago<> is a placeholder for an operation (a function, really) taking two inputs, mempty is a placeholder for a special value, and x and y are placeholders for arbitrary values. If you can find something that fits the pattern, then it is a monoid. Such as where <> is addition, mempty is 0, and x and y are numbers. Or where <> is string concatenation, mempty is the empty string, etc.
- DigitalJack 10y agoThank you.
- cottonseed 10y ago> At this point, I didn’t have much else to say. Maybe because I started studying pure math later in life and I had to be more conscious about it, I have thought a lot about what it means to understand and think well about mathematical concepts. I think the author misses the point of the question, "What is a group, actually?" after giving the formal definition of a group. The student was asking, "How am I to understand groups?" And more generally, understand mathematical concepts. Here are some tools I learned for understanding groups: - The informal definition. What's a group trying to model? - The formal definition. - Standard examples. What's the simplest? What are the "canonical examples"? Mathematicians love this question. See, for example (more links inside): http://mathoverflow.net/questions/3242/canonical-examples-of-algebraic-structures http://mathoverflow.net/questions/3242/canonical-examples-of... http://mathoverflow.net/questions/4994/fundamental-examples http://mathoverflow.net/questions/4994/fundamental-examples - What happens if we remove parts of the definition? Inverses? You get a monoid. Identity, too? A semigroup. What if you add additional properties? You get things like commutative groups, rings, etc. You'll want examples of these other structures, too. - The motivating history of groups. Who defined them, and why? - When mathematicians encounter a new object, the their first instinct is to classify it. Can we classify all groups? (No.) Are subclasses of groups that can be classified? Yes! Finite simple groups, finitely generated commutative and Lie groups are all hugely important examples. - Related to classification, what are the general properties of groups? What can you prove about them? This help develop an intuition for "how they behave". - The goal of math is to prove theorems. What are groups good for? What can you prove with them? This sets group theory in relation to other mathematical subfields. - As mathematical objects go, groups are relatively concrete, but for many objects, it can be a challenge to describe actual examples. How do you describe examples of groups? Tables, presentations (generators and relations). When do two presentations describe the same group? (Hard.) - What constructions exist on groups? Products, quotients, semi-direct (twisted) products, free products, fibered products, etc. Category theory suggests we should study not only groups, but relations between them. Groups form a category. What kind of category? What universal constructions hold in the category of groups? - What are the kinds of groups? Commutative, finite, finitely generated, Lie, matrix, simple, etc. All the above questions apply again! Canonical examples, history, informal definition, constructions, classifications, categories, etc.
- nerdponx 10y agoI don't think this is on the right track. Obviously, learning is a matter of personal preference and experience, but trying to teach someone about groups by explaining the definition of a group defeats the whole purpose of even studying groups in the first place. The power of Group theory, and of mathematical abstraction in general, is that it allows us to generalize and extend existing concepts. I agree, that it would be ridiculous to rename all "groups" to "clocks", just as it would be ridiculous to rename all rectangles to squares. But for a student who has never seen a rectangle that is not a square before, it would be unfair and counterproductive for you to ask that student to put aside the example of a square when studying rectangles. For teaching purposes, it is rarely wrong to draw analogies between the generalized object and its everyday analogue.
- js8 10y agoThis reminds me of a related thing to naming things in programming which I wonder about. Should the names of functions and types be intrinsic to the object itself (its inherent properties), or they should be extrinsic to it, describing the domain use? The first option (intrinsic names) has advantage in reusability, the other option (extrinsic names) has advantage in readability for particular application.
- bariumbitmap 10y agoPrevious discussion: https://news.ycombinator.com/item?id=10880839 https://news.ycombinator.com/item?id=10880839
- incepted 10y agoInteresting take but I disagree with one point: > This style of designing abstractions is often quite foreign in programming in the large, and other schools of thought (see Gang of Four) actively encourage weaving cryptic metaphors and anthropomorphising code as a means to convey structure. The GoF didn't try to anthropomorphize, all they wanted to do is put names on things. Sometimes, these names have some meaning (e.g. Factory pattern) and other times, they have none (e.g. the Flyweight pattern). The important concept that the GoF book introduced was to name things. What word was used for these names matters little. In other words, similar to what the author of this piece is trying to achieve (and he does so pretty convincingly).
- catnaroek 10y ago> other times, they have none (e.g. the Flyweight pattern). They could've called it “handrolled hash consing”, which is exactly what it is.
- comex 10y agoI don't think that's much better than Flyweight in terms of intrinsic meaning. A little better, since it breaks down into hash + consing, but having not heard of either before, I wasn't able to easily guess what it was despite knowing what hashes and cons cells are. Of course, like everything else in Lisp it predates GoF, so I suppose it would have been nice to reuse existing jargon... But maybe a better name would be "memoized construction".
- catnaroek 10y ago“Memoized construction” is a very good name, indeed. It's actually better than “hash consing”, because it isn't tied to a particular implementation strategy. But I think the “handrolled” part is also important, to stress that it isn't something the language implementation gives you for free.
- cantankerous 10y agoGoF didn't try to anthropomorphize, but they ended up doing it anyway. The things they sought to name where simply tools for humans. It's the programmers equivalent of a book about hammers and screwdrivers. It's valuable for learning how to use tools to drive fasteners, but without the existence of such things the information becomes about as actionable as any other anthropological piece.
- katzface 10y agoI can't understand the difference between the definitions of Identity and Invertibility - can someone explain? I.e.: Identity For any element a in G there is an element e where e⋆a = a⋆e = a. Invertibility For each element a in G there is an element b where a⋆b = b⋆a = e, where e is the identity.
- SatvikBeri 10y agoThe integers >= 0 have 0 as the identity: 0 + n = n + 0 = n. But they don't have inverses, because e.g. there's no positive number n such that n + 1 = 0.
- cantankerous 10y agoI think you mean the naturals.
- floatboth 10y agoPeople disagree about whether 0 is natural though. Better not to use the word at all :D
- shele 10y agoOP said "integers >= 0". Not much to "think" here.
- SatvikBeri 10y agoI wanted to avoid an argument about whether 0 is a natural number or not.
- mdpopescu 10y agoIt's about where "e", the identity element, is placed - in the "identity" rule it is one of the terms of the operation (e * a, a * e) while in the "invertibility" rule it's the result of the operation. If you want an example, think Z (integers) and "+": there is an element of Z, namely zero (0), where the identity rule tells us that x + 0 = 0 + x = x and the invertibility rule says that for any x in Z, there is an y in z such that x + y = 0
- edem 10y agoOn my Android (Chrome) content looks like this: "For all \(a\), \(b\) and \(c\) in \(G\), \((a \star b) \star c = a \star (b \star c)\)." Maybe a javascript issue?
- pklausler 10y agoI like using moves on Rubik's Cube to convey an example of a group. The idea of an identity becomes one of cancellation, there are obvious subgroups, etc.