Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoid temporary variables by using name shadowing

I create a lot of temporary variables in Haskell:

main = do
    let nums'' = [1..10]
    let nums' = a . bunch . of_ . functions $ nums''
    let nums = another . bunch . of_ . functions $ nums'
    print nums

That is, I don't want to write a long chain of functions like so:

let nums = another . bunch . of_ . functions . a . bunch . of_ . functions $ [1..10]

Because it becomes unreadable to me, so I try to group the functions according to what they do. In the process I end up creating a bunch of ugly temporary variables like nums'' and nums' (I could give them more meaningful names, but the point still stands...every new line means a new variable). This is a case where a shadowed variable would result in cleaner code. I'd like to do something like:

let nums = [1..10]
nums = a . bunch . of_ . functions $ nums
nums = another . bunch . of_ . functions $ nums

I.e. exactly the same as above but without the temporary variables. Is there any way to do this in Haskell? Maybe the whole thing could be wrapped in a "transaction":

atomically $ do
  (...this code...)
  return nums

Something that would let Haskell know that the code in this section contains shadowed variables, and it should only worry about the end result. Is this possible?

like image 451
Vlad the Impala Avatar asked May 17 '12 19:05

Vlad the Impala


2 Answers

This style is very common:

let nums = another
         . bunch
         . of_
         . functions
         . a
         . bunch
         . of_
         . functions
         $ [1..10]

It clearly delineates the code; while . serves the place of the temporary variable name.

And it avoids the dangerous issues that can happen when you start shadowing variable names -- accidentally referring to the wrong x will get you into trouble sooner or later.

like image 133
Don Stewart Avatar answered Sep 28 '22 05:09

Don Stewart


Here's a suggestion nobody else has given which I use from time to time: you may like naming your functions rather than naming your values! For example, perhaps you might write:

let runningSum = a . bunch . of_ . functions
    weight     = another . bunch . of_ . functions
in weight . runningSum $ [1..10]
like image 26
Daniel Wagner Avatar answered Sep 28 '22 05:09

Daniel Wagner