How do I call the `function` function?
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
add a comment |
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
Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)
– Konrad Rudolph
8 hours ago
Related: stackoverflow.com/questions/12982528/…
– Artem Sokolov
8 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 whatfunction
does.
– Artem Sokolov
8 hours ago
@ArtemSokolov … sure but that does exactly what mymean3
definition does. I’m well aware of workarounds, I was just curious why it doesn’t seem to work.
– Konrad Rudolph
8 hours ago
Sorry for misunderstanding. Please see my answer below.
– Artem Sokolov
4 hours ago
add a comment |
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
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
r
asked 9 hours ago
Konrad RudolphKonrad Rudolph
397k1017861033
397k1017861033
Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)
– Konrad Rudolph
8 hours ago
Related: stackoverflow.com/questions/12982528/…
– Artem Sokolov
8 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 whatfunction
does.
– Artem Sokolov
8 hours ago
@ArtemSokolov … sure but that does exactly what mymean3
definition does. I’m well aware of workarounds, I was just curious why it doesn’t seem to work.
– Konrad Rudolph
8 hours ago
Sorry for misunderstanding. Please see my answer below.
– Artem Sokolov
4 hours ago
add a comment |
Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)
– Konrad Rudolph
8 hours ago
Related: stackoverflow.com/questions/12982528/…
– Artem Sokolov
8 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 whatfunction
does.
– Artem Sokolov
8 hours ago
@ArtemSokolov … sure but that does exactly what mymean3
definition does. I’m well aware of workarounds, I was just curious why it doesn’t seem to work.
– Konrad Rudolph
8 hours ago
Sorry for misunderstanding. Please see my answer below.
– Artem Sokolov
4 hours ago
Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)
– Konrad Rudolph
8 hours ago
Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)
– Konrad Rudolph
8 hours ago
Related: stackoverflow.com/questions/12982528/…
– Artem Sokolov
8 hours ago
Related: stackoverflow.com/questions/12982528/…
– Artem Sokolov
8 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
8 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
8 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
8 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
8 hours ago
Sorry for misunderstanding. Please see my answer below.
– Artem Sokolov
4 hours ago
Sorry for misunderstanding. Please see my answer below.
– Artem Sokolov
4 hours ago
add a comment |
3 Answers
3
active
oldest
votes
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
.
1
I actually tried quoting the formals (as well as usingalist
), yet as you noticed this also doesn’t work.typeof(`for`)
is also “special”, but calling `for
` manually works.
– Konrad Rudolph
8 hours ago
1
Yeah becausefor
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 whatfunction()
takes.
– lionel
8 hours ago
Indeed. I just figured out that you can call it with a manually generatedpairlist
— but once again only indirectly because, as you said, there’s nopairlist
literal syntax.
– Konrad Rudolph
8 hours ago
add a comment |
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.)
add a comment |
After digging a little bit through the source code, here are a few observations:
The actual function creation is done by mkCLOSXP(). This is what gets called by
function() {}
, byas.function.default()
and by.Primitive("function")
(a.k.a.`function`
)as.function.default()
gets routed to do_asfunction(), which also calls CheckFormals(). However, it directly constructs these formals a few lines above that.As you pointed out, the other place where
CheckFormals()
gets called is insidedo_function()
. However, I don't thinkdo_function()
gets called by anything other than.Primitive("function")
, so this is the only situation whereCheckFormals()
is called on the user's input.CheckFormals()
does actually correctly validate apairlist
object.
You can check the last point yourself by running parts of the CheckFormals()
function using inline::cfunction
inline::cfunction( c(x="ANY"),
'Rprintf("is list?: %d\nTag1 OK?: %d\nTag2 OK?: %d\nTag3 NULL?: %d\n",
isList(x), TYPEOF(TAG(x)) == SYMSXP, TYPEOF(TAG(CDR(x))) == SYMSXP,
CDR(CDR(x)) == R_NilValue); return R_NilValue;' )( formals(mean) )
# is list?: 1
# Tag1 OK?: 1
# Tag2 OK?: 1
# Tag3 NULL?: 1
So, somewhere between you passing formals(means)
to .Primitive("function")
and it getting forwarded to CheckFormals()
by do_function()
, the argument loses its validity. (I don't know the R source well enough to tell you how that happens.) However, since do_function()
is only called by .Primitive("function")
, you don't encounter this situation with any other examples.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
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
.
1
I actually tried quoting the formals (as well as usingalist
), yet as you noticed this also doesn’t work.typeof(`for`)
is also “special”, but calling `for
` manually works.
– Konrad Rudolph
8 hours ago
1
Yeah becausefor
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 whatfunction()
takes.
– lionel
8 hours ago
Indeed. I just figured out that you can call it with a manually generatedpairlist
— but once again only indirectly because, as you said, there’s nopairlist
literal syntax.
– Konrad Rudolph
8 hours ago
add a comment |
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
.
1
I actually tried quoting the formals (as well as usingalist
), yet as you noticed this also doesn’t work.typeof(`for`)
is also “special”, but calling `for
` manually works.
– Konrad Rudolph
8 hours ago
1
Yeah becausefor
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 whatfunction()
takes.
– lionel
8 hours ago
Indeed. I just figured out that you can call it with a manually generatedpairlist
— but once again only indirectly because, as you said, there’s nopairlist
literal syntax.
– Konrad Rudolph
8 hours ago
add a comment |
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
.
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
.
answered 8 hours ago
lionellionel
2,9321518
2,9321518
1
I actually tried quoting the formals (as well as usingalist
), yet as you noticed this also doesn’t work.typeof(`for`)
is also “special”, but calling `for
` manually works.
– Konrad Rudolph
8 hours ago
1
Yeah becausefor
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 whatfunction()
takes.
– lionel
8 hours ago
Indeed. I just figured out that you can call it with a manually generatedpairlist
— but once again only indirectly because, as you said, there’s nopairlist
literal syntax.
– Konrad Rudolph
8 hours ago
add a comment |
1
I actually tried quoting the formals (as well as usingalist
), yet as you noticed this also doesn’t work.typeof(`for`)
is also “special”, but calling `for
` manually works.
– Konrad Rudolph
8 hours ago
1
Yeah becausefor
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 whatfunction()
takes.
– lionel
8 hours ago
Indeed. I just figured out that you can call it with a manually generatedpairlist
— but once again only indirectly because, as you said, there’s nopairlist
literal syntax.
– Konrad Rudolph
8 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
8 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
8 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
8 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
8 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
8 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
8 hours ago
add a comment |
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.)
add a comment |
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.)
add a comment |
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.)
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.)
answered 8 hours ago
Konrad RudolphKonrad Rudolph
397k1017861033
397k1017861033
add a comment |
add a comment |
After digging a little bit through the source code, here are a few observations:
The actual function creation is done by mkCLOSXP(). This is what gets called by
function() {}
, byas.function.default()
and by.Primitive("function")
(a.k.a.`function`
)as.function.default()
gets routed to do_asfunction(), which also calls CheckFormals(). However, it directly constructs these formals a few lines above that.As you pointed out, the other place where
CheckFormals()
gets called is insidedo_function()
. However, I don't thinkdo_function()
gets called by anything other than.Primitive("function")
, so this is the only situation whereCheckFormals()
is called on the user's input.CheckFormals()
does actually correctly validate apairlist
object.
You can check the last point yourself by running parts of the CheckFormals()
function using inline::cfunction
inline::cfunction( c(x="ANY"),
'Rprintf("is list?: %d\nTag1 OK?: %d\nTag2 OK?: %d\nTag3 NULL?: %d\n",
isList(x), TYPEOF(TAG(x)) == SYMSXP, TYPEOF(TAG(CDR(x))) == SYMSXP,
CDR(CDR(x)) == R_NilValue); return R_NilValue;' )( formals(mean) )
# is list?: 1
# Tag1 OK?: 1
# Tag2 OK?: 1
# Tag3 NULL?: 1
So, somewhere between you passing formals(means)
to .Primitive("function")
and it getting forwarded to CheckFormals()
by do_function()
, the argument loses its validity. (I don't know the R source well enough to tell you how that happens.) However, since do_function()
is only called by .Primitive("function")
, you don't encounter this situation with any other examples.
add a comment |
After digging a little bit through the source code, here are a few observations:
The actual function creation is done by mkCLOSXP(). This is what gets called by
function() {}
, byas.function.default()
and by.Primitive("function")
(a.k.a.`function`
)as.function.default()
gets routed to do_asfunction(), which also calls CheckFormals(). However, it directly constructs these formals a few lines above that.As you pointed out, the other place where
CheckFormals()
gets called is insidedo_function()
. However, I don't thinkdo_function()
gets called by anything other than.Primitive("function")
, so this is the only situation whereCheckFormals()
is called on the user's input.CheckFormals()
does actually correctly validate apairlist
object.
You can check the last point yourself by running parts of the CheckFormals()
function using inline::cfunction
inline::cfunction( c(x="ANY"),
'Rprintf("is list?: %d\nTag1 OK?: %d\nTag2 OK?: %d\nTag3 NULL?: %d\n",
isList(x), TYPEOF(TAG(x)) == SYMSXP, TYPEOF(TAG(CDR(x))) == SYMSXP,
CDR(CDR(x)) == R_NilValue); return R_NilValue;' )( formals(mean) )
# is list?: 1
# Tag1 OK?: 1
# Tag2 OK?: 1
# Tag3 NULL?: 1
So, somewhere between you passing formals(means)
to .Primitive("function")
and it getting forwarded to CheckFormals()
by do_function()
, the argument loses its validity. (I don't know the R source well enough to tell you how that happens.) However, since do_function()
is only called by .Primitive("function")
, you don't encounter this situation with any other examples.
add a comment |
After digging a little bit through the source code, here are a few observations:
The actual function creation is done by mkCLOSXP(). This is what gets called by
function() {}
, byas.function.default()
and by.Primitive("function")
(a.k.a.`function`
)as.function.default()
gets routed to do_asfunction(), which also calls CheckFormals(). However, it directly constructs these formals a few lines above that.As you pointed out, the other place where
CheckFormals()
gets called is insidedo_function()
. However, I don't thinkdo_function()
gets called by anything other than.Primitive("function")
, so this is the only situation whereCheckFormals()
is called on the user's input.CheckFormals()
does actually correctly validate apairlist
object.
You can check the last point yourself by running parts of the CheckFormals()
function using inline::cfunction
inline::cfunction( c(x="ANY"),
'Rprintf("is list?: %d\nTag1 OK?: %d\nTag2 OK?: %d\nTag3 NULL?: %d\n",
isList(x), TYPEOF(TAG(x)) == SYMSXP, TYPEOF(TAG(CDR(x))) == SYMSXP,
CDR(CDR(x)) == R_NilValue); return R_NilValue;' )( formals(mean) )
# is list?: 1
# Tag1 OK?: 1
# Tag2 OK?: 1
# Tag3 NULL?: 1
So, somewhere between you passing formals(means)
to .Primitive("function")
and it getting forwarded to CheckFormals()
by do_function()
, the argument loses its validity. (I don't know the R source well enough to tell you how that happens.) However, since do_function()
is only called by .Primitive("function")
, you don't encounter this situation with any other examples.
After digging a little bit through the source code, here are a few observations:
The actual function creation is done by mkCLOSXP(). This is what gets called by
function() {}
, byas.function.default()
and by.Primitive("function")
(a.k.a.`function`
)as.function.default()
gets routed to do_asfunction(), which also calls CheckFormals(). However, it directly constructs these formals a few lines above that.As you pointed out, the other place where
CheckFormals()
gets called is insidedo_function()
. However, I don't thinkdo_function()
gets called by anything other than.Primitive("function")
, so this is the only situation whereCheckFormals()
is called on the user's input.CheckFormals()
does actually correctly validate apairlist
object.
You can check the last point yourself by running parts of the CheckFormals()
function using inline::cfunction
inline::cfunction( c(x="ANY"),
'Rprintf("is list?: %d\nTag1 OK?: %d\nTag2 OK?: %d\nTag3 NULL?: %d\n",
isList(x), TYPEOF(TAG(x)) == SYMSXP, TYPEOF(TAG(CDR(x))) == SYMSXP,
CDR(CDR(x)) == R_NilValue); return R_NilValue;' )( formals(mean) )
# is list?: 1
# Tag1 OK?: 1
# Tag2 OK?: 1
# Tag3 NULL?: 1
So, somewhere between you passing formals(means)
to .Primitive("function")
and it getting forwarded to CheckFormals()
by do_function()
, the argument loses its validity. (I don't know the R source well enough to tell you how that happens.) However, since do_function()
is only called by .Primitive("function")
, you don't encounter this situation with any other examples.
answered 4 hours ago
Artem SokolovArtem Sokolov
4,86222038
4,86222038
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
var $window = $(window),
onScroll = function(e) {
var $elem = $('.new-login-left'),
docViewTop = $window.scrollTop(),
docViewBottom = docViewTop + $window.height(),
elemTop = $elem.offset().top,
elemBottom = elemTop + $elem.height();
if ((docViewTop elemBottom)) {
StackExchange.using('gps', function() { StackExchange.gps.track('embedded_signup_form.view', { location: 'question_page' }); });
$window.unbind('scroll', onScroll);
}
};
$window.on('scroll', onScroll);
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
Duplicate of stackoverflow.com/q/53218422/1968 (I swear I found this afterwards)
– Konrad Rudolph
8 hours ago
Related: stackoverflow.com/questions/12982528/…
– Artem Sokolov
8 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
8 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
8 hours ago
Sorry for misunderstanding. Please see my answer below.
– Artem Sokolov
4 hours ago