Thank you. I knew it had nothing to do with the choice of environment, but I 
thought I had seen such unwrapped code working in files in a previous version. 
Maybe I misremembered. Incidentally, there is nothing special about braces: 
anything that makes the statement incomplete will do.

Regards,
Jorgen.


> evalq( if (FALSE)

  cat("This shouldn't happen.\n")

else

  cat("Everything is fine.\n"),

+ .GlobalEnv

+ )

Everything is fine.

> x <- 1:5

> x[ if(FALSE) 1L

+    else 2L

+  ]

[1] 2


From: Andrew Simmons <akwsi...@gmail.com>
Date: Friday, 21October, 2022 at 11:20
To: Jorgen Harmse <jhar...@roku.com>
Cc: r-help@r-project.org <r-help@r-project.org>
Subject: [EXTERNAL] Re: [R] unexpected 'else' in " else"
The code working inside stats::weighted.residuals has nothing to do
with being evaluated in a different environment than globalenv() and
has nothing to do with being inside a package.
The reason the code works inside stats::weighted.residuals is because
the function body is wrapped with braces. You can try it yourself:

local({
    FILE <- tempfile(fileext = ".R")
    on.exit(unlink(FILE, force = TRUE, expand = FALSE), add = TRUE,
after = FALSE)
    writeLines("if (TRUE) \n    'evaluating cons.expr'\nelse
'evaluating alt.expr'", FILE)
    writeLines(readLines(FILE))
    try(source(FILE, local = TRUE, echo = TRUE, verbose = FALSE))
})

If you try entering it as a function, it still fails:

local({
    FILE <- tempfile(fileext = ".R")
    on.exit(unlink(FILE, force = TRUE, expand = FALSE), add = TRUE,
after = FALSE)
    writeLines("function () \nif (TRUE) \n    'evaluating
cons.expr'\nelse 'evaluating alt.expr'", FILE)
    writeLines(readLines(FILE))
    try(source(FILE, local = TRUE, echo = TRUE, verbose = FALSE))
})

But R packages use sys.source() instead of source() to run R code, but
it still fails if you run it:

local({
    FILE <- tempfile(fileext = ".R")
    on.exit(unlink(FILE, force = TRUE, expand = FALSE), add = TRUE,
after = FALSE)
    writeLines("if (TRUE) \n    'evaluating cons.expr'\nelse
'evaluating alt.expr'", FILE)
    writeLines(readLines(FILE))
    try(sys.source(FILE, envir = environment()))
})

The part that matters is that the function body is wrapped with
braces. `if` statements inside braces or parenthesis (or possibly
brackets) will continue looking for `else` even after `cons.expr` and
a newline has been fully parsed, but will not otherwise.

On Fri, Oct 21, 2022 at 10:39 AM Jorgen Harmse via R-help
<r-help@r-project.org> wrote:
>
> Andrew Simmons is correct but doesn't explain why the code works in the 
> package. This is one of only two differences I have found between running 
> code at the command line and running it from a file. (The other difference is 
> that code in a file is often executed in an environment other than 
> .GlobalEnv. There is some related sugar around packages that usually makes 
> things work the way a user would want.) At the command line, R executes code 
> whenever RETURN could be interpreted as the end of a statement. "If(�.) �. 
> RETURN" is ambiguous: will it be followed by "else", or is it a complete 
> statement? If it's in a file or wrapped in a block or other structure that 
> obviously hasn't ended yet then R will wait to see the next line of input, 
> but if it could be a complete statement then not executing it would cause a 
> lot of frustration for users. Once the statement is executed, R expects 
> another statement, and no statement begins with "else". (Maybe the 
> interpreter could be enhanced to keep the "if" open under some conditions, 
> but I haven't thought it through. In particular, "if" without "else" is NULL 
> if the condition is FALSE, so it might be necessary to undo an assignment, 
> and that seems very difficult.)
>
> Regards,
> Jorgen Harmse.
>
>
> On Fri., Oct. 21, 2022, 05:29 Jinsong Zhao, <jsz...@yeah.net> wrote:
>
> > Hi there,
> >
> > The following code would cause R error:
> >
> >  > w <- 1:5
> >  > r <- 1:5
> >  >         if (is.matrix(r))
> > +             r[w != 0, , drop = FALSE]
> >  >         else r[w != 0]
> > Error: unexpected 'else' in "        else"
> >
> > However, the code:
> >          if (is.matrix(r))
> >              r[w != 0, , drop = FALSE]
> >          else r[w != 0]
> > is extracted from stats::weighted.residuals.
> >
> > My question is why the code in the function does not cause error?
> >
> > Best,
> > Jinsong
> >
> > ______________________________________________
> > R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
> > https://stat.ethz.ch/mailman/listinfo/r-help
> > PLEASE do read the posting guide
> > http://www.R-project.org/posting-guide.html
> > and provide commented, minimal, self-contained, reproducible code.
> >
>
>         [[alternative HTML version deleted]]
>
>
>
>
> ------------------------------
>
> Subject: Digest Footer
>
> _______________________________________________
> R-help@r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
>
> ------------------------------
>
> End of R-help Digest, Vol 236, Issue 19
> ***************************************
>
>         [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.

        [[alternative HTML version deleted]]

______________________________________________
R-help@r-project.org mailing list -- To UNSUBSCRIBE and more, see
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
and provide commented, minimal, self-contained, reproducible code.

Reply via email to