Are there any performance issues with nested functions in F#?
If I have a function which is called on every item in an array, and this function has nested inner functions, does that mean on every iteration it needs to declare, create and assign all the inner nested functions?
Seems awfully inefficient but I really like the readability of nested functions as opposed to private outer functions.
Nested functions are extracted by the compiler into classes that inherit from FSharpFunc, nested within the module or type where their parent function is defined in. So the compiler essentially does for you what you would otherwise do by hand, with outer private functions.
All that happens at runtime is instantiation of these objects. There is a cost to it compared to executing inline code, but I suppose drastically less than what you anticipated in your mental model.
It does leave you with an extra object to GC though. Would this object instantiation matter in a tight loop then? In a naive implementation, where the function object is instantiated anew in each iteration, perhaps yes. But F# compiler is smarter than that and typically instantiates the functions used in the body of the loop once, outside the loop. So again, the cost is probably as low as it can be.
When in serious doubt, consult ILSpy and benchmark. As a rule of thumb - don't fret over it and just use nested functions.
Related
My understanding of closures so far is that they combine "open" functions with their surrounding scope, essentially making them closed expressions.
I've seen several examples of how this is implemented in Javascript, most of them using nested functions to create an outer and inner scope and show how the language creates a "snapshot" of the surrounding scope for the inner function.
However, I know there's languages that don't implement closures, for example C. In this particular case, there's also no (native) support for nested functions, so it seems that it is not possible to replicate the "inner" and "outer" cases from JavaScript - and as far as I know, due to this, not having closures doesn't become a important problem.
However, would it be possible for a language to have nested functions and still have no closures? Or does one implies on the another?
The concept of a "closure" is only meaningful when a function can be executed from outside of the scope in which it's declared.
In languages without first-class functions, i.e., where functions can't be passed around or assigned to variables, you could still have nested functions, but they couldn't be used as closures.
Here is the area to play scoping concept in javascript...as you know in java we use class components mostly then we achieve parents functionality's using inheritance but javascript is a weird language...so we can't achieve closures with out nested function
I've developed the habit of declaring almost all of my modules' functions with a colon rather than a dot, but I don't use much OOP and almost never use "self".
It seems redundant that self gets passed as a parameter every time I call a function, especially if the tables are quite large.
Is there any performance impact with this? Is it worth changing all my function declarations to use a dot?
There's not much of a performance impact to passing a single additional table reference to a function. This is regardless of the table size, as the table doesn't get copied.
Rather than performance, this seems to be a question of programming style. It is very uncommon to use the colon-syntax for module functions, as this idiom is clearly meant to be used for actual method calls. As such, a library that uses it where it's not necessary will look very confusing to any other Lua programmer.
Is it possible to check if a function was declared as recursive, i.e. with let rec?
I have a memoize function, but it doesn't work with arbitrary recursive functions. I would like to give an error if the user calls it with such a function. (Feel free to tell me if this is a bad way to deal with errors in F#)
F# code is compiled to .NET Common Intermediate Language. F# rec keyword is just a hint to F# compiler that makes identifier that is being defined available in the scope of the function. So I believe that there is no way to find out at runtime that the function is declared as recursive.
However you could use System.Diagnostic.StackTrace class (https://msdn.microsoft.com/en-us/library/system.diagnostics.stacktrace.aspx) to get and analyze stack frames at runtime. But accessing stack information have significant performance impact (I'm assuming that your memoization function is for speeding up program performance). Also stack information could be different in Debug and Release versions of your program as the compiler can make optimizations.
I don't think it can be done in a sensible and comprehensive manner.
You might want to reevaluate your problem though. I assume your function "doesn't work" with recursive functions, because it only memoizes the first call, and all the recursive calls go to the non-memoized function? Depending on your scenario, it may not be a bad thing.
Memoization trades off memory for speed. In a large system, you might not want to pay the cost of memoizing intermediate results if you only care about the final one. All those dictionaries add up over time.
If you however particularly care about memoizing a recursive function, you can explicitly structure it in a way that would lend itself to memoization. See linked threads.
So my answer would be that a memoize function shouldn't be concerned about recursion at all. If the user wants to memoize a recursive function, it falls to him to understand the trade-offs involved, and structure the function in a way that would allow intermediate calls to be memoized if that's what he requires.
Rascal feels both functional and imperative. It support assignments. But it is also claimed to be pure. So I guess features like assignments are simulated. Then what is the imperative model of Rascal, the Haskell way via monads or the Clean way via uniqueness?
Rascal is only pure in the sense that its data instances are immutable and in the sense that everything (function parameter passing, assignment, calling Java methods) is pass-by-value. There is no aliasing possible (*).
Even with globals, or comparably closures that capture stack locations, all assignments are by value but they are real assignments. I.o.w. there are no monads, no uniqueness typing, just plain and direct side-effects, but no aliasing and no mutation.
What makes side-effects into Java code in Rascal "safe" is that sending/receiving data is always via (de)serializing an immutable value, i.e. you really can not get a reference to stateful data into Rascal via Java (unless you start encoding pointers with int or loc :-)
(*) you can create a form of aliasing using closures, but you do have to jump through a few high hoops first to do such a thing.
i am kinda confused reading the definition between the two. Can they actually intersect in terms of definition? or am i completely lost? Thanks.
Closures, as the word tends to be used, are just functions (or blocks of code, if you like) that you can treat like a piece of data and pass to other functions, etc. (the "closed" bit is that wherever you eventually call it, it behaves just as it would if you called it where it was originally defined). A monad is (roughly) more like a context in which functions can be chained together sequentially, and controls how data is passed from one function to the next.
They're quite different, although monads will often use closures to capture logic.
Personally I would try to get solid on the definition of closures (essentially a piece of logic which also captures its environment, i.e. local variables etc) before worrying about monads. They can come later :)
There are various questions about closures on Stack Overflow - the best one to help you will depend on what platform you're working on. For instance, there's:
What are closures in .NET?
Function pointers, closures and lambda
Personally I'm only just beginning to "grok" monads (thanks to the book I'm helping out on). One day I'll get round to writing an article about them, when I feel I understand them well enough :)
A "closure" is an object comprising 1) a function, and 2) the values of its free variables where it's constructed.
A "monad" is a class of functions that can be composed in a certain way, i.e. by using associated bind and return higher-order function operators, to produce other functions.
I think monads are a little more complicated than closures because closures are just blocks of code that remember something from the point of their definitions and monads are a construct for "twisting" the usual function composition operation.