RX14 changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.24.1 | 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
cremes has quit [Quit: cremes]
justicefries has joined #crystal-lang
justicefries has quit [Quit: Textual IRC Client: www.textualapp.com]
daemonwrangler has quit [Quit: ZNC 1.6.5 - http://znc.in]
daemonwrangler has joined #crystal-lang
cremes has joined #crystal-lang
cremes has quit [Client Quit]
<FromGitter> <iambudi> crystal 0.24.1 on osx. Shards install slows down computer. There are a lot of process in activity monitor. Took sometimes to get back to normal.
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 240 seconds]
_whitelogger_ has joined #crystal-lang
avdi_ is now known as avdi
FromGitter has joined #crystal-lang
A124 has quit [Ping timeout: 260 seconds]
lachlan has joined #crystal-lang
A124 has joined #crystal-lang
<FromGitter> <lachlan> Would adding UUID#to_json(JSON::Builder) and UUID.new(JSON::PullParser) be accepted into the std library, so UUIDs can be used directly in JSON mappings? If so, I'd like to make a pull request for it
lachlan has quit [Remote host closed the connection]
hightower3 has quit [Ping timeout: 268 seconds]
hightower3 has joined #crystal-lang
hightower3 has left #crystal-lang [#crystal-lang]
jnyw has joined #crystal-lang
cremes has joined #crystal-lang
cremes has quit [Client Quit]
cremes has joined #crystal-lang
daemonwrangler has quit [Quit: ZNC 1.6.5 - http://znc.in]
cremes has quit [Client Quit]
daemonwrangler has joined #crystal-lang
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 265 seconds]
relyks has joined #crystal-lang
<relyks> is it possible to create RegEx's dynamically?
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 256 seconds]
ashirase has quit [Ping timeout: 240 seconds]
ashirase has joined #crystal-lang
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 240 seconds]
<FromGitter> <codenoid> lol no
<FromGitter> <codenoid> yes
TIMEBONEZ has quit [Quit: WeeChat 1.2]
_whitelogger has joined #crystal-lang
<relyks> @codenoid were you responding to me?
<FromGitter> <marksiemers> Yes regex's can be created dynamically: ⏎ ⏎ ```x = "a" ⏎ /#{x}/.match("asdf") # => #<Regex::MatchData "a">``` [https://gitter.im/crystal-lang/crystal?at=5a507c1029ec6ac311c55f6f]
<FromGitter> <marksiemers> You can also use the `new` method: `Regex.new("^a-z+:\\s+\\w+")`
rohitpaulk has joined #crystal-lang
<relyks> @marksiemers thanks that's what I wanted :)
alex`` has joined #crystal-lang
relyks has quit [Quit: relyks]
rohitpaulk has quit [Ping timeout: 256 seconds]
alex`` has quit [Ping timeout: 265 seconds]
rohitpaulk has joined #crystal-lang
vegai_ is now known as vegai
<FromGitter> <straight-shoota> @lachlan I don't see why not. Just open an issue about it first.
<crystal-gh> [crystal] noriyotcp opened pull request #5547: Fix typo mutli to multi (master...fix-typo-mutli-to-multi) https://git.io/vNT0n
rohitpaulk has quit [Ping timeout: 248 seconds]
Groogy2 has joined #crystal-lang
Groogy has quit [Disconnected by services]
Groogy2 is now known as GRoogy
GRoogy is now known as Groogy
<Groogy> Morning! o/
Groogy_ has joined #crystal-lang
<FromGitter> <bararchy> Morning :)
<Groogy> hopefully gonna get sometime to day to code ^^
<FromGitter> <imonmyown> morning 👏
<Groogy> ow yeah is 2.4 fully released now?
claudiuinberlin has joined #crystal-lang
<FromGitter> <bararchy> 1) 24
<FromGitter> <bararchy> yeha
<FromGitter> <lachlan> @straight-shoota OK, thanks, I'll open an issue
rohitpaulk has joined #crystal-lang
alex`` has joined #crystal-lang
jnyw has quit [Quit: WeeChat 2.0.1]
<FromGitter> <imonmyown> guys, how do I get the default system's size type in crystal?
<FromGitter> <bew> sizeof(SomeType) ?
<Groogy> think he means like in c++ you have std::size_t
<FromGitter> <imonmyown> I guess it should be something like sizeof(Pointer(Void))
<Groogy> which is defined as a unsigned int
<FromGitter> <imonmyown> @Groogy yeah
<FromGitter> <bew> Ah
<Groogy> don't think Crystal have any like that
<FromGitter> <imonmyown> don't you think it could be beneficial?
<FromGitter> <straight-shoota> what about `sizeof(LibC::SizeT)`?
<FromGitter> <imonmyown> well 32-bit systems are gradually phased out, so... probably not very beneficial
<Groogy> Array#size returns a Int32 ¯\(°_o)/¯
<FromGitter> <imonmyown> hm...
<FromGitter> <imonmyown> you have a 64 bit machine, right?
<FromGitter> <imonmyown> well I have that too and I'm 64
<jhass> Crystal doesn't use architecture specific sizes unless necessary to bind external libraries
<FromGitter> <imonmyown> well Cap says it limits container sizes..
<Groogy> you need an array larger than 3 billion?
<FromGitter> <imonmyown> no, but Cap has an opinion and you can't disrespect him ;)
<jhass> What's Cap
<Groogy> who is Cap?
<FromGitter> <bararchy> hard cap?
<FromGitter> <bararchy> as in limit?
tybee[m] has quit [Quit: idle on matrix for more than 30 days]
<FromGitter> <bew> Where is cap? (For completion ˆˆ)
<FromGitter> <imonmyown> well, you know, the Cap (http://knowyourmeme.com/memes/captain-obvious)
<Groogy> actually curious why Array uses Int32 and not UInt32
<Groogy> aaaah
<jhass> Groogy: probably because just writing 12 is a Int32 and foo.size == 12 is faster if both are the same type
<Groogy> true :/
<Groogy> though comparison I think work seemlesly?
<jhass> so there's a hard limit, yes, but it's not architecture specific in crystal (ignoring the maximum amount of coroutines)>
<Groogy> think it is probably a = 12; a = foo.size
<Groogy> that's where the problem comes
<jhass> well if I want to compare uint32 and int32 I need a bitshift, no?
<RX14> Not when they're positive
<Groogy> an int32 that is negative can never be true with an uint32
<Groogy> so the test would be pretty simple
<jhass> wouldn't it give false positives if the uint32 is > int32::MAX?
<jhass> and you happen to compare against a negative number
<Groogy> depends on how the comparison is written, but I think that works? It works in c++ at least
<jhass> so you have to check whether it's positive, still slower
<Groogy> wait a second gotta test this
<RX14> Yeah you'd just cast to signed
<RX14> And then compare
<Groogy> so it doesn't work it seems :P
<Groogy> foo is apparently less than bar
<FromGitter> <bararchy> well, Bar is always better ;)
<Groogy> ugh yeah nvm I forgot the compiler warns you about this, we have treat warnings as errors at work
<FromGitter> <asterite> The reason is to avoid mixing signed with unsigned. Someone said it: x = 1; x = a.size. Int32 is the most common type so writing to_i there is boring
<Groogy> Yeah I guessed as much
<Groogy> also I was super badly wrong on comparison between signed and unsigned
<FromGitter> <asterite> Unsigned comparison doesn't work in C but it works on Crystal
<FromGitter> <asterite> but it's a bit slower (just a bit)
<Groogy> oh it does? Nice
<FromGitter> <asterite> That was another reason to avoid signed, in the beginning the comparison didn't work, later we fixed it
<RX14> Slice size should be size_t though
<RX14> Not array, just slice
<RX14> Because most C buffers use sizet, if you can't create a slice of those buffers it defeats the point of slice
<Groogy> you mean LibC::SizeT?
<Groogy> shouldn't a SizeT be defined globally for that?
<RX14> And people will end up going back to just using pointer and not slice
<RX14> Groogy: if it's used in only one place why bother
<FromGitter> <asterite> I wouldn't mind Slice being like that. We'd have to change it and see how much code breaks
<RX14> Maybe alias Slice::Size
<RX14> @asterite yeah
<RX14> I should keep a list
<Groogy> Yeah that seems bit better
<Groogy> just Slice has useful areas outside of LibC
<Groogy> I use Slices for packing together data for the graphics card
<FromGitter> <bararchy> @asterite RX14, how much time would you evaluate adding support for Multi-Threading is going to take? would this https://github.com/ysbaddaden/gc/tree/rework-c-library/c be a part of the solution?
<Groogy> wait you guys writing a fresh new GC?
<RX14> @bararchy GC isn't a problem
<RX14> bdwgc handles threads perfectly fine
<RX14> if with a performance penalty
hightower2 has quit [Ping timeout: 240 seconds]
<RX14> having even manual Thread.new working would be fairly easy
thelonelyghost has quit [Quit: idle on matrix for more than 30 days]
<RX14> but nobody wants to do thread scheduling themselves
<RX14> they want to spawn a fiber and have it *just work* like go
<FromGitter> <bararchy> I was under the impression that the GC is a big part of why it's so hard to add it
<RX14> and that's the hard bit
<Groogy> well if threading starts to work I'll start to multithread my rendering....
<Groogy> you thought 11k frames were fast ;D
<RX14> @bararchy then you got the wrong impression
<Groogy> (though honestly it won't get higher than that I think, pretty sure at that point its GPU bound)
<FromGitter> <bararchy> apprently :)
<RX14> i'm in half a mind to just... add manual threading support
hightower2 has joined #crystal-lang
<Groogy> if you do it will be used
<FromGitter> <bararchy> I would Love Thread.new to work
<RX14> I think it would be useful even when we have a threadpool for fibers
<Groogy> not by me but yeah
<FromGitter> <bararchy> without sigfault
<RX14> because there exists plenty of C libraries that will want traditional threadpools anyway
<RX14> so I think we should support both
<FromGitter> <bararchy> ^ Totally aggree
<RX14> plus it gives something for the scheduler guys to work on top of
<Groogy> as with Pointer, support it, heavily discourage it
<RX14> indeed
<RX14> problem is if the lag between implementing that and implmenting a scheduler becomes too high then people will end up just using Thread
<Groogy> could put thread on an experimental branch
<Groogy> though depends on how easy that is to keep up to date
<Groogy> I would be on the experimental branch though :/
<Groogy> or just when you compile Crystal you have to turn it on like -DPOSIX=1
<FromGitter> <bararchy> Please add thread :)
<FromGitter> <bararchy> I would love to use it
<RX14> people loving to use it is the problem
<FromGitter> <bararchy> true
<RX14> what would you use it for @bararchy
<FromGitter> <bararchy> but now I have no better way
<RX14> graphics programming seems a very good usecase
<FromGitter> <bararchy> SHAInet, multi-thread functions for numeric calc
<Groogy> There's also for gameplay
TheGillies has quit [Quit: idle on matrix for more than 30 days]
<Groogy> but then jobs/fibers are probably better
<Groogy> there's also a super good talk about that at GDC
<RX14> well the idea to me would be, you'd have one thread that was your main thread and worked as it does currently
<RX14> and then you'd use Thread.new
<RX14> it'd have one "fiber" pinned to it
<RX14> and using Channel would raise
<FromGitter> <bararchy> can I share mem though ?
<RX14> ofc
<RX14> otherwise it's pointless
<FromGitter> <bararchy> awsome !
<RX14> just fork
<FromGitter> <bararchy> yeha
<RX14> you can use shared memory already
<FromGitter> <bararchy> it will make SHAInet so much faster
<RX14> if you use mmap
<FromGitter> <bararchy> but now you cannot allocate else it crashes
<RX14> and a bunch of things would either raise or just not use events
<FromGitter> <asterite> The GC is part of the problem for multithreading, though
<FromGitter> <asterite> To make it work there were some locks, and it made everything quite slow
<RX14> @asterite iirc that was a small patch and then it was fine
<RX14> oh
<FromGitter> <asterite> Yes, to make it work
<FromGitter> <asterite> But then it was slow
<RX14> but bdwgc must support multithreading
<FromGitter> <asterite> Then there's all the possible data races
<RX14> yeah
<FromGitter> <asterite> My guess is that it can take a couple of months, maybe more, to get it right
<RX14> I sort of admire nodejs for just saying "no"
<FromGitter> <bararchy> @asterite Thanks for the input
<RX14> we have the tools to make concurrency safe (channels)
<RX14> but not sure everyone will end up using them
<FromGitter> <bararchy> RX14, just adding working Threads would be a big deal of work?
<FromGitter> <asterite> Though when I was at Manas it was almost working, but still a bit slow, so probably now it's less time to get there
<Groogy> Alright so with Crystal I would have a case like this that I would want to multithread.
<Groogy> nvm the race condition in there
<RX14> @asterite merging something slow is fine to me though
<FromGitter> <asterite> For multithreading, Thread was already working
<RX14> yes
<FromGitter> <asterite> But only created and managed by the scheduler
<FromGitter> <asterite> For me too. @waj didn't want to, though
<RX14> I think at the least there should be a way to pin a fiber to a thread and take it out of the threadpool eventually
<FromGitter> <asterite> He wanted a perfect performance
<RX14> well
<FromGitter> <asterite> Maybe he's right
<FromGitter> <bararchy> Nha, a slower solution is better then no solution
<RX14> I don't think perfectionism is a good thing
<FromGitter> <asterite> Well, slower meant a slower http server
<Groogy> I agree with bararchy
<FromGitter> <bararchy> as long as it's faster then single thread, there is a point
<RX14> well it depends on the situation ofc
<FromGitter> <asterite> So what's the point of that?
<Groogy> worked with a lot of people where "But that's not perfect" but we have a problem right now we have to solve
<RX14> but I think perfectionism has harmed crystal before
phase[m] has quit [Quit: idle on matrix for more than 30 days]
<RX14> @asterite the point is that not everyone is running HTTP
<RX14> and we continue to recommend people run HTTP servers using SO_REUSEPORT
<FromGitter> <asterite> I mean, multithreaded code was slower than single threaded
<FromGitter> <bararchy> Oh
<RX14> because SO_REUSEPORT is faster *even in go*
<FromGitter> <asterite> So what's the point of having it like that?
<Groogy> well slower still means that you can get "ready to switch"
<RX14> @asterite because HTTP server performance is a degenerate case
<RX14> where every request is a new fiber
<Groogy> it's harder to make code multithreaded after you've already "set it in stone"
<FromGitter> <asterite> The only reason is to not block the single thread with math operations
<RX14> @asterite itf it's slower thats a fantastic reason to turn it off by default
<FromGitter> <asterite> Yes, I personally wanted multithreaded even if slow so code can already be written with that in mind. Then it's just about optimizing stuff
<FromGitter> <asterite> Like Go does
<Groogy> 👍
<FromGitter> <bararchy> maybe it's something that can be requested
<RX14> I think we should merge the ability to create a new threadpool which you can spawn fibers in
<FromGitter> <asterite> Unfortunately, the feature wasn't finished. There were still some rough edges
<RX14> and then you use pool.spawn
<FromGitter> <bararchy> you said it wasn't that long of a streach to have
<RX14> and then eventually
<RX14> once it performs well
<FromGitter> <bararchy> as it was already working
<RX14> we make a global threadpool
<RX14> and make ::spawn call GlobalPoo.spawn
<RX14> Pool*
<RX14> ...
<Groogy> I have a question on a more highlevel note though, will there be an interface like this? https://gist.github.com/Groogy/51c75a2164c6b733eeab19d88d33f600
<RX14> and then people who need math performance can get it now
<FromGitter> <asterite> I think fork was missing, probably some other things
<Groogy> parallell for, chunk up the data and process it?
<RX14> people who want to experiment don't have to use a branch
<Groogy> nvm the race condition
weston_[m] has quit [Quit: idle on matrix for more than 30 days]
<RX14> and we have a solid pathway into getting it being the default
<RX14> and people can experiment with thread safety in their libraries
<FromGitter> <bararchy> ^ 100% agree
<FromGitter> <bararchy> can we get this fork\repo somehow?
<FromGitter> <bararchy> can we ping @waj for it maybe?
<FromGitter> <asterite> But also, class vars and constants are initialized lazily, so a lock is missing there too. Or, well, synchronization. Paralelismos was still missing a bunch of things
<FromGitter> <asterite> It's in the thread something branch
<FromGitter> <bew> thread-support iirc
<FromGitter> <asterite> Yes
<RX14> not any more
<RX14> there's single-msqueue
<RX14> I asked manas to consider making parallelism not a single monolitic feature
<RX14> but a series of PRs
<RX14> like we're doing with windows
<RX14> but that was a while ago and they havent had time to work on it at all since then
<RX14> so i'll make sure to remind them once they get time to work on paralleism again
<Groogy> the hope is to have a similar API for this as Go or?
<crystal-gh> [crystal] bararchy opened pull request #5549: Thread support (master...thread-support) https://git.io/vNTae
<FromGitter> <asterite> That's kind of impossible, to do it little by little
<RX14> @asterite I don't believe that
<FromGitter> <asterite> Try :)
<RX14> @bararchy that's not helpful
<FromGitter> <bararchy> Oh ..
<FromGitter> <bararchy> yeha
<FromGitter> <bararchy> didn't work as I thought
<FromGitter> <bararchy> I'll close it
<FromGitter> <bararchy> sorrt
<FromGitter> <bararchy> I'll open an issue?
<crystal-gh> [crystal] bararchy closed pull request #5549: Thread support (master...thread-support) https://git.io/vNTae
<RX14> @asterite you can merge in first the ability to use Thread.new
<RX14> then merge in locking around constants in the compiler
<RX14> and then merge in a scheduler
<RX14> and then merge in optimizations
<RX14> and then merge in making it the default
<RX14> it's not going to be tens of PRs like windows
<RX14> but it can be more than one
watzon has quit [Quit: idle on matrix for more than 30 days]
<Groogy> I honestly don't understand Go concurrency/parallelism :/
<Groogy> I'm to set in old ways
<RX14> well
<RX14> Go's concurrency and parallelism is what we're aiming for
<Vexatos> I have never messed with go
<FromGitter> <asterite> RX14, well, just the first point is that whole branch, and it's unfinished, so...
<Vexatos> Is there anything special about its parallelism
<RX14> Groogy, it's just threads except implemented in userspace so they're really fast
<RX14> @asterite not really?
<Groogy> Yeah I know I just don't understand the API
<RX14> that branch is definitely a scheduler
<Vexatos> hm
<Groogy> I am too used to like more tangible things like Intel Blocks etc.
<RX14> Groogy, spawn is Thread.new
<RX14> channels are just queues
<Groogy> TBB
<RX14> what's difficult?
<RX14> thread safe queues*
<FromGitter> <asterite> A scheduler with multiple threads
<Groogy> well I am reading the Go code someone wrote
<Groogy> and I don't see anywhere where it actually spawns the thread
<RX14> it's the go keyword
<RX14> go function() runs function in a new green thread
<Groogy> they are waiting on IO and it just continues the loop with another function call?
<FromGitter> <asterite> go spawns a fiber
<Groogy> oooh
<RX14> Groogy, yeah go == spawn
<FromGitter> <asterite> And go's scheduler runs that in one of multiple threads
<Groogy> and one thread locked to one core or something?
<FromGitter> <asterite> Even does load balancing in case one thread is stuck in on all fibers, and such
<RX14> Groogy, nope
<FromGitter> <asterite> So you just worry about go, never threads and scheduling
<FromGitter> <asterite> It's super simple to the user, just one keyword
<RX14> so we should just exactly copy what go does
<RX14> lol
<FromGitter> <asterite> Of course then you have channels, locks data races, etc :)
<Groogy> Hmm... how would it distribute work over threads? I.e we have 5000 tasks to do, we know the individual speed of each task is gonna take (real life case)
<Groogy> can we hint to the scheduler on how to put the workforce together?
<Groogy> we had to do this for our AI
dtcristo1 has quit [Quit: idle on matrix for more than 30 days]
<FromGitter> <asterite> No hints. Go tries it best to figure that out for you, at runtime
<Groogy> but then you run into the problem we had
<Groogy> we were handing out the scheduling to TBB
sija[m] has quit [Quit: idle on matrix for more than 30 days]
<Groogy> what I am worried about is this: https://forum.paradoxplaza.com/forum/index.php?attachments/thread_utilisation_before_marks-png.318924/
<Groogy> since we know measure ourselves how long a specific AI agent is going to take we get a way better utilization of our threads: https://forum.paradoxplaza.com/forum/index.php?attachments/thread_utilisation_after-png.318925/
<RX14> Groogy, in go's scheduler when a fiber blocks (either a syscall or a channel or anything) it gives up the thread it's running on to the scheduler
<Groogy> green mark is when a thread starts, red is when it stops
<Groogy> yeah but that doesn't happen in games :P
<Groogy> this was a parallel_for so we were just trying to process a lot of data over as short period as possible
<FromGitter> <bararchy> RX14 should we open an issue "coordinate threading " ?
<RX14> but what exactly was the problem
<RX14> @bararchy i don't think so
<FromGitter> <bararchy> Having an active issue might bring more life no?
<Groogy> So let's say we have 4 threads. Each thread gets a chunk of AI agents to process.
<Groogy> that chunking is done by tbb::parallel_for
<Groogy> either way those agents take variable amount of time, but since the scheduler doesn't know typically that "FRance might need more time than Hamburg" to process stuff
<Groogy> it just spreads them evenly out.
<Groogy> The difference we did is to make things aware of how heavy an agent is going to be to go through based on previous tick so that in the next one they get spread out better
<Yxhuvud> <3 that example.
<Groogy> when we didn't do that, France and Hamburg would be put on two different threads, making Hamburg wait for FRance to finish before the threads are done.
<Groogy> now France gets Hamburg on its thread, but where Hamburg was before you get maybe Austria
<Groogy> (super simplified and it's A LOT more agents than just three of course...)
<FromGitter> <asterite> As far as I know, go's scheduler is mostly thought for servers, not games. Crystal will probably be the same. Otherwise, we need to go back to non-blocked by default, user threads, mutexes, etc. It was like that in the beginning.
<RX14> Groogy, so you need to binpack based on estimated times
<RX14> into threads
<Yxhuvud> In your case I'd sort the agents on previous cost order, and then process them expensive first
<Groogy> that's why I am wondering if I can hint somehow "I expect this to take 10 ms"
<FromGitter> <asterite> I mean, if you want to have full control of thinngs, like you can in Rust
<Groogy> Yxhuvud we already got it fixed, I am wondering for Crystal
<RX14> Groogy, in that case you'd probably spawn n fibers and schedule tasks manually onto those n fibers as if they were threads
<RX14> and because those fibers are busy they get threads
<Groogy> yeah probably
<Groogy> but I would still have to manually schedule things in a way right? :/
<RX14> yep
<Groogy> oh well then all I really need is just Thread.new xD
<Groogy> and tools to deal with threads
<RX14> @asterite regarding meta attributes I think the compiler should just accept any attribute you make up silently and then provide macro methods for iterating it
<RX14> so you just do @[JSON(foo, bar, baz: "bing", *whatever)]
<RX14> no pre-definition
<RX14> it just accepts it and stores it
<RX14> and then you use JSON.mapping
<RX14> it looks as `self`
<RX14> and can find the annotations
<RX14> in macros
<RX14> simple and flexible
<Groogy> you guys adding attributes?
<RX14> it's on the table
<crystal-gh> [crystal] RX14 pushed 1 new commit to master: https://git.io/vNTVl
<crystal-gh> crystal/master 161c17a Noriyo Akita: Fix typo mutli to multi (#5547)...
<RX14> i'm a bit iffy about it personally
<Groogy> well it would mean my hacks around in macros become obsolete
<RX14> seems too easy to get lost in metadata
<Groogy> how you mean?
<RX14> have you seen annotation-heavy java code?
<Groogy> oh right... yeah
<Groogy> yeah no I agree with there, I just like being able to define a nice DSL for like... aux stuff?
<Groogy> Not like how Java does things, thuogh I also don't use the JSON mapping stuff
<Groogy> though I also require you to mixin modules for my stuff to work
<FromGitter> <bararchy> So, are we going to have Thread.new or what? ;) ⏎ RX14 I remmber you said it was 10 min work
<RX14> if I said it was 10 minutes work it was hyperbole
<FromGitter> <bararchy> i was kidding :)
<Groogy> Programmer: IT's 5 minutes of work
<RX14> and "are we going to have Thread.new" isn't really my decision
<Groogy> Translation: It's about a days worth of work
<RX14> no
<RX14> it's 10 minutes of work and an hour to get it done :)
<FromGitter> <bararchy> RX14, then whos?
<Groogy> 10 minutes of work is "Will never get finished"
<RX14> that's what 5 minutes means
<RX14> @bararchy ours
<RX14> i don't make decisions
<RX14> i provide my opinion and we make decisions as a team
<RX14> my opions don't represent the core team, or what will actually get done
<RX14> they represent me
<RX14> we all learn from each other
<FromGitter> <bararchy> So, what is the decision of the Core Team?
<FromGitter> <bararchy> did you asked them in your private chat thingy?
<RX14> dunno havent asked them
<RX14> or made an issue about it
<FromGitter> <bararchy> I see
<RX14> or discussed it with them at all
<RX14> i don't have telepathy :)
<FromGitter> <bararchy> lol
<Groogy> sounds like a you problem RX14
cremes has joined #crystal-lang
<Groogy> get telepathy
<RX14> :(
<FromGitter> <bararchy> I see, sorry for being annoying I just really would love that in
<Groogy> I'm fine for now, I have tons of stuff to do
<Groogy> but I would love start messing around with it
<RX14> nah you're not being annoying
<Groogy> to try and help development of crystal
<Groogy> i.e I can be alpha tester and stress test the api ;D
<RX14> there's too much to do and paralleism isn't particularly important to me @bararchy
<RX14> i'd rather work on one focus at once
<RX14> i.e. windows
<Groogy> Yeah Windows is more important if you ask me
<Groogy> will also give the language a way bigger exposure
<FromGitter> <bajro17> I would like to start with crystal but I read negative comments like its so slow develop
<FromGitter> <bararchy> @bajro17 ? slow to develop in Crystal?
<Groogy> huh?
<Groogy> you mean to write code, or you mean the devs are slow?
<FromGitter> <bajro17> no language by self dont have so much improvements
<FromGitter> <bajro17> but I check github repo they update almost every day few stuff
<Groogy> Eh guess depends on what you compare to? It's way faster than C++ 😂
<FromGitter> <bararchy> RX14, can you give me pointers that would help me add Thread.new ?
<RX14> Not reallp
<Groogy> @bajro17 either way the language is being developed by quite a small team with not a lot of monetary backing. So if you compare to I guess Rust or Go I guess yeah it is probably quite slow
<RX14> Not really*
<Groogy> but meh, everything is there for me to work so and I add what I need myself
<FromGitter> <bajro17> can you tell me is it safe use it in production for website?
<Groogy> Eeeeh...... not my area.... I know some use it? But donno how safe for use it is
<RX14> I'd start by looking at the threading branch and seeing how that's done
<Groogy> IF you mean stability etc, the application doesn't crash then yeah it's stable. But I don't think the API not getting overhaul changes it isn't "stable"?
<FromGitter> <bajro17> Thank you so much @Groogy I will give it chance I really like syntax and simplicity
<Groogy> yeah, this place is great to get help if you get stuck. It's quite a different language
<Groogy> @RX14 how much is the stdlib gonna change in its public interface for Windows support?
<Groogy> i.e will all of my stuff break? :D
<Groogy> 🦔
<RX14> Unlikely
<RX14> Not much will change
<Groogy> nice
<RX14> I'd like to remove some unixisms from the stdlib but that's separate from windows support
<RX14> And will probably just be renamed
<RX14> Renames*
<Groogy> just curious if Boleite will work out of the box on Win
<RX14> Idk
<RX14> It won't be more than a typical crystal update
<RX14> Which breaks one or two things usually
<RX14> Well I hope
<Groogy> We'll see, will also have to see if linking with all the libraries still work as well
<travis-ci> crystal-lang/crystal#161c17a (master - Fix typo mutli to multi (#5547)): The build passed. https://travis-ci.org/crystal-lang/crystal/builds/325769101
<DeBot> https://github.com/crystal-lang/crystal/pull/5547 (Fix typo mutli to multi)
<Groogy> hmm stuff changed with 1.24, where is Time::Span::TicksPerSecond defined?
<Groogy> or am I supposed to use named arguments for that now?
<Groogy> huh I get a compile error in the #*
<Groogy> I guess even though it says : Number, it only handles ints :/
ashirase has quit [Ping timeout: 248 seconds]
ashirase has joined #crystal-lang
<FromGitter> <straight-shoota> yeah, that's an apparent error
<FromGitter> <codenoid> no @relyks
<FromGitter> <straight-shoota> `Int64 * float` returns float
<Groogy> yeah, I'll make an issue on it
<Groogy> oh there is already one
<FromGitter> <straight-shoota> then give it a bump ^^
<Groogy> on the PR or the issue?
<FromGitter> <straight-shoota> PR
<FromGitter> <straight-shoota> It should get a review
<Groogy> also hmm... why is my yml code giving me nil for 4 and 5 but 0 for 0? :S
<Groogy> hmm seems like my serializer can't read numbers anymore, weird
<Groogy> oh it got changed to be Int64 alright
<Groogy> something with font rendering is borked in 0.24 :(
<Groogy> is there a 0.24 changelist?
<FromGitter> <asterite> RX14 about meta, you are probably right. It's prone to typos, but I guess you'd test (or use) stuff with those attributes. I'm thinking we could also allow dot or `::` in the names, like @[JSON.Serializable], @[JSON.Attribute] and so on
<RX14> hmm
<RX14> not sure about the .
<RX14> @[JSON::Serializable(foo)] looks way better imo
<RX14> but I like it without
<FromGitter> <asterite> Well then, @[JSON::Serializable] then
<FromGitter> <asterite> I'm thinking, you could put that into a class
<RX14> @[JSON(foo)] I think
<FromGitter> <asterite> and it means "serialize all instance vars by default"
<RX14> well
<RX14> idk
<FromGitter> <asterite> then you can control individual instance vars with attributes
<RX14> I kinda like the idea of making JSON.mapping continue to exist
<FromGitter> <asterite> in JSON::Serializable you could say "serialize all by default" or "serialize none by default"
<RX14> except that it takes no args
<FromGitter> <asterite> I think JSON.mapping is ugly
<RX14> and works from attributes on the current class
<FromGitter> <asterite> for record Point, x : Int32, y : Int32 you have to repeat the info
<FromGitter> <asterite> here it would just be @[JSON::Serializable] on top of that
<FromGitter> <asterite> same if you want it to serialize to yaml
<RX14> class Foo; @[JSON("bar")]; property bar : String; JSON.mapping; end
<RX14> looks clean to me
<RX14> @asterite yeah actually record is a fair point
<RX14> yeah we should just put @[JSON::Serializable] on the class
<RX14> but then we need a macro which iterates all classes
<RX14> JSON.mapping at least you *know* exactly which classes you're scanning for attributes
<FromGitter> <asterite> my idea was that you could include some code in the attribute
<FromGitter> <asterite> and it gets executed at some point
<FromGitter> <asterite> I think I mentioned it in the proposal
<RX14> I don't like it actully
<FromGitter> <asterite> just brainstorming :)
<FromGitter> <asterite> gotta go
<RX14> i think that's too complex
<RX14> or at least make it simple:
<Groogy> huh..... in my text rendering now I only get the unicode box for unknown I think
<RX14> {% register_attribute_callback(JSON) do ... %}
<Groogy> did something change in regards to that?
<RX14> Groogy, ??
<Groogy> that's the font texture
<Groogy> when I'm loading the glyph, at least I am getting '5'
<Groogy> and so on
<Groogy> oooh... code.hash gives me a uint64 now?
<Groogy> ah there we go
<Groogy> #hash used to give the same thing as #ord does. Donno why I used #hash instead
<crystal-gh> [crystal] RX14 closed pull request #5543: Compiler: remove extra `shell` argument when executing macro run (master...bug/macro-run-extra-shell) https://git.io/vNU9N
alex`` has quit [Quit: WeeChat 1.9]
alex`` has joined #crystal-lang
cremes has quit [Quit: cremes]
rohitpaulk has quit [Ping timeout: 260 seconds]
<travis-ci> crystal-lang/crystal#525ea49 (master - Compiler: remove extra `shell` argument when executing macro run (#5543)): The build passed. https://travis-ci.org/crystal-lang/crystal/builds/325785507
<DeBot> https://github.com/crystal-lang/crystal/pull/5543 (Compiler: remove extra `shell` argument when executing macro run)
<FromGitter> <bew> @asterite what's the point of having an array of Node in YAML::Nodes::Document if it is documented that there can be at most 1 node in a document? https://github.com/crystal-lang/crystal/blob/master/src/yaml/nodes/nodes.cr#L39
<FromGitter> <codenoid> hi Groogy, long time no see
<FromGitter> <bajro17> Groogy is that opengl?
eperez has joined #crystal-lang
<FromGitter> <straight-shoota> Why does the compiler need libgc on linux when I'm cross-compiling to windows?
<FromGitter> <straight-shoota> ```code paste, see link``` ⏎ ⏎ using feature/windows-spec branch from @RX14 [https://gitter.im/crystal-lang/crystal?at=5a50e8e629ec6ac311c720b8]
<FromGitter> <bew> the use of `ld` make me think that you're trying to link on linux, instead of windows
<FromGitter> <straight-shoota> I'm not. The compiler command is `bin/crystal build --progress --cross-compile --target x86_64-unknown-windows-msvc spec/windows_spec.cr`
faustinoaq has joined #crystal-lang
<FromGitter> <bew> works for me https://i.imgur.com/Rm0af2l.png
rohitpaulk has joined #crystal-lang
<FromGitter> <bew> I'm on linux though, not on wsl
<FromGitter> <bew> but it should not link by itself
<FromGitter> <bew> but your error is weird, you're doing a macro run?
<FromGitter> <bew> it looks like it's trying to compile a macro run program
<FromGitter> <bew> do you have a `{{ run("file") }}` somewhere? @straight-shoota
<FromGitter> <codenoid> hi, what do you thing, i want make, crystal build in root of project, then the crystal will build from `src/folderprojectname.cr`
<FromGitter> <bew> shards build does sth like this iirc
<FromGitter> <straight-shoota> @bew it seems to be an issue with the self-built compiler in version `0.24.1+68 [6128a6f49]`
<FromGitter> <straight-shoota> with plain 0.24.1 the same file compiles and prints the linker command
<FromGitter> <bew> ok, good
cremes has joined #crystal-lang
<RX14> @straight-shoota i'm using built compiler and it's fine?
<RX14> somehow, you're not actually calling the compiler with --cross-compile methinks
cremes has quit [Quit: cremes]
rohitpaulk has quit [Ping timeout: 240 seconds]
cremes has joined #crystal-lang
<Groogy> @codenoid Hi
<Groogy> @bajro17 yes it is
ua has joined #crystal-lang
ua_ has quit [Ping timeout: 268 seconds]
dragonkh has joined #crystal-lang
<FromGitter> <Svenskunganka> Is there a Tar module for Crystal? I noticed Asterite worked on implementing it in the stdlib in the feature/tar (https://github.com/crystal-lang/crystal/tree/feature/tar) branch, but not sure what its current status is
rohitpaulk has joined #crystal-lang
dragonkh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
dragonkh has joined #crystal-lang
<dragonkh> hi
<dragonkh> I'm a bit confused with some type stuff
<dragonkh> my method returns a union type of a few types - and I know it contains a particular type - but I can't call a method on it - as it doesn't know which of the types it is until I use a case clause or an if statement with .is_a?
<oprypin> Svenskunganka, perhaps there isn't. https://github.com/crystal-lang/crystal/issues/5215#issuecomment-340637472 - maybe you should pick up that code into a shard
<dragonkh> so I guess if I want to get to the actual type I have to use case, or if .is_a?(Type)
<oprypin> Svenskunganka, u can adapt commit history keeping authorship
<dragonkh> but the crystal specs seems to also be confused about it: https://gist.github.com/kingsleyh/7170d5de30671047fbce14498a1e488b
<dragonkh> any help appreciated thanks
<oprypin> dragonkh, why would you call it confused? it literally says on line 3 that it is of one type, then on the next line you assert that it is in fact a different type. why are you surprised that it doesn't hold?
<dragonkh> result should be a DB::Success(RethinkDB::QueryResult)
<oprypin> but it isnt, so now what?
<dragonkh> since result.value is a RethinkDB::QueryResult - I don't see why it should not work?
<FromGitter> <bew> oprypin line 3 it checks `result.value` on line 4 it checks `result`
<oprypin> sorry then
<oprypin> ok so the helpful message is on the very right
<oprypin> `expected a DB::Success(Iterator::Stop | RethinkDB::QueryResult)) to be a DB::Success(RethinkDB::QueryResult)`
<dragonkh> ah ok - so I have to give it all the items from the union type
<oprypin> indeed the type system does catch the relationship in that way
<oprypin> Iterator::Stop really must not be part of this
<oprypin> dragonkh, yes, that would be a working workaround, but ^
<dragonkh> I don't know why Iterator::Stop is there
<dragonkh> thats just what the type system reports
<oprypin> dragonkh, well that's what the DB wrapper code actually does. i would suspect it shouldn't do that
<dragonkh> ok maybe its a problem in the RethinkDB library
<FromGitter> <bew> not a problem I think
<FromGitter> <bew> I suppose that when using findByEmail it can gives you multiple results
<dragonkh> it gives back either a Cursor or an Iterator::Stop it seems
<dragonkh> I guess when nothing is found - I get Iterator::Stop
<FromGitter> <bew> so it returns you an object that can be iterated to get the different results
<dragonkh> Cursor is enumerable I think yes
<dragonkh> it contains a list of QueryResult
<FromGitter> <bew> if you just want the first result you might be able to do `result.first` or sth like that
<dragonkh> yep
<FromGitter> <bew> which rethinkdb driver are you using?
<dragonkh> he's moving to this one: https://github.com/lbguilherme/rethinkdb-lite
<FromGitter> <bew> did you write `findByEmail` or is it from the shard?
<dragonkh> I wrote that
<FromGitter> <bew> ok, what's the line doing the request?
<dragonkh> r.table("users").filter{|user| user["email"] == email
<dragonkh> but I wrap it in a DB::Success or DB::Failure
<dragonkh> when RethinkDB::QueryResult, RethinkDB::Cursor, Iterator::Stop
<dragonkh> yield DB::Success.new(query)
<dragonkh> else I yield DB::Failure.new(query.to_s)
<FromGitter> <bew> why are you dealing with `Iterator::Stop` ? you're returning an iterator?
<FromGitter> <bew> or a bunch of values?
<dragonkh> this thing: r.table("users").filter{|user| user["email"] == email
<FromGitter> <Svenskunganka> @oprypin Ah I see. I'll take a look at continuing his work as a shard, although my code will probably not even come close to the same quality as asterite's 😅
<dragonkh> returns either Iterator:Stop or RethinkDB::Cursor
<FromGitter> <bew> why do you think it works like that?
<FromGitter> <bew> dragonkh: like: why sometime it returns a cursor and why an Iterator::Stop?
<dragonkh> aaah
<dragonkh> you are right
<dragonkh> I did this: r.table("users").filter{|user| user["email"] == "nothing"}.run(conn).next
<dragonkh> which returns: (Iterator::Stop | RethinkDB::QueryResult)
<dragonkh> if I take off the .next off the end - I get the Cursor
<FromGitter> <bew> there it is ;)
<dragonkh> I should just return the cursor and get the first item from the cursor
<dragonkh> great thanks :)
<FromGitter> <bew> yw!
<dragonkh> so one last question - if I have something that returns say: String | Cursor | SomethingElse
<FromGitter> <bew> also in the gist you posted, the value can be String, is it intented?
<dragonkh> I'll check about String
<dragonkh> in the return - what do people do to get the actual item from the union? do they use if or case ?
<dragonkh> like a = String | Cursor | Something - they would do if(a.is_a?(Cursor) a.first
<dragonkh> because you can't just do a.first - because it doesn't work out which one it is?
<FromGitter> <bew> it depends
<dragonkh> ok
<FromGitter> <bew> I'd say if you have different types, and need to do sth different for each possible types, I use case
<FromGitter> <bew> if you just need to do sth for 1 or 2 type, just use is_a
<dragonkh> thanks :)
dragonkh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<FromGitter> <bajro17> do you have example crud with crystal and rethinkdb?
<FromGitter> <bajro17> I find on official repo :)
Ven`` has joined #crystal-lang
<crystal-gh> [crystal] RX14 pushed 1 new commit to master: https://git.io/vNT5m
<crystal-gh> crystal/master 3cb4b94 Ary Borenszweig: CLI: remove deps command (#5544)
bazaar has quit [Quit: leaving]
dragonkh has joined #crystal-lang
<FromGitter> <straight-shoota> @RX14 but how? was there anything significant changed between 0.24.1 and 6128a6f49 ?
<RX14> I don't believe the problem is what it seems
<RX14> you must be providing different options to the two compilers
<FromGitter> <straight-shoota> no, exactly the same
<FromGitter> <straight-shoota> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5a5116b203838b2f2a7b38e1]
<FromGitter> <straight-shoota> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5a5116c8ba39a53f1ae39c88]
illyohs has joined #crystal-lang
<FromGitter> <straight-shoota> the only thing I did inbetween was `mv .build/crystal .build/_crystal`
<FromGitter> <straight-shoota> somehow a the first line breaks got lost in c&p
woodruffw has quit [Ping timeout: 248 seconds]
<travis-ci> crystal-lang/crystal#3cb4b94 (master - CLI: remove deps command (#5544)): The build passed. https://travis-ci.org/crystal-lang/crystal/builds/325843213
<DeBot> https://github.com/crystal-lang/crystal/pull/5544 (CLI: remove deps command)
woodruffw has joined #crystal-lang
woodruffw has quit [Changing host]
woodruffw has joined #crystal-lang
Ven`` has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<RX14> "_wstat does not work with Windows Vista symbolic links. In these cases, _wstat will always report a file size of 0. _stat does work correctly with symbolic links. "
<RX14> whyyyy
<oprypin> it's not like anyone uses symbolic links on windows
<oprypin> i think Python doesnt support them
<oprypin> RX14, so maybe don't bother with it, at least for now
<FromGitter> <straight-shoota> so you're porting File? =)
rohitpaulk has quit [Ping timeout: 268 seconds]
dragonkh has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Ven`` has joined #crystal-lang
dragonkh has joined #crystal-lang
dragonkh has quit [Client Quit]
dragonkh has joined #crystal-lang
dragonkh has quit [Client Quit]
snsei has joined #crystal-lang
rohitpaulk has joined #crystal-lang
Ven`` has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Ven`` has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 265 seconds]
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
snsei has quit [Remote host closed the connection]
snsei has joined #crystal-lang
snsei_ has joined #crystal-lang
eperez has quit [Ping timeout: 248 seconds]
snsei has quit [Ping timeout: 265 seconds]
Ven`` has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Ven`` has joined #crystal-lang
eperez has joined #crystal-lang
Ven`` has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
Ven`` has joined #crystal-lang
dragonkh has joined #crystal-lang
<dragonkh> I'm having iterator issues - I think it's a bug in the rethinkdb library I'm using - I can see a Cursor that has stuff in it - but when I do my_cursor.to_a - I get an empty array back. Cursor includes Iterator and from what I understand I should be able to do .to_a on an Iterator and get the result out - am I sounding reasonable? does this sound like a bug? https://gist.github.com/kingsleyh/2cbca1f5ee6cfd678045f6e
<dragonkh> 7343de046
<oprypin> dragonkh, are you by any chance using icr?
<dragonkh> icr?
relyks has joined #crystal-lang
<oprypin> dragonkh, then you're probably not. good
<dragonkh> oh!
<dragonkh> I think I might have figured it out
<dragonkh> I think I might have accidentally drained the iterator
<dragonkh> by printing it out in the code before it gets returned
<oprypin> that could do it
<dragonkh> if I want to look inside I have to rewind it?
<oprypin> dragonkh, just turn it to array and then look....
<dragonkh> I mean after turning it into an array - I should rewind after?
<dragonkh> oh I have to implement rewind
<oprypin> dragonkh, why are YOU implementing rewind?
<oprypin> are you editing a database driver?
<dragonkh> when I try to use rewind it says: abstract `def Iterator(T)#rewind()` must be implemented by RethinkDB::Cursor
<dragonkh> I'm trying to use the driver - but looks like it's missing some stuff - so I will edit it
<oprypin> you realize that rewinding would mean re-executing the query
<oprypin> and it's not good form to support that
<dragonkh> if I use cursor.to_a - it drains the iterator
<oprypin> as it should
<dragonkh> but I want to check if there is anything in the cursor earlier in the code
<dragonkh> this check is draining it - but I do still want to keep the check
<dragonkh> if rewinding is not a good idea - any suggestions?
<dragonkh> is there any kind of peek ?
<oprypin> dragonkh, no, and you should live without it just fine
<dragonkh> ok - so perhaps I should not check if it's empty until the point I actually use it
<oprypin> perhaps
<oprypin> easy way out, if it's not too costly: turn it to array right away and forget about it
<oprypin> forget about cursor, that is
<dragonkh> hmm maybe
<dragonkh> its nice having a lazy iterator for perf reasons - but in this case it might not be a big issue
<oprypin> meanwhile, https://crystal-lang.github.io/crystal-db/api/0.5.0/DB/ResultSet.html is not even an iterator -_-
snsei_ has quit [Remote host closed the connection]
snsei has joined #crystal-lang
Ven`` has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
snsei has quit [Ping timeout: 265 seconds]
alex`` has quit [Ping timeout: 255 seconds]
snsei has joined #crystal-lang
jnyw has joined #crystal-lang
<crystal-gh> [crystal] lachlan opened pull request #5551: Add JSON support to UUID (master...uuid-json) https://git.io/vNkLO
snsei has quit [Remote host closed the connection]
rohitpaulk has joined #crystal-lang
rohitpaulk has quit [Ping timeout: 265 seconds]
<relyks> what does this mean? instantiating 'Array(String | Nil)#each()'
<oprypin> relyks, you're looking at the context of the error, not the actual error
snsei has joined #crystal-lang
<oprypin> it says, you are calling the `each` method on an object of type `Array(String | Nil)`
<oprypin> now if you'd paste the whole error (https://bpaste.net/) and maybe even the code (https://carc.in/), maybe we could get somewhere with this
<relyks> oprypin: i just pasted it to carc.in, but it doesn't show that error. it just shows openssl errors
<relyks> I think the problem is that the array is Array(String | Nil) but I just want it to be Array(String)
snsei has quit [Ping timeout: 240 seconds]
<relyks> btw this is the first program I'm writing in crystal ever. wanted to try to make a web crawler
<oprypin> relyks, welp then "now if you'd paste the whole error (https://bpaste.net/)" still applies
<relyks> oprypin: sorry, let me do that :D
<oprypin> relyks, i think regex match .to_a returns Array(String | Nil)
<oprypin> i shouldn't be guessing though
<oprypin> just wanna see the error
<oprypin> relyks, aha see, the last part is the error
<oprypin> no overload matches 'Array(String)#push' with type (String | Nil)
<oprypin> the things before that just tell you how it got to that point
<relyks> ohhh
<relyks> I see now
<oprypin> puts typeof(urls) can help
<oprypin> also if you don't do the chaining of methods, the code is much more debuggable, and the erorrs are much clearer
<relyks> so method chaining is bad? :D
<relyks> oprypin: but yeah, so much for the help :) I got it to build now
<oprypin> i'm not talking for everyone but i think it's bad, especially when you start a new line with a dot
<Yxhuvud> you'd have an anearysm if you saw my solutions to advent of code then :P
<oprypin> it's very tempting, i use it sometimes even if i say it's bad lol
<relyks> I like doing it, because it's like a pipeline
<relyks> do all the time in ruby :D
<relyks> and hey for debugging purposes, isn't that what tap is for? :)
<relyks> haha
<relyks> actually if I add a .compact to the chain it also works
<FromGitter> <bew> I'm late to the party, but what's `tap` having to do with debugging?
<relyks> you can put tap in a method chain and puts what the value is at that point
<relyks> in the middle of the chain
<FromGitter> <bew> oh didn't know this usecase
<FromGitter> <bew> nice trick