Skip to topic | Skip to bottom
Home
Projects
Projects.Funnyr1.2 - 28 Apr 2003 - 11:47 - Main.fouqui_gtopic end

Start of topic | Skip to actions

Funny

Functional flavor C++

The aim of this work, is to provide an appealing and efficient way, to write functional flavor code in C++. Actually, what we're targetting for the moment, is structural sub-typing, and lambda abstraction.


Structural subtyping:

[FIXME: explain how it works]


Lambda abstractions:

Here, appealing means that the syntax must be as close as possible to a functional one (our reference being ocaml). Efficiant, means fast (actually, not too slow), and easy to plug into existant libraries (for exemple, stl). Here are a few considerations about how it should work (all the examples are written in ocaml).

The first principle, is that everything is an expression.

Thus, '2' is an expression, so is 'let x = 1 in x + 1'.

Let me emphasize on this: everything you write, gets evaluated to an expression. Actually, we want, and need, this strict evaluation to expressions. Indeed, the modeling is very easy to find. There shall be a base type, called 'expr', and all the other elements derive from it. Then, if e is an instance of expr, one should be able to write (for example) e() to ask for its evaluation.

What if e is a function, then ? what does evaluating a function mean ? consider this:

# let f = fun x -> x + 1;;
val f : int -> int = <fun>

Then let us ask the interpreter to evaluate f:

# f;;
- : int -> int = <fun>

Here is the point: the type of f() (evualtion of f) is .. well a function, of course! And now comes the funny stuff:

# let f = fun x -> fun y -> y + x;;
val f : int -> int -> int = <fun>
# f 10;;
- : int -> int = <fun>

This behavior is very easy to code, here's what the 'funtion type' should look like:

(This is only pseudo c++, further considerations about the implementation will come later) (expr has the operator() and operator(value) that dispatch to the real eval)

struct fun : public expr
{
   fun(var& var, const expr& body) : var_(var), body_(body) {}
   const expr eval(value x) const
   {
      var_.bind(x)
      return body_.eval();
   }
   const expr eval() const
   {
      return me();
   }
// ...
};

This works exactly as we want to. Consider this: (still pseudo c++) Let us do this: fun f(x, x + 1). Then f(1) gives us the expression 1 + 1. It can be used as this, or implicitely converted to 'value' (cast operator). Then, Let us try this: fun f(x, fun(y, y + x + 1)). Here's what happens:

f(): gives the function itself.

f(10): binds x to 10 return returns the evaluation of the body. But the body is a function, and the evaluation of a fuction is a function.

Thus f(10) gives us the function y -> y + 11, and we have partial application, without the need of awfull functions like bind** etc ..

Please note, that we dont need to support more that one argument, thanks to the curry principle. Thus we can easily tranform x,y -> f x y into x -> y -> f x y.

Syntactic considerations:

Writing fun f(x, x + 1) is cool. But not enough. My first attempt was to try and overload the -> operator. Alas, it must conform to fixed signature, and we cant use it as we want.

But here is the trick: by overloading the -- and > operator, we can write things such as x --> x + 1. Thus, curryfing functions is easy to do. All we need to do, is overload the ',' operator to make it build a variables list. Then, the '>' operator takes a var list, and an expressionm and builds fun(var[1], fun(var[2], ... expr))).

[more to come]

  • wraping user functions (real ones) in order to be able to use them in expressions : x --> curry(std::sqr)(x)
  • i need to think about things like twice = f --> f f (having twice(f, x) giving f(f(x)))

-- YoussefElfassyfihry? - 20 Mar 2003
to top


You are here: Projects > Funny

to top

Copyright © 1999-2010 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback