Multiple function signatures in externs rule - google-closure-compiler

I am writing closure externs for WebAssembly.
For function WebAssembly.instantiate, it has 2 function signatures.
Promise<{module:WebAssembly.Module, instance:WebAssembly.Instance}>
instantiate(BufferSource bytes [, importObject])
Promise<WebAssembly.Instance> instantiate(moduleObject [, importObject])
How to declare both rules in closure externs?
Reference:
https://github.com/WebAssembly/design/blob/master/JS.md#webassemblyinstantiate

You can specify that argument and result are union of two different types. See https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler about how to specify types.
Here is a simple example of such a function:
/**
* #param {string|number} value
* #return {string|number}
*/
ambiguous = function(value) {
if (typeof value == 'string') {
return value+' is string';
} else if (typeof value == 'number') {
return value+1;
} else throw new Error();
};
For your WebAssembly.instantiate function you will of course have more complex types than string and number. I don't know how you would specify the Promise types, I don't recognize the syntax shown for those, and I doubt closure compiler will parse that as-is. The extern then looks something like this (with bogus types for the Promises).
/**
#param (!BufferSource|!WebAssembly.Module) arg1 either a BufferSource or a module
#param Object= importObject optional object to import
#return (!PromiseType1|!PromiseType2)
*/
WebAssembly.instantiate = function(arg1, importObject) {};
The ! symbol is used to indicate a non-null object. If these can be null then leave that out. The = symbol after Object= means it can be undefined.
When using the results of this function you will need to test what type of thing you got using instanceof or some other method. Otherwise the compiler only knows the result is one of the two possible types. If not using instanceof, you can use type casting to tell the compiler that you know what the type is, see end of that page referenced above.
An example of a function from closure-library that has a union type in both its argument and its result is goog.array.find. The source for goog.array.find is available. Note that the angle brackets <> are used for the template type feature of the compiler.

Related

How do I specify a type for a function parameter that optionally includes a given method?

