Function variable and an array of functions in Chapel - function

In the following code, I'm trying to create a "function pointer" and an array of functions by regarding function names as usual variables:
proc myfunc1() { return 100; }
proc myfunc2() { return 200; }
// a function variable?
var myfunc = myfunc1;
writeln( myfunc() );
myfunc = myfunc2;
writeln( myfunc() );
// an array of functions?
var myfuncs: [1..2] myfunc1.type;
writeln( myfuncs.type: string );
myfuncs[ 1 ] = myfunc1;
myfuncs[ 2 ] = myfunc2;
for fun in myfuncs do
writeln( fun() );
which seems to be working as expected (with Chapel v1.16)
100
200
[domain(1,int(64),false)] chpl__fcf_type_void_int64_t
100
200
So I'm wondering whether the above usage of function variables is legitimate? For creating an array of functions, is it usual to define a concrete function with desired signature first and then refer to its type (with .type) as in the above example?
Also, is it no problem to treat such variables as "usual" variables, e.g., pass them to other functions as arguments or include them as a field of class/record? (Please ignore these latter questions if they are too broad...) I would appreciate any advice if there are potential pitfalls (if any).

This code is using first class function support, which is prototype/draft in the Chapel language design. You can read more about the prototype support in the First-class Functions in Chapel technote.
While many uses of first-class functions work in 1.16 and later versions, you can expect that the language design in this area will be revisited. In particular there isn't currently a reasonable answer to the question of whether or not variables can be captured (and right now attempting to do so probably results in a confusing error). I don't know in which future release this will change, though.
Regarding the myfunc1.type part, the section in the technote I referred to called "Specifying the type of a first-class function" presents an alternative strategy. However I don't see any problem with using myfunc1.type in this case.
Lastly, note that the lambda support in the current compiler actually operates by creating a class with a this method. So you can do the same - create a "function object" (to borrow a C++ term) - that has the same effect. A "function object" could be a record or a class. If it's a class, you might use inheritance to be able to create an array of objects that can respond to the same method depending on their dynamic type. This strategy might allow you to work around current issues with first class functions. Even if first-class-function support is completed, the "function object" approach allow you to be more explicit about captured variables. In particular, you might store them as fields in the class and set them in the class initializer. Here is an example creating and using an array of different types of function objects:
class BaseHandler {
// consider these as "pure virtual" functions
proc name():string { halt("base name called"); }
proc this(arg:int) { halt("base greet called"); }
}
class HelloHandler : BaseHandler {
proc name():string { return "hello"; }
proc this(arg:int) { writeln("Hello ", arg); }
}
class CiaoHandler : BaseHandler {
proc name():string { return "ciao"; }
proc this(arg:int) { writeln("Ciao ", arg); }
}
proc test() {
// create an array of handlers
var handlers:[1..0] BaseHandler;
handlers.push_back(new HelloHandler());
handlers.push_back(new CiaoHandler());
for h in handlers {
h(1); // calls 'this' method in instance
}
}
test();

Yes, in your example you are using Chapel's initial support for first-class functions. To your second question, you could alternatively use a function type helper for the declaration of the function array:
var myfuncs: [1..2] func(int);
These first-class function objects can be passed as arguments into functions – this is how Futures.async() works – or stored as fields in a record (Try It Online! example). Chapel's first-class function capabilities also include lambda functions.
To be clear, the "initial" aspect of this support comes with the caveat (from the documentation):
This mechanism should be considered a stopgap technology until we have developed and implemented a more robust story, which is why it's being described in this README rather than the language specification.

Related

How does ecmascript-6 Function.prototype.bind() handle a class constructor?

