<Kilo`byte>
commit 2344451615190a6e8963421e80d253518497f1e8 in case i add some commits before you see this
kori has joined #crystal-lang
DeBot has quit [Remote host closed the connection]
NeverDie has quit [Quit: I'm off to sleep. ZZZzzz…]
kyrylo has quit [Ping timeout: 244 seconds]
bcardiff has joined #crystal-lang
willl has joined #crystal-lang
dylanmei has quit [Quit: ZZZzzz…]
dylanmei has joined #crystal-lang
dylanmei has quit [Quit: ZZZzzz…]
vonkingsley has joined #crystal-lang
vonkingsley has quit [Client Quit]
dylanmei has joined #crystal-lang
dylanmei has quit [Client Quit]
BlaXpirit has joined #crystal-lang
willl has quit [Ping timeout: 244 seconds]
willl has joined #crystal-lang
bcardiff has quit [Quit: bcardiff]
Ven has joined #crystal-lang
ssvb has quit [Ping timeout: 265 seconds]
havenwood has joined #crystal-lang
ssvb has joined #crystal-lang
sdogruyol has joined #crystal-lang
tatey_ has quit []
Raimondii has joined #crystal-lang
Raimondi has quit [Ping timeout: 240 seconds]
<jokke>
how would i recursively delete a directory?
Raimondii is now known as Raimondi
<jokke>
i noticed there's no fileutils in the API
sdogruyol has quit [Ping timeout: 265 seconds]
sdogruyol has joined #crystal-lang
leafybasil has quit [Remote host closed the connection]
tatey_ has joined #crystal-lang
<jokke>
hm
<jokke>
i have a problem
<jokke>
my c lib has a function xapian_database_close
<jokke>
it takes a pointer to XapianDatabase
<jokke>
i've mapped XapianDatabase to Void*
<jokke>
XapianDatabase* to Void*
<jokke>
there are also other functions like xapian_writable_database_new
<jokke>
which return a XapianWritableDatabase*
<jokke>
which i've also mapped to Void*
<jokke>
now i have two classes XapianDatabase, and it's subclass XapianWritableDatabase
kyrylo has joined #crystal-lang
<jokke>
i want XapianDatabase to have an instance method close which calls xapian_database_close with the pointer returned by xapian_(writable_)database_new
<jokke>
but i crystal wont allow me to cast a WritableDatabase* to Database*
<jhass>
in the parent define def to_unsafe; @pointer as XapianDatabase*; end; def close; LibXapien.database_close(self); end;
<RX14>
Kilo`byte, are you around?
<jhass>
in the subclass def to_unsafe; @pointer as XapianWritableDatabase*; end; def initialize; @pointer = LibXapian.writable_database_new; end
<jhass>
mmh, actually not sure that works
<jhass>
might need private def database; @pointer as XapianDatabase*; end; ... LibXapian.close(database) in the parent
leafybasil has joined #crystal-lang
<jokke>
nope
<jokke>
can't cast Pointer(LibXapian::WritableDatabase)? to Pointer(LibXapian::Database)
<jokke>
this doesn't work either: in ./src/xapian/database.cr:21: can't cast (Pointer(LibXapian::WritableDatabase) | Pointer(LibXapian::Database)) to Pointer(LibXapian::Database)
<jhass>
meh, might need to cast to Void* first
<jokke>
:(
<jokke>
woh
<jokke>
wow
<jokke>
can't cast (Pointer(LibXapian::WritableDatabase) | Pointer(LibXapian::Database)) to Pointer(Void)
<jokke>
that sure is some type safety :D
Ven has quit [Ping timeout: 265 seconds]
<jhass>
uh
<jhass>
maybe it's still the union? :/
<jokke>
that would be can't cast Pointer(LibXapian::WritableDatabase)? to Pointer(Void)
<jokke>
right?
<jhass>
no
<jhass>
I think you just can't cast unions to things outside
<jhass>
jokke: how about protected def to_database; (@pointer as LibXapian::Database); end; def close; LibXapian.close(to_database); end; in the superclass and def to_database; (@pointer as LibXapian::WritableDatabase) as LibXapian::Database; end; in the subclass
<jhass>
RX14: click the link
<RX14>
back to ircv3 parsing
<RX14>
also the segfaults Kilo`byte got was because I didn't push my segfault fix...
<RX14>
stupid me
<jhass>
asterite: /cc ^
<jhass>
for when he reads the backlog
<RX14>
yeah the segfault was because of the :: unsafe I used
<RX14>
i fixed it but forgot to push which lead Kilo`byte to get confused
<RX14>
I thought I pushed it anyways
<RX14>
but never mind
<RX14>
it was my fault as I said yesterday
kyrylo_ has joined #crystal-lang
<RX14>
yes! all the specs run, it's just time for ircv3 now
kyrylo has quit [Ping timeout: 252 seconds]
<jokke>
jhass: awesome!
<jokke>
works like a charm
<jokke>
but i used to_unsafe instead of (@pointer as LibXapian::WritableDatabase)
<jokke>
which is exactly that
<jokke>
but i had to solve the union
<jhass>
yeah
<jhass>
I guess an alternative to casting is to use a different instance var in the subclass
<Kilo`byte>
now i just gotta figure out why my code doesn't actually parse the message
<jhass>
my real code is more like spawn do; loop do; spawn do; 1; end; end; sleep 1000; (well, not unlimited, just a whole bunch), no idea why it doesn't repro in the minimal example
<Kilo`byte>
hmmm weird
<Kilo`byte>
I'm fairly sure spawn instantly gives the fiber a time slice
<jhass>
oh, no
<jhass>
the fix was to Scheduler.yield after a threshold
<jhass>
well, workaround
<Kilo`byte>
what's diff between yield and reschedule
<jhass>
yield makes sure you're queued onto the pending ones
sdogruyol has quit [Remote host closed the connection]
<RX14>
hmmn, what's the best way to write a char to a stringbuilder
ssvb has joined #crystal-lang
<jhass>
<< char
<jhass>
and if it isn't it should be made the best way ;P
<RX14>
well as I have no faith in LLVM I will use 'x'.ord.to_u8
<RX14>
because << calls to_s self
<RX14>
and to_s on char calls ord.to_u8
<Kilo`byte>
can you tell crystal to spit out llvm bytecode?
<RX14>
yes
<Kilo`byte>
possibly in text form so you can actually read it
<jhass>
--emit llvm-ir iirc
<RX14>
you can read it
<jhass>
will dump a foo.ll
<jhass>
--prelude empty might help some
<RX14>
yet I have no faith that an optimisation that works one will work again
<RX14>
anyway my code isn't too unreadable
<RX14>
okay so my ircv3 parsing compiles
<RX14>
now it only needs to work!
<Kilo`byte>
xD
<jhass>
hey, that's usually 3/4 there in crystal!
<jhass>
if you trust llvm and stdlib that is :P
sdogruyol has joined #crystal-lang
<RX14>
well shit
<RX14>
all that debugging
<Kilo`byte>
crystal really needs to get better at debugging :P
<RX14>
and I had placed my hash[k] = v on the wrong line
<RX14>
too many nested stuffs
<RX14>
and i was too far in
<RX14>
okay it parses simple tags!
<Kilo`byte>
nice
havenwood has joined #crystal-lang
<RX14>
okay now I have an infinite loop
<RX14>
progress
<RX14>
okay i forgot an incr
<RX14>
and now it parses anything without values
<RX14>
now it parses anything without eascape sequences
<RX14>
even parsing a simple tag, performance goes down from nearly 4M RPS to 1.3M RPS
<RX14>
just adding @tag
<RX14>
or maybe it's the optimiser optimising out everything
<RX14>
hmmn, no tags should mean tags are nil
<RX14>
not empty hash
<RX14>
Kilo`byte, if something doesn't exist it should be nil
<RX14>
is there are no params, it will return nil instead of []
<RX14>
this greatly helps performance
<RX14>
I might want to rename params to params?
<Kilo`byte>
i it makes things a lot more work though
<RX14>
not really
<Kilo`byte>
and i am kinda against that
<RX14>
a nill check isn't bad
<Kilo`byte>
well okay, i use a macro to do param checking
<Kilo`byte>
so i can add that there
<Kilo`byte>
but still, its somewhat unexpected
<RX14>
no, we already returned nil if there was no prefix
<RX14>
Kilo`byte, it helps performance by about 2 million RPS
<RX14>
by over 2x
<Kilo`byte>
well, again
<Kilo`byte>
when do you not have params
<Kilo`byte>
practically never
<RX14>
but the same ius not true for prefix and tags
<RX14>
and it greatly helps there
<RX14>
we could make params always return []
<RX14>
but then it's not consistent
<Kilo`byte>
i don't really like having nilable types when its avoidable though
<Kilo`byte>
my personal opinion is that the current implementation will be fast enough for just about everything you will ever want
<Kilo`byte>
although, tag parsing is new
<Kilo`byte>
so i haven't benchmarked that yet
<Kilo`byte>
RX14: what you could do is make the tags getter lazily create an empty hash
<Kilo`byte>
when its nil
<Kilo`byte>
since tags are rarely read the performance should be good
tatey_ has quit []
<Kilo`byte>
and then a tags? method that might return nil
<RX14>
Kilo`byte, hmmn
<RX14>
yeah
<RX14>
tags? returns nil
<RX14>
then def tags; tags? ||= []; end
<RX14>
s/[]/{}/
<jhass>
eh, you can't assign to a method call :P
<RX14>
i meant ||
<RX14>
WAIT
<RX14>
I could have an immuytable {} and []
<RX14>
to save performance
<RX14>
maybe a Hash.empty which is immutable and there is only one instance
<Kilo`byte>
oh that exists?
<Kilo`byte>
that'd be handy
<RX14>
it would
<RX14>
but i don't think it does
<Kilo`byte>
well, crystal doesn't have the concept of immutability
<Kilo`byte>
sadly
Ven has quit [Remote host closed the connection]
<RX14>
basically passing {} and [] should be around the same perf. as nil
<Kilo`byte>
internally its a single pointer
<RX14>
Kilo`byte, well you can just extend hash and block all the right methods...
<Kilo`byte>
if pointer == 0 => nil, otherwise value
<Kilo`byte>
thats for reference types (read: everything that is no Int, Struct, Bool, etc)
<RX14>
well, whatever
<RX14>
it would be great
<Kilo`byte>
RX14: you should also consider using classes vs structs
bcardiff has quit [Quit: bcardiff]
blue_deref2 has joined #crystal-lang
<RX14>
no, I want to use structs
<Kilo`byte>
structs get copied when you pass them as param/return
<RX14>
because my classes are immutable
<RX14>
and structs have better passing performance
<RX14>
the docs say
blue_deref2 has left #crystal-lang [#crystal-lang]
<Kilo`byte>
it depends on the size of the struct
<RX14>
go benchmark it
<RX14>
or ask somebody likely to know
<Kilo`byte>
the only performance penalty i'd see is allocating it
<RX14>
like jhass
<Kilo`byte>
as allocating a class uses malloc
<Kilo`byte>
while allocating a struct doesn't
<dzv>
can the compiler be smarter? can it auto cast small classes to structs for methods that don't modify the class?
<dzv>
and then we wouldn't need to hand optimize. the optimization could also be platform specific
sdogruyol has quit [Read error: Connection reset by peer]
<jhass>
dzv: I think such optimizations shouldn't be done before we finalized language design
<RX14>
why not make an issue
<RX14>
something like "make crystal faster"
<RX14>
:P
<dzv>
optimizations can be changed/removed and don't require changes to the language
<jhass>
dzv: I'm more talking about effort spend now that might be nullified by language design changes
<jhass>
like if we change the language in a way that makes the optimization harder or easier to implement
<jhass>
while there are so many more important tasks still open :P
<dzv>
isn't "struct is faster" just as likely to change if the language changes? right developers are hand optimizing based on struct. future language changes could undo that. if the optimization was automatic developers could focus on readability and IF there's a need to optimize they could
<dzv>
it's more likely to break now based on structs and classes being handled differently
sdogruyol has joined #crystal-lang
<jhass>
time's limited, I think it's more important it's spent on things like the multithreaded scheduler and a sane crystal deps than smarter optimizations
<jhass>
it's fast enough atm
<sdogruyol>
yeah crystal is already fast enough :P
<sdogruyol>
cant imagine the performance with multithread though :O
<dzv>
but developers are already spending time on optimization. there is a choice. a) every developer chooses to spend time on optimization because the compiler is dumb or b) a few compiler writers spend time optimizing it ONCE
<RX14>
optimisations can be added after 1.0
<RX14>
and 1.0 will bring a lot of people to the langauge
<dzv>
jhass: i'll handle the multithreaded scheduler if someone else optimizes my classes to structs transparently
sdogruyol has quit [Remote host closed the connection]
<RX14>
okay i'm segfaulting again
<RX14>
wtf
<RX14>
oh no i'm not what am I saying
<BlaXpirit>
ok
<RX14>
okay so next in a stringbuilder block doesn't break that block
<RX14>
FFS
<jhass>
huh
<RX14>
but it does online
<BlaXpirit>
:D
<RX14>
not when I compile it
<RX14>
on carc.in
<jhass>
>> String.build {|b| b << "b"; next; b << "a" }
<crystal-gh>
crystal/master 160b233 Ary Borenszweig: Fixed #1201: don't cache include generic modules and inherited generic classes parents because they might later change
<crystal-gh>
crystal/master 744b447 Ary Borenszweig: Fixed #1185: disallow some types in fun pointers
<RX14>
as usual, looking at my code again and I work it out myself
<RX14>
okay, the parsing works
bcardiff has joined #crystal-lang
<jhass>
RX14: get a rubber duck :P
<RX14>
if I lived alone, yes
<RX14>
everyone would think I was crazy
<jhass>
huh? no, there's a WP article you can point to
<RX14>
Error writing file: Bad file descriptor (Errno)
<RX14>
so i don't know what to do
<asterite>
Try: File.open("/dev/null", "w")
<asterite>
It's a bug, in Ruby it says "not opened for writing", that check is probably missing in crystal...
<RX14>
thanks asterite
<RX14>
workes now
<RX14>
what's the StringPool useful for?
<asterite>
It's used in the json lexer and I thought it was generic enough, but I don't know
<asterite>
It lets you reuse string instances
<RX14>
it could help with some docs, like most things in crystal :P
<RX14>
i might get around to making docs
<RX14>
for some stuff
<jhass>
that's be awesome
<jhass>
*that'd
<RX14>
you should have written docs when you comitted it :(
<RX14>
but that never happens does it :P
bcardiff_ has joined #crystal-lang
bcardiff has quit [Ping timeout: 240 seconds]
bcardiff_ is now known as bcardiff
<luislavena>
asterite: may I pick your brain for a few minutes?
<asterite>
luislavena: sure
<luislavena>
asterite: just added you to something on github, wanted to check if sounds reasonable before open-source it :D
<asterite>
Let me check...
<luislavena>
still need to finish docs, but readme should be good intro
<RX14>
now i'm interested as to what this thing is :P
<asterite>
luislavena: Looks good!
<luislavena>
asterite: excellent, will add docs tonight and then open source
<luislavena>
thank you.
<asterite>
luislavena: Maybe Action could be a module
<luislavena>
asterite: thought about that, wasn't sure how that will result in Route#action union type :P{
<benner>
is it for purpose that puts [1, 2, 3] output is different than in ruby?
<asterite>
Oh, I see. Yes, class for now is ok :)
<luislavena>
asterite: ;-)
<asterite>
benner: at least i was surprised that in Ruby that doesn't output "[1, 2, 3]"
<jhass>
RX14: sounds like yet another webframework^^
<RX14>
it does
<benner>
asterite: we too. today found acidentally
<RX14>
[speculation intensifies]
<luislavena>
jhass: a slim HTTP routing toolkit, don't get too excited :P
<RX14>
do we have something like rack yet?
<jhass>
luislavena: have you seen artanis?
<RX14>
i like artanis
<RX14>
apart from the regex cost
<RX14>
i was going to make a microservice in crystal, then came all this IRC stuff
<RX14>
that side projects strip from commitstrip is my life basically
<luislavena>
jhass: I had, thing is that building regex on every request is not fast
<luislavena>
jhass: the other problem with sinatra-like approaches is test isolation
<luislavena>
your block is entirely bound to the HTTP Request/Response cycle, so you end needing to run the entire stack in order to test an specific action block
<crystal-gh>
[crystal] technorama opened pull request #1282: Add perm parameter to File.new & File.open (master...f/file_perm) http://git.io/vs5wi
<Kilo`byte>
actually i'd really like a profiler for crystal
<RX14>
If it's a : I just calculate the langth based on the string length instead of iterating through the remaining until I get to a 0
<RX14>
which obviously helps for PRIVMSG
<RX14>
because they have a long section after : usually
<Kilo`byte>
mhm
<Kilo`byte>
or even MOTD
<Kilo`byte>
because you get flooded with those
<Kilo`byte>
even though only once
<RX14>
i got 800000 RPS up to 1200000 RPS on a long PRIVMSG
<RX14>
1221046.55 874631.60
<Kilo`byte>
although on the client you don't really need that performance unless you are doing naughty stuff (*cough*clonebot*cough*)
<RX14>
umm
<RX14>
but IRCD parses PRIVMSG too
<RX14>
o do they?
<Kilo`byte>
yeah
<RX14>
well they need param 1
<RX14>
not 2
<RX14>
!wa
<RX14>
!calc
<RX14>
!help
<Kilo`byte>
also, once i implement server-linking that'll open a question
<Kilo`byte>
what linking protocol to use
<Kilo`byte>
options: official IRC one, reuse an optimized one from another ircd, roll own
<RX14>
a 1.4x improvement in parsing time with the message "nick!user@host PRIVMSG #channel :a very long, typical IRC message wooooooooocsssssssssssssssssssssssss"
<Kilo`byte>
official is not the most efficient
<Kilo`byte>
as it transmits "long" nicknames in plaintext, as well as even longer server names
<shevy>
hmm crystal seems to create a .crystal directory in the current directory; would it be possible to specify another directory to save-to? something under /tmp/ for instance
<RX14>
Kilo`byte, capnproto bindings to crystal would be nice
<Kilo`byte>
i am quite familar with the inspircd one which uses UIDs
<jhass>
shevy: yes, set the $CRYSTAL_CACHE_DIR environment variable
<RX14>
would that make a nice protocol?
<shevy>
ok
<Kilo`byte>
for binary data storage i either use plain binary or msgpack
<Kilo`byte>
depending on my needs
<RX14>
well capnp should be fastest
<Kilo`byte>
i know, but i still prefer msgpack for its compactness :P
<Kilo`byte>
but i'd probably actually use an irc based one
<RX14>
Kilo`byte, it's your IRCd
<Kilo`byte>
not a binary one
<RX14>
binary will be faster and easier to parse probably
<Kilo`byte>
well, i have time to decide that
leafybasil has joined #crystal-lang
<RX14>
but it's your IRCd
<Kilo`byte>
yeah, thats what i am thinking too
<RX14>
capnp crystal would be nice
<Kilo`byte>
yup, but i am talking here to get opinions in
<Kilo`byte>
:P
<shevy>
CRYSTAL_CACHE_DIR works nice. I had a look there, crystal generates files such as foo.bc and foo.o - I understand that .o is an object file but what is .bc?
<RX14>
llvm bytecode
<RX14>
i think
<jhass>
yeah
<Kilo`byte>
ah right i was wondering about that the other day as well
<jhass>
we can just ask file btw
<shevy>
ah ok
<jhass>
/home/jhass/.crystal/foo.cr/foo46cr.bc: LLVM IR bitcode
oal has quit [Ping timeout: 265 seconds]
<Kilo`byte>
jhass: just wonder, is there a documentation on how names are mangled?
<jhass>
doubt it
<Kilo`byte>
also how does gdb/valgrind demangle names?
<jhass>
still changes from time to time too
<Kilo`byte>
i mean neither are crystal aware
<jhass>
it doesn't?
<Kilo`byte>
is it stored in the binary?
<jhass>
I think it's the symbols, yeah
<Kilo`byte>
the names in stack traces do not look mangled to me
<jhass>
let's see if we can find the mangling code
<Kilo`byte>
like, in one of my tests it creates a Server, a User and a Channel with same params in pretty much every test
<asterite>
Yes, abstracting a method doesn't work right now
<asterite>
it probably shouldn't, because you are breaking that principle, liskov i think
<asterite>
Kilo`byte: you can use a helper method that gives you those three
<Kilo`byte>
hmm
<jhass>
asterite: maybe we should define a let macro for spec
<Kilo`byte>
yeah
<jhass>
though not sure how we could cache results on the top level :/
<Kilo`byte>
global variables? $__spec_name
<jhass>
and then busting the caches... nvm
<Kilo`byte>
does sound somewhat hacky tho
<Kilo`byte>
also crystals spec system makes it really fun writing tests
kyrylo has joined #crystal-lang
<Kilo`byte>
seeing all those green dots appear is really satisfying
<Kilo`byte>
i always feel like i can't have enough of those
<jhass>
we experimented a bit with a spec implementation that creates classes and methods for everything which would make let, before and so on all possible
<jhass>
defining that many classes slowed the compiler really down though, wasn't feasible for the compiler suite at least :/
<sardaukar>
hey
<Kilo`byte>
expected ArgumentError with "User already exists", got #<ArgumentError: Argument error> with backtrace:
<Kilo`byte>
rofl?
<sardaukar>
question: is the need for a temporary var in an if needed now as a temporary thing or will it be staying past 1.0 ?
<sardaukar>
for type resolution?
<Kilo`byte>
sardaukar: like if stuff = @stuff
<jhass>
sardaukar: it'll stay
<Kilo`byte>
its a design choice
<sardaukar>
what a hassle
<Kilo`byte>
@stuff can be nil inside the block
<Kilo`byte>
another thread might have changed it
<jhass>
no, it's the only correct code
<sardaukar>
I see the point, but it just feels like rote boilerplate
<sardaukar>
where's my programmer happiness ? :D
<jhass>
it would probably even more correct for the cases where you're not forced to it