How to convert data type if Variant.Type is known? - godot

How do I convert the data type if I know the Variant.Type from typeof()?
for example:
var a=5;
var b=6.9;
type_cast(b,typeof(a)); # this makes b an int type value

How do I convert the data type if I know the Variant.Type from typeof()?
You can't. GDScript does not have generics/type templates, so beyond simple type inference, there is no way to specify a type without knowing the type.
Thus, any workaround to cast the value to a type only known at runtime would have to be declared to return Variant, because there is no way to specify the type.
Furthermore, to store the result on a variable, how do you declare the variable if you don't know the type?
Let us have a look at variable declarations. If you do not specify a type, you get a Variant.
For example in this code, a is a Variant that happens to have an int value:
var a = 5
In this other example a is an int:
var a:int = 5
This is also an int:
var a := 5
In this case the variable is typed according to what you are using to initialized, that is the type is inferred.
You may think you can use that like this:
var a = 5
var b := a
Well, no. That is an error. "The variable type can't be inferred". As far as Godot is concerned a does not have a type in this example.
I'm storing data in a json file: { variable:[ typeof(variable), variable_value ] } I added typeof() because for example I store an int but when I reassign it from the file it gets converted to float (one of many other examples)
It is true that JSON is not good at storing Godot types. Which is why many authors do not recommend using JSON to save state.
Now, be aware that we can't get a variable with the right type as explained above. Instead we should try to get a Variant of the right type.
If you cannot change the serialization format, then you are going to need one big match statement. Something like this:
match type:
TYPE_NIL:
return null
TYPE_BOOL:
return bool(value)
TYPE_INT:
return int(value)
TYPE_REAL:
return float(value)
TYPE_STRING:
return str(value)
Those are not all the types that a Variant can hold, but I think it would do for JSON.
Now, if you can change the serialization format, then I will suggest to use str2var and var2str.
For example:
var2str(Vector2(1, 10))
Will return a String value "Vector2( 1, 10 )". And if you do:
str2var("Vector2( 1, 10 )")
You get a Variant with a Vector2 with 1 for the x, and 10 for the y.
This way you can always store Strings, in a human readable format, that Godot can parse. And if you want to do that for whole objects, or you want to put them in a JSON structure, that is up to you.
By the way, you might also be interested in ResourceFormatSaver and ResourceFormatLoader.

Related

Passing a def variable to a typed BigDecimal argument in Groovy

