<FromGitter>
<Daniel-Worrall> This is *very* broken with tuples :)
<straight-shoota>
Yeah there's a lot going on with tuples and generics
<straight-shoota>
I wouldn't necessarily consider this broken
<FromGitter>
<Daniel-Worrall> It's obviously not intended for tuples, but it'd be nice if it worked with them
<straight-shoota>
I think it's cause by Tuple's special invariant behaviour
<FromGitter>
<Daniel-Worrall> I think I have a work around for this
<straight-shoota>
,map(&.as({Int32, Int32})
<FromGitter>
<postmodern:matrix.org> Meta question: does the matrix bridge forward messages from IRC to Gitter, thru this channel and the Matrix bridge?
<FromGitter>
<Daniel-Worrall> yeah, I could always include code, but I think this is something the stdlib could support, I'm just gonna theory it
<straight-shoota>
The bridge between IRC and Gitter is still a custom bot
postmodern has joined #crystal-lang
<FromGitter>
<postmodern:matrix.org> ah ok, so it's more like Gitter <-> IRC and IRC -> Gitter <-> Element.
<oprypin>
Matrix1 <-> IRC <-> Gitter <-> Matrix2
<oprypin>
where Matrix1 is a channel that's basically impossible to join and Matrix2 is new
<oprypin>
and, well, the Matrix ones are managed by Matrix and are more seamless
<oprypin>
unfortunately adding Matrix1 <-> Gitter or IRC <-> Matrix2 is not possible
<FromGitter>
<jrei:matrix.org> Yeah, but an intermediate array can be avoided
<FromGitter>
<Daniel-Worrall> mhm
<FromGitter>
<jrei:matrix.org> If an `Indexable` was accepted
<FromGitter>
<jrei:matrix.org> I think it is a valid improvement
<FromGitter>
<Daniel-Worrall> yeah, I've been trying to figure out if it's possible to select/reject a Tuple
<FromGitter>
<Daniel-Worrall> but it seems a bit like a compiler limitation
<FromGitter>
<jrei:matrix.org> It would require a possibly huge union
<FromGitter>
<jrei:matrix.org> Lile, the return type for a tuple of 4 can be tuple of 1, 2, 3, 4 or nil
<FromGitter>
<jrei:matrix.org> Not mentioning different types in the tuple...
<FromGitter>
<Daniel-Worrall> It actually works if I just expand it to accept Tuples, but if the coersion Tuple is larger, it spits out some macro expansion errors instead of raising gracefully
<FromGitter>
<Daniel-Worrall> Well, it'll be caught at compile time regardless
<FromGitter>
<ryanprior:matrix.org> then later you can say `dog = {name: "Fido", age: 5_u8}`
<FromGitter>
<ryanprior:matrix.org> Is that what you had in mind?
<FromGitter>
<Aaron-JM> @ryanprior:matrix.org that looks good ill give it a try, thanks 👍
<FromGitter>
<Aaron-JM> @ryanprior:matrix.org unfortunly, this wont work correctly as many of the data types required for the struct havent been decleared yet. They are decleared later, i need something similar to the following line in C: struct sample; where by later i can simply expand/define the struct to whatever i need.
<FromGitter>
<ryanprior:matrix.org> @Aaron-JM: you can define an empty struct like `struct Dog end` just to reference it, and then you can redefine it later.
<FromGitter>
<Aaron-JM> @ryanprior:matrix.org I noticed this was possible but unfortunantly within the Lib definition the following error arises: Error: empty structs are disallowed. But if this was possible within the Lib binding bracket that would be perfect. Thanks again
bazaar has quit [Ping timeout: 240 seconds]
bazaar has joined #crystal-lang
<FromGitter>
<HertzDevil> if the struct is never passed by value, assume `alias Dog = Void`
<FromGitter>
<HertzDevil> if it is passed by value you prob need all the fields anyway (the abi needs to compute its `sizeof`)
<FromGitter>
<HertzDevil> also a named tuple isn't a struct
<FromGitter>
<HertzDevil> although, in fact, named tuples can be used inside `lib`s
_ht has joined #crystal-lang
_ht has quit [Remote host closed the connection]
_ht has joined #crystal-lang
<FromGitter>
<Aaron-JM> Is there possibly a method for referencing a struct defined later?
<FromGitter>
<Aaron-JM> @viraptor1:matrix.org Thats pretty much what I mean, but Unfortuantly those principles dont work inside the Lib bind
<FromGitter>
<Aaron-JM> The library Im binding uses multiple foward struct deceleration
postmodern has quit [Quit: Leaving]
<FromGitter>
<Nicolab> @jrei:matrix.org Do you use Nomad in production?
<FromGitter>
<jrei:matrix.org> @Daniel-Worrall: that's nice to have a compile time error instead of raising?
<FromGitter>
<jrei:matrix.org> @Nicolab: no, :( I have a colleague who have some knowledge, that's it
<FromGitter>
<mwlang> My Advent of Code Day 15 runs fine in Ruby (< 5 seconds), but runs forever in Crystal. It's quite literally the Ruby code slightly changed to suit Crystal's data typing restrictions. Any idea what might be wrong? I cannot spot a bug and it works for smaller problem space, just not the 300 millionth one. https://github.com/mwlang/advent-of-code/tree/main/2020/15
<FromGitter>
<Daniel-Worrall> @jrei:matrix.org I have a macro compile time raise that'll point to the right line but we'll see what happens in the Issue
<FromGitter>
<Daniel-Worrall> If I don't, it's a confusing error
<FromGitter>
<Daniel-Worrall> Lol I'd look at it if I had done today's aoc
<FromGitter>
<naqvis> @mwlang Code is making GC too much busy, invocation of stop-the-world GC few times, tighter loop invocation using cpu at its peek, causing cpu throttling and that's all
<FromGitter>
<naqvis> in summary, its running but with so much side-effects :P
<FromGitter>
<mwlang> I was guessing GC, but didn't really know for sure.
<FromGitter>
<mwlang> Any techniques for taming GC here?
<FromGitter>
<mwlang> or should I file a bug/issue for this one?
<FromGitter>
<jrei:matrix.org> You can try disable the GC to see if it is really the issue
<FromGitter>
<mwlang> Tried disabling GC and preallocating the Array sizes as well. No apparent difference in behavior: https://play.crystal-lang.org/#/r/a468
<FromGitter>
<erdnaxeli:cervoi.se> I don't know what is your problem, but you don't need to store all the collection at each turn
<FromGitter>
<Nicolab> @jrei:matrix.org Ok :)
zorp has joined #crystal-lang
* FromGitter
* tenebrousedge consider violence
<FromGitter>
<tenebrousedge> I think like making aggressive gestures towards a stuffed animal is probably appropriate
<FromGitter>
<tenebrousedge> I've been stuck on an AoC for days because of a dumb error
<FromGitter>
<erdnaxeli:cervoi.se> what happened? 😁
<FromGitter>
<tenebrousedge> transposed `x` and `y` in a call to `new`
<FromGitter>
<erdnaxeli:cervoi.se> aoutch x)
DTZUZU has quit [Ping timeout: 265 seconds]
r0bby has quit [Ping timeout: 260 seconds]
DTZUZU has joined #crystal-lang
r0bby has joined #crystal-lang
xaxisx has joined #crystal-lang
<FromGitter>
<tenebrousedge> > The third type of error is thesemantic error. If there is a semantic error in yourprogram, it will run successfully, in the sense that the computer will not generateany error messages, but it will not do the right thing. It will do something else.Specifically, it will do what you told it to do.
xaxisx has quit [Ping timeout: 256 seconds]
<Andriamanitra>
which day are/were you stuck on?
<Andriamanitra>
i still haven't found the courage to have another stab at day 13 part 2 :p
<FromGitter>
<RespiteSage> I only just finished day 10 part 2. I'll probably get farther behind but catch up in January.
<FromGitter>
<oz:matrix.org> I'm even farther back that you are. I just have other things to do some days. It's okay to do the puzzles when you get the time, even if it's nice to share/compare solutions with others too. :)
<FromGitter>
<franciscoadasme> hey everyone, I liked to know if there is a way to get all modules annotated with a particular annotation?, something akin to `Object.all_subclasses.select &.annotation(MyAnn)`
<FromGitter>
<Blacksmoke16> hm
<FromGitter>
<Blacksmoke16> whats the use case for annotating a module?
<FromGitter>
<Blacksmoke16> but no, idt thats a thing unless you also have some way to "register" the modules that should be checked or something
<FromGitter>
<franciscoadasme> In simple terms, I want to mark some modules that provide some API such that some methods could be generated during compilation in other classes
<FromGitter>
<franciscoadasme> that is, I want to use the annotation to "register" them
<FromGitter>
<Blacksmoke16> got an example? depending on exactly what you want to do a `macro included` hook might be enough
<FromGitter>
<Blacksmoke16> yea, annotations could use some work, but might not even be needed depending on what exactly you're wanting to do
<FromGitter>
<franciscoadasme> @Blacksmoke16 I don't think a `macro included` would work... anyhow, I have several modules that handle read/write of a file format where each module declares a `Reader` and `Writer` class, similar to `Compress::Zip` in the standard library... Now I want to generate some methods in other classes based on the available file formats
<FromGitter>
<franciscoadasme> so my idea was to annotate such modules as a way of registering them and proceed to generate the relevant methods... there is also additional info that the annotation holds
<FromGitter>
<Blacksmoke16> hm
<FromGitter>
<Blacksmoke16> what about using like a common interface you can either include/inherit from?
<FromGitter>
<franciscoadasme> all of that is to be able to do `Foo.read "/path/to/file.bar"`, and it will detect the file format from the filename (e.g., using the extension) and will call the corresponding Reader class
<FromGitter>
<Blacksmoke16> oof, is `Foo.read` a macro?
<FromGitter>
<franciscoadasme> No, is a class method
<FromGitter>
<franciscoadasme> Right now, I have it working but by annotating the Reader and Writer concrete classes, which includes the Reader and Writer modules... this means that the information about a file format is duplicated in the annotations
<FromGitter>
<franciscoadasme> this is a simplified example, but as you can see, the same annotation is declared twice
<FromGitter>
<franciscoadasme> the annotation has more info, so it is not ideal to need to declare it twice
<FromGitter>
<franciscoadasme> furthermore, I'm thinking to have multiple readers/writers so the same annotation may be declared multiple times
<FromGitter>
<franciscoadasme> if you have another idea about how to handle this, I'll appreciate it
<FromGitter>
<Blacksmoke16> and the goal is to use the annotations to build methods?
<FromGitter>
<franciscoadasme> yes
<FromGitter>
<Blacksmoke16> id maybe consider having a like `AbstractWriter` and `AbstractReader` types
<FromGitter>
<Blacksmoke16> in addition to just being used to find formats, you could also use them for common documentation/defining required methods each writer/reader needs to implement
<FromGitter>
<Blacksmoke16> you know like `abstract def write(io : IO) : Nil`
<FromGitter>
<franciscoadasme> Sorry for not being clear, but the auto-generated methods are for other classes
<FromGitter>
<Blacksmoke16> right, you could do like you had before
<FromGitter>
<franciscoadasme> One example is `Foo.read "file.xyz"`, which is implemented as a switch where each case corresponds to the annotated readers
<FromGitter>
<franciscoadasme> but that would require to annotate readers and writers separately, right?
<FromGitter>
<Blacksmoke16> yes
<FromGitter>
<franciscoadasme> then it would be the same as I have it now... but I was thinking about how to avoid the duplicate annotations; it seems that there is no way to work with annotated modules right now... bummer :/
<FromGitter>
<Blacksmoke16> correct
<FromGitter>
<Blacksmoke16> what do the generated methods look like?
<FromGitter>
<Blacksmoke16> i.e. do they need to be generated at compile time?
<FromGitter>
<Daniel-Worrall> Andriamanitra, linear diophantine equations might point you in the right direction, but the problem is a pretty famous theorem if you find it/know it
<Andriamanitra>
yeah, i looked at the wikipedia article for the theorem but couldn't figure out how to implement it and didn't want to cheat even more by looking at actual algorithms :p
<FromGitter>
<franciscoadasme> right now, yes... for example, the methods `Foo.from_xyz` and `Foo.to_xyz`are auto-generated assuming the file format `XYZ` exists
<FromGitter>
<Daniel-Worrall> In that case, did you find Bézout's identity?
<FromGitter>
<franciscoadasme> As file formats accept different options when reading/writing, I couldn't find a way to declare a general method without dropping type safety
<Andriamanitra>
yeah
<FromGitter>
<Daniel-Worrall> Welp, I think any further would ruin it. So good luck. I'm racking my head at implementing it right now
<FromGitter>
<Blacksmoke16> @franciscoadasme have you considered having a single class, like `XYZFormat` that implements the read/write methods?
<FromGitter>
<franciscoadasme> @Blacksmoke16 yes, but since reading and writing require different arguments and temporary data, I'm not a fan of merging the two classes into one... although there may be no other way
<FromGitter>
<Blacksmoke16> granted another option is to just not autogenerate all this stuff
<FromGitter>
<Blacksmoke16> unless you think adding formats is going to be common the extra complexity might not be worth it
<FromGitter>
<franciscoadasme> I have like 10 formats already, and there're many more to implement
<FromGitter>
<Blacksmoke16> ah fair enough
<FromGitter>
<franciscoadasme> there several libraries that do something similar within the same field, but most of them are implemented in Python or another dynamic lang... the few implemented in C/C++ or similar aren't easy to use so I was looking to find a sweet spot between speed and convenience
<FromGitter>
<franciscoadasme> one particular C++ library has a single class per format as you suggested, but in reality, it acts more like a common IO class (almost no share code between the read and write methods)
<FromGitter>
<Blacksmoke16> hmm
<FromGitter>
<mwlang> > I don't know what is your problem, but you don't need to store all the collection at each turn ⏎ ⏎ that's true. I hadn't thought beyond the initial implementation, yet. I got hung up on trying to figure out why Ruby's fast and Crystal's super slow in this scenario. That's the far more curious problem than the puzzle itself. :-)
<Andriamanitra>
mwlang: unshifting arrays is super slow in crystal
<Andriamanitra>
use deque and it's similarly fast as ruby
<Andriamanitra>
5.14 seconds in crystal (with deque), 12.33s in ruby on my machine