6

I recently came across a presentation from EclipseCon 2014, where on page 5 they say "Lambda expressions allow you to treat code as data".

I also came across this example code

button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent event) {
        System.out.println("button clicked");
    }
});

from "Java 8 Lambdas: Pragmatic Functional Programming" by Richard Warburton where he says

"This is actually an example of using code as data—we’re giving the button an object that represents an action."

What does code as data mean with respect to Lambda expressions and/or anonymous inner class?

SDS
  • 828
  • 3
  • 17
  • 35
  • Im guessing it's referring to passing around a method as a value, which lambdas give the illusion of doing. Values are seen as data, and "code" is probably referring to the block of code that is the method – Vince Feb 01 '15 at 19:48
  • Looks like any functional language that treats functions as _prime class citizens_ (the concept to give a function as input to another function). This example to me looks quite messy, other languages that are functional or hybrid-functional do a better job with the syntax, check Scala for example (which is still based on the JVM). – Marcs Feb 01 '15 at 20:59
  • "Code as data" is a catchphrase that doesn't mean anything you didn't already know. – user253751 Feb 04 '15 at 08:33

5 Answers5

5

As you pass functionality as an argument to another method, such as what action should be taken when someone clicks a button like your example code.

Lambda expressions enable you to do this, to treat functionality as method argument = code as data.

See oracle linkfor more info and lambda code examples.

MrSimpleMind
  • 7,890
  • 3
  • 40
  • 45
3

The idea of "code as data" is closely related to the concept of programming languages having first-class functions. See the Wikipedia article on this topic. In this other answer I talk about whether Java has first-class functions, but that article discusses some other issues as well.

The definition from the Wikipedia article (which cites Abelson & Sussman, Structure and Interpretation of Computer Programs, section 1.3) specifically mentions the following characteristics of functions that make them "first-class":

  • can be passed as arguments to other functions
  • can be returned as values from other functions
  • can be assigned to variables
  • can be stored in data structures

These are all things that you do with data. If you can do these same things with functions, then that's like treating "code as data."

If you look closely at how lambdas were added to the Java programming language, you'll see that a lambda is really converted to an instance of a functional interface. As such, it's an instance of some object, and therefore a descendant of class Object, and like all objects in Java, it has equals(), hashCode(), getClass() etc. methods, and references can be compared with ==, and so forth. However, you are explicitly discouraged from relying on any of this. See my other answer for additional discussion. In practice, when you use lambdas in Java, it really feels like you're passing code as an argument, or assigning it to a variable. For example,

list.replaceAll(x -> doSomething(x));

Predicate<String> pred = s -> s.length() > 5;

You really end up not thinking about the fact that, under the covers, lambdas are objects that are instances of functional interfaces.

Community
  • 1
  • 1
Stuart Marks
  • 127,867
  • 37
  • 205
  • 259
2

It means that your program code you write is also a data which can be passed as an argument to another method and manipulated by a program.

Neeraj Jain
  • 7,643
  • 6
  • 34
  • 62
1

In the golden age of Java, there was no convenient paradigm for passing functionality from a caller to a receiver. You had to hack together a class with some method (usually via the "Command" design pattern) and then pass that to the receiver.

Java 8 Lambdas have shifted the paradigm by introducing Lambda expressions. Forgetting about how these are represented to the runtime, Lambdas appear to the developer as pure code that can be passed to methods. Code as data!

This paradigm shift paved the way for java.util.Stream's that accept lambda expressions that tell a collection to perform a piece of functionality.

A beautifully clear, concise, and complete treatment of the whole topic is Maurice Naftalin's new book, Mastering Lambdas - Java Programming in a Multi-Core World.

Victor Grazi
  • 15,563
  • 14
  • 61
  • 94
1

Code is always data! The bytecode instructions for a program are stored in memory. The programmer does not have direct read and write access to this memory, but it's there.

When we talk about "treating" code as data, we refer to storing references to that memory in a way that it can be used and organized in the way we usually think of "data".

For example, one might imagine that inside button it looks something like this:

class Button {
    private ActionListener[] listeners = new ActionListener[100];
    private int count = 0;

    public void addActionListener(ActionListener listener) {
        listeners[count] = listener;
        ++count;
    }

    // called somehow when the button is clicked
    void notifyListeners() {
        ActionEvent theEvent = new ActionEvent(...);
        for(int i = 0; i < count; ++i) {
            listeners[i].actionPerformed(theEvent);
        }
    }
}

Essentially Button is keeping a list of functions in an array: this is treating code as data. In most cases an ActionListener serves no other purpose except to refer to a particular override of actionPerformed.

Since all Java instance methods are virtual, we could always treat code as data. This is demonstrated by AWT/Swing's elaborate event listening framework. Lambda expressions just add conceptual emphasis and short syntax. (Also a performance gain in most situations due to their implementation.)

Lambdas allow us to more clearly express our intent when we are using an object only to implement a particular method, not to store values.

Technically speaking, this is all done through indirection. An ActionListener does not hold the code: instead, the virtual machine knows somehow (that we are not privy to) that it points to a particular structure in memory that holds a pointer to the code. So some kind of reference to the code is what is actually getting passed around, hence "treating code as data".

Radiodef
  • 37,180
  • 14
  • 90
  • 125