Preparing for the 0.2 draft

Neal Gafter neal at gafter.com
Mon Feb 1 00:58:09 PST 2010


I ran the stats for openjdk6 sources, but not quite as you asked.  I started
answering questions that filter out those anons that couldn't possibly be
lambdas for one reason or another, and then answered the rest of the
interesting questions from among those.  It isn't interesting to know which
anonymous inner classes use "this" if they couldn't be lambdas because there
are, for example, constructor arguments.

So here are the stats:

Total anonymous classes: 1155
But with no constructor args: 1068
And defining only one method: 883
And where the type is a SAM type: 811
  Those that are recursive: 0
  Those that reference 'this': 2 (see below)
  Those that reference an enclosing 'this': 48
  Those that are interfaces: 752
  Those that are classes: 59
Total distinct interfaces: 50 (see below)
Total distinct classes: 13 (see below)

A couple of interesting things about the use cases exposed by this analysis:

There is virtually no utility to making "this" refer to the function
itself.  In the two cases where "this" appears, one does not actually use
the value (null would work as well), and the other could be trivially
rewritten using the proposed definite-assignment rule for a lambda appearing
in a variable initializer.  None of the anonymous SAMs are recursive.  On
the other hand, there are a fair number of explicit references to the
instance of the enclosing class, which would benefit from lexical scoping.

I also note that the use cases involving classes do not suffer from
lexically scoped lambdas because they can continue to be written exactly as
they are today.  Even the proposed lambda spec does not provide typesafe
access to the underlying SAM type, so I can't see anywhere this code base
would benefit from lambdas in which "this" references the function object
rather than the lexically enclosing instance.

Since Josh hadn't seen any use cases that benefit from lexical scoping of
"this", I've also enclosed pointers to 48 locations in the openjdk6 source
base.

====================================
Below are shown the two places where "this" appears.

The first would be easily solved by a rule treating a variable as definitely
assigned in the right-hand-side of its declaration if the initializing
expression is a delegate.

In the second, "null" would work just as well as "this", because the value
is discarded by the caller (on the next line).

