DEV Community

Discussion on: Stop Telling People For Loops Are Bad

Collapse
 
jbristow profile image
Jon Bristow • Edited

for only makes sense in languages where you have to manage memory yourself and/or you don't have easy access to true higher order functions.

Once you start passing functions as arguments, fold and its children make your life way more easy to deal with.

Take this contrived Haskell example:


isLetterA :: Char  Bool
isLetterA c 
  | c == 'A' = True
  | c == 'a' = True
  | otherwise = False

stripChars  (Char  Bool)  String  String
stripChars cfn = filter (not . cFn)

stripChars C.isSpace "I made a string!" -- Should return "Imadeastring!"
stripChars isLetterA "I made a string!" -- Should return "I mde  string!"

Ok, that's unreadable... let's convert it into its rough Javascript equivalent:


function isSpace(c) {
  return c == ' '; 
}

function isLetterA(c) {
  return c == 'a' || c == 'A'
}

function negate(boolFn) {
  return (v) => !(boolFn(v));
}

function stripChars(charFilterFn) {
  return (s) => s.filter(negate(charFilterFn));
}

stripChars(isLetterA)("I made a string!"); // should return "I mde  string!"
stripChars(isSpace)("I made a string!"); // should return "Imadestring!"

I know it looks like a lot, but it's a REALLY powerful concept that lets you make even MORE reusable things while not having to increase the complexity of the underlying building blocks. For small examples like this, it seems like a lot of overhead, but combined with a strong type system (and tail call optimization) you can more easily make trivially correct programs.

I wish I had the words to convey this better, but it's part of what makes functional and declarative styles so powerful and so difficult to get into after really learning the imperative style. Also, the fact that languages like c, Javascript and Python have dealt with recursion and corecursion so badly in the past hasn't helped us either. fold really relies on recursion as an underlying concept.