7 ms·
> personally I find my brain works very much like a Turing Machine Exactly this. How baking a cake in FP looks like: * A cake is a hot cake that has been cool
by strangenessak 7y ago
> personally I find my brain works very much like a Turing Machine
Exactly this. How baking a cake in FP looks like:
* A cake is a hot cake that has been cooled on a damp tea towel, where a hot cake is a prepared cake that has been baked in a preheated oven for 30 minutes.
* A preheated oven is an oven that has been heated to 175 degrees C.
* A prepared cake is batter that has been poured into prepared pans, where batter is mixture that has chopped walnuts stirred in. Where mixture is butter, white sugar and brown sugar that has been creamed in a large bowl until light and fluffy
Taken from here:
https://probablydance.com/2016/02/27/functional-programming-is-not-popular-because-it-is-weird/ https://probablydance.com/2016/02/27/functional-programming-...
- antisemiotic 7y agoAnd then you actually try to write it in a functional language, and end up with something like: cake = map (cool . bake 30 175) . splitIntoPans $ mix [ butter, sugar, walnuts ]
- p33p 7y agoI think partial application and pipe operators make this so very intuitive though: [butter, sugar, walnuts] |> mix() |> splitIntoPans(pans = 3) |> bake(time = 30, temp = 175) |> cool(time = 5)
- strangenessak 7y agoWe can improve the syntax further [butter, sugar, walnuts] mix() splitIntoPans(pans = 3) bake(time = 30, temp = 175) cool(time = 5) Hmm, wait a second.....
- pkilgore 7y ago[butter, sugar, walnuts] ^^^ Somewhere wanted type CakeIngredients but missing record field "Flour" If imperative style programming came with type inference on the level of the Ocaml compiler sign me up. For now, though, I can spare a few cycles in exchange for correct programs.
- antisemiotic 7y agoCareful, somewhere along that line you might even come to a conclusion that Haskell is world's most advanced imperative language, with the reprogrammable semicolons and whatnot.
- twic 7y agoOr, to coin a phrase: https://apps.dtic.mil/dtic/tr/fulltext/u2/a030751.pdf https://apps.dtic.mil/dtic/tr/fulltext/u2/a030751.pdf
- meijer 7y agoBut this doesn't handle the state. It is not working imperativ code.
- chii 7y agobut now that you've written the cake baking data type, with a little small tweak, you've got a bread baking data type.
- missosoup 7y agoI'll find it more intuitive to do both as an imperative series of steps. Some of my friends are in love with FP. I am not. I've done more FP than most, I can work with it, but my brain has never become in tune with it. I can bang out my intent as imperative code in real time, but with FP I have to stop and think to translate. FP also means that I can't always easily tell the runtime complexity of what I'm writing and there's a complex black box between my code and the metal. Maybe some of my friends' brains are superior and can think in FP, all the more power to them. but empirical evidence is that most people are not capable of that, so FP will probably forever remain in the shadow of imperative programming.
- pas 7y agoDo you think of types and transformations between types when you write imperative code? I mean usually the problem in FP is that you simply can't type mutation (you'd have to use dependent types and so on), okay, so use immutability, great, but then every "step" is just some franken-type-partial-whatever. And TypeScript has great support for these (first of all it infers a lot, but you can use nice type combinators to safeguard that you get what you wanted). I don't like pure FP exactly because of this, because many times you have to use some very complicated constellation of concepts to be able to represent a specific data flow / computation / transformation / data structure. Whereas in TS / Scala you just have a nice escape hatch.
- jacobush 7y agoHaha, that sounds like the C++ inheritance joke.
- Torwald 7y agoI'd rather have a baking class that takes an argument for what I want to bake, either bread or cake, and spares me the details of how baking is done. I don't have to know that a preheated oven is one that is at 175 grades etc
- amrrs 7y agoSame example of baking a cake to explain functional programming in R by Hadley Wickham. A good presentation. https://speakerdeck.com/hadley/the-joy-of-functional-programming https://speakerdeck.com/hadley/the-joy-of-functional-program...
- mbrock 7y agoI actually don't know of any functional programming languages that don't have syntactic and semantic support for writing step-by-step algorithms.
- pas 7y agoCould you elaborate on this a bit? Basically calling a functions form an other is how a step-by-step algorithm would work in FP, no? And pattern match on what comes in, and return an immutable copy. For example you can put functions in a list, and push a datastructure through them, like a pipeline. edit: https://probablydance.com/2016/02/27/functional-programming-is-not-popular-because-it-is-weird/#comment-2615 https://probablydance.com/2016/02/27/functional-programming-...
- pyrale 7y agoThe control structure that takes the different functions/values and glue them together is what makes your code imperative or descriptive. While there is a lot of overlap between descriptive style and fp, it is not always the case. In haskell, for instance, the do notation lets you write imperative code: f article = do x <- getPrices article y <- book article finishDeal article x y ...and then the compiler desugars it to a more descriptive form.
- gmfawcett 7y agoIn fairness, we could be in the List monad here, and this would effectively be a list comprehension rather than an imperative program. Even if we are in IO, `getPrices` and `book` may never execute --- even `finishDeal` may never execute! --- depending on non-local details that aren't shown here. The code certainly "looks imperative" but it's still a declarative program --- the semantics are rather different from what a typical "imperative programmer" would expect.
- gowld 7y agoYou miscounted the number of negatives in the comment you replied to.
- thih9 7y agoIf you want to bake a cake, FP like this could seem awkward. But what if you want to run a bakery and split the work across multiple cooks? In that case it helps to have clearly defined ingredients. I'm only trying to say that it all depends on the context. Obviously personal preference is a big factor too.
- u801e 7y agoYou should read the OOP version of "for want of a nail" proverb near the end of this post (http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom...).
- stereolambda 7y agoIt's a good analogy! But it also shows that in FP you have to specify what is needed for what and what happens why. If you wrote that imperatively, you could include steps like "go outside, count clouds, return" or "place a metal bowl next to everything, put some cereals inside". And then never return to that bowl again, just leave it like that. The programmer wanted to use this bowl for something, but then forgot it was there. And then, when someone returns to that code, they have no idea that these steps are unnecessary and why each step was taken. (Or maybe they are necessary, because cloud counting ensures there is time for ingredients to permeate?). So probably these steps will be left and more mess and jungle will accumulate.
- deleted 7y ago[deleted]
- jmilloy 7y agoBaking a cake is like being a compiler and a processor for recipe instructions. Of course it seems awkward from the perspective of a human baker because before you can process/bake you have to "compile" the expression to procedural steps. The computer does that without complaint. This may illustrate that humans aren't good compilers of functional code, or in particular that humans aren't good at parsing poorly formatted functional code (again, computer parsers don't care about formatting). But I don't think it indicates that functional code isn't good for reading and writing, even for the same humans. I also don't think this recipe resembles FP. Where are the functions and their arguments? There is no visible hieararchy. It is unnecessarily obtuse in the first place.
- denton-scratch 7y agoNever seen that before, thanks! It's very funny. I can't write Lisp to save my life, but I know roughly how you're supposed to do it.
- soulofmischief 7y ago> In any case the point is this: I had some straight imperative code that was doing the same thing several times. In order to make it generic I couldn’t just introduce a loop around the repeated code, but I had to completely change the control flow. There is too much puzzle solving here. In fact I didn’t solve this the first time I tried. In my first attempt I ended up with something far too complicated and then just left the code in the original form. Only after coming back to the problem a few days later did I come up with the simple solution above. There are two kinds of people, I guess. To me, this description simply encapsulates the process of being a programmer. Boo hoo, you had to think a little bit and come back later to a hard problem in order to figure it out. I'm sorry, but that's literally how every profession which requires engineering skills plays out. And like other professions, after you solve a problem once you don't have to solve the problem again. It's solved. The next template Gabriel writes in that flavor will not take nearly as long. Seriously, all of these points he raises against FP are entirely contrived, and come across as the meaningless complaining of an uninspired programmer.
- AnimalMuppet 7y ago"It doesn't fit the way I think" != "I'm too stupid or lazy to figure it out". And why should s/he do so? Between the language and the programmer, which one is the tool? Should not the tool fit the human, and not the other way around? FP fits the way some people think. It doesn't fit the way others think. And that's fine. It's not a defect that some people think that way, and it's not a defect that some people don't.
- soulofmischief 7y agoI think the whole conversation is silly; FP is another tool in my toolbox. Yes, with some effort I can accomplish most jobs with a crowbar, but why would I do that?
- temp1999 7y agoTo the second question, when you work in the industry you realize the answer is often the programmer. Edit: There were a lot of questions in that comment.
- dragonwriter 7y ago> How baking a cake in FP looks like: > * A cake is a hot cake that [...] The difference between a functional programmer and an imperative programmer is an imperative programmer looks at that and says “yeah, great takedown of FP”, while a functional programmer says, “what’s with the unbounded recursion?” But, more seriously, it's long been established that real programming benefits from use of both imperative and declarative (the latter including—but not limited to—functional) idioms, which is why mainstream imperative OO languages have for more than decade importing functional features at a mad clip, and why functional languages have historically either been impure (e.g., Lisp and ML and many of their descendants) or included embedded syntax sugar that supports expressing imperative sequences using more conventionally imperative idioms (e.g., Haskell do-notation.) The difference is that embedding functional idioms in imperative languages often requires warnings about what you can and cannot do safely to data without causing chaos, while imperative embeddings in functional code have no such problems.
- 6gvONxR4sf7o 7y agoOkay, so first of all this is an excellent joke. But it's not that great of an analogy. This quote chooses one of many FP syntaxes. It's cherry picking. It uses "a = b where c = d." That's equivalent to "let c = d in a = b." Let will allow you to write things like: let cake_ingredients = [butter, white sugar, sugar] batter = cream(ingredients=cake_ingredients, dish=large_bowl, condition=LIGHT_AND_FLUFFY) prepped_pans = pans_full_of(batter) oven = preheat(your_over, 175 C) cake = bake(cake, 30 minutes) in dessert_tonight = cooled(cake) This isn't where FP and imperative are different. What's really different is that the let statement doesn't define execution order. That's not so relevant to this part of the mental modeling though. I think it's great that I can choose between "let ... in ..." or "... where ...". In real life, for a complex bit of language, I happen to often like putting the main point at the top (like a thesis statement), then progressively giving more details. Mix and match however's clear.
- falcolas 7y agoPerhaps it's the analogy leaking, but in baking, order of operations matters, and some operations must be done in parallel (pre-heating, based on initial oven state) to produce a good end product.
- nybble41 7y agoYes, and this is one of the areas where functional programming really shines. An imperative program is defined as a series of ordered steps and the compiler can't (in general) reorder steps to optimize use of resources because the steps could have arbitrary side-effects.[1] The FP version is essentially a dependency graph which constrains the order of operations without mandating a specific final order. The pre-heated oven is needed for baking but not for the batter, so these parts can automatically be evaluated in parallel just by enabling the multithreaded runtime.[2] [1] Certain primitive operations can be reordered but that depends on the compiler having access to the entire program. A call to a shared library function is an effective optimization barrier for any access to non-local data due to potential side effects. [2] For the purpose of this example I'm assuming the unused `oven` variable was meant to be passed in to the `bake` function.