<FromGitter>
<asterite> Let's say you have this: ⏎ ⏎ ```if @nilable_int ⏎ do_something ⏎ puts @nilable_int + 1 ⏎ end``` ⏎ ⏎ What id `do_something` sets `@nilable_int` to nil? It's very hard to know, that method could call another method, and another one, and eventually change `self`. Or maybe not even changing it to `nil`, what if it's just increased by 10? If the compiler caches `@nilable_int` to use it later on,
<hightower3>
I meant just that basic one which gives a JSON::Any
<FromGitter>
<Blacksmoke16> `JSON.parse` then?
<hightower3>
Yes, but I thought there was `HTTP::Request#body_json` or something, maybe I confused it with some other thing
<FromGitter>
<Blacksmoke16> nope, you could parse the request's IO with `JSON.parse` tho, as it accepts string or IO
<hightower3>
done so now, great, thanks
<FromGitter>
<moe:busyloop.net> hm yea, i see the problem. still feel like the current available patterns are not ideal, given how frequently that kind of guard is needed. possibly something like a lock could make more sense, `with @foo; ...; end`. so no copying, just preventing other fibers from modifying the ivar. but well, that's just swapping out one boilerplate for another then, not really an improvement either. :/
<FromGitter>
<Blacksmoke16> reminder `#try` and `#not_nil!` are also options depending on your exact context
<FromGitter>
<moe:busyloop.net> yup yup. guess this has been discussed ad nauseam in the past already anyway. was just chiming in when it got brought up again the other day. the available stuff ofc works. i just remain in the camp of those who think it'd be nice if `@foo.bar if @foo` could "just work" w/o extra ceremony. somehow. ;)
Flipez has quit [Changing host]
Flipez has joined #crystal-lang
<FromGitter>
<oprypin:matrix.org> moe (https://matrix.to/#/@moe:busyloop.net): by creating a parallel universe at the branching point? or well, `fork` might be close enough
<FromGitter>
<rishavs> Need a bit of help. I am trying to create a function which returns another function. Not sure how to go about it. ⏎ Here is an attempt I did https://play.crystal-lang.org/#/r/crmu/edit
<FromGitter>
<Blacksmoke16> it returns a `Proc`, which you invoke via `#call`
<FromGitter>
<Blacksmoke16> sometimes think it would be cool if there was a `__invoke()` like method to make things invokable via `()`
<FromGitter>
<rishavs> got it. Thanks @Blacksmoke16 !
<FromGitter>
<Blacksmoke16> in ruby you can do like `obj.()` :S kinda interesting ha
<FromGitter>
<Blacksmoke16> seems to just be an alias to `obj.call` so meh
<FromGitter>
<asterite> In ruby if you write `foo.(1)` it's the same as `foo.call(1)`. For Crystal I thought having two ways to do this was a bit redundant
<FromGitter>
<Blacksmoke16> yea for sure, the latter is way more clear
<FromGitter>
<asterite> exactly! if it were `obj()` it would be better, but it conflicts with other things
<FromGitter>
<Blacksmoke16> conflict with what?
<FromGitter>
<Blacksmoke16> wouldnt the compiler be able to figure out if `obj` or `MyClass` has a `call` method, and expand that to `.call`
<FromGitter>
<Blacksmoke16> otherwise, whatever the error is that "this isnt a method" would result in
Na_Klar has joined #crystal-lang
<Na_Klar>
Why is the crystal compiler not part of the official repos in e.g. debian?
<FromGitter>
<Blacksmoke16> in the past was mainly since it wasn't 1.0.0. These days, not sure if there are plans to do that, or just keep rolling with OBS for that
<FromGitter>
<rishavs> How can I create a recursive tree structure? I want to do something like this ⏎ node = Hash(String, Int32 | String | Bool | node).new
<FromGitter>
<Blacksmoke16> that should w
<FromGitter>
<Blacksmoke16> oops
<FromGitter>
<Blacksmoke16> recursive aliases are kinda frowned upon, but you could deff have a `Node` that has an ivar of that structure
<FromGitter>
<rishavs> The error message kinda threw me off
<FromGitter>
<Blacksmoke16> interesting
waleee has quit [Ping timeout: 256 seconds]
waleee has joined #crystal-lang
<Na_Klar>
Well, I just used the tarball and fetched the dependencies and it runs. I have to say: I love it. Great project! It's my first compile-able language and I hardly have any efford to adjust since being firm in ruby. Lovely.
<FromGitter>
<Blacksmoke16> glad to hear, im sure you'll have to unlearn some rubyisms the more you get into it
<FromGitter>
<Blacksmoke16> 😉
<Na_Klar>
sure. but my first program was a threaded stdin listener. out of the head so to say. worked flawless. ofc there will be differences, but that seems to be a good common start to me.
<FromGitter>
<Blacksmoke16> 👍 nice!
<FromGitter>
<Blacksmoke16> to be clear, by threaded you mean like CPU threads or?
<Na_Klar>
no process threads
<riza>
Na_Klar: my experience has been, the rubyisms served me well
<FromGitter>
<Blacksmoke16> because Crystal is by default single threaded, unless you you're using the experimental flag
<FromGitter>
<Blacksmoke16> i.e. a fiber is not a process thread, or are you just spawning sub processes?
<Na_Klar>
FromGitter: but the OS can dissemitante two running crystal programs to different cores?
<FromGitter>
<Blacksmoke16> and mm im not sure. i imagine it would be up to the OS where to run those processes
<FromGitter>
<Blacksmoke16> at that point tho wouldnt that be more like a multi-process program versus a threaded one?
<Na_Klar>
true
<Na_Klar>
multi-instance even
<FromGitter>
<Blacksmoke16> yup
<riza>
Na_Klar: Adding types to your interfaces will help you a lot. My instinct was to never type things and let the compiler figure it out. It will do that and often impecably so, but it'll also make your code messy because you don't have a clean line where you remove the Nils from your interface.
<riza>
my rule is, anything that's a "public interface" gets explicit types unless there's some reason not to
<FromGitter>
<Blacksmoke16> 🙏
<FromGitter>
<Blacksmoke16> ill also add, even if something *shouldn't* have one, i found it nice to give it one anyway was `_`
<FromGitter>
<Blacksmoke16> anyway as*
<FromGitter>
<Blacksmoke16> functionally is the same as no restriction, but makes it clear thats what it should be, versus just not typed
<riza>
the thing that handicapps me a lot coming from ruby is that I'm used to taking care of nil-things implicitly over ------------------> here
<riza>
but crystal makes you explicitly take care of nil-things <------------- right here
<riza>
declaring types and return types on your interfaces helps with that a lot
<FromGitter>
<Blacksmoke16> take care of it as soon as you can, then downstream code can just not have to deal with it
<riza>
yeah
ur5us has joined #crystal-lang
<Na_Klar>
riza: makes sense. I think strong typing isn't a bad idea anyways.
ur5us_ has joined #crystal-lang
ur5us has quit [Ping timeout: 240 seconds]
<FromGitter>
<moe:busyloop.net> yup definitely better than running into type- and nil-errors after deploying to production. sadly a common thing with ruby. plus tests can focus on the stuff that matters and you need fewer of them. and probably the biggest win: refactoring is no longer a nightmare.
<FromGitter>
<Blacksmoke16> reminder tests are still always good, due to tree shaking
<FromGitter>
<moe:busyloop.net> well, tests never hurt. the problem in ruby is that it remains brittle even with 8x test coverage. esp. when monstrosities like rails are involved.
<FromGitter>
<moe:busyloop.net> update a framework in crystal and the compiler will barf at you. in ruby, you update to the next activerecord minor version, it pulls in 46 updated dependencies and it will still startup fine but then fail in random places.
<FromGitter>
<Blacksmoke16> see if you can spot the problem :P
<Na_Klar>
why would you update the compiler for a programm in production? that's seems like a brave idea to me.
<Na_Klar>
and/or interpreter
<FromGitter>
<Blacksmoke16> you have to eventually. i think his point was more so if you want to migrate from framework/lang version a to b, crystal helps a lot more with discovering errors than ruby due to being compiled
<FromGitter>
<moe:busyloop.net> well in crystal even updating the compiler is no big deal. ⏎ updating the ruby interpreter is indeed a whole nightmare of its own. (got some rails apps still on rails4 cause the update is just not realistic)
<FromGitter>
<moe:busyloop.net> i don't see it. i mean `two` will disappear. but when would that be a problem?
<FromGitter>
<Blacksmoke16> the case where you have a library, with a method that has invalid code (i.e. there is no `String#truncate` method), that is untested
<FromGitter>
<Blacksmoke16> user installs your lib, tries to use it and it fails since they were the first person trying to use it, so was never caught in CI
<FromGitter>
<Blacksmoke16> but if you had at least 1 unit test for it, it would have been detected
<FromGitter>
<Blacksmoke16> not even a unit test per say, but any test that would leverage that method
<FromGitter>
<moe:busyloop.net> well yea... but that's just a case of "untested code is broken code". 🤷 ⏎ in ruby you could have that method covered by 8 tests and it may still randomly return something unexpected.
<FromGitter>
<Blacksmoke16> sure, my point was that the compiler itself (while quite good in of itself) isn't a reason to *not* write tests
<FromGitter>
<Blacksmoke16> i.e. you can have less, but it doesnt fully remove the need for them
<FromGitter>
<moe:busyloop.net> yeh, no tests is always bad. but you def need fewer and they can be much smaller with crystal.
<FromGitter>
<Blacksmoke16> indeed
<FromGitter>
<oprypin:matrix.org> moe (https://matrix.to/#/@moe:busyloop.net): consider that the "in reply to" feature on Matrix gets shown as a sub-thread when bridged to Gitter, so you need to either use it 100% consistently or basically never (probably the only option that's reliable)
<FromGitter>
<moe:busyloop.net> hm, i'll try to resist. ⏎ the other way round they unfortunately also look rather garbled (above it looks like blacksmoke quoted himself a dozen times, even tho he was probably just adding to the thread on the gitter side)
<FromGitter>
<oprypin:matrix.org> yes... when a full-on thread emerges on Gitter, on Matrix side it looks like a battlefield :D
<FromGitter>
<moe:busyloop.net> guess the bridge gives an authentic impression of the gitter UX then. :P
<riza>
meanwhile over here on irc
<FromGitter>
<moe:busyloop.net> but yeh, matrix threads aren't great even when it's native matrix->matrix. ⏎ i don't understand why it takes everyone so long to catch up, slack has it solved for years.
<FromGitter>
<moe:busyloop.net> but looks like matrix is getting there. threads and a few other things are still messy, but for the most part it has become actually very usable, finally.
ejjfunky has joined #crystal-lang
<FromGitter>
<rushsteve1:matrix.org> Hey, I've got a weird use-case that I've been struggling with, and I was wondering if I could get some help/advice. I'm trying to buld both cross-compiled AND static binaries. In particular I have some ARM64 devices running older Linux distros, and I'd like to be able to build fully static binaries that I can just drop on them.
ur5us_ has quit [Read error: Connection reset by peer]
ur5us_ has joined #crystal-lang
<FromGitter>
<rushsteve1:matrix.org> Being ARM devices they're also quite low-power (Chromebooks) so compiling on-device is a no-go.