How do I call the `function` function?












16















I am trying to call the function `function` to define a function in R code.



As we all know™️, `function`is a .Primitive that’s used internally by R to define functions when the user uses the conventional syntax, i.e.



mean1 = function (x, ...) base::mean(x, ...)


But there’s nothing preventing me from calling that primitive directly. Or so I thought. I can call other primitives directly (and even redefine them; for instance, in a moment of madness I overrode R’s builtin `for`). So this is in principle possible.



Yet I cannot get it to work for `function`. Here’s what I tried:



# Works
mean2 = as.function(c(formals(mean), quote(mean(x, ...))))

# Works
mean3 = eval(call('function', formals(mean), quote(mean(x, ...))))

# Error: invalid formal argument list for "function"
mean4 = `function`(formals(mean), quote(mean(x, ...)))


The fact that mean3 in particular works indicates to me that mean4 should work. But it doesn’t. Why?



I checked the definition of the `function` primitive in the R source. do_function is defined in eval.c. And I see that it calls CheckFormals, which ensures that each argument is a symbol, and this fails. But why does it check this, and what does that mean?



And most importantly: Is there a way of calling the `function` primitive directly?





Just to clarify: There are trivial workarounds (this question lists two, and there’s at least a third). But I’d like to understand how this (does not) works.










share|improve this question























  • Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)

    – Konrad Rudolph
    3 hours ago











  • Related: stackoverflow.com/questions/12982528/…

    – Artem Sokolov
    3 hours ago











  • @Moody's answer in the link above points out rlang::new_function, which can be called directly as a function and does essentially what function does.

    – Artem Sokolov
    3 hours ago











  • @ArtemSokolov … sure but that does exactly what my mean3 definition does. I’m well aware of workarounds, I was just curious why it doesn’t seem to work.

    – Konrad Rudolph
    3 hours ago


















16















I am trying to call the function `function` to define a function in R code.



As we all know™️, `function`is a .Primitive that’s used internally by R to define functions when the user uses the conventional syntax, i.e.



mean1 = function (x, ...) base::mean(x, ...)


But there’s nothing preventing me from calling that primitive directly. Or so I thought. I can call other primitives directly (and even redefine them; for instance, in a moment of madness I overrode R’s builtin `for`). So this is in principle possible.



Yet I cannot get it to work for `function`. Here’s what I tried:



# Works
mean2 = as.function(c(formals(mean), quote(mean(x, ...))))

# Works
mean3 = eval(call('function', formals(mean), quote(mean(x, ...))))

# Error: invalid formal argument list for "function"
mean4 = `function`(formals(mean), quote(mean(x, ...)))


The fact that mean3 in particular works indicates to me that mean4 should work. But it doesn’t. Why?



I checked the definition of the `function` primitive in the R source. do_function is defined in eval.c. And I see that it calls CheckFormals, which ensures that each argument is a symbol, and this fails. But why does it check this, and what does that mean?



And most importantly: Is there a way of calling the `function` primitive directly?





Just to clarify: There are trivial workarounds (this question lists two, and there’s at least a third). But I’d like to understand how this (does not) works.










share|improve this question























  • Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)

    – Konrad Rudolph
    3 hours ago











  • Related: stackoverflow.com/questions/12982528/…

    – Artem Sokolov
    3 hours ago











  • @Moody's answer in the link above points out rlang::new_function, which can be called directly as a function and does essentially what function does.

    – Artem Sokolov
    3 hours ago











  • @ArtemSokolov … sure but that does exactly what my mean3 definition does. I’m well aware of workarounds, I was just curious why it doesn’t seem to work.

    – Konrad Rudolph
    3 hours ago
















16












16








16


4






I am trying to call the function `function` to define a function in R code.



As we all know™️, `function`is a .Primitive that’s used internally by R to define functions when the user uses the conventional syntax, i.e.



mean1 = function (x, ...) base::mean(x, ...)


But there’s nothing preventing me from calling that primitive directly. Or so I thought. I can call other primitives directly (and even redefine them; for instance, in a moment of madness I overrode R’s builtin `for`). So this is in principle possible.



Yet I cannot get it to work for `function`. Here’s what I tried:



