1

I'm new in Haskell programming. Now i'm learn lambda function and lambda abstractions. And i thought, what's the practice part of lambda functions. For example we have:

map(\x -> x * 2) [1,2,3,4,5]
[2,4,6,8,10]

What's of this practice part? We can create normal function and set it in map function argument. Only for code reduction? Then why was coming up this abstraction. Code reduction is not big point. Why?

Thank you.

Nikita Rybak
  • 67,365
  • 22
  • 157
  • 181
0xAX
  • 20,957
  • 26
  • 117
  • 206
  • I'm sure Wikipedia will answer you question. See [Functional programming](http://en.wikipedia.org/wiki/Functional_programming), for example. – YasirA Mar 14 '11 at 12:48
  • s/practice part/practical purpose/ ? – John L Mar 14 '11 at 14:43
  • Don't forget you can write this more concisely: `map (*2) [1..5]` – stusmith Mar 14 '11 at 15:57
  • The short answer is "why wouldn't you?" You don't *need* it, clearly, but it ends up making your life easier. In the end, it's about as remarkable as literal syntax for lists instead of `0:1:2:[]`. I said something to this effect in [my answer to this SO question about lambdas in Ruby](http://stackoverflow.com/questions/4352191/where-and-when-to-use-lambda/4353825#4353825). – Antal Spector-Zabusky Mar 14 '11 at 17:57

5 Answers5

4

Not all functions are used widely enough to "deserve" a name. For example, if you're only using this function once, for this specific map, you probably don't want to assign it a name because you'll never use it again.

quanticle
  • 4,872
  • 6
  • 32
  • 42
4

There's two ways to interpret this question. The first is why write map (\x -> x * x) when we can write

doubleIt x = x * x
... map doubleIt ...

The answer there is that you may have the following:

foo y zs = map (\x -> x^y) zs

and then there is no fully straightfoward transformation that allows you to float the anonymous function fully to the top level.

We could write

foo y zs = map (powerIt y) xs
powerIt y = ?

and then we discover that powerIt y = \x -> x^y ! (sure, you could float the x back to the outer definition, but in that case, you'd actually want to (although syntactically Haskell doesn't make you) write (powerIt y) as (\x -> powerIt y x).

When you have first class functions, they need to close over their environment, and that means that you need some way to introduce a function which can refer to things in the lexical scope where it is declared. That's the power of lambdas!

Now, the other question is why not float the anonymous functions to the appropriate level that's not the top and thus get, e.g.

foo y zs = let powerIt x = x^z
           in map powerIt zs

In that case, think carefully about what let really means again. In fact, we can transform the let into a few lambdas in the following way: foo ys zs = (\powerIt -> map powerIt zs) (\x -> x^y)

Now, in real implementations, these desugarings don't all happen exactly this way, and sometimes different clauses get treated differently by compilers for reasons involving efficiency. But the core thing remains -- lambdas are very powerful and expessive, and can give us a core language that is simple and easy to reason about despite the variety of binding forms that we layer on top of them.

Without lambdas we have a language where we can define variables and we can define functions and then we can sometimes do certain things with functions. With lambdas we have a language where functions are values just like any other value, and we have one set of uniform ways to assign names to anything.

The inversion of perspective is to see lambdas not as a special-case, but as the general case, and all our other various name binding mechanisms as sugar for them.

sclv
  • 38,665
  • 7
  • 99
  • 204
  • I should note that the reason why lets don't transform into lambdas as above, historically, is that let bindings are polymorphic, while arguments to lambda functions are, by default, monomorphic. But modern ghc is eliminating the default generalization of let bindings, which makes the transform much more straightforward. – sclv Mar 15 '11 at 13:54
2

you often face the situation, that you need a pretty specialized function. It is used in this part of your software and only there. Therefore it doesn't make any sense, to give it a concrete name.

frosch03
  • 719
  • 4
  • 13
2

Readability; you can have ( far fetched, but to illustrate the point )

map (\x -> x * 2) . anotherfunction . anotheragain . itgoesonandon $
[ a lont list ]

vs

map f . anotherfunction . anotheragain . itgoesonandon $
[ a lont list ]
  where f x = x * 2

It's matter of taste but in the first case you know right away what function you are mapping, in the second one you have to locate f in the source code, and it might be a few lines away.

By the way, I would write map (*2) .... anyway

Another example is desugared monadic notation.

For example,

do a <- action1
   b <- action2
   action3
   c <- action4 a b
   action5 c

becomes :

action1 >>= \a -> action2 >>= \b -> action3 >> action4 a b >>= \c -> action5 c

vs

action1 >>= a2
  where a2 a = action2 >>= a3
           where a3 b = action3 >> action4 a b >>= a4
                   where a4 c = action5 c

(there might be an error in that code, but I would never write that anyways )

David V.
  • 5,708
  • 3
  • 27
  • 27
0

If I understand your question correctly you are asking why someone would come up with the abstraction of Lambda functions outside of the scope of a specific programming language, correct?

Well, Lambda functions in programming languages are derived from Lambda calculus, which is a formal system for function definition. As Wikipedia says, Lambda calculus was introduced by Alonzo Church in the 1930s as part of an investigation into the foundations of mathematics. It has a wide range of applications, not just in Computer Science.

As noted by a commenter above, Functional programming has it's roots in Lambda calculus. I can only advise you to read the relevant entries in Wikipedia, there's some very interesting info in there ;-).

Cedric
  • 720
  • 5
  • 11