jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | 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
<FromGitter> <ImAHopelessDev_gitlab> @Blacksmoke16 https://paste.ee/p/fXJXT lol
<FromGitter> <j8r> you like using hashes instead over objects, do you? :)
<FromGitter> <Blacksmoke16> he likes using everything that would make his life easier
<FromGitter> <Blacksmoke16> er you know what i mean
<FromGitter> <ImAHopelessDev_gitlab> :D
<FromGitter> <j8r> haha... I believe you. for the long run, I doubt
<FromGitter> <j8r> a typo and the compiler won't save you for instance :/
<FromGitter> <Blacksmoke16> yea that code's going to be a nightmare to maintain
<FromGitter> <Blacksmoke16> and/or contribute to if its ever open sourced
<FromGitter> <Blacksmoke16> write any tests yet @ImAHopelessDev_gitlab ?
<FromGitter> <j8r> for JS, I did use some Crystal script to generate Crystal structs to JS objects
<FromGitter> <ImAHopelessDev_gitlab> @Blacksmoke16 i think that's rhetorical ;O
<FromGitter> <ImAHopelessDev_gitlab> i just love using methods on things
<FromGitter> <j8r> between client and server I use byteformat over WebSocket, and both end all is fully typed :D
<FromGitter> <j8r> @ImAHopelessDev_gitlab what do you use for collision detection?
<FromGitter> <ImAHopelessDev_gitlab> ```code paste, see link``` โŽ โŽ i just use simple square based detection on server [https://gitter.im/crystal-lang/crystal?at=5fc82cae924a486dd9e38231]
<FromGitter> <j8r> ha, ok! Me I use all circles, and the map is partitioned into chunks
<FromGitter> <ImAHopelessDev_gitlab> nice
<FromGitter> <j8r> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fc82d07924a486dd9e38278]
<FromGitter> <ImAHopelessDev_gitlab> i got some circle detection code. had to use stackoverflow for that
<FromGitter> <j8r> then, I add remove the radius of both objects, and I'm good
<FromGitter> <j8r> Lol now I think more about we are the total opposite
<FromGitter> <j8r> I use nearly no hashes, even in JS ๐Ÿ˜†
<FromGitter> <ImAHopelessDev_gitlab> i was using a lot of hashes when i started tbh, but for example i like dot notation far better now
<FromGitter> <ImAHopelessDev_gitlab> i like using classes and structs
<FromGitter> <j8r> I believe you it is gonna be hard to refactor this
<FromGitter> <j8r> On my side, if I miss to handle a client/server type message, Crystal won't compile, and the JS test will fail
<FromGitter> <ImAHopelessDev_gitlab> my mind changed on how json.parsing works with crystal too. i used to think JSON any was a type you'd use all over your code. but I feeel like that's a trap. from my experience, JSON::Any is best used as a temporal type, where you use it just at runtime, to create your truly statically typed classes/structs.
<FromGitter> <j8r> or JSON::Serializable. With https://github.com/j8r/crystalizer, you can even convert out of the box
<FromGitter> <j8r> of course, if you know the schema
<FromGitter> <j8r> yes JSON::Any is usually a trap: useful for debugging though
<FromGitter> <ImAHopelessDev_gitlab> i just use it as a helper method so i can have statically typed objects. then i don't even have to worry about calling to_i's or whatever after, as it will be statically typed
<FromGitter> <ImAHopelessDev_gitlab> that's where crystal really starts to shine
<FromGitter> <ImAHopelessDev_gitlab> far less casting, which i like
<FromGitter> <ImAHopelessDev_gitlab> basically
<FromGitter> <ImAHopelessDev_gitlab> cleaner code,too!
<FromGitter> <j8r> why not use `#from_json`?
<FromGitter> <Blacksmoke16> scroll up :P
sagax has quit [Quit: Konversation terminated!]
<FromGitter> <ImAHopelessDev_gitlab> too many issues with that i already tried
<FromGitter> <ImAHopelessDev_gitlab> it's a pita
<FromGitter> <Blacksmoke16> i disagree but ok
<FromGitter> <ImAHopelessDev_gitlab> i found creating a class, then passing in the json data in the parameters manually is easier โŽ โŽ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fc83797f995f9462740cca2]
<FromGitter> <Blacksmoke16> easier than `Hash(Int32, Quest_Schema).from_json File.read "..."`? i doubt it
<FromGitter> <ImAHopelessDev_gitlab> https://paste.ee/p/jYZkv
<FromGitter> <Blacksmoke16> at least name your data file `.json` :p
<FromGitter> <ImAHopelessDev_gitlab> example like that
<FromGitter> <ImAHopelessDev_gitlab> having ot deal with strings that are "" is a pita with a converter
<FromGitter> <Blacksmoke16> in what regard? empty strings are valid json
<FromGitter> <ImAHopelessDev_gitlab> iuno. last time i was pulling my hair out to deal with empty strings, and strings that need to be converted into an Array(Int32). so i just passed everything into the constructor as a parameter
<FromGitter> <ImAHopelessDev_gitlab> and used `semicolon_to_array`
<FromGitter> <Blacksmoke16> can you supply some JSON thats in that Quests file?
<FromGitter> <Blacksmoke16> also you should prob type your ivars
<FromGitter> <Blacksmoke16> atm idt theres anything preventing them from being changed...
<FromGitter> <Blacksmoke16> well i guess its inferred from the default values, nvm
<FromGitter> <ImAHopelessDev_gitlab> json https://paste.ee/p/lVOvO
<FromGitter> <ImAHopelessDev_gitlab> fields like `"quest_rewards":"40;42"` are a PITA
<FromGitter> <Blacksmoke16> why are the hash keys strings?
<FromGitter> <ImAHopelessDev_gitlab> iuno i just deal with how php exports json
<FromGitter> <Blacksmoke16> cant just do like `(int) $id`?
<FromGitter> <ImAHopelessDev_gitlab> iuno, i use php's default json exporter i ain't touching the source
<FromGitter> <Blacksmoke16> welp
<FromGitter> <ImAHopelessDev_gitlab> https://play.crystal-lang.org/#/r/a1eq
<FromGitter> <ImAHopelessDev_gitlab> let's start here
<FromGitter> <ImAHopelessDev_gitlab> i've reduced
<FromGitter> <Blacksmoke16> you got some bad data in there i think...`quest_rewards` is a number in one obj, but strings elsewhere...
<FromGitter> <Blacksmoke16> ones a number, ones an empty string, ones a `;` delimited string
<FromGitter> <ImAHopelessDev_gitlab> yes, if it's just a number, it should be just an array Int32 of size 1 ( the number ). if it's string delimited, it's an array of Int32
<FromGitter> <ImAHopelessDev_gitlab> if string is size == 0, it's just an empty array
<FromGitter> <Blacksmoke16> imo you should fix your data export
<FromGitter> <Blacksmoke16> its pretty shit
<FromGitter> <Leximatica> Hi... quick noob question:
<FromGitter> <Blacksmoke16> then all this would be soo much easier
<FromGitter> <ImAHopelessDev_gitlab> how in the world am i supposed to change the way i export numbers in a list lol
<FromGitter> <Leximatica> Why does this crash the compiler?
<FromGitter> <Leximatica> i = UInt128::MAX โŽ โŽ #>>> 340282366920938463463374607431768211455 โŽ โŽ i = 340282366920938463463374607431768211455_u128 ... [https://gitter.im/crystal-lang/crystal?at=5fc83bfa32153f0d44420f02]
<FromGitter> <ImAHopelessDev_gitlab> if mysql supported a type of Array Int32 i'd do that easily
<FromGitter> <Blacksmoke16> pretty sure `U128` isnt supported
<FromGitter> <Leximatica> 658376483_u128 works just fine
<FromGitter> <Leximatica> As long as the leading integer fits into u64.
<FromGitter> <Leximatica> Why have a _u128 specifier if it doesn't work?
<FromGitter> <Blacksmoke16> dunno, id read that issue
<FromGitter> <Blacksmoke16> @ImAHopelessDev_gitlab https://play.crystal-lang.org/#/r/a1f6
<FromGitter> <Leximatica> Thanks for the pointer to the bug entry. Case closed for me. I'll workaround and wait til the compiler gets fixed.
<FromGitter> <ImAHopelessDev_gitlab> ```code paste, see link``` โŽ โŽ and how exactly whas i supposed to learn ho wto code this [https://gitter.im/crystal-lang/crystal?at=5fc83cccf2a33f3163b024e4]
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/a1f7 fixed string to int keys
<FromGitter> <ImAHopelessDev_gitlab> i lhave no idea what that does. well, i kinda do now since we are on the same page
<FromGitter> <ImAHopelessDev_gitlab> but i couldn't consciously write that code
<FromGitter> <Blacksmoke16> most of this would be easier if your export was better
<FromGitter> <Blacksmoke16> i.e. actual number keys and stuff
<FromGitter> <ImAHopelessDev_gitlab> mysql mayne
<FromGitter> <ImAHopelessDev_gitlab> i can't export as array :(
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/a1f8 oh wait, crystal apparently handles string to int hash keys
<FromGitter> <Blacksmoke16> so there you go
<FromGitter> <Blacksmoke16> and the converter code is actually pretty simple
<FromGitter> <ImAHopelessDev_gitlab> what is `@[JSON::Field(converter: SemicolonToArrayConverter)]` doing
<FromGitter> <Blacksmoke16> telling `JSON::Serializable` that it should use the converter logic for that property
<FromGitter> <ImAHopelessDev_gitlab> "for that property"
<FromGitter> <ImAHopelessDev_gitlab> WHAT
<FromGitter> <Blacksmoke16> versus trying to directly deserialize an array of int32
<FromGitter> <ImAHopelessDev_gitlab> for what property????
<FromGitter> <Blacksmoke16> the one right below the annotation?
<FromGitter> <ImAHopelessDev_gitlab> there are multiple under it
<FromGitter> <Blacksmoke16> the one directly below it
<FromGitter> <ImAHopelessDev_gitlab> and how am i supposed to knwo
<FromGitter> <Blacksmoke16> you do now?
<FromGitter> <ImAHopelessDev_gitlab> it only effects 1 directly below it
<FromGitter> <ImAHopelessDev_gitlab> now i do
<FromGitter> <Blacksmoke16> well there you go :p
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fc83e5bf2a33f3163b027bb]
<FromGitter> <Blacksmoke16> made the converter a bit cleaner
<FromGitter> <ImAHopelessDev_gitlab> well u managed to get it to work witha converter
<FromGitter> <ImAHopelessDev_gitlab> i could never
<FromGitter> <Blacksmoke16> pull parser is kinda a pain to figure out but once you wrap your head around it its pretty simple
<FromGitter> <ImAHopelessDev_gitlab> and yes i agree with you,my export types are sht
<FromGitter> <Blacksmoke16> `pull.kind` returns the "type" of the current token
<FromGitter> <Blacksmoke16> so that we be the scalar number case, which we can just read it as an in and return an array of 1 with it
<FromGitter> <Blacksmoke16> in the case its a string, its either empty or `;` separated, so can read that as a string, split on `;`, remove empty strings, and convert all values to an int and return it
<FromGitter> <Blacksmoke16> otherwise its not something we're expecting, so raise an exception
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/pull/9983 adds some much needed docs to it
<FromGitter> <Blacksmoke16> anyway, a bit simpler than your previous logic eh?
<FromGitter> <ImAHopelessDev_gitlab> it's different, im still processing it
<FromGitter> <ImAHopelessDev_gitlab> but i mean it does look better than what i had..
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <mattrberry> Has there been any thought about moving from Gitter to another service? I feel like we lose a lot since gitterโ€™s search feature is so bad. I often try to search for something and have nothing show up, even if itโ€™s something that I know that *I* sent and I know when I sent it
<FromGitter> <Blacksmoke16> google search is better :P
<FromGitter> <Blacksmoke16> can scope it to gitter and is *fairly* decent
<FromGitter> <mattrberry> But for real though
<FromGitter> <mattrberry> Thatโ€™s what I do now
<FromGitter> <Blacksmoke16> :P
<FromGitter> <mattrberry> Thatโ€™s not a good solution though hahaha when there are so many other chat clients out there
<FromGitter> <Blacksmoke16> there are unofficial slack/discord servers
<FromGitter> <mattrberry> But thatโ€™s not where the core team / active people hang out
<FromGitter> <ImAHopelessDev_gitlab> is our channel indexable by google?
<FromGitter> <mattrberry> That happens here
<FromGitter> <mattrberry> It is indexable
<FromGitter> <Blacksmoke16> related
<FromGitter> <Blacksmoke16> a few core devs are in the discord server
<FromGitter> <Blacksmoke16> its deff more active than the slack one
<FromGitter> <Blacksmoke16> not nearly as active as gitter but :shrug:
<FromGitter> <ImAHopelessDev_gitlab> does google link back to direct chat timestamps in gitter for related questions?
<FromGitter> <mattrberry> Iโ€™m a big fan of discord, but I know some people have their reasons for not liking it
<FromGitter> <mattrberry> It does
<FromGitter> <mattrberry> There are IRCxDiscord bridge bots that people have built for those who donโ€™t like discord :p
<FromGitter> <ImAHopelessDev_gitlab> problem with discord, is it's not indexable in google i think. but i mean i don't know if that's a game changer for googlers
<FromGitter> <ImAHopelessDev_gitlab> they can just search on disc at that point too
<FromGitter> <mattrberry> But discord search is actually just really good, so I donโ€™t see that as an issue
<FromGitter> <ImAHopelessDev_gitlab> true. i'm on godot's discord. search is amazing
<FromGitter> <mattrberry> I can move this conversation to the forums. I just figured Iโ€™d ask after getting fed up with Gitterโ€™s search for like the 50th time lol
<FromGitter> <Blacksmoke16> id read thru that forum thread, this has been brought up before
<FromGitter> <ImAHopelessDev_gitlab> i know discord has a github bot too, so the gitter "activity tab" can essentially be there as well. (godot uses that)
<FromGitter> <ImAHopelessDev_gitlab> i just don't know, because everyone kinda knows about gitter and goes here subconsciously so it'll be hard
<FromGitter> <ImAHopelessDev_gitlab> it's like switching a domain name after you had a domain for a few years
<FromGitter> <mattrberry> Slack link in the forum is dead anyway, thatโ€™s one advantage of discord :p Either way, Iโ€™ll stop clogging up the Gitter chat and move this to the forum maybe :p
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 246 seconds]
chachasmooth has quit [Ping timeout: 246 seconds]
chachasmooth has joined #crystal-lang
<FromGitter> <Leximatica> How do I paste code into my messages here?
<FromGitter> <Blacksmoke16> three `
<FromGitter> <Blacksmoke16> make sure they're on their own line
<FromGitter> <Leximatica> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fc861f9f01b216de2b511f0]
<FromGitter> <Leximatica> So much for that.
<FromGitter> <Leximatica> Anyway, why can't I change the value of ptr[0]?
<FromGitter> <Blacksmoke16> also need them on the bottom
<FromGitter> <Blacksmoke16> before/after
<FromGitter> <Leximatica> (ok thanks)
<FromGitter> <Blacksmoke16> im going to ask the obvious and ask why you need to do this?
<FromGitter> <Leximatica> I'm trying to write a very efficient way to XOR binary numbers stored in strings.
<FromGitter> <Leximatica> "0010100" ^ "0110001", etc.
<FromGitter> <Blacksmoke16> `"0010100".to_i(2) ^ "0110001".to_i(2)`?
<FromGitter> <Leximatica> The various 'idiomatic' approaches are crushingly slow.... yeah, that one.
<FromGitter> <Leximatica> Slow.
avane has quit [Quit: ZNC - https://znc.in]
<FromGitter> <Leximatica> Remember to add in to cost of converting back to a string. Plus, you're limited to 64 bits.
<FromGitter> <Leximatica> Assume I have a good reason for wanting to do this.
<FromGitter> <tenebrousedge> output format?
<FromGitter> <Leximatica> Output format? A string of '0' and '1's.
<FromGitter> <HertzDevil> is writing to a separate buffer significantly slower than mutating the same string
<FromGitter> <Leximatica> Oh yes it is.
avane has joined #crystal-lang
<FromGitter> <Leximatica> The reference says:
<FromGitter> <Leximatica> ptr = Pointer(Int32).malloc(4) # [0, 0, 0, 0] โŽ ptr[1] = 42
<FromGitter> <Leximatica> I really don't understand why that should work and why my code doesn't.
<FromGitter> <tenebrousedge> pointers don't seem useful here
<FromGitter> <Leximatica> Perhaps I should write it in C then, because Crystal can't handle something that simple?
<FromGitter> <Leximatica> I'll have to use pointers to interface with C.
<FromGitter> <Leximatica> There should be no reason for Crystal to force me into C for something so basic.
<FromGitter> <HertzDevil> ~~have you tried not reading them into a crystal string in the first place~~
<FromGitter> <HertzDevil> just work with `Slice` directly
<FromGitter> <Leximatica> I'm choosing to represent the binary sequence in a string so they can be of arbitrary length.
<FromGitter> <Leximatica> I could use BigInt's but they are horrifically slow.
<FromGitter> <Blacksmoke16> couldnt that also be an array of bytes then?
<FromGitter> <HertzDevil> a `Slice` can also be of arbitrary length
<FromGitter> <HertzDevil> actually just use `Pointer.malloc` at this point
<FromGitter> <Leximatica> I need to use the strings as keys in a KV store, which requires strings.
<FromGitter> <Leximatica> Converting bytes to string is costly, as well.
<FromGitter> <tenebrousedge> storing `0` and `1` as `"0"` and `"1"` is kinda inefficient
<FromGitter> <HertzDevil> that's because they are, and if you were to do it in bare metal c you wouldn't have strings and hash tables either
<FromGitter> <Leximatica> Really my question comes down to why the Crystal Reference seems to state that this is direct and simple, and why my attempt is crashing the compiler?
<FromGitter> <Leximatica> It is inefficient. A BitArray would seem to be better. But they are slow as well, according to my benchmarks.
<FromGitter> <Blacksmoke16> did you build with release?
<FromGitter> <Leximatica> There is math involved in bit fiddling, which can be avoided by using extra memory (a full byte) to store each '1' or '0'.
<FromGitter> <Leximatica> No, I'm using playground mostly. I did try once with release however, and got the same error.
<FromGitter> <tenebrousedge> benchmarks that don't use release are probably not good things to base decisions on
<FromGitter> <Leximatica> The representation is space inefficient, but should be execution time efficient.
<FromGitter> <HertzDevil> why can't you use `Slice(UInt8)` as keys
<FromGitter> <Leximatica> I'll try it now, to confirm.
<FromGitter> <HertzDevil> and also are you trying to mutate the keys in a hash, because rehashing incurs its own cost
<FromGitter> <Blacksmoke16> release wouldnt help the fact you're getting an error
<FromGitter> <Blacksmoke16> however any benchmarks you've done without are essentially invalid
<FromGitter> <HertzDevil> now i'm confused
<FromGitter> <HertzDevil> did you crash the compiler, fail to compile, or crash during runtime
<FromGitter> <Leximatica> This particular example is not crashing, with --release.
<FromGitter> <Blacksmoke16> ha, llvm is quite smart so woudnt surprise me if its just removing all that code and hardcoding the output
<FromGitter> <Leximatica> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fc867354b2a214fbdc77d5b]
<FromGitter> <Leximatica> That is giving this:
<FromGitter> <Leximatica> ['?', '?'] โŽ ['?', '?']
<FromGitter> <Leximatica> The write to ptr[0] is simply not happening.
<FromGitter> <Leximatica> But this example isn't actually crashing. A previous example did. And I'm getting a crash in playground.
<FromGitter> <Blacksmoke16> is there some `struct` stuff going on here, like the fact its in an array is getting a copy of the pointer or something?
<FromGitter> <HertzDevil> just maybe
<FromGitter> <HertzDevil> what if the string's contents are encoded in a read-only segment
<FromGitter> <Leximatica> Playground gives this for the exact same code:
<FromGitter> <Leximatica> Invalid memory access (signal 10) at address 0x10b5506c4 โŽ [0x10b4185b6] *Exception::CallStack::print_backtrace:Int32 +118 โŽ [0x10b3f768e] __crystal_sigfault_handler +318 โŽ [0x7fff675715fd] _sigtramp +29 โŽ [0x10b43460f] *Pointer(UInt8)@Pointer(T)#[]=<Int32, UInt8>:UInt8 +15 ... [https://gitter.im/crystal-lang/crystal?at=5fc867b1489041542ff572ee]
<FromGitter> <Leximatica> Yet, --release is not crashing.
<FromGitter> <Blacksmoke16> :S
<FromGitter> <Leximatica> Quinton, that's entirely possible. But I can't find it documented anywhere, and it seems to contradict the Crystal reference docs.
<FromGitter> <Leximatica> And the inconsistent behavior of --release and playground is troubling.
<FromGitter> <Leximatica> Perhaps not so much 'troubling' as 'confusing'.
<FromGitter> <HertzDevil> ```s = String.build do |b| โŽ b << "??" โŽ end โŽ s.to_unsafe[0] = 0x21_u8 โŽ s # => "!?"``` [https://gitter.im/crystal-lang/crystal?at=5fc8685c924a486dd9e403d7]
<FromGitter> <Blacksmoke16> playground is essentially just like `crystal run file.cr`
<FromGitter> <Leximatica> So String.build creates a quasi-mutable string, which a String literal doesn't.
<FromGitter> <Leximatica> ?
<FromGitter> <Leximatica> I missed this in the documentation.
<FromGitter> <HertzDevil> strings are immutable so crystal is allowed to do this i guess
<FromGitter> <Leximatica> Quinton, thanks for that mate. Much appreciated. I'm still unhappy with the dark voodoo. But at least I have a way forward. Hopefully.
<FromGitter> <naqvis> @Leximatica โŽ โŽ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fc86983e30e0e0d50d94a6f]
<FromGitter> <Leximatica> Yes, but str_xor can't handle large strings.
<FromGitter> <naqvis> how long ?
<FromGitter> <naqvis> 64bit?
<FromGitter> <Leximatica> 256 bits.
<FromGitter> <Leximatica> Output of SHA-256.
<FromGitter> <naqvis> then go with `Slice` approach
<FromGitter> <Leximatica> Thanks again!
<FromGitter> <Leximatica> I think that can run faster by giving an allocation size for the String.build, and perhaps also by using raw pointer reads in place of the conversion to _slice.
<FromGitter> <Leximatica> I'll give it go. Thanks all!
<FromGitter> <naqvis> sure, first make things work, then work on the optimization part
<FromGitter> <Leximatica> Yep. Always great advice. :-)
<FromGitter> <naqvis> ๐Ÿ˜†
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fc86b74f995f94627413c95]
twistedpixels has quit [Ping timeout: 264 seconds]
twistedpixels has joined #crystal-lang
<FromGitter> <tenebrousedge> https://github.com/tenebrousedge/aoc2020/blob/master/03/crystal.cr โŽ I'm slow at this
<Andriamanitra> i took ages on the first part having all kinds of stupid bugs... i submitted a wrong answer thinking it was correct at least 5 times :D
<FromGitter> <tenebrousedge> yeah me too
<FromGitter> <tenebrousedge> tay, bedtime
twistedpixels has quit [Ping timeout: 240 seconds]
twistedpixels has joined #crystal-lang
sagax has joined #crystal-lang
<yxhuvud> Hmm. It would be nice if Enumerable#count would accept a zero or whatever, so it was possible to count bigger than Int32::MAX
f1refly has joined #crystal-lang
postmodern has quit [Quit: Leaving]
<kevinsjoberg> yxhuvud: I just stumbled across that myself doing AoC day 3.
<kevinsjoberg> thankfully I could use product with 1_u64 for p2.
<f1refly> Hold on, what part of the second task would require counting to a uint64?
<yxhuvud> it wouldn't, but the product of the numbers need it.
<yxhuvud> or at least they don't fit in i32, didn't check u32.
<kevinsjoberg> f1refly: yep, the product of the numbers.
<kevinsjoberg> So what I ended up with was something like [{1, 1}, {3, 1}, {5, 1}, {7, 1}, {1, 2}].product(1_u64) { |slope| day3.solve(*slope) }
<kevinsjoberg> yxhuvud: IIRC, it's just shy over the upper bound of u32.
<f1refly> Seems like I got lucky then, mine was in the bounds of an i32
<f1refly> Also I wasnt aware of .product, gotta say it looks very nifty
<kevinsjoberg> Yeah, I found it by accident. First implementation I mapped and then did product on the array. But apparently it takes a block as well.
<kevinsjoberg> I believe Ruby doesn't have an equivalent, right?
<f1refly> No idea, I dont speak ruby that well
<FromGitter> <HertzDevil> they don't
<FromGitter> <HertzDevil> they have `Array#product`, but that's the cartesian product
<FromGitter> <HertzDevil> we have that too, although after #10013 it'll simply be called `#cartesian_product` here to avoid the confusion
<DeBot> https://github.com/crystal-lang/crystal/pull/10013 (Move Array#product to Indexable#cartesian_product)
<jhass> I still wish for a better name than that, "cartesian product" is so mathy and anecdotal ("It's called this way because the first dude describing it was called Decartes")
<jhass> but can't really come up with something
<jhass> if it were for just pairs, each_pair would be great
<jhass> but to generalize... :/
<FromGitter> <HertzDevil> "each_pair" sounds like an alias to `each_slice(2)` to me
<jhass> each_cartesian sounds terrible though, sounds like you're iterating through some roman soldiers or whatever :P
<f1refly> I think it's perfectly adequate
<f1refly> You can't just come along and redifine solid mathematical definitions to something that "sounds better"
<f1refly> An alias would maybe work, but I think lots of people would be irritade when `/cartesian` on the api page doesn't find any matches
<jhass> a name is a shortcut to a definition, not the definiton itself. In maths too
<jhass> is that so? Currently it returns no matches.
<jhass> also the full math name is "each_cartesian_nfold_tuple"
<jhass> it's already a rename
<yxhuvud> please don't choose that long name at least :D
<jhass> now if we wanted to be super picky, the cartesian product is even just defined for ordered sets, it's not defined for ordered lists of items, that is it's only defined for distinct elements. Indexable and Enumerable don't iterate over distinct elements, there could be repetitions of the same element. So this is not actually implementing the cartesian product in its strict definition already.
Flipez has quit [Quit: The Lounge - https://thelounge.github.io]
Flipez has joined #crystal-lang
<f1refly> when matching a regex, can I somehow raise if the match returned nil? I'm mass-applying a regex to an array with map and would like to guarantee that there's only matchobjects after the map
<FromGitter> <HertzDevil> `#compact_map`?
<f1refly> but that wouldn't notify me if something goes wrong, right?
<jhass> .match().not_nil!
<f1refly> won't that replace the expressions return value in my map?
<jhass> oh, or just String#[](Regex)
<f1refly> That looks good, thank you :)
<jhass> .match().not_nil! gives you MatchData or raises on nil
<jhass> foo[regex] gives you the match as string (capture group 0) or raises on no match
<f1refly> Yeah, it's what String#match does internally
<f1refly> I just looked into its source
<f1refly> so .not_nil! is what i want then
<f1refly> great
<jhass> there's also some_string[regex, 2] if you're interested in only a particular capture group
<f1refly> I need them all, but yeah I saw that
<f1refly> Ill just use the .not_nil!, it's perfect
<FromGitter> <j8r> if you have a bit more time/space, better using a proper error
f1refly has quit [Ping timeout: 245 seconds]
<FromGitter> <j8r> not nil won't given any useful info, except the back trace
<FromGitter> <j8r> can be done `var = ...match(/.../) || raise "Context info about #{regex]"`
DTZUZU_ has quit [Read error: Connection reset by peer]
DTZUZU has joined #crystal-lang
<FromGitter> <Blacksmoke16> @straight-shoota Is this better? http://athenaframework.org ๐Ÿ˜‰ โŽ โŽ Includes an updated introduction page that does a high level overview of the features, along with differentiating `Athena Framework` from `Athena`. โŽ http://athenaframework.org/components includes a visual depiction of the request flow; going over all the events and such. โŽ `Components` also has subpages for each component and
<FromGitter> ... how it is integrated into Athena, with examples ... [https://gitter.im/crystal-lang/crystal?at=5fc8eb67f46e246609867520]
<straight-shoota> Awesome!
<FromGitter> <Blacksmoke16> ๐Ÿš€
<straight-shoota> The code examples would be way better readable when they would fit into 80 chars linewidth though
HumanG33k has quit [Quit: Leaving]
<FromGitter> <Blacksmoke16> fair enough, yea i could prob reformat some of them
<straight-shoota> And my wish for a really helpful improvement would be a guide for migrating a standard kemal app (or any similar light framework) to athena.
<erdnaxeli> i don't like that crystal tool format does not wrap lines :/
<straight-shoota> Including like how you can serve precompiled assets from disk for example. With kemal that's a simple serve_static
<straight-shoota> erdnaxeli, doing that automatically is really hard and could lead to weird formatting
<erdnaxeli> I agree, but that would be cool :)
<erdnaxeli> at least wrap on function parameters
<erdnaxeli> but yeah it could quickly be tricky
<FromGitter> <Blacksmoke16> @straight-shoota prob not a bad idea. Deff planning on adding a static file handling listener example to the cookbook
<FromGitter> <Blacksmoke16> which would be a start
sagax has quit [Read error: Connection reset by peer]
<FromGitter> <Blacksmoke16> but were you thinking of how kemal concepts map to athena concepts? Or actually show some kemal app with some routes/middleware and show what it looks like in athena land?
<straight-shoota> Hm, prob doesn't matter much whether it's an integrated example or individual pieces.
<kevinsjoberg> @j8r it's funny, I rarely use .not_nil! except for AoC, then I use it all the time, haha.
<straight-shoota> But a guide for the developer who has a kemal app or is familiar with kemal concepts and wants to move to athena
<FromGitter> <Blacksmoke16> so prob would be sufficient to just go over kemal concepts/features and show what the Athena equivalent would be
<FromGitter> <Blacksmoke16> with isolated examples
<straight-shoota> yeah
<FromGitter> <Blacksmoke16> ๐Ÿ‘
<FromGitter> <Blacksmoke16> sounds like a good first article in a `Guides` sub-section
<straight-shoota> I was thinking about moving shardbox.org to athena, but I've been repelled by having to figure out how to "translate" everything by myself
<FromGitter> <Blacksmoke16> i can be considered a resource as well ๐Ÿ˜‰
<FromGitter> <Blacksmoke16> happy to help with anything
<FromGitter> <Blacksmoke16> raz: yea...i should prob get a logo at some point
<straight-shoota> sure, but personal support probably doesn't scale well :D
<raz> blacksmoke16: yup, not too keen on that particular one, but something clean & b/w should look great
<FromGitter> <Blacksmoke16> no, but id say im doing something right when it becomes a problem ha
<raz> (it also helps with making the wall of text more approachable - it is very well written tho, good job! ๐Ÿ‘)
<straight-shoota> Maybe shardbox.org could serve as an example for a Athena migration? I'd say it's a pretty standard Kemal app like many others. Doesn't user kemal's view layer, though.
<straight-shoota> Maybe you could help with that? I'm currently working on switching in Clear as ORM, which is already a great improvement. And it's nearly finished.
HumanG33k has joined #crystal-lang
<FromGitter> <Blacksmoke16> yea could do, ill start to glance thru the code.
<straight-shoota> better wait until the Clear migration is finished
<FromGitter> <Blacksmoke16> ๐Ÿ‘Œ
<FromGitter> <Blacksmoke16> is there a dev branch tho?
<straight-shoota> I've already separated separate controller files in this one
<FromGitter> <Blacksmoke16> ๐Ÿ‘
<FromGitter> <j8r> kevinsjoberg not_nil! is fine for quick and dirty code, like AoC :)
<FromGitter> <j8r> or not so dirty, at least small
<yxhuvud> the more times I've done aoc the less instances of not_nil! there have been. After a while you can learn to avoid it. I tend to use `raise "Unreachable"` quite a lot though
<FromGitter> <Blacksmoke16> @straight-shoota looking thru it a bit, it'll be interesting as im not super familiar with server rendering HTML. I think theres deff parts that will work well, e.x. https://github.com/shardbox/shardbox-web/blob/rewrite-clear/src/controllers/categories.cr#L8-L19.
<FromGitter> <Blacksmoke16> i think the crinja stuff will fit quite well into things as well. Be a good time to try out some stuff
<straight-shoota> So my idea was that the HTML rendering could happen in a view event and the same controller result could be used for a JSON view for example
<FromGitter> <Blacksmoke16> I think it would be possible to do something like: โŽ โŽ `````` [https://gitter.im/crystal-lang/crystal?at=5fc8fc69ebb452409d4fffd5]
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fc8fc72f46e24660986a34c]
<FromGitter> <Blacksmoke16> yea theres deff options when the controller action just returns the data
<FromGitter> <Blacksmoke16> like have a listener check `Accept` header and if its html render template, if its json, fallback to default listener, otherwise could raise a 415
<straight-shoota> exactly
<straight-shoota> For many actions the template rendering needs some additional logic, though.
<straight-shoota> b/c in the HTML rendering, every shard-related page has lots of data in the header and sidebar which is unnecessary in an API response
<straight-shoota> not sure if that could be added by a decorator. But having separate controller actions for these things would probably be fine, too
<FromGitter> <Blacksmoke16> yea ideally there would be separate routes and routing just knows which one to call
<FromGitter> <Blacksmoke16> but that routing feature isnt a thing atm as im essentially using Amber's router ๐Ÿ™ˆ, plus i dont think thats a thing in any router in crystal land :/
<FromGitter> <tenebrousedge> Why did people need `not_nil!` for the AoC?
<FromGitter> <Blacksmoke16> rolling my own router is on the list to support this stuff, but i imagine it would be non trivial...
<FromGitter> <asterite> Kaia: is that a riddle? :)
<FromGitter> <tenebrousedge> I don't think I've used it yet
<FromGitter> <tenebrousedge> I did it before I went to bed last night, curious what other people wrote
<raz> Assertion failed: ((i >= FTy->getNumParams() || FTy->getParamType(i) == Args[i]->getType()) && "Calling a function with a bad signature!"), function init, file /var/cache/omnibus/src/llvm/llvm-6.0.1.src/lib/IR/Instructions.cpp, line 299.
<raz> kaboom
<raz> hmm no nope of reducing this i'm afraid (happens in deeply nested code with blocks etc.). my feeling is it has sth to do with `unless foo.nil?; sth_that_takes_a_block { foo.not_nil! }; end`
<raz> when i comment out that inner call with the block, it disappears. but there's so much nesting and blocks floating around here, it could be unrelated
<FromGitter> <tenebrousedge> maybe use `try` more often?
<FromGitter> <tenebrousedge> `foo.try {|foo| sth_that_takes_a_block { foo } }`
<raz> well, it's no big deal, i can work around it here (there's a combination of lines that works). there's some pretty crazy nesting going on, it seems i somehow slip through a nil/type check that should normally catch this earlier.
<raz> (can unfortunately not provide more useful info, it's a macro that generates a proc that calls other procs... lucky style framework ;))
* FromGitter * tenebrousedge eyes it with fear and suspicion
<raz> someone has to push the limits, otherwise the limits don't get pushed :p
<FromGitter> <tenebrousedge> neat ^_^
<FromGitter> <tenebrousedge> I think I prefer `x += dx` to `x = (i * dx) % map.first.size`
sagax has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> why do i feel like i pass objects too much? for example: https://play.crystal-lang.org/#/r/a1mg/edit โŽ โŽ notice the `do_something_to_monster` method. i'll create a lot of these methods, and then pass in the `monster` object as a parameter. is this a bad style of coding, or is just personal preference?
<FromGitter> <Blacksmoke16> i think it makes more sense to have it be a method you call on the object
<FromGitter> <tenebrousedge> ^
<FromGitter> <ImAHopelessDev_gitlab> i feel like i always keep typing the object's name, then the property. when i should just be typing the property. if that makes sense
<FromGitter> <Blacksmoke16> but depends on the context
<FromGitter> <tenebrousedge> probably most monster behavior should be in modules
<FromGitter> <ImAHopelessDev_gitlab> my entyire codebase is like this. just methods all over
<FromGitter> <ImAHopelessDev_gitlab> taking in objects
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/a1mj
<FromGitter> <Blacksmoke16> then you dont need to expose the properties
<FromGitter> <Blacksmoke16> i.e. `property` to `getter`
<FromGitter> <tenebrousedge> law of demeter
<FromGitter> <ImAHopelessDev_gitlab> when u say expose, odes that mean read the value or set it from outside of it
<FromGitter> <ImAHopelessDev_gitlab> or read from outside of it
<FromGitter> <tenebrousedge> set
<FromGitter> <Blacksmoke16> both
<FromGitter> <tenebrousedge> I mean both, but writing to properties should be very careful
<FromGitter> <ImAHopelessDev_gitlab> https://play.crystal-lang.org/#/r/a1ml
<FromGitter> <Blacksmoke16> all depends on context
<FromGitter> <ImAHopelessDev_gitlab> oh ok i see
<FromGitter> <ImAHopelessDev_gitlab> i feel like property opened me up
<FromGitter> <ImAHopelessDev_gitlab> to accessing objects all over lol
<FromGitter> <tenebrousedge> that's a good way to get spaghetti code and unexpected state changes
<FromGitter> <Blacksmoke16> passing in an object is fine, but when that function is doing nothing but altering the object itself then theres not really a reason to make that a function when it could be a method
<FromGitter> <tenebrousedge> ^
<FromGitter> <ImAHopelessDev_gitlab> like my first example
<FromGitter> <Blacksmoke16> yes
<FromGitter> <ImAHopelessDev_gitlab> correct?
<FromGitter> <tenebrousedge> and if you don't want to do that because you might reuse it, a module is a good idea
<FromGitter> <Blacksmoke16> plus you can have methods that accept objects as well
<FromGitter> <Blacksmoke16> like imagine a `def merge(monster : Monster)`
<FromGitter> <Blacksmoke16> `monster1.merge monster2`
<FromGitter> <ImAHopelessDev_gitlab> man, this transcends outsikde of just crystal too, bcz i do the same in gdscript (godot)
<FromGitter> <ImAHopelessDev_gitlab> i feel like i got a lot of spaghetti code
<FromGitter> <Blacksmoke16> this is OOP
<FromGitter> <Blacksmoke16> you do :p
<FromGitter> <ImAHopelessDev_gitlab> i mean honestly, it's just annoying to re-type the name of the object over and over, it just got em thinkig if i'm doing it wrong
<FromGitter> <ImAHopelessDev_gitlab> because it seemed redundant
<FromGitter> <tenebrousedge> but everyone makes mistakes when they code, from the syntactic to the structural to writing whole projects that don't need to exist
<FromGitter> <tenebrousedge> everything is a learning opportunity, and being able to look at your code and say, "Is there a better way?" is the important skill
<FromGitter> <tenebrousedge> and tbh you've become way better at that @ImAHopelessDev_gitlab
<FromGitter> <tenebrousedge> you're a much better coder than you were this time last year, pretty sure
<FromGitter> <Blacksmoke16> does he still hate `abstract` keyword? :P
<raz> does anyone _not_ hate it? :p
* FromGitter * Blacksmoke16 โœ‹
<FromGitter> <tenebrousedge> I'm not wild about `abstract`, but I probably don't write code meant to be extended too often
<raz> blacksmoke just secretly wants to be a java programmer
<FromGitter> <Blacksmoke16> it has its uses, esp when you're making a framework using interfaces with abstract defs are a key
<raz> but ok, i don't hate it either ;) - i just haven't found great use for it, yet
<FromGitter> <Blacksmoke16> its what allows things to be customized/replaced and everything still work
<FromGitter> <tenebrousedge> ^
<FromGitter> <ImAHopelessDev_gitlab> well ifyou want me to be honest with you, i like passing objects around. it makes it easier FOR ME to understand. but with that said, it might turn code into something it doesn't need to be. for some arbitrary reason, of which i don't know why... take this code (https://i.gyazo.com/0955613231203c45b872f295f7064e64.png) for example. instead, i could just call a method on temp_instance, to set the
<FromGitter> ... data, instead of having to type `temp_instance` every single time.
<FromGitter> <Blacksmoke16> as the internal code is relying upon an abstraction versus a concrete implementation
<raz> yup, in my few endeavours with abstract i've just run into weirdness too often and then just made it a regular class (sometimes with a macro raise when not overridden)
<raz> don't remember what the issues were but i think usually something with inheritance
<FromGitter> <Blacksmoke16> were you using generics?
<FromGitter> <tenebrousedge> `raise when not overridden` is pretty much what `abstract` is
<FromGitter> <Blacksmoke16> but at compile time :p
<raz> have you seen my compiler error from above? of course :P
<FromGitter> <Blacksmoke16> granted the compiler is kinda smart so you can get away without it
<FromGitter> <Blacksmoke16> but having it there allows documenting it and making that contract a bit more explicit
<FromGitter> <tenebrousedge> and yeah @ImAHopelessDev_gitlab it seems like a lot of the property editing would be duplicated effort too
<raz> yup yup, i guess you win. it is a legit feature.
<FromGitter> <ImAHopelessDev_gitlab> i view objects like letters in an envelope. you make the letter really nice, write to it, seal it up, and send it off. that process is how i view it when i pass that object to a method that modifies that object.
<FromGitter> <ImAHopelessDev_gitlab> does that make sense?
<FromGitter> <Blacksmoke16> yes but prob not the most optimal usage
<FromGitter> <tenebrousedge> it does make sense, but it's not how OO typically views things. Which is not to say it's wrong
<raz> it sounds like you treat your objects like structs mostly :)
<FromGitter> <tenebrousedge> OO isn't the end-all be-all of programming. Functional programming tends to have less emphasis on objects
<FromGitter> <Blacksmoke16> again it all depends on the context of what each method is exactly doing
<FromGitter> <Blacksmoke16> some are prob redundant, others are prob a good use case et
<FromGitter> <tenebrousedge> but it's probably important to know why OO exists and what problems it solves
<FromGitter> <tenebrousedge> and Crystal is a pretty OO language
morantron has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> is there performance differences between these two, or is this premature optimization talk?
morantron has quit [Client Quit]
<FromGitter> <tenebrousedge> too context dependent to answer
<FromGitter> <ImAHopelessDev_gitlab> basically, between my first example and blacksmokes, in practice, in a large codebase
<FromGitter> <Blacksmoke16> getting a little abstract but what really helped me is to realize the benefits of interfaces and what they enable. Like to stop thinking about how a specific system works holistically, and instead focus on how various components can be created to accomplish the intended goal. Following along with SOLID principles, i.e. single responsibility, dependency inversion etc
<FromGitter> <Morantron> hi! i want to build a crossplatform (osx and linux), CLI with crystal, but i'm not sure how i should handle the distribution, any tips?
<FromGitter> <Blacksmoke16> from a perf perspective, not really. But it helps a lot in the like maintainability, testability, readability areas
<FromGitter> <ImAHopelessDev_gitlab> you had me until the last sentence
<FromGitter> <tenebrousedge> there could be a slight advantage to not exposing properties
<raz> morantron: homebrew for osx (or you could bake a proper installer). linux is a sad story. probably best to start with snap, but depending on your needs you may also want to (or have to) bake packages for all the major distros (not fun)
<FromGitter> <tenebrousedge> I mean if you're just distributing a static binary...
<FromGitter> <Blacksmoke16> mac doenst support static binaries, so would have to maybe have another `dist_*` job to do that, but more ideally brew is the way to go
<raz> morantron: actually... for both linux & mac you can of course also simply offer binaries for download (but then users won't have auto-updates and need a bit more know-how to install them properly)
<FromGitter> <Morantron> i see
<FromGitter> <ImAHopelessDev_gitlab> i do have to say, the oo approach to my monster example looks much cleaner
<FromGitter> <Blacksmoke16> that thread is prob helpful
<FromGitter> <Morantron> thanks!
<FromGitter> <Morantron> i'm not sure if just requiring users to install `crystal` is a way to go ๐Ÿ˜‚
<FromGitter> <Blacksmoke16> also that post
<FromGitter> <Morantron> oooh, that's super helpful
<FromGitter> <Morantron> if i'm providing binaries, i guess i'll need to implement some sort of update checker to prompt users to upgrade
<FromGitter> <Blacksmoke16> i mean you can ideally do all of the above, brew/snap then binaries on the release
<FromGitter> <Morantron> thanks thanks
<raz> yep, as a user i generally prefer the brew/snap route. lets me install stuff with the commands i already know, and tends to just work
<FromGitter> <Morantron> i'm on archlinux myself, never used `snap` ๐Ÿ™ˆ
<raz> if you want users to upgrade you can just do a little version check in your app and print a message ('please run brew upgrade foobar')
<FromGitter> <Morantron> cool
<raz> yea, snap is a bit of a love/hate thing in the linux community :/
<raz> but the alternative (baking pkgs for all the distros) ain't rosy either
<FromGitter> <Morantron> in my case is just ignorance, don't have an opinion on it
<FromGitter> <Morantron> with arch i'm usually good with pacman and aur community packages
<raz> don't worry, the first time you google it, you'll get all the opinions :D
<FromGitter> <Morantron> hahahaha
<FromGitter> <Morantron> jeez distributing software is hard ๐Ÿ˜‚
<FromGitter> <Blacksmoke16> its nice when packages provide one, as it allows you to use it without manually building when its not in your native manager
<FromGitter> <Blacksmoke16> but if its in your native manager then just use that ofc
<FromGitter> <ImAHopelessDev_gitlab> for example, some my [code here](https://i.imgur.com/EUSwiuB.jpg] feels like i use `monster_obj` too much
<FromGitter> <Blacksmoke16> majority of that could probably live in a `#chase` method or something
<FromGitter> <Blacksmoke16> or `#patrol` depending on what exactly is happening
<raz> or make it an abstract monster that can potentially do both :p
<FromGitter> <ImAHopelessDev_gitlab> basically put the code inside the monster class?
<FromGitter> <tenebrousedge> or a module
<FromGitter> <Blacksmoke16> its quite abstract to think about, but https://gitter.im/crystal-lang/crystal?at=5fc91bfef46e24660986ff6d is beneficial i think
<FromGitter> <ImAHopelessDev_gitlab> like your example, blacksmoke, a monster will have its method to move, etc
<FromGitter> <tenebrousedge> yes
<FromGitter> <Blacksmoke16> its highly unlikely that the solution is as simple as "move all the code into a class"
<FromGitter> <Blacksmoke16> without stepping back and thinking/modeling what the classes are, how they interact etc
<FromGitter> <tenebrousedge> but your Monster class should probably be large
<FromGitter> <ImAHopelessDev_gitlab> ofc but u know what i mean
<FromGitter> <Blacksmoke16> but essentially yes, the monster class itself should expose methods to interact with it
<FromGitter> <Blacksmoke16> i.e. a public API
<FromGitter> <Blacksmoke16> `#move`, `#move_to(location : Location)`, `#attack(object : BaseEntity)` etc
<FromGitter> <Blacksmoke16> at least logic that is common enough
<FromGitter> <Blacksmoke16> then its as easy as like
<FromGitter> <tenebrousedge> this quotation and discussion are also somewhat relevant (https://stackoverflow.com/q/6016271/2487202)
<FromGitter> <ImAHopelessDev_gitlab> @raz "It reminds us that rather than asking an object for data and acting on that data, we should instead tell an object what to do."
<FromGitter> <Blacksmoke16> ```monster.attack cow โŽ monster.attack person``` [https://gitter.im/crystal-lang/crystal?at=5fc91f6de26f8407d3f65dba]
<FromGitter> <ImAHopelessDev_gitlab> i like that
<FromGitter> <tenebrousedge> "It is better to have 100 functions operate on one data structure than 10 functions on 10 data structures." โ€”Alan Perlis
<FromGitter> <ImAHopelessDev_gitlab> i guess the "asking an object for data" is what i do
<FromGitter> <ImAHopelessDev_gitlab> because i feel like it makes me more powerful as a programmer
<FromGitter> <ImAHopelessDev_gitlab> but in reality, it prob makees spaghetti code
<raz> well, it can lead to repetition. `monster.grow(1)` is fewer lines than `monster.width += 1; monster.height += 1` :)
<raz> esp. if you want to do that in multiple places (and perhaps handle common errors that may occur, etc.)
<FromGitter> <ImAHopelessDev_gitlab> iuno. i just feel like i've been comprehending crystal just fine just felt like tpying objec tnames all the time was redundant af
<FromGitter> <tenebrousedge> it is ๐Ÿ˜
<FromGitter> <Blacksmoke16> ask Santa for that for christmas
<FromGitter> <ImAHopelessDev_gitlab> lol
<FromGitter> <Blacksmoke16> https://blog.pragmaticengineer.com/a-philosophy-of-software-design-review/ or at least read thru this guy's summary :p
<FromGitter> <ImAHopelessDev_gitlab> @Blacksmoke16 what do you think of this video https://www.youtube.com/watch?v=QM1iUe6IofM?
<FromGitter> <Blacksmoke16> `Deep vs shallow modules and smart usage of layers` esp this part
<FromGitter> <ImAHopelessDev_gitlab> is this like the flat-earther type video of the software industry, or is he legit
<FromGitter> <tenebrousedge> very few people advocate for procedural programming
<FromGitter> <tenebrousedge> I might call it the MOND of the software world
<FromGitter> <Blacksmoke16> i dont have strong feelings on functional versus oop
<FromGitter> <ImAHopelessDev_gitlab> what's my style of programming
<FromGitter> <Blacksmoke16> i never really used the former so yea
<FromGitter> <Blacksmoke16> ๐Ÿ
<FromGitter> <Blacksmoke16> hybrid of everything xD
<FromGitter> <tenebrousedge> @ImAHopelessDev_gitlab you do a lot of procedural code
<FromGitter> <ImAHopelessDev_gitlab> lol
<FromGitter> <ImAHopelessDev_gitlab> @tenebrousedge thx. i wanted objective view cuz i honestly don't know
<FromGitter> <ImAHopelessDev_gitlab> from someone from the outside of my perspective
<FromGitter> <tenebrousedge> procedural coding isn't wrong, but it's been kinda passed by
<FromGitter> <ImAHopelessDev_gitlab> i take it, blacksmoke is 100% OOP?
<raz> 103%
<FromGitter> <Blacksmoke16> i mean use OO because the languages i use are OO
<FromGitter> <Blacksmoke16> and it works well, im sure there are cases where functional has its benefits but :shrug:
<raz> he goes to the anonymous OOholics because of his factory patterns
<FromGitter> <ImAHopelessDev_gitlab> i find this so interesting, how there is a phenomena between these two styles of programming in human existence in our universe
<raz> well the blacksmoke style turns out to work very well in crystal. i could see it becoming the dominating style
<FromGitter> <tenebrousedge> @ImAHopelessDev_gitlab is mathematics invented or discovered? is software math? is software discovered or invented?
<kevinsjoberg> @tenebrousedge I think I used not_nil! on day two on my regex to access the match data directly.
<raz> it's kinda like java but with the flexibility of ruby
<FromGitter> <tenebrousedge> kevinsjoberg link?
<FromGitter> <Blacksmoke16> my model is just normal OOP, so it makes sense it works well given crystal is OOP :P
<FromGitter> <ImAHopelessDev_gitlab> @tenebrousedge math is discovered, but software is invented. my views anyway
<FromGitter> <Blacksmoke16> i just like to think i have a good grasp on the principles that results in good oop code
<kevinsjoberg> Iโ€™m by no means an expert in Crystal. So take it at that. :)
<raz> OOP is many things tho. java is OOP. and so is ruby. yet their preferred coding styles are very different :)
<FromGitter> <Blacksmoke16> prob more related to one is static and other is dynamic maybe?
<FromGitter> <tenebrousedge> kevinsjoberg, nah that's fine, it's just a different choice, and not a bad one. The other way to do that opens a new block scope
<FromGitter> <ImAHopelessDev_gitlab> maybe it's like everything in life, you have to find a balance in-between them? like relationships
<FromGitter> <Blacksmoke16> prob yea, id say its deff possible to overuse interfaces and stuff
<FromGitter> <ImAHopelessDev_gitlab> there is an equilibrium. i think i went off the deep end with procedural, now gonna do a bit more oop to even myself out
<raz> yup, static vs dynamic seems to be a stronger differentiator nowadays, as most languages are OOP in one way or another
<raz> (except go-lang, which is... just bad)
<FromGitter> <tenebrousedge> `scanf` made my Ruby solution to Day 2 a lot shorter <__< if only there was something similar in Crystal ๐Ÿ˜…
<kevinsjoberg> @tenebrousedge what would be the alternative? Genuinely interested. ๐Ÿ™‚Initially I did it using a if statement, but given I know for fact it will match I thought of not_nil!.
<FromGitter> <ImAHopelessDev_gitlab> man programming is awesome
<FromGitter> <tenebrousedge> using `try` or just passing a block
<kevinsjoberg> Yeah, makes sense.
<FromGitter> <ImAHopelessDev_gitlab> so fascinating when u take a minute and think about it all
<kevinsjoberg> Something about try rubs me the wrong way. Donโ€™t know why though.
<FromGitter> <tenebrousedge> see also the Ruby solution in same folder
<raz> hopeless: i feel like you might enjoy this talk https://www.youtube.com/watch?v=6avJHaC3C2U :)
<FromGitter> <ImAHopelessDev_gitlab> rofl @tenebrousedge never knew ur avatar was an ice cave
<FromGitter> <ImAHopelessDev_gitlab> thought it was a flower
<FromGitter> <tenebrousedge> huh, I could see that
<kevinsjoberg> @tenebrousedge that Ruby solution is a slick.
<FromGitter> <ImAHopelessDev_gitlab> gitter icons ftw. saw your github profile and was like O_O
<FromGitter> <tenebrousedge> that pic was taken a looooong time ago
<FromGitter> <tenebrousedge> but hey it's cool so w/e
<FromGitter> <tenebrousedge> kevinsjoberg yeah `scanf` is great, I wrote a `crscanf` but it is apparently too buggy to be useful >_< which it was limited before, but I think I need to take another crack at it
<kevinsjoberg> Apparently used not_nil! for day 1 as well.
<FromGitter> <ImAHopelessDev_gitlab> @tenebrousedge ilike your blog
<FromGitter> <tenebrousedge> oh god I have a blog? that's online?
<FromGitter> <ImAHopelessDev_gitlab> good to see simple websites that actually load fast w/o crap nowadays
<FromGitter> <ImAHopelessDev_gitlab> eh, website
<FromGitter> <tenebrousedge> hmmm I bet it has the wrong name on it
<Andriamanitra> anyone know of a good style guide for crystal? my whitespace is all over the place and i can't be bothered to think of one for myself
<Andriamanitra> that's way too limited
<FromGitter> <ImAHopelessDev_gitlab> use converter on save with a text editor will help
<FromGitter> <tenebrousedge> `crystal tool format`
<FromGitter> <Blacksmoke16> limited how? what's missing?
<Andriamanitra> tenebrousedge: thanks, that does the trick
<Andriamanitra> Blacksmoke16: i don't know where i'm supposed to put whitespace
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <Blacksmoke16> > Within a class, separate method definitions, constants and inner class definitions with one newline.
<Andriamanitra> whitespace around .map { |x| x + 1 } seemed to be the one thing i was mostly inconsistent about
<FromGitter> <Blacksmoke16> ๐Ÿ‘
<FromGitter> <tenebrousedge> yeah I do that too
<FromGitter> <tenebrousedge> not the `+` but I squish my blocks together
<FromGitter> <ImAHopelessDev_gitlab> sounds hot
<FromGitter> <Blacksmoke16> depending on what editor you're using it might have a feature to format on save
<Andriamanitra> that's a good idea, i'll look into it
<FromGitter> <ImAHopelessDev_gitlab> if you want to use notepad++, lmk i got a guide on a forum to get it working
<FromGitter> <tenebrousedge> @Blacksmoke16 why does my code not produce the same answers in Ruby and Crystal?
<FromGitter> <Blacksmoke16> what code
<FromGitter> <tenebrousedge> my AOC day 3 (https://github.com/tenebrousedge/aoc2020/blob/master/03/crystal.cr). The `slope` method should be the same in both languages, but in practice...
<FromGitter> <Blacksmoke16> oh dunno, havent been doing those
<FromGitter> <Blacksmoke16> one question i did think of, whats the benefit of `"#{__DIR__}/input.txt"` versus `"./input.txt"`
<FromGitter> <ImAHopelessDev_gitlab> LOL
<FromGitter> <tenebrousedge> I'm not always running it from the same dir as the file?
<FromGitter> <Blacksmoke16> oh, is it not relative to the file its in
<FromGitter> <Blacksmoke16> that makes sense then ha
<FromGitter> <ImAHopelessDev_gitlab> curious george over here
<FromGitter> <RespiteSage> @tenebrousedge How does Ruby handle integer boundaries and overflow?
<kevinsjoberg> @tenebrousedge we have pretty much identical solutions except that you have a tuple of tuples and I have a array of tuples. Is there a benefit of having it as a tuple of tuples?
<kevinsjoberg> I know tuples are allocated on the stack, while arrays are allocated on the heap but is there a noticeable performance diff?
<FromGitter> <Blacksmoke16> given the size is static yes
<FromGitter> <Blacksmoke16> doesnt have to allocate the array
<FromGitter> <ImAHopelessDev_gitlab> oh boy here we go
<kevinsjoberg> :P
<FromGitter> <tenebrousedge> @RespiteSage just testing the `slope` method. Ruby should handle the large int just fine though
<FromGitter> <RespiteSage> Huh. So you're just using the same code in Ruby, but it's not giving the same output?
<FromGitter> <tenebrousedge> asterite did array of tuples too
<FromGitter> <tenebrousedge> yes
<FromGitter> <tenebrousedge> lemme gist, it's almost identical
<FromGitter> <tenebrousedge> produces `77` instead of `162`
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<FromGitter> <RespiteSage> Does Crystal `File.readlines` strip the input? I thought so, and it looks like Ruby doesn't: docs (https://ruby-doc.org/core-1.9.3/IO.html#method-c-readlines)
<FromGitter> <tenebrousedge> ah right, I even noticed that earlier
<FromGitter> <tenebrousedge> need to pass `chomp: true`
<FromGitter> <RespiteSage> So maybe the `WIDTH` is just messed up?
<FromGitter> <tenebrousedge> yup that was it
<FromGitter> <tenebrousedge> thanks
<FromGitter> <RespiteSage> Np.
HumanG33k has quit [Remote host closed the connection]
<kevinsjoberg> Having done a lot of Crystal lately, I sure miss external names for method arguments
<FromGitter> <tenebrousedge> huh?
<kevinsjoberg> In Ruby I mean
HumanG33k has joined #crystal-lang
<kevinsjoberg> It's really nice having the ability to provide a nice API for the caller while still using having a meaningful name within the method body.
<kevinsjoberg> s/using//
<FromGitter> <tenebrousedge> how is the syntax different?
<kevinsjoberg> I mean having the ability to do this def inc(by amount)
<FromGitter> <tenebrousedge> you mean overloading?
<kevinsjoberg> No, I mean external names for method arguments
<kevinsjoberg> so when I call inc I use inc(by: 1).
<kevinsjoberg> But within the method I use amount to reference the value.
<FromGitter> <ImAHopelessDev_gitlab> the value to reference a reference ?
<FromGitter> <ImAHopelessDev_gitlab> how is that working
<FromGitter> <tenebrousedge> huh. I think I forgot that existed
<FromGitter> <ImAHopelessDev_gitlab> what's `by` doing
<kevinsjoberg> So it's the external name for the amount parameter.
<FromGitter> <ImAHopelessDev_gitlab> there is no comma or `:`
HumanG33k has quit [Remote host closed the connection]
<FromGitter> <tenebrousedge> scroll to bottom
<FromGitter> <ImAHopelessDev_gitlab> it's an `External names`?
<kevinsjoberg> Yep!
<kevinsjoberg> I think it's super sweet.
<FromGitter> <ImAHopelessDev_gitlab> wtf never knew
<kevinsjoberg> I have missed that a lot of times in Ruby land.
HumanG33k has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> when i first looked, i thougt it was a typo lol
<kevinsjoberg> haha, I can imagine.
<FromGitter> <ImAHopelessDev_gitlab> https://play.crystal-lang.org/#/r/a1oi
<FromGitter> <ImAHopelessDev_gitlab> the wrath of `begin`
HumanG33k has quit [Client Quit]
<FromGitter> <Blacksmoke16> begin/rescue there is redundant
<FromGitter> <ImAHopelessDev_gitlab> no it isn't
<FromGitter> <tenebrousedge> I like `def ... rescue ... end`
<FromGitter> <ImAHopelessDev_gitlab> begin and rescue are keywords stapled across the language
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/a1op
<FromGitter> <ImAHopelessDev_gitlab> using begin as an external name is retarded
<FromGitter> <tenebrousedge> yeah what @Blacksmoke16 did
<FromGitter> <ImAHopelessDev_gitlab> let's use a keyword used across the language for blocks of code
<FromGitter> <ImAHopelessDev_gitlab> put in the docs, let use it as an external name!
<FromGitter> <tenebrousedge> using `begin` as a named parameter probably makes sense for some things
<FromGitter> <tenebrousedge> there's definitely nothing wrong with a symbol `:begin`
<FromGitter> <Blacksmoke16> like a calendar event
<FromGitter> <ImAHopelessDev_gitlab> start and end are much choices than begin and end
<FromGitter> <Blacksmoke16> but `start/end` is prob more likely
<FromGitter> <ImAHopelessDev_gitlab> better choices*
<FromGitter> <tenebrousedge> well `end` isn't great to use
<FromGitter> <tenebrousedge> I mean if you're going to complain about using `begin`, using `end` would be madness
<FromGitter> <ImAHopelessDev_gitlab> well, the dev should figure out a new external name that's not a keyword
<FromGitter> <ImAHopelessDev_gitlab> used in the language
<FromGitter> <ImAHopelessDev_gitlab> bcz that example in the doc is terrible
duane has quit [Remote host closed the connection]
<FromGitter> <ImAHopelessDev_gitlab> doesn't evne work, bcz time.now was radically changed
<FromGitter> <tenebrousedge> the example is purposefully bad, if that's bad
<FromGitter> <ImAHopelessDev_gitlab> for some reason, Time.now didn't make sense
<FromGitter> <ImAHopelessDev_gitlab> so it was changed
<FromGitter> <tenebrousedge> the point is to show how you can use keywords, not necessarily to encourage their use, but "Hey this is possible"
<FromGitter> <tenebrousedge> allowed by the syntax even
<FromGitter> <tenebrousedge> and yeah `Time.now` is ambiguous
<FromGitter> <tenebrousedge> is that local or unix or UTC?
<FromGitter> <ImAHopelessDev_gitlab> ambiguous to what?
<FromGitter> <tenebrousedge> `Time.now` could mean local time, utc, or unix time. All are perfectly valid choices
<FromGitter> <ImAHopelessDev_gitlab> `.now` means local
duane has joined #crystal-lang
<FromGitter> <tenebrousedge> I think it should be unix time
<Andriamanitra> isn't unix time the same regardless of time zone
<FromGitter> <ImAHopelessDev_gitlab> https://i.gyazo.com/5546f6778e6edf3e093fdb2d84e97974.mp4 wtf is up with this scroll menu
<FromGitter> <ImAHopelessDev_gitlab> can't even scroll up and down smoothly
<FromGitter> <ImAHopelessDev_gitlab> it literally stops halfway, then bounces back
<FromGitter> <ImAHopelessDev_gitlab> then goes up/down
hightower2 has joined #crystal-lang
<Andriamanitra> oh i guess crystal's time objects include a specific time zone for some reason.. can't say i agree with that decision
<FromGitter> <tenebrousedge> time really does need a geospatial component
<hightower2> Hey, I am replacing a small HTTP API handler that's composed of just one endpoint and accepts 15 query args (some optional, some required). Due to this very limited need, I am using HTTP::Server directly. I already have code which checks that all required and some optional args are present. What general code would you suggest for checking whether the arg values are of correct type (string, int, bool etc.)?
<FromGitter> <Blacksmoke16> try to convert them and catch the exception?
<FromGitter> <ImAHopelessDev_gitlab> `typeof` on them maybe?
<FromGitter> <Blacksmoke16> always going to be a string
<hightower2> typeof will probably be string for all of them, right? when I read them from HTTP::Params
<FromGitter> <Blacksmoke16> regex might work too if its just simple stuff
<FromGitter> <Blacksmoke16> like `/\d+/` and `/true|false/`
<FromGitter> <ImAHopelessDev_gitlab> https://play.crystal-lang.org/#/r/a1pg
<FromGitter> <tenebrousedge> maybe use like a class or struct to wrap the args, check types and do conversions
<FromGitter> <Blacksmoke16> @ImAHopelessDev_gitlab right but these values are not scalar
<FromGitter> <Blacksmoke16> they're coming from query params
<hightower2> yeah tenebrousedge great idea, especially since I also want to normalize the keys/values (since some args have alias names etc.)
<FromGitter> <tenebrousedge> @ImAHopelessDev_gitlab for an API call all the values will be strings
<hightower2> OK great, thanks for input all.
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/a1qe
<FromGitter> <Blacksmoke16> @ImAHopelessDev_gitlab
<FromGitter> <ImAHopelessDev_gitlab> https://play.crystal-lang.org/#/r/a1qv
<FromGitter> <ImAHopelessDev_gitlab> why can't this be caught
<FromGitter> <Blacksmoke16> prob because its not an exception?
<FromGitter> <ImAHopelessDev_gitlab> it's an error
<FromGitter> <ImAHopelessDev_gitlab> an error is an exception
<FromGitter> <Blacksmoke16> er no, it should be a https://crystal-lang.org/api/master/TypeCastError.html
postmodern has joined #crystal-lang
<FromGitter> <Blacksmoke16> which it doesnt seem to be raising that exception...
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/a1rd whereas this works
<FromGitter> <Blacksmoke16> prob a bug?
<Andriamanitra> generally error refers to something that happens compile-time and exception is something that happens at runtime, so no, error is not an exception (in the programming world)
<postmodern> how do you handle the case when your writing C bindings, but the library name may be different on different distros? Is there a way to specify alternate linking lib names, or would I have to write a tiny configure.sh script to search for the library and generate a .cr file?
<FromGitter> <Blacksmoke16> ^ is why PHP has the `Throwable` type, as an Error is not an Exception, but both are Throwable
<FromGitter> <tenebrousedge> postmodern maybe a makefile would help
<FromGitter> <RespiteSage> Isn't `#as` actually a compile-time flag for casting?
<FromGitter> <RespiteSage> Huh. But the array works...
<jhass> postmodern: one would hope the pkgconfig name is the same and use that
<jhass> otherwise you can use a run macro or compile time backticks, {{``}}
<jhass> to figure it out
<jhass> https://github.com/crystal-lang/crystal/blob/master/src/openssl/lib_ssl.cr ships a good example of how complex you can get
<postmodern> jhass, oh thank you. Also, ugh that is some gnarly looking macro code :/
<jhass> it is, it's a gnarly problem
<FromGitter> <ImAHopelessDev_gitlab> and how does a developer know the difference between as(Int32) gets executed as compile time, when .to_i is a runtime exception
<raz> you guys clearly haven't seen _gnarly_ macros yet :p
<jhass> much better if you have a consistent pkgconfig name https://github.com/crystal-lang/crystal/blob/master/src/yaml/lib_yaml.cr#L4
<FromGitter> <tenebrousedge> I'm writing a really nasty macro at the moment actually ๐Ÿ˜ฌ
<FromGitter> <tenebrousedge> @Blacksmoke16 has some good ones
<raz> yea, just sayin', that openssl thingy looks surprisingly legible to me :D - just a bunch of if's and elses
<FromGitter> <Blacksmoke16> my macros are *clean*, at least as much as i can when you cant reuse any of it
<FromGitter> <Blacksmoke16> wtb reusable macro code
<FromGitter> <ImAHopelessDev_gitlab> so what's the solution to @hightower2's question
<FromGitter> <ImAHopelessDev_gitlab> im stillt rying to figure this out
<FromGitter> <ImAHopelessDev_gitlab> how do we get the type from a string
<FromGitter> <tenebrousedge> convert it
<FromGitter> <ImAHopelessDev_gitlab> i tried, but i get an error
<FromGitter> <ImAHopelessDev_gitlab> and i can't rescue it
<FromGitter> <tenebrousedge> `"123".to_i`
<postmodern> jhass, would you recommend always using the pkg-config --libs method? What are the odds that some random pkg has weird -L flags or was renamed?
<FromGitter> <Blacksmoke16> ye, .as isnt what you really want to use in this context
<jhass> postmodern: take homebrew, very high
<FromGitter> <Blacksmoke16> .as is mainly for if you have a union of types and want to make the type more specific
<FromGitter> <ImAHopelessDev_gitlab> wtf does making a type more specific even mean
<FromGitter> <Blacksmoke16> but it does seem there is a bug in your example, maybe jhass has some thoughts :p
<hightower2> Hey will indirect initialization be supported in 1.0? I mean this: https://carc.in/#/r/a1rt
<FromGitter> <ImAHopelessDev_gitlab> isn't a type arbitrary
<FromGitter> <tenebrousedge> no?
<jhass> postmodern: not all libs or distros ship pkgconfig unfortunately, but if it works for your targets it's highly preferable IMO
<FromGitter> <ImAHopelessDev_gitlab> A type is a type
<FromGitter> <ImAHopelessDev_gitlab> How can a type, be "more specific"
<FromGitter> <tenebrousedge> say you have `Array(String | Int32)`, but you know that it will never have `Int32` in it. You can narrow the type using `as`
<FromGitter> <Blacksmoke16> hightower2 depending on your use case theres a work around, e.x.
<hightower2> ImAHopelessDev_gitlab: all query params are strings. But if I want to pass arg, say, &number=11, I want to actually read 11 as an int, not string. So you do param["number"].to_i
<FromGitter> <ImAHopelessDev_gitlab> is that statically typed at taht point?
<FromGitter> <tenebrousedge> yes, Crystal is statically typed
<FromGitter> <Blacksmoke16> using like `getter!`, but then have to do like `self.doit` versus `@doit`
<FromGitter> <ImAHopelessDev_gitlab> how if an array could be a string or int32
<FromGitter> <ImAHopelessDev_gitlab> and if know there will never be an int32 in it, why did i specify it as a type
<FromGitter> <tenebrousedge> static typing is usually contrasted with things like being able to do `1 + "1"`
<postmodern> also what is the general consensus on naming conventions for C binding libs vs. pure Crysal implementation libs?
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/a1s2
<FromGitter> <tenebrousedge> where the interpreter will mangle your types automatically
<jhass> postmodern: didn't notice any
<FromGitter> <tenebrousedge> or (apparently) SQLite, which lets you store any type in any column
<hightower2> Blacksmoke16: hm it appears even @doit works -- https://carc.in/#/r/a1s7
<FromGitter> <Blacksmoke16> sorry, i meant when using the ivar within the type
<FromGitter> <ImAHopelessDev_gitlab> https://play.crystal-lang.org/#/r/a1sc/edit
<FromGitter> <Blacksmoke16> as the `!` makes it nilable, but defines a getter that uses `.not_nil!`
<FromGitter> <ImAHopelessDev_gitlab> so now it's not an error, but an exception???
<FromGitter> <ImAHopelessDev_gitlab> wtf is going on
<FromGitter> <Blacksmoke16> as i said, im pretty sure its a bug with that one context
<hightower2> hm... interesting solution..
<hightower2> not sure that I really like it conceptually, but well
<FromGitter> <Blacksmoke16> depends on your use case
<hightower2> right
<hightower2> ok, great, thanks!
<FromGitter> <Blacksmoke16> as it moves errors to runtime
<FromGitter> <ImAHopelessDev_gitlab> i think there should be typeof alternative, that adev can use to get a type of a string
<FromGitter> <ImAHopelessDev_gitlab> i mean, the actual type of a string
<hightower2> ImAHopelessDev_gitlab you're trippin' :)
<FromGitter> <Blacksmoke16> oh boy
<FromGitter> <Blacksmoke16> how would it know
<FromGitter> <ImAHopelessDev_gitlab> typeof only works for native types, should be another variant to check for the actual type. for exampe, using @tenebrousedge meethod wrapped in a functioni or something
<FromGitter> <RespiteSage> What do you mean by "actual type"?
<FromGitter> <ImAHopelessDev_gitlab> based on a string* srry
<FromGitter> <RespiteSage> The type of the data that someone is representing with the string?
<hightower2> what if it's json in it? :)
<FromGitter> <tenebrousedge> you can represent arbitrary data using text. You can even sometimes represent the speech of programmers with it
<FromGitter> <ImAHopelessDev_gitlab> for example, the link blacksmoke posted https://play.crystal-lang.org/#/r/a1qe
<FromGitter> <ImAHopelessDev_gitlab> should be another way to handle the types from a string easier
<FromGitter> <Blacksmoke16> how would the compiler know when they're runtime values?
<FromGitter> <tenebrousedge> PHP makes its best guess, and frequently fails
<FromGitter> <ImAHopelessDev_gitlab> i don't mean a compile-time thing, just a helper method
<FromGitter> <RespiteSage> What type is `"one"`?
<FromGitter> <ImAHopelessDev_gitlab> similar how typeof works, but for strings at runtime
<jhass> what type is "tRuE"?
<FromGitter> <ImAHopelessDev_gitlab> string
<FromGitter> <Blacksmoke16> i did something similar for athena https://github.com/athena-framework/athena/blob/master/src/ext/conversion_types.cr
<jhass> what type is "tRuE".downcase?
<FromGitter> <Blacksmoke16> but you still need to know what type the string should try to be converted to
<FromGitter> <RespiteSage> Yeah, it's just always going to be much safer to have a purpose-built conversion for your input.
<FromGitter> <ImAHopelessDev_gitlab> bool
<postmodern> jhass, there's already a msgpack-crystal library that's a pure crystal implementation. was thinking about porting over my FFI bindings to libmsgpack[c]
<FromGitter> <Blacksmoke16> idt its possible to do that arbitrarily
<FromGitter> <tenebrousedge> it's not that it's impossible for the runtime to guess and see what happens. But Crystal is not the language for that
<FromGitter> <ImAHopelessDev_gitlab> i'm just trying to address @hightower2's question bcz it sounds like he has to do all that when it could be much simpler, especially since we got typeof already
<FromGitter> <tenebrousedge> PHP and to some degree JavaScript do this
<FromGitter> <ImAHopelessDev_gitlab> i wish as(Type) would work, and we could catch it with a rescue
<FromGitter> <RespiteSage> I mean, you could certainly just have a big list of rules that you use to convert from strings to other types, but someone has to decide those rules, and the rules are going to be wrong sometimes in unexpected ways.
<FromGitter> <ImAHopelessDev_gitlab> but it's not an "exception" it's a compile time error, apparently
<jhass> it's valid to parse this from a string, (though I wouldn't know why you wouldn't just parse it and check the resulting .class), but it's highly application domain specific, it's nothing stdlib should attempt
<raz> the average life of a web developer only has 4 types anyway. string, integer, boolean and "arrr, god damnit"
<FromGitter> <Blacksmoke16> @ImAHopelessDev_gitlab again, im pretty sure that one case is a bug, given its an exception for other usages
<FromGitter> <Blacksmoke16> and its not a compiler error since the code runs
<FromGitter> <ImAHopelessDev_gitlab> im just saying a helper method that wraps .as(Type) and returns it correctly, so the dev doesn't need to do all the checks for basic types, int32, string, bool (like what hightower's question). maybe a shard or just a little helper method would do it
<FromGitter> <RespiteSage> I'm not sure. Whoever implemented it might've thought that having the earlier compile-time warning in cases where it was obviously wrong is better.
<FromGitter> <RespiteSage> @ImAHopelessDev_gitlab Unfortunately, `#as` is documented as being impossible to override.
<FromGitter> <ImAHopelessDev_gitlab> for his case he just wants to know if it's an int32, bool, or string. seems like there should be a built in method to know that from a string...
<jhass> postmodern: I guess the question how much abstraction you want to provide on top, given shards works decentral even reusing the same name ain't too bad. If it's a very one to one binding to the lib I'd consider crystal-libmsgpack or libmsgpack.cr as repo name and just libmsgpack as shard name
<jhass> but it's fully ymmv
<raz> > even reusing the same name ain't too bad
<raz> VETO! please don't do that
<jhass> who's gonna try to use both in the same project?
<jhass> it's pretty much an either or situation
<raz> nobody, but everybody will hate you when they try to google it
<Andriamanitra> ImAHopelessDev: problem is that sometimes you actually want a string "123" and NOT the number 123, that's why you use .to_i when you want to get the number out of the string
<jhass> @hopeless: casting in a helper method has no point, as the helper returns all the possible types it reforms the union
<jhass> casting is a hint to the compiler, at runtime it's just one of the union types at any given point
<FromGitter> <ImAHopelessDev_gitlab> @andrianmanitra that's a good point, maybe it's too specific to their codebase and what they are doing with that data
<Andriamanitra> even in this particular example you could think of an url parameter "username", now imagine if user wanted to be called "133780085", your proposed "typeof function" would say that's a number and you'd run into all kinds of problems
<Andriamanitra> as username should always be a string
<FromGitter> <ImAHopelessDev_gitlab> yeah seems like the dev would just need to accept that as a string then
<FromGitter> <ImAHopelessDev_gitlab> there's no way to know the future for that particular use case for that developer
<raz> yup, wasn't that the point? as(String) gives a string, even when the input came in as an integer for a reason?
<Andriamanitra> you can'
<Andriamanitra> t use .as to convert anything
<Andriamanitra> just think of it more as an assertion about the type
<raz> i meant the 'as' he was asking for, not the one that exists ;)
<Andriamanitra> ah :)
<raz> but yea, agree, the idea seems difficult to generalize
<jhass> so I think the topic y'all are thinking about it is called type coercion
<raz> finally someone brings in the proper vocabulary o/
<raz> yap, i had it on the tip of my tongue but it eluded me
<jhass> implicit type coercion is what makes PHP and JS so brittle, Ruby ships some more explicit type coercion (check the coerce method), Crystal implements some implicit coercion for number types only
<jhass> for and between I wanted to say
<yxhuvud> jhass: C too, I'd say.
<FromGitter> <Blacksmoke16> oh wait
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Class.html#cast(other):self-class-method this is a thing
<raz> JS can do some cool tricks with it tho
<raz> `"b" + "a" + +"a" + "a";`
<raz> try that in your browser console :D
<FromGitter> <Blacksmoke16> ๐ŸŒ
<raz> right... js is probably the prime example for why it's a bad idea
<FromGitter> <Blacksmoke16> are missing the `.toLowerCase()` tho ๐Ÿ˜‰
<FromGitter> <ImAHopelessDev_gitlab> fck js
<oprypin> ๐Ÿ
<jhass> raz: you remember what's {} + [] and [] + {} though?
<raz> now i gotta retry it lol... i'm sure i've seen it before
<oprypin> wat's with it
<raz> jhass: well, obviously it's 0 and [object Object] respectively
<raz> i mean, what else would you expect?
<raz> :p
<raz> ...in a language that invented the === because == just wouldn't cut it anymore
<FromGitter> <Blacksmoke16> wtb ====
<FromGitter> <Blacksmoke16> ensures its same instance and type ;p
<jhass> I'd actually be curious on a history who invented all the bad concepts first, JS or PHP
<FromGitter> <tenebrousedge> JS half-seriously needs `====`
<jhass> isn't PHP slightly older than JS?
<FromGitter> <Blacksmoke16> modern PHP is pretty nice
<FromGitter> <ImAHopelessDev_gitlab> YIKES
<FromGitter> <Blacksmoke16> coughattributescough
<jhass> can't get rid of all of its type coercion madness though iirc
<FromGitter> <Blacksmoke16> @ImAHopelessDev_gitlab have you seen php8?
<Andriamanitra> to be fair to javascript it is pretty nice to be able to make mistakes and still have the thing you're making do *something* to show you what exactly is going wrong
<FromGitter> <tenebrousedge> PHP was sort of initially not that serious of a language. JS was more or less intentional
<Andriamanitra> especially when it's running client-side so it's not my problem when things blow up :D
<jhass> and it's a language that picked its initial stdlib function names so they would distribute well in their crappy hash table implementation, and didn't clean that up to date, so
<FromGitter> <ImAHopelessDev_gitlab> nope and never will. i'm happy on 5.7, ty
<FromGitter> <Blacksmoke16> oofc
<FromGitter> <Blacksmoke16> you're missing out
<FromGitter> <Blacksmoke16> https://stitcher.io/blog/new-in-php-8
<FromGitter> <Blacksmoke16> i like how they handled attributes
<jhass> JS was a demo that went into production. Author pretty much completely regrets all the initial design decisions :)
<FromGitter> <ImAHopelessDev_gitlab> if i have tosee another `public function xxx` i'm about to kill myself
<FromGitter> <Blacksmoke16> for the most part at least...
<FromGitter> <Blacksmoke16> :rolls_eyes:
<FromGitter> <ImAHopelessDev_gitlab> `public function foo(Foo|Bar $input): int|float;`
<FromGitter> <tenebrousedge> modern PHP is fairly tolerable. The Psy shell is nice
<FromGitter> <ImAHopelessDev_gitlab> and wtf isthis
<FromGitter> <Blacksmoke16> thats not much diff than crystal...
<FromGitter> <Blacksmoke16> a bit more explicit on visibility tho
<FromGitter> <ImAHopelessDev_gitlab> `function foo(string $a, string $b, ?string $c = null, ?string $d = null) `
<FromGitter> <ImAHopelessDev_gitlab> WTFFFFFFF
<FromGitter> <ImAHopelessDev_gitlab> `?` before the type
<FromGitter> <Blacksmoke16> crystal has `String?`
<FromGitter> <ImAHopelessDev_gitlab> and it's = null too
<raz> the problem with "modern X" is always that the X doesn't go away. typescript is quite neat but you can't use it without chaining your neck to a truckload of JS deps and legacies. same for all the JVM langs.
<FromGitter> <ImAHopelessDev_gitlab> but a question mark rofl
<FromGitter> <Blacksmoke16> again, nearly identical to crystal... not sure what point you're trying to make
<FromGitter> <ImAHopelessDev_gitlab> lolol
<FromGitter> <ImAHopelessDev_gitlab> u really love php don't u
<FromGitter> <Blacksmoke16> no i just dont see how you think thats any diff than crystal
<FromGitter> <tenebrousedge> PHP has `?String`, Crystal has `String?`
<FromGitter> <tenebrousedge> same thing
<FromGitter> <ImAHopelessDev_gitlab> absolutely not what i just posted
<FromGitter> <ImAHopelessDev_gitlab> `?string $c = null`
<raz> how drunk do you have to be to get the idea to put the ? in front tho?
<FromGitter> <ImAHopelessDev_gitlab> is not the same as String?
<FromGitter> <Blacksmoke16> `c : String? = nil`
<FromGitter> <Blacksmoke16> almost the same
<FromGitter> <tenebrousedge> maybe `?Foo` is more noticeable?
<FromGitter> <ImAHopelessDev_gitlab> dude
<Andriamanitra> i dislike php for many reasons but that is not one of them -- nilable types are a good feature
<FromGitter> <ImAHopelessDev_gitlab> `?` implies
<jhass> raz: it just distributes better in that hashtable or something :P
<FromGitter> <ImAHopelessDev_gitlab> nn for extra = null littered all over
<raz> lol!
<FromGitter> <ImAHopelessDev_gitlab> a question mark is not, holy hell
<FromGitter> <ImAHopelessDev_gitlab> is enough*
<raz> jhass++
<straight-shoota> hehe
<FromGitter> <Blacksmoke16> `?string $c` is not the same as `?string $c = null`
<FromGitter> <Blacksmoke16> `c : String?` is not the same as `c : String? = nil` in crystal
<FromGitter> <ImAHopelessDev_gitlab> im already lost
<FromGitter> <ImAHopelessDev_gitlab> so gg php
<FromGitter> <ImAHopelessDev_gitlab> "New mixed type" rofl
<FromGitter> <ImAHopelessDev_gitlab> `function bar(string|Stringable $stringable)` LOL
<FromGitter> <tenebrousedge> lots of good changes in PHP 8
<FromGitter> <ImAHopelessDev_gitlab> hey, it's a string, that's stringable, with a stringable variable! yipppeee ๐Ÿ˜‚๐Ÿ˜‚
<FromGitter> <Blacksmoke16> crystal has a mixed type tbh
<FromGitter> <Blacksmoke16> to be fair*
<FromGitter> <Blacksmoke16> `_`
<FromGitter> <tenebrousedge> the null coalescing situation seems kinda ugly but w/e
<Andriamanitra> union types are also nice, especially with good type inference system like in crystal or julia :)
<FromGitter> <ImAHopelessDev_gitlab> unions?
<FromGitter> <Blacksmoke16> no unions are the same as PHP
<FromGitter> <Blacksmoke16> using `|`
<FromGitter> <ImAHopelessDev_gitlab> ic
<FromGitter> <Blacksmoke16> mixed type is saying "this method can return diff types but i dont know them all"
<FromGitter> <ImAHopelessDev_gitlab> sounds like a confident method
<FromGitter> <Blacksmoke16> i just dont see why you think https://gitter.im/crystal-lang/crystal?at=5fc94a2bcdb54d716ee5721c is so bad
<FromGitter> <tenebrousedge> TypeScript ran into the same problem. Even if you bolt on types you still have old libraries that won't use them
<FromGitter> <Blacksmoke16> but crystal, which is literally almost identical, is fine
<FromGitter> <ImAHopelessDev_gitlab> after reading that article, you just solidified my ten foot pole @Blacksmoke16 . i just bought another pole and extended it
<raz> tenebrousedge: /ran/constantly runs/
<raz> i've tried to do some typescript, it's a pita
<FromGitter> <tenebrousedge> I really wanted TypeScript to be the thing to save us all from JS
<raz> but should get better as the TS ecosystem grows. the moment you bring in a js library you're pretty much lost
<raz> well, it still might... but gonna take a while
<FromGitter> <Blacksmoke16> you can still have `index.d.ts` for those js libs
<FromGitter> <Blacksmoke16> so its not as terrible
<raz> my younger self may have agreed. but crystal has lowered my pain threshold quite a bit.
<FromGitter> <ImAHopelessDev_gitlab> i wish i would have started learning dlang way back instead of php/js, all that stuff. but then again, i was doing mostly web based stuff to be fair
<FromGitter> <Blacksmoke16> idt you can compare crystal to ts/js
<Andriamanitra> it's a bit of a shame dart didn't end up becoming the new javascript (although i completely understand why)
<FromGitter> <Blacksmoke16> thats not really a fair comparison
<FromGitter> <Blacksmoke16> ts is quite nice for what it has to deal with
<raz> yea the problem with JS is how it ruins everyone who gets into programming. and then they have to spend decades to unlearn
<Andriamanitra> i'd rather just replace the client-side programming language altogether than deal with all these hot glue fixes :p
<jhass> Andriamanitra: just do flutter web apps :D
<jhass> raz: I used to say that about PHP actually
<jhass> (PHP is my first language fwiw)
<raz> yea php is similar, but JS has much more impact. it's the first language for pretty much everyone nowadays.
<FromGitter> <ImAHopelessDev_gitlab> me too, php then js
<jhass> and I feel so bad for that. The JS ecosystem is impossible to keep up with
<jhass> if I imagine myself back then being confronted with what the JS ecosystem is now, ugh
<FromGitter> <ImAHopelessDev_gitlab> actually, in middle school we were taught some action script doing flash player stuff. so it went php, as3, js
<raz> i see it mostly as wasted energy. it holds us back as a species
<FromGitter> <ImAHopelessDev_gitlab> i never got into as3 though, holy hell i still can't lol
<raz> the smart kids leave JS soon enough and... well, then they fall into the next trap, go-lang.
<FromGitter> <ImAHopelessDev_gitlab> php and js though, easily
<raz> it is hopeless seen๐Ÿ™ˆ
<raz> (um, -seen)
<raz> hey AS3 was actually really good
<raz> i still have fond memories
<raz> and flex
<jhass> btw the Ruby 3 typing effort is using a quite... interesting approach. I don't see it succeeding honestly. https://github.com/ruby/rbs
<jhass> blacksmoke gotta love it though, it's basically pure interfaces everywhere xD
<raz> jhass: yea, i also feel like they will have a hard time retro-fitting that (even tho it looks promising to me)
<FromGitter> <Blacksmoke16> what happened to that ice cream named type thing i thought they were doing?
<jhass> the thing is that you have to write all the boilerplate twice, and nobody is going to want to do that in practice and daily paid work, not even for new stuff
<raz> the stripe one? sorbet?
<FromGitter> <Blacksmoke16> hey now, interfaces have their place but idt you need one for *everything*
<FromGitter> <Blacksmoke16> yea thats it
<raz> oh it's alive and kicking, but i think few people use it
<jhass> ^
<Andriamanitra> why does ruby even want types? they've done perfectly fine with duck-typing and there's already plethora of great typed languages out there
<jhass> because it's the hip thing and they're a bit into the hip things recently
<raz> well... perfectly fine is arguable. once you've worked on a mid-sized rails codebase you realize you really want them
<jhass> I guess in theory it could allow some VM optimizations (think all the stuff JVM/truffle is doing with JITs and AOT)
<raz> but agree, ruby works *extremely* well despite not having them
<jhass> speaking of, Ruby's JIT approach is also quite out of the ordinary :D
<Andriamanitra> i like languages that do things a bit different, it's no fun when everyone does the exact same thing!
<jhass> (it generates C code, invokes the C compiler and dynamically links in the resulting object file)
<raz> well, all their core devs talk japanese, so nobody can understand anyone ยฏ\_(ใƒ„)_/ยฏ
<FromGitter> <RespiteSage> Re first languages, I wrote my early code on a TI-83. Pretty much the worst possible programming experience without dipping into esolangs.
<FromGitter> <RespiteSage> Most of that was the physical interface, though.
<FromGitter> <tenebrousedge> yeah I'm happy if the JIT thing works seamlessly, but I don't think I'm ever going to use typed Ruby
<FromGitter> <RespiteSage> @jhass That JIT description you just gave is wild.
<FromGitter> <RespiteSage> I guess it's probably easier (in the short term) than writing your own assembler, though.
<jhass> install ruby 2.7 and ruby --jit and it's running on your system :D
<FromGitter> <RespiteSage> And it does this when the program loads?
<Andriamanitra> ..does it still improve performance?
<raz> my main problem with ruby isn't even the speed but the memory leaks
<FromGitter> <ImAHopelessDev_gitlab> ruby has memory leaks?
<jhass> the idea of a JIT is to keep track of hot code paths and compile time
<bougyman> I've never had a memory leak problem that wasn't driven by some stupid active*something*
<bougyman> which is why I never use active*anything* in my ruby.
<jhass> raz: it got better in the last couple of releases, also jemalloc helps a lot. It's really not a leak but a bloat problem, as Ruby is or at least used to be quite conversative with releasing memory back to the system after a peak
<raz> jhass: yup i heard about it. sadly i maintain a bunch of older rails apps and they will just eat to any number of gigabytes you throw at them
<raz> through*
<jhass> anyways, so back to the JIT topic: it always happens in ("late") runtime, it has to be a heuristic between spending the time of doing the compilation vs the time saved after
<jhass> raz: putting them in a cgroup to restrict available memory helps a lot too to keep that in check. And really, try jemalloc, you can just LD_PRELOAD it into your existing ruby builds. Worst case you can have systemd do periodic restarts as they violate their memory constraints
<raz> jhass: i'll spare you the deployment details but... not that easy sadly ๐Ÿ˜ž
<jhass> if you feel super adventourus there's actually a ton of tuneables around this
<raz> i know. but some of them are on heroku (needs custom image to do anything custom), elastic beanstalk (don't even ask) and... oh well, just don't remind me ;)
<jhass> :P
<jhass> there's also this fun https://github.com/kzk/unicorn-worker-killer
<FromGitter> <ImAHopelessDev_gitlab> alright so im moving a lot of external code that's calling properties on an object to the inside
<FromGitter> <ImAHopelessDev_gitlab> this feels kinda better, ngl
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <Blacksmoke16> sounds like a plan, but ofc in some cases that doesnt really help all that much
<FromGitter> <Blacksmoke16> think about how the various "entities" in your game interact, then can figure what the api/methods should look like
<FromGitter> <ImAHopelessDev_gitlab> quite easy, everything is an object. i love objects
<FromGitter> <ImAHopelessDev_gitlab> i toss objects around in code like i do when i make a nice caesar salad ๐Ÿ˜‚๐Ÿ˜œ
<FromGitter> <ImAHopelessDev_gitlab> yes, think of telling objects what to do
<FromGitter> <Blacksmoke16> right
<FromGitter> <Blacksmoke16> mainly what im getting at is an api like `obj.move location` is must better than `obj.move location.x, location.y`
<FromGitter> <Blacksmoke16> esp when you have objects to represent these things
<FromGitter> <ImAHopelessDev_gitlab> now, let's go back to my envelope analogy. in oop, the post stamp is the oop principle. because the post stamp gives the workers on where to send it.
<FromGitter> <Blacksmoke16> oop isnt a messaging platform. there are patterns around that tho
<FromGitter> <Blacksmoke16> for example
<FromGitter> <ImAHopelessDev_gitlab> what i'm trying to say is: monster.move is the post stamp. the code inside the move method is the workers telling it what to do (the people at the post stamp facility)
<FromGitter> <Blacksmoke16> :thinking: i guess?
<FromGitter> <ImAHopelessDev_gitlab> me literally writing `monster.move` is the action of me putting the post stamp on the envelope
<FromGitter> <tenebrousedge> I can get behind this analogy, I think. It sounds like Alan Kay
<FromGitter> <ImAHopelessDev_gitlab> instead of writing all the move method functionality right there below it.
<FromGitter> <ImAHopelessDev_gitlab> bcz no workers at the mail office are at my house
<FromGitter> <tenebrousedge> https://wiki.c2.com/?AlanKayOnMessaging
<FromGitter> <ImAHopelessDev_gitlab> u get my drift now lol
<FromGitter> <tenebrousedge> OO is about sending messages to objects, and the object should decide what to do with those messages
<FromGitter> <ImAHopelessDev_gitlab> that's my problem, i send messages to the object, but i do it right then and there. instead of letting the object do itself
<FromGitter> <ImAHopelessDev_gitlab> do it, itself*
<FromGitter> <Blacksmoke16> i think there could be a better analogy, messaging makes it seem like you're sending it off to have things dont on it imo
<FromGitter> <Blacksmoke16> do on it*
<FromGitter> <Blacksmoke16> like the pipline example, whereas here you're kinda just telling your dog to do some trick its trained t odo
<FromGitter> <tenebrousedge> I mean the messaging idea is very much built into Ruby
<FromGitter> <ImAHopelessDev_gitlab> everything can still be an object though, right
<FromGitter> <ImAHopelessDev_gitlab> if all those objects have their own inherent functionality, it's legit?
<FromGitter> <tenebrousedge> yes
<FromGitter> <Blacksmoke16> yes thats right
<FromGitter> <ImAHopelessDev_gitlab> i like that
<FromGitter> <tenebrousedge> it's a very short conceptual chain between Smalltalk -> Ruby -> Crystal
<FromGitter> <Blacksmoke16> its just messaging to me makes me think of like async/later point in time thing versus something happening right then
<FromGitter> <ImAHopelessDev_gitlab> i don't have a problem with that, but why didn't i do that when i started
<FromGitter> <ImAHopelessDev_gitlab> why did i think i must use that object externally
<FromGitter> <ImAHopelessDev_gitlab> to confuse the sh*t out me later on, or ?
<FromGitter> <Blacksmoke16> part didnt know better part stubborn
<raz> hmm, btw, i'm growing a bit tired of VSCode. has anyone gotten an IDE to work well with crystal? it looks like jetbrains has some early support, but doesn't look too promising
<FromGitter> <tenebrousedge> it's more natural to use properties directly at first, imo
<FromGitter> <tenebrousedge> I don't know about an IDE, raz, but I tend to switch between VSCode and spacevim
<FromGitter> <Blacksmoke16> raz i just use sublime, highlighting + format on save, nothing more than that tho
<FromGitter> <ImAHopelessDev_gitlab> sublime is an amazing piece of software
<FromGitter> <ImAHopelessDev_gitlab> really sets the bar high for true usage of the conventional term software
<raz> tenebrousedge: yup exact same here. VSCode is ok (thank god it has vim emulation), but electron performance is just awful
<FromGitter> <ImAHopelessDev_gitlab> inb4 watzon'd
<raz> smoke: yup i don't need much more than that either. i just don't like how glitchy the auto-indentation is in vscode and such. it's super pleasant in JS, but in crystal i need to shuffle stuff around manually all the time
<raz> plus the performance feels like typing with boxing gloves.
<FromGitter> <ImAHopelessDev_gitlab> LOOOOOOOOOL
<raz> but i'm on a measly i9... i know it's a bit ambitious to expect it to display keystrokes, like, immediately ๐Ÿ™„
<FromGitter> <Blacksmoke16> download more ram
<FromGitter> <ImAHopelessDev_gitlab> damn raz, we think a like
<FromGitter> <ImAHopelessDev_gitlab> i like you
<raz> ๐Ÿ˜ฌ
<FromGitter> <ImAHopelessDev_gitlab> protect this person at all costs, folks
<FromGitter> <tenebrousedge> @Blacksmoke16 where is that PR about macro methods?
<FromGitter> <ImAHopelessDev_gitlab> @Blacksmoke16 send him some of your ram
<FromGitter> <ImAHopelessDev_gitlab> ๐Ÿ˜‚๐Ÿ˜‚
<FromGitter> <ImAHopelessDev_gitlab> send it through socket.puts, read it as a Ram type
<FromGitter> <Blacksmoke16> @tenebrousedge https://github.com/crystal-lang/crystal/issues/8835
<raz> if only ram could fix it. but i'm tempted to get one of those m1 macs. they are said to be super responsive
<FromGitter> <Blacksmoke16> i have 32 gigs so i can spare some ๐Ÿ˜‰
<FromGitter> <ImAHopelessDev_gitlab> don't do it, it's vscode aint nothing with your i9
<raz> ya, i know
<FromGitter> <ImAHopelessDev_gitlab> sell me ur i9 if u buy the mac
<FromGitter> <Blacksmoke16> @tenebrousedge thats my 2nd fav issue/pr ๐Ÿ˜‰
<FromGitter> <Blacksmoke16> id rather have the annotation one
<raz> well the i9 is also a mac ๐Ÿคทโ€โ™€๏ธ
<FromGitter> <ImAHopelessDev_gitlab> oh nvm
<FromGitter> <ImAHopelessDev_gitlab> is that meta of meta, in macro land
<FromGitter> <ImAHopelessDev_gitlab> i don't understand anything in that pr rofl
<FromGitter> <Blacksmoke16> its mainly around allowing the reuse/sharing of macro code
<FromGitter> <Blacksmoke16> which is part of the reason they're so ugly because you have to duplicate everything
<FromGitter> <tenebrousedge> macros are a little obnoxious to deal with at the moment
<FromGitter> <Blacksmoke16> id rather have my annotation updates first because there is just things you cant do at all atm
HumanG33k has joined #crystal-lang
<FromGitter> <tenebrousedge> @Blacksmoke16 how do I stick comments in macros without having them in my debug output?
<FromGitter> <Blacksmoke16> dont add comments :S
<FromGitter> <Blacksmoke16> is funny because you cant even comment them out ha
<FromGitter> <tenebrousedge> that seems...suboptimal
<FromGitter> <Blacksmoke16> maybe compiler could remove them? :shrug:
<FromGitter> <Blacksmoke16> or an option to the debug macro
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<oprypin> dang
<FromGitter> <Blacksmoke16> @ImAHopelessDev_gitlab https://github.com/crystal-lang/crystal/issues/10021
<FromGitter> <ImAHopelessDev_gitlab> interesting
<FromGitter> <ImAHopelessDev_gitlab> me (https://i.imgur.com/4OemMyp.mp4) when trying to use macros
<jhass> that's good! stops you from overusing them, which you shouldn't :P
<FromGitter> <ImAHopelessDev_gitlab> i don't want to fall in the hole!!
<raz> blacksmoke: thanks for the sublime heads up. giving it another shot now and liking it (had last used it years ago and the vim-emu sucked. but now it has six and... i like it!)
<FromGitter> <Blacksmoke16> ๐Ÿ‘
<Andriamanitra> sublime is really nice but i've become too dependent on vscode's extensions and version control tab
<FromGitter> <tenebrousedge> spacevim <3
<raz> yea, i don't use version control, but the search (across files) in sublime sucks
<raz> wonder if there's a plugin for that
<FromGitter> <ImAHopelessDev_gitlab> Bro the search on sublime is amazing
<FromGitter> <ImAHopelessDev_gitlab> must be a bug
<raz> tenebrousedge: i've had my share of trying to turn vim into an IDE... i don't think it will work ;)
<raz> hopeless, it just gives me a new window with a list of hits now
<raz> no realtime filtering like vscode, maybe i need a plugin
<FromGitter> <tenebrousedge> I mean I basically just use spacevim with the defaults
<FromGitter> <tenebrousedge> I think I added a couple lines of config to enable Crystal support and that was it
<FromGitter> <tenebrousedge> I don't know how to drive this thing, I just use it
<FromGitter> <ImAHopelessDev_gitlab> "I don't know how to drive this thing, I just use it" about sums up my life pretty well
<Andriamanitra> i'm still hoping one day someone builds a proper ide-like frontend for xi-editor
sagax has quit [Remote host closed the connection]
<sorcus> Mmm, reference book updated o_o
<FromGitter> <tenebrousedge> yus
<FromGitter> <tenebrousedge> it has shinies
<FromGitter> <ImAHopelessDev_gitlab> static public abstract annotated def method_name
<FromGitter> <Blacksmoke16> :rolls_eyess:
<FromGitter> <ImAHopelessDev_gitlab> :D just for you, george