# Works
mean2 = as.function(c(formals(mean), quote(mean(x, ...))))

# Works
mean3 = eval(call('function', formals(mean), quote(mean(x, ...))))

# Error: invalid formal argument list for "function"
mean4 = `function`(formals(mean), quote(mean(x, ...)))


The fact that mean3 in particular works indicates to me that mean4 should work. But it doesn’t. Why?



I checked the definition of the `function` primitive in the R source. do_function is defined in eval.c. And I see that it calls CheckFormals, which ensures that each argument is a symbol, and this fails. But why does it check this, and what does that mean?



And most importantly: Is there a way of calling the `function` primitive directly?





Just to clarify: There are trivial workarounds (this question lists two, and there’s at least a third). But I’d like to understand how this (does not) works.










share|improve this question














I am trying to call the function `function` to define a function in R code.



As we all know™️, `function`is a .Primitive that’s used internally by R to define functions when the user uses the conventional syntax, i.e.



mean1 = function (x, ...) base::mean(x, ...)


But there’s nothing preventing me from calling that primitive directly. Or so I thought. I can call other primitives directly (and even redefine them; for instance, in a moment of madness I overrode R’s builtin `for`). So this is in principle possible.



Yet I cannot get it to work for `function`. Here’s what I tried:



# Works
mean2 = as.function(c(formals(mean), quote(mean(x, ...))))

# Works
mean3 = eval(call('function', formals(mean), quote(mean(x, ...))))

# Error: invalid formal argument list for "function"
mean4 = `function`(formals(mean), quote(mean(x, ...)))


The fact that mean3 in particular works indicates to me that mean4 should work. But it doesn’t. Why?



I checked the definition of the `function` primitive in the R source. do_function is defined in eval.c. And I see that it calls CheckFormals, which ensures that each argument is a symbol, and this fails. But why does it check this, and what does that mean?



And most importantly: Is there a way of calling the `function` primitive directly?





Just to clarify: There are trivial workarounds (this question lists two, and there’s at least a third). But I’d like to understand how this (does not) works.







r






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked 5 hours ago









Konrad RudolphKonrad Rudolph

397k1017861033




397k1017861033













  • Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)

    – Konrad Rudolph
    3 hours ago











  • Related: stackoverflow.com/questions/12982528/…

    – Artem Sokolov
    3 hours ago











  • @Moody's answer in the link above points out rlang::new_function, which can be called directly as a function and does essentially what function does.

    – Artem Sokolov
    3 hours ago











  • @ArtemSokolov … sure but that does exactly what my mean3 definition does. I’m well aware of workarounds, I was just curious why it doesn’t seem to work.

    – Konrad Rudolph
    3 hours ago





















  • Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)

    – Konrad Rudolph
    3 hours ago











  • Related: stackoverflow.com/questions/12982528/…

    – Artem Sokolov
    3 hours ago











  • @Moody's answer in the link above points out rlang::new_function, which can be called directly as a function and does essentially what function does.

    – Artem Sokolov
    3 hours ago











  • @ArtemSokolov … sure but that does exactly what my mean3 definition does. I’m well aware of workarounds, I was just curious why it doesn’t seem to work.

    – Konrad Rudolph
    3 hours ago



















Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)

– Konrad Rudolph
3 hours ago





Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)

– Konrad Rudolph
3 hours ago













Related: stackoverflow.com/questions/12982528/…

– Artem Sokolov
3 hours ago





Related: stackoverflow.com/questions/12982528/…

– Artem Sokolov
3 hours ago













@Moody's answer in the link above points out rlang::new_function, which can be called directly as a function and does essentially what function does.

– Artem Sokolov
3 hours ago





@Moody's answer in the link above points out rlang::new_function, which can be called directly as a function and does essentially what function does.

– Artem Sokolov
3 hours ago













@ArtemSokolov … sure but that does exactly what my mean3 definition does. I’m well aware of workarounds, I was just curious why it doesn’t seem to work.

– Konrad Rudolph
3 hours ago







@ArtemSokolov … sure but that does exactly what my mean3 definition does. I’m well aware of workarounds, I was just curious why it doesn’t seem to work.

– Konrad Rudolph
3 hours ago