I totally missed the ES6 revolution and I'm returning to JavaScript after 7 years, to find a host of very strange things happening.
One in particular is the way Function.prototype.bind() handles class constructors.
Consider this:
// an ES6 class
class class1 {
constructor (p) {
this.property = p;
}
}
var class2 = class1.bind(passer_by);
var class3 = class2.bind(passer_by,3);
class2() // exception, calling a constructor like a function
class3() // idem
console.log (new class1(1)) // class1 {property: 1}
console.log (new class2(2)) // class1 {property: 2}
console.log (new class3() ) // class1 {property: 3}
// An ES5-style pseudo-class
function pseudoclass1 (p) {
this.property = p;
}
var property = 0;
var passer_by = { huh:"???" }
var pseudoclass2 = pseudoclass1.bind(passer_by);
var pseudoclass3 = pseudoclass1.bind(passer_by,3);
pseudoclass1(1); console.log (property) // 1 (this references window)
pseudoclass2(2); console.log (passer_by) // Object { huh: "???", property: 2 }
pseudoclass3() ; console.log (passer_by) // Object { huh: "???", property: 3 }
console.log (new pseudoclass1(1)) // pseudoclass1 {property: 1}
console.log (new pseudoclass2(2)) // pseudoclass1 {property: 2}
console.log (new pseudoclass3() ) // pseudoclass1 {property: 3}
Apparently class2 and class3 are identified as constructors, and class3 is a partial application of class1 that can generate instances with a fixed value of the first parameter.
On the other hand, though they can still act as (poor man's) constructors, the ES5-style functions are indeed served the value of this set by bind(), as can be seen when they act on the hapless passer_by instead of clobbering global variables as does the unbound pseudoclass1.
Obviously, all these constructors somehow access a value of this that allows them to construct an object. And yet their this are supposedly bound to another object.
So I guess there must be some mechanism at work to feed the proper this to a constructor instead of whatever parameter was passed to bind().
Now my problem is, I can find bits of lore about it here and there, even some code apparently from some version of Chrome's V8 (where the function bind() itself seems to do something special about constructors), or a discussion about a cryptic FNop function inserted in the prototype chain, and, if I may add, the occasional piece of cargo cult bu[beep]it.
But what I can't find is an explanation about what is actually going on here, a rationale as to why such a mechanism has been implemented (I mean, with the new spread operator and destructuring and whatnot, wouldn't it be possible to produce the same result (applying some arguments to a constructor) without having to put a moderately documented hack into bind()?), and its scope (it works for constructors, but are there other sorts of functions that are being fed something else than the value passed to bind() ?)
I tried to read both the 2015 and 2022 ECMA 262 specifications, but had to stop when my brains started leaking out of my ears. I traced back the call stack as:
19.2.3.2
9.4.1.3
9.4.1.2
7.3.13
where something is said about constructors, in a way: "If newTarget is not passed, this operation is equivalent to: new F(...argumentsList)". Aha. So this pseudo-recursive call should allow to emulate a new somehow... Erf...
I'd be grateful if some kind and savvy soul could give me a better idea of what is going on, show me which part(s) of the ECMA specs deal with this mechanism, or more generally point me in the right direction.
I'm tired of banging my head against a wall, truth be told. This bit of Chrome code that seems to indicate bind() is doing something special for constructors is just incomprehensible for me. So I would at least like an explanation about it, if everything else fails.
This doesn't have anything to do with classes specifically but with how .bind works.
You have been on the right track. The most relevan section here is 9.4.1.2.
Just as a recap: ECMAScript distinguishes between two types of functions: callable functions and constructable functions. Function expressions/declarations are both, whereas e.g. class constructors are only constructable and arrow functions are only callable.
In the specification this is represented by function's internal [[Call]] and [[Construct]] methods.
new will trigger the invocation of the internal [[Construct]] method.
.bind will return a new function object with different implementations for [[Call]] and [[Construct]]. So what does the "bound" version of [[Construct]] look like?
9.4.1.2 [[Construct]] ( argumentsList, newTarget )
When the [[Construct]] internal method of a bound function exotic object, F that was created using the bind function is called with a list of arguments argumentsList and newTarget, the following steps are taken:
Let target be F.[[BoundTargetFunction]].
Assert: IsConstructor(target) is true.
Let boundArgs be F.[[BoundArguments]].
Let args be a new list containing the same values as the list boundArgs in the same order followed by the same values as the list argumentsList in the same order.
If SameValue(F, newTarget) is true, set newTarget to target.
Return ? Construct(target, args, newTarget).
What this means is that the bound constructor will "construct" the original function (F.[[BoundTargetFunction]]) with the bound arguments (F.[[BoundArguments]]) and the passed in arguments (argumentsList), but it completely ignores the bound this value (which would be F.[[BoundThis]]).
but are there other sorts of functions that are being fed something else than the value passed to bind() ?
Yes, arrow functions. Arrow functions do not have their own this binding (the value from the closest this providing environment is used instead), so bound arrow functions also ignore the bound this value.

Why can't the "`main`" function be declared as a lambda in Kotlin?

