Announcement

Collapse
No announcement yet.

Programming question

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Originally posted by Kuciwalker View Post
    Asher, 90% of the work on this issue is not "how should we do closures" but "how should we do lambdas". They are different things. The rest is "should we relax the final restriction and force the VM to do a significant internal overhaul?"


    Kuci, I cannot explain this any better. Closures do not exist in Java. This is according to virtually everyone. James Gosling states they do not exist in Java. Mark Reinhold states they do not exist in Java. The entire ****ing internet states they do not exist in Java.

    Closures can serve as anonymous functions/classes, but they ARE NOT anonymous functions/classes.

    Here is an article by a Senior Sun engineer:
    http://www.ibm.com/developerworks/java/library/j-jtp04247.html

    The Java language provides inner classes, which can contain references to fields of their enclosing object. This feature is richer than function pointers because it allows the inner class instance to retain a reference to the environment in which it was created. Indeed, at first glance, inner classes seem to provide most, if not all, of the value of closures; one could easily construct an interface called UnaryFunction and create a memoizing wrapper that can memoize any unary function. But this approach is often unwieldy in practice; it forces all the code that interacts with your function to be written with an awareness of this function "framework."

    Anonymous classes let you create objects that capture part of the environment in which they were defined, but objects and blocks of code are not the same thing. As an example, consider any repetitive coding pattern, such as executing a block of code with a Lock held. If we want to increment a counter with a Lock held, the code looks like Listing 2 -- frustratingly verbose for such a simple operation:

    Listing 2. Canonical idiom for executing a block of code with a lock held

    lock.lock();
    try {
    ++counter;
    }
    finally {
    lock.unlock();
    }

    It would be nice to abstract out the lock management code, which would make the code more compact and less error-prone. As a first attempt, you might create a withLock() method like Listing 3:

    Listing 3. Attempt at abstracting the concept of "do this while holding lock," which suffers from a lack of exception transparency

    public static void withLock(Lock lock, Runnable r) {
    lock.lock();
    try {
    r.run();
    }
    finally {
    lock.unlock();
    }
    }

    Unfortunately, this approach only takes you part of the way to where you want to be. One of the goals of creating this abstraction was to make the code more compact; unfortunately, the syntax of anonymous inner classes is not very compact, and the calling code will look something like Listing 4:

    Listing 4. Client code for the withLock() method in Listing 3

    withLock(lock,
    new Runnable() {
    public void run() {
    ++counter;
    }
    });

    That's still a lot of code just to increment a counter with a lock held! Further, the abstraction barrier introduced by turning the block of code that is guarded by a lock into a method invocation complicates matters severely -- what happens if the guarded block of code might throw a checked exception? Now we cannot use Runnable as our task representation; we must create a new representation that allows exceptions to be thrown across the method invocation. Unfortunately, generics don't help us very much here either; while you can create a method that has a generic type parameter E identifying a checked exception it might throw, this approach doesn't generalize well to methods that throw more than one checked exception type (which is why the call() method in Callable is declared to throw Exception, rather than a type specified by a type parameter). The approach in Listing 3 is hampered by a lack of exception transparency. It also suffers from other forms of nontransparency; statements like return or break would mean something different in the context of the Runnable in Listing 4 than they would in the try block in Listing 2.
    Ideally, you'd like to be able to have your guarded increment operation look something like Listing 5 and have the code in the block mean the same as it would in the expanded form from Listing 2:

    Listing 5. Ideal (but hypothetical) form for client code for Listing 3

    withLock(lock,
    { ++counter; });

    By adding closures to the language, it becomes possible to create methods that can behave like control flow constructs, such as "execute this code with a lock held," "operate on this stream and close it when you're done," or "time how long it takes to execute this block of code." This strategy has the potential to simplify certain types of code that repeatedly use particular coding patterns or idioms, such as the locking idiom in Listing 2. (Another technique that offered similar expressiveness, to a certain extent, was the C preprocessor; it is possible to express the withLock() operation as a preprocessor macro, though macros are harder to compose and less safe than closures.)
    My point is you can approximate many of the features of closures, but there does not exist an actual closures implementation in Java. Your statement that Java has supported closures since 1997 is simply wrong. That is all there is to it.
    "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
    Ben Kenobi: "That means I'm doing something right. "

    Comment


    • dp
      "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
      Ben Kenobi: "That means I'm doing something right. "

      Comment


      • "Ricky" on blogspot, really? This is who you are using to refute the PEOPLE WHO DESIGNED THE LANGUAGE?
        "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
        Ben Kenobi: "That means I'm doing something right. "

        Comment


        • Originally posted by Kuciwalker View Post
          There is literally no difference whatsoever between two immutable references to the same object (which may itself be mutable) and one immutable reference shared between two closures.
          Didn't I already explain this to you?

          This approximation only works if you are manipulating a mutable reference type. It does not emulate proper Closure behaviour if you use immutable reference types or primitives.
          "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
          Ben Kenobi: "That means I'm doing something right. "

          Comment


          • The world's leading online dictionary: English definitions, synonyms, word origins, example sentences, word games, and more. A trusted authority for 25+ years!


            1. In a reduction system, a closure is a data structure that holds an expression and an environment of variable bindings in which that expression is to be evaluated. The variables may be local or global. Closures are used to represent unevaluated expressions when implementing functional programming languages with lazy evaluation. In a real implementation, both expression and environment are represented by pointers.


            Again, this is precisely an anonymous class in Java!

            Kuci, I cannot explain this any better. Closures do not exist in Java. This is according to virtually everyone. James Gosling states they do not exist in Java. Mark Reinhold states they do not exist in Java. The entire ****ing internet states they do not exist in Java.


            Tough. Anonymous classes meet all the necessary criteria to be called closures. They are, in the general case, very syntactically awkward closures. But for many common use cases (e.g. comparator) the relevant interface has already been defined and writing the closures is relatively painless.

            Comment


            • Originally posted by Asher View Post
              Didn't I already explain this to you?

              This approximation only works if you are manipulating a mutable reference type. It does not emulate proper Closure behaviour if you use immutable reference types or primitives.
              Asher, there is no difference between two functions containing different immutable references to the same immutable object, and two functions containing the same immutable reference to the same immutable object. Nor is there a difference between them containing different copies of the same immutable primitive versus sharing a copy of an immutable primitive.

              And in a pure functional language, the Java way is actually how you would implement closures.

              Comment


              • Originally posted by Kuciwalker View Post
                http://dictionary.reference.com/browse/closure?db=*

                1. In a reduction system, a closure is a data structure that holds an expression and an environment of variable bindings in which that expression is to be evaluated. The variables may be local or global. Closures are used to represent unevaluated expressions when implementing functional programming languages with lazy evaluation. In a real implementation, both expression and environment are represented by pointers.


                Again, this is precisely an anonymous class in Java!
                Didn't you go to CMU? This is just embarrassing. I thought it was a top-notch CS school.

                Anonymous classes are not closures, regardless of what dictionary.com might think. Closures do not exist in Java, your comment was wrong. Closures may exist in Java once they add it in Java 8.

                I'm retiring from this discussion because you are being patently absurd.
                "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
                Ben Kenobi: "That means I'm doing something right. "

                Comment


                • Shorter Asher: "lots of people say they aren't closures!"

                  Shorter Kuci: "hey, here's the definition of a closure, oh look anonymous classes satisfy it"

                  Comment


                  • I'm going to leave the discussion with a quote from one of the main Java designers.



                    From: Guy Steele - Sun Microsystems Labs sun.com>
                    Subject: Re: bindings and assignments (was: Re: continuations)
                    Newsgroups: gmane.comp.lang.lightweight
                    Date: 2003-08-21 19:57:51 GMT (7 years, 8 weeks, 5 days, 15 hours and 28 minutes ago)

                    ...

                    Some such programmers were asked, and we got a number of reactions,
                    including, "Ugh, bletch, even if you support full closures, they'll
                    be really ugly with all that syntax... I'm sticking to Lisp!"

                    Please remember that the design of a programming language consists
                    not just in a laundry list of features, but also in making judicious
                    choices of what to *omit* and, more importantly, in establishing
                    design principles that are easy to understand.

                    Java does not support decimal arithmetic well, nor classic coroutines,
                    nor full IEEE 754 floating-point arithmetic, nor computed GOTO,
                    nor Fortran-style (or Common Lisp-style) FORMAT operations, nor
                    automatic backtracking, nor pattern matching, nor unification of
                    PROLOG-style expressions, nor tail calls, nor a host of other features.
                    I've been beat up pretty hard over some of these. Some of them I even
                    argued for myself in the early days of Java (such as tail calls).
                    But others simply aren't needed for the clientele Java is trying to
                    serve.

                    One of the early design principles of Java was that heap allocation
                    occurrs if and only if a construct involving the "new" keyword is
                    executed. Adding full-blown closures violated this design principle.

                    (Dynamic class loading also violated the principle, but users seemed
                    to be comfortable with that, perhaps because they believed that
                    "once the computation got going" no more heap allocation would occur.)

                    Other features for Java release 1.5 will perform certain kinds
                    of autoboxing, which also violates the design principle. This fact
                    will make it easier to argue for restoring full-blown support
                    for closures in the future.

                    --Guy Steele
                    You are confusing a hacky approximation for closures using anonymous inner classes (which by everyone's expert opinion (save for 'Ricky'), does not constitute being a real closure) with closures. It should be clear to you that the statement that Java supports closures, when its own creators insist it does not, is incorrect.

                    This little song and dance about pedantic dictionary.com definitions is simply embarrassing for you. It's quite clear you do not understand the computer science concept around closures, which is clearly too nuanced for your understanding. Try out my factorial suggestion, then compare how it was implemented to C#. Then tell me which supports closures.
                    "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
                    Ben Kenobi: "That means I'm doing something right. "

                    Comment


                    • You are confusing a hacky approximation for closures using anonymous inner classes (which by everyone's expert opinion (save for 'Ricky'), does not constitute being a real closure) with closures. It should be clear to you that the statement that Java supports closures, when its own creators insist it does not, is incorrect.

                      This little song and dance about pedantic dictionary.com references is simply embarrassing for you. It's quite clear you do not understand the computer science concept around closures, which is clearly too nuanced for your understanding. Try out my factorial suggestion, then compare how it was implemented to C#. Then tell me which supports closures.


                      To the contrary, it's quite clear that I understand the actual idea of closures, and how Java (poorly) satisfies it, while you equate closures with lambdas even though they are subtly different things.

                      Comment


                      • Yes. I am confusing it, along with the people who created Java, the current Sun/Oracle engineers creating Java, the vast majority of the Java development community, etc. We are all wrong.

                        Perhaps you should send James Gosling the link to dictionary.com and let him know. He's out of the loop.
                        "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
                        Ben Kenobi: "That means I'm doing something right. "

                        Comment


                        • One of the early design principles of Java was that heap allocation
                          occurrs if and only if a construct involving the "new" keyword is
                          executed. Adding full-blown closures violated this design principle.


                          Adding closures over non-final variables would violate it. But you get exactly the same expressive power with a final Map<String, Object>...

                          Comment


                          • Seriously, Kuci: Write up something to compute the factorial of 1000 (int) in Java using "closures". I'll respond with the equivalent C# implementation.

                            That'll settle this debate.
                            "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
                            Ben Kenobi: "That means I'm doing something right. "

                            Comment


                            • Originally posted by Kuciwalker View Post
                              One of the early design principles of Java was that heap allocation
                              occurrs if and only if a construct involving the "new" keyword is
                              executed. Adding full-blown closures violated this design principle.


                              Adding closures over non-final variables would violate it. But you get exactly the same expressive power with a final Map%lt;String, Object%gt;...
                              Why do you not understand that the 'final' workaround does not always apply?

                              When computer scientists talk about computers, we try to speak in terms of universality. Because Java's hacky approximation for closures works in ~90% of cases does not mean it supports closures. I think the main disconnect here is you don't see why the 'final' workaround does not always work...if you understood that, we'd be getting somewhere.
                              "The issue is there are still many people out there that use religion as a crutch for bigotry and hate. Like Ben."
                              Ben Kenobi: "That means I'm doing something right. "

                              Comment


                              • Originally posted by Asher View Post
                                Yes. I am confusing it, along with the people who created Java, the current Sun/Oracle engineers creating Java, the vast majority of the Java development community, etc. We are all wrong.

                                Perhaps you should send James Gosling the link to dictionary.com and let him know. He's out of the loop.
                                Does it bother you that 90% of your posts are appeals to authority?

                                Closures aren't formally defined anywhere outside of specific programming languages. Informal defiitions will generally describe Java anonymous classes, so long as they don't require closure over all variables in scope. And closure over just one reference to a mutable collection instantly gives you all of the power of "normal" closures. The only difference is in ease-of-use.

                                Comment

                                Working...
                                X