<FromGitter>
<ArtLinkov> I figured it's something like that
<FromGitter>
<ArtLinkov> Thanks @naqvis
<FromGitter>
<ArtLinkov> Anyone know when a patch is due in Kemal?
<FromGitter>
<Blacksmoke16> can set the commit for now
<FromGitter>
<Blacksmoke16> essentially the same thing
<FromGitter>
<aravindavk> I think patch merged in Kemal master, but no release yet
<FromGitter>
<Blacksmoke16> right, can just do `commit: commit_hash_in_master` until a new release is created
<FromGitter>
<Blacksmoke16> safer than `branch: master`
<FromGitter>
<ArtLinkov> Good idea, thanks :)
ht_ has joined #crystal-lang
_ht has quit [Ping timeout: 258 seconds]
ht_ is now known as _ht
zorp has joined #crystal-lang
<FromGitter>
<wontruefree> hey @ArtLinkov it has been a while :)
<FromGitter>
<watzon> @Blacksmoke16 any idea if this would be possible? I want to make an arg parser, using macros, that takes a named tuple and attempts to parse a string into that named tuple, where the named tuple is something like `{value: Booll, other: String}`
<FromGitter>
<Blacksmoke16> got an example?
<FromGitter>
<watzon> I'm just trying to figure out if there's a way to build a named tuple like that using macros
<FromGitter>
<watzon> An example string to parse?
<FromGitter>
<Blacksmoke16> you can deff make a named tuple in a macro
<FromGitter>
<Blacksmoke16> if the keys are dynamic however you would have to use a hash
<FromGitter>
<watzon> That's the problem I'm dealing with. I know exactly the arguments I want and their types at compile time, so I'm trying to figure out how to use that to my advantage to output a NamedTuple rather than a Hash, since with a hash I'd end up with something like `Hash(String, String | Int32 | Bool)` and then I have to do runtime type conversion.
<FromGitter>
<watzon> Maybe it would be possible to build a macro HashLiteral and then use that to create a NamedTuple?
<FromGitter>
<watzon> I doubt it, but maybe?
<FromGitter>
<Blacksmoke16> im assuming you want like `some_macro "some_string" # => NamedTuple(..)`?
<FromGitter>
<Blacksmoke16> `.parse` is the macro?
<FromGitter>
<Blacksmoke16> you could do something like
<FromGitter>
<watzon> Well I was hoping I could rely on macro expressions inside of a normal method rather than an actual macro, since with a macro the string being parsed would have to be known at compile time.
<FromGitter>
<Blacksmoke16> similar to `Tuple.from(arr : Array)`
<FromGitter>
<watzon> Hmm, well that could work
<FromGitter>
<Blacksmoke16> > Well I was hoping I could rely on macro expressions inside of a normal method rather than an actual macro, since with a macro the string being parsed would have to be known at compile time. ⏎ ⏎ right and what was your plan to get the runtime value to parse in the macro?
<FromGitter>
<Blacksmoke16> or you just want to build the parsing logic with a macro based on the named tuple type as the "blueprint"?
<oprypin>
sorcus: this is a busyloop; yes, nothing else can happen within one thread
<oprypin>
if u had 4 threads with preview_mt, you'd also be able to run only 4 of these and 5th would get stuck
<oprypin>
if you really want to make this work, you could add Fiber.yield into the bottom loop
<oprypin>
i think sleep 0 is equivalent
<oprypin>
probably add it once every 1000 iterations or so, not to kill performance too much
<oprypin>
additionally, this is probably not thread safe
<oprypin>
no i guess it's fine regarding the last part
<FromGitter>
<naqvis> this is not thread-safe and there will be race-condition. Per my understanding IO isn't thread-safe in Crystal
<FromGitter>
<naqvis> writing from main thread and reading from other threads is definitely going to cause race-condition
<FromGitter>
<naqvis> `Do not communicate by sharing memory; instead, share memory by communicating.`, so `Channel` should be your best friend
<FromGitter>
<ImAHopelessDev_gitlab> LOL i thougt that said "token = tokens.shit" for a second
<FromGitter>
<naqvis> rofl
<oprypin>
@naqvis: yes but this isn't IO :D
<FromGitter>
<naqvis> damn, GFW of China is so much annoying, can’t access gist without vpn or proxy. i’m on cell, so don’t have access to vpn/proxy
<FromGitter>
<naqvis> but i had this impression that above gist was using IO::Memory
<FromGitter>
<naqvis> Thanks oprypin ❤️
<oprypin>
@naqvis: yep. and IO::Memory doesn't do any I/O 🙃
<oprypin>
@naqvis: uhh for what? :o
<FromGitter>
<naqvis> agree, but I was referring to IO as the base class
<FromGitter>
<naqvis> not means system IO
<FromGitter>
<naqvis> thanks for correction
<oprypin>
actual I/O is quite well confined to IO::FileDescriptor
<oprypin>
IO base also has no relation
<FromGitter>
<naqvis> yeah, but I meant to say IO base class 😄
<oprypin>
me too
<FromGitter>
<naqvis> I should be more specific by saying IO::Memory isnt thread safe
<FromGitter>
<naqvis> well actually majority of stdlib isnt thread safe
<FromGitter>
<naqvis> hope i’m not exaggerating here
<FromGitter>
<bararchy> What's the best way to know if a Path is under another Path? ⏎ `Path[/foo/bar/].parent_of?(Path[/foo/bar/file.txt]) => true`
<FromGitter>
<Blacksmoke16> sounds like a feature request
<sorcus>
Thanks oprypin.
<sorcus>
naqvis what does you mean? I shoudn't use `-Dpreview_mt` with `output.size` inside `spawn`?
_ht has quit [Quit: _ht]
narayana has left #crystal-lang ["User left"]
<FromGitter>
<mattrberry> Since StaticArrays are so slow to compile (my compile times jumped 30x from adding a single 4096-long StaticArray), I moved them to a different file that I wouldn't be touching much in the hopes that Crystal would incrementally compile them. That doesn't seem to be the case though. Is there any way to tell crystal that a certain file doesn't need to be recompiled?
<FromGitter>
<Blacksmoke16> dont think so
<FromGitter>
<mattrberry> As of right now, it seems like my only real solution is using StaticArray to work around the supposed gc issue. Build times of 5-8 minutes are just ridiculous though
<FromGitter>
<Blacksmoke16> maybe make a forum thread about it?
<jhass>
not too much point, it's a well known issue
<FromGitter>
<Blacksmoke16> ah, 👍
<jhass>
one big hack around I could imagine is to define it in a little C file as an exported global, compile to an object file and link and bind to on the Crystal side, wrapping it into a Slice
<FromGitter>
<mattrberry> I'll give that a shot. It's worth it to get these compile times down.. Thanks Jonne!
<FromGitter>
<j8r> How can I handle NaN? I would like to have `0 / 0` be `0`
<oprypin>
@mattrberry: lol i wonder if putting that constant into a class would help (probably not..)
<oprypin>
a class of its own i mean
<oprypin>
but yea the idea by jhass would definitely work
<jhass>
well, after all what crystal does for StaticArray is just define an LLVM type that big and then LLVMM chokes on that
<FromGitter>
<j8r> I tried to use macros, a custom struct with a big case/when - does not improve anything
<FromGitter>
<j8r> That's too bad, StaticArray is quite good
<jhass>
weird thing is, just putting StaticArray(Int32, 4096).new into a file isn't slow at all
<jhass>
so I wonder what kind of instructions using such a type get slow and maybe there's actually an easy way to hide the type from LLVM prior by casting it to a pointer and then back or so
<FromGitter>
<j8r> you missed the `[...].new 0`
<FromGitter>
<j8r> I tried `{{ "StaticArray(Int32, 4096).new 0".id }}`, didn't change the compilation time
<jhass>
?!
<oprypin>
jhass: yes at this point maybe it's worth looking for a workaround
<FromGitter>
<j8r> yes jhass, `StaticArray(Int32, 4096).new` does not work
<FromGitter>
<j8r> `StaticArray(Int32, 4096).new 0` does ;)
<jhass>
I just compiled the former?!
<jhass>
or you mean doesn't reproduce?
<oprypin>
i think j8r is going through macro to_s
<oprypin>
which could well be broken
<FromGitter>
<j8r> crystal eval 'StaticArray(Int32, 4096).new' ⏎ Showing last frame. Use --error-trace for full trace. ⏎ ⏎ error in line 1 ⏎ Error: private method 'new' called for StaticArray(T, N).class [https://gitter.im/crystal-lang/crystal?at=5ee7e197013105125a38d7ca]
<jhass>
>> StaticArray(Int32, 4096).new
<DeBot>
jhass: Error: private method 'new' called for StaticArray(T, N).class - https://carc.in/#/r/99w7
<jhass>
huh
<oprypin>
>> StaticArray(Int32, 4096).new
<DeBot>
oprypin: Error: private method 'new' called for StaticArray(T, N).class - https://carc.in/#/r/99w8
<jhass>
how does that work locally :D
<FromGitter>
<j8r> Haha :)
<jhass>
it's really broken in macros?
<oprypin>
woops too slow on mobile
<jhass>
super weird
<FromGitter>
<j8r> you're mind connected oprypin and jhass
<jhass>
ahaha, stdlib makes it private?
<jhass>
with an empty prelude it compiles :D
<FromGitter>
<j8r> Are you sure you are not using Crystal 0.11? (just kidding)
<oprypin>
jhass: lol ok
<jhass>
anyways, even with stdlib and .new(0), that's still fast
<FromGitter>
<j8r> you are putting it on a file, then `read_file`?
<jhass>
?!
<oprypin>
i think that's incompatible with the point jhass is makng
<FromGitter>
<j8r> I don't understand?
<oprypin>
why would you load the literal text [23:01:58] <ffffffoprypin> >> StaticArray(Int32, 4096).new from a file
<FromGitter>
<j8r> also, it is fast on --release or without?
<FromGitter>
<j8r> for me it is only slow on release mode
<jhass>
mmh. yeah stdlib and release makes it slow. empty prelude and release is still fast
<FromGitter>
<mattrberry> It's noticeably slower even not on release, but it's not significant
<oprypin>
on release there's basically no caching anyway
<oprypin>
so disregard my idea from before
<oprypin>
jhass: what kind of workaround could one even do? crystal has no other way of putting massive data on the stack
<oprypin>
@mattrberry: do you get a big win from using static array over slice? I'd doubt it
<jhass>
as a user? I'd give my object file + slice idea a shot
<jhass>
but I guess that's not on the stack anymore
<FromGitter>
<mattrberry> If I use slice or array instead of staticarray, the memory somehow gets corrupted when passing it to SDL
<FromGitter>
<mattrberry> Consistently
<FromGitter>
<mattrberry> So that's not an option
<jhass>
later down above I was talking about workarounds the compiler could make
<oprypin>
@mattrberry: let's try to solve that issue then!!
<oprypin>
jhass: i was thinking your idea would work but it works only for a single global value
<jhass>
yeah
<oprypin>
for stack it doesn't help, yea
<FromGitter>
<mattrberry> I'm down to keep trying! I've brought it up a number of times in this channel to no avail though :/ Spent awhile debugging with Jonne last week
<jhass>
I mean maybe you could have a C function returning you one?
<jhass>
but then you have type in crystal again, no that doesn't help
<oprypin>
@mattrberry: oh with Jonne? ok then it's hopeless to try anymore :D
<FromGitter>
<j8r> But you need a pointer somehow to use Slice?
<oprypin>
jhass: Crystal needs to allocate the stack stuff for C to return into
<jhass>
yeh
<jhass>
I still susupect some LLVM instruction getting slow on such types
<jhass>
which C just manages to avoid to generate
<oprypin>
well yea that's what it is
<oprypin>
does it end up generating a struct like {int1,int2,int3,...4095} or something lol
<jhass>
but then if I dump IR, llvm-extract and llc -O3, it's kinda slow for a single function, but not terribly, minutes slow
<oprypin>
@mattrberry: do you have a repro case (even with your whole repo) for that corruption?
<jhass>
ah, maybe I extracted the wrong function, not the one being slow
<jhass>
mmh, no the constructor on its own isn't slow either
<FromGitter>
... program. The behavior changes depending on whether I add a new instance variable or anything to the APU class
<FromGitter>
<mattrberry> There are a number of ways in which it presents itself. Do you know how digital audio works by chance? If (the buffer)[https://github.com/mattrberry/CryBoy/blob/master/src/cryboy/apu.cr#L135] is filled with only 0's, SDL should not play any audio. Everything should be silent. However, I often (but not always) get random background noise. Other times, SDL just starts reading invalid memory and segfaults the
<FromGitter>
<j8r> the slow thing seems to be `array = uninitialized self`
<FromGitter>
<j8r> 30 seconds for me
<FromGitter>
<j8r> but that's still reasonable
<FromGitter>
<mattrberry> And I'm just giving the SDL_QueueAudio function a pointerof(@buffer), which it then should be copying into its own internal structure
<jhass>
I guess there's one instruction that adds up
<FromGitter>
<mattrberry> I figure it's somewhat related to how the GC is moving values around on the heap, but I have no evidence of that necessarily. All I know is that the issues seem to not be present when I use StaticArray..
<jhass>
idk, llc is just significantly faster, even on the entire dumped IR
<jhass>
maybe that's a workaround for ya, dump unoptimized IR and compile with llc xD
<FromGitter>
<mattrberry> I'm gonna try just making them global constants in C unless you think there's a better workaround :)
<jhass>
oprypin: yeah, just adding --release dumps the optimized IR :)
<FromGitter>
<j8r> @mattrberry My bad, use using `0...N` is better
<jhass>
I guess there's some additional passes during call lowering, but it gets you a long way
<oprypin>
are we on a brink of a breakthrough
<FromGitter>
<j8r> also `#times` is a while loop
<FromGitter>
<j8r> in this case may not be properly handled
<FromGitter>
<mattrberry> > *<oprypin>* @mattrberry, well ok it's a bit of a repro, but is it possible to get a repro without requiring proprietary stuff (rom) ⏎ ⏎ You could probably just initialize SDL then keep passing it slices full of 0's. I imagine that might do the same thing
<oprypin>
there's probably some additional factor, it won't repro just like that
<FromGitter>
<mattrberry> Ah :/ It seems to depend on the structure of my APU class, so I'm not surprised :/
<jhass>
I wonder what the heck we enable for --release that llc -O3 doesn't thouggh
<FromGitter>
<mattrberry> @j8r Is there a downside to using your approach? It's just slightly slower to initialize at runtime? Shouldn't matter though since I'm only doing it once?
<jhass>
it generates a lot more code, so slightly bigger binary probably
<oprypin>
i think you have your solution :)
<FromGitter>
<mattrberry> I'll take it, that's worth the tradeoff for me :)
<FromGitter>
<mattrberry> Is this worth submitting an issue on github for? At least to investigate further?
<FromGitter>
<mattrberry> Hoping that this might be resolved :)
<jhass>
j8r: can't harm to document findings :)
<FromGitter>
<j8r> Sure
<FromGitter>
<j8r> I was not sure if it was the correct place
<FromGitter>
<j8r> Because closed
<FromGitter>
<mattrberry> You could always create a new issue and link to the old one. Might be a more effective way to "bump" it
<jhass>
I think I'll reopen it indeed
<jhass>
there's one more thing I want to try
<FromGitter>
<j8r> I think we may have a `new!` as a work-around, if the fix is not easy
<FromGitter>
<j8r> or change the existing `new`
<jhass>
I see no reason to not workaround in the existing new
<jhass>
it's functionally the same, probably not even really different tradeoffs
<FromGitter>
<j8r> you're right yes
<jhass>
just if we can fix it at compiler level, it might turn out to be generally better
<jhass>
and fixing at compiler level could be figuring out whatever the diff between crystal build --release and llc -O3
<jhass>
my first guess doesn't seem to be it :/
<FromGitter>
<mattrberry> And fixing at the compiler level could also potentially fix other sticking points in the compiler that we just don't know about yet!
<FromGitter>
<mattrberry> Rather than a super localized patch
<jhass>
yeah that's what I meant
<FromGitter>
<j8r> sure
<FromGitter>
<j8r> Maybe we should rename or open a new issue
<FromGitter>
<j8r> I can open a PR to fix slow compile times for StaticArray, then the remaining root issue will be the reduced sample
<FromGitter>
<j8r> the one I posted, which is slow to compile
<FromGitter>
<j8r> of course a code comment will mention this issue, to explain why a macro is used
<FromGitter>
<watzon> Waiting for the bus and I just got asked if I have any Crystal
<FromGitter>
<watzon> Why yes, yes I do
<FromGitter>
<Blacksmoke16> *no, but i have some rust*
<FromGitter>
<j8r> In your "GitHub" haha :D
<FromGitter>
<Blacksmoke16> *elixir*
<FromGitter>
<j8r> Ask a Police man if he has some Crystal in his GitHub :P
Human_G33k has joined #crystal-lang
<FromGitter>
<j8r> When thinking more about it, for those who doesn't know what Git is, a a Hub of Gits can seem weird
<FromGitter>
<Blacksmoke16> *a hub of gits is essentially a bunch of bits*
<FromGitter>
<watzon> Could be worth asking Andrew from Zig-lang if Zig has a similar issue with loop unrolling. If not he may have a solution.
<FromGitter>
<Blacksmoke16> *they zigged instead of zagged*
<FromGitter>
<Blacksmoke16> ok im done
<jhass>
gosh, I hope that's any understandable
HumanGeek has quit [Ping timeout: 256 seconds]
<FromGitter>
<ImAHopelessDev_gitlab> hi
<FromGitter>
<watzon> Oh look who it is
<FromGitter>
<watzon> Hey bud
<FromGitter>
<ImAHopelessDev_gitlab> hi @watzon how u been
<FromGitter>
<j8r> alternatively, Gir is also a village in Iran - Ng from Gir
<FromGitter>
<j8r> anyway, nice to see you
<FromGitter>
<Blacksmoke16> *ng-repeat*
<jhass>
gir is the file extension used for gobject introspection metadata files. I think the r there is repository :D
<FromGitter>
<ImAHopelessDev_gitlab> funny thing is, "girng" came to be from when i rage quit on the godot repo a long time ago from my old account, and wanted to make a new one. so when i registered, i just slammed my hands on the keyboard really quick and "girng" showed up. ⏎ ⏎ I do like IAmAHopelessDev though, which is from opryprin
<FromGitter>
<ImAHopelessDev_gitlab> wtf they got logs
<jhass>
nothing is ever forgotten :P
hightower3 has joined #crystal-lang
<hightower3>
Hey folks, is it true that method overloads don't distinguish a case where just the block restriction is different? Like, this example https://play.crystal-lang.org/#/r/99wh should print "int11", but it prints "string11" because the second definition overwrites the first one.
<hightower3>
And if that assessment is true, is there any workaround?
<FromGitter>
<Blacksmoke16> well you're not typing the argument you're passing
<hightower3>
This example seems to show that the second def overwrote the first one, and then complains about the type. If the order of the defs is changed (so that int version is second), then that example works without an error.
<FromGitter>
<Blacksmoke16> i think thats accurate, cant say i recall an issue/seeing anything about it tho
<hightower3>
Is this because the block signature is just a type restriction, and not the real thing used in deciding the overloads?
<FromGitter>
<Blacksmoke16> im not sure
<hightower3>
I'm reluctant to submit a new issue as most probably I'll receive the answer "yes it's a type restriction which is not used in overloads"... although I could use an idea how to work around it (other than using different method or argument names, which pretty much limits the choices :-)