The following trivial Kotlin code snippet
fun main() {}
compiles just fine, but the following
val main : () -> Unit = {}
makes the compiler complain that "No main method found in project.", while I was expecting them to be equivalent (I expect a programming language to be as conceptually uniform as possible).
Why does this happen? Is it related only to main, or does this behaviour concern a larger class of functions? Is there some subtle difference between declaring functions with "fun" and declaring them as lambdas?
Conceptually, they are different things. To see that, let's take a look at roughly what the equivalent Java would be. I'll use JVM for examples in this answer, but the same principles apply to all of the other Kotlin backends.
object Foo {
fun main() { ... }
}
This is roughly
class Foo {
public static void main() { ... }
}
Again, roughly. Technically, you'll get a singleton object and a method on it unless you use #JvmStatic (I assume there's some special handling for main that produces a static function on JVM, but I don't know that for a fact)
On the other hand,
object Foo {
val main: () -> Unit = { ... }
}
Here, we're declaring a property, which in Java is going to get implemented as a getter-setter pair
class Foo {
// Singleton instance
public static Foo instance = new Foo();
public Supplier<Void> main;
Foo() {
main = new Supplier<Void>() {
Void get() {
...
}
}
}
}
That is, there isn't actually a main method. There's a main field which, deep down somewhere, has a function inside of it. In my example above, that function is called get. In Kotlin, it's called invoke.
The way I like to think of it is this. Methods in Kotlin (i.e. the things you define on objects that designate their behavior) are not themselves first-class objects. They're second-class citizens which exist on an object. You can convert them to first-class objects by making them into functions. Functions are ordinary objects, like any other. If you take an ordinary object, which may or may not be a function, and call it with (), then you're actually invoking the method .invoke(...) on it. That is, () is an operator on objects which really ends up calling a method. So in Kotlin, functions are really just objects with a custom invoke and a lot of syntax sugar.
Your val defines a field which is a function. Your fun defines a method. Both of these can be called with (), but only one is a genuine method call; the other is secretly calling .invoke on another object. The fact that they look syntactically the same is irrelevant.
As the old adage goes, functions are a poor man's objects, and objects are a poor man's functions.
There is a subtle (or more than subtle) difference. Declaring it with val means that main is a property containing a reference to an anonymous function (which you defined with the lambda). If you define it with val, then when you call main(), you are actually calling the getter of the main property, and then using the invoke() operator to call invoke() on the return value of the property (the anonymous function).

Lambdas assigned to variables in Kotlin. Why?

I noticed that I get the same effect if I define this trivial function:
fun double ( i: Int ) = i*2
and if I define a variable and assign a lambda (with an identical body) to it:
var double = { i : Int -> i*2 }
I get the same result if I call double(a) with either declaration.
This leaves me confused. When is it needed, recommended, advantageous to define a variable as a lambda rather than define a function to it?
When is it needed, recommended, advantageous to define a variable as a lambda rather than define a function to it?
Whenever you have the choice of either, you should use a fun declaration. Even with a fun you can still get a first-class callable object from it by using a function reference.
On the JVM, a fun is significantly more lightweight, both in terms of RAM and invocation overhead. It compiles into a Java method, whereas a val compiles into an instance field + getter + a synthetic class that implements a functional interface + a singleton instance of that class that you must fetch, dereference, and invoke a method on it.
You should consider a function-typed val or var only when something is forcing you to do it. One example is that you can dynamically replace a var and effectively change the definition of the function. You may also receive function objects from the outside, or you may need to comply with an API that needs them.
In any case, if you ever use a function-typed property of a class, you'll know why you're doing it.
First, if I understand you right, your question is "Why are functions first-class citizens in Kotlin -- And when to use them as such?", right?
Kotlin functions are first-class, which means that they can be stored in variables and data structures, passed as arguments to and returned from other higher-order functions. You can operate with functions in any way that is possible for other non-function values. (see here)
As stated in the docs, one use case are higher-order functions. As a first step, I will leave the wikipedia link here: https://en.wikipedia.org/wiki/Higher-order_function
Basically, a higher-order function is a function that takes functions as parameters, or returns a function.
This means that a higher-order function has at least one parameter of a function type or returns a value of a function type.
Following a short example of a higher-order function that receives a parameter of function type (Int) -> Boolean:
fun foo(pred: (Int) -> Boolean) : String = if(pred(x)) "SUCCESS" else "FAIL"
This higher-order function can now be called with any (Int) -> Boolean function.
The docs also state ... [can be used] in any way that is possible for other non-function values.
This means that you can, for example, assign different functions to a variable, depending on your current context.
For example:
// This example is verbose on purpose ;)
var checker: (Int) -> Boolean
if (POSITIVE_CHECK) {
checker = { x -> x > 0 } // Either store this function ...
} else {
checker = { x -> x < 0 } // ... or this one ...
}
if (checker(someNumber)) { // ... and use whatever function is now stored in variable "checker" here
print("Check was fine")
}
(Code untested)
You can define variable and assign it lambda when you want change behaviour for some reason. For example, you have different formula for several cases.
val formula: (Int) -> Int = when(value) {
CONDITION1 -> { it*2 }
CONDITION2 -> { it*3 }
else -> { it }
}
val x: Int = TODO()
val result = formula(x)
If you simply need helper function, you should define it as fun.
If you pass a lambda as a parameter of a function it will be stored in a variable. The calling application might need to save that (e.g. event listener for later use). Therefore you need to be able to store it as a variable as well. As said in the answer however, you should do this only when needed!
For me, I would write the Lambda variable as followed:
var double: (Int) -> Int = { i -> //no need to specify parameter name in () but in {}
i*2
}
So that you can easily know that its type is (i: Int) -> Int, read as takes an integer and returns an integer.
Then you can pass it to somewhere say a function like:
fun doSomething(double: (Int) -> Int) {
double(i)
}

