<jhass>
really weird, I would expect to see some crash output before :/
<jhass>
can you not use shards build but crystal build --threads=1 -v src/foo.cr ?
<FromGitter>
<mattrberry> Does that build for release?
<FromGitter>
<mattrberry> I only get the issue when building for release
<jhass>
yeah, just add --release
<FromGitter>
<mattrberry> `crystal build --release --threads=1 src/cryboy.cr` fails in seemingly the same way
<jhass>
shards build just invokes it internally
<jhass>
mmh
<jhass>
can you try after nuking your cache? crystal env CRYSTAL_CACHE_DIR
<FromGitter>
<mattrberry> Took like 2 minutes to build, but it built..
<jhass>
and if you retry now with a warm cache? :)
<FromGitter>
<mattrberry> Hmmm, is it compiling files with c-bindings for release that takes forever? If I change any line in the file that has the c-bindings, compiling for release takes about 4 minutes.
<FromGitter>
<mattrberry> Without changing anything between compilation, it's obviously pretty quick though
<jhass>
release is just slow, we engage the highest LLVM optimizer mode
<jhass>
it probably just invalidates the cache
<FromGitter>
<mattrberry> Without these c-bindings, compiling for release takes be all of like 5 seconds
<jhass>
maybe it's just a lot less code without?
<jhass>
note that crystal only includes called code
<jhass>
if you never call a method its code is never generated
<jhass>
the more code is generated, the slower the LLVM codegen and optimization phase
<FromGitter>
<mattrberry> And just calling each once
<FromGitter>
<mattrberry> Know what? I just found out what is causing this to build so much slower. It's not the c-bindings
<FromGitter>
<mattrberry> As soon as I put ⏎ ⏎ ```@static_buffer = StaticArray(Float32, BUFFER_SIZE).new 0``` ⏎ ⏎ on my class, the build time goes from ~5 seconds to ~4 minutes, even if I *never* touch that variable. [https://gitter.im/crystal-lang/crystal?at=5ed6121fd137513704350b21]
<FromGitter>
<mattrberry> (I'm also clearing the crystal cache between every run)
<FromGitter>
<mattrberry> But if I remove that instance variable, then clear the cache, then build again, it builds in ~5 seconds again
<FromGitter>
<mattrberry> That line specifically is causing the build time to shoot up
<jhass>
mmh, what's BUFFER_SIZE?
<FromGitter>
<mattrberry> 4096
<jhass>
mmh, not too bad
<FromGitter>
<mattrberry> Yeah..
<jhass>
there has been some issue with big static arrays and compile times, trying to find it
<jhass>
since you embed into a class it's on the heap anyways, might juse use a Slice instead
<jhass>
that should workaround the issue
<FromGitter>
<mattrberry> I just made it an Array and it seems to be working fine..
<FromGitter>
<mattrberry> What's the advantage of Slice over Array in this case?
<jhass>
Slice is simpler and fixed size, array may reallocate internally
<jhass>
Slice is meant as a safe pointer, so a pointer plus a length
<jhass>
IO functions and similar work with slices for buffes but not arrays
<jhass>
so, I don't really know what you're using this for, the answer may be it's not :)
<jhass>
the above should give some hints on the tradeoffs
<FromGitter>
<mattrberry> Good info, thank you!
<jhass>
staticarray is for where you would use int[10] in C
<jhass>
so not a terrible amount of usecases outside C bindings
<FromGitter>
<mattrberry> There's still no reason that I see that would cause the compiler to shit the bed though..
<FromGitter>
<mattrberry> Thanks again for the help!!
<FromGitter>
... of Crystal at this point. Regardless, I still might try to add some detail to the api docs for StaticArray over the next few days since I think that'd be useful
<FromGitter>
<mattrberry> I added a comment to the closed issue you sent earlier. I think it'd be useful to describe the use-case for StaticArrays a little more clearly in the docs. It'd also be useful to find *some* way to improve error messages for this sort of thing, but that's beyond my knowledge. I've built a couple of toy compilers, and I know how much of a pain error messages can be. I can only imagine for a language the size
<FromGitter>
<mattrberry> Thank you again!
<FromGitter>
<ilourt> Hi, in a I have an annotation args as a TupleLiteral. I want to make a splat of it starting at the index 2. I don't find how to do that. Is anyone know if it is possible and how to do that ? thanks
<FromGitter>
<ilourt> *in a macro I have
<FromGitter>
<igor-alexandrov> Hooray! FastImage 0.2.0 release is here: https://github.com/jetrockets/fastimage.cr. Added support of dimensions for JPEG, PNG, BMP and GIF. Also refactored general API of library. Hope to add all other formats soon.
<yxhuvud>
staticarray is pretty nice if you want to embed a non-resizable array in an object itself without having to pay for the indirection of an actual array / slice.
<jhass>
I guess you trade one pointer dereference for more churn on the caches -> more page faults, especially if it gets big one can outweight the other :)
<yxhuvud>
The point would be less churn due to less fragmentation. It obviously demands that the usages actually do make use of the array
<yxhuvud>
But yeah, it definitely is something that may or may not be relevant on a case by case basis.
<jhass>
I'd say it's something not to guess but only look at if you got a benchmark
<FromGitter>
<Blacksmoke16> @ilourt prob could do something like `tuple_literal[2..-1].splat`
<FromGitter>
<Blacksmoke16> method should prob be added to the API docs that you can do a range
<FromGitter>
<j8r> I don't understand: Hash is not an Indexable?
<FromGitter>
<j8r> It has lots of methods which looks like it is: `dig`, `#[](index)`, etc
<FromGitter>
<igor-alexandrov> yes, but `Indexable ` has methods liks `#first` and `#last` for example
<FromGitter>
<igor-alexandrov> and `Hash` has `#first_value` and `#last_value`
<FromGitter>
<j8r> This does not really give an answer
<FromGitter>
<j8r> I would expect `Hash#first` to give a Tuple, like `Hash[0]`
<FromGitter>
<igor-alexandrov> of course `#first` for `Hash` could return a pair of key and value, but again such behaviour differs from what `Indexable` gives
<FromGitter>
<j8r> Hum why?
<FromGitter>
<j8r> the only thing to define is `unsafe_fetch` to be able to include `Indexable`
<FromGitter>
<igor-alexandrov> hmmm, no
<FromGitter>
<igor-alexandrov> Indexable works for a type
<FromGitter>
<Blacksmoke16> i would have thought `String` would have been as well, but :shrug:
<FromGitter>
<igor-alexandrov> and based on what we discussed above some of Hash methods return Type and others – Tuple
<FromGitter>
<j8r> @igor-alexandrov I mean we can then do `include Indexable({K, V})`
<FromGitter>
<j8r> Thats already done in Hash for Enumerable and Iterable
<FromGitter>
<j8r> @Blacksmoke16 Me too, there was an idea of a ByteView and CharView
<FromGitter>
<j8r> I make a helper `cast_to_hash_or_indexable`...
<FromGitter>
<j8r> because don't like `value.responds_to?(:dig)`
<FromGitter>
<j8r> I think this kind of duck typing is messy, better using proper types
HumanG33k has quit [Ping timeout: 256 seconds]
HumanG33k has joined #crystal-lang
<jhass>
Indexable is for indexing by integer
<jhass>
it's not meant as a generic Map interface
<jhass>
think of it as a List interface rather
<FromGitter>
<j8r> But we can index Hash by integer
<FromGitter>
<j8r> Hash can behave like a list
<FromGitter>
<j8r> It is even use a a backend for Set
<jhass>
so you want some_hash[0] to return the first element?
<FromGitter>
<j8r> ha, I see
<FromGitter>
<j8r> why not?
<FromGitter>
<j8r> It is already the case with `Hash#first`
<FromGitter>
<Blacksmoke16> because it would conflict with a key of `0` that is not first
<FromGitter>
<j8r> yeah...
<yxhuvud>
j8r: because I'd expect `{2 => 1, 0 => 10}[0]` to return 10.
<FromGitter>
<j8r> Or maybe having a `Diggable` module
<FromGitter>
<j8r> the `value.responds_to?(:dig)` feels hackish, there is no interface what so ever
<FromGitter>
<j8r> this method can be implemented incorrectly - that why in the first place I was looking at Indexable
<yxhuvud>
Yes, the first tries to implement dig all failed due to having horrible type sgnature.
<FromGitter>
<j8r> I guess I can include Indexable in a Any type
<FromGitter>
<j8r> Hum yes, but It won't support string keys...
<FromGitter>
<ilourt> @Blacksmoke16 thank you for your reply, it works like a charm.
<FromGitter>
<Blacksmoke16> 👍
<FromGitter>
<evvo> Hello!
<jhass>
hi :)
<FromGitter>
<Blacksmoke16> o/
<FromGitter>
<evvo> Does someone knows if generics works with static properties ?
<FromGitter>
<Blacksmoke16> like class vars? i would think not?
<FromGitter>
<evvo> I'm getting `Error: can't infer the type parameter ModelType for the generic class DatabaseProvider(ModelType). Please provide it explicitly`
<FromGitter>
<Blacksmoke16> got some example code?
<FromGitter>
<j8r> it is not possible, because class methods/vars are shared for ALL instances
<FromGitter>
<j8r> including generic variations
<jhass>
evvo: think about it, What type would DatabaseProvider.records have?
<FromGitter>
<j8r> @evvo I think you want to share DatabaseProvider globaly?
<FromGitter>
<evvo> @j8r , if the classes with different generics are not separate, it actually won't work at all for the purpose that I was planning to use it
<FromGitter>
<j8r> yep
<jhass>
just wrap it into one and make instances :)
<FromGitter>
<j8r> You can create an instance of DatabaseProvider, and assign it to a class var
<FromGitter>
<j8r> and expose it with `class_getter db_provider : DatabaseProvider`
<FromGitter>
<evvo> @j8r , I was planning to have separate global instances, based on their generics - for example DatabaseProvider(User) and DatabaseProvider(Address)
<jhass>
just have a class where you store those instances and look them u
<jhass>
up
<FromGitter>
<j8r> yes, like jhass said
<jhass>
can even reuse DatabaseProvider
<FromGitter>
<evvo> I will send you another example to see what is my idea
<FromGitter>
<Blacksmoke16> repository is tricky, esp the save side of things
<FromGitter>
<Blacksmoke16> like how to update the `id` without exposing a setter
<FromGitter>
<j8r> @evvo you can't use generics with `class_` things
<FromGitter>
<j8r> To sumup, what is know at compile time, and what is needed to be retrieved globally?
<FromGitter>
<j8r> Does Address and User will always be set, somehow?
<FromGitter>
<evvo> Yes, these classes should be known at compile time
<FromGitter>
<evvo> @j8r , I think that my general mistake was that I was assuming that class variables for different generics signatures are created separately (for example @@records for Repository(UserModel) are not the same @@records for Repository(AddressModel))
<FromGitter>
<j8r> Ha I think I see
<FromGitter>
<j8r> What can solve you issue
<FromGitter>
<j8r> Make them inherit from a same class, or include a same module
<FromGitter>
<j8r> So, no need generics
<FromGitter>
<j8r> of course, `UserModel` and `AddressModel` may have different methods. Casting will be needed afterwards
<FromGitter>
<evvo> Yes, I run into such casting issues before
<FromGitter>
<j8r> `abstract def` can be defined in the `Model` module too
<FromGitter>
<evvo> I will need to create separate repositories - for all models
<FromGitter>
<Blacksmoke16> or just make your repositories instances
<FromGitter>
<j8r> yeah, repository instances
<FromGitter>
<Blacksmoke16> ORM we use at work uses this approach (in PHP so not exactly the same but yea). I.e. like `$em->getRepository(User::class)`
<FromGitter>
<evvo> @Blacksmoke16 , yes, they will be separate instances, resolsved from a single container
<raz>
Stephie: wait, so you could donate $1k to yourself and github will give you another free $1k? :p
<raz>
(not saying you should do that! lol)
<FromGitter>
<j8r> if *this* is the last breaking change...
<Stephie>
raz, you can't donate to yourself, and donations from other accounts who are also being sponsored dont count
<Stephie>
also, they'll just ban you
<FromGitter>
<j8r> It could be spotted work raz, but you can agree with another guy
<raz>
j8r: i guess both windows users will be very sad for the entire 10 seconds it takes them to fix their code :P
<FromGitter>
<j8r> But having only one guy donating 1k is very suspect lol
<FromGitter>
<j8r> I do bet there is an exception for the "no more breaking changes", if it is necessary for more Windows support
<raz>
Stephie: yea, i guess it could still be cheated (colluding with multiple ppl etc.), but i hope ppl don't abuse it as it's a really cool offer by github
<Stephie>
yeah
<Stephie>
its been a while and they're still doing it
<Stephie>
so it's clearly been good!
<FromGitter>
<j8r> Right raz
<FromGitter>
<j8r> I sponsor you, and you sponsor me haha
<raz>
who's getting the crystal donations btw? (i'm already donating there, i wonder if it'd be smarter if all the core devs get on the github boat :P)
<raz>
j8r: i imagine they'd probably shut it down when any interesting amount is reached anyway ;)
<FromGitter>
<yorci> Hi, can i bind the outgoing request to a particular IP address on my server with HTTP::Client ?
<FromGitter>
<yorci> and how
<FromGitter>
<j8r> Not sure to understand @yorci
<raz>
he wants to change the src address
<raz>
(server prob has multiple interfaces)
<FromGitter>
<j8r> but why HTTP::Client
<raz>
possibly the other side firewalls and he need his request to come from a specific ip
<FromGitter>
<j8r> Yes you can bind on multiple interfaces
<FromGitter>
<j8r> with `HTTP::Server#bind_tcp`
<FromGitter>
<yorci> I mean i have 10 ip adress on a server, i want to send request to some API with different ip addresses i have bcuz API has ip based request limits
<FromGitter>
<yorci> No, not server
<FromGitter>
<j8r> ha ok
<FromGitter>
<j8r> got it
<raz>
basically the --interface option on curl
<FromGitter>
<j8r> the server part was superfluous information
<raz>
not sure if crystal HTTP has an api for that
<FromGitter>
<yorci> @raz yea i was using curl but, i need to implement that feature in my crystal program
<FromGitter>
<j8r> of course you will have to use raw HTTP/1.1 - but that's not very hard
<FromGitter>
<yorci> @j8r alright thank you
<FromGitter>
<j8r> There is an examples below, with udp (but tcp can be used too)
<FromGitter>
... sanity testing, though, and it was wonderfully painless.
<FromGitter>
<kinxer> I just want to express how happy I am with I/O in Crystal. I'm writing code in Java that has to read a binary file in a particular format, and I've discovered that there's no good API for reading little-endian values in Java (the `DataInputStream` class, which I would expect to do this, reads only big-endian and doesn't document that fact). I wrote a little program in Crystal to generate files in this format for