Skip to content

print.closure at the R level

8 messages · Duncan Murdoch, Romain Francois, Martin Maechler

#
Hello,

Could the code that auto prints a function/closure be extracted from 
print.c so that there would be a print.closure function.
I would like to be able to mask a print.closure function so that I have 
a custom auto-print. One reason for that is I plan to have syntax 
highlighting within the R console.

Romain
#
On 18/04/2009 10:12 AM, Romain Francois wrote:
The class of a closure is "function", so you'd want the method to be 
print.function.  Currently that doesn't work for auto printing, so your 
suggestion is still interesting.  (I'm not sure why auto printing is 
special here...)

Duncan Murdoch
#
Duncan Murdoch wrote:
Apparently, auto printing does not use the regular dispatch mechanism. 
See below:

I'll  make a more concrete proposal. This could be an opportunity to 
nail down as.character.function as well.

Romain

(from print.c)

 *  print.default()  ->     do_printdefault (with call tree below)
 *
 *  auto-printing   ->  PrintValueEnv
 *                      -> PrintValueRec
 *                      -> call print() for objects

and PrintValueRec switches on the typeof :

switch (TYPEOF(s)) {
...
    case CLOSXP:
    case LANGSXP:
    t = getAttrib(s, R_SourceSymbol);
    if (!isString(t) || !R_print.useSource)
        t = deparse1(s, 0, R_print.useSource | DEFAULTDEPARSE);
    for (i = 0; i < LENGTH(t); i++)
        Rprintf("%s\n", CHAR(STRING_ELT(t, i))); /* translated */
#ifdef BYTECODE
    if (TYPEOF(s) == CLOSXP && isByteCode(BODY(s)))
        Rprintf("<bytecode: %p>\n", BODY(s));
#endif
    if (TYPEOF(s) == CLOSXP) {
        t = CLOENV(s);
        if (t != R_GlobalEnv)
        Rprintf("%s\n", EncodeEnvironment(t));
    }
    break;
#
Duncan Murdoch wrote:
The attached patch implements exposing the print.function at the R level.

Romain
#
Yesterday's patch did not print the attributes. This one seems fine:

 > f <- function(){}
 > attr( f, "yada" ) <- function( ) "lobster bisk"
 > f
function(){}
attr(,"yada")
function( ) "lobster bisk"

Romain
Romain Francois wrote:

  
    
1 day later
#
Hello,

Sorry if I have waisted any time of people truing this patch. There was 
an issue with debugging (use of debug and browser that caused an 
infinite recursion). I think this is now fixed.

At the R level, I have now this :

 > print.function
function (x, useSource = TRUE, ...)
{
    invisible(.Internal(print.function(x, useSource, ...)))
}
<environment: namespace:base>

and the PrintValueRec dispatches like this at the C level:

    case LANGSXP:
    PrintLanguage(s, FALSE) ;
    break;
    case CLOSXP:
    {
        SEXP call;
        PROTECT( call = lang2(install("print.function"), s));
        eval(call,env);
        UNPROTECT(1);
        break;
    }

so that LANGSXP are printed using the PrintLanguage function and CLOSXP 
are printed using the R function print.function which in turns calls the 
PrintClosure function (unless it is masked in R)

Romain
Romain Francois wrote:

  
    
#
RF> Hello,

    RF> Sorry if I have waisted any time of people truing this
    RF> patch. 

yes, you did waste (sic) ....
but thank you for the code suggestions anyway.

    RF> There was an issue with debugging (use of debug
    RF> and browser that caused an infinite recursion). I think
    RF> this is now fixed.

[ actually I had found even simpler bugs in it, e.g.
  you accidentally called C-level "print.function()" on "language",
  some may have been fixed by your new patch too, but others are  
  not {e.g., print() *must* return its argument !}
]

However, I've already changed your old patch too much
(notably by using *our* C coding standards) to want to look at
your new patch in detail.

If you want we can communicate off-list about this, 
tomorrow...

Martin Maechler, ETH Zurich


    RF> At the R level, I have now this :

    >> print.function
    RF> function (x, useSource = TRUE, ...)  {
    RF> invisible(.Internal(print.function(x, useSource, ...)))
    RF> } <environment: namespace:base>

    RF> and the PrintValueRec dispatches like this at the C
    RF> level:

    RF>     case LANGSXP: PrintLanguage(s, FALSE) ; break; case
    RF> CLOSXP: { SEXP call; PROTECT( call =
    RF> lang2(install("print.function"), s)); eval(call,env);
    RF> UNPROTECT(1); break; }

    RF> so that LANGSXP are printed using the PrintLanguage
    RF> function and CLOSXP are printed using the R function
    RF> print.function which in turns calls the PrintClosure
    RF> function (unless it is masked in R)

    RF> Romain
RF> Romain Francois wrote:
>> Yesterday's patch did not print the attributes. This one
    >> seems fine:
    >> 
    >> > f <- function(){} > attr( f, "yada" ) <- function( )
    >> "lobster bisk" > f function(){} attr(,"yada") function( )
    >> "lobster bisk"
    >> 
    >> Romain
    >>
>> Romain Francois wrote:
>>> Duncan Murdoch wrote:
>>>> On 18/04/2009 10:12 AM, Romain Francois wrote:
>>>>> Hello,
    >>>>> 
    >>>>> Could the code that auto prints a function/closure be
    >>>>> extracted from print.c so that there would be a
    >>>>> print.closure function.  I would like to be able to
    >>>>> mask a print.closure function so that I have a custom
    >>>>> auto-print. One reason for that is I plan to have
    >>>>> syntax highlighting within the R console.
    >>>> 
    >>>> The class of a closure is "function", so you'd want the
    >>>> method to be print.function.  Currently that doesn't
    >>>> work for auto printing, so your suggestion is still
    >>>> interesting.  (I'm not sure why auto printing is
    >>>> special here...)
    >>>> 
    >>>> Duncan Murdoch
    >>> The attached patch implements exposing the
    >>> print.function at the R level.
    >>> 
    >>> Romain
    >>> 
    >>> ------------------------------------------------------------------------
    >>> 
    >>> ______________________________________________
    >>> 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


    RF> -- Romain Francois Independent R Consultant +33(0) 6 28
    RF> 91 30 30 http://romainfrancois.blog.free.fr
#
RF> Hello,

    RF> Sorry if I have waisted any time of people truing this
    RF> patch.

    MM> yes, you did waste (sic) ....  but thank you for the
    MM> code suggestions anyway.

    RF> There was an issue with debugging (use of debug and
    RF> browser that caused an infinite recursion). I think this
    RF> is now fixed.

    MM> [ actually I had found even simpler bugs in it, e.g.
    MM> you accidentally called C-level "print.function()" on
    MM> "language", some may have been fixed by your new patch
    MM> too, but others are not {e.g., print() *must* return its
    MM> argument !}  ]

    MM> However, I've already changed your old patch too much
    MM> (notably by using *our* C coding standards) to want to
    MM> look at your new patch in detail.

    MM> If you want we can communicate off-list about this,
    MM> tomorrow...
{and we did}

It turns out to be considerably more tricky than I had
anticipated...

Note that we also really want auto-printing and print()ing to be
equivalent,
and that is not even the case for .Primitives in current R :

  > c
  function (..., recursive = FALSE)  .Primitive("c")
  > print(c)
  function (..., recursive = FALSE)  
  > 

{for "obvious" reasons, but needing even more work ...}

Also, Romain was "right" insofar as he would have wanted to only
deal with closure, whereas of course Duncan was right that the
corresponding class is 'function' and that comprises other types
(in the 'typeof' sense).

[story to be continued ...]

Martin Maechler, ETH Zurich


    RF> At the R level, I have now this :

    >>> print.function
    RF> function (x, useSource = TRUE, ...)  {
    RF> invisible(.Internal(print.function(x, useSource, ...)))
    RF> } <environment: namespace:base>

    RF> and the PrintValueRec dispatches like this at the C
    RF> level:

    RF> case LANGSXP: PrintLanguage(s, FALSE) ; break; case
    RF> CLOSXP: { SEXP call; PROTECT( call =
    RF> lang2(install("print.function"), s)); eval(call,env);
    RF> UNPROTECT(1); break; }

    RF> so that LANGSXP are printed using the PrintLanguage
    RF> function and CLOSXP are printed using the R function
    RF> print.function which in turns calls the PrintClosure
    RF> function (unless it is masked in R)

    RF> Romain
RF> Romain Francois wrote:
>>> Yesterday's patch did not print the attributes. This one
    >>> seems fine:
    >>> 
    >>> > f <- function(){} > attr( f, "yada" ) <- function( )
    >>> "lobster bisk" > f function(){} attr(,"yada") function(
    >>> ) "lobster bisk"
    >>> 
    >>> Romain
    >>>
>>> Romain Francois wrote:
>>>> Duncan Murdoch wrote:
>>>>> On 18/04/2009 10:12 AM, Romain Francois wrote:
>>>>>> Hello,
    >>>>>> 
    >>>>>> Could the code that auto prints a function/closure be
    >>>>>> extracted from print.c so that there would be a
    >>>>>> print.closure function.  I would like to be able to
    >>>>>> mask a print.closure function so that I have a custom
    >>>>>> auto-print. One reason for that is I plan to have
    >>>>>> syntax highlighting within the R console.
    >>>>> 
    >>>>> The class of a closure is "function", so you'd want
    >>>>> the method to be print.function.  Currently that
    >>>>> doesn't work for auto printing, so your suggestion is
    >>>>> still interesting.  (I'm not sure why auto printing is
    >>>>> special here...)
    >>>>> 
    >>>>> Duncan Murdoch
    >>>> The attached patch implements exposing the
    >>>> print.function at the R level.
    >>>> 
    >>>> Romain
    >>>> 
    >>>> ------------------------------------------------------------------------
    >>>> 
    >>>> ______________________________________________
    >>>> 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


    RF> -- Romain Francois Independent R Consultant +33(0) 6 28
    RF> 91 30 30 http://romainfrancois.blog.free.fr

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