Calling a function in an interpolated string


#1

Why can’t I call a function in an interpolated string? For example,

let stringFunction = (input : string) => {j|$(input) is a string"|j};
let testString = {j|This is a test string calling a function $(stringFunction)|j};

This is fine because it just logs “function”. But if I try this

let testString = {j|This is a test string calling a function $(stringFunction("test"))|j};

Will trigger an Error: `stringFunction(’ is not a valid syntax of interpolated identifer.

Piping the argument causes the same problem. Why is this?


#2

Because the syntax of the Reason interpolated string is not the same as that of the JS interpolated string?

I think if you do want the flexibility of JS string templates, you can wrap an actual string template in a %raw directive, like this: https://github.com/persianturtle/reason-app-shell-starter-kit/blob/master/src/Index.re#L7

Or you might use the good old string concatenation:

let testString = "This is a test string calling a function " ++ stringFunction("test");

I think string templates are most valuable when they are actually used as templates, for css-in-js and suchlike, when there’s a lot of string, a few parameters and probably some custom processing. For simple cases, interpolation is sometimes slightly more readable than concatenation, and sometimes slightly less.


#3

BuckleScript’s interpolation supports only variables, not arbitrary expressions (like functions).


#4

Do either of you know if it’s a fundamental reason or just a characteristic of the implementation. I ask because it seems like it should just the evaluation of a block.


#5

The interpolation happens at compile time so it can’t evaluate arbitrary expressions.


#6

So if we want anything complicated, like CSS-in-JS or GQL queries, it has to be done via PPX?


#7

Not sure I understand, there are currently Reason PPXs that do both of these (i.e. they do some specific jobs).


#8

I mean, in JS, writing custom tags for tagged templates is relatively simple: a tag is just a function that receives n values (interpolations) and n+1 strings. In Reason, to write a PPX, you have to know about OCaml ASTs, which looks way scarier (not that I tried).

Then again, there doesn’t seem to be a shortage of very strong programmers in the Reason community, so maybe we won’t have a shortage of useful PPXes :slight_smile:


#9

Typically the recommendation is that PPXs are a ‘last resort’, try everything else before you try them. For example, we already have powerful string interpolation available in OCaml/Reason, from the Printf module. It’s worth a look.


#10

Hey, I didn’t know about Prinf, thanks!