Question: In a functional language, functions are first class citizens and thus *calling* them is not the only thing I can do. I can also store them away. 

Now when I have a language, which is strict by default, then I am still not forced to evaluate a function call. I have the option to store the function and its parameters e.g. in a tuple for later evaluation. 

So instead of

```
x = f a b c

```

I do something like

```
x = (f,a,b,c)

```

And later, I can evaluate this thing with something like

```
eval (f,a,b,c) = f a b c

```

Well, there is probably more to it, because I want to evaluate each unevaluated function call only once, but it seems to me, that this can also be solved with a data structure which is a bit fancier than just a tuple.

The inverse also seems to be the case, because e.g. in Haskell, which is lazy be default I can enforce evaluation with `seq` or `BangPatterns`.

So is it correct to say, that every functional language has the potential of being lazy, but most of them are just not lazy *by default* and thus require additional programming effort to call a function lazily, whereas haskell *is* lazy by default and requires additional programming effort to call a function in a strict way?

Should that be the case, what is more difficult for the programmer: writing lazy function calls in a strict language or writing strict function calls in a lazy language?

As a side note: was Simon P. Jone serious when he said: "the next version of haskell will be strict". I first thought that this was a joke. But now I think *strict by default* isn't all that bad as long as you can be lazy if required.

Answer: 
Lazy evaluation, at the low level, is implemented by a concept called a **thunk**, which comprises two things:

1. A closure that computes the value of the deferred computation
2. A set-once mutable storage cell for memoizing the result.

The first part, the closure, can be modeled in an even simpler way than your tuple with the function and its arguments. You can just use a function that accepts unit or no arguments (depending on how your language works), and in its body you apply the function to the arguments. To compute the result, you just invoke the function.

Paul Johnson mentions Scheme, which is a perfect language to demonstrate this. As a Scheme macro (pseudocode, untested):

```
(define-syntax delay
  (syntax-rules ()
    ((delay expr ...)
     ;; `(delay expr)` evaluates to a lambda that closes over
     ;; two variables—one to store the result, one to record
     ;; whether the thunk has been forced.
     (let ((value #f)
           (done? #f))
       (lambda ()
         (unless done?
           (set! value (begin expr ...))
           (set! done? #t))
         value)))))

(define (force thunk)
  ;; Thunks are procedures, so to force them you just invoke them.
  (thunk))

```

But to get this back to the title of the question: does this mean that every functional language can be lazy? The answer is **no**. Eager languages can implement thunking and use it to provide opt-in delayed evaluation *at user-selected spots*, but this isn't the same as having pervasive lazy evaluation like Haskell implementations provide.
What you propose will work. The details for doing this in Scheme can be [found in SICP](https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-27.html#%25_sec_4.2). One could envisage a strict version of Haskell in which there is a "lazy" function which does the opposite of what "seq" does in Haskell. However adding this to a strict Haskell-like language would require compiler magic because otherwise the thunk gets forced before being passed to "lazy".

However if your language has uncontrolled effects then this can get hairy, because an effect happens whenever its enclosing function gets evaluated, and figuring out when figuring out when that is going to happen in a lazy langauge is difficult. Thats why Haskell has the IO monad.