Updated Question
I want to define a function named bsearch() to do binary searches against arrays of arbitrary object types. When I invoke the function, I want it to check whether or not the Type of the array contains a compare() method and use it, if it does. If it does not, I want it to fall back to using < and === (so it will work with strings and numbers).
What should the function declaration look like? (I don't need an actual implementation, just the syntax for a type-safe solution.)
Or maybe I'm going about this all wrong? How can I create a function that uses a method built into a parameter type if it exists, or use some other function when it doesn't?
Original Question
This is the original question, but I've replaced it with the above as it seems this wasn't getting my point across.
I want to define a function named bsearch() to do binary searches against arrays of arbitrary object types. So I'd like to do something like this:
type Comparator = <Type>(a: Type, b: Type) => -1 | 0 | 1;
static bsearch<Type extends { compare?: Comparator }>(
ary: Type[],
value: Type
): number { ... }
My goal is to specify that Type must extend a type that may or may not include the compare method. In my function, I will check whether the compare method exists on the value parameter and call if it does, or use a generic function (that uses < and ===) if it does not.
The definition of bsearch() does not produce any warnings or errors, but attempts to invoke it from my unit test does:
class Person {
name: string;
length: number;
compare: Comparator<Person>; // What goes here?
}
describe('Utils tests', () => {
const arrayOfInt = [10, 20, 30, 40];
const arrayOfStr = ['Alfred', 'Bob', 'Chuck'];
const arrayOfPersons: Person = [
{name:'Barney',length:2},
{name:'Fred',length:6}
{name:'Wilma',length:12},
];
it('can find integer in an array of integers', () => {
let search_for = 30;
let result = Utils.bsearch(arrayOfInt, search_for)
expect(result).to.be.equal(2);
});
it('can find string in an array of strings', () => {
let search_for = 'Bob';
let result = Utils.bsearch(arrayOfStr, search_for)
expect(result).to.be.equal(1);
});
it('can find Person in an array of Persons', () => {
// This one uses Person.compare() to do the search.
// The previous two tests used the fallback technique.
let search_for = {name:'Fred',length:6};
let result = Utils.bsearch(arrayOfPersons, search_for)
expect(result).to.be.equal(1);
});
});
The error message is:
TS2345: Argument of type 'number[]' is not assignable to parameter of type '{ compare?: Comparator | undefined; }[]'.   Type 'number' has no properties in common with type '{ compare?: Comparator | undefined; }'.
I would appreciate pointers to other techniques if there is a better way to accomplish this (I'm still a TypeScript newbie).
Your generic is:
Type extends { compare?: Comparator }
Which means that Type must fulfill { compare?: Comparator } type. While passing object value, for example { name: 'Barney', length: 2, comparator: /* snip */}, is obviously correct, it's not the case for primitives like 10 and Bob. You need to include information about primitive types in the generic, for example:
Type extends ({ compare?: Comparator }) | number | string
Also, you'd probably want to enrich a bit the object typing:
{[key: string]: unknown, compare?: () => void } | number | string
Because, based on your description, you'd also want to accept also objects that do not have compare function in their type signature at all. If it does sound strange, I recommend reading about excess property checking.

In functional programming, is "saving the state" of an algorithm at the recursive function argument cheating?

for instance, lets suppose we had to write an algorithm to get the max value of an array of integers, could we still call the code functional if we make the recursive function return various information that simulates an assignment to a global object? an exemple:
function getMax(array, props={}) {
const {index = 0, actualMax = array[0]}= props ///initial props
const arrayNotEnded = array[index + 1] !== undefined
if (arrayNotEnded) {
const maxOf= (a, b) => a > b ? a : b
const newMax = maxOf(actualMax, array[index+1])
const nextIndex = index+1
return getMax(array, {index:nextIndex, actualMax:newMax} )
}else return actualMax
}
a funny thing about that is, in Haskell, we cannot have optional arguments, so this logic would not be something cool to work with, since we would have to pass the initial props every time we would need to call this function.
Yes, you could consider it cheating, but this is a well-known technique in functional programming, the accumulator argument [1][2][3]. Remember: code doesn't become functional by not having state, functional programming is all about making state explicit. There's no better way of doing that than by making it a parameter of your function.
Your code has some other problems, though. Most prominently, the state should be internal to your function, only being passed to a helper function (that might be locally declared or separate) but not as part of your function's public interface. This also prevents confusing your helper function by passing invalid state (e.g. out-of-bound indices). And yes, also the optional parameter smells - not because you think this is not possible in Haskell (it is, using Maybe), but because it can be forgotten or passed mistakenly. Instead, the helper function should have a required state parameter, and getMax should have none.
Last but not least, you should avoid out-of-bounds indexed access on arrays - check the length to know where the end is, don't compare to undefined. This includes unconditionally accessing array[0] - that makes it very easy to overlook that your function can return undefined. Make this error condition explicit as well.
Here's how I'd write it:
function getMax(array) {
if (!array.length)
throw new Error("array must be non-empty");
else
return maxFrom(1, array[0]);
function maxFrom(index, max) {
if (index < array.length)
return maxFrom(index+1, array[index] > max ? array[index] : max);
else
return actualMax
}
}
Even better than throwing exceptions would be if you'd had an algebraic data type at hand that you could return to represent the error-or-result.

PHP7. Reflection doesn't work from old versions php

I have a php script which was written on php 5.6.19, works on 5.3 version to, with some installed addons.
I decide to try execute it on php7.
The special of the script that I am initializing a class with parameter by reference via creating a new instance with Reflection::class. And there warning then waited variable by reference but value received.
Definition of the class' constructor method tried to create an instance from:
public function __construct($user, IDatabase &$repository, $errors = null);
Sample of code where this constructor is used:
// define manager type to create (all managers has the same constructor)
$manager = $managersNamespace . ucfirst($this->_manager) . "Manager";
// trying to create the manager
// !!!And here a Warning occurs
$reflect = new \ReflectionClass($manager);
$manager = $reflect->newInstance($user, $database, $errors);
After these I am invoking a method I need, and here the fatal error with stopped the script:
$method = "show" . ucfirst($this->_page) . "Page";
$reflect->getMethod($method)->invoke($manager);
I didn't see any changes in documentation. Anyone had the same issue?
First and foremost, why are you passing an object by reference !?
Objects have pass-by-reference semantics, forcibly trying to pass objects by reference has not made good sense since PHP 4.
Just remove the & ...
Let's ignore that, and pretend there is still a problem, so that you can try to understand what is going on.
To break down the problem, first you need to understand the distinction between a variable and an expression:
mine(1 + 2);
The argument to mine has no name, it's represented by a temporary variable in the engine: it's an expression.
mine(1);
The argument to mine has no name, it's not an expression, but a literal constant, represented by a compiler variable in the engine. It's similar to a temporary variable, a kind of constant expression.
mine($a);
The argument to mine has a name, which you can use to refer to it's value. It's a normal variable.
Only variables can be passed by reference because you cannot refer to expressions or literal constants
Next you need to understand why we pass-by-reference:
function mine(int $thing) {
$thing++;
}
$a = 1;
mine($a);
var_dump($a); // int(1)
In this code, $a is passed to mine() by value, so that the changes that mine() make to $thing are only visible inside the scope of mine. $a is unchanged after the call to mine() returns because $a and $thing are distinct, having been passed-by-value, which means it's value was copied on to the call stack for the invocation of mine().
function mine(int &$thing) {
$thing++;
}
$a = 1;
mine($a);
var_dump($a); // int(2)
In the code above, $a is passed to mine() by reference, this means that $a and $thing are no longer distinct. The changes mine() make to $thing are now visible after the call to mine() returns.
The last piece in the puzzle is Reflection:
function mine(int &$thing) {
$thing++;
}
$a = 1;
$reflector = new ReflectionFunction("mine");
$reflector->invoke($a);
The code above will raise:
Warning: Parameter 1 to mine() expected to be a reference, value given in /usr/src/php-src/refs.php on line 9
This is because ReflectionFunction::invoke and similar reflection functions (ReflectionClass::newInstance) accept their parameters by value and pass them onto the invoked function by value.
But ...
There is still a difference between pass-by-reference semantics, and passing by reference, a dangerous one:
class Foo {
public function qux() {}
}
class Bar {}
function mine(Foo &$foo) {
$foo = new Bar();
}
$foo = new Foo;
mine($foo);
$foo->qux();
Will obviously yield:
PHP Fatal error: Uncaught Error: Call to undefined method Bar::qux() in /usr/src/php-src/refs.php:16
Stack trace:
#0 {main}
thrown in /usr/src/php-src/refs.php on line 16
The declaration of mine() tells lies about the type safety of it's parameter. Type safety is only guaranteed upon entry to the function, the function body is free to break type safety, but it doesn't usually affect the caller when relying on the engines pass by reference semantics for objects.
This is an extremely scary kind of API, that should be avoided.

Examining the signature of function assigned to an interface{} variable using reflection

I'm trying the build a generic currying function that's look like:
package curry
import (
"fmt"
"reflect"
)
// Function
type fn interface{}
// Function parameter
type pr interface{}
// It return the curried function
func It(f fn, p ...pr) (fn, error) {
// examine the concret type of the function f
if reflect.ValueOf(f).Kind() == reflect.Func {
// Get the slice of input and output parameters type
} else {
return nil, fmt.Errorf("%s", "takes a function as a first parameter")
}
// _, _ = f, p
return nil, nil
}
Is it possible to extract the slice of input and output parameters types as []reflect.Type of the function f ?
You can use reflect.Type.In(int) and reflect.Type.Out(int), there are corresponding methods called NumIn() int and NumOut() int that give you the number of inputs/outputs.
However, keep in mind a few caveats:
To correctly extract the function for an arbitrary signature, you'll need an infinite number of cases. You'll have to switch over every single In and Out in turn to correctly get the type to extract.
You can't dynamically create a function anyway. There's no FuncOf method to go with SliceOf, MapOf, etc. You'll have to hand code the curried versions anyway.
Using reflection to emulate generics is generally considered a Bad Idea™.
If you absolutely have to do something like this, I'd heavily recommend making an interface and having each implementation do the currying itself, rather than trying to hack it "generically" for all cases, which will never work as of Go 1.2.1.
Go 1.5 will add a function that could help here.
(review 1996, commit e1c1fa2 by Dave (okdave))
// FuncOf returns the function type with the given argument and result types.
// For example if k represents int and e represents string,
// FuncOf([]Type{k}, []Type{e}, false) represents func(int) string.
//
// The variadic argument controls whether the function is variadic. FuncOf
// panics if the in[len(in)-1] does not represent a slice and variadic is
// true.
func FuncOf(in, out []Type, variadic bool) Type
The test cases include this intriguing code:
v := MakeFunc(FuncOf([]Type{TypeOf(K(""))}, []Type{TypeOf(V(0))}, false), fn)
outs := v.Call([]Value{ValueOf(K("gopher"))})

In boost::python how to wrap an overrideable function which takes a container of pointers to C++ objects and returns a pointer to one of them?

I'm wrapping a C++ framework with boost::python and I need to make a C++ method overrideable in python. This is a hook method, which is needed by the framework and has a default implementation in C++, which iterates through a list (passed as parameter) and performs a choice. The problems arise because the choice is stated by returning a pointer to the chosen element (an iterator, in fact), but I can't find a way to return a C++ pointer as a result of a python function. Can anyone help?
Thanks
This is most certainly doable, but you don't really have enough details. What you really need to do is create a c++ function that calls your python function, proceses the python result and returns a c++ result. To paraphrase (let's assume I have a boost object called func that points to some python function that parses a string and returns an int):
using boost::python;
A* test(const std::string &foo) {
object module = import("mymodule");
object func = module.attr("myfunc");
// alternatively, you could set the function by passing it as an argument
// to a c++ function that you have wrapped
object result = func(foo);
int val = extract<int>(result);
return new A(val); // Assumes that you've wrapped A.
}
// file: https://github.com/layzerar/box2d-py/blob/master/python/world.cpp
struct b2ContactFilter_W: b2ContactFilter, wrapper<b2ContactFilter>
{
bool ShouldCollide(b2Fixture* fixtureA, b2Fixture* fixtureB)
{
override func = this->get_override("ShouldCollide");
if (func)
{
return func(ref(fixtureA), ref(fixtureB)); //ref is boost::ref
}
return b2ContactFilter::ShouldCollide(fixtureA, fixtureB);
}
bool ShouldCollideDefault(b2Fixture* fixtureA, b2Fixture* fixtureB)
{
return b2ContactFilter::ShouldCollide(fixtureA, fixtureB);
}
};
class_<b2ContactFilter_W, boost::noncopyable>("b2ContactFilter")
.def("ShouldCollide", &b2ContactFilter::ShouldCollide, &b2ContactFilter_W::ShouldCollideDefault)
;
Is this what you need ?

Resources