On May 31, 2011, at 5:23 PM, Thomas Friedrichsmeier wrote:
> On Tuesday 31 May 2011, Simon Urbanek wrote:
>> The history entries are somewhat in a grey area, because most GUIs use
>> their own implementation of history (and thus they are irrelevant) and the
>> *history() commands are documented to only use readline-backend. That
>> said, they could be easily used by all GUIs if the Windows code is
>> amended.
>
> Actually, I would suggest to use a different solution, though: This is not
> really a problem that needs to be addressed on a low level of pointers to C
> functions. Perhaps it would make more sense to allow to set some R
> function(s)
> to handle these via options() (or perhaps via a dedicated gui.options()).
>
I suppose, yes, it's possible, but I see somewhat of an asymmetry if done that
way : GUIs are like plug-ins in that there is a set of functions they have to
implement to work properly. In the current state this is done using the C-level
hooks, but they are incomplete in that some of the required hooks are not
available on all platforms. However, if you introduce an additional layer of R
function hooks, there will be two sets of competing ways for the GUI so
register and some of them are simply not feasible on the R level (console
handling, for example, which is why we have C-level hooks). It also makes the
GUI unnecessary messy, since they will need to provide both C code and R code,
where the R code essentially just points to C code, practically replicating
what the C-level hooks would do (just more complicated as it requires embedded
symbol registrations etc.).
Currently I'm more inclined to make the hooks cross-platform (maybe conditional
on the GUI type set to "custom" or something like that). But if someone wants
to devise some nice way of customizing parts using R callback, I won't oppose
it.
>>> - utils::select.list() and utils::menu(): I want to show my own UI if
>>> graphics==TRUE. Currently, select.list() has special code for windows,
>>> "aqua" and tcltk; menu() essentially assumes the same code. Give me a
>>> way to run register my own UI.
>>
>> ptr_do_selectlist provides the customization and could be extended to other
>> platforms.
>
> See above. But yes, if at least it was cross-platform, that would be nice.
>
>>> - base::system(), base::system2(): As you will be aware, capturing the
>>> output of system commands in a GUI is tricky on Unix. I do have a
>>> solution for that, but I need to run synchronization code at the start
>>> and end of system() and system2(), in order to get interleaving right.
>>> Give me a hook, each, at the start and end of these functions.
>>
>> I'm not sure I understand your concern here. What exactly is your worry?
>> Capturing output is trivial since it simply involves creating a pipe when
>> you initialize R which you can read while R is running and the
>> synchronization is provided by the OS, no magic involved.
>
> Is that pipe buffered?
No (although you could buffer it if you wanted).
> In my setup it is. And so consider code like this:
> for (i in 1:10) {
> print (i)
> system (paste ("echo", i))
> }
> How do you ensure that this results in
> 1
> 1
> 2
> 2
> ...
> rather than e.g.
> 1
> 2
> 3
> 1
> 2
> 4
> 3
> 5
> 6
> ...
>
In R the output will be
1
1
2
2
by design - system() is synchronous, so stdout will arrive between the
WriteConsole calls - try in the the R for Mac GUI and you'll see:
> for (i in 1:10) {
+ print (i)
+ system (paste ("echo", i))
+ }
[1] 1
1
[1] 2
2
[1] 3
3
[1] 4
4
[1] 5
5
[1] 6
6
[1] 7
7
[1] 8
8
[1] 9
9
[1] 10
10
>
Obviously, for wait=FALSE all bets are off. [Note: although the Mac GUI uses a
hook for system, it is to run commands as root, not to do any special handling
of I/O].
> I could not get it to work for RKWard without adding code to make sure the
> "other" output is flushed.
If you have issues with stdout buffer before the pipe, use can use setvbuf() to
disable buffering.
> (Note: I'm capturing regular R output via
> R_WriteConsoleEx, since I am interested in the differentiation between output
> types that this provides. So I cannot simply push that down the same pipe.).
>
>>> - graphics::plot.new(): I need a hook *before* the new plot is started,
>>> in order to properly implement device-independent plot history. I would
>>> appreciate not having to implement my own graphics device just to be
>>> able to run some code at this point.
>>>
>>> - grDevices::dev.off(): I need a hook before the device is closed. Also
>>> for plot history.
>>>
>>> - grDevices::dev.set(): I need a hook after the new device has been set.
>>> Also for plot history.
>>>
>>> - grid::newpage(): See graphics::plot.new(). Of course, even better, I
>>> would like to have a hook that is called every time before a new page /
>>> frame is started on a device.
>>
>> For all of the above: all of them are already available a device callbacks
>> (newPage, close, activate and newPage again).
>
> Quoting myself: I would appreciate not having to implement my own graphics
> device just to be able to run some code at [these] point[s].
>
Cautiously I would argue you have to the moment you're outside R, essentially
since the built-in graphics devices are not guaranteed to work when embedded.
In practice, I think if you write a GUI, you have to provide a GD - that is the
only reasonable way you can seamlessly incorporate R graphics into your GUI.
That said, there is a precedent for graphics hooks. The problem I see is the
same that became apparent with grid last time we added hooks - there are
potentially multiple ways to get to the same C level point, and they are either
easily forgotten, or even hard to enumerate. For example, dev.set() is not the
only way to activate a device - it can be activated from the menu and other
means via selectDevice() which is at C level, so there is no R code involved at
all, thus setting a hook on dev.set() is will work only in a subset of cases
and thus you cannot expect consistency in your GUI.
(Note: none of my comments are specific to RKWard, since it is not even
available for OS X so I don't know anything about it)
Cheers,
Simon
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel