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.
Related
I was looking inside the create_vlabel function and noted that to get the graph_name and label_name it is used graph_name = PG_GETARG_NAME(0) and label_name = PG_GETARG_NAME(1). Since these two variables are also passed as parameters, I was thinking that, if I wanted to add one more parameter to this function, then I would need to use PG_GETARG_NAME(2) to get this parameter and use it in the function's logic. Is my assumption correct or do I need to do more tweaks to do this?
You are correct, but you also need to change the function signature in the "age--1.2.0.sql" file, updating the arguments:
CREATE FUNCTION ag_catalog.create_vlabel(graph_name name, label_name name, type new_argument)
RETURNS void
LANGUAGE c
AS 'MODULE_PATHNAME';
Note that all arguments come as a "Datum" struct, and PG_GETARG_NAME automatically converts it to a "Name" struct. If you need an argument as int32, for example, you should use PG_GETARG_INT32(index_of_the_argument), for strings, PG_GETARG_CSTRING(n), and so on.
Yes, your assumption is correct. If you want to add an additional parameter to the create_vlabel function in PostgreSQL, you can retrieve the value of the third argument using PG_GETARG_NAME(2). Keep in mind that you may need to make additional modifications to the function's logic to handle the new parameter correctly.
The answers given by Fahad Zaheer and Marco Souza are correct, but you can also create a Variadic function, with which you could have n number of arguments but one drawback is that you would have to check the type yourself. You can find more information here. You can also check many Apache Age functions made this way e.g agtype_to_int2.
I've been looking at the compiled version of some code snippets to dig into how my code is represented at runtime.
I'm not surprised to see that safe coerce and unsafe coerce are the same in the compiled JavaScript. There's a dictionary passed into safe coerce that's unused/undefined in the code I've looked at so far.
It seems like if the runtime representation of two types is the same, then there shouldn't be any runtime overhead for having/using such a type. This isn't true and I'm curious to understand why.
Coercing two types requires a function call at runtime. What I'm not understanding is that this function call appears to do nothing.
exports.unsafeCoerce = function (x) {
return x;
};
If I declare a newtype
newtype Selection = Selection Int
I see something similar in JavaScript:
var Selection = function (x) {
return x;
};
Which means I might see something like this in JavaScript:
return Selection(Data_Int.pow(2)(Safe_Coerce.coerce()(n) - 1 | 0));
which should be identical to this:
return Data_Int.pow(2)(n - 1 | 0);
In this case, both Selection and coerce only ever return what they're given. Once the type checking has been done, I'm not sure what purpose they continue to serve.
The reason the code is generated like it is, and not in a more efficient form like you suggest, is because the purs compiler has only a simplistic optimiser.
Why unsafeCoerce is defined as it is is because it is a PureScript function and must match the runtime representation of PureScript functions. Same goes for Selection.
Constraints are represented as functions on dictionaries. Some time ago there was an optimisation added such that empty dictionaries do not have to be constructed as empty JavaScript objects, and instead can be represented by undefined. That is why there is no argument passed to coerce.
All is in the subject, really.
I fail to see what the difference in behavior is between those two methods for x:
// first version
Method m(ByRef x As whatever)
{
// play with x
}
// second version
Method m(Output x As whatever)
{
// play with x
}
There must be some reason why both those modifiers exist, however my "mastery" (uhm) of the language is not enough to understand the difference. I have tried and read the documentation, search it etc, to no avail so far.
So, what is the difference between those two argument modifiers?
Well those are just "prettifiers", they don't do much in terms of actual language behaviour, and only used to provide documentation. Idea is that arguments documented as ByRef provide both input and output, for example you can pass an array to be sorted, and Output arguments only provide output, for example list of errors. Output modifier was introduced later, and a lot of system code still use ByRef for both use cases.
If argument is actually passed by reference is only determined by method caller, and keyword doesn't really matter. You will call your method as ..m(.parameter) to pass variable by reference, and ..m(parameter) to pass variable by value.
As per my understanding, partial functions are functions that are defined for a subset of input values.
So should I use partial functions for DAO's. For example:
getUserById(userId: Long): User
There is always an input userId which does not exists in db. So can I say it is not defined. And lift it when I call this function.
If yes where do I stop. Should I use partial functions for all methods which are not defined, say for null.
PartialFunction is used when function is undefined for some elements of input data (input data may be Seq etc.)
For your case Option is better choice: it says that return data may be absent:
getUserById(userId:Long):Option[User]
I would avoid using partial functions at all, because scala makes it very easy to call a partial function as though it were a total function. Instead it's better to use a function that returns Option as #Sergey suggests; that way the "partial-ness" is always explicit.
Idiomatic scala does not use null so I wouldn't worry about methods which are not defined for null, but certainly it's worth returning Option for methods which are only defined for some of their possible input values. Better still, though, is to only accept suitable types as input. E.g. if you have a function that's only valid for non-empty lists, it should take (scalaz) NonEmptyList as input rather than List.
In the book of "functional programming in Scala", it gives some examples about side-effects, like:
Modifying a variable
Modifying a data structure in place
Setting a field on an object
Throwing an exception or halting with an error Printing to the console or reading user input
Reading from or writing to a file
Drawing on the screen
My question is, is reading some data from outside rathen than the parameters makes the function impure?
E.g.
val name = "Scala"
def upcase() = name.toUpperCase
Is the upcase function pure or not?
Edit: as per this answer: https://stackoverflow.com/a/31377452/342235, my "function" is not actually function, it's a method, so I give a function version of it, and ask the same question:
val name = "Scala"
val upcase: () => String = () => name.toUpperCase
Reading from immutable data is not impure; the function will still return the same value every time. If name were a var then that function would be impure, since something external could change name, so multiple calls to upcase() might evaluate to different values.
(Of course it might be possible to e.g. alter name through reflection. Properly we can only talk about purity with respect to some notion of what kind of functions are allowed to call a given function, and what kind of side effects we consider to be equivalent)
It's worth noting that your function is not pure because toUpperCase is not pure; it depends on the system's default Locale, and may produce different results on different systems (e.g. on a Turkish system, "i".toUpperCase == "İ"). You should always pass an explicit Locale, e.g. def upcase() = name.toUpperCase(Locale.ENGLISH); then the function will be pure.
Interestingly, the answer is "No", but not for the reason you think it is. Your upcase is not a pure function. It is, however, pure, but it is a method, not a function.