2 Answers
2






active

oldest

votes


















7














This is because function is a special primitive:



typeof(`function`)
#> [1] "special"


The arguments are not evaluated, so you have actually passed quote(formals(mean)) instead of the value of formals(mean). I don't think there's a way of calling function directly without evaluation tricks, except with an empty formals list which is just NULL.






share|improve this answer



















  • 1





    I actually tried quoting the formals (as well as using alist), yet as you noticed this also doesn’t work. typeof(`for`) is also “special”, but calling ` for ` manually works.

    – Konrad Rudolph
    3 hours ago








  • 1





    Yeah because for takes a symbol and two expressions, for which there is parser syntax. There is no explicit parser syntax for creating a pairlist literal, which is what function() takes.

    – lionel
    3 hours ago











  • Indeed. I just figured out that you can call it with a manually generated pairlist — but once again only indirectly because, as you said, there’s no pairlist literal syntax.

    – Konrad Rudolph
    3 hours ago





















4














For completeness’ sake, lionel’s answer hints at a way of calling `function` after all. Unfortunately it’s rather restricted, since we cannot pass any argument definition except for NULL:



mean5 = `function`(NULL, mean(x, ...))
formals(mean5) = formals(mean)


(Note the lack of quoting around the body!)



This is of course utterly unpractical (and formals<- internally calls as.function anyway.)






