[HN Gopher] Why study functional programming? (2012)
___________________________________________________________________
Why study functional programming? (2012)
Author : arkj
Score : 113 points
Date : 2022-08-02 17:00 UTC (6 hours ago)
(HTM) web link (acm.wustl.edu)
(TXT) w3m dump (acm.wustl.edu)
| globalise83 wrote:
| I find it beautiful, especially recursion. The fact that you can
| just let the computer take care of the problem in some strange
| and invisible separate dimension is pretty magical to me.
| procavia wrote:
| At my university the first programming class that every CS major
| had to take was functional programming. Many people would come in
| with no experience and FP would be their first introduction to
| the field. It was a very controversial course among students due
| to its perceived usefulness (or lack thereof), but as someone who
| already was familiar with imperative languages I really enjoyed
| it.
| anonimamente wrote:
| Oftentimes we read a comment of the kind "bad or good code can be
| written in any language or paradigm" in response to writings of
| the ills or virtues of said language or paradigm. Thus implying
| that we really shouldn't care of the choice of tools but rather
| concern ourselves with the individuals using them? This seems
| like an easy out. Too easy. If it is bad code that we need to
| worry about, no matter what the syntax or semantics, then how do
| we do that? Is bad code, like porn, something that we only
| recognize when we see it, impossible to clearly define? If that's
| the case, then we really need to figure out some better way to
| guide us. The mention of Kevlin Henney is particular here in that
| he has made presentations specifically identifying examples of
| bad code and how they are made better. If no language or paradigm
| can help steer us in the right direction--a proposition that I do
| not believe--then there best be some clear way to tell us how to
| avoid the pitfalls other than "I know it when I see it."
| silent_cal wrote:
| The problem with programming paradigms is that people tend to
| follow them obsessively, to the point where breaking from the
| paradigm seems automatically bad. For example, the four "pillars"
| of OOP are kind of arbitrary in my opinion, so I don't see an
| issue with breaking them, but sometimes writing a class is a
| better way to handle a collection of inter-related variables &
| functions. I don't think that makes me an OOP "adherent". It's
| not really possible to determine a priori if one theory will
| always be better than another when it comes to writing programs.
| tomxor wrote:
| Correct, more generally the problem is often absolutism, and
| presenting or applying ideas as absolute truths.
|
| All of the ideas have merit, they have cases where they work
| wonderfully, and a lot of places where they do not. This issue
| extends beyond programming patterns and paradigms, not only
| into the rest of technology but life in general. You cannot
| unsee this, you will start to see "worked for me"s being
| presented as "this is the solution to all things" everywhere.
|
| My first criticism to observation based conclusions anyone
| suggests is usually "that's subjective" and the following
| criticisms are usually exploring the parameters of that
| subjectivity, my partner is so tired of me saying this, because
| everything is subjective - I shouldn't need to say it, but we
| seem to live in a world where it's increasingly necessary to
| point out.
| danielvaughn wrote:
| Agreed. My favorite example of this is domain-driven design. I
| _love_ the core concepts - get everyone on the same language,
| make sure the code follows directly from business rules, etc.
| But you open the book and it 's a flurry of absurd terminology
| that does nothing but obfuscate whatever the author is trying
| to talk about.
|
| Then that terminology gets tossed around by hardcore adherents,
| and you end up more confused about software development than
| before you learned about DDD. It's a shame.
| silent_cal wrote:
| It may be because programmers are often also attracted to
| mathematics, and so they think everything in programming must
| be very carefully defined, and everything must follow from
| axioms. In reality, programming has a lot more in common with
| a practical skill like carpentry - you use the best tools &
| methods available depending on the product you're trying to
| make.
| edgyquant wrote:
| Funny you chose carpentry which is very much a field where
| everything must be mathematically tested and proofed.
| dboreham wrote:
| Obvious reason to study FP is: when, inevitably, someone appears
| who believes they are smarter than you due to their love of FP,
| you can more effectively defeat them.
| Traubenfuchs wrote:
| In such a situation you can also chose not to engage. The FP
| nerd might perceive this as you giving up, but a strong, mature
| personality like yours allows you to know you are the true
| winner.
| harveywi wrote:
| Wanderer: What is the secret to eternal happiness?
|
| Guru: To not argue with fools.
|
| Wanderer: I disagree.
|
| Guru: Yes, you are right.
| b5n wrote:
| > Sometimes I just agree with people so they can stop
| talking.
|
| - Jet Li
| filoleg wrote:
| This is so true, it hurts.
|
| From my personal (and rather limited) experience, there are two
| kinds of people who are into FP. First are those who will act
| like christian missionaries or competitive vegans and tell you
| all about it in the most obnoxious way possible every time they
| see you. And the rest are those who you wouldn't even know are
| into FP.
|
| Obviously exaggerating for a comedic effect here, as there are
| a few people in the middle. But the median of my personal
| experiences is definitely very well described by just those 2
| commonly present types above.
|
| You joke, but your "to shut the obsessed ones down easier"
| reasoning for getting into FP was one of my primary reasons for
| doing the same (along with just actually liking FP paradigms
| and learning quite a bit of cool stuff from it).
| magicalhippo wrote:
| Being self-taught, once we got internet back in the days I
| spent a lot of time on IRC for help with programming. As I
| grew more experienced I spent a _lot_ of time on IRC helping
| others.
|
| After a decade or so, I formulated a theory based on my
| myself and those I helped on IRC. It seemed many (most?)
| programmers starting out followed a similar trajectory where,
| as they became competent programmers and grew confident in
| their skills, would latch on to some way as _the_ way.
|
| Then, over time, as they got a lot more experience, they'd
| realize that often there are many different approaches with
| different merits and tradeoffs, and not get so dismissive to
| other approaches.
|
| Could it be your "two kinds" are those that just became good
| at FP, and those that have been good at it for a while and
| grown in experience?
|
| Anyway, not saying this is any profound insight, just
| something that struck me at some point during my journey.
|
| edit: Not all would grow beyond that initial stage. Some
| plateaued shortly after. But for myself and many of those I
| followed over time seemed to fit this.
| q7xvh97o2pDhNrh wrote:
| I learned a ton through IRC, too! And I'd give a strong +1
| for this pattern. Personally, I think it applies generally
| to a lot of fields. Once someone has sufficient experience
| and wisdom, they inevitably come face-to-face with how
| little they truly know.
|
| Ideally, that humility is paired with a general sense of
| wonder and curiosity. I think, once you realize how little
| you know, it gets so much easier to (re)embody the
| childlike curiosity and desire to learn more. I don't think
| it's a given, though -- and sometimes (at the risk of
| arrogantly declaring myself to be humble), I find it pretty
| hard not to be overwhelmed by the massive volumes of
| reality that I'll never get to learn about.
|
| William Butler Yeats had a slightly different -- but far
| more beautifully phrased -- take on it in his poem, _The
| Second Coming_ : [1] The best lack all
| conviction, while the worst Are full of passionate
| intensity.
|
| [1]: https://www.poetryfoundation.org/poems/43290/the-
| second-comi...
| peoplefromibiza wrote:
| I admit I laughed at this!
|
| Whatever is the motivation, I'll say that the more people learn
| FP the better.
|
| It won't hurt.
| [deleted]
| thankful69 wrote:
| serde111 wrote:
| If you learn FP, in a real FP language, it will bring discipline
| into the way you write code. All code you write, once you "get
| it", functional or non-functional may become an order of
| magnitude better.
| [deleted]
| tresqotheq wrote:
| Because Haskell is awesome, and if you want to code in Haskell,
| you need to grok functional programming.
| tpoacher wrote:
| I have a feeling the term "functional programming" will be a
| negative term by the end of the decade.
|
| Not "functional aapproaches", just "functional programming".
|
| In the same way that now "Object-oriented programming" is a
| negative term (but OO techniques in isolation where appropriate
| by context are totally fine).
| jacquesm wrote:
| > I have a feeling the term "functional programming" will be a
| negative term by the end of the decade.
|
| And what do you base this feeling on?
|
| Functional programming has been on a very slow and steady rise
| since... the 1950s. In fact the site that you are writing this
| on is written in a functional programming language.
| baby wrote:
| slow and steady doesn't win the race :p I think FP would have
| to get big before getting any bad rap, and I don't think it
| will
| jacquesm wrote:
| FP has a lot going for it and it is gaining traction bit by
| bit in all kinds of domains where previously this was not
| the case.
|
| I'm not sure if we should lump Erlang/Elixir in with
| functional programming (I think they should be but others
| may disagree because of the Prolog ancestry), but Clojure
| is definitely there as is Haskell, F# and so on.
|
| Reliability in software is rapidly becoming a key item, as
| more and more real world processes are directly influenced
| by software accidents have the potential to have very bad
| consequences, and functional programming is very good at
| completely avoiding certain classes of bugs. Couple that
| with mature eco systems and success stories such as
| WhatsApp and I think we are getting closer to seeing FP
| become mainstream.
|
| What really would move the needle is if software
| engineering were to be held to the same standard as regular
| engineering: liability. Sooner or later this industry will
| have to grow up and all the band-aids in the world won't
| help to achieve that if it isn't addressed at the
| foundation.
| eatonphil wrote:
| I think the best reason to study FP is to get out of the OOP
| mindset.
|
| But ideally in the real world you don't go crazy with either.
|
| Objects are excellent for data but OOP is a mess for control
| flow.
|
| Immutability is great but everything-is-recursion is not.
|
| And so on.
|
| When performance comes up all of this goes out of the window,
| maybe. But I'm talking about good defaults for correct, readable
| programs.
| kalekold wrote:
| > I think the best reason to study FP is to get out of the OOP
| mindset.
|
| > Objects are excellent for data but OOP is a mess for control
| flow.
|
| http://nomad.uk.net/articles/developers-who-hate-on-oop-don'...
| cardanome wrote:
| > If OOP is causing complexity in your program it's either
| the wrong tool for the job or you are using it poorly.
|
| No.
|
| The whole point about OOP is that it increases complexity. It
| uses higher levels of abstraction to organize the program.
|
| Sure you might end up with a program that is possibly easier
| to understand and maintain and maybe even shorter but always
| more complex than the strict procedural equivalent. Simply
| cause you increased the levels of abstractions one needs to
| go through to understand the program.
|
| That is, of course, not OOP specific. Introducing any form of
| abstraction introduces extra complexity. If you use the
| abstraction right, the problem becomes easier to handle but
| you always pay a cost.
|
| Though the have a point with
|
| > If you have used OOP well and the program still turns out
| more complicated than if it was written in a procedural style
| then you may as well use procedural code.
|
| The art of software engineering is finding a level of
| abstraction that is appropriate for the complexity of the
| problem that is to be solved. Don't over-engineer but also
| don't under-engineer your software.
| pdpi wrote:
| Funnily enough, I disagree -- I find that the overwhelming
| majority of problems with OOP come precisely from trying to use
| it with data. The only thing it's good for is precisely control
| flow at the macro level.
| eatonphil wrote:
| We'll just have to agree to stay away from each other's code.
| :)
| guelo wrote:
| One of the bigger advantages of OOP that I rarely see discussed
| is the natural namespacing that you get. In other paradigms you
| end up polluting the global namespace more easily, harming
| autocompletion and discoverability.
| pharmakom wrote:
| Most FP languages have modules so not sure where this idea
| comes from.
| jrvarela56 wrote:
| | Objects are excellent for data
|
| Check out DOP
| https://blog.klipse.tech/dop/2022/06/22/principles-of-dop.ht...
| and Rich Hikey's critique of OOP (~'objects are custom
| languages on top of data'; they force you to learn specific
| semantics to manipulate plain data structures and make it tough
| to reuse your code).
| dkarl wrote:
| > Objects are excellent for data
|
| Objects are great for modeling data as long as you still
| think of it as data, and you can write good data processing
| programs using OO language constructs.
|
| OOP as an approach to programming gets it backwards, though.
| OOP encourages you to think of the objects as primary and the
| data representing them (on the wire, in a datastore) as a
| secondary, inferior manifestation. This is the opposite of
| true. The software's value is created by its handling of data
| on the wire, reading data from other systems and writing data
| to other systems. OOP objects provide no value except by
| reading and writing data. If you start believing that the
| objects provide the value and the data exists to support the
| objects, as OOP encourages, then you start to suffer from all
| kinds of delusions.
| lostcolony wrote:
| Once you start thinking that way, you start wondering why
| Objects, rather than (from Java) records, or (from most
| every other language) structs/tuples.
|
| That is, why bundle functions with the data and encapsulate
| it as a new type that ties them together? It invites the
| very thing you're saying not to do; if you want to think of
| it as just data...then make it just data. Nouns only; no
| verbs. Even if you have a verb as data, treat it as a noun
| (i.e., a higher order function).
|
| It's all translatable; you can break an object into
| functions and data, and create an object bundling functions
| and data, but, as you say, it's about how you think...and
| objects do not encourage you to think about the underlying
| data, but about the abstraction. And abstractions are
| leaky, don't translate well into new domains, and are much
| harder to communicate (both at an API level and between
| humans) than data.
| vkou wrote:
| The semantics of objects are pretty straightforward, but the
| assurances that they provide on top of your data is their
| main value add in this context.
|
| Yes, things like protobufs, or equivalents thereof provide
| you with a list of auto-generated low-level assurances, but
| there are often bits of non-trivial business logic about data
| modification/reading that cannot be easily expressed outside
| of a object implementation in a Turing-complete language.
|
| They also clearly express a concept of, and when used
| correctly, boundaries for data ownership, which for non-
| ephemeral data can be important.
| jcelerier wrote:
| > (~'objects are custom languages on top of data';
|
| how is that a bad thing - that's literally the point of the
| activity of programming, creating domain-specific
| sublanguages to manipulate data in a way that is readable by
| domain experts of this specific data
| jrvarela56 wrote:
| The argument is that this default forces you into creating
| DSLs for basic data manipulation (it's all [] and {} in the
| end).
|
| You end up with 'custom' logic with custom naming that
| increases the overhead of using your codebase. That's a
| long way of saying your code is less reusable.
|
| In DOP/FP land, you create functions to manipulate basic
| data types and your domain-specific knowledge ends up
| encoded as basic data types (say you want validations on a
| model, you'd encode those as a {} and create functions to
| validate vanilla []/{}).
| oxff wrote:
| > Objects are excellent for data
|
| They are not. If your data is in objects, you have already
| demoted data as a first class member of your language (ie.
| Java)
| rr888 wrote:
| > OOP is a mess for control flow.
|
| I used to think this until my new project where everything is
| functional, everything is reactive, everything is a lambda.
| Each function is very simple but the whole thing is impossible
| to trace.
| freedomben wrote:
| I've seen functional code like that as well, and it's truly
| awful. If all FP was that way I'd avoid touching it with a
| 1,000 foot pole. Most of the time though it's a developer who
| writes bad code no matter which language/paradigm they're in,
| but FP does give them tools to make it even more unreadable
| bitL wrote:
| Immutability is slow, so if you are somebody squeezing the
| maximum FLOPS out of a CPU, you might want to stay away (sorry,
| 1.3x slowdown in your best case is not acceptable, and "leave
| it out to the compiler" is not a valid argument).
|
| It's like with project management - the iron triangle of speed,
| quality, price, pick two. With each programming paradigm you
| pick a different set of attributes that might or might not be
| the best for what you need and they enable you on one thing and
| constrain you on another thing.
| duped wrote:
| Immutability is an API not an implementation. Immutable code
| often outperforms mutable, it depends on the use case.
| bitL wrote:
| There is often some "redefinition of terms" going on with
| dedicated functional programming folks in order to assert
| their claims as you just demonstrated. There was some
| benchmark where mutable Java was shown to be around 30x
| faster than immutable OCaml and the discussion went to
| something like "no, no, that's a wrong comparison, compare
| it with immutable vs mutable OCaml, that is then just 2x
| slower! And the next compiler revision will remove it! 100%
| sure about it!" etc.
|
| Why can't other modes of thinking coexist with your view?
| FP is OK, so is OOP, so is imperative, low-level machine
| code, "loop programs" (see Dennis Ritchie dissertation),
| logic programming etc. I like them all but hate it when
| somebody tries to push me one way telling me all other ways
| are wrong.
| mrkeen wrote:
| Awesome, I'd love to read it!
| freedomben wrote:
| > _Why can 't other modes of thinking coexist with your
| view? FP is OK, so is OOP, so is imperative, low-level
| machine code, "loop programs" (see Dennis Ritchie
| dissertation), logic programming etc. I like them all but
| hate it when somebody tries to push me one way telling me
| all other ways are wrong._
|
| Why do you think GP is saying or doing that? I think
| you've put a _lot_ of words into their mouth that aren 't
| there, and then got yourself worked up about it, enough
| to accuse them of ignorance and small-mindedness (at
| best).
|
| I see absolutely nothing in their comment that even
| weighs in favor of FP, let alone saying other modes of
| thinking can't coexist. For all we know GP is a rabid OOP
| fan but sees the value in immutability (which FP
| certainly does not have a monopoly on).
| bitL wrote:
| OK, my apologies, that comes as a baggage from previous
| discussions with FP experts that routinely dismissed any
| opposing ideas and the OP's answer struck the same chord.
| freedomben wrote:
| Immutability can be fast or slow depending on the
| implementation. There are tons of copy-on-write
| implementations that blaze past mutable implementations. When
| the compiler knows that a particular variable/piece of data
| will never be changed, it opens up a ton of optimizations
| that can be used to make it fast. With mutable memory it's on
| the developer to optimize, rather than the compiler. Most of
| the time, the latter is better at it.
| guelo wrote:
| The problem is that developer has no idea if the
| implementation is going to be performant for their use
| case. The mutable compilers normally have less magic and
| thus are easier for the developer to understand and
| optimize. FP is really just a higher level language, that's
| why they don't teach algorithms classes using FP languages.
| bitL wrote:
| With infinite memory and "no cost memory allocation" you'll
| be likely correct, but in real world production loads
| you'll hit those limits quickly and then the immutability
| is likely getting in the way. Imagine just keeping a large
| (possibly compressed) bitmap (TBs in memory) to keep track
| of subscribers in your queue which is what many distributed
| queues use - how would you do it in immutable fashion? Copy
| the whole bitmap on each small change? There are simply
| many problems where immutability is the wrong answer if you
| want anything resembling performance.
| freedomben wrote:
| Absolutely, that would be one of the cases where "most of
| the time" is not "this time." Although for most
| developers/applications, I would imagine keeping TBs of
| bitmap in memory isn't a common task. Fetching some rows
| from the DB and transforming them into some sort of HTML
| or JSON probably is
| cpursley wrote:
| Just don't make the mistake of studying FP first...
|
| I can't seem to wrap my head around OOP. There's too many
| concepts in OOP. In FP it's just data and functions for
| transforming that data.
| magicalhippo wrote:
| > In FP it's just data and functions for transforming that
| data.
|
| In OOP it's just data and methods for manipulating that data.
| Floegipoky wrote:
| I started with mainstream procedural and OO languages like
| C++ and Java. I felt like I had a pretty good understanding
| of OOP by the time I left university. Later, learning a
| little about FP took my OOP to a whole new level. I really
| recommend reading Sussman and Steele if you haven't already,
| it's basically a constructive proof showing how to represent
| objects in a functional language. Unfortunately the title is
| so boring that generations of CS undergrads skipped reading
| the paper, so the zeitgeist forgot. Hewitt was another
| important researcher at the MIT AI lab at that time credited
| with discovering the Actor Model, which basically combines
| objects with a concurrency model. I've seen him post on HN
| occasionally =)
|
| So many people think "OOP == classes", and I think it's
| really a shame that (in many ways superior) alternative
| representations were relegated to the sidelines for so long.
| I see Java's relatively recent inclusion of algebraic
| datatypes as a tacit admission that contemporary computing
| requires different primitives, and I expect to see a shift in
| best practices towards objects represented as immutable data
| structures combined with effectively-pure functions. Just
| like the FP folks have been saying all along!
|
| > This work developed out of an initial attempt to understand
| the actorness of actors... Sussman suggested the experimental
| approach of actually building an "ACTORS interpreter"... When
| it was completed, we discovered that the "actors" and the
| lambda expressions were identical in implementation.
|
| https://dspace.mit.edu/handle/1721.1/5794
| bitL wrote:
| Can you explain monads to a 5-year old? Can you explain
| objects?
| unsafecast wrote:
| Yes, I can definitely explain monads to a 5-year old.
|
| See, a monad is like a box. You can put something in the
| box and close it very easily. But once it's closed, you
| can't open it anymore. The action of closing the box is
| called the wrap operation.
|
| What you _can_ do though, is tell someone else to do
| something to the thing inside the box. For example, if you
| put a toy in and close the box, you can ask a friend to go
| ahead and add a new one in. Or remove the toy. These are
| monadic functions.
|
| That's it. That's literally it. It's just a pattern of
| hiding the data and letting monadic functions be the only
| ones that deal with it.
|
| In the case of the Maybe monad for example, you'd have the
| unwrap function that tries to get whatever is inside out,
| but it might not be able to (if the box is empty).
| taeric wrote:
| Not going to lie, I don't understand that explanation. It
| honestly sounds more like you are describing a form of
| encapsulation, as the contents of the box are hidden and
| someone else has the ability to open said box to get
| access to it.
|
| I also find the appeal to a physical object to explain a
| functional concept is rather amusing.
| ModernMech wrote:
| > I also find the appeal to a physical object to explain
| a functional concept is rather amusing.
|
| The challenge was to describe it to a 5 year old. 5 year
| olds are better with concrete thinking than abstract
| reasoning. This is what made using the turtle in Logo a
| genius move, as it allowed younger children to write
| programs by conceptualizing a physical turtle that can
| move, rather than thinking in terms of an abstract
| function that mutates data.
| taeric wrote:
| Fair, and I don't necessarily disagree. I think this
| leads rather close to object oriented software being
| easier to reason about concretely than functional
| programming, though. And since most people are trying to
| get a concrete job done, that feels like a significant
| claim.
|
| For turtle geometry, it is also important to acknowledge
| the metaphor and shortcomings of a more traditionally
| analytic framing of drawings. Specifically, X and Y
| coordinates for a drawing are surprisingly hard to work
| with. For example, I challenge you to describe the
| fractal snow flake in an easier way than using directions
| as a metaphor. Same for the dragon curve. This can be
| seen akin to picking a different coordinate system, I
| presume?
| solomonb wrote:
| Not sure if you are looking for an explanation of Monads,
| but Monad tutorials are a long running joke in the
| haskell world. They are almost exclusively written by
| people for whom the concept just clicked and they either
| fail provide context for someone without that experience
| or they fail to actually describe the concept correctly.
|
| I'm not gonna give you an explanation but I will say that
| IMO the best way to actually learn about them is to just
| look at the typeclass and a bunch of instances of it and
| how they are used. If you ignore all the theory (and the
| "theory") and just look at the code you will find that
| they aren't that hard to sort out from a usage
| perspective.
| taeric wrote:
| Apologies, I seem to have deleted a sentence where I
| think I can make my understanding fit that metaphor. I
| don't think they are completely unapproachable, but I am
| not at all clear that a physical metaphor works. And, I
| really wanted to shine a light on the amusing appeal to
| physical objects in a thread that is about the short
| comings of object oriented programming. :D
| solomonb wrote:
| No need for apologies! I 100% agree that the physical
| metaphor doesn't work and said so in another nearby
| comment.
|
| If you go back to Phil Wadler's original paper on
| implementing monads in haskell, he doesn't talk about
| category theory or boxes or anything. He lays out a
| handful of common things you might do in programming but
| which seem totally unrelated. For each one he implements
| a solution and then reveals that all these solutions fit
| the same interface.
| solomonb wrote:
| Unfortunately the container metaphor only works for a
| subset of monads. It fails with `IO`, `Reader`, `Writer`,
| `State`, `Parser`, etc.
| peoplefromibiza wrote:
| how about we call the box wrapper and the operations on
| it computations?
|
| metaphors are good for beginners, to grasp the concept,
| they don't need to be perfectly valid.
|
| for example the popular OOP metaphor a car is a vehicle
| becomes useless pretty much immediately.
| solomonb wrote:
| IMO the metaphor is already getting too frayed at this
| point.
|
| I'm not opposed to metaphors in general, but metaphors
| are lot like abstractions. If you don't get the right one
| then the details leak everywhere and you may as well have
| not used it to begin with.
| AnimalMuppet wrote:
| Well, for IO, it seems to me that maybe it still works.
| You're putting the entire external world in the box, but
| you're still (kind of?) doing the same thing.
| solomonb wrote:
| I don't think that is a fair comparison. Monad is a
| typeclass so it would be like explaining some specific Java
| Interface (and all the context for Interfaces) to a 5 year
| old.
|
| The Haskell (since you brought up Monads) equivalent to
| explaining Objects would be like explaining Records or Sum
| types, which would be very easy to explain and don't
| require talking about inheritance like Objects would.
| mejutoco wrote:
| I'll try.
|
| A monad is a description of actions to do and their order,
| in place of the actual actions. This description can be
| passed around and eventually acted upon.
|
| Objects (not Alan Kay's original ones but say Java) are
| abstractions that model state and behaviour together.
| Objects can share common behaviour through interfaces
| freedomben wrote:
| I don't know if you're being serious or not, but you can
| learn a ton of FP without having to understand monads. Also
| asking to explain "objects" is too ambiguous. an "object"
| in json is very simple. OOP on the other hand involves a
| mountain of different concepts, design patterns, best
| practices, etc. I would guess GP is referring to that
| stuff.
| LudwigNagasena wrote:
| You can learn a ton of OOP without having to dive into a
| mountain of different concepts too.
| pmontra wrote:
| You can write OOP code without knowing a single pattern
| and whilst laughing at Factory classes you read in
| someone else's code. You might have to reinvent the wheel
| sometimes and face some difficulties talking with people
| that know every single pattern.
|
| And there are best practices for every single language
| and paradigm.
| mdcds wrote:
| I heard following explanation of monads somewhere online:
| _" monads allow us to write imperative code in the
| functional setting. e.i. chain computations"_.
|
| But that explanation wouldn't make sense to a 5-year-old
| peoplefromibiza wrote:
| monads are a very simple pattern
|
| it takes 5 minutes to understand it, the jargon is complex,
| the implementation is not.
|
| case in point
|
| https://youtu.be/C2w45qRc3aU
|
| objects are a very leaky abstraction that usually brings
| people to build taxonomies, mostly unrelated to the parent.
|
| reuse of code, which is the selling point of OOP,also comes
| often short with a miriad of very specialized subclasses
| that have nothing in common anymore.
|
| OOP is not horrible, but it requires a good amount of
| discipline to get it right, while FP has less concepts and
| you can (usually) silo the "and now for the tricky bits"
| (cit. Robert Virding) in a small core.
|
| the rest is simple pure functions that have also the
| benefit of being stupid trivial to test.
|
| Also, you don't have to be purely functional nowadays, and
| that helps a lot.
|
| If only I learned FP sooner, my life as a programmer would
| have been so much better.
| freedomben wrote:
| You're point about testability is a good one that I feel
| is often missed. Trying to test functions in OOP code is
| often impossible because they presuppose some state in
| the "object" and if it's not initialized properly, it
| doesn't work. Then they also often make side effects. So
| you end up building a huge test harness to build up some
| state, run one test, and tear it all back down again only
| to rebuild it from scratch for the next test. It's doable
| of course, but it's easy for a simple CRUD app to have a
| 15 minute test suite and for tests to become flaky
| because of some unexpected state change done in some
| unrelated test on the other side of the code base. That's
| a special form of hell
| goostavos wrote:
| Monads are indeed way simpler. Just a few beautiful laws.
| The problem is that they take a loooooooooooong time to
| really internalize. Saying it takes "5 minutes" is empty
| in the same way that "learn C++ in 24 hours" claims are
| (or you're hella smart!).
|
| There's a quote that floats around that's like "as soon
| as you understand monads, you lose the ability to explain
| monads." It takes a ton of leg work to make them click.
| They're simpler, but definitely not easy (in the Rich
| Hickey sense).
| bitL wrote:
| Ok, so you understood flatmap and therefore monads in 2
| minutes. Now you need something that needs nested monads.
| That's where major complexity suddenly appears - your
| code is no longer simple and is full of artificial
| constructs like transformers just to do simple things.
| Moreover, anyone who reads your code must know all
| language constructs you are using or they are lost and
| can't fix any issue in your code.
| solomonb wrote:
| > Moreover, anyone who reads your code must know all
| language constructs you are using or they are lost and
| can't fix any issue in your code.
|
| Does this not apply to every language ever?
| peoplefromibiza wrote:
| 5 minutes is the time it takes to understand how the
| pattern works.
|
| Be good at it?
|
| More like a thousand hours.
|
| there is nothing that is really simple, but before being
| simple, everything looks difficult.
|
| p.s. I love Rich Hickey and especially his keynotes at
| Clojure conferences.
|
| I've watched simple made easy at least 10 times.
| trebbble wrote:
| > I can't seem to wrap my head around OOP. There's too many
| concepts in OOP.
|
| Which ones? You're familiar with structs, right? OO is just
| structs with a little magic & sugar. Not even that much.
| Objects, methods, properties, instances, classes:
|
| Imagine if, when defining a struct type, you could put
| references to functions on it, such that any struct of that
| type would contain those same fields with references to the
| same functions you put in the type definition. Then, if you
| create a struct of that type, the compiler and/or runtime
| will helpfully and magically appends an extra argument to
| those function signatures, assigning it some conventional
| name ("this", perhaps) and, if you call such a function "on"
| a struct of that type, the compiler/runtime will quietly, in
| the background, pass a reference to the struct you called the
| function "on" in that last argument slot, so that within the
| function you can make use of the function's "parent" struct
| (as, perhaps, a variable named "this").
|
| The struct type with slightly-magical function references is
| a class.
|
| The fields on the struct containing references to functions
| with the magical "this" argument appended when invoked, are
| methods.
|
| A struct of that struct-type is an object, or _instance_ of
| the struct type, if you will.
|
| Fields on the struct are properties or members or whatever
| you like to call them. Static:
|
| What if you could tell the compiler/runtime not to bother
| appending that "this" argument to some of those functions you
| attached to a struct type definition? Or to have a given
| field on a struct type definition always point to the same
| location for every single struct of that type, so that they
| all essentially share a single variable? That's what "static"
| means. Inheritance:
|
| What if you could tell the compiler/runtime that it should
| associate one or more other struct type definitions with the
| struct type you're currently writing, and that if it can't
| find a given field (including ones that are refs to
| functions, aka methods) on a struct of this type, it should
| check an associated struct of the other type(s) and only
| error if it can't find it there, either. With the result that
| a struct type so constructed effectively contains all the
| fields of the structs associated with it, unless a duplicate
| exists on that child struct type, in which case that takes
| precedence.
|
| That's basically inheritance. It's all about setting up and
| manipulating those kinds of relationships & precedence for
| lookups. That's all. Abstract, et c.:
|
| Just ways to have the compiler enforce constraints and
| requirements on a struct type definition.
| Final
|
| I do solemnly swear this is a constant, not a variable.
|
| Now, there are implementation details under the hood for all
| this, but that covers actual usage, terminology, and concepts
| pretty well. You don't need to dig into the details of e.g.
| vtables (one tool for efficiently settling those inheritance-
| leveraging field lookups) unless you're implementing OO
| itself.
| kephasp wrote:
| > _Immutability is great but everything-is-recursion is not._
|
| Why oppose a real pattern and a imaginary one?
| jstx1 wrote:
| I mean there's other options too. Go for example is mostly
| imperative(?) - it doesn't encourage heavy OOP or pure
| functional programming. Rust has more functional features but
| it's still neither purely functional nor heavily OOP. Julia
| isn't OO at all but it doesn't emphasize FP either.
|
| Those are just three languages that are all (1) modern, (2)
| generally well received, (3) neither OO nor heavily functional
| and (4) still very different from each other.
| mikewarot wrote:
| _The recent focus on adapting functional programming_ is a
| reaction from the shift to the dangerous quadrant of the
| immutable-mutable /unshared-shared "Magic Quadrant" chart.
|
| Before multi-core, multi-threading, it didn't matter how or when
| you decided to update your local variables, they were YOUR local
| variables... unshared.
|
| With threading, and multiple cores, we all just blindly moved
| right to the mutable/shared quadrant... the one in bright red...
| which effectively _changes the laws of physics_ of your programs.
| Effectively every piece of code now runs in it 's own time and
| space, and if you don't coordinate things correctly, it's like
| killing your own grandparents.
|
| It took me a long time to understand why you'd want to refactor
| your code until everything was immutable[1], but now that I get
| the lesson, its something I won't forget.
|
| Functional programming avoids mutable data, and thus,
| intentionally or not, works well in a world of shared data.
| Because pure functions have no side effects, they are timeless -
| they need no synchronization.
|
| Spend a few nights watching everything Kevlin Henney has said in
| the last few years, and you'll have a _much_ better handle on
| things. [1] - https://youtu.be/APUCMSPiNh4
|
| [Edit] Incorporate wording suggestion from DonaldPShimoda
| badpun wrote:
| I've worked in two functional codebases so far and I'd say that
| in both cases the mutation of shared state was just moved to
| database and its transaction semantics. The FP code itself was
| about mostly stateless server-side processing. So, FP wasn't
| doing anything for us on that front. The main selling point for
| it was that it makes program more composable, more concise and
| easier to refactor (as you're effectively working with higher-
| level abstractions).
| lostcolony wrote:
| >> in both cases the mutation of shared state was just moved
| to database and its transaction semantics. The FP code itself
| was about mostly stateless server-side processing. So, FP
| wasn't doing anything for us on that front.
|
| Sure it was. While it didn't force devs to stop using mutable
| state, you just called out that it -did- force them to move
| that state out of the service and into something with ACID
| guarantees, and write their server code in a way that was far
| more stateless. That sounds like a win to me?
| nine_k wrote:
| Your global variables were / are shared with yourself, even in
| no-concurrency case. With typical control flow being far from
| linear, it's easy to surprise yourself with unexpected state
| mutation.
| Scarbutt wrote:
| Hence the value of immutability even for single-threaded
| code.
| Jtsummers wrote:
| Giving me flashbacks to inherited codebases from old-school
| FORTRAN coders... // 500 variables shared by
| everything main loop "task" 1 "task" 2
| "task" 3 ... "task" n
|
| So _t121_ is now supposed to only be used by task 3, but "t"
| as a prefix means it is temp. However, we don't want to
| change all the references. So just don't use it everyone
| else, please?
| MaxBarraclough wrote:
| Right. Pure functions make it considerably easier to reason
| about code, even in the absence of concurrency.
|
| It's a shame D's _pure_ modifier (to statically guarantee
| purity) isn 't available in many other languages. [0] SPARK
| Ada has something similar in that functions must always be
| pure, forcing procedures to be used for impure functionality.
| [1] _edit_ I think that 's mistaken, SPARK appears to permit
| functions to read globals but not to modify them.
|
| _edit_ John Carmack has written about this kind of thing.
| From [2]:
|
| > _if a function only references a piece or two of global
| state, it is probably wise to consider passing it in as a
| variable. It would be kind of nice if C had a "functional"
| keyword to enforce no global references._
|
| [0] https://dlang.org/spec/function.html#pure-functions
|
| [1] https://learn.adacore.com/courses/intro-to-
| spark/chapters/01...
|
| [2] https://cbarrete.com/carmack.html
| bitL wrote:
| This resembles a situation when I got a new boss who once tried
| to write a 2-threaded app and got burnt, so from then onward he
| mandated to never use multiple threads (despite me using it
| safely on 65000+ threads before). A better answer would be
| "most devs aren't skilled enough to use many threads/mutable
| shared objects, so lets mandate immutable for basic devs so
| that they don't get burnt". But why would you prevent proven
| experts from operating in the dangerous quadrant? Does
| everything have to become dumb to make it safe?
| jerf wrote:
| That dangerous quadrant has a track record of chewing up and
| spitting out "proven experts". I'd put your question in the
| same class of question as "Look, I know memory management in
| C is just dangerous, but do we have to make everything dumb
| to make it safe?" False dichotomy; the solution to everything
| isn't to "make it dumb", but the proven experts have a long
| track record of being chewed up and spit out and the answer
| isn't to tell them to just Git Gud either. We tried that. We
| tried that a _lot_. It doesn 't work.
|
| The solutions to concurrency pretty much all involve staying
| out that quadrant as much as possible. Immutability isn't the
| only solution. Another is to confine all variables to one
| thread. Erlang, for instance, superficially uses immutability
| to achieve this, but a deeper reason it achieves it is that
| there is simply no way for a "thread" (what Erlang calls
| "process") to modify a variable that another thread can see;
| this is sufficient. (See what Elixir does.) Rust implements a
| super-rich system of variable ownership that allows you to
| implement the constraint that no variable can be unexpectedly
| just modified by an arbitrary thread in a far richer fashion
| than just hard-locking all memory to a particular owner
| thread. This is also sufficient. I program a lot in Go, and
| while it lacks compiler support for forcing you to stay out
| of that quadrant, my code runs at high concurrency rates
| precisely because I've learned how to stay out of there, and
| my code looks very Erlang-ish when you look at the
| concurrency patterns in play.
| Chris_Newton wrote:
| _new boss who once tried to write a 2-threaded app and got
| burnt, so from then onward he mandated to never use multiple
| threads_
|
| An unfortunate overreaction, I agree.
|
| _Does everything have to become dumb to make it safe?_
|
| I don't think trying to avoid shared mutable state is dumb.
| It's deliberately choosing a safer default, just like not
| allowing all references to be null or not accepting the
| string "123" where an integer like 123 is needed.
|
| Sometimes it can be useful to have shared mutable state, or
| to make a reference nullable, or to accept different types of
| data and quietly reinterpret them the same way internally.
| But these are inherently more dangerous styles of programming
| -- they create opportunities for mistakes that are otherwise
| systematically prevented -- so it seems reasonable to
| encourage the safer alternatives unless there is a good
| reason not to use them, and to make the more dangerous
| choices the ones you have to make explicitly.
| kephasp wrote:
| I'd ask the opposite question: why would you use a dangerous
| paradigm when a safe one exists and the dangerous one doesn't
| offer much benefit?
| bitL wrote:
| The question is if the "unsafe" one really doesn't offer
| much benefit. If the unsafe one leads to a 3x speed up or a
| 10x lower memory consumption, then I'll use it.
| jahewson wrote:
| > Functional programming is a reaction from the shift to the
| dangerous quadrant of the immutable-mutable/unshared-shared
| "Magic Quadrant" chart.
|
| This makes it sound like you're saying that's why functional
| programming was created, which isn't the case. I assume you
| mean that this is why it's gained popularity but I don't really
| agree with that - it's certainly valuable but most functional
| programmers will never touch threads. I'd argue that programs
| without state are just easier to reason about and debug and for
| most software this is where the value comes from.
| klipt wrote:
| > I'd argue that programs without state are just easier to
| reason about and debug
|
| Right, isn't the fundamental trade-off between programmer
| efficieny and runtime efficiency?
|
| Immutable structures are easier to reason about, but almost
| always run slower than their mutable counterparts.
|
| The holy grail would be immutable structures that are equally
| performant, but I'm not sure that's even mathematically
| possible in general.
| kephasp wrote:
| Is there data supporting the notion that immutable
| structures are slower?
|
| There are many cases where there won't be a single
| difference in performance and there are a bunch of cases
| where immutable structures will be way faster than mutable
| ones.
| philipkglass wrote:
| The most obvious case I'm aware of is with large
| numerical simulations in scientific computing. I worked
| on molecular simulations in graduate school. The core
| data structures are large (many-gigabytes) arrays, and
| almost every element of the array is updated on every
| iteration. Everything that requires more memory or even
| more memory accesses is going to be slower. In business
| applications you're usually not updating everything in a
| data structure all the time, so I can see how clever
| immutability may improve performance.
| philipkglass wrote:
| It's not possible to do always but it feels like it should
| be possible in special cases. If you can prove that a value
| V2 is ultimately derived from a modification of V1, and V1
| is never referenced after creating V2, then it should be
| possible to invisibly convert this to an in-place mutation
| [1]. In the case of applying a bunch of text normalization
| rules to a string, for example, I care about the final
| string but not the intermediate states. It could be
| mutation underneath and I'd be none the wiser, except that
| the runtime performance would be better.
|
| In Scala you can add a "@tailrec" annotation to recursive
| functions. The annotation means that the function is
| guaranteed to recurse efficiently (without growing the
| stack) OR that the compiler will give an error telling you
| why it can't be guaranteed. I could imagine a similar
| annotation like "@withmutation" for functions where you
| want to guarantee efficient in-place mutation at runtime.
| As it is, when I run into performance pain points in Scala
| I redo the critical bits with (manually written) while-
| loops and imperative mutation.
|
| [1] Unless you later attach a debugger and expect to be
| able to observe V1 and V2 simultaneously. But I presume
| this sort of issue already comes up and is somehow dealt
| with regarding other compiler optimizations.
| cassepipe wrote:
| I think this is the idea behind Richard Feldman's Roc
| programming language https://www.roc-lang.org/
| at_compile_time wrote:
| What are the advantages of complete immutability when we can
| write compilers that specifically prevent shared mutability?
| You're avoiding the dangerous quadrant but also excluding a
| valid one. I'd definitely prefer FP's solution over Python's
| GIL, but it still feels like an unnecessary compromise.
| assbuttbuttass wrote:
| Most functional languages allow mutability when you need it,
| they just default to immutable data. Haskell might be the
| exception, where everything has to be immutable all the time
| marcosdumay wrote:
| Everything does not have to be immutable in Haskell. It's
| only that mutability can only exist in IO or some other
| context that deals with it. The language enforces purity,
| not immutability.
| poorlyknit wrote:
| This is not true, Haskell of course allows you to mutate
| state. It just forces you to declare it: For example,
| there's a MutableByteArray type whose operations only work
| in a specific Monad (because Haskell...) [1].
|
| There's also more basic stuff like IORef which represents
| an assignable variable [2]. Again, you're constrained to
| use this in IO contexts.
|
| Etc.
|
| Haskell basically just forces you to do that thing someone
| else in this thread mentioned: Write functional APIs, allow
| side effects but make them explicit and confined to very
| specific places.
|
| [1]: https://hackage.haskell.org/package/primitive-0.7.4.0/
| docs/s... [2]: https://hackage.haskell.org/package/base-4.1
| 6.3.0/docs/Data-...
| heavenlyblue wrote:
| Functional programming is representing the program state as a
| single expression, so that the compiler could do funky maths
| stuff in reordering things in it. It has little to do with
| immutability or functions per se.
| DonaldPShimoda wrote:
| Just a small nitpick about your comment:
|
| > Functional programming is a reaction from the shift to the
| dangerous quadrant of the immutable-mutable/unshared-shared
| "Magic Quadrant" chart.
|
| I might rather say " _The recent focus on adapting functional
| programming_ is a reaction... ". Functional programming itself
| is nearly as old as the modern computer (McCarthy's first LISP
| paper was published in 1960), but your phrasing kind of
| suggests that the entirety of FP is a recent innovation.
| frostwarrior wrote:
| Functional programming itself is really old. Practical
| functional programming for scale is the new trend.
|
| What's new is the scale of software being developed right
| now. Developers simply can't afford to create mutable and
| shared state as if their program was just another desktop
| program, executed on a computer disconnected from the
| internet.
|
| Sooner or later we learn that focusing on the human value of
| code (I mean, making the code clear, concise and simple to
| read) pays off way better on the long run rather than
| optimizing for CPU cycles or memory footprint.
| tacone wrote:
| Simply put: to have one more option.
| nnoitra wrote:
| So you can pretend to be smarter than you are solely based on the
| paradigm.
| clircle wrote:
| As an R user, FP seems like the norm. Working with data or stats
| without FP mechanics sounds unpleasant.
| epgui wrote:
| As another R user and FP aficionado, most R code is non-FP. If
| you work somewhere where you need to use R, and FP patterns are
| the norm, you're lucky!
| dbrueck wrote:
| In my mind, 'wustl.edu' will forever be one of best treasure
| trove FTP sites back in the late 90's. That is all.
| [deleted]
| pharmakom wrote:
| Even if you don't find it very interesting, functional
| programming can make you rich.
| nnoitra wrote:
| How come, it's barely used in industry lol.
| kephasp wrote:
| It's not used by many, but it's used by niche environments
| that have a lot of money, especially in Fintech. When you
| want your code to be extremely reliable while really fast,
| there's nothing like languages like OCaml or Haskell.
| epgui wrote:
| You don't become rich or great (and then maybe rich) by
| following the biggest crowd, so I don't see how your response
| is relevant.
| pharmakom wrote:
| Top paying languages are Clojure, F#, OCaml
| jjice wrote:
| It's the same reason to learn alternatives to anything: to have a
| wider breadth of knowledge. Your thought process becomes more
| open and can better way alternatives because you actually have
| alternatives.
|
| My compiler course in college was in SML and it was excellent for
| teaching more more than just compilers. It taught me a lot about
| recursion and the idea of composing a problem in terms of itself,
| which has been incredibly powerful in my career.
|
| Being exposed to other great concepts like algebraic data types
| (sum types/Rust's enums) just helps expand my way of thinking
| when I write PHP code at work.
|
| The idea of using a function as a fundamental building block for
| abstracting ideas has also been fantastic. Mostly in the form of
| using functions as arguments to alter behavior.
|
| As with everything, there's a balance. I don't write pure FP, nor
| do I want to, but the ideas are huge. Same with OOP. OOP has some
| good ideas, but I don't lean on the words of the GOF as if they
| were GOD. Pulling in the best of all worlds has been really huge
| for my life as an engineer.
| Banana699 wrote:
| Dijkstra once explained how his process for writing code is to
| state\solve the problem in the most obvious and natural
| language possible. If a compiler\interpreter existed for that
| language, then he's done, he now has an executable solution to
| the problem. If not, then he recursively solves the problem of
| translating each construct of this non-executable-but-
| convenient language down into other constructs, if _those_
| constructs are executable, well and good, if not, he has to
| break them down further.
|
| Learning new programming languages, paradigms, architectures,
| approaches and formalisms aids this process because it gives
| you more mental building blocks to use in your journey from
| non-executable specifications to executable implementations.
| Even if you never write haskell, learning it makes your brain
| evolve a haskell-like pseudocode in which to think and express
| problems, and this can come in handy when the problem is most
| naturally expressed in haskell. If a haskell implementation
| exist, great, if not, transform the haskell formulation
| gradually into whatever executable form available. This, for a
| certain class of problems - let us rather unimaginatively call
| them 'haskell problems' -, is better and more enlightening than
| attempting to directly solve them in executable format.
|
| ------
|
| One common saying is "You Can Write Fortran In Any Language",
| another one is "Any Sufficiently Complicated C Program Contains
| An Ad-hoc Informal Implementation Of Common Lisp".
|
| The fundamental truth that both of those aphorisms hint at is
| that programmers are human compilers, the programming language
| they write in is their target language, the "assembly", and the
| description of of the problem they are solving is the source
| language they are compiling. Here's the thing though : just
| like actual compilers, programmers don't have to compile the
| source language all in one go. Machine compilers often go
| through several detours and meander through different
| intermediate representation of the code being translated before
| outputting the final target. The equivalent of this for
| programmers is the Dijkstra process, describe your problems in
| a hierarchy of languages that _ends_ , not begins, with the
| programming language you happen to use.
|
| If the problem is best described as a Fortran program, write it
| (in your head) as a Fortran program then implement whatever
| necessary of Fortran in the actual available language to write
| the program. If the problem is best described as Common Lisp
| program, then think about it in your head as a Common Lisp
| program then implement the necessary parts of Common Lisp in C
| to write the program (The full quote is only saying this is bad
| insofar as it happens non-deliberately and haphazardly, if it's
| deliberate then it's just good design). Programming Languages
| are notations/pseudocode/ways of thought/mental models/semantic
| repositories of meaning, they can be useful even if there is
| not a single executable implementation of them in sight.
| kazinator wrote:
| > _If a compiler\interpreter existed for that language ..._
|
| Then Dijkstra would have written a disparaging article about
| it, and then worked the solution in Algol 60.
| dial9-1 wrote:
| every program is a compiler
| orthecreedence wrote:
| I've been taking a kind of middle ground lately: build functional
| APIs. Move your side effects as far outward as possible and make
| your library's interface take everything it needs and return
| everything it computes. No HTTP calls, no database access, no
| random number generation. For example, don't have your library
| build the query and then run it, have it built the query and
| return it so it can be run at a higher-level.
|
| I know this seems obvious, but it was a breakthrough I had with
| organizing the way I built things a few years back and it has
| been serving me amazingly well. I think I originally stumbled
| onto the idea through a talk on domain-driven development.
|
| The result is that you get a lot of the benefits of functional
| (easy testing, portability, etc) but you don't have to deal with
| all the oddball patterns of recursion or currying or things that,
| yeah, sure, makes sense on some theoretical level but makes me
| want to gouge my eyes out when I try to read it. I've tried
| fully-fledged functional programming in a few cases and it
| doesn't click with me. I appreciate and understand that some love
| it, but in the end if your exposed public API is functional, the
| internals are less important.
|
| To me the important thing is the mindset: move your side effects
| as high up the chain as you can.
| adamkl wrote:
| The term for this that I have come across is "stratified
| design" and goes back to the book Structure and Interpretation
| of Computer Programs by Abelson and Sussman. I have no idea why
| this approach isn't more well known (especially compared to
| typical "layered" design approaches) as the benefits are so
| great!
|
| https://medium.com/clean-code-development/stratified-design-...
| jmt_ wrote:
| Is there a good open-source example of this paradigm? I'm
| interested by the idea but struggling a bit to see how it would
| actually be implemented for something like, say, a regular
| REST/JSON API.
| i_hate_pigeons wrote:
| this is what I learned is functional programming and I've also
| benefited greatly from it
| mdcds wrote:
| I tried learning Haskell for fun while working as a Python dev.
| Understanding importance of managing side-effects definitely
| influenced how I changed my approach to code organization at
| work.
| kephasp wrote:
| You may find it interesting to study FP a bit more, because
| recursion, when understood, is pretty universally felt as way
| more readable than its imperative alternatives.
|
| I also usually find currying extremely practical and easier for
| me when it's available.
|
| Most of us that only use FP in our day job don't do it out of
| masochism, AFAICT. I certainly don't.
| yodsanklai wrote:
| Modern languages assimilate ideas from all paradigms. Besides, FP
| isn't some theoretical obscure stuff. I'd except most programmers
| to know some rudiment of Scheme or ML.
| whitenickel08 wrote:
| I miss Erlang-ish languages in the article.
| 112233 wrote:
| That lowly imperative programming: hard to prove your program is
| correct. Functional programming: easy to prove your program is
| correct, hard to prove its' execution will fit in the known
| universe.
|
| Functional programming IS math, so it's super satisfying to learn
| intellectually. It is also a spherical cow.
| kephasp wrote:
| Why would it be hard to prove that functional code is actually
| runnable?
| rekrsiv wrote:
| Because it allows you to compose anything from only functions and
| category theory.
| agentultra wrote:
| Because there is an essential complexity to programming in
| general that you cannot escape. Avoiding functional programming
| is like navigating a dark cave by bumping into obstacles when you
| have an assistive technology that can guide you.
___________________________________________________________________
(page generated 2022-08-02 23:01 UTC)