faustinoaq has quit [Quit: IRC client terminated!]
fomagnoma has joined #crystal-lang
fomagnoma has quit [Quit: Leaving]
faustinoaq has joined #crystal-lang
return0e has joined #crystal-lang
<FromGitter>
<S-YOU> @bew, example provided by h2o does not work with its on eventloop somehow (some c api are different on master), so I am using libuv.
<FromGitter>
<bew> ok, that's weird
<FromGitter>
<S-YOU> Writing bindings is least effort, than writing own xD
p0p0pr37_ has joined #crystal-lang
p0p0pr37 has quit [Ping timeout: 265 seconds]
p0p0pr37_ is now known as p0p0pr37
<FromGitter>
<S-YOU> crystal-pg not using libpq right? is there libpq binding?
<FromGitter>
<S-YOU> ok, there is
pabs has quit [Ping timeout: 256 seconds]
pabs has joined #crystal-lang
<crystal-gh>
[crystal] MakeNowJust opened pull request #6150: Drop 'when _' support (master...fix/crystal-syntax/drop-when-underscore-support) https://git.io/vhWsm
p0p0pr37_ has joined #crystal-lang
p0p0pr37_ has joined #crystal-lang
p0p0pr37 has quit [Ping timeout: 240 seconds]
p0p0pr37_ is now known as p0p0pr37
pabs has quit [Ping timeout: 265 seconds]
pabs has joined #crystal-lang
p0p0pr37_ has joined #crystal-lang
p0p0pr37_ has joined #crystal-lang
p0p0pr37 has quit [Ping timeout: 248 seconds]
p0p0pr37_ is now known as p0p0pr37
hightower3 has joined #crystal-lang
Groogy has joined #crystal-lang
<Groogy>
Morning! o/
p0p0pr37_ has joined #crystal-lang
p0p0pr37_ has joined #crystal-lang
p0p0pr37 has quit [Ping timeout: 265 seconds]
p0p0pr37_ is now known as p0p0pr37
return0e has quit [Ping timeout: 260 seconds]
hightower3 has quit [Ping timeout: 260 seconds]
<FromGitter>
<bew> hey :) it's been a long time, back on your game?
<wrq>
So what's the best way to deal with SomeType | Nil. I just have to check for nil in every spot I use that value? Is there a better way?
<wrq>
But crystal doesn't have Some/None, which I guess doesn't matter since it doesn't exhaustively check case expressions anyways so I'm not protected there. Normally in rust I use match and a Result for io, and I don't have to worry about my value throwing a wrench in anything whether the operation fails or not
<FromGitter>
<asterite> in the next version it will
<RX14>
wrq, you'd need to check for nil anyway, since obviously you don't want a null pointer exception
<RX14>
it's just now the compiler forces you to do it
<RX14>
I don't find nil checking to be a problem
<RX14>
or even really very common in my code
<wrq>
That's true.
<RX14>
maybe it requires adapring your design if you're coming from a dynamic language
<RX14>
but to me, dealing with nil and changing my code design around nil has become natural
<RX14>
it's just experience
<RX14>
if you give examples, the people in this channel wil always be glad to lend their experience :)
<wrq>
Well and that api makes it more clear sort of the symbolic meaning of nil in crystal, and roughly how to use it
<crystal-gh>
[crystal] r00ster91 opened pull request #6152: Use Char instead of String at escape sequences (master...improvements) https://git.io/vhWVr
<RX14>
you mean the docs wrq?
<RX14>
ok yeah, you said you're used to Some and None in Rust
<wrq>
Yeah that api page, sorry
<RX14>
well give me any pattern in rust and it'll be super simple to translate into crystal
<FromGitter>
<asterite> RX14 how did the exams go?
<RX14>
they really are very similar
<RX14>
@asterite pretty good actually, thanks for asking :)
<RX14>
glad to not think about them again
<FromGitter>
<asterite> Great :)
<wrq>
I see the similarity, I'm realizing that nil is sort of very similar to None but without the T information
<RX14>
yeah
<RX14>
because the T is encoded in the union
<wrq>
Right
<RX14>
it's just T | Nil instead of Option(T)
<RX14>
and you can use normal operators in the value
<wrq>
So I'm still essentially doing the same behavior
<RX14>
instead of custom methods on Option
<RX14>
and using "if" changes the type of the variable
<RX14>
instead of having to manually unwrap
<RX14>
which is why I think this way is superior
<wrq>
Right, no .expect
<wrq>
I do like that too
<RX14>
yeah
<RX14>
.expect is just
<RX14>
foo || raide "str"
<RX14>
raise*
<RX14>
it's super intuitive
<RX14>
instead of learning the method names :)
<wrq>
Alright, so I think I was thinking about the problem wrong. I'm More comfortable now that crystal is doing the tight thing
<RX14>
yeah
<wrq>
I'm glad you explained it
<wrq>
Thank you
<RX14>
as I said, it's almost possible to convert rust code using Option to use T? automatically
<RX14>
they're fairly similar
<RX14>
apart from the pattern matching
<wrq>
Right, just T|Nil
<RX14>
you generally just use "if" instead of case in crystal
<wrq>
Yeah, which is readable when it's only two possibilities
<RX14>
it's hard, because union types really aren't a thing in any other language
<RX14>
crystal has a lot of unique things in it so it's definitely harder to learn than your typical language
<wrq>
It can't be worse than rust
<wrq>
Honestly
<FromGitter>
<asterite> about union types, nilable are great, but other unions are usually a code smell
<RX14>
crystal has probably more unusual things than rust
<RX14>
but their total sum of unusuality is less
<FromGitter>
<asterite> that's why probably nilable types exist in other languages, but not general union types
<RX14>
@asterite I'm not sure about that
<RX14>
and besides
<FromGitter>
<asterite> proabably union types are good for private code, but for public APIs they are not that great
<RX14>
once you model T, Nil and NoReturn properly
<RX14>
it's just so easy to add all the other types :P
<RX14>
and it gives you so much flexability
<FromGitter>
<asterite> I guess that's true
<wrq>
My lunch break is almost over, thanks a ton for taking the time, gents. I'll give it another go this evening now that it clicked with me
<wrq>
:)
<RX14>
patterns like using `foo = Foo.new(foo) if foo.is_a? String` instead of an overload @asterite
<FromGitter>
<asterite> It's also the consequence of how typing works... but it could just be an error if a union type other than a nilable type would to be created
<RX14>
wrq, nice, have a good one
<FromGitter>
<asterite> yeah, that's useful
<RX14>
i mean even stuff like ebing able to change the type of a variable halfway through a method isn't in a lot of languages
<RX14>
I use that one a lot
<RX14>
sure, you could get 90% of the way to crystal with 40% of the features, but we're already 100% of the way there, I don't want to give up on this opportunity and let all these innovative new ideas go to waste
<RX14>
because there really are so many innovative new ideas in crystal
<RX14>
ideas that are largely yours
<RX14>
and thats a big part of the reason I continue working in crystal
<RX14>
it's not just "go with ruby syntax" :P
<FromGitter>
<asterite> well, let me rephrase that too "big union types are a smell"
<FromGitter>
<asterite> :-P
<RX14>
yeah, thats usually true
<RX14>
perhaps max 5 types
<RX14>
unless they're all in the same type hierarchy
<RX14>
then... it gets more complicated
<FromGitter>
<asterite> yeah, it's complex
<RX14>
which is why you used to promote them
<RX14>
i honestly don't use inheritance much in crystal
<ben___>
Is the complexity of inference more the number of types in a union or the complexity of the types in the union, like 2 structs with 5 including other types? Just to understand
<oprypin>
who said it was related
pabs has quit [Ping timeout: 260 seconds]
<FromGitter>
<asterite> oprypin: I actually think that now mostly because you noticed it :-)
rohitpaulk has joined #crystal-lang
<oprypin>
oh ok
pabs has joined #crystal-lang
<RX14>
i don't think they're code smells
<RX14>
crystal certainly makes it easy to write bad code
<RX14>
but it also makes it easy to write fantastic code
<RX14>
it's just what expressiveness gets you
<oprypin>
let's just say it's a powerful tool...
<RX14>
exactly
<RX14>
crystal is one of the most powerful programming languages out there
<RX14>
at least more powerful than is typical for commonly used languages
<RX14>
well, statically typed ones
<RX14>
dynamically typed interpreted languages kind of give you fairly infinite power but people still use them
<oprypin>
oh my yes
<RX14>
I think thats the best argument against trying to go and say "xyz is an antipattern lets remove it"
<RX14>
people use ruby all the time and it has all these features
<RX14>
in crystal we need to weigh up these features with compiler complexity though
<FromGitter>
<Grabli66> Hi! I like that all types is not null. But i think, that syntax someVal.try &.callMethod is more verbose than simeVal?.callMethod in other languages. Can i hope that it will be less verbose, some day? :)
<RX14>
i don't think so
<RX14>
I don't really use .try very often if at all
<oprypin>
ya
<RX14>
if you're using try everywhere, your code probably needs a redesign
<FromGitter>
<Grabli66> RX14, I dont use it everywhere. Sometimes
<FromGitter>
<Grabli66> But i think simeVal?.callMethod?.callOther?.value much better than ((someVal.try &.callMethod).try &.callOther).try &.value
<RX14>
if you ever have to write that, there's something going wrong
<RX14>
do you have a code example?
<FromGitter>
<Grabli66> No. I never will write such code. I hope :)
<RX14>
so
<RX14>
don't?
<RX14>
it's been quite a few years and I don't think anyone's come up with something like that using try
<RX14>
oh and besides
<RX14>
some_val.try(&.method).try(&.other).try(&.value) looks way better
<RX14>
[]? always returns nil if the key doesn't exist
<RX14>
if you use [] you'll get an exception
<FromGitter>
<Grabli66> But why it does not check types?
<RX14>
what do you mean, it does check types?
<RX14>
oh you mean why does [] not restrict it's argument to the key type of the hash?
<RX14>
well thats just a design decision
<FromGitter>
<Grabli66> Yes
<RX14>
it can make some things a bit uglier
<RX14>
and probably doesnt catch too many errors
<RX14>
so
<RX14>
the root of this is equality
<RX14>
for some people, 4 == "str" should raise
<RX14>
because the answer is always false
<RX14>
they're different types
<RX14>
why does the compier not catch this?
<RX14>
and really, looking up in a hash is an extension of equality
<RX14>
so it has the same semantics where's the type isn't strictly enforced
<FromGitter>
<Grabli66> I think compiler should throw exception if types not equals.
<RX14>
it creates a lot of false errors in reality
<RX14>
with union types, often only a subset of types match
<RX14>
stuff like querting a Hash(String, String) with a String | Int32, you often want that to just work right
snsei has quit [Remote host closed the connection]
rohitpaulk has quit [Ping timeout: 240 seconds]
<FromGitter>
<Grabli66> That example is ok. But transfer int32 as key to Hash(String, String) is error for sure.
<FromGitter>
<bew> @RX14 I also think those methods should be typed, and a union type is not a problem, because the type in a method is a restriction not a type assert
<FromGitter>
<bew> I have a branch with all hash methods typed to K or V, and it works well
<FromGitter>
<bew> ah you mean the key is a union.. that's wrong to me, and should error
<FromGitter>
<bew> the given key should always have a type that is a subset of Hash's key
faustinoaq has quit [Quit: IRC client terminated!]
faustinoaq has joined #crystal-lang
<RX14>
perhaps
<FromGitter>
<asterite> If someone wants to change that, make the change and send a PR. I already did and a lot of code became harder and uglier to write. But please, go ahead. I wasn't able to finish it, maybe someone can. Or they will realize what's the problem with that.
<FromGitter>
<bew> Will do! What do you this the problem is with that?
<FromGitter>
<asterite> Do it and you'll understand
<FromGitter>
<Grabli66> Did you decide to leave your creation? 😟
<FromGitter>
<asterite> What do you mean?
<FromGitter>
<raydf> @RX14 how do you fix the json traversing without try?
<FromGitter>
<Grabli66> @asterite I just thought that you want abandon work on crystal.
<FromGitter>
<raydf> example json["key"]?.try &.["key2"].try &.["key3"]?
<FromGitter>
<raydf> only serializing? If you have a dynamic code based on definitions created on json? for handling multiple cases
<crystal-gh>
[crystal] bew opened pull request #6154: WIP - Add K/V type restrictions for Hash methods (master...add-K-V-restriction-to-Hash-methods) https://git.io/vhWiH
<FromGitter>
<bew> @asterite ok I see the 'problem' 😛
<FromGitter>
<bew> I'll try to fix it
<FromGitter>
<bew> @RX14 was it you saying that master doesn't compile on Arch ? (I get an undefined llvm reference error at link time)
<FromGitter>
<bew> note: I'm using llvm v6.0.0
p0p0pr37_ has joined #crystal-lang
p0p0pr37_ has joined #crystal-lang
thews has quit [Excess Flood]
p0p0pr37 has quit [Ping timeout: 240 seconds]
p0p0pr37_ is now known as p0p0pr37
thews has joined #crystal-lang
thews has joined #crystal-lang
thews has quit [Changing host]
wrq has quit [Quit: Connection closed for inactivity]
<FromGitter>
<bew> nevermind I just needed to clean the cache ><
snsei has joined #crystal-lang
ua_ has joined #crystal-lang
<FromGitter>
<bararchy> So, Sunday or Monday for the 0.25 release?
havenwood has left #crystal-lang ["Textual IRC Client: www.textualapp.com"]
return0e has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
return0e has quit [Read error: Connection reset by peer]
return0e has joined #crystal-lang
<FromGitter>
<Blacksmoke16> looking into fibers for first time. If i have a channel that im sending stuff to in a spawn do block, is there a way to have the channel complete all "tasks" without calling `channel.receive` the same number of times you added to it
<FromGitter>
<Blacksmoke16> from my understanding a channel is like a queue where you can send it "tasks" that fibers will take off of it and complete?
<FromGitter>
<bew> you don't send "tasks", you send data, and some fiber can take that data and to something with it
<FromGitter>
<Blacksmoke16> afaik this will go out and concurrently do the HTTP request, get the data, and print it
<FromGitter>
<Blacksmoke16> with a fiber for each user that is requesting the wallet info
<FromGitter>
<Blacksmoke16> which seems to be the case as it prints all the users wallet info in about 1 second, vs 4 just doing the users do loop
<FromGitter>
<Blacksmoke16> for 24 users
<FromGitter>
<Blacksmoke16> i guess a better question would be, the `channel.receive` doesnt actually cause the http request to get made, but just returns the first fiber where its "job" is finished
return0e has quit [Read error: Connection reset by peer]