The difference is whether you want to have \n converted into a newline by Julia and sent to the program (my solution: use $"...") or if you want to send \ and n to the program and have the program convert the backslash escape to a newline itself (your solution: use echo -e).
The problem with the latter echo -e solution is that it only works for echo — if you want to pass a newline to most programs, they won’t have any option to interpret backslash escapes themselves and you must form the newline character on the Julia side.
Fair enough. However, I have to admit that I have never ever needed to pass a string to a Linux command that was meant to have a newline inside and not represented by \n. If the situation arose, I would have just did command "`echo -e "a\nb"`" in the terminal (which works as it can be confirmed by replacing command by echo without the -e).
Is this documented? Running External Programs · The Julia Language has a whole section on interpolation with variables but I can’t find anything about interpolating with a string literal…
The shortest complete expression after the $ is taken as the expression whose value is to be interpolated into the string.
So it’s reasonable to conclude that "\n" is the expression to be interpolated here. But in practice it doesn’t work (outside of ` `). And "xxx $3 xxx" also doesn’t work, while "xxx $(3) xxx" does. So AFAICS the documentation is misleading, and the syntax `echo $"hello\nworld"` is undocumented…
Changing the documentation can be done very easily, PR’s can be done with a mouse click. No need to fork the repo!
I think, this interpolation thing in the context of backticks and Cmd would suit well in the corresponding docs.
I just always use $(...) when doing interpolation in Julia, for the same reason why I always use ${...} when referencing a variable in the shell: I don’t have to deal with corner cases where omitting the parentheses would break.
$ interpolates the first Julia expression fragment it encounters — the first “lexical atom” (symbol or literal value) if there are no parens. You only need parentheses if you want to interpolate a compound expression involving multiple atoms.
For example, $1+2 does interpolation equivalent to $(1)+2, since 1 is the first parsed atom. So you need $(1+2) if you want to interpolate 3. Similarly, $sin(1) will interpolate $(sin)(1) since the symbol sin is the first parsed atom; you need $(sin(1)) to interpolate the whole function call.
A string literal "foo", on the other hand, is a single lexical “atom” — once the parser encounters ", there is no valid way to stop parsing until it reaches the closing ". So you don’t need parens to interpolate $"foo".
Clarifications to the documentation on interpolation would be welcome, of course.
so Julia’s behavior is not consistent with this idea (expressed in the documentation) that $ interpolates “the first Julia expression fragment it encounters”… Is it a bug in Julia or a mistake in the documentation?
I understand this is what the documentation says. But my expectation was rather based on empirical experience (not only with Julia but also with other languages/tools I have used for a long time). For example: all of the following 3 constructs should work under the stated rule, but actually produce syntax errors (at least in the case of string interpolation, which is by far the kind of interpolation I’m using the most):
This might very well be a bug, but I’m really fine with it and never noticed it before. Actually, the only thing I really expect from interpolation is a form of referential transparency that lets me have a mental model where:
var = something # a string or vector or number or any expression, really
"hello $var world"
produces the same result as
"hello $(something) world"
And I’m not bothered by the (possibly useless) parentheses, for the reasons mentioned by @giordano above: I got a long time ago into the habit of always putting brackets/parens/etc around interpolated expressions in shell scripts/Makefiles/etc
My only point is this: I understand the viewpoint where interpolation should really work on the following lexical atom. Under this interpretation, there are a few bugs with string interpolation, which would need fixing.
On the other hand, my point-of-view is that putting parentheses around interpolated expressions is a common practice (maybe even recommended for anything other than a plain variable name). Under this view, string interpolation is not really buggy nor surprising. But then the behavior of command interpolation seems a bit surprising when it correctly handles literals of many more types than string interpolation. Hence my proposal of advertising the use of $(...) in the documented examples of command interpolation even though parentheses are not strictly needed in this specific context.