Support for java 11 syntax

Previously I was excited to use java8 syntax in processing ide using Sampottingers development version of processing. However things are moving apace, and if you are prepared to build your own copy of latest version, you will find support for java11 syntax. So my first example becomes:-

import hype.*;

void setup() {
  size(640, 640);
  H.init(this);
  H.background(#242424);
  var pool = new HDrawablePool(100);
  pool.autoAddToStage()
    .add(new HRect(50))
    .onCreate(
    ((var obj) -> {
    var d =  (HDrawable)obj;
    d.strokeWeight(1)
      .stroke(#999999)
      .fill(#202020)
      .loc((int)random(width), (int)random(height));
  }
  )

  )
  .requestAll();
  H.drawStage();
  noLoop();
}

void draw() {
}

Note we do not need to pre-declare pool above since it is only use in the setup scope. This is not true for second example that becomes:-

import hype.H;
import hype.HCanvas;
import hype.HDrawable;
import hype.HDrawablePool;
import hype.HRect;
import hype.extended.behavior.HOscillator;
import hype.extended.behavior.HTimer;
import hype.extended.colorist.HPixelColorist;

HDrawablePool pool;
HPixelColorist colors;
HCanvas canvas;

void setup() {
  H.init(this);
  H.background(0xff000000);
  H.use3D(true);
  colors = new HPixelColorist("gradient.jpg");
  canvas = new HCanvas(P3D).autoClear(true);
  H.add(canvas);
  pool = new HDrawablePool(1000);
  pool.autoParent(canvas)
    .add(new HRect().rounding(10))
    .onCreate((var obj) -> {
    int i = pool.currentIndex();
    var d = (HDrawable) obj;
    d.noStroke()
      .size((int) random(40, 80), (int) random(60, 80))
      .loc((int) random(width), (int) random(height))
      .anchorAt(H.CENTER)
      .obj("xo", new HOscillator()
      .target(d)
      .property(H.X)
      .relativeVal(d.x())
      .range(-(int) random(5, 10), (int) random(5, 10))
      .speed(random(.005f, .2f))
      .freq(10)
      .currentStep(i)
      )
      .obj("ao", new HOscillator()
      .target(d)
      .property(H.ALPHA)
      .range(50, 255)
      .speed(random(.3f, .9f))
      .freq(5)
      .currentStep(i)
      )
      .obj("wo", new HOscillator()
      .target(d)
      .property(H.WIDTH)
      .range(-d.width(), d.width())
      .speed(random(.05f, .2f))
      .freq(10)
      .currentStep(i)
      )
      .obj("ro", new HOscillator()
      .target(d)
      .property(H.ROTATION)
      .range(-180, 180)
      .speed(random(.005f, .05f))
      .freq(10)
      .currentStep(i)
      )
      .obj("zo", new HOscillator()
      .target(d)
      .property(H.Z)
      .range(-400, 400)
      .speed(random(.005f, .01f))
      .freq(15)
      .currentStep(i * 5)
      );
  }
  )
  .onRequest((var obj) -> {
    var d = (HDrawable) obj;
    d.scale(1).alpha(0).loc((int) random(width), (int) random(height), -(int) random(200));

    var xo = (HOscillator) d.obj("xo");
    xo.register();
    var ao = (HOscillator) d.obj("ao");
    ao.register();
    var wo = (HOscillator) d.obj("wo");
    wo.register();
    var ro = (HOscillator) d.obj("ro");
    ro.register();
    var zo = (HOscillator) d.obj("zo");
    zo.register();
  }
  )
  .onRelease((var obj) -> {
    var d = (HDrawable) obj;

    var xo = (HOscillator) d.obj("xo");
    xo.unregister();
    var ao = (HOscillator) d.obj("ao");
    ao.unregister();
    HOscillator wo = (HOscillator) d.obj("wo");
    wo.unregister();
    var ro = (HOscillator) d.obj("ro");
    ro.unregister();
    var zo = (HOscillator) d.obj("zo");
    zo.unregister();
  }
  );
  new HTimer(50)
    .callback((var obj) -> {
    pool.request();
  }
  );
}

void draw() {
  for (var d : pool) {
    d.loc(d.x(), d.y() - random(0.25f, 1), d.z());

    d.noStroke();
    d.fill(colors.getColor(d.x(), d.y()));

    if (d.z() > -10 && d.z() < 10) {
      d.fill(0xffFFFFCC); // if the z axis hits this range, change fill to light yellow
    }
    if (d.y() < -40) {
      pool.release(d);
    }
  }
  H.drawStage();
}

void settings() {
  size(640, 640, P3D);
}

So you get to save a bit of typing, still not as elegant as ruby though.

1 Like

hallo, how to understand the differences ?

on the first look i see

-A- downloadable Processing ( Sam Pottinger 0270 )
supports JAVA 8 Lambda

-B- own build version from GitHub source ( i did not try )
supports JAVA 11 Lambda

when will all this be available for us normal users?

code difference:
-A- JAVA 8
.onCreate((Object obj) -> {
HDrawable d = (HDrawable) obj;
for (HDrawable d : pool) {

-B- JAVA 11
.onCreate((var obj) -> {
var d = (HDrawable) obj;
for (var d : pool) {


so it is all about?
https://medium.com/the-java-report/java-11-sneak-peek-local-variable-type-inference-var-extended-to-lambda-expression-parameters-e31e3338f1fe ,
http://openjdk.java.net/jeps/323 ,
http://tutorials.jenkov.com/java/lambda-expressions.html ?


1 Like

In Java 8 or 11 you shouldn’t normally need Object or var - eg. this would be more typical

onCreate(o -> {
HDrawable d = (HDrawable) o;
1 Like

Of course you are right (you can still use var inside lambda scope).

This is getting closer to ruby syntax but ruby still wins.

For completeness second example without Object in lambda as neilsmith suggested:-

import hype.H;
import hype.HCanvas;
import hype.HDrawable;
import hype.HDrawablePool;
import hype.HRect;
import hype.extended.behavior.HOscillator;
import hype.extended.behavior.HTimer;
import hype.extended.colorist.HPixelColorist;

HDrawablePool pool;
HPixelColorist colors;
HCanvas canvas;

void setup() {
  H.init(this);
  H.background(0xff000000);
  H.use3D(true);
  colors = new HPixelColorist("gradient.jpg");
  canvas = new HCanvas(P3D).autoClear(true);
  H.add(canvas);
  pool = new HDrawablePool(1000);
  pool.autoParent(canvas)
    .add(new HRect().rounding(10))
    .onCreate((obj) -> {
    int i = pool.currentIndex();
    var d = (HDrawable) obj;
    d.noStroke()
      .size((int) random(40, 80), (int) random(60, 80))
      .loc((int) random(width), (int) random(height))
      .anchorAt(H.CENTER)
      .obj("xo", new HOscillator()
      .target(d)
      .property(H.X)
      .relativeVal(d.x())
      .range(-(int) random(5, 10), (int) random(5, 10))
      .speed(random(.005, .2))
      .freq(10)
      .currentStep(i)
      )
      .obj("ao", new HOscillator()
      .target(d)
      .property(H.ALPHA)
      .range(50, 255)
      .speed(random(.3, .9))
      .freq(5)
      .currentStep(i)
      )
      .obj("wo", new HOscillator()
      .target(d)
      .property(H.WIDTH)
      .range(-d.width(), d.width())
      .speed(random(.05, .2))
      .freq(10)
      .currentStep(i)
      )
      .obj("ro", new HOscillator()
      .target(d)
      .property(H.ROTATION)
      .range(-180, 180)
      .speed(random(.005, .05))
      .freq(10)
      .currentStep(i)
      )
      .obj("zo", new HOscillator()
      .target(d)
      .property(H.Z)
      .range(-400, 400)
      .speed(random(.005, .01))
      .freq(15)
      .currentStep(i * 5)
      );
  }
  )
  .onRequest((obj) -> {
    var d = (HDrawable) obj;
    d.scale(1).alpha(0).loc((int) random(width), (int) random(height), -(int) random(200));

    var xo = (HOscillator) d.obj("xo");
    xo.register();
    var ao = (HOscillator) d.obj("ao");
    ao.register();
    var wo = (HOscillator) d.obj("wo");
    wo.register();
    var ro = (HOscillator) d.obj("ro");
    ro.register();
    var zo = (HOscillator) d.obj("zo");
    zo.register();
  }
  )
  .onRelease((obj) -> {
    var d = (HDrawable) obj;

    var xo = (HOscillator) d.obj("xo");
    xo.unregister();
    var ao = (HOscillator) d.obj("ao");
    ao.unregister();
    HOscillator wo = (HOscillator) d.obj("wo");
    wo.unregister();
    var ro = (HOscillator) d.obj("ro");
    ro.unregister();
    var zo = (HOscillator) d.obj("zo");
    zo.unregister();
  }
  );
  new HTimer(50)
    .callback((obj) -> {
    pool.request();
  }
  );
}

void draw() {
  for (var d : pool) {
    d.loc(d.x(), d.y() - random(0.25, 1), d.z());

    d.noStroke();
    d.fill(colors.getColor(d.x(), d.y()));

    if (d.z() > -10 && d.z() < 10) {
      d.fill(0xffFFFFCC); // if the z axis hits this range, change fill to light yellow
    }
    if (d.y() < -40) {
      pool.release(d);
    }
  }
  H.drawStage();
}

void settings() {
  size(640, 640, P3D);
}
1 Like

See latest Sam Potter binary release, you will need to a bit of work after unzipping binary (well on linux anyway, the processing executable is in the linux/work folder):-

1 Like

Meh! :smile: btw, you still have more brackets than you need in your example - you don’t need brackets around the input argument if there’s only one.

While I don’t think your example can make use of it, the main benefit for Processing with lambdas IMO will be access to method references. eg. in your example, something like the HTimer callback if it didn’t pass in an Object could be written in one line as new HTimer(50).callback(pool::request); I think that’s more beginner friendly than lambdas, or Strings (eg. as in the thread method that I hate!)

1 Like

i not know what you referred to,
download / unzip / make shortcut to desktop

run your test ( and sysinfo )
( works on Win 10 )

@FunctionalInterface
interface MyFunction{
  float calculate(float x);
}

void setup(){
  MyFunction doubling = (float x)-> x * 2;
  var doubled = new float[]{2,3};
  for (var value:doubled){
    println(doubling.calculate(value));
  }
  mysysinfo();
}

void mysysinfo() {
  println("\nsysinfo:");
  println( "System     : " + System.getProperty("os.name") + "  " + System.getProperty("os.version") + "  " + System.getProperty("os.arch") );
  println( "JAVA       : " + System.getProperty("java.home")  + " rev: " +javaVersionName);
  //println( "\n" + isGL() + "\n" );
  println("OPENGL_VENDOR: " + PGraphicsOpenGL.OPENGL_VENDOR+" OPENGL_RENDERER: " + PGraphicsOpenGL.OPENGL_RENDERER+" OPENGL_VERSION: " + PGraphicsOpenGL.OPENGL_VERSION+" GLSL_VERSION: " + PGraphicsOpenGL.GLSL_VERSION);
  println( "user.home  : " + System.getProperty("user.home") );
  println( "user.dir   : " + System.getProperty("user.dir") );
  println( "sketchPath : " + sketchPath() );
  println( "dataPath   : " + dataPath("") );
  println( "dataFile   : " + dataFile("") );
}

and ( your test VAR code ) only run in this latest downloaded version,
but i fail to find where the file differences are
AND he fail to have any version info ( as file or in run window “Processing 0270” same )

also not understand, is he there now? can we call it:

Processing 4.0 beta

my first test run on both ( ? as not use the var thing ?)

// https://www.datadrivenempathy.com/processing

/*

 About Sam Pottinger's Processing Branch
 The Sam Pottinger branch of Processing offers the following over the mainline version of Processing:
 
 Support for Java 11, OpenJDK, and OpenJFX.
 Move to ANTLR 4 with Java 8 language features (lambdas and generics!) and localization of syntax errors.
 Continuous integration and deployment via Travis.
 Updated license text.
 
 It is an incredibly exciting step forward in the Processing code base that helps the project prepare for its future
 while migrating to a fully open source stack and giving the community long-awaited access to important language features
 like lambdas and generics. It is currently being reviewed so is not yet official build from the Processing foundation and its edits are not accepted.
 However, like regular Processing, it is released under the same GPL / LGPL license (use at your own risk,
 no implied or explicit warranty of any kind).
 
 */

// also see https://discourse.processing.org/t/arraylist-full-of-functions/10786/6

// generic example from
// https://www.tutorialspoint.com/java/java_generics.htm#
// now try the new thing:

public static < E > void printArray( E[] inputArray ) {
  for (E element : inputArray)  System.out.printf("%s, ", element);
  println();
}

Integer[]   intArray    = { 1, 2, 3, 4, 5 };
Double[]    doubleArray = { 1.1d, 2.2d, 3.3d, 4.4d };
Character[] charArray   = { 'H', 'E', 'L', 'L', 'O' };

void setup() {
  println("Array intArray contains:");
  printArray(intArray);   // pass an Integer array

  println("\nArray doubleArray contains:");
  printArray(doubleArray);   // pass a float array

  println("\nArray charArray contains:");
  printArray(charArray);   // pass a Character array
  
  println("_____________\ntest also LAMBDA example\n");
  use_lambda();
}

void draw(){}

// now check on
// https://www.geeksforgeeks.org/lambda-expressions-java-8/

interface FuncInterface {
  void abstractFun(int x);               // An abstract function
  default void normalFun() {
    println("default normalFun(): Hello from interface FuncInterface");     // A non-abstract (or default) function
  }
}

void use_lambda() {     // lambda expression to implement above functional interface.
  //                       This interface by default implements abstractFun()
  FuncInterface fobj = (int x)->println("x= "+x+", 2*x= "+2*x);
  fobj.abstractFun(5);  // This calls above lambda expression and prints 10.
  fobj.normalFun();     // prints info
}

/*
 //without the Generic Methode it produce:
 
 Array intArray contains:
 [0] 1
 [1] 2
 [2] 3
 [3] 4
 [4] 5
 
 Array doubleArray contains:
 [0] 1.1
 [1] 2.2
 [2] 3.3
 [3] 4.4
 
 Array charArray contains:
 [0] H
 [1] E
 [2] L
 [3] L
 [4] O
 
 // with:
 
 Array intArray contains:
 1, 2, 3, 4, 5,
 
 Array doubleArray contains:
 1.1, 2.2, 3.3, 4.4,
 
 Array charArray contains:
 H, E, L, L, O,
 
 _____________
test also LAMBDA example

x= 5, 2*x= 10
default normalFun(): Hello from interface FuncInterface
 */

Processing version is still in development (the number 0270 is a numbering system I think Ben Fry uses to keep on top of versions). I somewhat expect that when it lands it will be something like 4.0.0 in semantic versioning (denoting major change and possible incompatibility with previous versions, although I expect many libraries to continue to work). For a maven project the version would probably be 4.0.0-SNAPSHOT which would warn you to expect changes until release.

1 Like