feel-scala icon indicating copy to clipboard operation
feel-scala copied to clipboard

New built-in function for string interpolation

Open saig0 opened this issue 2 years ago • 8 comments

Is your feature request related to a problem? Please describe. FEEL supports string concatenation using the + operator. For short strings, this is easy and sufficient. But it gets messy for bigger strings or string templating.

Other languages (e.g. Scala, Kotlin, etc.) support string interpolation for this case. Common syntax:

// Scala
s"Hello $name"

// Kotlin
"Hello $name"

Or, for more complex expressions:

// Scala
s"Hello ${name.forename}"

// Kotlin
"Hello ${name.forename}"

Describe the solution you'd like Provide a new built-in function for strings to support a simple form of string interpolation.

  • function name: string template()
  • arguments:
    • template: string - the template as a string with $<variable name> as placeholders
  • result:
    • string - evaluated template that contains the variable value instead of the placeholders
    • null - if a variable is not present or the template is invalid

Example:

string template("Hello $name")
// "Hello world"

string template("The score of $name is $score.")
// "The score of Jon is 78."

Related issues

  • Camunda BPM:
  • Zeebe broker:

Related conversation

saig0 avatar Jan 19 '22 06:01 saig0

Probably here I am missing a point: given the signature string template("Hello $name") who is putting $name in scope?

ubaldop avatar Jan 26 '22 17:01 ubaldop

given the signature string template("Hello $name") who is putting $name in scope?

The variables that are referenced in the template are accessed directly from the current or global scope. Instead of passing the variables as arguments explicitly (e.g. like Java's String#format("Hello %s", name)), the method can access the local/global scope to extract the variables (i.e. or to pass the variables as implicit arguments).

For example:

// name is a global variable
string template("Hello $name")

// name is a local variable
{
  name: "Jon",
  greetings: string template("Hello $name")
}

saig0 avatar Jan 27 '22 05:01 saig0

To be a real help for users in basic usage scenarios I think we should make this available via native string templating.

For example, it does not help me much if I need to pipe my template Hello ${user.name}, how are you? through a complex FEEL expression such as, i.e. populate a MESSAGE_BODY like this:

= template("Hello ${user.name}, how are you?")

What does help me tremendously if it was available for all strings, per default.

Hello ${user.name}, how are you?

Related to https://github.com/camunda-cloud/zeebe/issues/8733.

nikku avatar Feb 14 '22 10:02 nikku

@nikku I see your point. Regarding,

What does help me tremendously if it was available for all strings, per default.

Supporting interpolation/templating in default strings (e.g. "Hello ${user.name}, how are you?") could cause backward compatibility issues for existing expressions.

In order to avoid backward compatibility issues, we need a new construct for this feature. The most common way in FEEL is creating a new built-in function (e.g. string template("Hello ${user.name}, how are you?").

As an alternative, we introduce a new form of string literal. For example, using a triple quote, like in other languages Java 13+, Kotlin, Scala, etc.

"""Hello ${user.name}, how are you?"""

saig0 avatar Feb 16 '22 09:02 saig0

Tripple string could be a partial solution, if it is multi-line and trims whitespaces (beginning and end).

I could do something like this, i.e. to define an email body:

= """Hello ${user.name},

How are you doing?

Greetings 
${department.name} official"""

On the modeling UX side of things we could then automatically wrap any string-like input (no = prefix in = """${INPUT}""". So as a user, I could still just work with the plain text string:

Hello ${user.name},

How are you doing?

Greetings 
${department.name} official

This would help in other places, too. I.e. if we template URLs such as http://my.service/accounts?id=${account.id} we'd automatically wrap them into tripple-quotes, too.


It would still involve a little bit of magic though if people switch between string input and conditional input; but I'm sure we'd be able to figure that out.


We could also wrap in a template("${INPUT}") expression, but that has higher potential to break. For example we'd need to escape " in the input more carefully + show users one thing while serialized is a different thing.

nikku avatar Feb 16 '22 11:02 nikku

We're currently investigating string templating in other places of our stack.

There mustache style {{ }} came up as a separator.

nikku avatar Aug 09 '22 09:08 nikku

We've discussed this issue along with a number of templating variations in this conversation, too.

nikku avatar Sep 26 '22 11:09 nikku

Native support for the feelers templating language would be great.

sbuettner avatar Nov 02 '23 09:11 sbuettner