Lambda the Ultimate

inactiveTopic Paul Graham: Accumulator Generator
started 2/13/2003; 6:11:48 AM - last post 2/18/2003; 11:41:29 AM
Manuel Simoni - Paul Graham: Accumulator Generator  blueArrow
2/13/2003; 6:11:48 AM (reads: 3849, responses: 14)
Paul Graham: Accumulator Generator
The problem: Write a function foo that takes a number n and returns a function that takes a number i, and returns n incremented by i.

A comparison between about twenty languages. Paul Graham's Arc and NewtonScript (a selfish and schemish language-OS hybrid for the Apple Newton) seem have the most pragmatic syntaxes.

NewtonScript link via Steve Dekorte.


Posted to functional by Manuel Simoni on 2/13/03; 6:17:10 AM

Joshua Rothenberg - Re: Paul Graham: Accumulator Generator  blueArrow
2/13/2003; 4:09:46 PM (reads: 2086, responses: 0)
I can't figure out how to sumbit new versions to him, but the Python version he has is just plain silly. A much more reasonable method is:

>>> def foo(n):

... return lambda i: n+i

Updated: as Manuel Simoni has pointed out, I obviously wasn't paying attention when I wrote this -_- ....

Tim Sweeney - Re: Paul Graham: Accumulator Generator  blueArrow
2/13/2003; 4:17:36 PM (reads: 2140, responses: 0)
From the site:

>> Note: (a) that's number, not integer, (b) that's incremented by, not plus. <<

This is an interesting study of solutions to an ill-defined problem.

1. The term "number" is left undefined. If the problem we posed in terms of "integers" or "natural numbers", it would be clear. Are complex numbers, numbers? Are p-adics and reals, numbers? If you define "number" to include all of these different mathematical objects, then the problem is ill-typed because, for example, you can't add a p-adic to a real. The problem doesn't define what should happen in this case; should it crash? Return 7*pi?

2. You can't "increment a number". Adding 2 to 3 doesn't change the value of 3! 3 still remains 3. Numbers, as defined by mathematics sense, are immutable. One might correct this by indicating that your function should take a reference to an integer, and add a certain integer to the value referred to. But is such a function actually a function? Not in the mathematical sense. What about the case where the reference is null, if the language supports such a concept?

What the article did succeed in doing, if you read through the code examples, is highlight the non-portability (across languages) of programs depending on ill-defined concepts like "references" and "numbers". The problem as posed can't be solved minimally (with neither error cases nor behaviour beyond what is specified) in any of the languages shown!

-Tim

Patrick Logan - Re: Paul Graham: Accumulator Generator  blueArrow
2/13/2003; 4:30:07 PM (reads: 2064, responses: 0)
I had the same response as Tim: while this comparison says somewhat interesting things about various languages, the description itself is a study on poor specifications.

BTW somebody from the Mozart team better get a more palatable sample on that page quick. What a mess!

Erlang: Yes! Maybe this will get people to realize just how lightweight their processes are.

Manuel Simoni - Re: Paul Graham: Accumulator Generator  blueArrow
2/13/2003; 5:59:11 PM (reads: 2029, responses: 0)

> The term "number" is left undefined.

On the companion page, accgensub.html, "number" is somewhat defined: Works for any numeric type-- i.e. can take both ints and floats and returns functions that can take both ints and floats.

It's probably supposed to be an abstract data type that supports the + message, and not a pure mathematical number. It is right that nothing is said about the paradigm used to describe the situation (for example message-passing paradigm.)

> the Python version he has is just plain silly

I do not know Python, but it seems to me that def foo(n): return lambda i: n+i would violate point 3 on the companion page (Generates functions that return the sum of every number ever passed to them, not just the most recent.) because n is never incremented.

Todd Coram - Re: Paul Graham: Accumulator Generator  blueArrow
2/14/2003; 6:38:40 AM (reads: 1975, responses: 0)
The OO examples (C++ and Python) are something of a cheat since they rely on object instantiation as the "function returning a function". But, then again, its only a cheat if Graham was trying to make a point about unamed function and closure support in languages.

