Live data from Hacker News

Admitting That Functional Programming Can Be Awkward (2007)

prog21.dadgum.com

81–90 of 148 posts

Re: Admitting That Functional Programming Can Be Awkward (2007)

#81
post #67

Earlier quoted context omitted.

> Functional programming as a concept is well defined, and it's not merely "first-order functions". Then, sincerely, what is the definition? Does that definition succeed in excluding languages that are not considered functional, e.g. C++, Java, Python, Go? And if it doesn't, and the definition is so broad as to encompass every language, then what is the useful purpose of going out of one's way to label a language as…

Functional programming languages, more often than not, distinguish themselves with some combination of the following features: * First-order functions * Partial function application / currying * Type inference * Algebraic data types * Typeclasses * An emphasis on pure functions (side effects must be explicitly annotated), opening up more possibilities for static analysis * Lazy evaluation This is not to say that the…

> However, FP is designed to prioritize the above features, whereas other languages may not be.

This statement is pretty vauge and further supports kibwen's claim that a term "functional programming" ceased to be meaningful or is in the course of being so. I can't see the reason that Rust is not as functional as OCaml by your standard, as both fill four boxes out of seven (only OCaml has currying, only Rust has typeclasses). It can be argued that Rust was not originally designed as functional one, but that would be absurd because it doesn't relate to the current language.

Re: Admitting That Functional Programming Can Be Awkward (2007)

#82
post #42

Earlier quoted context omitted.

Eh, syntactically it hides the state as in `f x` has the same value every time, but calling functional programming stateless is a stretch, I consider it a half-truth told the newcomers to understand the concept. Functional languages still have state but they're abstracted out to function call. E.g. if you have a recursive descent parser written in Haskell, your program will still have state, not every time you're in…

In addition, every closure is also a 'state container,' as it were. This is how some functional languages e.g. Erlang emulate mutation. A function holds the desired state in a closure and evaluates to a new function closure with updated state. It's also how a stateful object system can be trivially implemented in Scheme. A few of pieces of the Erlang OTP infrastructure are actually just an elaborate mechanism to rein…

It’s important to note Erlang’s global state tools are about controlled global state. The process registry is more elaborate than a simple naming scheme in say Python or Java but really not much harder to use. However that controlled registry allows the process registry to become multi-node with minimal or no code changes for the clients. It’s comparable in power to but far simpler than Consul or etcd for finding services. I view micro services as fairly equivalent to Erlang actors as they both reinforce that state encapsulation. The same idea goes for mnesia or ETS which are comparable in power to Redis.

Re: Admitting That Functional Programming Can Be Awkward (2007)

#83

Earlier quoted context omitted.

> sometimes OOP. I think OOP is taught somewhat wrong because people will dwell on contrived examples of inheritance when its real value as a paradigm is coupling state with functions. What we've learned from FP is immutability is easier to reason about, but when it isn't is when OOP shines because it gives you a sane way for managing state.

Inheritance is valuable and gets a bad wrap, IMO. I just think about Django's `Model` class and how much time that's saved me and probably tens of thousands of other people. It doesn't even really seem to have any foot guns to speak of, it's just a great use of the abstraction to build up database models without mucking about in the stuff you wish was already written. The downside to them is that there is that the ba…

Inheritance is a kind of implicit adapter pattern -- instead of implementing a (complex or low-level) interface directly, you can implement a slightly simpler or better-tuned interface, and the inheritance machinery takes care of adapting that interface to the one you ultimately need.

When used in that context, it's truly excellent. I suspect your example from Django fits this pretty well. But it's far too easy to abuse for general code reuse, which is a deep and alluring tar pit.

Re: Admitting That Functional Programming Can Be Awkward (2007)

#84
The direct update imperative way works until you have enough multithreaded actions that interact in undesirable ways. In addition, locks don't compose. I worked on a relatively straightforward trading app with charting and realtime rates. There were so many bugs from direct updates that interfered with rendering that it was best to restructure it as world-in, apply function(s), world-out. Then the renderer only had to deal with one frame of the world. Some items had a smaller 'world', like a single price tile. Whether done in a functional language or a procedural one this functional pattern is a common one.

Re: Admitting That Functional Programming Can Be Awkward (2007)

#85
post #52
post #40

Earlier quoted context omitted.

Do you have any examples of compilers or linters that assist with this? Any kind of error or warning would do.

Haskell has ST[1], which allows you to do mutable in place updates in a way that the compiler can guarantee are not visible from the outside. It's not particularly popular though. Typically it seems to be more convenient to either be thoroughly pure or accept mutability and use IO. [1] https://hackage.haskell.org/package/base-4.14.0.0/docs/Contr...

