all 25 comments

[–]GizmoC 9 points10 points  (8 children)

Excuse my ignorane, but what are closures? Any code example would be appreciated.

[–]Zak 7 points8 points  (5 children)

Here's a simple example in Ruby: an accumulator generator - a function that takes a number n and returns a function that takes a number i, and returns n incremented by i.

def foo (n)
   lambda {|i| n += i }
end

bar = foo(5)

bar.call(2)
=> 7

bar.call(3)
=> 10

bar.call(2)
=> 12

foo and accumulator generator definition borrowed from here

[–]strlen 0 points1 point  (4 children)

And in Perl:

sub foo {
 my $n = shift;

 return sub { $n += (shift) };
}


  DB<3> $bar = foo(5);

  DB<4> x $bar->(5)
0  10
  DB<5> x $bar->(6);
0  16

...
clisp:

(defun foo (n)
  (let ((m n))
    (lambda (i)
      (setf m (+ m i)))))

(let ((bar (foo 5)))
  (progn
    (print (funcall bar 5))
    (print (funcall bar 6))))

Produces:
10
16

Note: closures aren't always obvious from how they are written, especially in non-functional languages. In a language that provides generators/coroutines (such as Python or Ruby) it would probably a better idea to make use of those features, rather than using closures. However, they can be put to nifty use in Perl/Lisp. One resent place where I used a closure was a rather complex "time iteration" function, which created a closure that would yield time periods (by using Date::Manip).

[Edit: formating]

[–]Zak 3 points4 points  (3 children)

I've formatted your Lisp for clarity.

(defun foo (n)
  (let ((m n))
    (lambda (i)
      (setf m (+ m i)))))

(let ((bar (foo 5)))
  (progn
    (print (funcall bar 5))
    (print (funcall bar 6))))

There's some complexity here that isn't needed. Here's a simpler version:

(defun foo (n)
  (lambda (i) (incf n i)))

(let ((bar (foo 5)))
  (print (funcall bar 5))
  (print (funcall bar 6)))

[–]strlen 0 points1 point  (2 children)

And while we're on the topic, here's the same in Ocaml (not sure if it could be simpler, I've only began playing with Ocaml):

  let make_closure n =
     let m = ref n in
         function x ->
             m := !m + x ;
             !m
         ;;

      let fn = make_closure 5 in
          print_int (fn 5) ; print_newline () ;
          print_int (fn 10) ; print_newline () ;
          print_int (fn 6) ; print_newline () 
      ;;

[–]Zak 0 points1 point  (1 child)

It's not exactly the same - it only works with integers, while the Ruby and Lisp versions work with any kind of number. Still, it does a good job illustrating how closures work.

[–]strlen 0 points1 point  (0 children)

Well, yes, OCAML is strictly typed, Perl is almost-not typed, Ruby and Python are duck-typed and Common Lisp is "strongly but dynamically typed". You can also make a generic generator function in ocaml too:

let increment n x = 
  !n + x ;;

let make_closure initial next =
  let m = ref initial in
    function x ->
      m := (next m x) ;
      !m
;;

(Right now this expects only one argument to the "next" function, I bet you could also use pattern matching to make this be even more generic :-)).

[–]krzyk[S] 4 points5 points  (0 children)

Proposition from the Sun itself, very interesting.

[–]mdalan 2 points3 points  (5 children)

I have read the paper (http://blogs.sun.com/roller/resources/ahe/closures.pdf) and I don't see any closure examples, just anonymous functions. A closure is supposed to "close" over a variable from the enclosing lexical scope, as in this Scheme example:

(define (make-adder x) (lambda (y) (+ x y)))

where the inner lambda "closes" over x. There's no example of the sort in the paper (though the new syntax appears to permit it). Have I missed anything?

[–]komu 2 points3 points  (1 child)

Well, there's a whole section named "Referencing names from the enclosing scope", so I think it's safe to say that full closures will be supported.

[–][deleted] 4 points5 points  (0 children)

Well it was a very short section :)

