If you are coming from a C# background then you may like to think of partial application as a kind of factory pattern. Instead of producing objects these factories produce functions. Your first example f prints "Hello" every time the factory is used and you show that in the definition of g1 by using the factory to build a function that has the side effect of printing "Hello". Your g2 is a function that, when invoked, will use the factory to build a function and immediately invoke that function (f is fully applied in the body of g2).

Currying and partial application are related but not the same. A curried function is a function that returns a function. A partial application is the application of a function to an argument to produce another function rather than a non-function result. In other words, curried functions can be partially applied.

Cheers,
Jon.

By on 7/4/2008 2:12 PM ()

Thanks Jon.

The way of think of partial application as a kind of factory pattern is interesting and inspiring. In this way, according to the execution result and what you said, the f inside g1 and the f inside g2 is differenct. The f inside g1 is <i>some kind of an object which had been partially executed<i>, i.e. printfn "Hello". Every time g1 is called, the rest of the f inside g1 will be executed. While the f inside g2 is <i>just an instruction of calling f<i>, telling that every time g2 is called, call f and execute all code of f. Is this correct? Therefore, g1 is a partial application while g2 is just a definition inside which there's an instruction of calling f, right? One more question, what about the types inferred from the compiler and display in F# Interactive (g1 is ("int -> int") and g2 is "int -> int")? Are they for telling the difference of g1 and g2? Or they have other purposes? Thanks for your inspiring.

By on 7/6/2008 6:28 PM ()

Hi allenlooplee,

Your understanding is correct: g1 is a computed function (a function value produced as a result of computation) and g2 is a syntactic function (a function defined in the syntax of the source code).

The difference between them is a implemenation detail of the compiler and it is not usually something a functional programmer needs to be aware of. Curiously F# manifests this function kind distinction in the types of functions and that is the difference you are seeing in the types of g1 and g2 (the type "(a -> b)" is a computed function and "a -> b" is a syntactic function). I forget why this is important, but for one it can control how functions are compiled to IL: computed functions are compiled as fields of a FastFunc type and syntactic functions are compiled as methods.

By on 7/7/2008 8:02 AM ()

Thanks gneverov.

Your question why the difference is important reminds me of <i><A href="http://research.microsoft.com/fsharp/manual/advanced.aspx">Advanced Topics</A><i> of <i>F# Manual<i>, inside which there's a section named <i>Function and Signatures<i>. I think that would give us some clues. Thanks again for your inspiring.

By on 7/7/2008 6:14 PM ()

The way I understand this is:

- in the g1 case you are applying "f" to the value 10 and the result of "f" is a new function which is then bound to "g1". You see "Hello" at this point because the function "f" is being executed. When you use "g1" you do not see "Hello" being printed since the return value of f is "fun y -> x + y" and does not inculded the "printfn" statement.

- in the g2 case you are creating a new function, becuase you g2 has a parameter y. When you define a function none of the computation takes place until the function is called. This is why you do not see "Hello" until "g2" is called.

I do not think (int -> int) and int -> int are different types, I think this is just a minor bug in the pretty printer, but I could be wrong on this point.

Hope that makes sense.

Cheers,
Rob

By on 7/4/2008 12:45 AM ()

Thanks Rob.

Can I think of g1 and g2 this way?

  1. g1 was computed from f, during which printfn "Hello" inside f was executed.
  2. g2 was defined with a call to f inside its body and therefore no part of f was executed.

In one word, when defining g1, part of f was executed, while defining g2, f was not executed. Is this correct? If so, then g2 is a general function definition is imperative programming, but what about g1? Is it a function object or anything else? It seems that g1 is called a function value, right? Is it a (partial) function application? If so, when is the difference between function value and function application (and what about function object or there's not a concept of function object?) or they are both just the same in F#?

Thanks for your inspiring.

By on 7/6/2008 6:04 PM ()
IntelliFactory Offices Copyright (c) 2011-2012 IntelliFactory. All rights reserved.
Home | Products | Consulting | Trainings | Blogs | Jobs | Contact Us | Terms of Use | Privacy Policy | Cookie Policy
Built with WebSharper