Open wurli opened 9 months ago
I love julia
's string literals!
I have a couple thoughts on the exact implementation, but I think supporting something like this would be really nice as a general concept.
I have mixed feelings about R's reliance on meaningful syntax in function names (fn<-
, %fn%
, fn.class
, and now fn"
). Julia uses this too with its fn_str
convention, but gets away from the .class
syntax with its dispatch system. An alternative would be to have a generic similar to infix operators.
I've often felt it would be nice to incorporate a juxtapose
generic. When two parsed nodes are butted up against eachother, it would be equivalent to a juxtapose
call, i.e. g"string"
gets parsed as juxtapose(g, "string")
, which then could repurpose the dispatch system to handle this case, and many more!
Then (using R's S3 dispatch style for the sake of example), to implement this we might do:
class(glue::glue) <- c("glue_fmt_function", "function")
g <- glue::glue
juxtapose.glue_fmt_function <- function(e1, e2) {
e1(e2)
}
Or to move entirely away from meaningful syntax in function names dispatch might be articulated more like it is in Julia with typed parameters:
juxtapose <- function(e1: glue_fmt_function, e2) {
e1(e2)
}
Just as a motivating example, allowing dispatch on this type of juxtapose
generic would allow use cases where users generate a formatter:
fmt <- my_code_style(whitespace = 3L, always_backtick_names = TRUE)
fmt"a + b"
# [1] `a` + `b`
This is a silly example with a silly code style, but you can imagine situations when someone might have more reasonable settings for formatters. Perhaps things like json-prettyfication or error message formatting style.
The juxtapose
idea is nice - I also have mixed feelings about syntax in function names. I'm not sure if it could potentially cause any readability issues, e.g. code that changes function with the addition/omission of a single space. My gut feeling is that it would, but I can't think of any cases where that could happen, so maybe it would be okay. Maybe interference with infix operators could somehow be an issue?
I think maybe a good approach would be to decide sooner rather than later whether syntax in function names is something this project will keep. If it is kept, I think it should probably be used in favour of juxtapose
. But, I think it would be infinitely cooler to take the plunge and cook up an alternative, unified syntax for defining generics, infix operators, assignment operators etc. In this case, something like juxtapose
could be a really nice addition and should hopefully slot nicely into that system.
I share your concerns. Introducing meaningful whitespace is a language decision that shouldn't be taken lightly.
There's also an option for a middle ground. Maybe a totally generic juxtapose
function is a bit overkill, but we still want some format
generic that accepts a formatter and a string. Unlike juxtapose
, which might apply to any two juxtaposed syntax nodes, maybe something like format
would only be called internally when a name precedes a string literal.
This would still let us use dispatch to introduce new methods without the bespoke function declaration syntax while achieving a very similar behavior. Because the design stands to benefit so much from generics, I'd probably hold off on this until we have the generics/dispatch built up.
I do think something like this is tremendously valuable for any analytic language. glue
is a great example, but I especially like julia
's SQL and regex format strings.
One could define a function to operate on a single string like so:
This would basically give you something very similar to Python's f-strings:
Obviously, the {glue} package isn't available in this version of R, but you get the idea 😄
This idea comes from Julia, which lets you define non-standard string literals in the same way: https://docs.julialang.org/en/v1/manual/metaprogramming/#meta-non-standard-string-literals.