There's also the probably underappreciated packages ref-tf and ref-fd which let you write code that is polymorphic over the type of state reference. These can make 'ST' more acceptable because you don't have to make the decision of what state reference to use up front.

Re: Admitting That Functional Programming Can Be Awkward (2007)

#86
post #30
post #5

Earlier quoted context omitted.

I'd go one step further and say that most people should care little about language features when doing an actual production project, as there are aspects such as how proficient your team is in a given language and how easy it will be to maintain afterwards that are simply more important. That does not mean having a favorite paradigm or language is useless, of course I love Rust and I find functional programming elega…

> how proficient your team is in a given language and how easy it will be to maintain afterwards that are simply more important. That is a double-edged sword. On one hand it makes sense because it allows teams to be more productive. Otoh, it leads to this decade where it has become okay to create a desktop application using HTML/JS (while more performant tooling exist) simply because a lot of people happen to know HT…

I’d agree with this. In my experience, choosing a language/platform based on the teams experience instead of the best tool for the job is a siren song. It’s less pain upfront, but way more amortized pain over the life of the project.

Start with good engineers who understand CS fundamentals. After a week or two of immersion, they’re passable in a new language. After a month or two, there’s basically no difference with a veteran.

Okay, sure there are exceptions with very different paradigms. Kotlin devs may take more time with low-level memory managed C code. C hackers may struggle with Haskell. But Pythonistas can write pretty good Typescript in their first week.

In contrast starting with wrong tool for the job, just gets continuously worse as the project progresses. The friction of constantly cutting against the grain is an accumulated drag. As the project grows more complex, the kludges and workarounds become an increasingly heavy burden on a day-to-day basis.

Re: Admitting That Functional Programming Can Be Awkward (2007)

#87
post #6

I think it's time we stop using the phrase "functional" to describe this paradigm; at this point, every imperative language made in the past 30 years has first-class functions, and there is no other first-class language feature common to all the self-described "functional" languages. IMO, a more accurate term would be stateless programming. This paradigm is about minimizing state. Of course, as the OP mentions, state…

Before reading this article and its follow-on, I would have completely endorsed the view that global mutable state is the worst, but for the sorts of issues the author is writing about, it seems that global mutable state is precisely the thing that makes procedural solutions more straightforward. In this case, it seems to be an intuitive and straightforward model for how both the programmer and player view the proble…

The article didn't talk about global mutable state. Nobody likes global mutable state. Nobody, not even C programmers. If possible mutable state should always be local to a function.

Re: Admitting That Functional Programming Can Be Awkward (2007)

#88
I'm not sure I'm understanding the point of this article. Every language and language paradigm is awkward if it's used for purposes it's not meant for. Writing a game is something that is really heavily dependent on mainting some sort of state and functional programming in principle is supposed to be stateless. So, unsurprisingly, it's awkward to use FP for game development.

Re: Admitting That Functional Programming Can Be Awkward (2007)

#89

Earlier quoted context omitted.

> sometimes OOP. I think OOP is taught somewhat wrong because people will dwell on contrived examples of inheritance when its real value as a paradigm is coupling state with functions. What we've learned from FP is immutability is easier to reason about, but when it isn't is when OOP shines because it gives you a sane way for managing state.

I _really_ struggled to not use contrived examples when teaching OOP. It was very hard because you don't really need it until your application becomes non-trivial so I see why all the college classes use cars & trucks or whatever. I think I ended up going with a Player API with tapes, records, CDs etc. Some could skip, others only fast-forward. I was still unhappy with it, but it was better than most examples. I like…

If it helps, IMO inheritance is the least interesting feature of OOP. Programming with interfaces is a much more compelling story. A concrete example that is probably small enough to fit within an article or class is a 2d physics engine, where object positions, velocities and accelerations are updated in a loop.

Re: Admitting That Functional Programming Can Be Awkward (2007)

#90
post #6

I think it's time we stop using the phrase "functional" to describe this paradigm; at this point, every imperative language made in the past 30 years has first-class functions, and there is no other first-class language feature common to all the self-described "functional" languages. IMO, a more accurate term would be stateless programming. This paradigm is about minimizing state. Of course, as the OP mentions, state…

Functional programming was never about first-class functions. It was always about programming with pure and total functions in their mathematical version.

> It was always about programming with pure and total functions in their mathematical version.

Are you sure about this? A total function is defined for all of its possible inputs, i.e., it must always terminate. A functional programming language with only total functions isn't Turing complete.

Post reply on HN