Passing arguments to multiple functions

I have 2 general questions about function programming.
Consider the following 3 functions:
result = fun3(fun2(fun1(param1))); // param4
function fun1(param1) {
// ...
return param2;
}
function fun2(param2) {
// ...
return param3;
}
function fun3(param3) {
// ...
return param4;
}
Each function expects 1 parameter, does some computation and returns a variable.
In my case, every subsequent function relies on the output of the preceding function.
Is the solution in my example a common practice? Or are there better ways?
What if a function produces 2 outputs and 2 different functions need them?
Like in this example:
function fun1(param1) {
// ...
return param2, param3;
}
function fun2(param2) {
// ...
return param4;
}
function fun3(param3) {
// ...
return param5;
}
PS: Although this is a general programming questions, maybe it could be important to mention, that I use PHP.
The answer to the first question is that, yes, it's a very common technique in functional programming. It is, for example, the basis of currying which is also very common.
As regards the second question, many functional languages support the concept of a tuple or heterogeneous list - if you want to return multiple values you either explicitly create one or the runtime generates one for you on the fly. Sending return values into multiple subsequent functions would be done with the aid of a helper function which does the multiplexing. The question becomes how you handle the return values from those functions, presumably as a list I guess. It might depend on your use case.
In Python that might look like
def multiplex(functions, value):
return [func(value) for func in functions]
To keep with your single-argument style the above might end up being curried in some fashion so that the list of functions to multiplex to are bound in a separate function application. Different languages achieve that in different ways, Python has a functools module which supports partial application of a function whereas Scala natively supports partially applying a function.

Function objects in C++ (C++11)

I am reading about boost::function and I am a bit confused about its use and its relation to other C++ constructs or terms I have found in the documentation, e.g. here.
In the context of C++ (C++11), what is the difference between an instance of boost::function, a function object, a functor, and a lambda expression? When should one use which construct? For example, when should I wrap a function object in a boost::function instead of using the object directly?
Are all the above C++ constructs different ways to implement what in functional languages is called a closure (a function, possibly containing captured variables, that can be passed around as a value and invoked by other functions)?
A function object and a functor are the same thing; an object that implements the function call operator operator(). A lambda expression produces a function object. Objects with the type of some specialization of boost::function/std::function are also function objects.
Lambda are special in that lambda expressions have an anonymous and unique type, and are a convenient way to create a functor inline.
boost::function/std::function is special in that it turns any callable entity into a functor with a type that depends only on the signature of the callable entity. For example, lambda expressions each have a unique type, so it's difficult to pass them around non-generic code. If you create an std::function from a lambda then you can easily pass around the wrapped lambda.
Both boost::function and the standard version std::function are wrappers provided by the li­brary. They're potentially expensive and pretty heavy, and you should only use them if you actually need a collection of heterogeneous, callable entities. As long as you only need one callable entity at a time, you are much better off using auto or templates.
Here's an example:
std::vector<std::function<int(int, int)>> v;
v.push_back(some_free_function); // free function
v.push_back(&Foo::mem_fun, &x, _1, _2); // member function bound to an object
v.push_back([&](int a, int b) -> int { return a + m[b]; }); // closure
int res = 0;
for (auto & f : v) { res += f(1, 2); }
Here's a counter-example:
template <typename F>
int apply(F && f)
{
return std::forward<F>(f)(1, 2);
}
In this case, it would have been entirely gratuitous to declare apply like this:
int apply(std::function<int(int,int)>) // wasteful
The conversion is unnecessary, and the templated version can match the actual (often unknowable) type, for example of the bind expression or the lambda expression.
Function Objects and Functors are often described in terms of a
concept. That means they describe a set of requirements of a type. A
lot of things in respect to Functors changed in C++11 and the new
concept is called Callable. An object o of callable type is an
object where (essentially) the expression o(ARGS) is true. Examples
for Callable are
int f() {return 23;}
struct FO {
int operator()() const {return 23;}
};
Often some requirements on the return type of the Callable are added
too. You use a Callable like this:
template<typename Callable>
int call(Callable c) {
return c();
}
call(&f);
call(FO());
Constructs like above require you to know the exact type at
compile-time. This is not always possible and this is where
std::function comes in.
std::function is such a Callable, but it allows you to erase the
actual type you are calling (e.g. your function accepting a callable
is not a template anymore). Still calling a function requires you to
know its arguments and return type, thus those have to be specified as
template arguments to std::function.
You would use it like this:
int call(std::function<int()> c) {
return c();
}
call(&f);
call(FO());
You need to remember that using std::function can have an impact on
performance and you should only use it, when you are sure you need
it. In almost all other cases a template solves your problem.