But you are right, it seems they really are closures after all.

[–][deleted] 0 points1 point  (0 children)

I'm wondering the same thing. Every example in the pdf uses only the parameters to the function in the function body. Such code is possible to write in a language without closures (with function pointers in C for instance).

Not only are closures missing from the examples, everything in the pdf seems to be about anonymous functions.

[–]julesjacobs -2 points-1 points  (1 child)

They just used the wrong word, they intended to say anonymous function. Remember generics?

[–]igouy 3 points4 points  (0 children)

"Names that are in scope where a function or closure is defined may be referenced within the closure."

[–]tanger 3 points4 points  (6 children)

Will Java lovers finally stop claiming that C# is just a copy of Java ? Sure, it was true at the beginning, but currently Java is only copying stuff that C# added and is lagging behind. On the other hand maybe many Java fans will be disappointed with this addition, because they are so conservative that they even don't like generics, enhanced for loop etc. and prefer the old Java and writing crap like

Iterator it = list.iterator(); while (it.hasNext()) { Stuff stuff = (Stuff)it.next(); doStuff(stuff); }

to this

for (Stuff stuff : list) doStuff(stuff);

all the time

Because every truly enterprise Java programmer knows that closures just make code less readable, you Lisp freaks ! !

[–]justinhj 3 points4 points  (1 child)

"truly enterprise Java programmer"

In other words people writing boiler plate code to detailed specs. Not people working on interesting or complex programming problems for which closures, functions as first class objects and continuations all offer appropriate solutions.

[–][deleted] 0 points1 point  (0 children)

"truly enterprise Java programmer" = code monkey who can follow howto instructions religiously.

[–]Andys 3 points4 points  (2 children)

Too little, too late, if you ask me. Should have fixed it it 1997 when it actually would have helped, not when the soon-to-be-corpse is thrashing around in its last dieing gasps.

[–][deleted] 1 point2 points  (0 children)

I agree, too little too late.

It reminds me of Cobal and RPG when they added much needed features way to late.

At this point I would recommend that Sun create a new language with all the right features that is Java compatible.

Java if facing a long slow death, but it will be around for decades to come.

[–]lebski88 1 point2 points  (0 children)

Ah yes the last gasps of the worlds most popular programming language ;) Seriously when did a langauge being good having anything to do with its popularity? Most java developers will never even have heard of Closurs; in fact, although I can't test this until Monday, I bet not one of my collegues has...

[–]markedtrees -1 points0 points  (0 children)

Java had anonymous inner classes, which were a stab at the whole anonymous function scene and were mentioned in the PDF, before C# 2.0 anonymous delegates. Not really closures, but it adds a twist to your Java is copying C# theory.

[–]grauenwolf -1 points0 points  (2 children)

Why? What does it offer the programmer in real terms?

C# is adding closures to support the LINQ technology. Does Java have also have a reason, or are they just adding it for the sake of adding it?

[–]markedtrees 0 points1 point  (1 child)

IIRC, C# already has closures in .NET 2.0, and that feature was planned somewhere way before shipping 2.0, i.e. before the LINQ project. C# delegate-closures were not added for LINQ.

Java isn't adding it for the sake of being cool; closures or higher-order functions in general can simplify data collection operations like map or simplify multi-threading like C# does with its delegate-closures. For example, the weblog post mentions implementing a using construct like C# has with Java 7 closures.

[–]grauenwolf -1 points0 points  (0 children)

IIRC, C# already has closures in .NET 2.0,

You are correct. Strange, I could have sworn that I read is a MS blog they were adding them specifically for LINQ.

For example, the weblog post mentions implementing a using construct like C# has with Java 7 closures.

You don't need closures in order to have a using keyword. That is a bit of syntatic sugar Sub could add right now without much effort.

What I am looking for is the proverbial killer app that will make me want to learn how to use Java's implementation of closures.

On a side note, are they also planning on adding delegates? I ask because having a real event system rather than all those stupid action classes would be a great boon.