PL/Python3 with VARIADIC arrays as arguments - postgresql

I'm using plpython3u to process a result that contains an arbitrary number of columns each of which hold an array (of varying lengths > 0). In python, I'd be expecting to process this data as a multidimensional array but I'm having trouble getting it from Postgres into my function.
The function declaration I am using looks like this:
CREATE OR REPLACE FUNCTION is_set_cover_possible(VARIADIC args numeric[][])
The problem is that when I try
SELECT is_set_cover_possible(ARRAY[1,2],ARRAY[1,2]);
I get:
No function matches the given name and argument types. You might need to add explicit type casts.
If I pass in (ARRAY[1,2]) the function returns a result without failing so it seems postgres can't handle the multidimensional declaration above.
So, if it's actually possible: How do I declare the function so as to receive a list of arrays?

You cannot to do it. Arguments used as variadic arguments cannot be arrays.
Implementation of variadic arguments was at time when this was not possible technically. Now it is possible, but nobody implemented it.

Related

Call a kdb function passing another function as argument using sendSync method of qpython(kdb)

In the KDB server, we have two functions defined as
q)t:{0N!x[`min]; 0N!x[`max];}
q).up.map:{[keyList; valueList] keyList!valueList}
The KDB server, does not allow to pass dict()!() as an argument directly to a function, rather one has to use .up.map.
Calling t function from kdb would be like
q)t[.up.map[`min`max;10 20]]
I want to call the t function from qpython sendSync() method passing another function .up.map[`min`max;10 20] as an argument to t.
Unfortunately, I cannot find a solution in the qptyhon doc - https://qpython.readthedocs.io/en/latest/qpython.html#qpython.qconnection.QConnection.sendSync
Error -
When I tried sendSync() method, below error is raised -
qpython.qtype.QException: b'['
The KDB server, does not allow to pass dict()!() as an argument directly to a function, rather one has to use .up.map.
May I know why this is so? It's not a bad idea to challenge the original design before looking for workarounds. If dictionary were allowed as its parameter, it could have been as simple as
params = QDictionary(qlist(numpy.array(["min", "max"], dtype=numpy.string_), qtype=QSYMBOL_LIST),
qlist(numpy.array([10, 20], dtype=numpy.int64), qtype=QLONG_LIST))
with qconnection.QConnection(host='localhost', port=5000) as q:
q.sendSync("t", params)
If you want to do what you can do in q console via qpython, it's actually also simple: you pass the same string over. Effectively it's the same mechanism as a q client passing a string via IPC to the server, where the string is parsed and evaluated. Here you need to convert the input to the given string format in your Python code, thus not as clean as the above (although it looks more verbose).
with qconnection.QConnection(host='localhost', port=5000) as q:
q.sendSync("t[.up.map[`min`max;10 20]]")
Maybe you can use a lambda for this. That way it's just the arguments that need be serialized:
q.sendSync("{t[.up.map[x;y]]}", qlist(["min", "max"], qtype=QSYMBOL_LIST), [10, 20])
If that's not permitted, you could create it as a named wrapper function on the kdb side, which could be.
Alternatively, you could format your call with arguments as a string. A bit hacky; but workable for simple input.
q.sendSync(f"t[.up.map[`{'`'.join(['min', 'max'])};{' '.join(['10', '20'])}]]")

Built-in list of numeric types in Matlab

Does Matlab provide a list of numeric datatypes?
Some functions, like zeros, take an optional typename argument, a string naming a numeric type (e.g., 'double' or 'uint8'), that determines the type of the returned array. I would like to add something similar to my own code, and a complete list of numeric types would help with argument validation, as in:
ip = inputParer()
...
ip.addParameter('DataType', 'double', #(x) ismember(x, numeric_types()));
It seems as though something similar must exist, but I haven't been able to find it.
isnumeric checks an instance, rather than the typename itself.
superclasses doesn't return anything for numeric types on 2018b.
Obviously, this is not hard to implement, but it'd be nice to use a built-in if it existed.

Three dots in Swift init method

I was looking at some Apple Combine source code and saw a Publisher name MergeMany with an init method defined like this:
public init(_ upstream: Upstream...)
What are the three dots ... after the Upstream? The value of Upstream is just another publisher as defined in the Struct definition.
public struct MergeMany<Upstream> : Publisher where Upstream : Publisher {
The three dots mean that it is a variadic function and can take a list of Upstream. This is a function of the Swift Language and not the Combine Framework.
From Sergio Pietri's Blogpost:
Why should we use variadic functions? When you declare this type of function you are adding flexibility to the code. For example: the printf is probably the most notable function that uses this principle. The printf will take N amount of arguments and has many different parameters to format the output it will print.
And from the Swift documentation:
A variadic parameter accepts zero or more values of a specified type. You use a variadic parameter to specify that the parameter can be passed a varying number of input values when the function is called. Write variadic parameters by inserting three period characters (...) after the parameter’s type name.
The values passed to a variadic parameter are made available within the function’s body as an array of the appropriate type. For example, a variadic parameter with a name of numbers and a type of Double... is made available within the function’s body as a constant array called numbers of type [Double].

Spread syntax in function call in Reason

In Javascript you can use the spread syntax in a function call like this:
console.log(...[1,2,3]);
Is there an equivalent in Reason? I tried the following:
let bound = (number, lower, upper) => {
max(lower, min(upper, number));
};
let parameters = (1,0,20);
bound(...parameters) |> Js.log;
But this gives an unknown syntax error:
Try reason snippet
There's not. Reason is a statically typed language, and lists are dynamically-sized and homogenous. It would be of very limited use, and not at all obvious how it would deal with too few or too many arguments. If you want to pass a list, you should just accept a list and deal with it appropriately, as a separate function if desired.
You could of course use a tuple instead, which is fixed-size and heterogenous, but I don't see a use-case for that either, since you might as well just call the function directly then.
For JavaScript FFI there is however the bs.splice attribute, which will allow you to apply a variable number of arguments to a js function using an array. But it needs to be called with an array literal, not just any array.

How can I make the value of an expression equal to a second return value of another expression

Is there an idiomatic way in Matlab to bind the value of an expression to the nth return value of another expression?
For example, say I want an array of indices corresponding to the maximum value of a number of vectors stored in a cell array. I can do that by
function I = max_index(varargin)
[~,I]=max(varargin{:});
cellfun(#max_index, my_data);
But this requires one to define a function (max_index) specific for each case one wants to select a particular return value in an expression. I can of course define a generic function that does what I want:
function y = nth_return(n,fun,varargin)
[vals{1:n}] = fun(varargin{:});
y = vals{n};
And call it like:
cellfun(#(x) nth_return(2,#max,x), my_data)
Adding such functions, however, makes code snippets less portable and harder to understand. Is there an idiomatic to achieve the same result without having to rely on the custom nth_return function?
This is as far as I know not possible in another way as with the solutions you mention. So just use the syntax:
[~,I]=max(var);
Or indeed create an extra function. But I would also suggest against this. Just write the extra line of code, in case you want to use the output in another function. I found two earlier questions on stackoverflow, which adress the same topic, and seem to confirm that this is not possible.
Skipping outputs with anonymous function in MATLAB
How to elegantly ignore some return values of a MATLAB function?
The reason why the ~ operator was added to MATLAB some versions ago was to prevent you from saving variables you do not need. If there would be a syntax like the one you are searching for, this would not have been necessary.