Functions as Classes: Which languages?

I was thinking of possibly making all functions in the Heron programming language into classes with a single public field named "result". I was wondering what other languages do similar things to this, and what the advantages / disadvantages might be of such as approach.

I have posted an example of Heron code which would model this apporach at http://www.artima.com/weblogs/viewpost.jsp?thread=116558

Thanks in advance!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Take a look at Scala. They ha

Take a look at Scala. They have a function class, and even make arrays and other mapping classes into subclasses of functions.

Scala functions are objects but not classes

I was looking at Scala, and this is where I got the idea from. The difference in Scala is that each function is treated as an instance of one of the nine function classes (function0, ..., function9) but is itself not a type. What this means is that you can't parameterize with a function.

In Scala you can write:

{
  var x : List[int];
  ...
  x.foreach(Console.println); 
}

which requires the object to be instantiated first and then passed. I want to pass the type instead so that the compiler expand the code in place:

{
  var x : List[int];
  ...
  x.foreach[Console.println](); 
}

This is more efficient in Heron because it uses
C++ semantics for parameterized types.

Python

Any Python class with the method __call__ defined can be used to instantiate objects that can be called in the same way as functions, e.g. obj() rather than obj.meth(). Functions are also objects, and can have methods attached to them, e.g.:

>>> def fun(a):
... 	return a*2
... 
>>> fun
<function fun at 0x0114CDB0>
>>> def show_self(self):
... 	print self
... 	
>>> import new
>>> fun.show_self = new.instancemethod(show_self, fun, fun.__class__)
>>> fun.show_self()
<function fun at 0x0114CDB0>

E is similar, I think - I believe functions in E are callable objects.

Interesting

That's interesting to know. The other day I was working on fuzzy membership functions. That could be one approach to the problem.

programmable runtime

I always thought the most interesting aspect of Python not the language itself, but the fact that the designers put in so many flexible hooks to twist the runtime behaviour of objects.

I like that Python can be highly customizeable by simply toying around with these methods:
__setattr__
__getattr__
__delattr__
__cmp__
__gt__
__lt__
__call__
__iter__

You can proxy attribute access to child attributes, for instance. so many sweet ways to do creative stuff...

Python is a lovely customizeable, programmable runtime...

Have you heard of common lisp

Have you heard of common lisp?

yes!

heard it's the ugly duckingly of the Lisp family... ;)

Scheme has my vote for best overall designed Lisp.

And, yes, i'm aware of Paul Graham's "programmable programming language" quote from his friend.

still, Python has several nice things going for it, which _are_ easier in the eyes than either Scheme or CL...

Field?

Functions are isomorphic to instances of classes with a single method, not field.

The “state” of a function consists of local variables defined in enclosing scopes which were used by its body. The shape of the state doesn't influence the interface of the function, it's private — the only public interface of the function is the single method. In the case of mutable variables the function object refers to variables themselves, not their values.

"Functions are isomorphic t

"Functions are isomorphic to instances of classes with a single method, not field."

