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
<oprypin> 3n-k1, ayy
gangstacat has quit [Ping timeout: 260 seconds]
gangstacat has joined #crystal-lang
<FromGitter> <aaaScript> @oprypin I had a quick question about this monitor you helped me with a while back: https://gist.github.com/oprypin/0174dee7f56fe033382db99af335dff2 ⏎ ⏎ It works amazing btw for a bunch of API calls and it's also really helpful for filesystem monitoring. My question is around the sleep portion: ⏎ ⏎ ```code paste, see link``` ... [https://gitter.im/crystal-lang/crystal?at=5fb31ebfc10273610a0d8291]
<FromGitter> <3n-k1> because without the sleep, your os scheduler will just run it as fast as it possibly can
<FromGitter> <3n-k1> whatever core it's on will turbo up to max clock and run literally as hot as it can get until it starts to throttle
<FromGitter> <wyhaines> If sleeping 0.1 is too long for the responsiveness that you want, make the sleep shorter. Run some benchmarks. You can probably make it a lot shorter without significantly affecting baseline CPU usage.
<FromGitter> <Blacksmoke16> pretty sure `sleep 0` is a thing
<FromGitter> <Blacksmoke16> like a track that checks for other fibers to execute and if nothing continues with this fiber w/o actually sleeping
<FromGitter> <Blacksmoke16> trick*
<FromGitter> <Blacksmoke16> dont quote me tho
<FromGitter> <3n-k1> i've written super short sleeps in other languages, it's usually not that much of an issue as long as you actually do have a call to sleep
<FromGitter> <Blacksmoke16> related https://github.com/crystal-lang/crystal/issues/9128
<FromGitter> <aaaScript> Actually it looks like sleep 0 works in this loop, however, it looks like it didn't fix my ImGui overheating issues. Even with sleep 0.1 the application ran smooth at 60 fps.
<FromGitter> <3n-k1> how about `sleep 10.milliseconds`?
<FromGitter> <aaaScript> Looks like it's still really hot. It might just be ImGui or actually SFML specific since that's the backend.
<FromGitter> <3n-k1> well the next question becomes "what cpu are you using?"
<FromGitter> <aaaScript> How do you mean?
<FromGitter> <3n-k1> well if you're using an extremely low-end cpu, that could be the issue
<FromGitter> <aaaScript> Oh I see. I have the opposite, it's an i9
<FromGitter> <3n-k1> and if by "running hot" you literally mean hot, could be a bad thermal issue
<FromGitter> <3n-k1> nevermind lol
<FromGitter> <3n-k1> could try profiling it for a few seconds. i did that when i had a similar issue with crystal-gobject
<FromGitter> <aaaScript> It's visibly more CPU intensive in the activity monitor on top of turning into a burning oven. I am running with vsync enabled as well from SFML for constant 60fps. If I limit it to 15fps, it's not so much of an oven, but it's a painful user experience
<FromGitter> <aaaScript> I suspect this may be just rendering issue instead, I'll see if I can research a way to kind of limit it rendering if it's not needed. Hopefully that would work. I initially suspected it may have been the sleep but it doesn't seem the case.
mistergibson has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> hi
<FromGitter> <Blacksmoke16> o/
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 264 seconds]
<FromGitter> <3n-k1> is there a way to use a global literal in a macro? something like this ⏎ ⏎ ```foo = {"bar" => "baz"} ⏎ {% for thing in foo %} ⏎ do_something foo ⏎ {% end %}``` [https://gitter.im/crystal-lang/crystal?at=5fb348afb86f64070456aa00]
<FromGitter> <Blacksmoke16> use a const
<FromGitter> <3n-k1> ah, ty
<FromGitter> <Blacksmoke16> or make it a macro var if its only needed in macro land
<FromGitter> <3n-k1> what's a macro var, defining it just in the macro?
<FromGitter> <Blacksmoke16> `{% foo = {"bar" => "baz"} %}`
<FromGitter> <3n-k1> ah til, thanks
<FromGitter> <Blacksmoke16> or just do it inline?
<FromGitter> <Blacksmoke16> `for thing in {"foo" => "baz"}`
<FromGitter> <3n-k1> that could work too, thanks
avane has quit [Quit: ZNC - https://znc.in]
avane has joined #crystal-lang
chachasmooth has quit [Ping timeout: 260 seconds]
chachasmooth has joined #crystal-lang
DTZUZU has quit [Read error: Connection reset by peer]
<FromGitter> <3n-k1> is there a reason the `finished` hook doesn't return methods that start with `self.`?
<FromGitter> <3n-k1> whoops, forgot a few words
<FromGitter> <3n-k1> is there a reason that calling `@type.methods` from the `finished` hook doesn't return methods that start with `self.`?
<FromGitter> <Blacksmoke16> @type.class.methods
<FromGitter> <3n-k1> ahh thank you
DTZUZU has joined #crystal-lang
<FromGitter> <Blacksmoke16> np
johnny101 has quit [Ping timeout: 264 seconds]
<FromGitter> <fabianhjr> Is there someone from https://github.com/crystal-lang-tools/ here that could help tagging a new scry release? ⏎ ⏎ The latest release cannot be built on any of the more recent crystal releases (0.31.1-0.35.1) and would help packaging on NixOS.
johnny101 has joined #crystal-lang
<FromGitter> <watzon> Hey everyone, it's been a minute
<FromGitter> <watzon> @Blacksmoke16 since you asked a while ago https://github.com/crystal-term
<FromGitter> <watzon> I haven't done much with Crystal the past 3 months. Been pretty focused on my new job and dealing with a baby in the NICU.
ua has quit [Ping timeout: 256 seconds]
ua has joined #crystal-lang
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
<oprypin> aaaScript, i don't know. maybe it's the fact that SFML's .sleep or .display blocks all fibers
andremedeiros has quit [Quit: ZNC 1.8.2 - https://znc.in]
andremedeiros has joined #crystal-lang
deavmi has quit [Ping timeout: 272 seconds]
deavmi has joined #crystal-lang
mistergibson has quit [Read error: Connection reset by peer]
mistergibson has joined #crystal-lang
<FromGitter> <HertzDevil> question: let's say i have ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ how do i extend this to the variadic case? [https://gitter.im/crystal-lang/crystal?at=5fb3b8802a60f731f75e3f05]
<FromGitter> <HertzDevil> more specifically, what should go inside `???` here: ⏎ ⏎ ```class A(*T) ⏎ def initialize(*@t : ???) end ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5fb3b88bf2fd4f60fc7bfe7e]
<FromGitter> <HertzDevil> in the method case you could do `def f(*t : Array(_))` but that doesn't work here because the free vars must be bound to the generic vars and underscores don't bind to anything
<FromGitter> <HertzDevil> `*Array(...)` is wrong since array isn't splattable, and `Array(*T)` is also wrong since array still only takes one generic var
<FromGitter> <HertzDevil> it's easy if i could use `typeof` or macros but afaik they are unavailable here
<FromGitter> <Daniel-Worrall> Looks like a job for macros
<FromGitter> <Daniel-Worrall> Or a tuple of arrays
<FromGitter> <Daniel-Worrall> What's the use case?
<FromGitter> <HertzDevil> it's the same issue if `@x` isn't a splat
<FromGitter> <HertzDevil> that'd be `@t : Tuple(???)`
<FromGitter> <HertzDevil> you cannot directly refer to the type of `T` in the class body via macros for some reason
<FromGitter> <HertzDevil> one use case is allowing `Iterator(T)#zip` to take multiple other iterators
<FromGitter> <HertzDevil> `Enumerable#zip` can do this because the non-block variant returns an array directly, but such an iterator needs to store that `*@t : Iterator(???)` somewhere
sorcus has quit [Ping timeout: 260 seconds]
<FromGitter> <HertzDevil> if you just chain multiple zips the result type is a *tree* of 2-tuples and that's not very good, compared to `Enumerable`
sorcus has joined #crystal-lang
sorcus has quit [Ping timeout: 272 seconds]
<oprypin> HertzDevil, i think with some inefficiencies storage is possible
<oprypin> say if you had a.. Array(Array(typeof(*T)))
<oprypin> HertzDevil, not that it's super likely to help but https://crystal-lang.org/2015/08/24/its-a-typeof-magic.html is a must-read
<FromGitter> <HertzDevil> `Tuple(Array(U | T))` is *very* different from `Tuple(Array(U), Array(U))`
<FromGitter> <HertzDevil> oops
<FromGitter> <HertzDevil> `Tuple(Array(T | U))` and `Tuple(Array(T), Array(U))` i mean
<oprypin> yea
<riffraff169> interesting article
<oprypin> HertzDevil, sigh there's this horror https://carc.in/#/r/9yqa
<oprypin> HertzDevil, or, well, what's wrong with making the `T` itself just be `Array(T)` in the first place https://carc.in/#/r/9yqh
<FromGitter> <HertzDevil> then type deduction fails because the type vars must be specified for `C`
<FromGitter> <HertzDevil> i.e. you can't do `C.new` anymore
<oprypin> HertzDevil, i dont understand the problem
sorcus has joined #crystal-lang
<oprypin> HertzDevil, fyi u can do `typeof(C[0]).new`
<oprypin> uh excuse me
<oprypin> HertzDevil, fyi u can do `typeof(C.new[0]) .new` ??
<FromGitter> <HertzDevil> hm
<FromGitter> <HertzDevil> looks like the second snippet is the closest
<FromGitter> <HertzDevil> it still affects the overloads but w/e
<FromGitter> <HertzDevil> in that case there's `{% unless T.all? &.<= Array %}`
<oprypin> i'm looking for a good (made up but realistic) example of when one needs to update a unittest in accordance to a code change
<oprypin> where the code itself is something self-contained
<oprypin> mm im thinking something like split a string into words, and there was some bug in determining what's the word boundary
<FromGitter> <HertzDevil> found a different way: https://carc.in/#/r/9yrb
<FromGitter> <Blacksmoke16> oprypin, another option would be like code that throws an exception and the message changes where the unit test was checking for that
deavmi has quit [Quit: Eish! Load shedding.]
<oprypin> good direction to think in
<FromGitter> <Blacksmoke16> also the case where there is a bug in the new code and the unit test is actually correct
<oprypin> yes
<oprypin> i realized another thing that'd be very nice to have. the (expected) output should be much bigger than the input
deavmi has joined #crystal-lang
<oprypin> i guess exception message can fit well into that but i'd like something more "normal"
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <Daniel-Worrall> So I have a file that compiles on its own directly but then doesn't when it's required from a different file
<FromGitter> <tenebrousedge> error message?
<FromGitter> <Daniel-Worrall> Primarily to do with compile time nil checks
<FromGitter> <Daniel-Worrall> `Error: undefined method 'game_id' for Nil (compile-time type is (Twitch::Stream | Nil))`
<FromGitter> <Daniel-Worrall> It's gonna take me a while to get a minimal reproduction of this
<FromGitter> <Blacksmoke16> does some other file reopen it or redefine that getter that could also return nil
<FromGitter> <Daniel-Worrall> nope
<FromGitter> <Daniel-Worrall> It happens on the only thing being `require "./other_file"`
<raz> oprypin: how much realism can you handle tho? the most common case is probably: one day before launch marketing decides to change the product from "online game about dragons" to "social cooking recipes app". all models, views, controllers have to change. "unit tests? oh yes, we'll add these later in between the change reqs" :p
<FromGitter> <tenebrousedge> @Daniel-Worrall so if you put just that in a file and try to build, it fails?
<FromGitter> <Daniel-Worrall> yes
<FromGitter> <Daniel-Worrall> `crystal build src/require_file` fails
<oprypin> raz, i can handle about 1000 characters
xaxisx has joined #crystal-lang
<FromGitter> <Daniel-Worrall> `crystal build src/other_file` succeeds
<raz> hey, i think my scenario could actually fit that :D
<FromGitter> <Daniel-Worrall> It's a really weird issue I've come across before but didn't have time to reduce
<oprypin> and not like videogame characters xD
<FromGitter> <tenebrousedge> is this file something you can throw in a gist or pastebin?
<oprypin> [15:21:05] <@Daniel-Worrall> It's gonna take me a while to get a minimal reproduction of this
<FromGitter> <Daniel-Worrall> I'm reducing it slowly but it also depends on shards and other files
<FromGitter> <Daniel-Worrall> Will gist it asap
<FromGitter> <Daniel-Worrall> Here's a really bad minimal example
<FromGitter> <Daniel-Worrall> but it seems to depend on being in the iteration, on it being nilable, on it being used to construct an array
<FromGitter> <Daniel-Worrall> yeah, this is the exact same bug as before that I failed to reproduce properly
<FromGitter> <Blacksmoke16> whats the problem tho? that works fine for me?
<FromGitter> <Blacksmoke16> nvm
<FromGitter> <Daniel-Worrall> It's the compile time nil branch stuff
<FromGitter> <Daniel-Worrall> It's a weird issue
<FromGitter> <Blacksmoke16> oof
<FromGitter> <Daniel-Worrall> It's not app breaking, I came across it in testing at least
<FromGitter> <Daniel-Worrall> but it bugged the hell out of me
<FromGitter> <anthonyshull> hey all, very new to crystal. just wondering...is it not possible to use an array inside of a named tuple?
<FromGitter> <tenebrousedge> should be possible
<FromGitter> <Blacksmoke16> no you can, but id advise against using named tuples in the first place
<FromGitter> <tenebrousedge> structs are <3
<FromGitter> <anthonyshull> so if i want to have a bunch of convenience methods where i can pass in a hash, etc. instead of a struct or class instance
<FromGitter> <anthonyshull> you're basically saying that in crystal i should use a struct or class instance?
<FromGitter> <tenebrousedge> or don't type the convenience methods
<FromGitter> <Blacksmoke16> dont suppose you could create some sample code https://play.crystal-lang.org/#/cr ?
<FromGitter> <anthonyshull> https://play.crystal-lang.org/#/r/9yrg
<FromGitter> <anthonyshull> basically, i want to have methods like `validateAddress` that can either take an Address or some kind of object
<FromGitter> <anthonyshull> i work at ShipEngine and i'm leading a project to write half a dozen SDKs so i'm trying to use Literate and Crystal to communicate intention for all the SDK behavior
<FromGitter> <tenebrousedge> you don't *need* to type restrict a method. I would kinda wonder what other address-like objects existed and where they were coming from though
<FromGitter> <Blacksmoke16> yea, sounds like a record representing an address would be the ideal approach
<FromGitter> <Blacksmoke16> like `record Address, country : String, residential : Bool, postal_code : String, ...`
<FromGitter> <tenebrousedge> https://crystal-lang.org/api/0.35.1/toplevel.html#record(name,*properties)-macro
<FromGitter> <anthonyshull> ok, so it just isn't common in crystal to use hashes or named tuples in this way?
<FromGitter> <Blacksmoke16> not really
<FromGitter> <Blacksmoke16> you lose type saftey
<FromGitter> <anthonyshull> yeah, the only thing is that our first two SDKs are PHP and TypeScript so I think the expectation is that we play pretty loose with type safety
<FromGitter> <Blacksmoke16> and structs are more flexible, i.e. can add methods to them etc
<FromGitter> <Blacksmoke16> how does crystal fit into this then?
<FromGitter> <tenebrousedge> TypeScript, but with loose type safety?
<FromGitter> <tenebrousedge> uh, what?
<FromGitter> <tenebrousedge> like you *can*, but why?
<FromGitter> <Blacksmoke16> like all the SDKs forward stuff to crystal for the actual implementation?
<FromGitter> <anthonyshull> no, just the go-to outline of how the SDKs should work is in crystal
<FromGitter> <anthonyshull> and, we are using typescript but supporting isomorphic javascript
<FromGitter> <anthonyshull> so basically providing the types
<FromGitter> <Blacksmoke16> wouldnt it be hard to show how the SDK works in one lang when the others are in diff langs?
<FromGitter> <Blacksmoke16> i.e. the semantics of each lang are not the same, thus theres things you can do in crystal you cant do in PHP
<FromGitter> <anthonyshull> yeah, definitely, especially for OOP and functional, etc.
<FromGitter> <Blacksmoke16> id rather have examples/docs in the lang of the SDK im using
<FromGitter> <anthonyshull> the idea is to have something common to reference
<FromGitter> <anthonyshull> internally
<FromGitter> <anthonyshull> yeah, so then the individual SDKs do have their own tutorials and examples
<FromGitter> <Blacksmoke16> 👌
<FromGitter> <anthonyshull> but we need to communicate *in general* how they should work
<FromGitter> <anthonyshull> so devs have something to look at. my idea is that crystal is a good compromise between php, javascript, etc. and java, c#, etc.
<FromGitter> <Blacksmoke16> deal readable yea
<FromGitter> <Blacksmoke16> deff*
<FromGitter> <tenebrousedge> typed, minimal syntax, close enough to other c-derivatives
<FromGitter> <Blacksmoke16> i still think the record based approach would be ideal, you can document the types/methods etc event if every SDK's lang wont enforce the types
<FromGitter> <Blacksmoke16> even if*
<FromGitter> <Blacksmoke16> as they're all prob going to have a specific structure and such anyway id imagine?
<FromGitter> <anthonyshull> yeah
<FromGitter> <tenebrousedge> and types are documentation
<FromGitter> <anthonyshull> and i want to have an algebra where if it compiles we know it is correct
<FromGitter> <anthonyshull> using https://zyedidia.github.io/literate/index.html
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <Blacksmoke16> interesting
<FromGitter> <anthonyshull> so it generates the crystal code and also generates HTML
<FromGitter> <anthonyshull> and then i can compile the crystal code to make sure that my tutorial actually works
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <Blacksmoke16> crystal can handle generating docs for you, and if you write specs that should be good enough no?
<FromGitter> <anthonyshull> yeah, but the idea is that you can the *.lit files and swap out the crystal code for PHP and then do the same thing
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <anthonyshull> it's for generating tutorials and examples
<FromGitter> <anthonyshull> just trying to tame what will be half a dozen SDKs
<FromGitter> <Blacksmoke16> 👍 gl :p
<FromGitter> <anthonyshull> i guess there is no way to split the constructor args onto separate lines?
<FromGitter> <Blacksmoke16> you can
<FromGitter> <anthonyshull> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fb3f4618d286f2076b5c402]
<FromGitter> <Blacksmoke16> you dont use `{}`
<FromGitter> <Blacksmoke16> ```Point.new( ⏎ x: 1, ⏎ y: 2 ⏎ )``` [https://gitter.im/crystal-lang/crystal?at=5fb3f4787cac87158fb10d52]
<FromGitter> <anthonyshull> awe, nice, thanks
<FromGitter> <Blacksmoke16> and ofc you dont need to use the named args, positional ones can work as well
<FromGitter> <anthonyshull> yeah, some of entities are *very* large
<FromGitter> <Blacksmoke16> cant be broken down more?
<FromGitter> <Blacksmoke16> or have some constructors that create it based on other objects?
<FromGitter> <anthonyshull> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fb3f58cdc70b5159a19f746]
<FromGitter> <anthonyshull> and address is just part of a contact, etc.
<FromGitter> <Blacksmoke16> `valid = shipengine.validate address`
<FromGitter> <anthonyshull> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fb3f5b5b86f640704585b42]
<FromGitter> <Blacksmoke16> where you have an overload of `validate` specific for `Address` type
<FromGitter> <anthonyshull> yeah, the idea is to have a bunch of overloading
<FromGitter> <anthonyshull> so you can pass me an address instance or you can give me the information to build an address, etc.
<FromGitter> <tenebrousedge> hmmm
<FromGitter> <anthonyshull> because most people using the SDKs will basically be doing one or two things
<FromGitter> <anthonyshull> validate an address, track a shipment, etc. so we are making those convenience methods on the client itself
<FromGitter> <tenebrousedge> and some of those things will be in languages like PHP where everything is an array anyway
<FromGitter> <anthonyshull> yeah
<FromGitter> <anthonyshull> makes less sense for strongly typed languages, obviously
<FromGitter> <tenebrousedge> whoa, BrucePerens opened a bug
<FromGitter> <Blacksmoke16> isnt his first :p
<FromGitter> <tenebrousedge> when did he start with Crystal?
<FromGitter> <Blacksmoke16> i wanna say a few months ago but dont quote me
<FromGitter> <tenebrousedge> goddamn
Human_G33k has quit [Ping timeout: 272 seconds]
<FromGitter> <tenebrousedge> I remember talking with him on Slashdot when I was in high school
Human_G33k has joined #crystal-lang
mistergibson has quit [Quit: Leaving]
<FromGitter> <HertzDevil> i finally found a solution: https://play.crystal-lang.org/#/r/9ysj
<FromGitter> <HertzDevil> the key seems to be using tuples of type vars as generic vars instead of splatting them, so that the type has access to both `*T` and `Array`s-of-`*T`
<straight-shoota> Blacksmoke16, Bruce Perens has written blog posts about Crystal two years ago, so I wouldn't quote your few months ;)
<erdnaxeli> he is even "building a startup web business using the Crystal language and the Lucky web framework." https://perens.com/2020/06/28/building-a-startup-with-crystal-and-lucky/
<FromGitter> <Blacksmoke16> ha fair enough, i was mainly thinking a few months that hes been active on the forums/creating issues
<FromGitter> <Blacksmoke16> boo, should have used Athena 😉
xaxisx has quit [Quit: Leaving...]
chloekek has joined #crystal-lang
<FromGitter> <Blacksmoke16> @3n-k1 isnt that already a thing? https://kemalcr.com/guide/#middleware
Human_G33k has quit [Remote host closed the connection]
Human_G33k has joined #crystal-lang
<FromGitter> <Simerax> if i have an Array of BaseClass and I put an element of Subclass in it can it somehow check the type and then call a specific method of that subclass? i tried something like this in my spec: ⏎ ⏎ ```e = element[0] ⏎ if e.is_a?(Subclass) ⏎ e.subclass_method() ⏎ end``` ⏎ ⏎ This however gives me a compile error "undefined method 'sublcass_method' for Subclass (compile-time type is BaseClass+)"
<FromGitter> <Blacksmoke16> that should work
<FromGitter> <Blacksmoke16> got some example code?
<FromGitter> <Simerax> nevermind im just dumb...in my actual code i used the array right away without a temporary variable... ⏎ ⏎ ```if elements[0].is_a?(SubClass) ⏎ elements[0].subclass_method() ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5fb448337cac87158fb1e92e]
<FromGitter> <Blacksmoke16> now *that* wouldnt work :p
<FromGitter> <watzon> Ahh yeahm that would do it haha
<FromGitter> <watzon> Because technically `elements[0]` could change at any time
<FromGitter> <Simerax> maybe i should get a rubber duck before posting here ^^
<FromGitter> <Simerax> yes i thought the same now...i somehow totally ignored that
<FromGitter> <watzon> I got one for you
<FromGitter> <Simerax> haha perfect ;)
<FromGitter> <watzon> For some reason I got this for free with one of my 3d printer upgrades
<FromGitter> <watzon> Lol
<FromGitter> <j8r> that's a good marketing!
chloekek_ has joined #crystal-lang
chloekek has quit [Ping timeout: 240 seconds]
chloekek_ has quit [Remote host closed the connection]