These chains become easy to read and understand with a small language feature like the pipe operator (elixir) or threading macro (clojure) that takes the output of one line and injects it into the left or rightmost function parameter. For example:
(Elixir)
"go "
|> String.duplicate(3) # "go go go "
|> String.upcase() # "GO GO GO "
|> String.replace_suffix(" ", "!") # "GO GO GO!"
;; Using the thread-last macro
(->> '(1 2 3 4)
(filter even?) ; The list is passed as the last argument
(map double)) ; The result of filter is passed as the last argument
;=> (4.0 8.0)
Things like this have been added to python via a library (Pipe) [1] and there is a proposal to add this to JavaScript [2]
(Clojure) ;; Nested function calls (map double (filter even? '(1 2 3 4)))
;; Using the thread-last macro (->> '(1 2 3 4) (filter even?) ; The list is passed as the last argument (map double)) ; The result of filter is passed as the last argument ;=> (4.0 8.0)
Things like this have been added to python via a library (Pipe) [1] and there is a proposal to add this to JavaScript [2]
1: https://pypi.org/project/pipe/ 2: https://github.com/tc39/proposal-pipeline-operator