First, one comment:
You're right about the illegality of _PIPE_ as a name, I had
misremembered the rule.
About your proposal:
I don't find it attractive, but I can see that some people would. But I
don't think it's necessary to put it into the base parser. Other than
using an illegal name, there doesn't seem to be a reason you couldn't
write a small function to convert your placeholder proposal to a call to
a function. So instead of typing
x |> { y <- _PIPE_+1; _PIPE_ / y }
you would type
x |> forpipe({ y <- PIPE_+1; PIPE_ / y })
I don't think "forpipe" is the right name here. I proposed a
generic
"as.call" before, but I don't like that one either. I'm still
trying to
think of a good name, and whether or not it makes sense for it to be
generic.
But the point is that we don't need to choose just one from all the
proposed replacements for anonymous function syntax, we can try them out
and see which ones we like. We might end up with more than one (like we
have at least 4 different high level graphics paradigms!), and that's
not the end of the world.
Duncan Murdoch
On 08/12/2020 4:26 p.m., Bravington, Mark (Data61, Hobart)
wrote:>>> On 06/12/2020 8:22 p.m., Bravington, Mark (Data61, Hobart) wrote:
>> (and Duncan Murdoch responded, as below)
>
> It still seems to me that placeholders are viable and unambiguous (only as
things in RHS of pipes), and that something like
>
> x |> foo( _PIPE_)
> x |> bah( otherarg, _PIPE_)
> x |> { y <- _PIPE_+1; _PIPE_ / y } # anonymous function
>
> would be a viable solution that doesn't break syntax. This suggestion
expands slightly on my previous post, to deal with anonymous functions without
either ugly or cumbersome syntax. Specifically, the parser could expand
curly-braces in a pipe RHS like this:
>
> x |> {expr}
>
> into
>
> _ANON_( _PIPE_, {expr})( x)
>
> where '_ANON_' itself constructs-and-calls a function with one
argument called '_PIPE_' whose body consists of 'expr' (which
presumably refers to '_PIPE_')
>
> No new weird operators like \(, and the only break with normal syntax is
the expansion of curly-braces--- plus treating one symbol, _PIPE_ or any other
pre-agreed one perhaps even just _, as a legal name inside a pipe.
>
> Now back to my previous post and responding to Duncan's comments:
>
>>> - I don't see the problem with a placeholder--- doesn't
it remove all ambiguity? Sure there needs to be a standard unclashable name and
people can argue about what that should be, but the following seems clear and
flexible... to me, anyway:
>>>
>>> thing |>
>>> foo( _PIPE_) |> # standard
>>> bah( arg1, _PIPE_) |> # multi-arg function
>>> _ANON_({ x <- sum( _PIPE_); _PIPE_/x + x/_PIPE_ }) # anon
function
>>>
>>> where '_PIPE_' is the ordained name of the placeholder, and
'_ANON_' constructs-and-calls a function with single argument
'_PIPE_'. There is just one rule (I think...): each pipe-stage must be a
*call* involving the argument '_PIPE_'.
>
> and (see end) I think the line with _ANON_ above could in fact just be
>
> ... |> { x <- sum( _PIPE_); _PIPE_/x + x/_PIPE_ }
>
>> I believe there's no ambiguity if the placeholder is *only* allowed
in the RHS of a pipe expression.
>
> Yes--- that's my suggestion: there and only there. Hence an
otherwise-illegal name like _PIPE_.
>
>> I think the ambiguity arises if you allow
>> the same syntax to be used to generate anonymous functions.
>
> Agreed; don't allow that outside of pipes.
>
>> We can't use _PIPE_ as the placeholder, because it's a legal
name.
>
> Surely _PIPE_ is not a legal R name though? Not in my R4.1.0dev, anyway. Of
course, the parser can _make_ it legal *only* in the context of RHS of pipe.
Anyway, I'm not suggesting the names must be _PIPE_ and _ANON_--- the name
is secondary to the concept.
>
>> But we could use _.
>
> Yes, any unclashable name would do--- though "_" is hard to read
(as per complaints about "." as placeholder, which I use in my own
code). And I remember back when R decided to disallow "_" as an
assignment operator. Which forced me to change about 50000 lines of code that
wasn't stored in text files, so I wasn't happy--- and the only reason
that was ever given to me, was "it's ugly" ! Which is kinda true.
>
>> However, implementing this makes the parser pretty ugly: its handling
of _ depends on the outer context.
>
> That context issue is already the case under the current proposal though;
eg 'head(10)' in
>
> x |> head(10) # really head( <arg>, 10)
>
> or indeed 'head' in
>
> x |> head # actually a call to head(<arg>), not a symbol
>
>
>> I now agree that leaving out placeholder syntax was the right decision.
>
> Others are not so sure!
>
> Re operator precedence: thanks for pointing that out, I accept that R's
current operator-precedence rules make it impossible for people to cleanly
implement their own preferred homemade %my_pipe_op%.
>
> All the more reason to be careful with the pipe syntax choice for base-R,
of course...
>
>
>> Then
>
>> x |> (_ + 1) + mean(_)
>
>> could expand unambiguously to
>
>> (function(_) (_ + 1) + mean(_))(x)
>
>> but
>
>> (_ + 1) + mean(_)
>
>> shouldn't be taken to be an anonymous function declaration,
otherwise
>> things like
>
>> mean(_ |> _)
>
>> do become ambiguous: is the second placeholder the argument to the
anon
>> function, or is it the placeholder for the embedded pipe?
>
> That wouldn't be allowed in my proposal; the "_ |> _" is
illegal because the RHS is not a call. For the whole thing, I'd require
>
> x |> _ANON_((_PIPE_ + 1) + mean( _PIPE_))
>
> or the just-curly version
>
> x |> { (_PIPE_ + 1) + mean( _PIPE_)}
>
> but with the implication that this would parse out to
>
> (`_ANON_`( { (_PIPE_ + 1) + mean( _PIPE_)}))( x)
>
>>> [*] Definition of _ANON_ could be something like this--- almost
certainly won't work as-is, this is just to point out that it could be done
in standard R.
>
>>> `_ANON_` <- function( expr) {
>>> #1. Construct a function with arg '_PIPE_' and body
'expr'
>>> #2. Construct a call() to that function
>>> #3. Do the call
>
>>> f <- function( `_PIPE_`) NULL
>>> body( f) <- expr
>>> environment( f) <- parent.frame() # or something... yes these
details are almost certainly wrong
>>> expr2 <- substitute( f( `_PIPE_`)) # or something...
>>> eval.parent( expr2) # or something...
>>> }
>
>
> Mark Bravington
> CSIRO Marine Lab
> Hobart
> Australia
>
>
> ________________________________________
> From: Duncan Murdoch <murdoch.duncan at gmail.com>
> Sent: Monday, 7 December 2020 21:31
> To: Bravington, Mark (Data61, Hobart); Gabor Grothendieck; Gabriel Becker
> Cc: r-devel at r-project.org
> Subject: Re: [Rd] New pipe operator
>
> On 06/12/2020 8:22 p.m., Bravington, Mark (Data61, Hobart) wrote:
>> Seems like this *could* be a good thing, and thanks to R core for
considering it. But, FWIW:
>>
>> - I agree with Gabor G that consistency of "syntax" should
be paramount here. Enough problems have been caused by earlier
superficially-convenient non-standard features in R. In particular:
>>
>> -- there should not be any discrepancy between an in-place
function-definition, and a predefined function attached to a symbol (as per
Gabor's point).
>>
>> -- Hence, the ability to say x |> foo ie without parentheses,
seems bound to lead to inconsistency, because x |> foo is allowed, x |>
base::foo isn't allowed without tricks, but x |> function( y) foo( y)
isn't... So, x |> foo is not worth keeping. Parentheses are a price well
worth paying.
>>
>> -- it is still inconsistent and confusing to (apparently) invoke a
function in some places--- normally--- via 'foo(x)', yet in others---
pipily--- via 'foo()'. Especially if 'foo' already has a default
value for its first argument.
>>
>> - I don't see the problem with a placeholder--- doesn't it
remove all ambiguity? Sure there needs to be a standard unclashable name and
people can argue about what that should be, but the following seems clear and
flexible... to me, anyway:
>>
>> thing |>
>> foo( _PIPE_) |> # standard
>> bah( arg1, _PIPE_) |> # multi-arg function
>> _ANON_({ x <- sum( _PIPE_); _PIPE_/x + x/_PIPE_ }) # anon
function
>>
>> where '_PIPE_' is the ordained name of the placeholder, and
'_ANON_' constructs-and-calls a function with single argument
'_PIPE_'. There is just one rule (I think...): each pipe-stage must be a
*call* involving the argument '_PIPE_'.
>
> I believe there's no ambiguity if the placeholder is *only* allowed in
> the RHS of a pipe expression. I think the ambiguity arises if you allow
> the same syntax to be used to generate anonymous functions. We can't
> use _PIPE_ as the placeholder, because it's a legal name. But we could
> use _. Then
>
> x |> (_ + 1) + mean(_)
>
> could expand unambiguously to
>
> (function(_) (_ + 1) + mean(_))(x)
>
> but
>
> (_ + 1) + mean(_)
>
> shouldn't be taken to be an anonymous function declaration, otherwise
> things like
>
> mean(_ |> _)
>
> do become ambiguous: is the second placeholder the argument to the anon
> function, or is it the placeholder for the embedded pipe?
>
> However, implementing this makes the parser pretty ugly: its handling
> of _ depends on the outer context. I now agree that leaving out
> placeholder syntax was the right decision.
>
>
>>
>>
>> - The proposed anonymous-function syntax looks quite ugly to me,
diminishing readability and inviting errors. The new pipe symbol |> already
looks scarily like quantum mechanics; adding \( just puts fishbones into the
symbolic soup.
>>
>> - IMO it's not worth going too far to try to lure magritter-etc
fans to swap to the new; my experience is that many people keep using older
inferior R syntax for years after better replacements become available (even if
they are aware of replacements), for various reasons. Just provide a good
framework, and let nature take its course.
>>
>> - Disclaimer: personally I'm not much of a pipehead anyway, so
maybe I'm not the audience. But if I was to consider piping, I wouldn't
be very tempted by the current proposal. OTOH, I might even be tempted to
write--- and use!--- my own version of '%|>%' as above (maybe someone
already has). And if R did it for me, that'd be great :)
>
> Yours would suffer one of the same problems as magrittr's: it has the
> wrong operator precedence. The current precedence ordering (from
> ?Syntax) is, from highest to lowest:
>
>
> :: ::: access variables in a namespace
> $ @ component / slot extraction
> [ [[ indexing
> ^ exponentiation (right to left)
> - + unary minus and plus
> : sequence operator
> %any% special operators (including %% and %/%)
> * / multiply, divide
> + - (binary) add, subtract
> < > <= >= == != ordering and comparison
> ! negation
> & && and
> | || or
> ~ as in formulae
> -> ->> rightwards assignment
> <- <<- assignment (right to left)
> = assignment (right to left)
> ? help (unary and binary)
>
>
> The %>% operator has higher precedence than the arithmetic operators, so
>
> x*y %>% f()
>
> is equivalent to x*f(y), not
>
> f(x*y)
>
> as it should "obviously" be. I believe the new |> operator
falls
> between "| ||" and "~", so
>
> x || y |> f()
>
> is the same as f(x || y), and
>
> x ~ y |> f()
>
> is x ~ f(y). There could be arguments about where the new one appears
> (and there probably have been), but *clearly* magrittr's precedence is
> wrong, and yours would be too, because they are both fixed at the quite
> high precedence given to %any%.
>
> Duncan Murdoch
>
>>
>> [*] Definition of _ANON_ could be something like this--- almost
certainly won't work as-is, this is just to point out that it could be done
in standard R.
>>
>> `_ANON_` <- function( expr) {
>> #1. Construct a function with arg '_PIPE_' and body
'expr'
>> #2. Construct a call() to that function
>> #3. Do the call
>>
>> f <- function( `_PIPE_`) NULL
>> body( f) <- expr
>> environment( f) <- parent.frame() # or something... yes these
details are almost certainly wrong
>> expr2 <- substitute( f( `_PIPE_`)) # or something...
>> eval.parent( expr2) # or something...
>> }
>>
>> cheers
>> Mark
>>
>> Mark Bravington
>> CSIRO Marine Lab
>> Hobart
>> Australia
>>
>>
>> ________________________________________
>> From: R-devel <r-devel-bounces at r-project.org> on behalf of
Gabor Grothendieck <ggrothendieck at gmail.com>
>> Sent: Monday, 7 December 2020 10:21
>> To: Gabriel Becker
>> Cc: r-devel at r-project.org
>> Subject: Re: [Rd] New pipe operator
>>
>> I understand very well that it is implemented at the syntax level;
>> however, in any case the implementation is irrelevant to the
principles.
>>
>> Here a similar example to the one I gave before but this time written
out:
>>
>> This works:
>>
>> 3 |> function(x) x + 1
>>
>> but this does not:
>>
>> foo <- function(x) x + 1
>> 3 |> foo
>>
>> so it breaks the principle of functions being first class objects. foo
and its
>> definition are not interchangeable. You have
>> to write 3 |> foo() but don't have to write 3 |> (function(x)
x + 1)().
>>
>> This isn't just a matter of notation, i.e. foo vs foo(), but is a
>> matter of breaking
>> the way R works as a functional language with first class functions.
>>
>> On Sun, Dec 6, 2020 at 4:06 PM Gabriel Becker <gabembecker at
gmail.com> wrote:
>>>
>>> Hi Gabor,
>>>
>>> On Sun, Dec 6, 2020 at 12:52 PM Gabor Grothendieck
<ggrothendieck at gmail.com> wrote:
>>>>
>>>> I think the real issue here is that functions are supposed to
be
>>>> first class objects in R
>>>> or are supposed to be and |> would break that if if is
possible
>>>> to write function(x) x + 1 on the RHS but not foo (assuming foo
>>>> was defined as that function).
>>>>
>>>> I don't think getting experience with using it can change
that
>>>> inconsistency which seems serious to me and needs to
>>>> be addressed even if it complicates the implementation
>>>> since it drives to the heart of what R is.
>>>>
>>>
>>> With respect I think this is a misunderstanding of what is
happening here.
>>>
>>> Functions are first class citizens. |> is, for all intents and
purposes, a macro.
>>>
>>> LHS |> RHS(arg2=5)
>>>
>>> parses to
>>>
>>> RHS(LHS, arg2 = 5)
>>>
>>> There are no functions at the point in time when the pipe
transformation happens, because no code has been evaluated. To know if a symbol
is going to evaluate to a function requires evaluation which is a step entirely
after the one where the |> pipe is implemented.
>>>
>>> Another way to think about it is that
>>>
>>> LHS |> RHS(arg2 = 5)
>>>
>>> is another way of writing RHS(LHS, arg2 = 5), NOT R code that is
(or even can be) evaluated.
>>>
>>>
>>> Now this is a subtle point that only really has implications in as
much as it is not the case for magrittr pipes, but its relevant for discussions
like this, I think.
>>>
>>> ~G
>>>
>>>> On Sat, Dec 5, 2020 at 1:08 PM Gabor Grothendieck
>>>> <ggrothendieck at gmail.com> wrote:
>>>>>
>>>>> The construct utils::head is not that common but bare
functions are
>>>>> very common and to make it harder to use the common case so
that
>>>>> the uncommon case is slightly easier is not desirable.
>>>>>
>>>>> Also it is trivial to write this which does work:
>>>>>
>>>>> mtcars %>% (utils::head)
>>>>>
>>>>> On Sat, Dec 5, 2020 at 11:59 AM Hugh Parsonage
<hugh.parsonage at gmail.com> wrote:
>>>>>>
>>>>>> I'm surprised by the aversion to
>>>>>>
>>>>>> mtcars |> nrow
>>>>>>
>>>>>> over
>>>>>>
>>>>>> mtcars |> nrow()
>>>>>>
>>>>>> and I think the decision to disallow the former should
be
>>>>>> reconsidered. The pipe operator is only going to be
used when the rhs
>>>>>> is a function, so there is no ambiguity with omitting
the parentheses.
>>>>>> If it's disallowed, it becomes inconsistent with
other treatments like
>>>>>> sapply(mtcars, typeof) where sapply(mtcars, typeof())
would just be
>>>>>> noise. I'm not sure why this decision was taken
>>>>>>
>>>>>> If the only issue is with the double (and triple) colon
operator, then
>>>>>> ideally `mtcars |> base::head` should resolve to
`base::head(mtcars)`
>>>>>> -- in other words, demote the precedence of |>
>>>>>>
>>>>>> Obviously (looking at the R-Syntax branch) this
decision was
>>>>>> considered, put into place, then dropped, but I
can't see why
>>>>>> precisely.
>>>>>>
>>>>>> Best,
>>>>>>
>>>>>>
>>>>>> Hugh.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sat, 5 Dec 2020 at 04:07, Deepayan Sarkar
<deepayan.sarkar at gmail.com> wrote:
>>>>>>>
>>>>>>> On Fri, Dec 4, 2020 at 7:35 PM Duncan Murdoch
<murdoch.duncan at gmail.com> wrote:
>>>>>>>>
>>>>>>>> On 04/12/2020 8:13 a.m., Hiroaki Yutani wrote:
>>>>>>>>>> Error: function '::' not
supported in RHS call of a pipe
>>>>>>>>>
>>>>>>>>> To me, this error looks much more friendly
than magrittr's error.
>>>>>>>>> Some of them got too used to specify
functions without (). This
>>>>>>>>> is OK until they use `::`, but when they
need to use it, it takes
>>>>>>>>> hours to figure out why
>>>>>>>>>
>>>>>>>>> mtcars %>% base::head
>>>>>>>>> #> Error in .::base : unused argument
(head)
>>>>>>>>>
>>>>>>>>> won't work but
>>>>>>>>>
>>>>>>>>> mtcars %>% head
>>>>>>>>>
>>>>>>>>> works. I think this is a too harsh lesson
for ordinary R users to
>>>>>>>>> learn `::` is a function. I've been
wanting for magrittr to drop the
>>>>>>>>> support for a function name without () to
avoid this confusion,
>>>>>>>>> so I would very much welcome the new pipe
operator's behavior.
>>>>>>>>> Thank you all the developers who
implemented this!
>>>>>>>>
>>>>>>>> I agree, it's an improvement on the
corresponding magrittr error.
>>>>>>>>
>>>>>>>> I think the semantics of not evaluating the
RHS, but treating the pipe
>>>>>>>> as purely syntactical is a good decision.
>>>>>>>>
>>>>>>>> I'm not sure I like the recommended way to
pipe into a particular argument:
>>>>>>>>
>>>>>>>> mtcars |> subset(cyl == 4) |> \(d)
lm(mpg ~ disp, data = d)
>>>>>>>>
>>>>>>>> or
>>>>>>>>
>>>>>>>> mtcars |> subset(cyl == 4) |>
function(d) lm(mpg ~ disp, data = d)
>>>>>>>>
>>>>>>>> both of which are equivalent to
>>>>>>>>
>>>>>>>> mtcars |> subset(cyl == 4) |>
(function(d) lm(mpg ~ disp, data = d))()
>>>>>>>>
>>>>>>>> It's tempting to suggest it should allow
something like
>>>>>>>>
>>>>>>>> mtcars |> subset(cyl == 4) |> lm(mpg
~ disp, data = .)
>>>>>>>
>>>>>>> Which is really not that far off from
>>>>>>>
>>>>>>> mtcars |> subset(cyl == 4) |> \(.) lm(mpg ~
disp, data = .)
>>>>>>>
>>>>>>> once you get used to it.
>>>>>>>
>>>>>>> One consequence of the implementation is that
it's not clear how
>>>>>>> multiple occurrences of the placeholder would be
interpreted. With
>>>>>>> magrittr,
>>>>>>>
>>>>>>> sort(runif(10)) %>% ecdf(.)(.)
>>>>>>> ## [1] 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1.0
>>>>>>>
>>>>>>> This is probably what you would expect, if you
expect it to work at all, and not
>>>>>>>
>>>>>>> ecdf(sort(runif(10)))(sort(runif(10)))
>>>>>>>
>>>>>>> There would be no such ambiguity with anonymous
functions
>>>>>>>
>>>>>>> sort(runif(10)) |> \(.) ecdf(.)(.)
>>>>>>>
>>>>>>> -Deepayan
>>>>>>>
>>>>>>>> which would be expanded to something equivalent
to the other versions:
>>>>>>>> but that makes it quite a bit more complicated.
(Maybe _ or \. should
>>>>>>>> be used instead of ., since those are not legal
variable names.)
>>>>>>>>
>>>>>>>> I don't think there should be an attempt to
copy magrittr's special
>>>>>>>> casing of how . is used in determining whether
to also include the
>>>>>>>> previous value as first argument.
>>>>>>>>
>>>>>>>> Duncan Murdoch
>>>>>>>>
>>>>>>>>
>>>>>>>>>
>>>>>>>>> Best,
>>>>>>>>> Hiroaki Yutani
>>>>>>>>>
>>>>>>>>> 2020?12?4?(?) 20:51 Duncan Murdoch
<murdoch.duncan at gmail.com>:
>>>>>>>>>>
>>>>>>>>>> Just saw this on the R-devel news:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> R now provides a simple native pipe
syntax ?|>? as well as a shorthand
>>>>>>>>>> notation for creating functions, e.g.
?\(x) x + 1? is parsed as
>>>>>>>>>> ?function(x) x + 1?. The pipe
implementation as a syntax transformation
>>>>>>>>>> was motivated by suggestions from Jim
Hester and Lionel Henry. These
>>>>>>>>>> features are experimental and may
change prior to release.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> This is a good addition; by using
"|>" instead of "%>%" there should be
>>>>>>>>>> a chance to get operator precedence
right. That said, the ?Syntax help
>>>>>>>>>> topic hasn't been updated, so
I'm not sure where it fits in.
>>>>>>>>>>
>>>>>>>>>> There are some choices that take a
little getting used to:
>>>>>>>>>>
>>>>>>>>>> > mtcars |> head
>>>>>>>>>> Error: The pipe operator requires a
function call or an anonymous
>>>>>>>>>> function expression as RHS
>>>>>>>>>>
>>>>>>>>>> (I need to say mtcars |> head()
instead.) This sometimes leads to error
>>>>>>>>>> messages that are somewhat confusing:
>>>>>>>>>>
>>>>>>>>>> > mtcars |>
magrittr::debug_pipe |> head
>>>>>>>>>> Error: function '::' not
supported in RHS call of a pipe
>>>>>>>>>>
>>>>>>>>>> but
>>>>>>>>>>
>>>>>>>>>> mtcars |> magrittr::debug_pipe()
|> head()
>>>>>>>>>>
>>>>>>>>>> works.
>>>>>>>>>>
>>>>>>>>>> Overall, I think this is a great
addition, though it's going to be
>>>>>>>>>> disruptive for a while.
>>>>>>>>>>
>>>>>>>>>> Duncan Murdoch
>>>>>>>>>>
>>>>>>>>>>
______________________________________________
>>>>>>>>>> R-devel at r-project.org mailing list
>>>>>>>>>>
https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>>>>>
>>>>>>>>>
______________________________________________
>>>>>>>>> R-devel at r-project.org mailing list
>>>>>>>>>
https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>>>>>
>>>>>>>>
>>>>>>>> ______________________________________________
>>>>>>>> R-devel at r-project.org mailing list
>>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>>>
>>>>>>> ______________________________________________
>>>>>>> R-devel at r-project.org mailing list
>>>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>>
>>>>>> ______________________________________________
>>>>>> R-devel at r-project.org mailing list
>>>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Statistics & Software Consulting
>>>>> GKX Group, GKX Associates Inc.
>>>>> tel: 1-877-GKX-GROUP
>>>>> email: ggrothendieck at gmail.com
>>>>
>>>>
>>>>
>>>> --
>>>> Statistics & Software Consulting
>>>> GKX Group, GKX Associates Inc.
>>>> tel: 1-877-GKX-GROUP
>>>> email: ggrothendieck at gmail.com
>>>>
>>>> ______________________________________________
>>>> R-devel at r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>>
>>
>> --
>> Statistics & Software Consulting
>> GKX Group, GKX Associates Inc.
>> tel: 1-877-GKX-GROUP
>> email: ggrothendieck at gmail.com
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>> ______________________________________________
>> R-devel at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-devel
>>
>