Here the function imresize from ImageTransformation.jl is defined.
On line 164 there is this expression:
resized[I] = original(I_o...)
From Julia's documentation I understood the triple dot is called splatting and it unpacks an argument into multiple arguments. For example I_o is a tuple here. My issue is that I cannot find any trace of a function called original in the mentioned Julia file.
Where is original? From the code itself I have the impression that original should be an array and indeed on line 147 the type of original is annotated as AbstractInterpolation yet in turn I could not find any object of such type in the rest of the code.
The function declaration reads:
function imresize!(resized::AbstractArray{T,N}, original::AbstractInterpolation{S,N}) where {T,S,N}
Hence, original is the parameter of the imresize! function.
Now, you can see that this is called with paranthesis (). This happens because a functor has been defined.
This functor seems to be defined outside of this package but you can see in the package how it is used:
#inline _getindex(A, v) = A[v...]
#inline _getindex(A::AbstractInterpolation, v) = A(v...)
so simply it is used to yield an interpolation element.
You can find the actual declaration of this functor in the Interpolations package (for each interpolation type). For an example:
#inline function (itp::BSplineInterpolation)(x::Vararg{UnexpandedIndexTypes})
itp(to_indices(itp, x)...)
end
Source: https://github.com/JuliaMath/Interpolations.jl/blob/33409a657cacabf877681439605f16431f4bc8f4/src/b-splines/indexing.jl#L46
Related
Here is a function:
let newPositions : PositionData list =
positions
|> List.filter (fun x ->
let key = (x.Instrument, x.Side)
match brain.Positions.TryGetValue key with
| false, _ ->
// if we don't know the position, it's new
true
| true, p when x.UpdateTime > p.UpdateTime ->
// it's newer than the version we have, it's new
true
| _ ->
false
)
it compiles at expected.
let's focus on two lines:
let key = (x.Instrument, x.Side)
match brain.Positions.TryGetValue key with
brain.Positions is a Map<Instrument * Side, PositionData> type
if I modify the second line to:
match brain.Positions.TryGetValue (x.Instrument, x.Side) with
then the code will not compile, with error:
[FS0001] This expression was expected to have type
'Instrument * Side'
but here has type
'Instrument'
but:
match brain.Positions.TryGetValue ((x.Instrument, x.Side)) with
will compile...
why is that?
This is due to method call syntax.
TryGetValue is not a function, but a method. A very different thing, and a much worse thing in general. And subject to some special syntactic rules.
This method, you see, actually has two parameters, not one. The first parameter is a key, as you expect. And the second parameter is what's known in C# as out parameter - i.e. kind of a second return value. The way it was originally meant to be called in C# is something like this:
Dictionary<int, string> map = ...
string val;
if (map.TryGetValue(42, out val)) { ... }
The "regular" return value of TryGetValue is a boolean signifying whether the key was even found. And the "extra" return value, denoted here out val, is the value corresponding to the key.
This is, of course, extremely awkward, but it did not stop the early .NET libraries from using this pattern very widely. So F# has special syntactic sugar for this pattern: if you pass just one parameter, then the result becomes a tuple consisting of the "actual" return value and the out parameter. Which is what you're matching against in your code.
But of course, F# cannot prevent you from using the method exactly as designed, so you're free to pass two parameters as well - the first one being the key and the second one being a byref cell (which is F# equivalent of out).
And here is where this clashes with the method call syntax. You see, in .NET all methods are uncurried, meaning their arguments are all effectively tupled. So when you call a method, you're passing a tuple.
And this is what happens in this case: as soon as you add parentheses, the compiler interprets that as an attempt to call a .NET method with tupled arguments:
brain.Positions.TryGetValue (x.Instrument, x.Side)
^ ^
first arg |
second arg
And in this case it expects the first argument to be of type Instrument * Side, but you're clearly passing just an Instrument. Which is exactly what the error message tells you: "expected to have type 'Instrument * Side'
but here has type 'Instrument'".
But when you add a second pair of parens, the meaning changes: now the outer parens are interpreted as "method call syntax", and the inner parens are interpreted as "denoting a tuple". So now the compiler interprets the whole thing as just a single argument, and all works as before.
Incidentally, the following will also work:
brain.Positions.TryGetValue <| (x.Instrument, x.Side)
This works because now it's no longer a "method call" syntax, because the parens do not immediately follow the method name.
But a much better solution is, as always, do not use methods, use functions instead!
In this particular example, instead of .TryGetValue, use Map.tryFind. It's the same thing, but in proper function form. Not a method. A function.
brain.Positions |> Map.tryFind (x.Instrument, x.Side)
Q: But why does this confusing method even exist?
Compatibility. As always with awkward and nonsensical things, the answer is: compatibility.
The standard .NET library has this interface System.Collections.Generic.IDictionary, and it's on that interface that the TryGetValue method is defined. And every dictionary-like type, including Map, is generally expected to implement that interface. So here you go.
In future, please consider the Stack Overflow guidelines provided under How to create a Minimal, Reproducible Example. Well, minimal and reproducible the code in your question is, but it shall also be complete...
…Complete – Provide all parts someone else needs to reproduce your
problem in the question itself
That being said, when given the following definitions, your code will compile:
type Instrument() = class end
type Side() = class end
type PositionData = { Instrument : Instrument; Side : Side; }
with member __.UpdateTime = 0
module brain =
let Positions = dict[(Instrument(), Side()), {Instrument = Instrument(); Side = Side()}]
let positions = []
Now, why is that? Technically, it is because of the mechanism described in the F# 4.1 Language Specification under §14.4 Method Application Resolution, 4. c., 2nd bullet point:
If all formal parameters in the suffix are “out” arguments with byref
type, remove the suffix from UnnamedFormalArgs and call it
ImplicitlyReturnedFormalArgs.
This is supported by the signature of the method call in question:
System.Collections.Generic.IDictionary.TryGetValue(key: Instrument * Side, value: byref<PositionData>)
Here, if the second argument is not provided, the compiler does the implicit conversion to a tuple return type as described in §14.4 5. g.
You are obviously familiar with this behaviour, but maybe not with the fact that if you specify two arguments, the compiler will see the second of them as the explicit byref "out" argument, and complains accordingly with its next error message:
Error 2 This expression was expected to have type
PositionData ref
but here has type
Side
This misunderstanding changes the return type of the method call from bool * PositionData to bool, which consequently elicits a third error:
Error 3 This expression was expected to have type
bool
but here has type
'a * 'b
In short, your self-discovered workaround with double parentheses is indeed the way to tell the compiler: No, I am giving you only one argument (a tuple), so that you can implicitly convert the byref "out" argument to a tuple return type.
If I declare a function
test(A) -> 3.
Erlang generates a warning about variable A not being used. However the definition
isEqual(X,X) -> 1.
Doesn't produce any warning but
isEqual(X,X) -> 1;
isEqual(X,Y) -> 0.
again produces a warning but only for the second line.
The reason why that doesn't generate a warning is because in the second case you are asserting (through pattern matching), by using the same variable name, that the first and second arguments to isEqual/2 have the same value. So you are actually using the value of the argument.
It might help to understand better if we look at the Core Erlang code produced from is_equal/2. You can get .core source files by compiling your .erl file in the following way: erlc +to_core pattern.erl (see here for pattern.erl).
This will produce a pattern.core file that will look something like this (module_info/[0,1] functions removed):
module 'pattern' ['is_equal'/2]
attributes []
'is_equal'/2 = fun (_cor1,_cor0) ->
case <_cor1,_cor0> of
%% Line 5
<X,_cor4> when call 'erlang':'=:=' (_cor4, X) ->
1
%% Line 6
<X,Y> when 'true' ->
0
end
As you can see, each function clause from is_equal/2 in the .erl source code gets translated to a case clause in Core Erlang. X does get used in the first clause since it needs to be compared to the other argument. On the other hand neither X or Y are used in the second clause.
Alright, so I'm a happy fsx-script programmer, because I love how I can have the compiler shout at me when I do mistakes before they show up at runtime.
However I've found a case which really bothers me because I was expecting that by doing some refactoring (i.e.: adding an argument to a function) I was going to be warned by the compiler about all the places where I need to put the new argument. But, not only this did not happen, fsharpi ran my script and ignored the function call completely!! :(
How can I expect to refactor my scripts if this happens?
Here is my code:
let Foo (bar: string) =
Console.WriteLine("I received " + bar)
Foo("hey")
It works.
Now, later, I decide to add a second argument to the function (but I forget to add the argument to all the calls to it):
let Foo (bar: string) (baz: bool) =
Console.WriteLine("I received " + bar)
Foo("hey")
The result of this is: instead of the compiler telling me that I'm missing an argument, it is fsharpi running the script and ignoring the call to Foo! Why?
PS: I know the difference between currying and tuples, so I know Foo("hey") becomes a function (instead of a function call), because of partial application. But I want to understand better why the compiler is not expecting a function evaluation here, instead of seeing a function and ignoring it. Can I enable a warningAsError somehow? I would like to avoid resorting to using tuples in order to workaround this problem.
The fsharpi (or fsi if you're on Windows) interpreter makes no distinction between running a script and typing code at the interactive prompt (or, most often, submitting code from your editor via a select-and-hit-Alt-Enter keyboard shortcut).
Therefore, if you got what you're asking for -- fsharpi issuing a warning whenever a script line has a return value that isn't () -- it would ruin the value of fsharpi for the most common use case, which is people using an interactive fsharpi session to test their code, and rapidly iterate through non-working prototypes to get to one that works correctly. This is one of F#'s great strengths, and giving you what you're asking for would eliminate that strength. It is therefore never going to happen.
BUT... that doesn't mean that you're sunk. If you have functions that return unit, and you want fsharpi to give you a compile-time error when you refactor them to take more arguments, you can do it this way. Replace all occurrences of:
Foo("hey")
with:
() = Foo("hey")
As long as the function Foo has only one argument (and returns null), this will evaluate to true; the true value will be happily ignored by fsharpi, and your script will run. However, if you then change Foo to take two arguments, so that Foo("hey") now returns a function, the () = Foo("hey") line will no longer compile, and you'll get an error like:
error FS0001: This expression was expected to have type
unit
but here has type
'a -> unit
So if you want fsharpi to refuse to compile your script when you refactor a function, go through and change your calls to () = myfunc arg1 arg2. For functions that don't return unit, make the value you're testing against a value of that function's return type. For example, given this function:
let f x = x * 2
You could do
0 = f 5
This will be false, of course, but it will compile. But if you refactor f:
let f x y = x * 2 + y
Now the line 0 = f 5 will not compile, but will give you the error message:
error FS0001: This expression was expected to have type
int
but here has type
int -> int
To summarize: you won't ever get the feature you're looking for, because it would harm the language. But with a bit of work, you can do something that fits your needs.
Or in other words, as the famous philosopher Mick Jagger once put it:
You can't always get what you want. But if you try, sometimes you might find you get what you need.
In my Lua script I'm trying to create a function with a variable number of arguments. As far as I know it should work like below, but somehow I get an error with Lua 5.1 on the TI-NSpire (global arg is nil). What am I doing wrong? Thanks!
function equation:init(...)
self.equation = arg[1]
self.answers = {}
self.pipe = {arg[1]}
self.selected = 1
-- Loop arguments to add answers.
for i = 2, #arg do
table.insert(self.answers, arg[i])
end
end
instance = equation({"x^2+8=12", -4, 4})
Luis's answer is right, if terser than a beginner to the language might hope for. I'll try to elaborate on it a bit, hopefully without creating additional confusion.
Your question is in the context of Lua embedded in a specific model of TI calculator. So there will be details that differ from standalone Lua, but mostly those details will relate to what libraries and functions are made available in your environment. It is unusual (although since Lua is open source, possible) for embedded versions of Lua to differ significantly from the standalone Lua distributed by its authors. (The Lua Binaries is a repository of binaries for many platforms. Lua for Windows is a batteries-included complete distribution for Windows.)
Your sample code has a confounding factor the detail that it needs to interface with a class system provided by the calculator framework. That detail mostly appears as an absence of connection between your equation object and the equation:init() function being called. Since there are techniques that can glue that up, it is just a distraction.
Your question as I understand it boils down to a confusion about how variadic functions (functions with a variable number of arguments) are declared and implemented in Lua. From your comment on Luis's answer, you have been reading the online edition of Programming in Lua (aka PiL). You cited section 5.2. PiL is a good source for background on the language. Unfortunately, variadic functions are one of the features that has been in flux. The edition of the book on line is correct as of Lua version 5.0, but the TI calculator is probably running Lua 5.1.4.
In Lua 5, a variadic function is declared with a parameter list that ends with the symbol ... which stands for the rest of the arguments. In Lua 5.0, the call was implemented with a "magic" local variable named arg which contained a table containing the arguments matching the .... This required that every variadic function create a table when called, which is a source of unnecessary overhead and pressure on the garbage collector. So in Lua 5.1, the implementation was changed: the ... can be used directly in the called function as an alias to the matching arguments, but no table is actually created. Instead, if the count of arguments is needed, you write select("#",...), and if the value of the nth argument is desired you write select(n,...).
A confounding factor in your example comes back to the class system. You want to declare the function equation:init(...). Since this declaration uses the colon syntax, it is equivalent to writing equation.init(self,...). So, when called eventually via the class framework's use of the __call metamethod, the real first argument is named self and the zero or more actual arguments will match the ....
As noted by Amr's comment below, the expression select(n,...) actually returns all the values from the nth argument on, which is particularly useful in this case for constructing self.answers, but also leads to a possible bug in the initialization of self.pipe.
Here is my revised approximation of what you are trying to achieve in your definition of equation:init(), but do note that I don't have one of the TI calculators at hand and this is untested:
function equation:init(...)
self.equation = select(1, ...)
self.pipe = { (select(1,...)) }
self.selected = 1
self.answers = { select(2,...) }
end
In the revised version shown above I have written {(select(1,...))} to create a table containing exactly one element which is the first argument, and {select(2,...)} to create a table containing all the remaining arguments. While there is a limit to the number of values that can be inserted into a table in that way, that limit is related to the number of return values of a function or the number of parameters that can be passed to a function and so cannot be exceeded by the reference to .... Note that this might not be the case in general, and writing { unpack(t) } can result in not copying all of the array part of t.
A slightly less efficient way to write the function would be to write a loop over the passed arguments, which is the version in my original answer. That would look like the following:
function equation:init(...)
self.equation = select(1, ...)
self.pipe = {(select(1,...))}
self.selected = 1
-- Loop arguments to add answers.
local t = {}
for i = 2, select("#",...) do
t[#t+1] = select(i,...)
end
self.answers = t
end
Try
function equation:init(...)
local arg={...}
--- original code here
end
In my Lua script I'm trying to create a function with a variable number of arguments. As far as I know it should work like below, but somehow I get an error with Lua 5.1 on the TI-NSpire (global arg is nil). What am I doing wrong? Thanks!
function equation:init(...)
self.equation = arg[1]
self.answers = {}
self.pipe = {arg[1]}
self.selected = 1
-- Loop arguments to add answers.
for i = 2, #arg do
table.insert(self.answers, arg[i])
end
end
instance = equation({"x^2+8=12", -4, 4})
Luis's answer is right, if terser than a beginner to the language might hope for. I'll try to elaborate on it a bit, hopefully without creating additional confusion.
Your question is in the context of Lua embedded in a specific model of TI calculator. So there will be details that differ from standalone Lua, but mostly those details will relate to what libraries and functions are made available in your environment. It is unusual (although since Lua is open source, possible) for embedded versions of Lua to differ significantly from the standalone Lua distributed by its authors. (The Lua Binaries is a repository of binaries for many platforms. Lua for Windows is a batteries-included complete distribution for Windows.)
Your sample code has a confounding factor the detail that it needs to interface with a class system provided by the calculator framework. That detail mostly appears as an absence of connection between your equation object and the equation:init() function being called. Since there are techniques that can glue that up, it is just a distraction.
Your question as I understand it boils down to a confusion about how variadic functions (functions with a variable number of arguments) are declared and implemented in Lua. From your comment on Luis's answer, you have been reading the online edition of Programming in Lua (aka PiL). You cited section 5.2. PiL is a good source for background on the language. Unfortunately, variadic functions are one of the features that has been in flux. The edition of the book on line is correct as of Lua version 5.0, but the TI calculator is probably running Lua 5.1.4.
In Lua 5, a variadic function is declared with a parameter list that ends with the symbol ... which stands for the rest of the arguments. In Lua 5.0, the call was implemented with a "magic" local variable named arg which contained a table containing the arguments matching the .... This required that every variadic function create a table when called, which is a source of unnecessary overhead and pressure on the garbage collector. So in Lua 5.1, the implementation was changed: the ... can be used directly in the called function as an alias to the matching arguments, but no table is actually created. Instead, if the count of arguments is needed, you write select("#",...), and if the value of the nth argument is desired you write select(n,...).
A confounding factor in your example comes back to the class system. You want to declare the function equation:init(...). Since this declaration uses the colon syntax, it is equivalent to writing equation.init(self,...). So, when called eventually via the class framework's use of the __call metamethod, the real first argument is named self and the zero or more actual arguments will match the ....
As noted by Amr's comment below, the expression select(n,...) actually returns all the values from the nth argument on, which is particularly useful in this case for constructing self.answers, but also leads to a possible bug in the initialization of self.pipe.
Here is my revised approximation of what you are trying to achieve in your definition of equation:init(), but do note that I don't have one of the TI calculators at hand and this is untested:
function equation:init(...)
self.equation = select(1, ...)
self.pipe = { (select(1,...)) }
self.selected = 1
self.answers = { select(2,...) }
end
In the revised version shown above I have written {(select(1,...))} to create a table containing exactly one element which is the first argument, and {select(2,...)} to create a table containing all the remaining arguments. While there is a limit to the number of values that can be inserted into a table in that way, that limit is related to the number of return values of a function or the number of parameters that can be passed to a function and so cannot be exceeded by the reference to .... Note that this might not be the case in general, and writing { unpack(t) } can result in not copying all of the array part of t.
A slightly less efficient way to write the function would be to write a loop over the passed arguments, which is the version in my original answer. That would look like the following:
function equation:init(...)
self.equation = select(1, ...)
self.pipe = {(select(1,...))}
self.selected = 1
-- Loop arguments to add answers.
local t = {}
for i = 2, select("#",...) do
t[#t+1] = select(i,...)
end
self.answers = t
end
Try
function equation:init(...)
local arg={...}
--- original code here
end