I am new to Groovy so I am a bit confused by the run time binding, typed and not typed attributes of the language. Personally I prefer types to be declared.
However, I have a question.
I have a small method that takes some variable from maps, input, whatever, that I know are numbers. Let's say that I don't know what the initial type was (it's somewhere deep in the code or comes from an external source), other that it was a number. Now I have a method that takes two of these arguments and I have to do a modulo operation on them. Because they might be decimal or not, I wrote a small method using the remainder of BigDecimal so to enforce the type I used the type BigDecimal on the method signature.
def callerMethod(Map map) {
...
map.each{
calledMethod(it.val1, it.val2)
...
}
...
}
def calledMethod(BigDecimal val1, BigDecimal val2) {
...
vl1.remainder(val2)
...
}
Is this correct? If the incoming argument is Integer (most of the time the primitives are boxed if I understand it correctly), will it be implicitly cast or turned into a BigDecimal?
How does this work in Groovy.
I still think that since I have the option to use types, I want to use them rather than declaring everything def. It also makes it easier to read code or see what something is if you reading already existing code
The problem in this methods are not the type of variables, is the each of your map
In a groovy Map, the each have two signatures.
One receive a Map.Entry of parameter and other receive key and value
Ex.:
Map map = [key1:'value1',key2:'value2']
map.each{ Map.Entry entryMap ->
println "The value of key: ${entryMap.key} is ${entryMap.value}"
}
The result of this each will be:
The value of key: key1 is value1
The value of key: key2 is value2
Or could be like this
Map map = [key1:'value1',key2:'value2']
map.each{ def key, def value ->
println "The value of key: ${key} is ${value}"
}
And the result of this second will be the same of the first.
If you want to pass two specific arguments to you calledMethod, pass both outside of the each like this:
def callerMethod(Map map) {
calledMethod(map.val1, map.val2)
}
I don't understand perfectly what you want.. I hope that's help you to do you code.

Pass by Reference in Haskell?

Coming from a C# background, I would say that the ref keyword is very useful in certain situations where changes to a method parameter are desired to directly influence the passed value for value types of for setting a parameter to null.
Also, the out keyword can come in handy when returning a multitude of various logically unconnected values.
My question is: is it possible to pass a parameter to a function by reference in Haskell? If not, what is the direct alternative (if any)?
There is no difference between "pass-by-value" and "pass-by-reference" in languages like Haskell and ML, because it's not possible to assign to a variable in these languages. It's not possible to have "changes to a method parameter" in the first place in influence any passed variable.
It depends on context. Without any context, no, you can't (at least not in the way you mean). With context, you may very well be able to do this if you want. In particular, if you're working in IO or ST, you can use IORef or STRef respectively, as well as mutable arrays, vectors, hash tables, weak hash tables (IO only, I believe), etc. A function can take one or more of these and produce an action that (when executed) will modify the contents of those references.
Another sort of context, StateT, gives the illusion of a mutable "state" value implemented purely. You can use a compound state and pass around lenses into it, simulating references for certain purposes.
My question is: is it possible to pass a parameter to a function by reference in Haskell? If not, what is the direct alternative (if any)?
No, values in Haskell are immutable (well, the do notation can create some illusion of mutability, but it all happens inside a function and is an entirely different topic). If you want to change the value, you will have to return the changed value and let the caller deal with it. For instance, see the random number generating function next that returns the value and the updated RNG.
Also, the out keyword can come in handy when returning a multitude of various logically unconnected values.
Consequently, you can't have out either. If you want to return several entirely disconnected values (at which point you should probably think why are disconnected values being returned from a single function), return a tuple.
No, it's not possible, because Haskell variables are immutable, therefore, the creators of Haskell must have reasoned there's no point of passing a reference that cannot be changed.
consider a Haskell variable:
let x = 37
In order to change this, we need to make a temporary variable, and then set the first variable to the temporary variable (with modifications).
let tripleX = x * 3
let x = tripleX
If Haskell had pass by reference, could we do this?
The answer is no.
Suppose we tried:
tripleVar :: Int -> IO()
tripleVar var = do
let times_3 = var * 3
let var = times_3
The problem with this code is the last line; Although we can imagine the variable being passed by reference, the new variable isn't.
In other words, we're introducing a new local variable with the same name;
Take a look again at the last line:
let var = times_3
Haskell doesn't know that we want to "change" a global variable; since we can't reassign it, we are creating a new variable with the same name on the local scope, thus not changing the reference. :-(
tripleVar :: Int -> IO()
tripleVar var = do
let tripleVar = var
let var = tripleVar * 3
return()
main = do
let x = 4
tripleVar x
print x -- 4 :(

Make a type be either one type or another

I'm a beginner in Haskell playing around with parsing and building an AST. I wonder how one would go about defining types like the following:
A Value can either be an Identifier or a Literal. Right now, I simply have a type Value with two constructors (taking the name of the identifier and the value of the string literal respectively):
data Value = Id String
| Lit String
However, then I wanted to create a type representing an assignment in an AST, so I need something like
data Assignment = Asgn Value Value
But clearly, I always want the first part of an Assignment to always be an Identifier! So I guess I should make Identifier and Literal separate types to better distinguish things:
data Identifier = Id String
data Literal = Lit String
But how do I define Value now? I thaught of something like this:
-- this doesn't actually work...
data Value = (Id String) -- How to make Value be either an Identifier
| (Lit String) -- or a Literal?
I know I can simply do
data Value = ValueId Identifier
| ValueLit Literal
but this struck me as sort of unelegant and got me wondering if there was a better solution?
I first tried to restructure my types so that I would be able to do it with GADTs, but in the end the simpler solution was to go leftroundabout's suggestion. I guess it's not that "unelegant" anyways.

The last challenge of Bytewiser: Array Buffers

The challenge is like that:
Array Buffers are the backend for Typed Arrays. Whereas Buffer in node
is both the raw bytes as well as the encoding/view, Array Buffers are
only raw bytes and you have to create a Typed Array on top of an Array
Buffer in order to access the data.
When you create a new Typed Array and don't give it an Array Buffer to
be a view on top of it will create it's own new Array Buffer instead.
For this challenge, take the integer from process.argv[2] and write it
as the first element in a single element Uint32Array. Then create a
Uint16Array from the Array Buffer of the Uint32Array and log out to
the console the JSON stringified version of the Uint16Array.
Bonus: try to explain the relevance of the integer from
process.argv[2], or explain why the Uint16Array has the particular
values that it does.
The solution given by the author is like that:
var num = +process.argv[2]
var ui32 = new Uint32Array(1)
ui32[0] = num
var ui16 = new Uint16Array(ui32.buffer)
console.log(JSON.stringify(ui16))
I don't understand what does the plus sign in the first line means? And I can't understand the logic of this block of code either.
Thank you a lot if you can solve my puzzle.
Typed arrays are often used in context of asm.js, a strongly typed subset of JavaScript that is highly optimisable. "strongly typed" and "subset of JavaScript" are contradictory requirements, since JavaScript does not natively distinguish integers and floats, and has no way to declare them. Thus, asm.js adopts the convention that the following no-ops on integers and floats respectively serve as declarations and casts:
n|0 is n for every integer
+n is n for every float
Thus,
var num = +process.argv[2]
would be the equivalent of the following line in C or Java:
float num = process.argv[2]
declaring a floating point variable num.
It is puzzling though, I would have expected the following, given the requirement for integers:
var num = (process.argv[2])|0
Even in normal JavaScript though they can have uses, because they will also convert string representations of integers or floats respectively into numbers.

How do I use a Haskell type constructor as an enumeration?

I am writing a program in Haskell that makes use of a lookup table.
eg.
type Table = [(Object, FilePath)]
data Object = Player { pName :: String }
I want to construct this in such a way that Player can be a lookup key:
[(Player, "data/players"), ...]
If I added another Object type Monster, my table might look like:
[(Player, "data/players"), (Monster, "data/mons"), ...]
However, my type definition of a Table suggests that I am looking up instantiated objects when, really, I just want to check if it's one type constructor or the other.
How do I go about doing this?
EDIT:
I suppose I want something like:
data ObjectType = Player | Monster | ...
but is there a way to avoid duplication of the data constructor and type constructor?
You can't really do this in the way you describe. Because Player takes an argument (pName), the type of Player itself is String -> Object, so it won't fit in your Table type properly.
As suggested in your edit, you should probably make a separate enumeration type without arguments specifically for Table:
data ObjectType = PlayerType | MonsterType | ...
Depending on how the other constructors of Object will be defined, you might be able to avoid duplication, e.g.
data Object = Object { objectType :: ObjectType, name :: String }
but that does assume that every kind of Object will have exactly one name argument and nothing else.
EDIT:
On reflection, I wonder if having a lookup table structure makes sense in the first place. You could replace the table with this:
lookupPath :: Object -> String
lookupPath (Player {}) = "data/players"
lookupPath (Monster {}) = "data/mons"
...
This format will make it harder to do things like persisting the table to disk, but does exactly capture your intention of wanting to match on the object without its parameters.
(The Player {} format for the match is the best way to match on constructors that may acquire more arguments in future, as it saves you from having to update the matching code when this happens.)

Resources