[HN Gopher] Learn Functional Programming Visually
       ___________________________________________________________________
        
       Learn Functional Programming Visually
        
       Author : polyrand
       Score  : 291 points
       Date   : 2021-02-14 10:25 UTC (12 hours ago)
        
 (HTM) web link (david-peter.de)
 (TXT) w3m dump (david-peter.de)
        
       | austincheney wrote:
       | The biggest challenge with teaching functional programming is
       | that people tend to take the word _function_ or the concept way
       | to seriously. They start mandating restrictions on input /output,
       | what functions should be used for, and all kinds of other
       | unnecessary nonsense. It's like they need some sort of self
       | imposed guardrails to qualify making better or more common use of
       | functions. Like they need an official invitation before joining
       | the party.
       | 
       | Perhaps some of that stupidity is bound to a developer's
       | understanding of their language at hand. Some languages are more
       | expensive than others. This is where the sad confused developer
       | mandates that functional programming must be declarative... until
       | you point out the languages _Red_ and _Rebol_ are functional
       | imperative languages. It's not some shallow wishful opinion. That
       | is how those languages describe themselves and it's what they
       | look like.
       | 
       | When you take all the stupidity, assumptions, and restrictions
       | away functions are most universally a bag of instructions, as are
       | classes and various other things. Functions are unique from other
       | instruction bags in that they execute. That creates potential for
       | instruction reuse and thus portability.
       | 
       | Different languages impose different restrictions on where or how
       | functions may present. In JavaScript functions are first class
       | citizens which means they can be used anywhere a primitive may be
       | used, which is almost everywhere. Functions can also be nested in
       | that language which just means subdivided layers of
       | portability/reuse. In this case, in a highly imperative way,
       | functional programming can mean programming with a mindset of
       | functions first, as opposed to other means of structure or
       | extension. Again that interpretation of functional programming
       | tends to make people uncomfortable as there are no restrictive
       | guardrails or super specific defining rules.
        
         | louthy wrote:
         | > They start mandating restrictions on input/output, what
         | functions should be used for
         | 
         | Like what? You've thrown out a ton of generalisations, but
         | nothing here is concrete.
         | 
         | > When you take all the stupidity, assumptions, and
         | restrictions away functions are most universally a bag of
         | instructions, as are classes and various other things.
         | 
         | If you group all things together as a 'bag of instructions'
         | then there's no point in teaching functional concepts or any
         | paradigm's concepts for that matter.
         | 
         | I am reading between the lines here, but I am assuming by
         | 'restrictions' you're referring to functions taking immutable
         | values and returning immutable values. There are sensible
         | reasons for this (along with referential transparency in
         | general) that enable function composition, which is the 'super
         | power' of functional programming. It isn't a requirement, it's
         | just good practice, and so I can understand why FP advocates
         | would promote it (I certainly do).
         | 
         | A class can have those powers too if it is immutable, because
         | ultimately any class is just a set of functions with an
         | implicit 'this' argument, but it's often understood
         | differently. It doesn't seem unreasonable to promote and talk
         | about the differences in approach, especially in languages that
         | allow you to 'cheat'.
         | 
         | Yes, the narrow definition of a functional language is that it
         | has first class functions. Clearly though there's techniques
         | for success within the paradigm.
         | 
         | Again, it's quite hard to latch onto exactly what you're saying
         | here, but I don't think functions as structure is the argument
         | for FP (as such), it's functions that work like mathematical
         | functions, to leverage the centuries of knowledge of
         | mathematical expressions, proofs, etc. Personally, I find my
         | functional code much easier to understand, compose, test, and
         | generally have confidence in. When I compose two functions I
         | don't have to 'go and look inside' to see what it does first,
         | because they're pure and declarative.
         | 
         | The declarative nature of the functions is an artefact of
         | following the good practice of immutable values, referential
         | transparency, and total functions which lead to 'honest' type-
         | signatures, it just happens on its own.
         | 
         | I spent a reasonable part of my career in imperative-land, and
         | honestly I wish I'd found functional programming much earlier.
         | I write fewer bugs and I have more confidence in my code. And
         | yes, it adds constraints that are annoying sometimes, but those
         | constraints ultimately stop the code becoming a cognitively
         | difficult mass of mutation or hidden complexity.
        
           | austincheney wrote:
           | > You've thrown out a ton of generalisations, but nothing
           | here is concrete.
           | 
           | That was intentional. Specifics aren't necessary for making
           | the point. Had I stated the specifics you were looking for I
           | suspect you would have focused only on that, missing the
           | primary point.
        
             | tempodox wrote:
             | > ...missing the primary point.
             | 
             | Like GP, I would have to guess what your point actually is.
        
               | austincheney wrote:
               | _They start mandating restrictions on input /output, what
               | functions should be used for, and all kinds of other
               | unnecessary nonsense._
        
               | jhardy54 wrote:
               | A specific example of what you mean would be great. More
               | comments quoting yourself and refusing to explain what
               | you mean would be not great.
        
         | eevilspock wrote:
         | Whether or not you're right about functional programming, your
         | use of "stupidity" made me think more about what kind of person
         | you are rather than the merits of your argument.
         | 
         | In your other reply you come off as haughty or patronizing.
         | 
         | One does not need high EQ or SQ to be kind.
        
         | [deleted]
        
       | MauranKilom wrote:
       | I had fun playing through all the challenges. But I don't think I
       | walked away with a better idea of functional programming. This is
       | closer to "learn LINQ", seeing as we're only chaining functions.
       | 
       | I would be interested in seeing this expanded to include passing
       | functions to functions (that is, make the user build a tree of
       | functions, not a list). And yes, that might put you into hot
       | water regarding how to communicate signatures and such.
        
       | bhargav wrote:
       | The way this works technically is really great. Kudos to the
       | developer. The game itself ... I do not think it helped me learn
       | anything.
        
       | np_tedious wrote:
       | Cool game!
       | 
       | Headline here might be a little grandiose. Author has "A puzzle
       | game inspired by functional programming" on the project's Github.
       | I find this more apt
        
       | franknine wrote:
       | This game reminds me of Infinifactory by Zachtronics
       | https://store.steampowered.com/app/300570/Infinifactory/
        
       | shaneprrlt wrote:
       | Really cool! If you had the time/energy, this would be an
       | enjoyable mobile game.
        
       | auggierose wrote:
       | Cool game, but I don't think it is actually a good idea to see
       | this as "learning functional programming".
       | 
       | After all, this shows some very convoluted ways of getting a
       | simple end result ;-)
       | 
       | Also, I've only played the first few easy levels, so I guess
       | there will be more than "map" later on? Otherwise I would just
       | leave the "map" word out of it.
        
         | alisonkisk wrote:
         | No, it's just a misleading HN title.
        
         | cush wrote:
         | As a game it seems to exercise the same parts of your brain.
        
       | wodenokoto wrote:
       | What is the programming equivalent of stack equal columns?
       | 
       | I get the map and filter operations but I can't remember ever
       | coming across a function like that before.
        
         | yatac42 wrote:
         | > What is the programming equivalent of stack equal columns?
         | 
         | The game's "stack equal columns" corresponds to Haskell's
         | Data.List.group function:
         | 
         | > import Data.List
         | 
         | > group [1,2,2,3,3,3,2,1,1]
         | 
         | [[1],[2,2],[3,3,3],[2],[1,1]]
        
       | julienfr112 wrote:
       | What about Excel ? ;)
        
       | j1elo wrote:
       | This I don't understand: Seems like whenever functional paradigms
       | are discussed, the whole same stuff is always repeated without
       | failure: on one hand fuzzy generalizations like "pure functions",
       | "no side effects", "no state"... on the other, all examples
       | always talking about using map, filter, fold, flat, zip. One
       | would think that "functional programming" _is_ using those
       | functions. That FP is all about Iterators and what things you can
       | do with them.
       | 
       | But I never see contrived real-world examples, those that
       | _really_ show how things are different from imperative or
       | procedural programming. I want to see how you use stateless
       | functional programming to control a garage door actuator. Or how
       | you model a Car which can have their doors open or closed either
       | by the class itself or external actors. How do you receive UDP
       | packets, including a buffer implementation that is able to sort
       | out-of-order packets and send retransmission requests for missing
       | ones? That kind of stuff.
       | 
       | Are there any resources that show these kind of "here is a list
       | of problems, how they are typically solved, and how you could
       | solve with FP" style examples?
       | 
       | EDIT: This message was actually to say thank you and that TFA is
       | an awesome resource to help understand how the Iterator methods
       | work! And then I got lost in my semi-rant and forgot to actually
       | say thanks :)
        
         | random314 wrote:
         | All of the real world examples you described above involve I/O.
         | There are various approaches for this, the most popular being
         | the IO monad.
         | 
         | A function using the IO Monad looks like regular imperative
         | code except for the type signature of the function which
         | indicates that the function side effects and thus can only be
         | called by other functions that side effect. Pure functions
         | cannot call a side effecting function. This helps in isolating
         | side effects and capturing it in the type signature of
         | functions.
         | 
         | Plenty of examples here
         | 
         | https://www.haskell.org/tutorial/io.html
         | 
         | Functional programming is not stateless programming. Rather it
         | captures any state changes in the type signature. An explicit
         | example of it would be the state monad.
        
           | millstone wrote:
           | Many functional languages do not model effects in the type
           | system, like the ML family. Many do not have static types at
           | all, like Clojure/LISP.
        
         | Grustaf wrote:
         | > But I never see contrived real-world examples, those that
         | really show how things are different from imperative or
         | procedural programming. I want to see how you use stateless
         | functional programming to control a garage door actuator.
         | 
         | I'm not sure why you'd want to see contrived examples, but the
         | reason to focus on map, filter etc is that this is where it
         | starts, and this is what functional programming _is_,
         | transforming sequences of values with pure functions, rather
         | than keeping a lot of state and change it imperatively.
         | 
         | How to write a real world program with functional programming
         | is a later question, and pointless until you understood the
         | basics. All your examples also include a bunch of concepts and
         | data that A. can't be purely functional and B. will vary widely
         | between programming languages, so they are very poorly suited
         | for an introduction.
        
           | j1elo wrote:
           | I agree. So, I guess what I mean then is that once you're
           | past the usual introductions, there aren't many "next steps"
           | kind of guides to start doing actual work with the functional
           | mindset.
           | 
           | Although I must say, my examples are actual instances where I
           | tried to put the shallow learning I had done about FP and
           | failed spectacularly at doing so. It was no doubt due to my
           | ignorance and lack of experience with FP, but maybe also
           | there is a part of me not working with problems that lend
           | themselves easily to a FP approach...
        
             | samhh wrote:
             | The next step here may be recognising that just as you'd
             | map a list, you can also map lots of other data structures,
             | namely anything that's a functor (see: `fmap`).
             | 
             | Have something nullable? Stick it inside `Maybe` and map
             | it.
             | 
             | Have a side effect in `IO` and want to manipulate the
             | result? Map it.
             | 
             | Following that, look at monadic binding. It's basically
             | flat mapping.
             | 
             | From here you can start to see how programs can be composed
             | in languages like Haskell. You have these foundational
             | typeclasses and you sort of just connect all your functions
             | together with them until you're left with one big
             | expression in `main` which is your application entrypoint.
        
             | Grustaf wrote:
             | I suppose it's tricky to apply an FP approach when you get
             | closer to the external interface, it's moe suitable for the
             | more internal stuff. But when you combine it with reactive
             | approaches into FRP you can do more, and there are more
             | complex examples to be found.
             | 
             | But I'd say in general that FP is mostly just an
             | alternative to OOP, maybe even leas than that, not a
             | complete paradigm for writing complex programs. At least if
             | you use a mainstream language, then FP is probably
             | something you do pretty locally.
        
             | pcstl wrote:
             | You are completely right that FP is lacking in guides that
             | go beyond the basics. There's a great abundance of
             | introductory material, but very little about how functional
             | programmers structure large programs or deal with complex
             | I/O.
             | 
             | That is way too much for me to put into a single comment,
             | but the most common approach is to split your program into
             | "pure" and "impure" parts and then model all of your
             | interactions with the real world in a way where the "pure"
             | part of your program becomes an "interpreter" that deals
             | with the pure representations of real-world events.
             | 
             | A common pattern for doing this (but by no means the only
             | one) is using Free Monads.
        
         | xupybd wrote:
         | I'm currently reading Domain Driven Design Made Functional.
         | https://pragprog.com/titles/swdddf/domain-modeling-made-func...
         | 
         | It shows how a functional approach can embed much of the domain
         | logic into the types used. They are so simply expressed in F#
         | that non programmers can understand what they say about the
         | problem domain.
         | 
         | The book is selling me on the idea that Functional programming
         | could do a better job in CRUD style business apps.
        
         | alisonkisk wrote:
         | I think you are replying to misleading title and some other
         | article. There is no "TFA" here; it's a little game.
        
         | adamkl wrote:
         | I've found Grokking Simplicity [0] to be a great, pragmatic
         | introduction to solving real-world problems with "functional
         | thinking".
         | 
         | All the code is JavaScript and it tries to walk you through how
         | you might solve common, everyday business problems with a more
         | functional approach. All without getting bogged down with terms
         | like "monad" or "functor".
         | 
         | This book (along with Domain Driven Design made Functional,
         | mentioned elsewhere) are both great resources for getting
         | introduced to "useful" functional programming.
         | 
         | [0] https://www.manning.com/books/grokking-simplicity
        
         | gmi01 wrote:
         | I share your opinion. I found the book Real World Haskell very
         | useful http://book.realworldhaskell.org/ It has a few nice
         | chapters about system programming, database interactions and a
         | few other use cases.
         | 
         | Here is an educational bulletin board website built with
         | Haskell: https://gitlab.com/gilmi/bulletin-app
        
         | snarkypixel wrote:
         | Redux in the react world is a good example of real-world
         | application using pure functions and functional programming
         | concepts.
        
           | Jestar342 wrote:
           | Likewise most of the hooks (useReducer being the obvious
           | primary example), and functional components in general.
           | That's how 99% of functional programming is done - state and
           | function are separate, first class, concepts. The line is
           | very distinct.
        
             | sfvisser wrote:
             | I don't thinks hooks are a great example. Hooks are by
             | definition effectful. Best compared to 'Applicative's in
             | Haskell. (Not monadic unfortunately)
             | 
             | So a functional component in react using hooks is not pure.
             | You can translate it into FP with a bit of magic, but
             | requires a context. The line is not that distinct at all.
        
         | proc0 wrote:
         | One of the main differences in reasoning I think is how each
         | paradigm deals with time, not in a datetime or library sense,
         | but in the literal sense of time and causality. Does the
         | paradigm abstract the passage of time or not? FP abstracts away
         | time, and statements in FP are timeless, true now and in the
         | future. That is why it ends up looking like math a bit more.
         | Once statements in the language are sensitive to time... that
         | means there is mutation and the line above can have a side
         | effect on lines of code below. It's like FP is jumping a
         | dimension and it makes statements that have to be true at all
         | times (pure FP anyway), while mutation languages give you fine-
         | grain control on what is being computed each unit of time.
         | 
         | Of course you then have a mixture of both, which many if not
         | most modern languages have. Pure FP can be expressed in a
         | language that supports mutation anyway, it's just a matter of
         | how much first class support those features have. Languages
         | like Haskell I think go so far into the abstracting of time,
         | that they reached around and achieve something like mutation
         | based syntax, except there is a tower of abstractions working
         | under the hood, ensuring that it's still timeless equations
         | which result in side effects.
        
         | logbiscuitswave wrote:
         | I've long struggled to "get" functional programming - both its
         | syntax, and it's real world uses. Everything is so terse and
         | abstract and I find the lack of clear expressiveness to be
         | daunting. It all often feels too "magic" to me which makes me
         | suspicious. Then I wonder "what's in it for me?" - how does it
         | make my job or life easier? (I find myself much less motivated
         | to learn something new without a clear answer to these things.)
         | 
         | One things I've found enlightening is when participating in
         | Advent of Code exercises, watching how people are able to solve
         | problems using functional languages. While I may not always
         | grok the solutions in their entirety I'm often impressed by the
         | compactness and elegance.
        
       | maartenh wrote:
       | This reminds me of the tree diagrams I wrote during the Term
       | Rewriting Systems course at the Vrije Universiteit [1].
       | 
       | Functional programming really started to resonate with me at that
       | time. Properties like confluence were very useful to understand
       | distributed systems algorithms later on, and e.g. how eventual
       | consistency plays out.
       | 
       | [1] The teacher was awesome too. If you'd like to learn more
       | about term rewriting systems, go take a peek at his slides
       | http://joerg.endrullis.de/teaching/#trs (Note, just noticed that
       | they are behind a password. A gentle email will probably get you
       | the slides though :)
        
         | mettamage wrote:
         | Fun to see you here! We've studied together! I'm glad I'm not
         | the only one recommending Vrije Universiteit courses on HN, now
         | we're a crowd :P
         | 
         | I'll send you a PM :)
        
       | alisonkisk wrote:
       | Since the model is an array of pillars, the visualization has a
       | wall is confusing. Would be better to add some space between
       | columns, and remove the 3D/isometric effect.
       | 
       | The mathematical problems break the "visual" model. They are
       | harder to understand when you have to spend most of your energy
       | doing 8 simultaneous mental conversions to base 8 while solving.
        
       | spiralganglion wrote:
       | This is cool. It would be improved by adding the CSS _#controls {
       | user-select: none }_ (with various vendor prefixes). A bit of
       | refinement to how dragging is detected wouldn 't hurt either.
        
       | t0astbread wrote:
       | Good idea but I was able to solve most of the puzzles without
       | ever thinking about what my program was actually doing,
       | especially in the "math" levels. In the sense that I knew what
       | was going on, I got the concepts but I never "evaluated" the
       | program in my head. I just made some educated guesses based on
       | what I thought the patterns might turn into. Maybe that's
       | deliberate here but I thought that's usually not what puzzle
       | games want.
        
         | alisonkisk wrote:
         | The other problem is that it's easier to brute force the small
         | set of permutations of options, than to think it through.
        
       ___________________________________________________________________
       (page generated 2021-02-14 23:00 UTC)