7 ms·
Because functional programming is so damned hard if you don't grasp recursion. Otherwise, it is simple. Sorry for the cheap pun, but I think the main difficult
by choeger 5y ago
Because functional programming is so damned hard if you don't grasp recursion. Otherwise, it is simple.
Sorry for the cheap pun, but I think the main difficulty is getting along with recursion.
And corecursion, of course ;).
- onlyrealcuzzo 5y agoI also think that most people who learn a functional language try to take what they know in an imperative language and translate it on the fly to a functional paradigm. This seems like a lot more work than just learning how to think functionally.
- dagw 5y agoThe intro to programming course for the math department at my University was taught in Haskell. And it was really interesting to see how people who had never programmed before on the whole did better than those who had a bit of programming experience. Those that had programmed before kept trying to make Haskell behave how they thought a programming language 'should' behave, while those who had never programmed just looked at Haskell and went "I guess this is what programming is" and just rolled with it. The only problem was that once they moved onto the intermediate course, taught in Java, they where completely lost again.
- scns 5y agoIntroduction to Programming at CMU is done in SML. They make the same observations as you. Those that have prior exposure to programming struggle. Those students without experience find it easy. They are a bit baffled in the next course, which is done in an imperative language.
- rgrmrts 5y ago15-150 (during my time), but it wasn’t the intro to programming - the course is titled “introduction to functional programming”. The intro to programming is Python (unless it changed). The trajectory for students is Python to C to SML (15-110 to 15-122 to 15-150). Some people take the C and SML courses in the same semester. I was really happy to have been introduced to many different paradigms over the course of a few years. But to both your points, once we moved on to Java I had a really bad time.
- TchoBeer 5y agoAlternatively, learning a new thing is easier if you have a grounding somewhere. Maybe the ideal would be a guide like "this is how functional programming differe from imperative programming"
- bsaul 5y agorecursion is always synonymous to me of unbounded memory usage. Understanding the memory consumption of a for loop updating a local variable looks easy. But a recursive function ? forget it...
- emodendroket 5y agoWell that's why you want a function to be tail recursive, right?
- bsaul 5y agoyeah but how do i know for sure that the compiler is going to optimize the memory or not ? Some compilers are smarter than other to rewrite recursion in a tail recursive way, and others aren't, and it's probably not possible all the time anyway.. It seems like a very convoluted way to do a simple thing ( sometimes).
- emodendroket 5y agoIn Scala, as I recall, you could annotate a method as tail recursive so it wouldn't build if it weren't. A serious functional language pretty much has to have an answer for this since you're supposed to use recursion instead of iteration.
- yawaramin 5y agoScala has the '@tailrec' annotation for this, and OCaml has the '[@@tailcall]' attribute for the same reason.
- carnitine 5y agoA tail recursive function can always be optimised into code which does not consume memory on recursion, and it’s a pretty basic fact to learn about a given language/implementation.
- 5y ago
- sltkr 5y agoI think recursion is just one of the hurdles. Another one is the use of higher-level functions and function composition. Another one is the use of monads (at least in pure functional languages like Haskell).
- nightski 5y agoMonads aren't really related to purity. Haskell uses one instance of a monad, the IO monad to encapsulate IO. But there are other ways of doing it. Most monads have nothing to do with side effects. You see things like functors/monads all the time even in regular imperative languages. For example in .NET we have Linq, Nullable types, etc... They aren't as well defined as in Haskell but still an incredibly useful pattern. You also have higher ordered functions and whatnot in imperative languages now. In fact, in JavaScript and .NET they are used all over the place.
- DaiPlusPlus 5y agoI don’t believe .NET’s `System.Nullable<T>` is a monad. For example, a type that can encapsulate any other type fulfils the definition of a monadic-value, but `Nullable<T>` cannot be used with reference-types and delegates, only a strict subset of value-types (as `Nullable<T>` itself is a value-type, but you cannot use `Nullable<T2>` for T1 in `Nullable<T1>`). While .NET allows for composition with delegates, it’s not very smart, and results in unnecessary type information erasure; for example in Linq if you take a projection of a fixed-size list, then that length information is lost if you then add another step after the projection. (Linq internally has some ugly, but inconsistent implementation hacks; for example, IList<T> length information may be preserved but IReadOnlyCollection<T> length information will not.
- nightski 5y agoC# has nullable reference types now. But I agree it's not perfectly a monad in implementation due to engineering decisions. But the pattern generally follows that of the Option monad in Haskell, even if it falls short. If you know the Option monad you'll find it really easy to pick up .NET's nullable types. That's my point, you find these patterns all over in common programming languages and even though they are hard to learn it's worth it.
- Banana699 5y ago> I think the main difficulty is getting along with recursion meh, recursion is easy. Recursion is mainstream. It _began_ as a way to fake a loop without mutation, but I struggle now to remember a mainstream language without it. The hardest part is all the new patterns you have to grok, it's like learning programming again from a blank slate, because it kinda is. It doesn't get any easier when Haskell decides it needs 7 new syntaxes and someone rushes to compose them all in one line.
- nwallin 5y agoI disagree entirely. I understand recursion just fine. I can look at a problem and think "this problem space is correctly represented by a tree/graph" and can meaningfully translate that into a program that shoves the data into a tree/graph-like data structure, and my natural inclination when computing on a tree/graph-like data structure is to use recursion. On the other hand, I understand that not all problems lend themselves to recursive solutions. I can look at a problem and think "this problem space is correctly represented by a matrix" and the reality is that linear algebra problems are often iterative, not recursive, in nature. It is certainly possible to do the simplex algorithm recursively with immutable data, but it's just so much straightforward to do it iteratively on a mutable matrix. The other thing is that most of my day job is just hooking one API up to another API to achieve my business's desired outcome. I don't need "interesting" algorithmic solutions for 95% of what I do. I just... extract data from one API and plug the data into another. You don't need recursion for that, and the "list of steps to do in order and (possibly) loop over that" paradigm with whichever seasonings you wish to add to it is just fine. (OOP is the flavor of the ~~day~~century at my company) edit: I forgot the bit that ties it all together. I am absolutely no good at functional programming. I've tried to sit down and learn Haskell or Lisp a dozen times and always failed. I've bought books. I'm still no good. It just takes me ten times as much code that's completely unreadable to do something that would be simple and straightforward in C++.
- silon42 5y agojust do a "pure object procedural" style of functional... all "objects" are immutable (or by value), as are the functions arguments and return values. But within a function you can still use variables and for loops.