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.popave...@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.rowling...@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.popave...@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 <
ggrothendi...@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@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel



         [[alternative HTML version deleted]]

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel


        [[alternative HTML version deleted]]

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to