share|improve this answer























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54596743%2fhow-do-i-call-the-function-function%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    7














    This is because function is a special primitive:



    typeof(`function`)
    #> [1] "special"


    The arguments are not evaluated, so you have actually passed quote(formals(mean)) instead of the value of formals(mean). I don't think there's a way of calling function directly without evaluation tricks, except with an empty formals list which is just NULL.






    share|improve this answer



















    • 1





      I actually tried quoting the formals (as well as using alist), yet as you noticed this also doesn’t work. typeof(`for`) is also “special”, but calling ` for ` manually works.

      – Konrad Rudolph
      3 hours ago








    • 1





      Yeah because for takes a symbol and two expressions, for which there is parser syntax. There is no explicit parser syntax for creating a pairlist literal, which is what function() takes.

      – lionel
      3 hours ago











    • Indeed. I just figured out that you can call it with a manually generated pairlist — but once again only indirectly because, as you said, there’s no pairlist literal syntax.

      – Konrad Rudolph
      3 hours ago


















    7














    This is because function is a special primitive:



    typeof(`function`)
    #> [1] "special"


    The arguments are not evaluated, so you have actually passed quote(formals(mean)) instead of the value of formals(mean). I don't think there's a way of calling function directly without evaluation tricks, except with an empty formals list which is just NULL.






    share|improve this answer



















    • 1





      I actually tried quoting the formals (as well as using alist), yet as you noticed this also doesn’t work. typeof(`for`) is also “special”, but calling ` for ` manually works.

      – Konrad Rudolph
      3 hours ago








    • 1





      Yeah because for takes a symbol and two expressions, for which there is parser syntax. There is no explicit parser syntax for creating a pairlist literal, which is what function() takes.

      – lionel
      3 hours ago











    • Indeed. I just figured out that you can call it with a manually generated pairlist — but once again only indirectly because, as you said, there’s no pairlist literal syntax.

      – Konrad Rudolph
      3 hours ago
















    7












    7








    7







    This is because function is a special primitive:



    typeof(`function`)
    #> [1] "special"


    The arguments are not evaluated, so you have actually passed quote(formals(mean)) instead of the value of formals(mean). I don't think there's a way of calling function directly without evaluation tricks, except with an empty formals list which is just NULL.






    share|improve this answer













    This is because function is a special primitive:



    typeof(`function`)
    #> [1] "special"


    The arguments are not evaluated, so you have actually passed quote(formals(mean)) instead of the value of formals(mean). I don't think there's a way of calling function directly without evaluation tricks, except with an empty formals list which is just NULL.







    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered 3 hours ago









    lionellionel

    2,9221518




    2,9221518








    • 1





      I actually tried quoting the formals (as well as using alist), yet as you noticed this also doesn’t work. typeof(`for`) is also “special”, but calling ` for ` manually works.

      – Konrad Rudolph
      3 hours ago








    • 1





      Yeah because for takes a symbol and two expressions, for which there is parser syntax. There is no explicit parser syntax for creating a pairlist literal, which is what function() takes.

      – lionel
      3 hours ago











    • Indeed. I just figured out that you can call it with a manually generated pairlist — but once again only indirectly because, as you said, there’s no pairlist literal syntax.

      – Konrad Rudolph
      3 hours ago
















    • 1





      I actually tried quoting the formals (as well as using alist), yet as you noticed this also doesn’t work. typeof(`for`) is also “special”, but calling ` for ` manually works.

      – Konrad Rudolph
      3 hours ago








    • 1





      Yeah because for takes a symbol and two expressions, for which there is parser syntax. There is no explicit parser syntax for creating a pairlist literal, which is what function() takes.

      – lionel
      3 hours ago











    • Indeed. I just figured out that you can call it with a manually generated pairlist — but once again only indirectly because, as you said, there’s no pairlist literal syntax.

      – Konrad Rudolph
      3 hours ago










    1




    1





    I actually tried quoting the formals (as well as using alist), yet as you noticed this also doesn’t work. typeof(`for`) is also “special”, but calling ` for ` manually works.

    – Konrad Rudolph
    3 hours ago







    I actually tried quoting the formals (as well as using alist), yet as you noticed this also doesn’t work. typeof(`for`) is also “special”, but calling ` for ` manually works.

    – Konrad Rudolph
    3 hours ago






    1




    1





    Yeah because for takes a symbol and two expressions, for which there is parser syntax. There is no explicit parser syntax for creating a pairlist literal, which is what function() takes.

    – lionel
    3 hours ago





    Yeah because for takes a symbol and two expressions, for which there is parser syntax. There is no explicit parser syntax for creating a pairlist literal, which is what function() takes.

    – lionel
    3 hours ago













    Indeed. I just figured out that you can call it with a manually generated pairlist — but once again only indirectly because, as you said, there’s no pairlist literal syntax.

    – Konrad Rudolph
    3 hours ago







    Indeed. I just figured out that you can call it with a manually generated pairlist — but once again only indirectly because, as you said, there’s no pairlist literal syntax.

    – Konrad Rudolph
    3 hours ago















    4














    For completeness’ sake, lionel’s answer hints at a way of calling `function` after all. Unfortunately it’s rather restricted, since we cannot pass any argument definition except for NULL:



    mean5 = `function`(NULL, mean(x, ...))
    formals(mean5) = formals(mean)


    (Note the lack of quoting around the body!)



    This is of course utterly unpractical (and formals<- internally calls as.function anyway.)






    share|improve this answer




























      4














      For completeness’ sake, lionel’s answer hints at a way of calling `function` after all. Unfortunately it’s rather restricted, since we cannot pass any argument definition except for NULL:



      mean5 = `function`(NULL, mean(x, ...))
      formals(mean5) = formals(mean)


      (Note the lack of quoting around the body!)



      This is of course utterly unpractical (and formals<- internally calls as.function anyway.)






      share|improve this answer


























        4












        4








        4







        For completeness’ sake, lionel’s answer hints at a way of calling `function` after all. Unfortunately it’s rather restricted, since we cannot pass any argument definition except for NULL:



        mean5 = `function`(NULL, mean(x, ...))
        formals(mean5) = formals(mean)


        (Note the lack of quoting around the body!)



        This is of course utterly unpractical (and formals<- internally calls as.function anyway.)






        share|improve this answer













        For completeness’ sake, lionel’s answer hints at a way of calling `function` after all. Unfortunately it’s rather restricted, since we cannot pass any argument definition except for NULL:



        mean5 = `function`(NULL, mean(x, ...))
        formals(mean5) = formals(mean)


        (Note the lack of quoting around the body!)



        This is of course utterly unpractical (and formals<- internally calls as.function anyway.)







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered 3 hours ago









        Konrad RudolphKonrad Rudolph

        397k1017861033




        397k1017861033






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54596743%2fhow-do-i-call-the-function-function%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Aikido

            Tivadar Csontváry Kosztka

            Metroo de Marsejlo