cross-parsing in function input parameters - r

This really falls under the purview of "Don't DO that!" ,but..
I wrote this to see what would happen.
circit <-function(x=deparse(substitute(y)),y=deparse(substitute(x)))
{
return(list(x=x,y=y))
}
Two examples:
> circit()
$x
[1] "deparse(substitute(x))"
$y
[1] "deparse(substitute(y))"
> circit(3)
$x
[1] 3
$y
[1] "3"
Notice the subtle swap of "x" and "y" in the output.
I can't follow the logic, so can someone explain how the argument parser handles this absurd pair of default inputs? (the second case is easy to follow)

The key thing to understand/remember is that formal arguments are promise objects, and that substitute() has special rules for how it evaluates promise objects. As explained in ?substitute, it returns their expression slot, not their value:
Substitution takes place by examining each component of the parse
tree as follows: If it is not a bound symbol in ‘env’, it is
unchanged. If it is a promise object, i.e., a formal argument to
a function or explicitly created using ‘delayedAssign()’, the
expression slot of the promise replaces the symbol. If it is an
ordinary variable, its value is substituted, unless ‘env’ is
‘.GlobalEnv’ in which case the symbol is left unchanged.
To make this clearer, it might help to walk through the process in detail. In the first case, you call circuit() with no supplied arguments, so circuit() uses the default values of both x= and y=.
For x, that means its value is gotten by evaluating deparse(substitute(y)). The symbol y in that expression is matched by the formal argument y, a promise object. substitute() replaces the symbol y with its expression slot, which holds the expression deparse(substitute(x)). Deparsing that expression returns the text string "deparse(substitute(x))", which is what gets assigned to x's value slot.
Likewise, the value of y is gotten by evaluating the expression deparse(substitute(x)). The symbol x is matched by the formal argument x, a promise object. Even though the value of x is something else, its expression slot is still deparse(substitute(y)), so that's what's returned by evaluating substitute(x). As a result, deparse(substitute(x)) returns the string "deparse(substitute(y))"

Related

Erlang Understanding recursion: Find if substring is prefix of string recursively

I want to understand this implementation of finding a prefix in a string, which is implemented without using any built-in list functions, but using recursion to iterate through the string.
attempt:
checkStringPrefix([C|StringTail],[C|LookupTail]) ->
checkStringPrefix(StringTail,LookupTail);
checkStringPrefix(_,[]) ->
"***";
checkStringPrefix(_String,_Lookup) ->
"".
It works, the function calls itself recursively separating the first Character from the Tail.
Example calls:
1> stringUtil:checkStringPrefix("test xxxxx", "test").
"***"
2> stringUtil:checkStringPrefix("test xxxxx", "testtt").
[]
In the case of two non equal characters, the last function variant gets called.
I dont fully grasp this concept, I would appreciate an explanation. I understand the process of recursive iteration, what I dont understand is why the second variants gets called in the correct moment.
Consider what happens when passing either single character strings or empty strings as arguments:
Passing "a" and "a": this calls the first clause of checkStringPrefix/2 because explicitly matches the first elements of both arguments in its function head, which also enforces that neither argument can be the empty list. This clause calls the function recursively, and since neither argument has a tail, the second function clause gets called because the second argument matches the empty list, so the result is "***".
Passing "a" and "b": this won't call the first clause because the first elements do not match, and it won't call the second clause because the second argument isn't the empty list. It therefore calls the third clause, so the result is "".
Passing "" and "": this won't call the first clause because both arguments are empty lists; it calls the second clause because the second argument matches the empty list, so the result is "***". In fact, since the second clause treats its first argument as a don't-care, this same analysis applies even if the first argument is non-empty.
Passing "" and "a": this won't call the first clause because the first argument is empty, and it won't call the second clause because the second argument is not empty, so it calls the third clause and the result is "".
No matter the lengths of the two argument strings, these are the choices for each invocation.
To answer your specific question about when the second function clause gets called, it happens any time the second argument is the empty list because of the specific match for that case in the function head, and that function head also ignores the first argument. Matching occurs in order of declaration; the first function clause requires both arguments to have at least one element, so when the second argument is the empty list, it can't match the first clause and so matches the second clause.

Why does switch("d", a = 1, b = 2) not give any warning, error, or output?

Clearly, switch("d", a = 1, b = 2) does not have a default value, a value matching "d", or any reason to return anything. The documentation for switch tells us that "A warning is signaled if no alternatives are provided, as this is usually a coding error". However, when I run switch("d", a = 1, b = 2), nothing happens at all. I get no outputs, warnings, or errors. What have I misunderstood about R's switch? I expected a warning.
As already stated in the comments by #MrFlick, the warning is returned when you don't provide alternatives and not if the expression ends up having a value which is different from the alternatives you provided (that looks like your interpretation).
The doc mentions this warning because of the signature of switch:
> switch
function (EXPR, ...) .Primitive("switch")
You see the ...; they are optional additional arguments. You usually don't get errors or warnings if you don't provide additional arguments to a function accepting .... switch is pretty uncharacteristic in this behaviour and that's why the warning is documented.
Another point is that, in your example, you do get an output: it's NULL, returned invisibly, which is clearly documented in the "Value" section:
The value of one of the elements of ‘...’, or ‘NULL’, invisibly
(whenever no element is selected).
The result has the visibility (see ‘invisible’) of the element
evaluated.
A call to switch() evaluates to NULL if none of the arguments get matched to the supplied value. If EXPR evaluates to a character you can specify a default value by including an unnamed argument. If EXPR evaluates to integer, numeric or logical you cannot specify a default for it. You can always use a different conditional operator if this is too limiting.

