[Rd] [External] Re: capture "->"
Duncan Murdoch
murdoch@dunc@n @end|ng |rom gm@||@com
Mon Mar 4 18:15:12 CET 2024
That's a good suggestion, but if the function accepts strings, the
problem is fairly easy using the parser. E.g. compare
> getParseData( parse(text="x1 + x2 -> a3") )
line1 col1 line2 col2 id parent token terminal text
11 1 1 1 13 11 0 expr FALSE
7 1 1 1 7 7 11 expr FALSE
1 1 1 1 2 1 3 SYMBOL TRUE x1
3 1 1 1 2 3 7 expr FALSE
2 1 4 1 4 2 7 '+' TRUE +
4 1 6 1 7 4 6 SYMBOL TRUE x2
6 1 6 1 7 6 7 expr FALSE
5 1 9 1 10 5 11 RIGHT_ASSIGN TRUE ->
8 1 12 1 13 8 10 SYMBOL TRUE a3
10 1 12 1 13 10 11 expr FALSE
> getParseData( parse(text="a3 <- x1 + x2") )
line1 col1 line2 col2 id parent token terminal text
11 1 1 1 13 11 0 expr FALSE
1 1 1 1 2 1 3 SYMBOL TRUE a3
3 1 1 1 2 3 11 expr FALSE
2 1 4 1 5 2 11 LEFT_ASSIGN TRUE <-
10 1 7 1 13 10 11 expr FALSE
4 1 7 1 8 4 6 SYMBOL TRUE x1
6 1 7 1 8 6 10 expr FALSE
5 1 10 1 10 5 10 '+' TRUE +
7 1 12 1 13 7 9 SYMBOL TRUE x2
9 1 12 1 13 9 10 expr FALSE
The expressions produced are the same, but the parse data is different.
Duncan Murdoch
On 04/03/2024 11:51 a.m., Bill Dunlap wrote:
> Maybe someone has already suggested this, but if your functions accepted
> strings you could use sub or gsub to replace the -> with a symbol that
> parsed at the same precedence as <-,
> say <<-. Then parse it and deal with it. When it is time to display the
> parsed and perhaps manipulated formulae to the user, deparse it and do the
> reverse replacement.
>
>> encode <- function(string)gsub(perl=TRUE, "->", "<<-", x=string)
>> decode <- function(string)gsub(perl=TRUE, "<<-", "->", x=string)
>> rightArrow <- as.name("<<-")
>> leftArrow <- as.name("<-")
>> ast1 <- parse(text=encode("x1 + x2 -> a3"))[[1]]
>> ast2 <- parse(text=encode("y4 <- b5 + (b6 / b7)"))[[1]]
>> identical(ast1[[1]], rightArrow)
> [1] TRUE
>> identical(ast2[[1]], leftArrow)
> [1] TRUE
>> ast1[[3]] <- as.name("new_a3")
>> decode(deparse(ast1))
> [1] "x1 + x2 -> new_a3"
>
> -Bill
>
> On Mon, Mar 4, 2024 at 1:59 AM Dmitri Popavenko <dmitri.popavenko using gmail.com>
> wrote:
>
>> Dear Barry,
>>
>> In general, I believe users are already accustomed with the classical
>> arrows "->" and "<-" which are used as such in quoted expressions.
>> But I agree that "-.>" is a very neat trick, thanks a lot. A small dot,
>> what a difference.
>>
>> All the best,
>> Dmitri
>>
>> On Mon, Mar 4, 2024 at 11:40 AM Barry Rowlingson <
>> b.rowlingson using lancaster.ac.uk> wrote:
>>
>>> It seems like you want to use -> and <- as arrows with different meanings
>>> to "A gets the value of B" in your package, as a means of writing
>>> expressions in your package language.
>>>
>>> Another possibility would be to use different symbols instead of the
>>> problematic -> and <-, for example you could use <.~ and ~.> which are
>> not
>>> at all flipped or changed before you get a chance to parse your
>> expression.
>>> It might make your language parser a bit trickier though. Let's see how
>>> these things turn into R's AST using `lobstr`:
>>>
>>> > library(lobstr)
>>> > ast(A ~.> B)
>>> █─`~`
>>> ├─A
>>> └─█─`>`
>>> ├─.
>>> └─B
>>> > ast(A <.~ B)
>>> █─`~`
>>> ├─█─`<`
>>> │ ├─A
>>> │ └─.
>>> └─B
>>>
>>> You'd have to unpick that tree to figure out you've got A and B on either
>>> side of your expression, and that the direction of the expression is L-R
>> or
>>> R-L.
>>>
>>> You could also use -.> and <.- symbols, leading to a different tree
>>>
>>> > ast(A -.> B)
>>> █─`>`
>>> ├─█─`-`
>>> │ ├─A
>>> │ └─.
>>> └─B
>>> > ast(A <.- B)
>>> █─`<`
>>> ├─A
>>> └─█─`-`
>>> ├─.
>>> └─B
>>>
>>> Without knowing the complexity of your language expressions (especially
>> if
>>> it allows dots and minus signs with special meanings) I'm not sure if A)
>>> this will work or B) this will bend your brain in horrible directions in
>>> order to make it work... Although you don't need to parse the AST as
>> above,
>>> you can always deparse to get the text version of it:
>>>
>>> > textex = function(x){deparse(substitute(x))}
>>> > textex(A <.~ B)
>>> [1] "A < . ~ B"
>>>
>>> The <.~ form has an advantage over the <.- form if you want to do complex
>>> expressions with more than one arrow, since the ~ form is syntactically
>>> correct but the - form isnt:
>>>
>>> > textex(A <.~ B ~.> C)
>>> [1] "A < . ~ B ~ . > C"
>>> > textex(A <.- B -.> C)
>>> Error: unexpected '>' in "textex(A <.- B -.>"
>>>
>>>
>>> Barry
>>>
>>>
>>> On Sun, Mar 3, 2024 at 12:25 PM Dmitri Popavenko <
>>> dmitri.popavenko using gmail.com> wrote:
>>>
>>>> This email originated outside the University. Check before clicking
>> links
>>>> or attachments.
>>>>
>>>> On Sat, Mar 2, 2024 at 7:58 PM Gabor Grothendieck <
>>>> ggrothendieck using gmail.com>
>>>> wrote:
>>>>
>>>>> Would it be good enough to pass it as a formula? Using your
>> definition
>>>> of
>>>>> foo
>>>>>
>>>>> foo(~ A -> result)
>>>>> ## result <- ~A
>>>>>
>>>>> foo(~ result <- A)
>>>>> ## ~result <- A
>>>>>
>>>>
>>>> Yes, to pass as a formula would be the idea.
>>>> It's just that the parser inverses "~A -> result" into "result <- ~A".
>>>> We are seeking for any way possible to flag this inversion.
>>>>
>>>> Avi, thank you for your efforts too. Wrapping symbols into percent signs
>>>> is
>>>> an option, but as Duncan says it is much more intuitive to just quote
>> the
>>>> expression.
>>>> The challenge is to somehow flag the parser inversion, otherwise a
>> quoted
>>>> expression seems to be the only solution possible.
>>>>
>>>> Regards,
>>>> Dmitri
>>>>
>>>> [[alternative HTML version deleted]]
>>>>
>>>> ______________________________________________
>>>> R-devel using r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>
>>>
>>
>> [[alternative HTML version deleted]]
>>
>> ______________________________________________
>> R-devel using r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list