What does Code As Data mean?

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

I also came across this code example

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

from "Richard 8 Lambdas: Pragmatic Functional Programming" by Richard Warburton, where he speaks

"This is actually an example of using code as data - given a button - an object representing an action.

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

+5
source share
5 answers

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

The definition from the Wikipedia article (which refers to Abelson and Sussman's “Structure and Interpretation of Computer Programs”, section 1.3) specifically refers to 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

That is all you do with the data. If you can do the same with functions, then it's like treating "code as data."

If you look closely at how lambdas were added to the Java programming language, you will see that lambda is actually converted to an instance of the functional interface. Thus, this is an instance of some object and, therefore, a descendant of the Object class and, like all objects in Java, has methods equals(), hashCode(), getClass() , etc. And links can be compared with == and etc. However, you are clearly not encouraged to rely on all of this. See our other answer for more information. In practice, when you use lambdas in Java, it really seems like you are passing the code as an argument or assigning it to a variable. For instance,

 list.replaceAll(x -> doSomething(x)); Predicate<String> pred = s -> s.length() > 5; 

You really don’t think that under the covers of lambdas are objects that are instances of functional interfaces.

+1
source

How do you pass functionality as an argument to another method, for example, what action should be taken when someone presses a button similar to your example.

Lambda expressions allow you to do this in order to consider functionality as an argument of a method = code as data .

See the oracle link for more information and sample lambda code.

+5
source

This means that your program code that you write is also data strong>, which can be passed as an argument to another method and controlled by the program.

+1
source

In the golden age of Java, there was no convenient paradigm for transferring functions from the caller to the recipient. You had to crack the class using some method (usually using the " Command " pattern, and then pass it to the recipient.

Java 8 Lambdas have moved the paradigm by introducing lambda expressions. Forgetting how they are represented at run time, Lambdas presents itself to the developer as clean code that can be passed to methods. Code as data!

This paradigm transition has paved the way for java.util.Stream, which accept lambda expressions that tell collections about the execution of a function.

Absolutely clear, concise and complete attitude to the whole topic - a new book by Maurice Naphthalene, Mastering Lambdas - Java programming in a multi-core world .

+1
source

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

When we talk about “processing” code as data, we refer to storing references to this memory so that they can be used and organized in the way we usually think of “data”.

For example, you can imagine that inside the 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); } } } 

Basically, a button stores a list of functions in an array: it is processing the code as data. In most cases, an ActionListener serves no other purpose than to refer to a specific actionPerformed override.

Since all Java instance methods are virtual, we can always treat code as data. This is demonstrated by AWT / Swing, designed for listening. Lambda expressions simply add a conceptual accent and short syntax. (Also an increase in performance in most situations due to their implementation.)

Lambdas allows us to more clearly express our intent when we use an object only to implement a specific method, and not to store values.

From a technical point of view, all this is done indirectly. ActionListener does not contain code: instead, the virtual machine somehow knows (that we do not know) that it points to a specific structure in memory that contains a pointer to the code. Thus, some reference to the code is what is actually transmitted, therefore, "processing the code as data."

+1
source

Source: https://habr.com/ru/post/1212393/


All Articles