The README file on GitHub mentions that StaticStrings.jl uses string macros of the form static"Hello world!"12 which take more than one parameter. I didn’t know that this is possible. Is this described anywhere in the Julia documentation? If not, what exactly are the rules?
See the section just above Generated Functions:
Another way to define a macro would be like this:
macro foo_str(str, flag)
# do stuff
end
This macro can then be called with the following syntax:
foo"str"flag
The type of flag in the above mentioned syntax would be a String with contents of whatever trails after the string literal.
It’s not documented super clearly in the manual at the moment, it seems — this should really be fixed.
The way it works is that any suffix after the string is parsed as a second argument to the string macro:
julia> macro foo_str(str, suffix="default")
@show str
@show suffix
str
end
@foo_str (macro with 2 methods)
julia> foo"string"
str = "string"
suffix = "default"
"string"
julia> foo"string"xyz
str = "string"
suffix = "xyz"
"string"
I’m not 100% sure what the rules are for parsing the suffix. It looks like most things get parsed as a string, but numbers get parsed as numbers:
julia> foo"string"1
str = "string"
suffix = 1
"string"
julia> foo"string"1.
str = "string"
suffix = 1.0
"string"
Thanks to both you!
I think it would help to use the word “string macro” in addition to “string literal” when discussing this in the documentation. The concept is referred to as “string macro” in several places in the documentation, but not where they are explained. So a full-text search doesn’t help.
So can we expect your PR, @matthias314? ![]()
I think making the wording consistent in the documentation and possibly add some more linking between the places would be a welcomed contribution. It sounds like you just got already kind of an overview.
I can make a PR to add the “string macro” terminology, but I wouldn’t say that I have an overview. I don’t know more about the parsing of the suffix than what @stevengj said. It could be that numbers (including Bool) are parsed as such (contradicting the docs) and everything else as a string. The end of the string seems to be the next space/newline character or an operator or maybe even something else.
That is probably the second step. Making it more likely to find what is already there (i.e. consistent wording + potentially links) would already be a good first step.
I was not referring to that second step and the truth is probably in the source. But as an aside, what I like to do in cases like this, is to (mis)use Expr to answer what Julia does:
julia> :(abc"def"1.2) |> dumpstrip
Expr
head: Symbol macrocall
args: Array{Any}((3,))
1: Symbol @abc_str
2: String "def"
3: Float64 1.2
julia> :(abc"def"123ghi) |> dumpstrip
Expr
head: Symbol call
args: Array{Any}((3,))
1: Symbol *
2: Expr
head: Symbol macrocall
args: Array{Any}((3,))
1: Symbol @abc_str
2: String "def"
3: Int64 123
3: Symbol ghi
julia> :(abc"def"ghi123) |> dumpstrip
Expr
head: Symbol macrocall
args: Array{Any}((3,))
1: Symbol @abc_str
2: String "def"
3: String "ghi123"
That’s also a quick way when you see an expression and wonder how the operator precedence plays out. You can use dump if you do not have a suitable dumpstrip in your startup which removes the LineNumberNodes (removing them like here is only suitable for dumping).
As said in the PR, it would be good if somebody who knows the internals could check the claim about the parsing of the trailing parameter.