# simple let binding vs constant function

I understand the reasons why I would prefer `let a = f(x)` over `let a() = f(x)`, especially when f takes is a long running function.

I also think it is correct to say, that, considering lambda calculus origins of functional programming `let a()` is truly functional, while `let a` is not. Please correct me if I'm wrong on this.

However I have no clue which expression will actually be better:

``````let a = 4
``````

or

``````let a() = 4
``````

Is there any reason I would prefer one over the other?

• If anything, `4` is not "functional" (in the sense of being native to lambda calculus). `let x = foo in bar` is spelled `(\x bar) (foo)` in lambda calculus, and `let x() = foo in bar` is, if I understand F# correctly, just `(\x -> bar) (\_ foo)`.
– user7043
Aug 29, 2014 at 16:06

There's nothing "unfunctional" about `let a = 4` as opposed to `let a () = 4`. In fact, in many abstract formulation of type theories, the latter is really syntactic sugar for `let a = fun () -> 4`.

The main difference is when you want the expression to be evaluated, as you said. If `a` will eventually be evaluated anyway, there's no point in wrapping it into a function. OTOH if you think that there's a good chance that `a` might not be evaluated, and the evaluation is very expensive (or may even fail if some precondition is not satisfied), then it might be beneficial to keep as a function. However, in the latter case you still have to be careful to not evaluate the function more than once.

However, I'm not sure if pervasive use of laziness is all that common in a strict language such as F#.

In many formal mathematical specifications of a language, the `let` construct binds an expression to a single variable:

``````let VARIABLE = EXPRESSION in EXPR
``````

The reason is because this is simpler than having a `let` that binds arbitrary functions such as `let f x = 2 * x`. Instead, the latter is treated as a syntactic sugar for the more verbose `let f = fun x -> 2 * x`.

However, neither is more "functional" (if that word even has a well-defined meaning). Functional programming does not mean you should attempt to use functions everywhere possible. Rather, it merely puts functions on equal standing with other values so that you can manipulate both functions and values with equal ease.

The `let` construct in Haskell looks superficially like the one in F#, but semantically it is very different because it's non-strict ("lazy") by default. This means `let x = 4 in 2 * x` in Haskell is more appropriately translated into `let x = lazy(4) in 2 * Lazy.force x`.

The `let` construct should not be confused with assignments, which are an entirely different thing as it requires mutation. By constrast, let does not mutate anything: it merely introduces a new variable. F# blurs the boundary because it allows pure and impure functions to be mixed, so `let` bindings can have side-effects as a result and hence the way you bind them (as functions or values) will matter.

In a pure language, `let` bindings cannot cause any side-effects, but the order of evaluation still matters for two reasons:

• Efficiency: because we don't have infinite resources and infinite patience.
• Divergence: functions can still fail, or go into an infinite loop.

So even in pure languages, it still matters whether evaluation is done eagerly or lazily.

• IF you wanted, you could implement memoization to get the best of both worlds. Aug 29, 2014 at 17:10
• Could You please explain there's nothing "unfunctional" in `let a = 4`? And why You say that `let a() = 4` is opposite to that (so if I understood You well, has something "unfunctional")? Is that because it is not a lambda but just a regular function. On the other hand, f# is not purely functional language for sure. Is similar assignment (`let a = 4) possible in Haskell? Aug 29, 2014 at 18:55

Apart from lambda calculus related considerations, there are as well practical considerations. Whether you create a value (`let a = 4`) or a function value (`let a() = 4`) has an impact on when your code gets executed, which, at times is of importance. The following F# code shows the effect in a simple way:

``````let A = printfn "A invoked"
let B() = printfn "B invoked"

let Run() =
printfn "Run() invoked"
A
B()

Run()
``````

The output is:

``````A invoked
Run() invoked
B invoked
``````

This might come as a surprise once in a while. For simple constant numerical values, less so, than for some functions producing side effects (printfn,...).

Don't be concerned about which is more "functional." You're a programmer, not a mathematician. Use `let a()` when you want to evaluate it at the point of use, when you don't care about evaluating it multiple times. Use `let a` when you want to evaluate it at the definition point, and only want it to be evaluated once.

Your third choice is `let a = lazy(f(x))`, which waits until it is needed to evaluate, but only evaluates it once. This is my preferred choice for expensive functions that may not be needed. This is kind of ugly in F# though, because it requires an explicit a.Force, unlike most functional languages which force evaluation automatically at the appropriate time.

Remember, `let a` looks sort of like a mutating assignment, but it isn't. Pure functional programs can be substituted and expanded out to one big nested expression. Conceptually, if you expand your program out, you still end up with essentially the same expression with `let a`, it just eliminates some duplication when you evaluate it.

• I guess we could have a discussion about "You're a programmer, not a mathematician." someday, somwhere :-) Anyway, thank You for Your point. Aug 30, 2014 at 8:30