Comment by ninetyninenine

9 months ago

Yes. This works but only if the functions are pure and using pure function composition.

Uncle bob doesn’t mention this.

   createspecialString(y) =
       Capitalizefirstletter .
       MakealllowerCase .
       AddNumberSuffix .
       removeLetterA .
       removeLetterB .
       ConcatwithWord(x)

   CapitalizeFirstLetter(a) = a[0].upper() + a[1:]
   MakeAllLowercase(a) = map(a, (t) => t.lower())
   Addnumbersuffix(a) a + 3.toString()
   RemoveLetterA(t) = filter(t, (s) => s.lower() == “a”)
   RemoveLetterB(t) = filter(t, (s) => s.lower() == “b”)
   ConcatenateWithWord(x) = (y) => y + x

   

There see? It’s mostly doable in pure functional composition where the dot represents function composition. I program like this all the time. No way anyone can pull this off while mutating state and instantiating objects.

   F . P = (x) => F(P(x))

Forgive some inconsistent formatting and naming im typing this on my phone.

People who complain about this style tend to be unfamiliar with it. If you had knowledge about procedural coding styles and a function composition approach like this then usually this style is easier as the high level function literally reads like English. You don’t need to even look at the definitions you already know what this complicated string formatting function does.

No comments needed. And neither author tells you about this super modular approach. They don’t mention the critical thing in that this style requires functions to be pure.

Thus to get most of your code following this extremely modular and readable approach… much of your code must be minimizing IO and state changes and segregating it away as much as possible.

The Haskell type system, the IO monad is pushing programmers in this direction.

Again neither author talks about this.

Based on his blog, Martin has been getting into Clojure in recent years. I was kind of hoping that the experience with a functional lisp would shift some of opinions that he previously stood by in Clean Code, but based on this discussion, it doesn't seem like it.

`createspecialString` is seven lines long though.

  • Then split it. All pure functions are easily decomposed into the most primitive units so even the most dogmatic ass hole can't talk shit.

       createSpecialString = createFormattedString . createNewString
    
       createFormattedString = 
           Capitalizefirstletter .
           MakealllowerCase .
           AddNumberSuffix .
    
    
       createNewString(y) = 
           removeLetterA .
           removeLetterB .
           ConcatwithWord(x)
    

    Or put it all on one line.

          createspecialString(y) = Capitalizefirstletter . MakealllowerCase . AddNumberSuffix . removeLetterA . removeLetterB . ConcatwithWord(x)
    

    The amount of lines becomes off topic once you get into this style. It's a completely orthoganol concept as it's completely irrelevant to readability and modularity.

    Lines doesn't makes sense for pure non imperative functions. Lines ONLY make sense for imperative functions because each line represents an instruction.

    • Well, the most interesting thing about purely functional composition would be the ability to un(de)compose them, inlining the bodies until the resulting function is large enough to be worth the effort of reading it.

      1 reply →