-1
$\begingroup$

Functional programming is said to be superior in many ways to imperitive programming. But I am struggling to find a simple functional way of writing:

x = f(y);
g(x,x)

Since in functional language this would be g(f(y),f(y)) thereby calling the function f twice. Whereas in imperitive language this seems more efficient. Equally one could write this as:

(x=>g(x,x)) f(y)

But then this to be exactly the same as imperitive way just rearranged slightly differently.

What is the "functional" way to repeating things in expression?

$\endgroup$
1
  • $\begingroup$ You should look up let-statements in SML, OCaml, or Haskell. $\endgroup$ Commented Aug 23, 2020 at 13:43

1 Answer 1

4
$\begingroup$

In the pure functional language Haskell, you could write this as

result =
  let x = f y
  in g x x

or

result = g x x
  where x = f y

or, indeed, as

result = (\x -> g x x) (f y)

...if you really wanted to for some reason.

An imperative language is one where the program is organized as a series of instructions (verbs)—that is the literal meaning of the word imperative. For the most part, this is equivalent to saying an imperative language is one that allows repeated mutation of a variable.

By contrast, the above notations bind the variable x once; it cannot be updated in-place. x is a name for a shared subexpression, not a mutable memory location.

Imperative vs. functional is a matter of language semantics, not language syntax. If you take an imperative language and disallow reassignment of all variables (i.e. require programs to be written in static single assignment form) and mutation of data structures, you no longer have an imperative language; you have a first-order functional language with a somewhat inconvenient syntax.

To write a very imperative version of this using Haskell monads—that explicitly creates a mutable memory location, assigns it the value of f y, reads it twice, and calls g with these values—you'd have to write something like

result = runST $ do
  x <- newSTRef (f y)
  liftM2 g (readSTRef x) (readSTRef x)

It is worth mentioning that the history of the past 40 years or so of programming language design is dominated by designers trying new ways of hybridizing features of imperative and functional programming languages. That is why JavaScript has const-bindings and anonymous functions, Haskell has monads, etc.

$\endgroup$
6
  • $\begingroup$ My thoughts are that you could just write this in the imperitive way. But just disallow reassignment of variables. Seems to be equivalent. Except it just depends if you write the assinment first or write it after as with "where". $\endgroup$
    – zooby
    Commented Aug 23, 2020 at 18:59
  • $\begingroup$ @zooby What is the distinction between functional and imperative in your mind? $\endgroup$ Commented Aug 23, 2020 at 19:05
  • $\begingroup$ In my view. Imperitive involves assigning variables and reusing them in later equations. $\endgroup$
    – zooby
    Commented Aug 23, 2020 at 19:07
  • $\begingroup$ Exactly, so it seems like if you disallow mutation. Your imperitive program is equivalent to a functional program. But just keeps the same syntax. $\endgroup$
    – zooby
    Commented Aug 23, 2020 at 19:12
  • 1
    $\begingroup$ @zooby See my edits to the answer $\endgroup$ Commented Aug 23, 2020 at 19:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.