in src/share/classes/sun/java2d/StateTrackableDelegate.java:
   public synchronized StateTracker getStateTracker() {
       StateTracker st = theTracker;
       if (st == null) {
           switch (theState) {
           case IMMUTABLE:
               st = StateTracker.ALWAYS_CURRENT;
               break;
           case STABLE:
               st = new StateTracker() {
                   public boolean isCurrent() {
                       return (theTracker == this);
                   }
               };
               break;
    ....

in src/share/classes/javax/imageio/spi/IIORegistry.java
        PrivilegedAction doRegistration =
            new PrivilegedAction() {
                public Object run() {
                    Iterator categories = getCategories();
                    while (categories.hasNext()) {
                        Class<IIOServiceProvider> c =
(Class)categories.next();
                        for (IIOServiceProvider p :
ServiceLoader.loadInstalled(c)) {
                            registerServiceProvider(p);
                        }
                    }
                    return this;
                }
            };
        AccessController.doPrivileged(doRegistration);

====================================
Below are all the distinct classes

     com.sun.tools.example.debug.tty.Commands.AsyncExecution
     com.sun.tools.hat.internal.model.AbstractJavaHeapObjectVisitor
     com.sun.tools.hat.internal.util.Comparer
     java.awt.font.TextLine.Function
     java.io.InputStream
     java.io.OutputStream
     java.lang.Thread
     java.nio.charset.CoderResult.Cache
     java.util.TimerTask
     java.util.regex.Pattern.CharProperty
     java.util.regex.Pattern.CharPropertyNames.CharPropertyFactory
     java.util.regex.Pattern.CharPropertyNames.CloneableProperty
     javax.swing.AbstractAction


====================================
Below are all the distinct interfaces

     com.sun.java.util.jar.pack.Histogram.BitMetric
     com.sun.jdi.connect.Transport
     com.sun.jmx.remote.internal.NotificationBufferFilter
     com.sun.media.sound.ModelTransform
     com.sun.net.ssl.HostnameVerifier
     com.sun.security.auth.callback.DialogCallbackHandler.Action
     com.sun.tools.example.debug.bdi.InputListener
     com.sun.tools.example.debug.bdi.OutputListener
     com.sun.tools.example.debug.expr.ExpressionParser.GetFrame
     com.sun.tools.hat.internal.oql.ObjectVisitor
     com.sun.tools.jdi.CommandSender
     com.sun.tools.script.shell.Main.Command
     java.awt.Conditional
     java.awt.KeyEventPostProcessor
     java.awt.event.ActionListener
     java.awt.event.HierarchyListener
     java.beans.ExceptionListener
     java.beans.PropertyChangeListener
     java.beans.VetoableChangeListener
     java.io.FilenameFilter
     java.io.ObjectInputValidation
     java.lang.Runnable
     java.net.CookiePolicy
     java.net.HttpCookie.CookieAttributeAssignor
     java.security.PrivilegedAction
     java.security.PrivilegedExceptionAction
     java.util.Comparator
     java.util.Enumeration
     java.util.concurrent.Callable
     java.util.concurrent.Executor
     java.util.concurrent.ThreadFactory
     javax.imageio.event.IIOReadWarningListener
     javax.imageio.event.IIOWriteWarningListener
     javax.management.NotificationListener
     javax.swing.UIDefaults.ActiveValue
     javax.swing.UIDefaults.LazyValue
     javax.swing.event.CaretListener
     javax.swing.event.ChangeListener
     javax.swing.event.HyperlinkListener
     javax.xml.crypto.KeySelectorResult
     javax.xml.crypto.NodeSetData
     sun.awt.RequestFocusController
     sun.java2d.StateTracker
     sun.java2d.cmm.ProfileActivator
     sun.java2d.loops.ProcessPath.EndSubPathHandler
     sun.misc.JavaIODeleteOnExitAccess
     sun.misc.JavaLangAccess
     sun.misc.JavaNetAccess
     sun.nio.ch.FileChannelImpl.FileLockTable.Releaser
     sun.nio.ch.Interruptible


====================================

Locations in openjdk6 where lexically-scoped "this" would be helpful:

src/share/classes/com/sun/java/util/jar/pack/Histogram.java:187
src/share/classes/com/sun/media/sound/SoftJitterCorrector.java:126
src/share/classes/com/sun/security/auth/PolicyFile.java:849
src/share/classes/com/sun/tools/example/debug/bdi/JDIEventSource.java:80
src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java:167
src/share/classes/com/sun/tools/jdi/ClassTypeImpl.java:189
src/share/classes/com/sun/tools/jdi/ObjectReferenceImpl.java:341
src/share/classes/java/awt/Container.java:2744
src/share/classes/java/awt/Container.java:4268
src/share/classes/java/awt/Container.java:4283
src/share/classes/java/awt/EventQueue.java:823
src/share/classes/java/awt/SequencedEvent.java:92
src/share/classes/java/awt/datatransfer/Clipboard.java:128
src/share/classes/java/awt/datatransfer/Clipboard.java:326
src/share/classes/java/beans/beancontext/BeanContextSupport.java:1296
src/share/classes/java/beans/beancontext/BeanContextSupport.java:1310
src/share/classes/java/lang/Class.java:1306
src/share/classes/java/nio/channels/spi/AbstractSelector.java:208
src/share/classes/java/security/ProtectionDomain.java:317
src/share/classes/java/util/regex/Pattern.java:3352
src/share/classes/javax/management/monitor/Monitor.java:1609
src/share/classes/javax/swing/BufferStrategyPaintManager.java:213
src/share/classes/javax/swing/JComponent.java:4804
src/share/classes/javax/swing/JOptionPane.java:1011
src/share/classes/javax/swing/JOptionPane.java:1524
src/share/classes/javax/swing/ProgressMonitor.java:214
src/share/classes/javax/swing/SwingWorker.java:902
src/share/classes/javax/swing/TimerQueue.java:95
src/share/classes/javax/swing/plaf/basic/BasicLookAndFeel.java:2123
src/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java:745
src/share/classes/javax/swing/plaf/basic/BasicPopupMenuUI.java:778
src/share/classes/javax/swing/text/JTextComponent.java:4932
src/share/classes/sun/applet/AppletClassLoader.java:631
src/share/classes/sun/applet/AppletViewer.java:641
src/share/classes/sun/awt/datatransfer/SunClipboard.java:113
src/share/classes/sun/awt/datatransfer/SunClipboard.java:287
src/share/classes/sun/awt/im/InputContext.java:648
src/share/classes/sun/security/jca/ProviderConfig.java:244
src/share/classes/sun/security/provider/SeedGenerator.java:255
src/share/classes/sun/tools/jconsole/inspector/XSheet.java:181
src/share/classes/sun/tools/jconsole/inspector/XSheet.java:216
src/share/classes/sun/tools/jconsole/inspector/XSheet.java:329
src/share/classes/sun/tools/jconsole/inspector/XSheet.java:371
src/share/classes/sun/tools/jconsole/inspector/XSheet.java:411
src/share/classes/sun/tools/jconsole/inspector/XSheet.java:668
src/share/classes/sun/tools/jconsole/inspector/XSheet.java:686
src/share/classes/sun/tools/jconsole/inspector/XTree.java:159
src/share/classes/sun/tools/jconsole/inspector/XTree.java:261


More information about the lambda-dev mailing list