I’d like to point out that this proposal (string interpolation) is also discussed in the upstream PRs (Create eep-0062.md: String interpolation syntax by TD5 · Pull Request #45 · erlang/eep · GitHub and feature: String interpolation by TD5 · Pull Request #7343 · erlang/otp · GitHub).
Named parameters via a map to io:format/*
is also an interesting track.
A problem with them is the often additional level of indirection, where one might have to create map field names that just are in the way.
Suppose you want to create a string with the variables A
, B
, and C
.
~i"Lorem ipsum $A, $B, $C"
vs.
io_lib:format("Lorem ipsum ~p[a], ~p[b], ~p[c]", #{a => A, b => B, c => C})
I created this topic to get some attention to the question about EEP 62 wanting to make the Erlang tokenizer recursive / modal.
It seems the answer to that points towards - that is not a good idea since there must be better and solutions less violent to the Erlang language, for the original problem of string interpolation.
So I will try to close this topic, and the discussion about string interpolation can continue where it started. See @mikpe’ post right above this.
It basically has to parse the interpolation when scanning so it can do the right thing with it. So you end up with string → expression → string → expression … in the scanner as @nzok pointed out earlier.
I am definitely a KISS person so having this type of handling is definitely against all my beliefs.
Actually I am a KICASS person, Keep It Consistent And Simple, Stupid.
This feature definitely breaks one rule we tried to keep and that is that constructors and patterns for the same datatype should look the same which this featuer clearly breaks,
What does “a #{if “#{2}” == “3” then 1 else 2 end} c”
mean as a pattern?
Recursive string interpolation sure messes this up.
But, since strings are syntactical sugar for lists:
1> "ab\d".
[97,98,127]
there are multiple ways to get the same value. And yes, "ab\d"
is a value that is also a pattern.
So it would not be so hard to get away with ~"ab\d"
as syntactical sugar for <<"ab\d"/utf8>>
.
However, that ~i"ab${D/foo}"
would be syntactical sugar for ["ab", foo(D)]
, I can see is a bit ugly. It is an I/O list expression, not a pattern.
If we remove the possibility for a stringifying function, then it can be a pattern, but awkward, and all interpolated variables would have to contain string or binary values. Or not. That depends on if you need to print the value or if you are happy with a mixed list of strings and values.