



I don't have the source anymore. It's been 2003 when we did this. But

it's not hard to do this yourself, really.



Cheers



-- Martin



On Tue, Apr 28, 2009 at 8:08 PM, Paul Chiusano <

>> To get a demonstration what difference this can make, I invite you to

>> try to do this little task, which was originally proposed by Corky

>> Cartwright at a WG 2.8 meeting (**):

>>

>> The task is to write an interpreter for a little functional language -

>> lambda calculus with n-argument functions and integer arithmetic.

>

>

> This sounds very interesting, Martin! Are the solutions people came up with

> documented anywhere that we could look at?

> On Tue, Apr 28, 2009 at 5:23 AM, martin odersky <

> wrote:

>>

>> On Tue, Apr 28, 2009 at 3:03 AM, FFT <

>> > I was watching a Google Tech talk by Martin Odersky, in which he says

>> > that functional programmers do not understand the usefulness of OOP,

>> > specifically, the ability to extend classes by overriding methods.

>> > However, as far as I can tell, he does not support this claim later in

>> > the talk. As a counter-argument, I know that in OCaml, OOP is

>> > available (the "O" part), but is widely viewed as a failed experiment

>> > (not "failed" in a pejorative sense, but even its creator does not use

>> > the objective extensions). What can overriding methods do that

>> > higher-order functions can not do as well or better?

>> >

>> The crucial thing is to be able to implement methods (and, in the case

>> of Scala, types)

>> in subclasses. That way, the unknown part of an abstraction can be

>> left open in a class to be filled in later in subclasses. Functional

>> programmers indeed usually don't get this, and think higher-order

>> methods or ML functors are a sufficient replacement. But the crucial

>> difference is this:

>>

>> An implementation of an abstract {def, val, type} can refer to other

>> members of its superclass. But an argument to a higher order method or

>> functor cannot refer to

>> the result of the application. So open recursion with abstraction is

>> supported in OOP but it requires elaborate and rather tedious

>> boilerplate in FP (such as the encodings of classes in TAPL (*).

>>

>> To get a demonstration what difference this can make, I invite you to

>> try to do this little task, which was originally proposed by Corky

>> Cartwright at a WG 2.8 meeting (**):

>>

>> The task is to write an interpreter for a little functional language -

>> lambda calculus with n-argument functions and integer arithmetic.

>> There are several means to represent

>> variables and environments in such an interpreter. For instance,

>> variables could be strings and environments association lists, or

>> variables could be DeBruijn numbers, and environments simple stacks.

>> The question is this -- how much of your interpreter can you re-use if

>> you change your decision how to represent variables and environments?

>>

>> Corky put this up as a challenge in the meeting because he noted that

>> this was rather easy in Scheme, but almost impossible in GJ (or Java

>> today). So are static types hindering re-use? People at the meeting

>> came up with three different solutions, one in SML, one in Haskell,

>> and one in Scala. The Scala solution used a simple abstract class for

>> the interpreter where environment type, variable type and environment

>> access were kept abstract. Abstract members were then implemented in

>> different ways for DeBruijn and association list interpreters. The

>> Haskell solution used a big type class (with six functional

>> dependencies, if I remember correctly). The ML solution used functors

>> with sharing constraints. It was about 1 1/2 times the length of the

>> other two solutions. Also, everyone but the most experienced ML

>> programmers found it significantly harder to understand than the other

>> two solutions. But it's really better if you try this out for

>> yourself...

>>

>> Cheers

>>

>> -- Martin

>>

>> (*) Benjamin Pierce: Types And Programming Languages

>> (**) IFIP Working Group for Functional Programming

>

>

>> To get a demonstration what difference this can make, I invite you to>> try to do this little task, which was originally proposed by Corky>> Cartwright at a WG 2.8 meeting (**):>>>> The task is to write an interpreter for a little functional language ->> lambda calculus with n-argument functions and integer arithmetic.> This sounds very interesting, Martin! Are the solutions people came up with> documented anywhere that we could look at?> On Tue, Apr 28, 2009 at 5:23 AM, martin odersky < [hidden email] > wrote:>>>> On Tue, Apr 28, 2009 at 3:03 AM, FFT < [hidden email] > wrote:>> > I was watching a Google Tech talk by Martin Odersky, in which he says>> > that functional programmers do not understand the usefulness of OOP,>> > specifically, the ability to extend classes by overriding methods.>> > However, as far as I can tell, he does not support this claim later in>> > the talk. As a counter-argument, I know that in OCaml, OOP is>> > available (the "O" part), but is widely viewed as a failed experiment>> > (not "failed" in a pejorative sense, but even its creator does not use>> > the objective extensions). What can overriding methods do that>> > higher-order functions can not do as well or better?>> >>> The crucial thing is to be able to implement methods (and, in the case>> of Scala, types)>> in subclasses. That way, the unknown part of an abstraction can be>> left open in a class to be filled in later in subclasses. Functional>> programmers indeed usually don't get this, and think higher-order>> methods or ML functors are a sufficient replacement. But the crucial>> difference is this:>>>> An implementation of an abstract {def, val, type} can refer to other>> members of its superclass. But an argument to a higher order method or>> functor cannot refer to>> the result of the application. So open recursion with abstraction is>> supported in OOP but it requires elaborate and rather tedious>> boilerplate in FP (such as the encodings of classes in TAPL (*).>>>> To get a demonstration what difference this can make, I invite you to>> try to do this little task, which was originally proposed by Corky>> Cartwright at a WG 2.8 meeting (**):>>>> The task is to write an interpreter for a little functional language ->> lambda calculus with n-argument functions and integer arithmetic.>> There are several means to represent>> variables and environments in such an interpreter. For instance,>> variables could be strings and environments association lists, or>> variables could be DeBruijn numbers, and environments simple stacks.>> The question is this -- how much of your interpreter can you re-use if>> you change your decision how to represent variables and environments?>>>> Corky put this up as a challenge in the meeting because he noted that>> this was rather easy in Scheme, but almost impossible in GJ (or Java>> today). So are static types hindering re-use? People at the meeting>> came up with three different solutions, one in SML, one in Haskell,>> and one in Scala. The Scala solution used a simple abstract class for>> the interpreter where environment type, variable type and environment>> access were kept abstract. Abstract members were then implemented in>> different ways for DeBruijn and association list interpreters. The>> Haskell solution used a big type class (with six functional>> dependencies, if I remember correctly). The ML solution used functors>> with sharing constraints. It was about 1 1/2 times the length of the>> other two solutions. Also, everyone but the most experienced ML>> programmers found it significantly harder to understand than the other>> two solutions. But it's really better if you try this out for>> yourself...>>>> Cheers>>>> -- Martin>>>> (*) Benjamin Pierce: Types And Programming Languages>> (**) IFIP Working Group for Functional Programming Hi Paul.I don't have the source anymore. It's been 2003 when we did this. Butit's not hard to do this yourself, really.Cheers-- MartinOn Tue, Apr 28, 2009 at 8:08 PM, Paul Chiusano < [hidden email] > wrote: