grain-lang / grain

The Grain compiler toolchain and CLI. Home of the modern web staple. 🌾
https://grain-lang.org/
GNU Lesser General Public License v3.0
3.29k stars 115 forks source link

Lang: String interpolation #1853

Open alex-snezhko opened 1 year ago

alex-snezhko commented 1 year ago

Most high-level programming languages have a mechanism for interpolating data into strings as an alternative for manual concatenation to aid in readability, and it would seem to be a good fit for Grain as well. If such a feature were to be implemented, there are several questions to work out for the syntax and semantics:

spotandjake commented 1 year ago

Most high-level programming languages have a mechanism for interpolating data into strings as an alternative for manual concatenation to aid in readability, and it would seem to be a good fit for Grain as well. If such a feature were to be implemented, there are several questions to work out for the syntax and semantics:

  • What should be the pattern that indicates when something is interpolated? Common options from other languages include {val}, ${val}, $val, \(val). An advantage of the \ prefix over others is that it would be less likely for someone to accidentally add an interpolation when they really just wanted a dollar sign or brackets, etc.
  • Should interpolation work on normal strings or would a different quote character/prefix be required?
  • Should interpolation be strongly typed? To me allowing only strings seems like a sensible option, and likely wouldn't require a breaking change if a more lenient system becomes desired in the future. Using a printf sort of scheme where different types are notated differently is also an option, though that wouldn't scale well for complex types
  • Should arbitrary expressions be allowed or only variable names? An argument against arbitrary expressions is that you can get weirdness with strings inside of the interpolation string i.e. "Hello {if (world) "world" else "there"}"

I think that there was a plan to use macros for this. but if we do not go through with that I would prefer we take an approach like js with different qoutes. and ${} syntax inside. or alternatively f strings like in python. I think the argument about accidentally doing string interpolation isn't that important given it is opt in on a certain type of string rather than on regular strings.

I feel we shouldn't allow arbitrary expressions for the single reason of keeping code tidy though there are defiantly arguments to this, that are valid.

as per string being strongly types rather then implicitly converting them. I think strongly typed makes more sense because its so easy to stringify elements in grain using toString it makes things a lot more explicit and scales better.

alex-snezhko commented 1 year ago

I think that there was a plan to use macros for this

This seems like a common enough feature to just include direct support for imo

I think if we use a prefix/different quote then an f prefix would make more sense than ` since there is already precedent of prefixed strings with byte literals b"abc". My original argument for \() was more so in the case of interpolation into normal (non-prefixed) strings, and I agree that if you have to opt-in to this functionality it is less likely. In this case I think I personally like just {} like Python because of its terseness

spotandjake commented 1 year ago

I prefer c Sharps $"Position: {position} syntax. But I do like in javascript how you have todo ${} the ${ feels far more intentional similar to your \( to me, not that escaping is overly necessary but still. The minimalism of {} is for sure a plus though.

I think you make an extremely good point about using a prefix over tilde, though. I think before workshopping the syntax too much though it the behaviour of type safety and more importantly if the rest of the team wants this / sees this as a language feature needs to be decided.

alex-snezhko commented 1 year ago

I think in JS the ${ makes more sense because `-strings serve several roles in addition to interpolation, but I think the "intentionality" is already covered when you put the prefix in the string. I also like C#'s $"" syntax, but afaik all of the string prefixes in C# are non-characters and since we already have b"" I like the idea of using letters for consistency's sake. Another thing to consider is that the f prefix in Python stands for "format" which in my mind evokes functionality like being able to give special format specifications i.e. f"Money left: {money:.2f}" so perhaps a different letter would be a better fit :thinking:

spotandjake commented 1 year ago

I think in JS the ${ makes more sense because `-strings serve several roles in addition to interpolation, but I think the "intentionality" is already covered when you put the prefix in the string. I also like C#'s $"" syntax, but afaik all of the string prefixes in C# are non-characters and since we already have b"" I like the idea of using letters for consistency's sake. Another thing to consider is that the f prefix in Python stands for "format" which in my mind evokes functionality like being able to give special format specifications i.e. f"Money left: {money:.2f}" so perhaps a different letter would be a better fit 🤔

yeah, I think that given we only have b so far we haven't confined ourselves to letters just yet over symbol.

I also don't really know a better letter than f to be fair.

I agree with the reasoning as to why it exists in js which is why I noted I don't think that it's necessary, I do in c# and python though accidentally add extra $s lol to my string all the time by accident.

Also I don't know if b"" is quite the same realm as string interpolation when you think about it b"" is really a bytes literal not a string. I see the pattern and agree that it's worth considering I just don't know if we should completely base syntax off it.

alex-snezhko commented 1 year ago

we haven't confined ourselves to letters just yet over symbol.

Fair enough; I'm also struggling to think of a better character; Scala has s but it's not clear to me why they chose that. I do think $ also looks nice and is somewhat clearer since dollar signs typically allude to variables

spotandjake commented 1 year ago

we haven't confined ourselves to letters just yet over symbol.

Fair enough; I'm also struggling to think of a better character; Scala has s but it's not clear to me why they chose that. I do think $ also looks nice and is somewhat clearer since dollar signs typically allude to variables

my thoughts exactly, I think the only sensible options were f and $.

KAVA-Leigh commented 1 year ago

Random bystander comment, but either the same or similar to JS is the friendliest & most sane approach of interpolation IMO. i.e. hello ${w}.