Open AndreMikulec opened 7 years ago
For example, output resulting from the use of magritter and R.rsp is the following.
> library(R.rsp)
R.rsp v0.40.0 (2016-12-05) successfully loaded. See ?R.rsp for help.
Attaching package: 'R.rsp'
The following objects are masked from 'package:base':
parse, write
> library(magrittr)
> rstring('<% rnorm(5) %>% print %>')
[1] "% print %>"
The result is not correct.
In contrast, output resulting from the use of magritter alone is the following.
> library(magrittr)
> rnorm(5) %>% print
[1] -0.5036753 -2.3572792 0.9902699 0.1383998 0.8297871
The result is correct.
> sessionInfo()
R version 3.3.2 (2016-10-31)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 10 x64 (build 10586)
locale:
[1] LC_COLLATE=English_United States.1252
[2] LC_CTYPE=English_United States.1252
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] R.oo_1.21.0 R.methodsS3_1.7.1 magrittr_1.5 R.rsp_0.40.0
loaded via a namespace (and not attached):
[1] tools_3.3.2 digest_0.6.11 R.cache_0.12.0 R.utils_2.5.0
Thanks for this and sorry for the radio silence. I meant to reply to this but it kept slipping away.
Although it's a critical limitation, I don't have a quick fix for this, but please see my thoughts below.
I am aware of this problem and it's been a long-term goal to workaround it for quite a while. Basically, the main problem is that RSP uses tag %>
that can also be the start of an R infix operator, e.g. %>%
but also %>yada yada yada%
. For example,
> `%>yada yada yada%` <- function(lhs, rhs) list(lhs = lhs, rhs = rhs)
> 123 %>yada yada yada% 456
$lhs
[1] 123
$rhs
[1] 456
The quick workaround for a user can often be (as you suggest) to "rename" the conflicting infix operator. However, this does not work with operators that use non-standard evaluation (NSE) such as magrittr::`%>%`
.
In short, in order to solve this, the RSP parser has to resolve these conflicts / ambiguities. Here are some idea I have had for allowing %>%
inside RSP constructs such as
Hello <% cat("world") %>! Here are the data:
<% data %>% print %>
%
after an RSP closing tag %>
.One could restrict the RSP syntax such that %
is not allowed immediately after an RSP construct. This would prevent RSP parse parse %>%
as %>
+ "%"
, which it does now. Instead, this would always be parsed as the R infix operator %>%
. The problem is, it might be that someone wants to do "Inflation was <%= 52 %>% last year"
. As workaround on top of this workaround, one could imagine "Inflation was <%= 52 %[]>% last year"
where []
is an ending RSP option (currently not supported).
It feels like approach is rather ad hoc and will only target %>%
crossing the fingers that the risk for other infix %> ... %
operators to appear is small. More over, RSP was actually written to work in "any" language, not just R, meaning this fix would be a fix just for R.
In addition to current <% ... %>
syntax, one could support <%%% ... %%%>
to mean the same thing. This would
Hello <% cat("world") %>! Here are the data:
<%%% data %>% print %%%>
I think this would be non-ambigous because %%%>%
is not valid syntax in R.
However, ... unfortunately, <%% ... %%>
is already used to escape RSP constructs, which causes <%%% ... %%%>
to be interpreted the same way;
> rcat("A random integer in [1,100]: <%%%=sample(1:100, size=1)%%%>\n")
A random integer in [1,100]: <%%=sample(1:100, size=1)%%>
This calls for an alternative "alternative" RSP construct. Maybe <%! ... !%>
, e.g.
Hello <% cat("world") %>! Here are the data:
<%! data %>% print !%>
Another rule could be that any symbol following <%
can be used and if it that same symbol exists just before %>
that defines the RSP construct. Not sure what complexity this would add to the RSP parser.
<% ... %>
to a "safer" syntaxFor a user using lots of magrittr pipes, their RSP code would contain lots of <%! ... !%>
which becomes quite meaty. They original problem is the use of %
. An alternative would be to use another symbol that %
in <% ... %>
. There are many options:
<* ... *>
<$ ... $>
<: ... :>
<^ ... ^>
<& ... &>
<| ... |>
<[ ... ]>
</ ... />
<! ... !>
- clashes with valid R syntax, e.g. 0 <! 0
<( ... )>
- clashes with valid R syntax, e.g. 0 <(0)
and (0)>0
<{ ... }>
- clashes with valid R syntax, e.g. 0 <{0}
and {0}>0
Yet further alternatives are:
{{ ... }}
- clashes with valid R syntax, e.g. {{ 0 }}
However, there are plenty of "macro" languages out there that already uses that construct, so that would be confusing.
So, as you see, there are multiple paths here of which some a fairly "quick" and others requires bigger commitments. I simply have to think more about this, but the most likely "fix" is that I add support for something like <%! ... !%>
.
Always happy for suggestions.
Thanks. Andre Mikulec
The GetoptLong package provides an argument code.pattern = qq.options("code.pattern")
for its qq()
function, which is set to "@\\{CODE\\)"
by default. Perhaps a similar argument could be provided for RSP functions, such as pattern = GetOption("R.rsp.pattern")
with default "<% ... %>"
. The <%! ... !%>
syntax could be documented as a magrittr-friendly alternative.
How would I write/escape the R magrittr function
%>%
( if possible ) inside R.rsp?For example
Note: I can not alias i.e. :
The way magrittr is written, Funct would not work.