# How to use lambda expression in Painless?

**URL:** <https://discuss.elastic.co/t/how-to-use-lambda-expression-in-painless/103758>\
**Category:** Elasticsearch\
**Created:** [October 12, 2017, 3:42pm UTC](https://discuss.elastic.co/t/how-to-use-lambda-expression-in-painless/103758 "2017-10-12T15:42:30Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![klahnakoski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/klahnakoski/32/3679_2.png) [@klahnakoski](https://discuss.elastic.co/u/klahnakoski)\
**Post date:** [October 12, 2017, 3:42pm UTC](https://discuss.elastic.co/t/how-to-use-lambda-expression-in-painless/103758/1 "2017-10-12T15:42:30Z")

</div>

I am attempting to define-and-call a lambda function. This technique works in Java, but I have not been able to do this from Painless:

```
{
    "from": 0,
    "query": {"bool": {"must": [{"match_all": {}}]}},
    "script_fields": {"v": {"script": {
        "inline": "((doc[\"v.$string\"].empty) && (doc[\"v.$number\"].empty))?null:((!(doc[\"v.$number\"].empty)) ? (((Function) (\n value -> {\n String output = String.valueOf(value);\n if (output.endsWith(\".0\")) {\n output = output.substring(0, output.length() - 2);\n }//endif\n return output;\n }\n )).apply((doc[\"v.$number\"].values)[0])) : ((doc[\"v.$string\"].values)[0]))",
        "lang": "painless"
    }}},
    "size": 10,
    "stored_fields": []
}

```

here is a the same script, slightly better formatted,

```
((doc["v.$string"].empty) && (doc["v.$number"].empty))?null:((!(doc["v.$number"].empty)) ? (((Function) (
                    value -> {
                        String output = String.valueOf(value);
                        if (output.endsWith(".0")) {
                            output = output.substring(0, output.length() - 2);
                        }//endif
                        return output;
                    }
            )).apply((doc["v.$number"].values)[0])) : ((doc["v.$string"].values)[0]))

```

The query results in an error:

```
Internal Server Error:{
"error":{
	"root_cause":[{
		"type":"script_exception",
		"reason":"compile error",
		"script_stack":[
			"... value -> {\n ...",
			" ^---- HERE"
		],
		"script":"((doc[\"v.$string\"].empty) && (doc[\"v.$number\"].empty))?null:((!(doc[\"v.$number\"].empty)) ? (((Function) (\n value -> {\n String output = String.valueOf(value);\n if (output.endsWith(\".0\")) {\n output = output.substring(0, output.length() - 2);\n }//endif\n return output;\n }\n )).apply((doc[\"v.$number\"].values)[0])) : ((doc[\"v.$string\"].values)[0]))",
		"lang":"painless"
	}],
	"type":"search_phase_execution_exception",
	"reason":"all shards failed",
	"phase":"query",
	"grouped":true,
	"failed_shards":[{
		"shard":0,
		"index":"testing_000_k20171012_153014",
		"node":"QAI8rNAFTsOpaRaSYAA1Hw",
		"reason":{
			"type":"script_exception",
			"reason":"compile error",
			"script_stack":[
				"... value -> {\n ...",
				" ^---- HERE"
			],
			"script":"((doc[\"v.$string\"].empty) && (doc[\"v.$number\"].empty))?null:((!(doc[\"v.$number\"].empty)) ? (((Function) (\n value -> {\n String output = String.valueOf(value);\n if (output.endsWith(\".0\")) {\n output = output.substring(0, output.length() - 2);\n }//endif\n return output;\n }\n )).apply((doc[\"v.$number\"].values)[0])) : ((doc[\"v.$string\"].values)[0]))",
			"lang":"painless",
			"caused_by":{
				"type":"illegal_argument_exception",
				"reason":"invalid sequence of tokens near ['->'].",
				"caused_by":{"type":"no_viable_alt_exception","reason":null}
			}
		}
	}]
},
"status":500

```

}

I have tried a variety of legitimate Java, but nothing works. I suspect the Painless parser is expecting the lambda definition to be a parameter of a method call, not some stand-alone entity. How can I call this lambda expression?

Thank you

---

<div class="post-metadata">

**Author:** ![klahnakoski](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/klahnakoski/32/3679_2.png) [@klahnakoski](https://discuss.elastic.co/u/klahnakoski)\
**Post date:** [October 12, 2017, 5:03pm UTC](https://discuss.elastic.co/t/how-to-use-lambda-expression-in-painless/103758/2 "2017-10-12T17:03:14Z")

</div>

The trick is to find a method that accepts a lambda. In this case `Optional.of(<expr>).map(<lambda>).orElse(null)` works good enough:

```
{
    "from": 0,
    "query": {"bool": {"must": [{"match_all": {}}]}},
    "script_fields": {"v": {"script": {
        "inline": "((doc[\"v.$string\"].empty) && (doc[\"v.$number\"].empty))?null:((!(doc[\"v.$number\"].empty)) ? (Optional.of((doc[\"v.$number\"].values)[0]).map(\n value -> {\n String output = String.valueOf(value);\n if (output.endsWith(\".0\")) {\n output = output.substring(0, output.length() - 2);\n }//endif\n return output;\n }\n ).orElse(null)) : ((doc[\"v.$string\"].values)[0]))",
        "lang": "painless"
    }}},
    "size": 10,
    "stored_fields": []
}
```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [November 9, 2017, 5:03pm UTC](https://discuss.elastic.co/t/how-to-use-lambda-expression-in-painless/103758/3 "2017-11-09T17:03:27Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