I am perhaps not being clear. What I am proposing is that the actions which take place in a function would occur instead in the class constructor (which I am unsure if it is technically a method, because it can't be invoked in Heron in any context outside of construction of the object), and instead of having a return value as functions usually do, the class would return the value in a result field.

To illustrate using C++, any function would be rewritten from this:

int square(int x) { return x * x; } 

int n = square(42)

to this:

struct square 
{ 
  typedef int result_type;
  result_type result;    
  // constructor
  square(int x) {
    result = x * x;
  }
}

int n = square(42).result;

What is different about this approach is that by treating the function as a class (as opposed to function pointer or object) you can pass any function as a template parameter (instead of as an argument).

See also C#

A delegate in C# is an object that encapsulates a target object and method name - basically a method pointer. Delegates are called by calling Invoke on them. They can also be called asynchronously by calling BeginInvoke, which queues the delegate for execution by a thread in the thread-pool and returns an IAsyncResult object that can be used to check whether the delegate has finished executing. You pass the IAsyncResult object to the EndInvoke method of the delegate to wait for it to finish and pick up a return value, or catch an exception.

Borrowing from this pattern, you could extend the "square" example as follows:

(C# code)
public class Square
{
   private ManualResetEvent waitHandle = new ManualResetEvent(false);
   private int x;
   private int result;
   private Exception exception;

   public Square(int x)
   {
      this.x = x;
      Thread t = new Thread(new ThreadStart(ComputeResult));
      t.Start();
   }

   private void ComputeResult()
   {
      try
      {
         result = x * x;
      }
      catch (Exception exception)
      {
         this.exception = exception;
      }
      waitHandle.Set();
   }

   public int Result
   {
      get
      {
         waitHandle.waitOne();
         if (exception==null)
            return result;
         else throw exception;
      }
   }
}

This will start the computation off on another thread, which will collect any result or error in a private field and set a synchronization event when it's finished. Calling Result waits for the synchronization event and either returns the result or throws the exception.

Alternative execution schemes are possible - you could wait until Result is called before actually performing the computation, for instance, so that the constructor simply captures the arguments for later. One could perhaps have an optional mode parameter to the constructor that specified whether lazy or asynchronous execution was desired.

But they are not a type.

In C# though the function itself can not be treated as a type.

Would render functions 2nd class

Unless you also have classes as first-class citizens (which no typed language supports, AFAIK) this would prevent functions from being first-class, wouldn't it? That makes them almost useless.

I don't see any advantage in exchange either. What does it buy you?

First-class classes

I believe Dylan supports first-class classes. It's a functional language, though, so it would be easy enough to just pass functions directly.

OOHaskell represents classes as functions, so they're first-class as well. Of course, representing a function with a class implemented as a function seems a bit redundant.

I don't see the disadvantage

I don't see any disadvantage to passing functions as template parameters. The advantage is that the compiler can generate mor efficient code by inlining the function.

Huh?

Didn't I just point out the (huge) disadvantage? Functions would no longer be first-class, i.e. you could not return them from other functions, compose them, store them in a list, or whatever. But being able to do this is the whole point of having a functional language.

You probably couldn't even have closures, because they would correspond to runtime definition of classes.

For the few cases that would still be possible under your proposal the inlining optimisation you mention is possible already. Some compilers even do it where worthwhile according to certain heuristics, but not everywhere, to avoid code bloat (in languages with first-class functions, function calls should be comparably cheap anyway).

Actually:

You would be able to compose functions. The following creates a new function by repeatedly applying f to an argument.

def repeat[f : F[T], n : 'int](x : T)
{
  f(x);
  if (n > 1) {
   repeat[f, n-1](x);
  }
}

A list of functions could be created at compile-time using meta-programming techniques.

def f(int x) : int {
  result = x + 1;
}

def g(int x) : int {
  result = x * 2
}

def fxn_list[H : F[int][int], T : fxn_list] {
  def head : H;
  def tail : T;
}

def apply_fxn_list[XS : fxn_list](int n) : int {
  result = XS.head(apply_fxn_list[XS.tail](n))
}

def apply_fxn_list[XS : void](int n) : int {
  result = n;
}

def test(int n) : int {
  def fxns = fxn_list[F, fxn_list[G, void]];
  result = apply_fxn_list[fxns](n);
}

I concede that this is not as expressive nor elegant as if functions were treated as objects.

You can however implement closures in my proposed approach.

No closures

First, a minor change: instead of putting code in a constructor, better put it in a static method. Or if you don’t have anything like static methods, in a plain method invoked on a dummy object with no fields. This way the result will be returned in a natural way, without an auxiliary field.

But this is cosmetics. Unless your classes differ significantly from what I’ve seen in statically typed languages, this restricts to have a finite set of global functions—you can’t define a function locally with access to local variables of the containing code.

This is more restrictive than the C++ approach of objects with operator(). C++ function objects can access local environment—you must pack the relevant bits of environments manually, but it’s possible at all.

This is also more restrictive from C function pointers, because in your system the type depends on the implementation, not only on the interface (function signature).

So there are two properties participating in expressiveness: the ability to access local environment, and having a type dependent only on the interface. True closures have both, C++ objects with operator() have the first, C function pointers have the second, and your system has neither.

Could be fixed

The local variables for functions would be fields in my proposed system. The access to these fields could be shared by passing a context variable to the constructors. This would enable closures.

Static method idea is solid

I like the static method idea.

Javascript, PLT Scheme

In Javascript, functions are special objects that are applicable, but you can assign them extra fields as you like. (You can't go the other direction: ordinary objects can't be promoted to functions.)

In PLT Scheme you can declare structure types that are applicable as procedures (it's referred to as "structs-as-procedures"). See the documentation for make-struct-type.

Sounds like you should look a

Sounds like you should look at the functional (meta-) programming stuff at boost.org.

Ah, the irony

I have this feeling that Monsieur Diggins is one of the people pushing the Boost.Interfaces library for inclusion. ;)

eep

... (I opted to pull my comment, reread the post and realized I had the wrong idea at first glance) ...

Ohmu

See Ohmu. functions and objects are the same. function calls, currying, object instantiation, subclassing are all the same operation. Objects can have a result field as you mention.

The power of symmetry: unifying inheritance and generative programming (ACM subscription required)

The author, DeLesley Hutchins, is a student of Philip Wadler.

"The Ohmu model unifies functions, classes, instances, templates, and even aspects into a single construct - the structure. Function calls, instantiation, aspect-weaving, and inheritance are likewise unified into a single operation - the structure transformation"

Sym

For those of us who don't have ACM subscription, a short substitute: Knowledge Representation in
Domain Specific Languages
.

Transframe

Transframe uses classes for everything.