jhass changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.5.8 | Paste > 3 lines of text to https://gist.github.com | GH: https://github.com/manastech/crystal - Docs: http://crystal-lang.org/docs/ - API: http://crystal-lang.org/api/ - Logs: http://irclog.whitequark.org/crystal-lang
waj has joined #crystal-lang
weskinner has quit [Quit: weskinner]
weskinner has joined #crystal-lang
weskinner has quit [Ping timeout: 264 seconds]
leafybasil has quit [Remote host closed the connection]
leafybasil has joined #crystal-lang
weskinner has joined #crystal-lang
weskinner has quit [Ping timeout: 265 seconds]
<zamith_> asterite: or waj: you should apply to this http://curry-on.org/
<zamith_> ;)
zamith_ has quit [Quit: Be back later ...]
<waj> sounds perfect :)
waj has quit [Quit: Leaving.]
weskinner has joined #crystal-lang
weskinner has quit [Ping timeout: 264 seconds]
waj has joined #crystal-lang
waj has quit [Quit: Leaving.]
waj has joined #crystal-lang
waj has quit [Quit: Leaving.]
crystal-gh has joined #crystal-lang
<crystal-gh> [crystal] asterite pushed 1 new commit to master: http://git.io/bVi2
<crystal-gh> crystal/master c415807 Ary Borenszweig: [Markdown] Parse horizontal rules
crystal-gh has left #crystal-lang [#crystal-lang]
travis-ci has joined #crystal-lang
<travis-ci> manastech/crystal#1929 (master - c415807 : Ary Borenszweig): The build passed.
travis-ci has left #crystal-lang [#crystal-lang]
weskinner has joined #crystal-lang
weskinner has quit [Ping timeout: 245 seconds]
bcardiff has joined #crystal-lang
bcardiff1 has joined #crystal-lang
bcardiff has quit [Ping timeout: 245 seconds]
waj has joined #crystal-lang
leafybasil has quit [Remote host closed the connection]
waj has quit [Quit: Leaving.]
leafybasil has joined #crystal-lang
tymat has quit [Ping timeout: 265 seconds]
waj has joined #crystal-lang
tymat has joined #crystal-lang
zamith__ has joined #crystal-lang
jhass has quit [*.net *.split]
jhass has joined #crystal-lang
waj has quit [Quit: Leaving.]
waj has joined #crystal-lang
bcardiff1 has quit [Quit: Leaving.]
waj has quit [Quit: Leaving.]
waj has joined #crystal-lang
waj has quit [Client Quit]
waj has joined #crystal-lang
bcardiff has joined #crystal-lang
asterite has joined #crystal-lang
waj1 has joined #crystal-lang
waj has quit [Ping timeout: 246 seconds]
bcardiff1 has joined #crystal-lang
waj1 has quit [Quit: Leaving.]
waj has joined #crystal-lang
bcardiff has quit [Ping timeout: 255 seconds]
<jhass> asterite: mmh, can I forward declare a C struct? lib A; struct B; end; ... struct B; a : Foo; end; end;
<asterite> I’m not sure. I think you can do it for enums, but for structs it should be doable (if not, open an issue)
<asterite> jhass: what do you think of http://curry-on.org/ ?
<asterite> do you think it would make sense for us to try to be there?
asterite_ has joined #crystal-lang
<jhass> I'm not sure, I always find it hard to decipher the blabla, but given the speaker set, I think you wouldn't be misplaced ;)
<jhass> I think Crystal is a very practical approach to a programming language while many new languages are fairly academical, so it might add a nice perspective
asterite has quit [Ping timeout: 244 seconds]
asterite_ is now known as asterite
<jhass> For a talk I'd mainly focus on motivation & history, not too much on the language actually
<asterite> Thanks for the feedback :)
<asterite> My main concern is that we are not dealing with, like, big-data or security, as they say there. Nor we are doing something academic. We are trying to make something useful, fun and efficient. On the other hand there’s Brendan Eich there :)
asterite has quit [Client Quit]
<jhass> big-data and security are just buzz words
<jhass> security since snowden ;)
<jhass> so that's what I called "blabla" ;)
<jhass> I'm sure you'll meet some nice people there and maybe take away an idea or two and after all that's what a conference like that is about
asterite has joined #crystal-lang
bcardiff has joined #crystal-lang
bcardiff1 has quit [Ping timeout: 264 seconds]
endou_ has joined #crystal-lang
endou has quit [Ping timeout: 256 seconds]
filer has quit [Quit: No Ping reply in 180 seconds.]
filer has joined #crystal-lang
Liothen has quit [Ping timeout: 245 seconds]
Liothen has joined #crystal-lang
asterite_ has joined #crystal-lang
asterite has quit [Ping timeout: 245 seconds]
asterite_ is now known as asterite
Liothen has quit [Ping timeout: 245 seconds]
Liothen has joined #crystal-lang
<asterite> jhass: do you have enums whose values come later?
<jhass> maybe
<asterite> I mean, something like: enum Bar; X = A; end; A = 1
<jhass> the generated binding for Gtk is already ~10kloc ^^
<asterite> :-o
<jhass> ah, no
<asterite> Does it compile fast?
<jhass> it does not compile yet :D
<asterite> How are you generating the bindings?
<jhass> with gobject-introspection
<jhass> I have functions using enums in their signature before they're defined apparently, mmh
<jhass> but nothing like you wrote there
<jhass> brb, shopping
asterite_ has joined #crystal-lang
asterite has quit [Ping timeout: 252 seconds]
asterite_ is now known as asterite
leafybasil has quit [Remote host closed the connection]
waj1 has joined #crystal-lang
bcardiff1 has joined #crystal-lang
waj has quit [Ping timeout: 256 seconds]
bcardiff has quit [Ping timeout: 245 seconds]
shama has joined #crystal-lang
zamith__ has quit [Ping timeout: 250 seconds]
<jhass> back
<asterite> jhass: Pushed. Let me know if that works for you :)
crystal-gh has joined #crystal-lang
<crystal-gh> [crystal] asterite pushed 4 new commits to master: http://git.io/b6Xd
<crystal-gh> crystal/master 908bcf9 Ary Borenszweig: Improved Call#to_s when there's &.
<crystal-gh> crystal/master 970933b Ary Borenszweig: Fixed a parser bug involving &. and do
<crystal-gh> crystal/master 1a289d3 Ary Borenszweig: Correct way to do BufferedIO#gets(delimiter : Char) (although slower)
crystal-gh has left #crystal-lang [#crystal-lang]
<jhass> <3
<asterite> Which one?
<jhass> using &.foo and passing a block literal
<jhass> I don't think we should allow that, it's unclear which one wins
<jhass> or would the do end block still bind to the .foo?
<asterite> The way I did it is that `do` will bind to foo, in that particular case
<jhass> mmh
<asterite> I’m not sure it’s correct, though, maybe I introduced an inconsistency
leafybasil has joined #crystal-lang
<asterite> I was trying to do this:
<asterite> [nil, [1, 2, 3]].each &.try &.each do |x|
<asterite> puts x
<asterite> end
<asterite> But that didn’t parse...
waj1 has quit [Quit: Leaving.]
<jhass> I think with { } it's understandable
waj has joined #crystal-lang
<asterite> I think that once you have &., a “do” block obviosuly can’t come, so a “do” must belong to the next call
<jhass> but do end, I'm used from Ruby it would bind to the outer each
travis-ci has joined #crystal-lang
travis-ci has left #crystal-lang [#crystal-lang]
<travis-ci> manastech/crystal#1930 (master - 20d56c0 : Ary Borenszweig): The build passed.
<asterite> Unless there’s a case I’m not seeing
<asterite> But it can’t bind to the outer each because you specified the block with &.
<asterite> and that always comes first
<asterite> Maybe this rule is ok because there’s no &. in Ruby, but I’m not sure :)
<jhass> yeah, I think semantically it's unambigous
<jhass> but I'm not sure it's clear what happens when reading the code
<asterite> And it’s clear if you have { .. .} ?
<jhass> yes, because that binds to the right-most call
<jhass> a matter of getting used to I guess
<jhass> since &. is a new language feature compared to Ruby
<asterite> I guess. I can’t think of an ambiguity here. I know “do” binds to the left-most call, but with &. that rule becomes void
<asterite> At least I was surprised when the code I pasted above didn’t compile
<asterite> For me it was kind of clear… But I admit it can become long and hard to understand
<jhass> yeah, I guess my point maybe is that with too many exceptions from the general rule it becomes harder to follow
<jhass> but we can leave it to the programmer I guess
<jhass> .each(&.try(&.each do end)) :P
<asterite> :)
bcardiff has joined #crystal-lang
bcardiff1 has quit [Ping timeout: 245 seconds]
<jhass> >> enum Foo; A; B; end; {Foo::A => "bar", Foo::B => "quux"
<DeBot> jhass: Syntax error in eval:3: unterminated hash literal
<jhass> er
<jhass> >> enum Foo; A; B; end; {Foo::A => "bar", Foo::B => "quux"}
<DeBot> jhass: Syntax error in eval:3: unterminated hash literal
<jhass> still ;)
<asterite> Weird
<asterite> Ah, dummy parser, it think Foo: means a symbol key
<asterite> Mmm… not sure
<jhass> asterite: forward declarations seem to work <3
<asterite> Yay!
<asterite> Good. We want C bindings to be as painless as possible
<asterite> We also added to_s to c structs and unions (for unions it’s just a dummy), so it’ll be easier to debug C things from now on
<jhass> yeah, the pain is in gobject really
<jhass> gives me enum names like nvokeSomething m(
<jhass> and actually misses tons of functions...
<jhass> and that is essential ones
<asterite> I don’t really know what gobject is :(
<jhass> it's basically an object orientation framework for C
<jhass> you can define objects, interfaces, methods, callbacks, signals and so on
<asterite> And why do you want to use that from crystal?
<jhass> I'm not saying I fully grasped it yet
<jhass> I don't, I want to use Gtk which uses it ;)
<asterite> Oh! :)
<jhass> so, gobject-introspection is a project that gives you an API that allows you to enumerate all the gobject stuff
<jhass> "give me all entities in this namespace, give me all methods for this object" etc
<jhass> but tbh I'm not sure I'll pursue it beyond the "hello world window" state
<jhass> so it probably stays a PoC
<crystal-gh> [crystal] asterite pushed 1 new commit to master: http://git.io/bivu
<crystal-gh> crystal/master ebee669 Ary Borenszweig: Fixed a parser bug where a hash literal of namespaced values couldn't be created ({Foo::A => 1, Foo::B => 2})
<jhass> wow, that was fast :D
<asterite> You can see that the fix was easy, my comment about the symbol-things was right… had a duplicated code but it wasn’t exactly duplicated :)
<asterite> I like to fix bugs soon :)
r20 has joined #crystal-lang
travis-ci has joined #crystal-lang
<travis-ci> manastech/crystal#1931 (master - ebee669 : Ary Borenszweig): The build was broken.
travis-ci has left #crystal-lang [#crystal-lang]
<jhass> I wish libunwind wouldn't cause so many reports by valgrind
<asterite> libgc doesn’t do its share too?
<jhass> right, it does
<jhass> probably even more actually
<asterite> You have a memory leak?
<jhass> nah, valgrind is nice for segfaults too
<asterite> Ah, didn’t know that
<jhass> ==12720== Process terminating with default action of signal 11 (SIGSEGV)
<jhass> ==12720== Access not within mapped region at address 0x1
<jhass> ==12720== at 0x942841A: g_option_context_parse (in /usr/lib/libglib-2.0.so.0.4200.1)
<jhass> ==12720== by 0x52DBE27: gtk_parse_args (in /usr/lib/libgtk-3.so.0.1400.8)
<jhass> ==12720== by 0x52DBE88: gtk_init_check (in /usr/lib/libgtk-3.so.0.1400.8)
<jhass> ==12720== by 0x52DBED8: gtk_init (in /usr/lib/libgtk-3.so.0.1400.8)
<jhass> ==12720== by 0x40112C: __crystal_main (in /home/jhass/projects/crystal-gobject/gtk_hello_world)
<jhass> ==12720== by 0x40189F: main (in /home/jhass/projects/crystal-gobject/gtk_hello_world)
<jhass> now how did I achieve that :D
<jhass> ARGC_UNSAFE and ARGV_UNSAFE are the raw things like they're passed to main() in a C program, right?
<asterite> Yes
<jhass> mmh, wait, it wants a pointer to argc? weird
<jhass> fun init = gtk_init(argc : Int32, argv : UInt8**) : Void
<jhass> that's kind of contradicting, no?
travis-ci has joined #crystal-lang
<travis-ci> manastech/crystal#1931 (master - ebee669 : Ary Borenszweig): The build was broken.
travis-ci has left #crystal-lang [#crystal-lang]
<asterite> Yeah, I wonder why it needs a pointer to those
<asterite> Then you have UInt8*** ?
<jhass> note that signature I pasted is generated with gobject-introspection
<jhass> meh
<asterite> Hehe, I was just there. So why it generates wrong bindings?
<jhass> looks like it really wants a pointer and I'm generating the signature wrongly
<jhass> because...
<jhass> TypeInfo is hell
<jhass> ah, it needs an additional * because it's direction is inout
<jhass> obviously!
<jhass> xD
<jhass> uh, I made a blank window!
<asterite> Awesome!!
<asterite> With a “hello world” title?
<jhass> yeah, I should set it to that instead of Window
<jhass> xD
<asterite> :)
<jhass> It closes but it doesn't quit the process because I didn't figure out callbacks yet xD
<jhass> meh, Github rejects pushes to gists with directories now :/
<asterite> Gist for the gtk window?
<jhass> gist for everything
<jhass> before they had the directory restriction in place you could abuse gist as small mini repos :D
<jhass> the window is just
<jhass> require "./lib_gtk"
<jhass> LibGtk.init pointerof(ARGC_UNSAFE), pointerof(ARGV_UNSAFE)
<jhass> window = LibGtk.window_new(LibGtk::WindowType::TOPLEVEL) as LibGtk::Window*
<jhass> LibGtk.window_set_title(window, "Hello World!")
<jhass> LibGtk.widget_show(window as LibGtk::Widget*)
<jhass> LibGtk.main
<jhass> for now
<jhass> no wrapper classes generated, yet
<asterite> Nice
bcardiff has quit [Quit: Leaving.]
travis-ci has joined #crystal-lang
<travis-ci> manastech/crystal#1931 (master - ebee669 : Ary Borenszweig): The build has errored.
travis-ci has left #crystal-lang [#crystal-lang]
travis-ci has joined #crystal-lang
<travis-ci> manastech/crystal#1931 (master - ebee669 : Ary Borenszweig): The build passed.
travis-ci has left #crystal-lang [#crystal-lang]
<waj> yeah! finally the build passed! :P
<asterite> It’s a funny story :)
<asterite> waj downloaded llvm, compiled it with a patch and uploaded it to amazon’s ec2
<asterite> but sometimes when I wanted to do a release I would generate flawed binaries, the ones that segfaulted on incorrect input
<asterite> but doing the same on waj’s machine worked fine
<waj> yup… the one that was meant to be patched months ago :(
<asterite> Well… it turned out waj actually uploaded an unpatched llvm version to amazon :-P
<jhass> :D
<asterite> The strange thing is, when we used that unpatched llvm in travis, the specs that were failing started to pass
<jhass> LLVM 3.6 is close I hear <3
<asterite> For that we have no explanation at all
<asterite> The worse thing is that the crashes are totally random
<asterite> But it’s good that we finally understand almost everything :)
<asterite> We should check if llvm 3.6 still has that bug or not. I think not, llvm 3.5.1 has it but the patch has been later merged
<jhass> it was branched mid January I think
<waj> yup, 3.6 has the patch
<jhass> silly question: how close are captured blocks to C functions? Could I get a pointer to them and pass it where some library expects a function pointer?
<asterite> It’s not a silly question at all :)
<asterite> Our function pointers are represented as a pair of pointers: one for the real function, another one for the closure data
<asterite> The closure data will be nil if the function is not a closure
<asterite> You can’t cast one of our function pointers to void* because they are not exaclty pointers, but you can do...
<asterite> >> ->{ 1 }.pointer
<DeBot> asterite: Pointer(Void)@80495B0
<asterite> And you can actually pass them to C just like that
<asterite> However, if you try to pass a closure, you will get a runtime exception saying “can’t pass closure to C”
<jhass> mmh
<asterite> And, if the compiler can detect that you are indeed passing a closure, it will give you an error (like, when you define the function literal right in the call)
<jhass> kay, it definitely should supported closures
<asterite> >> a = 1; ->{ a }.closure?
<DeBot> asterite: true
<asterite> >> ->{ 1 }.closure?
<DeBot> asterite: false
<jhass> mmh
<asterite> How it should support closures?
<jhass> well, ultimately the high level API should look like window.connect("quit") do Gtk.quit; end or so
<jhass> while that case doesn't require a closure
<jhass> think about button.connect("click") do self.some_method end
<asterite> I don’t know what the low-level api looks like
<jhass> I'm still figuring it out
<jhass> so I need to write some marshaller
<asterite> Yes, but in C apis you usually can pass a (void* data), so you can pass a function that has the closure and then invoke it
<jhass> but still no real idea how that looks lke
<asterite> Sorry, not exactly like that
<asterite> You can pass something you can use in user_data
<asterite> You can also try passing f.pointer and … mmm… there’s no way to get the closure data right now :(
<asterite> When I said “pass them to C just like that”, I mean that you don’t need to invoke “.pointer”, crystal will do that for you, but will first check that it’s not a closure (and raise in that case)
<jhass> ugh, the python thing for that is a whooping 1kloc of C https://github.com/GNOME/pygobject/blob/master/gi/pygtype.c
<asterite> What is all of that for?
<asterite> I hope in crystal it ends up being much shorter :
<asterite> :)
<jhass> https://github.com/mvz/gir_ffi/blob/master/lib/ffi-gobject/ruby_closure.rb here's ruby, though it heavily depends on FFI I think
<jhass> closure.set_marshal proc { |*args| marshaller(*args) } I guess that's where FFI took a large part of the job
<jhass> mmh, or maybe not
<asterite> I think g_cclosure_new or g_cclosure_new_swap are good
<asterite> We pass the closure data as the first parameter, so probably g_closure_new_swap is the one to go
<asterite> But we’ll have to add something to get the closure data out of a function pointer
<jhass> LibGObject.signal_connect_data(window as Void*, "destroy", -> { LibGtk.main_quit }, nil, nil, LibGObject::ConnectFlags::ZERO_NONE)
<jhass> that actually works oO
<jhass> first nil there is data, so if I got you right the function that's pointed to there just expects the closure data pointer as first param?
<jhass> in case it needs a closure
<asterite> I think so, yes
<asterite> We are enhancing Function so you’ll be able to try more things
<jhass> can you get a function pointer to a toplevel method? or even a function & closure pointer for a method on an object?
<asterite> Yes
<jhass> mmh
<asterite> >> def foo; 1; end; f = ->foo; f.call
<DeBot> asterite: 1
<jhass> couldn't we do (a rather unsafe, granted) send with that? :D
<jhass> Object#send
<asterite> >> def foo(x); x + 1; end; f = ->foo(Int32); f.call(2)
<DeBot> asterite: 3
<jhass> >> class Foo; def initialize(@x); end; def foo; @x+1; end; end; foo = Foo.new(2); f = ->foo.foo; f.call
<DeBot> jhass: 3
<jhass> hah
<jhass> >> class Foo; def initialize(@x); end; def foo; @x+1; end; end; foo = Foo.new(2); f = ->foo.foo; f.class
<DeBot> jhass: ( -> Int32)
<jhass> ugh, now I'm getting ideas :P
<jhass> >> class Foo; def initialize(@x); end; def foo; @x+1; end; end; def bar; yield; end; foo = Foo.new(2); f = ->foo.foo; bar(&f)
<DeBot> jhass: 3
<jhass> wow
<jhass> that's nice
<jhass> did I overlook docs for it? :D
<asterite> Umm… wait. Didn’t you read the whole compiler’s source code?
<jhass> No, I don't dare to look beyond stdlib :P
<asterite> ;)
<asterite> I actually never used that, but we thought it makes the language more complete
<asterite> More functional, if you want
<jhass> yeah
<jhass> it's basically equivalent to Ruby's Method#to_proc I guess
<jhass> which you too use very rarely, but has its uses from time to time
<jhass> >> class Foo; def self.store cb; @@cb = cb; end; def run; @@cb.call; end; def foo; 1; end; store ->foo; end; Foo.new.run
<DeBot> jhass: Error in line 3: undefined local variable or method 'foo'
<jhass> >> class Foo; def self.store cb; @@cb = cb; end; def run; @@cb.call; end; def foo; 1; end; store ->self.foo; end; Foo.new.run
<DeBot> jhass: Error in line 3: error instantiating ->self.foo
<jhass> mmh, no way to point to an instance method without the instance I guess
leafybasil has quit [Remote host closed the connection]
<asterite> Well, it’s something I’d like to do, in fact
<asterite> but it will give you a function with an extra parameter, self, and you must provide it
<jhass> yeah
<asterite> so that way you can get the definition of the function and invoke it with different selves
<asterite> selfs?
leafybasil has joined #crystal-lang
<jhass> okay, weird idea: what if we have a wrapper object for that closure object a Function can have and allow setters for it
<jhass> and then have all things that have methods a method to obtain such a thing
<asterite> Mmm… I’m not following you
<jhass> weird pseudo code in progress
<jhass> class Foo; def initialize(@x) def x; @x; end; end; instance_x ->Foo#x; instance_x.call #=> error; instance_x.context = Foo.new(1).to_context; instance_x.call #=> 1; instance_x.context = Foo.new(2); instance_x.call #=> 2
<jhass> makes any sense?
leafybasil has quit [Ping timeout: 245 seconds]
<jhass> probably no way to make that any kind of safe
<asterite> Oh, I was thinking something more like: f = ->Foo.x(self); f.call(Foo.new(1))
<jhass> yeah, got that
<asterite> That is, not something you can configure, but you can make a wrapper that’s configurable, I guess
<asterite> But I think that wrapper can be written in Crystal, right?
<jhass> mmh, probably
<jhass> could have it in stdlib even then
<asterite> Yes, maybe. What would you do with it?
<jhass> I was just thinking it be nice to set the context somewhere and the pass it on to something that doesn't know the context
<jhass> wrapper didn't occur to me right away, but you're right
<jhass> one idea I have right away for it is adding a parameter to the match call in the plugin API of my IRC bot
<jhass> which lets you define which method is called for the matcher
<jhass> match /^!a/, ->#handle_a
<asterite> The methods are argless?
<jhass> match /^!b/, ->#handle_b
<asterite> Ah, I see
<jhass> no, but requiring a common interface to them wouldn't be something I would worry about
<asterite> Why not match /^!a/ { … }
<asterite> (with a macro, of course)
<asterite> Ah, but that’s also hard (need to keep state in the macro)
<jhass> yeah, and currently I'm actually instantiating a new instance of the plugin for every message
<jhass> if a matcher matches
<jhass> could probably do that in a stored block, but meh
<jhass> would still require some boilerplate in the caller side I think
leafybasil has joined #crystal-lang
<asterite> Well, now you have a more powerful Function (need to recompile the compiler for that): https://github.com/manastech/crystal/blob/master/src/function.cr
<asterite> We realized we could implement some primitives in crystal itself, and now it’s very clear how a Function is represented internally :)
<asterite> And in case you need to see how to use it: https://github.com/manastech/crystal/blob/master/spec/std/function_spec.cr#L51
<jhass> neat
asterite has quit [Quit: asterite]
<travis-ci> manastech/crystal#1932 (master - bee1395 : Ary Borenszweig): The build passed.
asterite has joined #crystal-lang
<asterite> jhass: do you get files with strange names in your crystal directory?
<jhass> like ??? ?
<jhass> ls
<jhass> ???? bin CHANGELOG.md cloc crystal.cloc Dockerfile Dockerfile.release LICENSE Makefile Rakefile README.md samples spec src tests Vagrantfile
<jhass> I thought that ???? is a btrfs bug :P
<jhass> yeah, fresh clone doesn't have it
<asterite> For us it’s more like V%FF, %*)_%FF
<jhass> ruby sees it as "\u0002\x9E\xFF\u007F"
waj has quit [Quit: Leaving.]
<jhass> possibly from the spec run?
<asterite> Yes, those “\u007F” are here too
<asterite> We are not sur
<asterite> e
<asterite> Well, just wanted to know that, thanks :)
asterite has quit [Quit: asterite]
bcardiff has joined #crystal-lang
bcardiff has quit [Quit: Leaving.]
bcardiff has joined #crystal-lang
<crystal-gh> [crystal] ysbaddaden opened pull request #400: Fix: leaking file descriptors on socket creation errors (master...close-sockets-on-errors) http://git.io/bPMx
shama has quit [Remote host closed the connection]
shama has joined #crystal-lang
bcardiff has quit [Quit: Leaving.]
zamith__ has joined #crystal-lang
asterite has joined #crystal-lang
asterite has quit [Client Quit]
bcardiff has joined #crystal-lang