att / rcloud

Collaborative data analysis and visualization
http://rcloud.social
MIT License
432 stars 142 forks source link

use of package swirl #1778

Open martymcwizard opened 8 years ago

martymcwizard commented 8 years ago

Is there a setting or option in RCloud that would enable the interactive package swirl?

http://swirlstats.com/

here is a naive attempt

http://rcloud.social/edit.html?notebook=e0d835879d1016f9b51a

seankross commented 8 years ago

Hi RCloud team,

I'm the maintainer of swirl and I would like to help get swirl working on RCloud. I did a little experiment and it looks like there might be an issue with how RCloud handles task callbacks. Run the following code in RCloud and on your own R console and observe the difference:

times <- function(total = 3, str = "Task a") {
  ctr <- 0

  function(expr, value, ok, visible) {
    ctr <<- ctr + 1
    cat(str, ctr, "\n")
    if(ctr == total) {
      cat("handler removing itself\n")
    }
    return(ctr < total)
  }
}

# add the callback that will work for
# 4 top-level tasks and then remove itself.
n <- addTaskCallback(times(4))

print("Hello")
print("Hello")
print("Hello")
print("Hello")

I copied this code straight form the help page of addTaskCallback().

gordonwoodhull commented 8 years ago

Thanks @seankross, I verified that the task callback is not added (or doesn't function) in RCloud.

On a quick search I find suggestions that Rserve doesn't implement/handle addTaskCallback:

http://r.789695.n4.nabble.com/automatically-calling-dev-off-td4711715.html

s-u commented 8 years ago

There are no top-level tasks in RCloud, so for the same reason this has no effect. Top level tasks only work when REPL is used, since it is an internal mechanism in R - so you would not expect (nor want) to call those in RCloud. Could you provide any context here? Task callbacks are often used as a horrible hack when the code doesn't actually use proper input handlers in R, but since I have no idea what it's used for in this context I can't say if you can simply register a cell callback (is that what you would want?) or whatever other purpose it serves.

s-u commented 8 years ago

Just as a context for those not familiar with the details: When R is used in REPL mode (Run/Evaluate/Print/Loop) it allows user code to inject arbitrary functions into the loop. Those callbacks are called in between the iterations of the loop. However, RCloud doesn't use REPL since that would require R to control the entire process and also would restrict it to purely serial "console" mode. Instead, RCloud uses a mode where R is always available for evaluations since you may want to run other things that are not part of the "console" (out-of-band cell executions, re-drawing plots, etc.) which mean that inherently the REPL mode makes no sense (we are also not sending raw "input" but evaluate cells instead).

Also cells are executed directly, so there is no separation of individual evaluations. Thus RCloud provides much more flexibility - the application is informed by OOB message on any asynchronous action and can act on many different callbacks. That said, we cannot easily create a compatibility mode to run R top level callbacks in addition to the native methods even if we wanted to have Rserve_eval to fire task callback, because R doesn't currently expose Rf_callToplevelHandlers as part of the API.

s-u commented 8 years ago

I have added a very, very hacky work-around to rcloud.social (see also Rserve/top-level-handlers. It's not perfect, because of several issues - many of them deep inside R (it turns out the R internal code that runs handlers uses the similar facility that we use for running RCloud cells which means we get into recursions which mess up things ...). I'd still prefer if we found an "official" way to get swirl to work directly...

martymcwizard commented 8 years ago

thanks Simon. I was able to work through a few prompts until I got to one that I believe calls omnitest. Here's the session log from rcloud.social, invoked with library(swirl) swirl()

| Welcome to swirl!

| Please sign in. If you've been here before, use the same name as you did | then. If you are new, call yourself something unique.

What shall I call you? mm6769

| Thanks, mm6769. Let's cover a few quick housekeeping items before we begin | our first lesson. First of all, you should know that when you see '...', that | means you should press Enter when you are done reading and ready to continue. ... <-- That's your cue to press Enter to continue

| Also, when you see 'ANSWER:', the R prompt (>), or when you are asked to | select from a list, that means it's your turn to enter a response, then press | Enter to continue.

Select 1, 2, or 3 and press Enter

1: Continue. 2: Proceed. 3: Let's get going!

Selection: 1

| You can exit swirl and return to the R prompt (>) at any time by pressing the | Esc key. If you are already at the prompt, type bye() to exit and save your | progress. When you exit properly, you'll see a short message letting you know | you've done so.

| When you are at the R prompt (>): | -- Typing skip() allows you to skip the current question. | -- Typing play() lets you experiment with R on your own; swirl will ignore | what you do... | -- UNTIL you type nxt() which will regain swirl's attention. | -- Typing bye() causes swirl to exit. Your progress will be saved. | -- Typing main() returns you to swirl's main menu. | -- Typing info() displays these options again.

| Let's get started! ...

| Please choose a course, or type 0 to exit swirl.

1: R Programming 2: Take me to the swirl course repository!

Selection: 1

| Please choose a lesson, or type 0 to return to course menu.

1: Basic Building Blocks 2: Workspace and Files
3: Sequences of Numbers 4: Vectors
5: Missing Values 6: Subsetting Vectors
7: Matrices and Data Frames 8: Logic
9: Functions 10: lapply and sapply
11: vapply and tapply 12: Looking at Data
13: Simulation 14: Dates and Times
15: Base Graphics

Selection: 1

|
| | 0%

| In this lesson, we will explore some basic building blocks of the R | programming language.

...

|
|== | 3%

| If at any point you'd like more information on a particular topic related to | R, you can type help.start() at the prompt, which will open a menu of | resources (either within RStudio or your default web browser, depending on | your setup). Alternatively, a simple web search often yields the answer | you're looking for.

...

|
|==== | 5%

| In its simplest form, R can be used as an interactive calculator. Type 5 + 7 | and press Enter.

Warning: stack imbalance in '.Call', 72 then 73 Warning: stack imbalance in '<-', 66 then 67 Warning: stack imbalance in '{', 63 then 64 Warning: stack imbalance in 'if', 57 then 58 Warning: stack imbalance in '<-', 55 then 56 Warning: stack imbalance in '{', 52 then 53 Warning: stack imbalance in 'if', 46 then 47 Warning: stack imbalance in '<-', 44 then 45 Warning: stack imbalance in '{', 41 then 42 Warning: stack imbalance in '.Call', 38 then 39 Warning: stack imbalance in '<-', 32 then 33 Warning: stack imbalance in '{', 29 then 30

s-u commented 8 years ago

Yes, I saw that, too, but I have no idea what swirl is doing at that point so it's over to their side.

seankross commented 8 years ago

I'll take a look. All of these comments are very useful, thanks so much. Just a warning: don't expect an answer or a guess from me today.

gordonwoodhull commented 8 years ago

Now that's an error!

s-u commented 8 years ago

Note that the imbalance warnings come probably because there is an error raised in the callback itself which blows up things (since we're relying on our error handling which gets scrupulously replaced when R runs the handlers so the whole protection stack gets messed up - R will clean up the mess it caused itself, but grudgingly as you can see ;)). But that's just my theory - the whole top level callback handling is so ugly (it was designed to be run only at C level but then R level was added on top of it which is very fragile). Again, I'd prefer explicit handlers instead of the top level callbacks if at all possible...