<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> 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>
<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> 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> 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> 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>
<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>
<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> 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>
<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>
<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. :-)
<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
<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.
<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
<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> 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> 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?
<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> 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> 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>
<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> 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>
<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>
<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>
<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>
<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>
<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> 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> 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/`
<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
<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
<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>
<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>
<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
<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>
<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>
<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 ;)
<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>
<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>
<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
<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
<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