0

Programmers often talk about point-free style. In contrast to the imperative style (pseudocode):

h := function(x) {
  y := f(x)
  z := g(y)
  return z;
}

one might write the following point-free:

h := f . g

where . is composition and the argument is now implicit. I'm wondering if there is a name for

h := function(x) {
  return g(f(x))
}

or

h := x -> g(f(x))

where there are no assignments, just a series of function calls. (They might be more complex than simple composition, though, like h := x -> g(f(x), q(r(x), 1), x).) The only points are the arguments themselves, there are no intermediates and the entire function is essentially a return statement.

It seems like this is related but not identical to functional programming. What is it called? Are there references discussing it (as there are for functional and point-free programming)? I know it's popular in some languages more than others.

14
  • 1
    Single expression/statement function? May 12, 2016 at 16:05
  • 1
    @CodesInChaos: I think it's just ordinary function composition. May 12, 2016 at 16:05
  • 1
    @RobertHarvey I wouldn't refer to x -> g(f(x), q(r(x), 1), x) as function composition. May 12, 2016 at 16:07
  • 1
    For what it's worth, I find that more readable than it's point-free counterpart. May 12, 2016 at 16:09
  • 2
    @CodesInChaos Well, what is it then? There doesn't have to be a "term" for it, necessarily. Let's make this a real question and answer pair, and not just toss around terms. I would love to learn more about this. May 12, 2016 at 16:09

3 Answers 3

1

In the terminology of the lambda calculus, the relation between f and \x -> f(x) is called eta equivalence. By the same reasoning, f . g = \x -> (f . g)(x) = \x -> f(g(x)) could be called "practically" eta equivalent, if we inline the intermediate step of applying the function composition (.).

6

It's just an expression, or more specifically, a lambda expression. Because of referential transparency, you can substitute a function's body or its result wherever it is called. If you actually did this for an entire program, you'd see that every functional program is effectively a single large expression like your examples. We just employ a lot of syntax to split it up and make it more modular and easy to read and maintain.

0

I'm not sure it's a distinct style, because once you allow functions with named parameters, it is easy to simulate named intermediate values by taking a lambda function and immediately invoking it.

Let me rewrite your first example into a language with an explicit skoped "let" construct, specifically Elm. I'm replacing f(x) and g(y) with concrete silly computations, because there will be lots of function calls below and I don't want these to confuse things.

h_let(x) =
  let y = "foo of " ++ x in
    let z = "goo of " ++ y in
      z

Simulating let

This "let" is just syntax sugar, we can simulate it with lambda functions and function calls:

h_lambdas(x) =
  (\y ->
     (\z ->
        z
     )("goo of " ++ y)  
  )("foo of " ++ x)

(Many LISP dialects actually implement let as a macro, expanding to such a lambda call.)

But as you can see, it's very cumbersome that the values appear at the end, so nobody likes to use this style when they have a choice.
(In javascript, this coding style is known as IIFE — Immediately Invoked Function Expression, and has been useful before ES6 modules.)

Fixing the cumbersome order

This manual simulation of let can be much less awkward languages with some kind of "pipeline" syntax, which lets you write something like value |> func instead of func(value). As it happens, Elm has an |> operator:

h_pipe(x) =
  "foo of " ++ x |> \y ->
    "goo of " ++ y |> \z ->
      z

Actually you don't even need syntax! Could also improve this with a tiny helper:

mylet(value, func) = func(value)

h_helper(x) =
  mylet("foo of " ++ x, \y ->
    mylet("goo of " ++ y, \z ->
      z
    )
  )

Executable version of above examples: https://ellie-app.com/bj8rSK5R4w8a1

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.