A couple of Tcl solutions (http://mini.net/tcl/3520) were turned down (for unclear reasons), so I imagine that the interpretation of the requirements are subject to Graham's tastes.

Ruiner - Re: Paul Graham: Accumulator Generator  blueArrow
2/14/2003; 4:25:46 PM (reads: 1881, responses: 0)
Interesting that he specifically excludes ocaml and ml because they have no way to implictly intermingle floats and ints. Of course, I still haven't figured out why it is that ocaml will allow you to write comparisons that work on ints or floats but not arithmetic operators. i.e.
# let comp x y = x < y;;
val comp : 'a -> 'a -> bool = <fun>
# comp 1 2;;
- : bool = true
# comp 1.2 2.2;;
- : bool = true
It's kind of an annoying wrinkle on an otherwise nicely balanced language.

Isaac Gouy - Re: Paul Graham: Accumulator Generator  blueArrow
2/15/2003; 8:36:44 AM (reads: 1824, responses: 1)
ocaml will allow you to write comparisons that work on ints or floats but not arithmetic operators
I'm unsure what you mean, could you say more.

Ehud Lamm - Re: Paul Graham: Accumulator Generator  blueArrow
2/15/2003; 9:39:27 AM (reads: 1874, responses: 0)
Since I haven't used Ocaml I can only speculate. Aren't these the same as the equality types in ML?

Isaac Gouy - Re: Paul Graham: Accumulator Generator  blueArrow
2/15/2003; 10:54:14 AM (reads: 1796, responses: 0)
I was unclear. As far as I can tell you can't directly compare int with float, and you can't directly use arith operators for int with float.
# comp 1 1.0;;
Characters 7-10:
  comp 1 1.0;;
         ^^^
This expression has type float but is here used with type int

# 1 + 1.0 ;; Characters 4-7: 1 + 1.0 ;; ^^^ This expression has type float but is here used with type int

Oh, I see, Ruiner was pointing out that int and float use the same relational operators < > = but use different arithmetic operators: + * for int but +. *. for float

Isaac Gouy - Re: Paul Graham: Accumulator Generator  blueArrow
2/15/2003; 1:01:01 PM (reads: 1765, responses: 0)
Tim wrote This is an interesting study of solutions to an ill-defined problem
With just int and float, I wonder if the solutions listed do the same implicit numeric conversions, and give the same result?

Dan Shappir - Re: Paul Graham: Accumulator Generator  blueArrow
2/17/2003; 1:25:20 AM (reads: 1682, responses: 0)
You should check out Sjoerd's Accumulator Generator implementation using Loell, it's the shortest one yet. This is not so surprising considering that the Accumulator Generator design pattern as presented by Paul Graham is best supported by closures, and Loell is all about closures.

Ruiner - Re: Paul Graham: Accumulator Generator  blueArrow
2/17/2003; 1:03:33 PM (reads: 1668, responses: 0)
Oh, I see, Ruiner was pointing out that int and float use the same relational operators < > = but use different arithmetic operators: + * for int but +. *. for float
Indeed. The reason I was pointing it out is that if ocaml's (+) supported the same sort of overloading as (<), then Graham's generator could be written:
let foo n = let x = ref n in function i -> x := !x + i; !x;;

It would be convenient if operators and functions could be overloaded in ocaml. But at the same time I still have not the feeling that it makes that much difference in practice. However, I understand someone has implemented this. But I can't tell if it will ever be incorporated into the language.

Isaac Gouy - Re: Paul Graham: Accumulator Generator  blueArrow
2/18/2003; 10:50:02 AM (reads: 1568, responses: 0)
Graham's generator could be written
Let me take this opportunity to be wrong ;-)
Let's say ocaml's + did have the same sort of overloading as ocaml's <

Why would that help with accumlator generator? As far as I can see, int < int is valid, float < float is valid, but int < float is invalid. So even if + supported the same sort of overloading as <, wouldn't int + float be invalid?

Ruiner - Re: Paul Graham: Accumulator Generator  blueArrow
2/18/2003; 11:41:29 AM (reads: 1567, responses: 0)
It depends on how '+' was defined but if it were defined as
   generic plus = case
   | int -> int -> int => (+)
   | float -> float -> float => (+.)
   | int -> float -> float => fun x y -> float x +. y
   | float -> int -> float => fun x y -> x +. float y
   ...
then it would work just fine (stolen from http://pauillac.inria.fr/~furuse/thesis/chapter01.ps.gz)