Method for ascertaining if a value has been given in a function call

I am writing a function, there is one part of the function that can either accept a single value, or a vector, or keeps the default if nothing is specified in the function call.
In the code below "a" is given the default of 0 and then in the function there is an if statement to see if "a" is still 0 or if a value has been assigned to it.
If I call the function using a single value, a vector, or leave it blank it prints the expected result. If the vector that is given to it has a length of more than 1, I get the expected warning message (despite the function still working):
' the condition has length > 1 and only the first element will be used'
My query is therefore what is the best way to test to see if "a" has been left blank and if it has been left blank to run a piece of code (in this case to print "default") or if "a" has been given a value then to run some other code (in this case to print "value given") without having the warning message if a vector is assigned to "a" when I call the function.
The example code is as below:
#Function
ExampleFunction<-function(a=0)
{
if (a==0)
print ("default")
else{print("value given")}
}
#Run function using a vector which gives the warning message
abc<-c(1,2,3)
ExampleFunction(abc)
The warning is seen because in evaluating an if statement, R needs a single Boolean,
not a vector of Booleans, hence the warning seen is seen when you try to send abc <- c(1,2,3) only the first value of vector abc, which is 1 gets assigned to the parameter a in the function. I would suggest you to read about the "Named arguments" in R.
In the meanwhile you could put a check of length of parameter a along with its value to see whether or not it has been assigned to a non-zero value when the function is called. Hope it helps!
Links about Named Arguments: Function default arguments and named values
https://www.r-bloggers.com/r-tip-force-named-arguments/
https://www.safaribooksonline.com/library/view/r-in-a/9781449358204/ch09s05.html

String object value evaluated as expression

I have a string variable and I would like to evaluate its value as an expression using expression()
Example:
>expression("Text")
expression("Text")
>a <- "Text"
>expression(a)
expression(a)
I want to do something to make expression(a) evaluate to expression("Text").
maybe you could write why you need it?
Because what you want makes no sense to me.
Type
?expression
and you will see:
expression returns a vector of type "expression" containing its arguments (unevaluated)
You would have to rewrite the function to make it do what you want.
If you wanted to fake it, you would do something like this (not recommended :) ):
paste("expression(", a, ")", sep="")
edit:
From ?expression you can see at the bottom, that as.expression(a) is what you needed
as.expression attempts to coerce its argument into an expression object

The arcane formals(function(x){})$x

What is the object formals(function(x){})$x?
It's found in the formals of a function, bound to arguments without default value.
Is there any other way to refer to this strange object? Does it have some role other than representing an empty function argument?
Here are some of its properties that can be checked in the console:
> is(formals(function(x){})$x)
[1] "name" "language" "refObject"
> formals(function(x){})$x
> as.character(formals(function(x){})$x)
[1] ""
EDIT: Here are some other ways to get this object:
alist(,)[[1]]
bquote()
quote(expr=)
Background: What is formals(function(x) {})?
Well, to start with (and as documented in ?formals) , formals(function(x) {}) returns a pairlist:
is(formals(function(x){}))
# [1] "pairlist"
Unlike list objects, pairlist objects can have named elements that contain no value -- a very nice thing when constructing a function that has a possibly optional formal argument. From ?pairlist:
tagged arguments with no value are allowed whereas ‘list’ simply ignores them.
To see the difference, compare alist(), which creates pairlists, with list() which constructs 'plain old' lists:
list(x=, y=2)
# Error in list(x = , y = 2) : argument 1 is empty
alist(x=, y=2)
# $x
#
# $y
# [1] 2
Your question: What is formals(function(x) {})$x?
Now to your question about what formals(function(x) {})$x is. My understanding is in some sense its real value is the "empty symbol". You can't, however, get at it from within R because the "empty symbol" is an object that R's developers -- very much by design -- try to entirely hide from R users. (For an interesting discussion of the empty symbol, and why it's kept hidden, see the thread starting here).
When one tries to get at it by indexing an empty-valued element of a pairlist, R's developers foil the attempt by having R return the name of the element instead of its verbotten-for-public-viewing value. (This is, of course, the name object shown in your question).
It's a name or symbol, see ?name, e.g.:
is(as.name('a'))
#[1] "name" "language" "refObject"
The only difference from your example is that you can't use as.name to create an empty one.

Resources