ChanServ changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
hightower4 has joined #crystal-lang
hightower3 has quit [Ping timeout: 260 seconds]
hightower4 has quit [Remote host closed the connection]
hightower4 has joined #crystal-lang
hightower3 has joined #crystal-lang
hightower4 has quit [Ping timeout: 260 seconds]
ur5us has quit [Ping timeout: 256 seconds]
ur5us has joined #crystal-lang
greenbigfrog has quit [Ping timeout: 252 seconds]
greenbigfrog has joined #crystal-lang
wwalker has quit [Remote host closed the connection]
wwalker has joined #crystal-lang
Sankalp has quit [Ping timeout: 265 seconds]
Sankalp- has joined #crystal-lang
Sankalp- is now known as Sankalp
ur5us has quit [Ping timeout: 260 seconds]
_ht has joined #crystal-lang
<FromGitter> <domgetter> Can a numeric variable change types at runtime? I have a variable such that `puts grid_offset_y.class` prints out `Int32` on one line, and then a few lines later, `puts grid_offset_y.class` prints out `UInt16`. Between the two puts there is an assignment of `grid_offset_y = y + cel.y_offset` where `y` is a UInt16, and `cel.y_offset` is an Int16. Is this expected?
<FromGitter> <domgetter> For now I've wrapped the RHS of the assignment in a `.to_i32!` but I didn't think I had to do that.
kiiNODA has joined #crystal-lang
<FromGitter> <moe:busyloop.net> yup. you re-assigned it, so it then points to the new value. ⏎ ⏎ https://carc.in/#/r/eeoy
kiiNODA has quit []
ur5us has joined #crystal-lang
ur5us has quit [Ping timeout: 260 seconds]
<FromGitter> <domgetter> So is Crystal not statically typed?
<FromGitter> <moe:busyloop.net> it is, but it tries to stay out of your way as much as possible
<FromGitter> <moe:busyloop.net> if you want to reassign vars, it lets you do that - unless/until you create a type-conflict that it can't resolve, then it forces you to be explicit
<FromGitter> <moe:busyloop.net> that's what makes it so fun to write. in other languages you have to declare types everywhere, which gets noisy and annoying quick. ⏎ in crystal the compiler does most of this work for you. in most places you can omit the type and it will infer it.
<FromGitter> <domgetter> I do like the type inference, but I thought that a variable's type couldn't change over time, and that the compiler would infer something like (UInt16 | Int32) instead of making it an Int32 at one point, and then a UInt32 later.
hightower3 has quit [Remote host closed the connection]
hightower3 has joined #crystal-lang
<FromGitter> <moe:busyloop.net> it does such things in certain scenarios. ⏎ but in yours there is no ambiguity.
<FromGitter> <domgetter> Is it possible to puts the type of the variable instead of the class of the object to which it currently refers?
<FromGitter> <moe:busyloop.net> https://carc.in/#/r/eerd
<FromGitter> <moe:busyloop.net> sure :)
<FromGitter> <moe:busyloop.net> you can also assign at the same time: `a : Int32 = 5`
<FromGitter> <domgetter> Hmm when I write `grid_offset_y : (UInt16 | Int32) = 0` it still only ever prints UInt16 or Int32 when I puts the .class or the typeof().
<FromGitter> <moe:busyloop.net> When you use the .class or typeof() method in Crystal, it returns the class of the object at runtime, not the type that was specified in the variable declaration. The type specified in the variable declaration is used at compile-time for type checking, but it does not affect the value of the object at runtime. ⏎ ⏎ In your example, the variable grid_offset_y is defined as a union of UInt16 and
<FromGitter> ... Int32, but at runtime, it can only ever be an instance of one of those classes. The .class or typeof() method will return the class of the actual object that is assigned to the variable, which will be either UInt16 or Int32, not the union of the two.
<FromGitter> <moe:busyloop.net> (chatgpt ftw)
hightower3 has quit [Ping timeout: 256 seconds]
<FromGitter> <domgetter> My question is, is there a way to see that the variable is that type union at runtime?
<FromGitter> <moe:busyloop.net> sec, conferring with gpt
<FromGitter> <moe:busyloop.net> well, the tldr seems to be: nope
<FromGitter> <moe:busyloop.net> or rather, you can do: `var.is_a?(Type.union(UInt16, Int32))` - but the question is why would you want to
<FromGitter> <domgetter> yeah if I already knew it, it would be moot to ask
<FromGitter> <moe:busyloop.net> exactly ;)
<FromGitter> <domgetter> I got tripped up in this case because I didn't know it was inferred to a union
<FromGitter> <moe:busyloop.net> yep, unions can be confusing. but (without knowing your code) my first question about your particular case would be: why is the offset sometimes an Int32 and sometimes an UInt16?
<FromGitter> <domgetter> a `cel.y_offset` is a value from an aseprite project file which is a 16bit signed integer for the current image's pixel data offset to the top left of the canvas, and is signed because pixels can be "off-canvas", `y` is the coordinate within a current cel so it's unsigned since pixel data within a cel can't be "off-cel", and grid_offset_y is a value I created to do analysis with the underlying pixel data in
<FromGitter> ... order to slice them into subsprites for a game, so I had no need or want to limit it to 16bit.
quazimodo has quit [Ping timeout: 268 seconds]
renich has quit [Read error: Connection reset by peer]
hightower2 has joined #crystal-lang
<FromGitter> <moe:busyloop.net> hm yea, then you have to cast it somewhere to the type that your game uses - exactly what the compiler asked you to do above :)
<FromGitter> <moe:busyloop.net> if that causes friction in multiple places then maybe you can move the casting to some "earlier" place (e.g. when the sprite is loaded)
<FromGitter> <Blacksmoke16> you can add type restrictions to local vars. So yes it *can* be statically typed, but its not a requirement in some cases, like local vars
kiiNODA has joined #crystal-lang
kiiNODA has quit [Client Quit]
notzmv has quit [Ping timeout: 260 seconds]
notzmv has joined #crystal-lang
u0_a393 has joined #crystal-lang
notzmv has quit [Ping timeout: 255 seconds]
_ht has quit [Quit: _ht]
u0_a3931 has joined #crystal-lang
u0_a393 has quit [Ping timeout: 260 seconds]
jmdaemon has joined #crystal-lang
jmdaemon has quit [Ping timeout: 256 seconds]
jmdaemon has joined #crystal-lang
notzmv has joined #crystal-lang
jmdaemon has quit [Ping timeout: 268 seconds]
ur5us has joined #crystal-lang
jmdaemon has joined #crystal-lang
jmdaemon has quit [Ping timeout: 272 seconds]
jmdaemon has joined #crystal-lang
jmdaemon has quit [Ping timeout: 256 seconds]
jmdaemon has joined #crystal-lang
jmdaemon has quit [Ping timeout: 272 seconds]
_dave has quit [Read error: Connection reset by peer]
<FromGitter> <domgetter> The way I see it now is that it is statically typed to the union type that I didn't understand. Is that a good way of looking at it?