schibsted / jslt

JSON query and transformation language
Apache License 2.0
618 stars 119 forks source link

Higher Order Functions #120

Open wdonne opened 4 years ago

wdonne commented 4 years ago

I've been writing functions in jslt and I miss higher order functions. Being able to pass a function as an argument to another function or to return a function can make code a lot DRYer. I think closures would be a vital part of this feature.

larsga commented 4 years ago

I have a lot of sympathy for this view, and have been thinking along the same lines myself. The difficulty is that so far JSLT has maintained a strict "all values are JSON" approach, which makes functions-as-values problematic. Although not necessarily impossible.

It would be interesting to see some code examples showing ways you are thinking you would use this feature, assuming JSLT had it.

wdonne commented 4 years ago

I understand that the impact would be considerable in that case. Because I changed my original code in the end the better example is gone now. Instead I'll show this tiny one. The current code is this:

def relation(filteredRelations)
  if (size($filteredRelations) == 1) $filteredRelations[0] else null

def relation-parent(relations, type)
  relation([for ($relations) . if (.type == 1 and .pupilRelationType == $type)])

def relation-self(relations)
  relation([for ($relations) . if (.type == 1 and .pupilRelationType == null)])

The "algorithm" is repeated in the functions relation-parent and relation-self. Instead it could be like this:

def relation-with(relations, criterion)
    relation([for ($relations) . if (.type == 1 and criterion(.))])

It could then be called like this:

relation-with(relations, json -> json.pupilRelationType == null)

The example is too small to make a point, but for every new criterion I would have to repeat relation-with, while with a predicate I could use any criterion.