Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
In scala we have the concept of an implicit variable or parameter, which can be handy, although sometimes confusing, in many cases. The question is:
Is there something like implicit variables in R?
If there is not, would be possible to achieve the same behavior as scala implicit parameters while calling some function in R?
Moved from comments.
If I understand this correctly an implicit parameter to a function is a function argument which, if not specified when calling the function, defaults to a default associated with that argument's type and only one such default can exist for all instances of that type at any one time; however, arguments in R don't have types -- its all dynamic. One does not write f <- function(int x) ... but just f <- function(x) ... .
I suppose one could have a convention that integerDefault is the default value associated with the integer type:
f <- function(x = integerDefault) x
g <- function(y = integerDefault) y + 1L
integerDefault <- 0L
f()
## [1] 0
g()
## [1] 1
There is nothing that will prevent you from passing a double to f and g but
if you don't pass anything then you get the default integer which seems similar to scala and
there can only be one such default at any point since they all go by the same name which seems similar to scala. Also
if no value is assigned to integerDefault then the function fails which is also similar to scala.
Note that integerDefault will be looked up lexically -- not in the caller.
I'm not sure what the desired behavior is. From the first paragraph of the site you link, it seems to be simply a default parameter setting for parameters not provided to the function. This is used in R all the time:
> f <- function(x=10) print(x)
> f()
[1] 10
Is that what you mean?
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I am learning the Julia language and would like to know which implementation is likely to have better performance.
In answer to question How to check if a string is numeric Julia last answer is
isintstring(str) = all(isdigit(c) for c in str)
This code works well, but it could be rewritten
isintstring = str -> mapreduce(isnumeric, &, collect(str))
Is the rewrite better or worse? or just different? The Julia Style Guide does not seem to provide guidance.
Edit: As originally expressed, this question was blocked for seeking opinion not facts. I have rephrased it in gratitude for the three outstanding and helpful answers the original question received.
If you are using collect there is probably something wrong with your code, especially if it's a reduction. So your second method needlessly allocates, and, furthermore, it does not bail out early, so it will keep going to the end of the string, even if the first character fails the test.
If you benchmark the performance, you will also find that mapreduce(isnumeric, &, collect(str)) is an order of magnitude slower, and that is without considering early bailout.
In general: Don't use collect(!), and bail out early if you can.
The idiomatic solution in this case is
all(isdigit, str)
Edit: Here are some benchmarks:
jl> using BenchmarkTools, Random
jl> str1 = randstring('0':'9', 100)
"7588022864395669501639871395935665186290847293742941917566300220720077480508740079115268449616551087"
jl> str2 = randstring('a':'z', 100)
"xnmiemobkalwiiamiiynzxxosqoavwgqbnxhzaazouzbfgfbiodsmhxonwkeyhxmysyfojpdjtepbzqngmfarhqzasppdmvatjsz"
jl> #btime mapreduce(isnumeric, &, collect($str1))
702.797 ns (1 allocation: 496 bytes)
true
jl> #btime all(isdigit, $str1)
82.035 ns (0 allocations: 0 bytes)
true
jl> #btime mapreduce(isnumeric, &, collect($str2))
702.222 ns (1 allocation: 496 bytes) # processes the whole string
false
jl> #btime all(isdigit, $str2)
3.500 ns (0 allocations: 0 bytes) # bails out early
false
The rewrite is definitely worse. Slower, less elegant and more verbose.
Another edit: I only noticed now that you are using isnumeric with mapreduce, but isdigit with all. isnumeric is more general and much slower than isdigit so that also makes a big difference. If you use isdigit instead, and remove collect, the speed difference isn't so big for numeric strings, but it still does not bail out early for non-numeric strings, so the best solution is still clearly all(isdigit, str).
Part of your question is about named vs anonymous functions. In the first case, you created a function via its first method and assigned it to an implicitly const variable isintstring. The function object itself also gets the name isintstring, as you can see in its type. You can't reassign the variable isintstring:
julia> isintstring(str) = all(isdigit(c) for c in str)
isintstring (generic function with 1 method)
julia> typeof(isintstring)
typeof(isintstring)
julia> isintstring = str -> mapreduce(isnumeric, &, collect(str))
ERROR: invalid redefinition of constant isintstring
julia> isintstring = 1
ERROR: invalid redefinition of constant isintstring
Now let's restart the REPL and switch the order to start at the second case. The second case creates an anonymous function, then assigns it to a variable isintstring. The anonymous function gets a generated name that can't be a variable. You can reassign isintstring as long as you're not trying to declare it const, which includes method definitions.
julia> isintstring = str -> mapreduce(isnumeric, &, collect(str))
#5 (generic function with 1 method)
julia> typeof(isintstring)
var"#5#6"
julia> isintstring(str) = all(isdigit(c) for c in str)
ERROR: cannot define function isintstring; it already has a value
julia> isintstring = 1
1
It's far more readable to add methods to a named function, all you have to do is define another method using the const name, like isintstring(int, str) = blahblah().
It's actually possible to add methods to an anonymous function, but you have to do something like this: (::typeof(isintstring))(int, str) = blahblah(). The variable isintstring may not always exist, and the anonymous function can have other references such as func_array[3], in which case you'll have to write (::typeof(func_array[3]))(int, str) = blahblah(). I think you'll agree that a const name is far clearer.
Anonymous functions tend to be written as arguments in method calls like filter(x -> x%3==0, A) where the anonymous function only needs 1 method. In such a case, creating a const-named function would only bloat the function namespace and force a reader to jump around the code. In fact, do-blocks exist to allow people to write a multiple-line anonymous function as a first argument without bloating the method call.
Just like Gandhi said "My life is my message", Julia says "My code is my guide". Julia makes it very easy to inspect and explore standard and external library code, with #less, #edit, methods, etc. Guides for semantic style are rather hard to pin down (as opposed to those for syntactic style), and Python is rather the exception than the rule when it comes to the amount of documentation and emphasis surrounding this. However, reading through existing widely used code is a good way to get a feel for what the common style is.
Also, the Julialang Discourse is a more useful resource than search engines seem to give it credit for.
Now, for the question in your title, "using functional idioms" is a broad and vague descriptor - Julian style doesn't generally place high emphasis on avoiding mutations (except for performance reasons), for eg., and side effects aren't something rare and smelly. Higher order functions are pretty common, though explicit map/reduce are only one part of the arsenal of tools that includes broadcasting, generators, comprehensions, functions that implicitly do the mapping for you (sum(f, A::AbstractArray; dims): "Sum the results of calling function f on each element of an array over the given dimensions"), etc.
There's also another factor to consider: performance trumps (almost) anything else. As the other answers have hinted at, which style you go for can be a matter of optimizing for performance. Code that starts out reading functional can have parts of it start mutating its inputs, parts of it become for loops, etc., as and when necessary for performance. So it's not uncommon to see a mixture of these different style in the same package or even the same file.
they are the same. and if you just look at it...clearly the first one is cleaner even shorter
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I have an question about https://github.com/pyrocat101/opal/blob/master/opal.ml.
At line 105, I replaced the definition of many with let rec many x = option [] (x <~> many x);;. Then, I got the following error message:
Stack overflow during evaluation (looping recursion?).
However, these two codes seem to be same. Why?
I used OCaml version 4.12.0.
OCaml is an eager language. Thus in
let rec many x = option [] (x <~> many x)
the inner expression many x is fully evaluated as soon as the argument x is provided. Consequently, evaluating many x requires to evaluate many x and the function loops.
The smallest fix is to avoid hiding the input argument of many:
let rec many x input = option [] (x <~> many x) input
(In other words, point-free style is not consequence free in an eager and mutable language.)
Since the inner many x is a closure here, its execution will be suspended breaking the loop.
Similarly, the inlined version
let rec many x = option [] (x >>= fun r -> many x >>= fun rs -> return (r :: rs))
achieve the same result by moving the inner expression many x in an anonymous function fun r -> ....
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I've been trying to a adopt a functional language into my programing. I use C# and rely heavily on LINQ and other functional constructs. Currently I'm focusing on Elm.
One thing that continues to bother me is the lack of parenthesis in functions. Math expressions use them:
f(z) = ln(z) + 1
Yet in many functional languages this is written as:
f z = ln z + 1
It this just a style thing or is there something deeper going here?
Functional languages take root in lambda calculus, which do not use parentheses for functional application.
It is a syntactical thing sure, but the way that functions are applied it makes sense to leave parentheses out since a function with two arguments first applies the left most argument to the function and output a function that is used by the second argument. For example the function you are used to:
add(x,y) { return x + y }
in functional terms is
add x y
add :: Int->Int->Int
where the intermediate step after applying x returns another function
add 4 -- returns a function that will return 4 + y, when y is applied
add 4 :: Int->Int
To a certain degree this helps avoid confusion with the programming languages you are used to where add(4) would throw an error. It reads more like math with associativity, ((add x) y).
One of the reasons to avoid parenthesis in function application is currying.
If you code f x y (like you should in Ocaml) then f x is simply a curryfication. If you don't have such a notation, you need an explicit lambda (or some anonymous function notation), like in Scheme (lambda (y) (f x y))
On the other hand, languages with currying often implicitly interpret f x y as (f x) y and then their implementation need to optimize that to avoid creating useless temporary closures.
I have mixed feelings w.r.t. currying. It is perhaps not often useful (but you'll need it sometimes), and a short anonymous function notation is perhaps enough
Alot of the notation we see is influenced my mathematics, and I've seen atleast two types of function notation within maths to show domain to codomain mapping.
f(x) = x + 1 and x -> x + 1
So I guess maybe the languages without parenthesis derive from the later maybe
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am starting to use the RProvider. For starters, I have just tried to evaluate functions in different ways. It seems I have already run into problems (perhaps a problem with my understanding of how the RProvider works). I have run the same function in four different ways, which I thought to be equivalent. However, the four example provides me with two different results.
R.sapply(R.c(1,2,3,4,5), R.eval(R.parse(text="mean"))).GetValue<float[]>()
// val it : float [] = [|1.0; 2.0; 3.0; 4.0; 5.0|]
R.sapply(R.c(1,2,3,4,5),"mean").GetValue<float[]>()
// val it : float [] = [|1.0; 2.0; 3.0; 4.0; 5.0|]
R.mean(R.c(1,2,3,4,5)).GetValue<float[]>()
// val it : float [] = [|3.0|]
R.eval(R.parse(text="mean(c(1,2,3,4,5))")).GetValue<float[]>()
// val it : float [] = [|3.0|]
Can anyone tell me why this is? My own guess is that R.sapply applies the given function element-wise. But how do I get around this?
do.call() is the function in R for "applying" a function to a list of parameters (a slightly different meaning from applying or mapping a function over a vector or list of values, which is what the *apply family does).
The R function for what you want would be
do.call("mean",list(c(1,2,3,4,5)))
According to the comments (I don't speak F# myself), the F# analogue would be:
R.do_call("mean", R.list(R.c(1,2,3,4,5)))
This question already has answers here:
How to use R's ellipsis feature when writing your own function?
(5 answers)
Closed 9 years ago.
I have seen several related questions to the ellipses, but I am still not sure what it means to pass "..." as an argument. I am completely new to R, but am trying to understand what the following means:
forest <- randomForest(x = train.x, y = train.y, ...)
The typical use of ... argument is when a function say f internally calls a function g and uses ... to pass arguments to g without explicitly listing all those arguments as its own formal arguments. One may want to do this, for example, when g has a lot of optional arguments that may or may not be needed by the user in the function f. Then instead of adding all those optional arguments to f and increasing complexity, one may simply use ....
What it means, as you asked, is the function f will simply ignore these and pass them on to g. The interesting thing is that ... may even have arguments that g does not want and it will ignore them too, for say h if it needed to use ... too. But also see this so post for a detailed discussion.
For example consider:
f <- function (x, y, ...) {
# do something with x
# do something with y
g(...) # g will use what it needs
h(...) # h will use that it needs
# do more stuff and exit
}
Also, see here in the intro-R manual for an example using par.
Also, this post shows how to unpack the ... if one was writing a function that made use of it.