<txdv>
the benchmark just compares CSV implementations
<txdv>
the crystal implementation of the csv parser is slow
<txdv>
might have nothing to do with the language itself
<FromGitter>
<l3kn> The article doesn't mention which build flags were used and how the file looked like, I'm not sure how valid the results are
<txdv>
it doesnt meantion anything
<txdv>
cant even test his results
<txdv>
;D
<FromGitter>
<l3kn> With a file of 1M lines w/ 3 random floats each and `crystal build --release` / `go build`the resulting times are very similar (2.6s / 2.7s)
<FromGitter>
<l3kn> Maybe the results in the blog post were from running `crystal run --release` and `go run`, the go compiler seems to be a little bit faster
<bew78>
oh that might explain, thanks guys!
<FromGitter>
<luislavena> @l3kn the blog post is not fair. using `CSV.parse` will load the entire contents of the CSV in memory as an array while Go AFAIK offers a reader that is moved on each row, thus not allocating the entire thing in memory. https://crystal-lang.org/api/0.21.0/CSV.html
<FromGitter>
<luislavena> The recommended approach will be `CSV.new(io) { |row| ... }`, which will avoid allocating the entire thing in memory.
<FromGitter>
<luislavena> (or `csv = CSV.new; while row = csv.next; end` something like that)
<bew78>
Here, I don't get why there is an error on the last line: https://git.io/vyc4Y
<bew78>
well no, more specifically, in a module what is the difference between `def foo; end` and `def self.foo; end` as there cannot be a module instance?
<Papierkorb>
bew78: same as in a class, though for that to work for a module, you include it into one
mgarciaisaia has joined #crystal-lang
mgarciaisaia has left #crystal-lang [#crystal-lang]
pawnbox has quit [Remote host closed the connection]
pawnbox has joined #crystal-lang
pawnbox has quit [Ping timeout: 264 seconds]
<bew78>
Papierkorb: but then, why this fails: https://git.io/vyc4Y (last snippet line)
<Papierkorb>
bew78: because include and extend operate on the "instance" methods of the module only.
<Papierkorb>
what's what asterite says there
<bew78>
ok, so doing `def self.foo; end` in a module then including/extending a class with that module is pointless ?
<Papierkorb>
it's not pointless, but it won't "copy" that method, yes
<Papierkorb>
Generally, I use the Ruby methodology of having a InstanceMethods and a ClassMethods module, and the outer module includes/extends these into the class which inlude'd it
<Papierkorb>
you can do that through the `included` macro hook in Crystal
<bew78>
Papierkorb: but how do you use the ClassMethods module ? If I understand well, you use the `included` macro to put the defs from ClassMethods in the wanted class? but how..
<Papierkorb>
`extend ClassMethods`
<Papierkorb>
copies the instance methods from that module into the class method scope
<Papierkorb>
(To be more precise, it doesn't copy the methods, but merely adds ClassMethods into the lookup path for the Class you extended into)
<bew78>
so: in MyClass, `include Something` will take all defs from Something and add them to the lookup of MyClass instances, and `extend SomethingElse` will take the defs from SomethingElse and add them to the lookup of MyClass's class methods ?
<Papierkorb>
yes
<crystal-gh>
[crystal] asterite pushed 1 new commit to master: https://git.io/vycEr
<crystal-gh>
crystal/master 957c701 Ary Borenszweig: Formatter: fixed a few issues regarding newlines, comments and indents. Fixes #4088
<crystal-gh>
[crystal] asterite pushed 1 new commit to master: https://git.io/vycXF
<crystal-gh>
crystal/master ac7a5f0 Ary Borenszweig: travis: run specs in verbose mode...
<crystal-gh>
[crystal] olbat opened pull request #4103: Add spec compiler to s c bindings (master...add_spec_compiler_to_s_c_bindings) https://git.io/vycMl
mgarciaisaia has quit [Quit: Leaving.]
<crystal-gh>
[crystal] asterite pushed 1 new commit to master: https://git.io/vyc7r
<crystal-gh>
crystal/master 3dc743d Ary Borenszweig: Codegen: define __crystal_malloc_atomic first before any other code...
akwiatkowski has joined #crystal-lang
pawnbox_ has joined #crystal-lang
pawnbox has quit [Ping timeout: 240 seconds]
splitty_ has quit [Ping timeout: 240 seconds]
splitty_ has joined #crystal-lang
Hates__ has joined #crystal-lang
danzilio_ has joined #crystal-lang
Yxhvd has joined #crystal-lang
leex has joined #crystal-lang
toxedvirus has joined #crystal-lang
fedruantine_ has joined #crystal-lang
braidn[m]1 has joined #crystal-lang
braidn[m] has quit [*.net *.split]
Hates_ has quit [*.net *.split]
danzilio has quit [*.net *.split]
fedruantine has quit [*.net *.split]
leex_ has quit [*.net *.split]
txdv has quit [*.net *.split]
Yxhuvud has quit [*.net *.split]
danzilio_ is now known as danzilio
Hates__ is now known as Hates_
ome has quit [Ping timeout: 255 seconds]
ome has joined #crystal-lang
gloscombe has quit [Remote host closed the connection]
<FromGitter>
<tekjar> What does `read_byte` return `UInt8 | Nil` instead of raising an exception?
<FromGitter>
<tekjar> Why does*
<jhass>
because it's 1) not exceptionally rare 2) forces you to handle the case while you could forget to handle the exception
<FromGitter>
<tekjar> Ohh.. What is the idiomatic way to handle ` X | Nil` cases in crystal?
<FromGitter>
<tekjar> Can you please point me to an example?
<FromGitter>
<dreyks> `try`?
<jhass>
depends, Object#try or just if/else them
lacour has joined #crystal-lang
<FromGitter>
<tekjar> Thanks. I'll try `try`
soveran has joined #crystal-lang
soveran has joined #crystal-lang
soveran has quit [Changing host]
pnshrmp has joined #crystal-lang
<pnshrmp>
Hey all... new crystal user here! kudos for your great work.
<jhass>
<3 welcome
<FromGitter>
<sdogruyol> @pnshrmp welcome :)
<Papierkorb>
Hello pnshrmp, enjoy your stay
<pnshrmp>
kemal is awesome. I've been using such _many_ equally simplistic python web libraries/frameworks. I can now have that same productivity and higher performance. Happiness!! :D
<FromGitter>
<sdogruyol> that's great to hear :)
<pnshrmp>
so the website mentions that there are people working on concurrency... the docs do mention fibers, spawn etc. Is this stuff usable?
<jhass>
yes, it just might change and runs on a single thread for now
<pnshrmp>
how does one cap the amount of concurrent fibers?
<jhass>
you don't really need to, having several thousands is no issue on a 64bit machine
<pnshrmp>
I would love a simple api in the lines of aquire() release() but I get the feeling that is not really the crystal way
<pnshrmp>
but one could want to do that because of other reason than resources
<jhass>
then you should use higher level primitives, like connection pools, semaphores or whatever
<pnshrmp>
like, I don't know, in a game for example, or for dun
<pnshrmp>
yes, that is what I am asking, is there a semaphore implementation?
<jhass>
nothing in stdlib, but it's really easy to do on your own while everything is single threaded
<jhass>
there's some support for atomic operations
<pnshrmp>
That would be a good little exercise for me to get more familiar with the language
<jhass>
to wait/lock you'd just use an unbuffered channel and receive/send on it
<pnshrmp>
ahahah man, I was already typing a question asking how to do that
<pnshrmp>
another stupid question, I'm not really a runy person. Is there a simpler for cycle construct to iterate over collections? I mostly see rubyesque code with blocks and the like
<Papierkorb>
`each` etc. is the way to go
<Yxhvd>
each is 1: easy and foolproof 2: without overhead as blocks will be inlined.
<Yxhvd>
but, if you find something that doesn't express easily, you may want to drop the code here and someone may tell you a way to do it in a cleaner way
<jhass>
you can construct for-like loops with n.upto(m) od
<jhass>
* do |i|
<jhass>
but usally there's a nicer alternative, yeah
<pnshrmp>
is there anything like python list comprehensions? Or, if not, is it feasable to implement them with a macro for example?
<Papierkorb>
Looks like map
<Yxhvd>
No, you don't need them. each/map etc is a different paradigm. Both have strengths and weaknesses compared to the other.
<jhass>
yep, don't try to retrofit what you know into a new language, give its idioms a try first
<jhass>
personally I prefer Ruby/Crystal style method chaining over python list comprehensions, as you can read them forward instead of backwards
<jhass>
and may not even end up needing the resulting array
<Yxhvd>
backwards? they are inside out!
<jhass>
as in not even generating it because it all happens on iterators
<Papierkorb>
*looks up python* Wow .. people really claim that python is readable?
<Yxhvd>
well, list comprehensions are pretty ok until you try to nest them. Then they become horrible.
<Papierkorb>
pnshrmp: Crystal has a focus on OOP, so you usually call methods on stuff. Python has a different focus, and thus, heavily different paradigms
<Yxhvd>
whereas ruby/crystal iteration chaining reads a lot easier.
<pnshrmp>
I love python comprehensions, usually I chaing them byt assigning them to variables. Generator comprehensions mostly. I also like F# pipes.
<pnshrmp>
ok, while we're at it... what would be the closest to python generators (yes, I reckon I refereing to python all the time...sorry)
<jhass>
Iterator
<jhass>
well or a normal method with a yield is pretty close already I guess
<jhass>
but you can do "foo".each_char.map(&.ord).sum or the like
<jhass>
which shouldn't allocate more than an Int32 or two
<pnshrmp>
mmm looks different, I remember reading about yield yesterday... it puts a block of code in its place if I understand it right...?
<jhass>
yes
<pnshrmp>
is the code just placed there? like just expanded?
<jhass>
that's how all the standard "loops" are build, so a simplified Array#each is just def each; 0.upto(size) do |i| yield get(i); end; end; so to say
<jhass>
yes
<Yxhvd>
the code is placed there, but the scope you execute your code in stays the same (except for the block variable that is injected
<jhass>
you can also think about like anonymous functions which are always inlined
<pnshrmp>
I am not familiar with compilers, but yeah, makes sense
<jhass>
has not too much to do with compilers (only the inlining part), ruby has just the same concept
bjz_ has quit [Ping timeout: 260 seconds]
<Yxhvd>
It is basically a lexical closure, but without the performance overhead that they usually have.
<pnshrmp>
ok, more interesting question I guess... if I go to D or nim website, there is a huge focus on macros and metaprogramming. Not so much on crystal's... is there any perticular reason for this? looks capable in this repsect as well AFAICT
<jhass>
our community thinks our macros are awesome, our language's father is afraid they'll get overused/abused ;)
<Yxhvd>
macros are nice to have sometimes, usually to avoid repeating yourself, but most of the time there really is no need to use them
bjz has joined #crystal-lang
<Yxhvd>
sometimes to create nice DSLs. I guess those are the ones that may be abused :P
pawnbox has quit [Remote host closed the connection]
bjz has quit [Quit: My MacBook Pro has gone to sleep. ZZZzzz…]
perks has joined #crystal-lang
<FromGitter>
<tekjar> Hi. How do I raise an exception for ` X | Nil` type when the value is nil at runtime during assignment. For example ⏎ ⏎ ```b = io.read_byte``` ⏎ ⏎ after assignment, the type of `b` here should be `UInt8` . Not `UInt8 | Nil` [https://gitter.im/crystal-lang/crystal?at=58b9e96621d548df2c8962da]
<RX14>
@takjar use .not_nil!
<FromGitter>
<dreyks> `not_nil!`
<RX14>
it'll raise if it is nil
<FromGitter>
<tekjar> I tried doing `if b = io.read_byte` but there are lot of `read_byte` calls in my code
<FromGitter>
<tekjar> Ohh thanks alot
<FromGitter>
<dreyks> actually isn't this an antipattern?
<jhass>
.not_nil! explicitly most of the time is
<FromGitter>
<dreyks> you're trading compile-time exception for a runtime one
<jhass>
the stdlib mostly takes care of providing non-raising variants for where it's used
<FromGitter>
<tekjar> What if I don't have anything to do after catching it in compile time?
<jhass>
what it signals you is that you have no data where you expected some
<jhass>
you proably should abort your program with a specific error then
<jhass>
like abort "expected to find header field X but stream was closed"
<FromGitter>
<tekjar> Ok. The protocol expects data to be there. If it's not, it should raise an exception. Maybe I should raise a custom exception
<jhass>
yeah
<FromGitter>
<tekjar> jhass: What is the idiomatic way to do that without using `not_nil`?
<jhass>
tekjar: I'd say if/else, maybe you can hide some redundant code inside a method, depends on your programs structure
<FromGitter>
<tekjar> sija: I tried reading docs to find example about `try` but I couldn't find any. I'm not a ruby guy
<RX14>
I usually create a fail(message) thing
<jhass>
pnshrmp: fun fact: for loops in Ruby are calling .each internally and are actually slower than .each in recent MRI versions
<RX14>
then do fail("message") unless variable
<RX14>
and it'll make sure variable isn't nil after that point
<sija>
tekjar: it executes the given block for any not `.nil?` value
<FromGitter>
<tekjar> RX14: Ohh. I'll try that
<FromGitter>
<tekjar> sija: Ohh okk. Thanks :)
adam12 is now known as adam
adam is now known as Guest18238
<FromGitter>
<jwoertink> Is there a way to tell child classes that there's a method from the parent you can override, but it's not required. Something like `abstract`, but without it being required... Or is it better to just define an empty method?
<RX14>
just define an empty method
<FromGitter>
<jwoertink> :thumbsup:
<FromGitter>
<tekjar> Hi. How do I convert `UInt8` to `enum QoS: UInt8` type?
<FromGitter>
<tekjar> Since the number `UInt8` variable holds during runtime might fall out of range for `enum` type
perks has quit [Quit: perks]
soveran has quit [Remote host closed the connection]
<FromGitter>
<l3kn> @tekjar `QoS.from_value(v)` will raise an exception if the v is out of range (and `QoS.from_value?(v)` will return `nil`)