jhass changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.28.0 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
ashirase has joined #crystal-lang
_whitelogger has joined #crystal-lang
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
alexherbo21 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 255 seconds]
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
early has quit [Quit: Leaving]
early has joined #crystal-lang
teardown has joined #crystal-lang
early has quit [Quit: Leaving]
early has joined #crystal-lang
laaron has quit [Remote host closed the connection]
Raimondii has joined #crystal-lang
Raimondi has quit [Ping timeout: 245 seconds]
Raimondii is now known as Raimondi
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
_whitelogger has joined #crystal-lang
<FromGitter> <watzon> I can't remember who was trying to help me before, I think it was you @Blacksmoke16, but I think I found the error that was causing my seemingly simple method that works in Javascript to fail in Crystal
<FromGitter> <watzon> #7782
<FromGitter> <watzon> I'm finding a lot of weirdness here
<FromGitter> <watzon> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cdbc8bde7f42160fa908a60]
<FromGitter> <kaukas_gitlab> @watzon, I think you should just declare your types, `x : Int64, j : Int64`
<FromGitter> <watzon> I could do that, but I shouldn't have to
DTZUZO has quit [Ping timeout: 246 seconds]
<jokke> straight-shoota: thanks!
ashirase has quit [Ping timeout: 255 seconds]
ashirase has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> @watzon woah that's weird.
<FromGitter> <dscottboggs_gitlab> so... at some point it was decided to automatically assign values their types based on constant values. Integers still default to `Int32`. So, `0x10000000000` is a literal which MUST be of type `Int64` (because it overflows `Int32`), but `j` has defaulted to `Int32`. `Int32#+(Int64)` should return an `Int64`, imo, but it does not, and there inlies your problem.
<FromGitter> <straight-shoota> @dscottboggs_gitlab If `Int32#+(Int64)` returned `Int564`, you couldn't do `a += b` when `a` is restricted to `Int32` and `b` is `Int64`. And the same should probably apply for `UInt64`, which would make `-2 + 1_u64` overflow.
<FromGitter> <dscottboggs_gitlab> oof
<FromGitter> <dscottboggs_gitlab> yeah
<FromGitter> <dscottboggs_gitlab> I was thinking after I said that that that would probably be confusing
<FromGitter> <dscottboggs_gitlab> so then I think your only option in that case is to annotate `j` as an `Int64`? Which seems pretty fair to me considering
<FromGitter> <straight-shoota> Yes, if you wan't Int64 maths
sz0_ has joined #crystal-lang
<FromGitter> <mwlang> @Blacksmoke16 ⏎ ⏎ > hardest part of all this is making sure the required services are registered before they are needed, if you have any ideas im open to them :) ⏎ ⏎ I don't think you should solve this particular case. This is a programmer's error. if a compiler error's not possible here (remember, I'm still learning crystal..) and depending on how you implemented it under the covers, my thought
<FromGitter> ... would be to check for presence in the registry, if not there, raise runtime error. [https://gitter.im/crystal-lang/crystal?at=5cdc040256271260f96692df]
<FromGitter> <Blacksmoke16> no i mean say you do something like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cdc04348fcdb05d47dd534d]
<FromGitter> <Blacksmoke16> when you iterate over children of the parent class, AService would be registered first, since it was defined first
<FromGitter> <Blacksmoke16> which would mean it doesnt know about the `Store` dependency
<FromGitter> <Blacksmoke16> would be a terrible UX to require the user to define their services in right order just for it to work
<FromGitter> <mwlang> Ah, I get you.
<FromGitter> <Blacksmoke16> yea, have it working atm but im not a fan of it
<FromGitter> <mwlang> Are these typically all in the same file or are they dispersed into specific folders of a typical Athena project?
<FromGitter> <Blacksmoke16> id imagine each service would be its own file
<FromGitter> <Blacksmoke16> there isnt a specific folder structure for athena unlike rails or whatever
<FromGitter> <mwlang> so, can you rely on establishing a convention that would reduce likelihood of this case occurring?
<FromGitter> <Blacksmoke16> like what?
<FromGitter> <mwlang> well, without the folder structure a-la Rails, nixes that idea I had. ;-)
<FromGitter> <Blacksmoke16> even if there was a `services` directory, it would require them in abc order, so would run into same problem
<FromGitter> <Blacksmoke16> could*
<FromGitter> <mwlang> I was just thinking if there's a conventional structure established, then you can control order of loading.
<FromGitter> <Blacksmoke16> currently im doing it in three steps
<FromGitter> <Blacksmoke16> first step is to register the ones that do not have any deps, or no service deps
<FromGitter> <Blacksmoke16> then iterate services that have service deps and see if they are all registered by now
<FromGitter> <Blacksmoke16> if so, register them, otherwise add them to a diff hash
<FromGitter> <Blacksmoke16> stage 3, iterate over that other hash until they are all registered, via checking if they have all been resolved and adding/deleting that record from the other hash if so, otherwise continue
<FromGitter> <mwlang> possible to lazy evaluate on first time encounter/usage?
<FromGitter> <Blacksmoke16> maybe?
<FromGitter> <Blacksmoke16> well hmm
<FromGitter> <Blacksmoke16> that would be harder as you would have to have a way to new up services but without actually newing them up?
<FromGitter> <Blacksmoke16> or at least delay the initialization, could be an optoin
<FromGitter> <mwlang> delaying the initialization is what I was thinking
<FromGitter> <mwlang> the register call just adds them to that hash of yours
<FromGitter> <mwlang> then when it's invoked the first time, that's when you instantiate.
<FromGitter> <mwlang> presumably by the time the code that's using it is encountered, everything's been loaded and registered.
<FromGitter> <Blacksmoke16> possibly, might have to think about that more
<FromGitter> <r00ster91> I'm really confused. In LLVM there are custom integer bit-width types (https://llvm.org/docs/LangRef.html#integer-type) ranging from 1 bit to 8388607 bits. An integer with 8388607 can represent a number that fills my entire terminal when printing it (>9001 lines). So why don't we go higher than 128 bits and use LLVM's custom bit widths instead of using GMP?
<FromGitter> <Blacksmoke16> thanks for the idea, ill keep you posted :p
<FromGitter> <mwlang> I'm reading through cyrstal's standard library and noticed this in HTTP::Websocket (https://github.com/crystal-lang/crystal/blob/7f82f79bd1e3a7a1a73607e35c0662906736f1f8/src/http/web_socket.cr#L43) ⏎ ⏎ ```def on_close(&@on_close : String ->)``` [https://gitter.im/crystal-lang/crystal?at=5cdc0731e7f42160fa92779c]
<FromGitter> <mwlang> I'm gathering & is like Ruby's & and essentially passing a Proc in, but could someone describe the whole of what's happening here left to right in English to help me interpret?
<FromGitter> <mwlang> especially the -> after the String is tripping me.
<FromGitter> <Blacksmoke16> normally `&` inthe args is a way to show that that arg is a block
<FromGitter> <Blacksmoke16> where the blocks gets a string, but returns anything?
<FromGitter> <Blacksmoke16> `String -> String` vs this where the block would be required to return a string as well
<FromGitter> <mwlang> So, "a block assigned to @on_close instance variable whose result must return a String"
<FromGitter> <mwlang> what would be the difference between ```(&@on_close : String)``` and ```(&@on_close : String ->)```
<FromGitter> <mwlang> Is this a blocking call? ```while data = @channel.receive?``` or can I add to this something like ```while data = @channel.receive? || idle_too_long?``` with intent that of implementing a means of sending a keep alive signal on the websocket if it goes too long without receiving any new data in it's on_message event.
DTZUZO has joined #crystal-lang
<FromGitter> <mwlang> Woah, this LLVM project is really cool. I never looked before! I just thought LLVM referred to how the parser for Crystal was built....as in an alternative to Lex/Bison for building fast parsers for the compiler.
alexherbo21 has quit [Ping timeout: 268 seconds]
alexherbo21 has joined #crystal-lang
<FromGitter> <Blacksmoke16> @mwlang close, the value in the block would be a string, not the return value
<FromGitter> <Blacksmoke16> like
<FromGitter> <Blacksmoke16> ```@on_close do |string| ⏎ # string is a string ⏎ # return type doesn't matter ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5cdc12ed0f381d0a76bdf75e]
laaron has joined #crystal-lang
alexherbo21 is now known as alexherbo2
<FromGitter> <mavu> I'm looking for a nice way to iterate over an array and delete elements.
<FromGitter> <mavu> (and do something with those elements before deleting them)
<FromGitter> <tenebrousedge> `keep_if` ? or `delete_if` ?
<FromGitter> <Blacksmoke16> delete_if is only for a hash it seems
<FromGitter> <tenebrousedge> `select` or `reject` are also things
<FromGitter> <tenebrousedge> what does "do something with those elements" entail?
<FromGitter> <mavu> I have a list of delays which I want to cancel
<FromGitter> <mavu> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cdc19e36fd7c11cd8c0c8b1]
<FromGitter> <mavu> but it occured to me that this is currently a memory leak
<FromGitter> <mavu> because I never clean up the array and it will accumulate dead delays.
<FromGitter> <mavu> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cdc1a2856271260f96738b7]
<FromGitter> <tenebrousedge> I would try to avoid reaching outside the block scope during iteration, as a general principle
<FromGitter> <mavu> yes, thats why I was asking for a nice way to do this :)
<FromGitter> <mavu> I can only think of things like after the @delays.each loop, do another loop which deletes elements.
<FromGitter> <Blacksmoke16> couldnt you do like
<FromGitter> <mavu> I thought there might be a nice way.
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cdc1aaab149ca509896fefa]
<FromGitter> <mavu> I'm not sure if I can. My thinking was that that might mess with the running itteration?
<FromGitter> <Blacksmoke16> :shrug: guess we'll find out
<FromGitter> <mavu> because the Array would change length while we are in the process of itterating overit
<FromGitter> <mavu> :P
<FromGitter> <tenebrousedge> it's possible, but I would work to avoid that. Are you deleting based on some condition?
<FromGitter> <mavu> no, just delete after calling cancel
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/6x6q
<FromGitter> <Blacksmoke16> yea rip
<FromGitter> <Blacksmoke16> is the expectation that delays is empty at the end of this?
<FromGitter> <mavu> yes
<FromGitter> <mavu> (ehrm. I think.)
<FromGitter> <mavu> yes. empty is right.
<FromGitter> <mavu> I could just throw the array away and assign a new one?
<FromGitter> <tenebrousedge> `@delays.map(&:cancel).clear` ?
<FromGitter> <mavu> yes!
<FromGitter> <mavu> that looks nice.
<FromGitter> <tenebrousedge> that's ruby :?
<FromGitter> <mavu> I'll take that :)
<FromGitter> <tenebrousedge> `@delays.map(&.cancel).clear`
<FromGitter> <Blacksmoke16> `arr.tap(&.each(&.cancel)).clear`
<FromGitter> <Blacksmoke16> to avoid the map, make intent more clear?
<FromGitter> <tenebrousedge> why avoid map?
<FromGitter> <mavu> not more clear to me :P
<FromGitter> <mavu> what is
<FromGitter> <Blacksmoke16> because it implies you're returning an array then clearing it, vs iterating over each delay, cancelling it, then clearing the delays array
<FromGitter> <Blacksmoke16> since `.each` returns nil
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/0.28.0/Object.html#tap(&block)-instance-method
<FromGitter> <mavu> Oh my. I bet you can write quite unreadable code with tap without much effort. Powerful thing though.
<FromGitter> <tenebrousedge> `partition...tap` can be more convenient than assigning two vars
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
<FromGitter> <pynixwang> any plan for pattern matching?
<FromGitter> <pynixwang> ruby 2.7 case in is comming
alexherbo29 has joined #crystal-lang
<FromGitter> <yxhuvud> IMO, there is no use implementing it before it is shown to actually be widely used in ruby. It is a quite big one, after all.
alexherbo2 has quit [Ping timeout: 258 seconds]
<FromGitter> <j8r> what's not possible already with `when`?
<FromGitter> <Blacksmoke16> @mavu sorry had a meeting
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cdc2528f251e60ffa87b9c2]
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cdc25465a887e1cd9f163f2]
<FromGitter> <Blacksmoke16> map has to create an intermediate array, then clears it, while tap each, clears the actual delays array, this avoiding another array
<FromGitter> <tenebrousedge> and if those few nanoseconds and bytes matter, use that
<FromGitter> <tenebrousedge> but otherwise use the higher-level iterator
<FromGitter> <mavu> @Blacksmoke16 Interesting.
<FromGitter> <Blacksmoke16> IMO the latter makes it more clear that you're "canceling each delay, then clearing the array", while the map version would make me think "im creating an array from the return value of `cancel` then clearing it"
<FromGitter> <tenebrousedge> you just like using `each`
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/6x7u your map version isnt actually clearing the `@delays` array
<FromGitter> <Blacksmoke16> just that array that gets returned via the map
<FromGitter> <Blacksmoke16> hence the need for tap each
<FromGitter> <Blacksmoke16> er wait
<FromGitter> <Blacksmoke16> yea
<FromGitter> <Blacksmoke16> updated link, added comments
<FromGitter> <tenebrousedge> you could do `@delays = @delays.map` but using `tap/each` makes more sense there. But using lower-level iterators without a specific need always produces worse code
<FromGitter> <vladfaust> Is it normal that we cannot define `abstract def self.foo` on abstract objects?
<FromGitter> <vladfaust> https://carc.in/#/r/6x7w
<FromGitter> <Blacksmoke16> yes
<FromGitter> <vladfaust> Has it always been this way?
<FromGitter> <vladfaust> What's the point of this restriction if I can do https://carc.in/#/r/6x7x
<FromGitter> <Blacksmoke16> wrap that in a included
<FromGitter> <vladfaust> /cc @RX14
<FromGitter> <Blacksmoke16> so it runs in the child class
<FromGitter> <vladfaust> What?
<FromGitter> <Blacksmoke16> https://carc.in/#/r/6x7y
<FromGitter> <Blacksmoke16> @tenebrousedge sure, but map isnt the right on here either
<FromGitter> <Blacksmoke16> if the intent is to do some action to each object then clear the initial array
<FromGitter> <vladfaust> Why would I want that? I'm struggling for defining an abstract method, which must be implemented in children
<FromGitter> <vladfaust> And your carc raises even if it is
<FromGitter> <Blacksmoke16> sec
<FromGitter> <Blacksmoke16> https://carc.in/#/r/6x8i forgot a `\`
<FromGitter> <Blacksmoke16> could update error message to include the class name
<FromGitter> <vladfaust> Oh, nice
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <vladfaust> Wouldn't work for nested inheritance, though?
<FromGitter> <Blacksmoke16> it would unless the middle type defines it
<FromGitter> <Blacksmoke16> which the child there would use the middle types method
<FromGitter> <vladfaust> Indeed https://carc.in/#/r/6x8k. Thanks!
<FromGitter> <Blacksmoke16> np
<FromGitter> <mwlang> > I thought there might be a nice way. ⏎ ⏎ Implement within a method, returning what's not "deleted" and assign method result back to the @delays variable.
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/0.28.0/Array.html#reject!(&block)-instance-method would be good for that
<FromGitter> <tenebrousedge> yes, these things were mentioned
<FromGitter> <watzon> I'm not good with this kind o stuff. Does anyone know how I could take an array of integers and split it into groups of 512 bits each?
<FromGitter> <bcardiff> @watzon you might be looking for `BitArray`
<FromGitter> <watzon> Maybe if it was possible to turn an Array into a BitArray and then back again. All I need to do is take each element in an array of integers, count the bits (most likely 16), and then chunk groups of those elements together where their total size is 512 bits.
<FromGitter> <watzon> I was thinking the `Array#chunk` method would work, but it's not looking like it
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/0.28.0/Enumerable.html#in_groups_of(size:Int,filled_up_with:U=nil)forallU-instance-method
<FromGitter> <Blacksmoke16> ?
<FromGitter> <watzon> If only `in_groups_of` worked on the bitsize of the integer instead of the count
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/6x8v
<FromGitter> <Blacksmoke16> assuming you would be able to convert your array of ints into binary
<FromGitter> <Blacksmoke16> then in_group_of would work nicely with bit array to get groups of 512
<FromGitter> <Blacksmoke16> but that conversion im not sure of either :/
<FromGitter> <watzon> Hmmm
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/6x9j :shrug: idk
<FromGitter> <Blacksmoke16> has to be a better way
dannyAAM has quit [Quit: znc.saru.moe : ZNC 1.6.2 - http://znc.in]
dannyAAM has joined #crystal-lang
<FromGitter> <tenebrousedge> Apparently Crystal doesn't have `Array#pack` or `String#unpack`, for reasons: ⏎ https://github.com/crystal-lang/crystal/issues/276 ⏎ but there is an implementation here: ⏎ https://github.com/Fusion/crystal-pack [https://gitter.im/crystal-lang/crystal?at=5cdc4249f52a23751638d239]
moei has joined #crystal-lang
alexherbo299 has joined #crystal-lang
alexherbo29 has quit [Ping timeout: 268 seconds]
alexherbo299 has quit [Ping timeout: 257 seconds]
alexherbo2995 has joined #crystal-lang
alexherbo2995 is now known as alexherbo2
alexherbo2 is now known as alex```
<z64> @watzon would something like this be what you're looking for? https://play.crystal-lang.org/#/r/6xaa
<z64> woops, @position is unnecessary.. https://play.crystal-lang.org/#/r/6xac
<FromGitter> <tenebrousedge> @z64 would there be an advantage to using `Iterator`, do you think?
<FromGitter> <z64> for his use case, it doesn't sound like it, no
<FromGitter> <tenebrousedge> what might a good heuristic be for deciding between those?
<FromGitter> <z64> iterator is good for things you want to do lazily
<FromGitter> <z64> in his case, he'll always want to "consume" the entire set of bits in the number, and not stop short
<FromGitter> <Blacksmoke16> e.x. iterating a large array of objects so that the whole array isnt in memory at once right?
<FromGitter> <z64> sure
<FromGitter> <z64> thats what i understand they want to do, anyways - waiting for them to reply to clarify:V
<FromGitter> <z64> additionally in this case, all these calculations happen on the stack / don't allocate anything, and have a fixed upper size (the biggest int) ⏎ so no need to worry about memory or speed here, should be plenty fast
<FromGitter> <tenebrousedge> sure, I'm just theorizing
<FromGitter> <z64> another example i like, Iterator is good for something like, wrapping an API endpoint that is paginated
<FromGitter> <z64> where you would have some state to keep track of a cursor
<FromGitter> <tenebrousedge> 👍
<FromGitter> <Blacksmoke16> oo where your `next` method would fetch the next page
<FromGitter> <Blacksmoke16> neat
<FromGitter> <z64> exactly - then the user doesn't have to juggle the cursor themselves, they just `paginated_request.each do |page_of_results|`, or like `paginated_request.each.to_a` to get an array of all results
<FromGitter> <Blacksmoke16> 💯 clever
greengriminal has joined #crystal-lang
sz0_ has quit [Quit: Connection closed for inactivity]
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
laaron has quit [Remote host closed the connection]
laaron has joined #crystal-lang
dannyAAM has quit [Quit: znc.saru.moe : ZNC 1.6.2 - http://znc.in]
dannyAAM has joined #crystal-lang
dannyAAM has quit [Client Quit]
dannyAAM has joined #crystal-lang
laaron has quit [Remote host closed the connection]
<FromGitter> <mwlang> How do you spawn, say 10 fibers then wait for all 10 to complete before moving on? i.e. Ruby's ```threads.each(&:join)``` where threads is an array of Thread
laaron has joined #crystal-lang
<FromGitter> <mwlang> goal is to download data in parallel from REST API and once all data is collected, then fire up Websocket to listen for changes in the data.
<FromGitter> <mwlang> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5cdc8deb56271260f96a78e5]
hightower2 has joined #crystal-lang
hightower2 has quit [Ping timeout: 255 seconds]
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/0.28.0/toplevel.html#parallel(*jobs)-macro
<FromGitter> <Blacksmoke16> could use that
<FromGitter> <mwlang> I don't know how you keep finding all these things, but yeah, exactly what I needed.
<FromGitter> <Blacksmoke16> :p
moei has quit [Quit: Leaving...]