Closed bates64 closed 7 years ago
I agree, string interpolation is a nice feature that fits very well in Gravity. We need to find out a smart syntax, Swift for example supports a syntax like:
var name = "Jason"
println("Hello, \(name)!")
//prints "Hello, Jason!"
Gravity could use the @ character:
var name = "Jason"
System.print("Hello, @(name)!")
//prints "Hello, Jason!"
I like #()
syntax. \()
seems like (
backslash-escape...
I'm adamant on "normal" strings (quotes, double quotes) being just that - normal. Backtick/triple-quote strings should be the only kinds of strings that support a) direct newlines and b) interpolation:
// syntax error (newlines)
System.print("roses are red
violets are blue")
// correct, also allows interpolation
var flower = "roses"
System.print(`@(flower) are red
violets are blue`)
Which syntax should we use for string interpolation in Gravity?
@()
System.print("Hello, @(name)!")
#()
System.print("Hello, #(name)!")
\()
System.print("Hello, \(name)!")
%()
System.print("Hello, %(name)!")
from that selection, I think I prefer @()
(probably the easiest character for me to type)
The $
sign also seems to be used a fair amount in other languages, so that might also be familiar. I've seen syntaxes such as $name
, ${name}
etc.
For example, bash, Dart, Groovy, JS, Perl, PHP, and Scala all use some form of the $
sign.
If we are going for uniqueness, the @
is probably the one. The only language I know of that uses this is Perl, but used for arrays only.
The $ sign also seems to be used a fair amount in other languages, so that might also be familiar. I've seen syntaxes such as $name, ${name} etc.
I would prefer ${name} for this reason, unneeded uniqueness is not a good thing...
I agree with @parro-it that unneeded uniqueness is not a good thing and perhaps it is just a personal preference, but the ${}
notation seems so old school to me...
I like ${name}
and %{name}
. Personally I prefer the dollar sign, but both are nice to me.
I think the @
works best, but I would prefer to use @{name}
instead of @(name)
. I feel like curly braces stand out more than parenthesis but this is probably just a personal preference. Plus with most programs using a @
to reference other people (Like Github and Slack) I think it makes sense and is easier to remember.
if we need brackets at all, I too would prefer the curly braces.
I vote for @(name)
or @{name}
I liked ruby's #{name}
.
@
reminds me of instance variables.
We also need to figure out what activates the string interpolation. i.e. ' vs `
@(var)
I think curly braces are the way to go, they stand out a lot more. I think familiarity is also going to be a bonus for people learning it. So, I'd suggest ${value}.
For activation, I think it should just be default.
I don't think it's really necessary for it to be explicit, as the pattern itself makes it identifiable.
If you're saying that for concern out of lexer performance, I don't think it's too much of a performance hit, as it still needs to read the string, and make sure it hits the end, so checking for other characters, via a switch, or something won't contribute any conceivable downside.
An alternative approach would be the one adopted by C# where string interpolation is even more condensed. For example:
func fullname (firstname, lastname) {
return $"Your full name is {firstname} {lastname}."
}
So when you use the special character $ (or @) in front of the entire string then everything inside curly braces is interpolated. If you need to use real curly braces then they must be escaped.
I would be open to this. Maybe even a more condensed version where the $ and @ are not needed at all?
func fullname (firstname, lastname) {
return "Your full name is {firstname} {lastname}."
}
My reasoning for using a character at the start of the interpolation target is two-fold. (The interpolation target being "${this}") Firstly, familiarity. Most programming languages, standard libraries, and even some common libraries (such as logging frameworks, etc), use this or a very similar pattern, which means people aren't going to have to learn a different set of interpolation rules. In my head, that's a plus, as the less work an adopter has to do to use and understand gravity, the better.
Secondly, recognisability. While reading a string, it's going to be much easier to spot the start of an interpolation target, then it would be otherwise. If we remove the starting character/sequence, it's going to be much more context sensitive, if the string should be an interpolation target, or if it actually just contains braces. This means that those braces need to be escaped so gravity knows if it's an interpolation target or not. You could use variability scope, and if there's no variable with that name within that scope, just assume it's not a target, but then you have the problem of the language doing some pretty sneaky stuff behind the scenes that isn't immediately apparent. Also, you might run into a problem of people removing variables, and gravity not being able to tell them that something is wrong. If we have an explicit target for interpolation, we can, at the very least, emit warnings for it. So that comes down to explicitness. It's better for the programmer to be explicit in what is desired, rather than hoping the compiler finds no problem with it.
In response to the C# method:
I don't think brevity is something we should be concerned about, considering the sequence itself is quite small.
If it's easier to scan a string and immediately locate the targets that's a plus, but at the same time, readability isn't the only thing.
Writeablity is also a concern.
The programmer shouldn't get annoyed at having to escape every {
or }
within a string just because they use the interpolation system.
If I output a string that's heavy on braces (Such as another programming language), it's going to get annoying to escape each brace, even more so, because it will actually reduce readability in the end as well.
If it's annoying to write, it will, most likely, be annoying to read. If it's annoying to read, it might not have been annoying to write.
I think exactness, and descriptiveness is much more desired than saving a couple of characters.
I am working on string interpolation and in the meantime I added support for more escaped sequences inside Strings: \x for hex \u for 4 chars unicode and \U for 8 chars unicode.
For the interpolation syntax I decided to follow the Swift way, so \(). The String function used in the Vector sample code (in ReadMe.md) will the be rewritten as:
func String() {
return "[\(x),\(y),\(z)]"
}
I should be able to commit the new code within a couple of days.
String interpolation just added: https://github.com/marcobambini/gravity/commit/072006b0c061b3c0725e9011d02199a0acd16f1e
Both JavaScript and Ruby (and probably others) have a syntax similar to the following:
(note interpolation-ready strings use backticks not quotes) This'd be a really neat feature to have in Gravity.