Haxe Code Cookbook
Haxe programming cookbookMacrosThreading macro like Clojure and pipe operator

Threading macro like Clojure and pipe operator

Reading time: 1.5 minute

Introduction

Threading macros (or arrow macros) are used in Clojure for compose many function calls.

Other language like Elixir, LiveScript or F# use a pipe operator |> for the same functionality.

In Haxe we can create the same utility with a simple macro. Thanks to the static analyzer we can eliminate the temp variables used for memorize the intermediate values.

The code macro

 import haxe.macro.Expr; import haxe.macro.Context; using haxe.macro.ExprTools; using haxe.macro.MacroStringTools; class FunctionThread {  public static macro function thread(exprs:Array<Expr>) {  var exprs = [ for (expr in exprs) macro var _ = $expr ];  exprs.push(macro _);  return macro $b{exprs};  } } 

A simple example

 import FunctionThread.thread; class Main {  static function sum(a, b) return a + b;  static function main() {  var x = 0;  var res = thread(  sum(x,1),  sum(_,1),  sum(_,2),  sum(3,_)  );  trace(res);  } } 

The code generated in JavaScript without the static analyzer

 // Generated by Haxe 3.3.0 (function () { "use strict"; var HxOverrides = function() { }; HxOverrides.iter = function(a) {  return { cur : 0, arr : a, hasNext : function() {  return this.cur < this.arr.length;  }, next : function() {  return this.arr[this.cur++];  }}; }; var Main = function() { }; Main.sum = function(a,b,c) {  if(c == null) {  c = 0;  }  return a + b + c; }; Main.main = function() {  var x = 0;  var _ = Main.sum(x,1);  var _1 = Main.sum(_,1,5);  var _2 = Main.sum(_1,2);  var _3 = Main.sum(3,_2,7);  var res = _3;  console.log(res); }; Main.main(); })(); 

The code generated with the static analyzer

In this case thanks to the static analyzer we don't need of the temp variables

 // Generated by Haxe 3.3.0 (function () { "use strict"; var HxOverrides = function() { }; HxOverrides.iter = function(a) {  return { cur : 0, arr : a, hasNext : function() {  return this.cur < this.arr.length;  }, next : function() {  return this.arr[this.cur++];  }}; }; var Main = function() { }; Main.sum = function(a,b) {  return a + b; }; Main.main = function() {  console.log(Main.sum(3,Main.sum(Main.sum(Main.sum(0,1),1),2))); }; Main.main(); })(); 

With inline function

With inline of sum and static analyzer the output is:

console.log(7);

Contributors:
Mark Knol
francesco agati
Last modified:
Created:
Category:  Macros
Tags: