<FromGitter>
<akzhan> Looks lik e time to release Crystal 0.24.0 (yet w/o SipHash)
DissonantGuil3 has joined #crystal-lang
DissonantGuile has quit [Ping timeout: 248 seconds]
<FromGitter>
<GrgDev> Just to be sure, (coming from a Ruby background) there's no #freeze method, right? Just mark it as a constant and be done with it?
DTZUZU has quit [Ping timeout: 240 seconds]
DTZUZU has joined #crystal-lang
alex`` has joined #crystal-lang
lacour has quit [Quit: Leaving]
dostoyevsky has quit [Ping timeout: 240 seconds]
dostoyevsky has joined #crystal-lang
claudiuinberlin has joined #crystal-lang
flaviodesousa has joined #crystal-lang
mark_66 has joined #crystal-lang
<FromGitter>
<zyriuse75> @RX14 thanks man ;)
alex`` has quit [Ping timeout: 252 seconds]
kubaxvx has joined #crystal-lang
claudiuinberlin has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
RickHull has quit [Ping timeout: 260 seconds]
claudiuinberlin has joined #crystal-lang
<FromGitter>
<zyriuse75> i've a stupid question to ask you
<FromGitter>
<zyriuse75> i try to call my class method since my module but unfortunately i've an error
<FromGitter>
<zyriuse75> i already had this error a long time ago in ruby but i dont remember exactly how i fix it
<FromGitter>
<ansarizafar> @zyriuse75 use self.mainMenu to call method
<FromGitter>
<zyriuse75> @ansarizafar thank i goign to read more documentation about how to use and in which case to use `self`
claudiuinberlin has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
claudiuinberlin has joined #crystal-lang
alex`` has joined #crystal-lang
zeitchef has joined #crystal-lang
claudiuinberlin has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
claudiuinberlin has joined #crystal-lang
<zeitchef>
Hi everyone, junior Rails dev here really curious about Crystal! I'd love to know of the best learning resources out there, aside from the Crystal docs/guide. Thanks!
gcds has joined #crystal-lang
hightower4 has joined #crystal-lang
hightower3 has quit [Ping timeout: 240 seconds]
claudiuinberlin has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
claudiuinberlin has joined #crystal-lang
<FromGitter>
<zyriuse75> if you are french we made the translation ;)
<FromGitter>
<Papierkorb> zeitchef, there's http://www.crystalforrubyists.com/ by @sdogruyol - apart from that: Think of something you'd like to build, and then build that.
<FromGitter>
<krypton97> That multithreading javascript runtime looks very good, gonna do some benchmarks against node's cluster to see if there's major differences
<FromGitter>
<krypton97> Ty for sharing
<FromGitter>
<Papierkorb> @GrgDev Correct, we don't have `#freeze`
claudiuinberlin has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
claudiuinberlin has joined #crystal-lang
claudiuinberlin has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<FromGitter>
<iambudi> > That multithreading javascript runtime looks very good, gonna do some benchmarks against node's cluster to see if there's major differences ⏎ ⏎ Mention me the result 🤓
<crystal-gh>
[crystal] asterite closed pull request #5129: Ensure FormData::Builder field value is a String (master...bugfix/multipart-builder-tos) https://git.io/vdMBT
<FromGitter>
<OldhamMade> hey peeps. working with hashes and arrays, if I were to have a type of `Hash(String, Array(NamedTuple(...)))`, how could I iteratively push items into the arrays adding new keys as necessary?
<FromGitter>
<OldhamMade> seems like I'd have to do something like ``` ⏎ foo = Hash(String, Array(NamedTuple( ~definition here~ ))
<FromGitter>
<OldhamMade> which means if the NamedTuple definition is long, there's a lot of duplication and the possibility of errors being introduced over time
<FromGitter>
<krypton97> Sure, as soon as I get home I'll post them ;)
<FromGitter>
<krypton97> And run em ofc
Groogy2 has quit [Quit: WeeChat 1.9]
claudiuinberlin has joined #crystal-lang
<FromGitter>
<asterite> OldhamMade: don't use NamedTuple. They just represent named arguments
<FromGitter>
<asterite> I don't know why everyone uses NamedTuple so much...
<FromGitter>
<OldhamMade> @asterite it's a common datastructure in Python, so feels comfortable as a way to define a fixed structure of symbol: value for things like records
<FromGitter>
<OldhamMade> as in, grab row from db, collect vals in to list of namedtuples, pass that around as needed to quickly access parts of each collection
<FromGitter>
<asterite> So how would you write the above snippet in python?
<FromGitter>
<OldhamMade> that will set the default value for a missing key to the type passed in to the constructor, so missing keys are auto-assigned an empty list in this example
<FromGitter>
<asterite> Ah, but there's no such thing as missing keys in a NamedTuple in Crystal, so you can't do that
<FromGitter>
<asterite> Missing keys are for Hash, so you might want to use that. Alternatively you can use a class or record with nilable fields
<FromGitter>
<OldhamMade> no, I have missing keys in the hash that I'd like to auto-fill with an array
<FromGitter>
<asterite> Nevermind. I guess the only way to solve this is by removing NamedTuple from the language, it was probably a mistake. Like double splat. Too ambitious
<FromGitter>
<OldhamMade> I'm finding double-splat very useful, but again, that's cos I'm used to kwargs in Python
<FromGitter>
<OldhamMade> and also the way elixir does it
<FromGitter>
<asterite> Yes, but those are dynamic languages
<FromGitter>
<OldhamMade> however, in this case the problem isn't namedtuples for me, but the hash itself
<FromGitter>
<asterite> I think it was a mistake to bring so many things from Ruby when most of the use cases are impossible to do in Crystal with the same data structures
<FromGitter>
<OldhamMade> if I were to use something else, the problem is still the same:
<FromGitter>
<asterite> Ah, but back to the original snippet, can't you use an alias for the definition of NamedTuple?
<FromGitter>
<asterite> I think alias is the answer
<FromGitter>
<OldhamMade> ahh, alias!
<FromGitter>
<OldhamMade> @asterite you're a legend! :D
<FromGitter>
<OldhamMade> I'm coming from a dynamic world, so I apologize for many novice questions. :)
claudiuinberlin has joined #crystal-lang
<FromGitter>
<sdogruyol> @OldhamMade he's the creator of Crystal so :D
claudiuinberlin has quit [Client Quit]
jsn- has joined #crystal-lang
<FromGitter>
<faustinoaq> 😃
<FromGitter>
<Papierkorb> Could we please not remove tuple types nor splatting?
<FromGitter>
<Papierkorb> People not understanding that data transfer is different from data storage isn't the issue. The issue is on the documentation not explaining this. It would be obvious for someone coming from Java, not much for those coming from Ruby or Python, and basically absolutely non-obvious for JS people
<FromGitter>
<faustinoaq> Yeah, I like NameTuples and splatting, maybe we just need better guides and documentation warnings 😅
<FromGitter>
<Papierkorb> If I wanted severe restrictions on what the languages allowed me, I'd use Go
<FromGitter>
<Papierkorb> I don't use Go
<FromGitter>
<paulcsmith> I rarely instanitate a namedtuple but I do use double splat and love it. Though if double splat returned a hash I think it would work just as well in most (all?) of my use cases.
claudiuinberlin has joined #crystal-lang
claudiuinberlin has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
claudiuinberlin has joined #crystal-lang
SurgeR has joined #crystal-lang
<SurgeR>
Why Crystal does not support Windows?
<FromGitter>
<zyriuse75> i guess it's because currently you have little bit more linux server than windows in the companies and also the OS of apple is very close . The Windows architecture is completely different so i think you have to rewrite a lot of code.
<FromGitter>
<zyriuse75> all stop me if i said an error
<SurgeR>
Windows Subsytem for Linux is basically a VM
<FromGitter>
<jwaldrip> @asterite are you around?
<FromGitter>
<jwaldrip> Would you mind adding any pending PRs to the next milestone so that we can have an idea when the next release of Crystal will be cut?
<FromGitter>
<paulcsmith> I think the best bet for using Crystal is to use VirtualBox/VMware with a linux VM
<rkeene>
Moved off the interesting slide now, I'll try to find the slides
<rkeene>
Touches on a lot of Crystal stuff
<FromGitter>
<sdogruyol> thanks @rkeene
<rkeene>
No problem, I'm at the conference right now
<FromGitter>
<asterite> jwaldrip: I'm not in charge of releases
<FromGitter>
<jwaldrip> oh... who is?
<FromGitter>
<asterite> Manas
<FromGitter>
<jwaldrip> Oh, I thought you were with manas.
<FromGitter>
<GrgDev> Hmmm... Crystal's Regex doesn't seem to have the old #last_match from Ruby. Guess I could just extend it or something.
<FromGitter>
<ansarizafar> @asterite NamedTuple is very convenient, specially for developers coming from dynamic languages.
<FromGitter>
<asterite> GrdDev: it's $~
<FromGitter>
<GrgDev> Oh, it's just a global?
claudiuinberlin has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<FromGitter>
<asterite> It's method local
<FromGitter>
<GrgDev> That still works for me. Thanks!
<FromGitter>
<GrgDev> Is there a list of $ variables like that?
claudiuinberlin has joined #crystal-lang
mark_66 has quit [Remote host closed the connection]
<FromGitter>
<asterite> Just $~, $! and $1, $2...
<FromGitter>
<asterite> They are not documented (yet)
<FromGitter>
<GrgDev> Hmmm... speaking of which, is there a method similar to #inspect? And is there a crystal equivalent of IRB to experiment in?
<FromGitter>
<bew> Did you tried #inspect ?
* FromGitter
* GrgDev looks at the docs for #inspect
<FromGitter>
<GrgDev> I am being silly
<FromGitter>
<GrgDev> sorry about that
<rkeene>
Next up at the Tcl conference is the SQLite guy (drh) talking about SQLite... might still be interesting to you guys, but definitely not Crystal
<FromGitter>
<bew> @GrgDev you can play and experiment in `crystal play` or carc.in
<FromGitter>
<bew> There is ICR that looks like a repl, but it's a hack and is not complete
DTZUZO has joined #crystal-lang
<FromGitter>
<GrgDev> I'll have to check that out
SurgeR has quit [Quit: Page closed]
<FromGitter>
<coderhs> Hi there. I was looking through the documentation of NamedTuple to write an article about it in my blog. I came across this example in the doc -> https://crystal-lang.org/api/0.23.1/NamedTuple.html#from%28hash%3AHash%29%3Aself-class-method ⏎ ⏎ where we set `42.as(Int32 | string)`. I am not clear of the purpose of that in that example. As even if we just pass in integer directly or an integer stored in a
<FromGitter>
... variable it would work.
<FromGitter>
<coderhs> was that meant to infer any point?
<Ovius>
The server only ever seems to receive messages if I send them from inside a loop repeatedly
<Ovius>
sending them slowly (as in the above link has no effect, they don't seem to arrive)
<Ovius>
Anyone know WTF is going on?
<jsn->
coderhs, afaics, the purpose is to show you that if we're building a tuple element from a union-type value, it gets narrowed down to the exact type specified by the tuple
<Ovius>
This feels like a crystal bug, I've been going over this code for two hours to no success
<FromGitter>
<coderhs> @jsn- gotcha, i will mention that.
<Ovius>
Some sort of crazy timing bug!?
<jsn->
Ovius, weird, i've seen a similar problem yesterday, but with TCPServer
<jsn->
specifically, s = TCPServer.new(); logger.info "something", s.accept() gives me accept: Invalid argument (Errno)
<jsn->
and logger.info "something"; s = TCPServer.new(); s.accept() works without problems
<Ovius>
This is such a werid bug
oz has quit [Ping timeout: 264 seconds]
<Ovius>
:o
<Ovius>
That's odd too
<jsn->
try with s.puts first, gets later, perhaps? :)
<Ovius>
:o
oz has joined #crystal-lang
<jsn->
at least in my case it's definitely seems like a crystal bug, and it's 100% reproducible both with TCPServer and with UNIXServer
flaviodesousa has quit [Ping timeout: 264 seconds]
<Ovius>
Something very very strange is going on
<Ovius>
I can't replicate it but I swear it started working when I added an empty loop inside a spawn
<FromGitter>
<GrgDev> I'm in the middle of porting a ruby library to crystal and I find a line where they do an inline #extends on the String class. ಠ_ಠ
<Ovius>
And my terminal keeps freezing
<Ovius>
Going for a full restart and a cold shower lol
Ovius_ has joined #crystal-lang
Ovius has quit [Ping timeout: 260 seconds]
<Ovius_>
What the utter fuck
<Ovius_>
So sending a message works, but if I then try to receive a message, the first message doesn't get sent
<Ovius_>
how does this make any sense at all
<Ovius_>
It doesn't even send the first message
<Ovius_>
wtf?!
<Ovius_>
This is an issue even without OpenSSL, I just checked and it happens on normal sockets
<Ovius_>
that's good, will make it easier to reproduce when I create the issue
rohitpaulk has joined #crystal-lang
<Ovius_>
Actually nevermind
<FromGitter>
<HCLarsen> Thanks @drosehn
<FromGitter>
<HCLarsen> I've been playing around with Crystal in my Linux machines, but haven't put it on my Mac yet.
<FromGitter>
<asterite> Obius_: if you can submit reproducible code that shows the bug, that would be great
<Ovius_>
asterite: The issue is that anyone trying to reproduce it would have to setup a CA and certificates and entity stuff which is a pain
kp666[m] has quit [Ping timeout: 240 seconds]
cptaffe has quit [Ping timeout: 240 seconds]
sija[m] has quit [Ping timeout: 240 seconds]
olbat[m] has quit [Ping timeout: 240 seconds]
watzon has quit [Ping timeout: 240 seconds]
jplatte has quit [Ping timeout: 240 seconds]
thelonelyghost has quit [Ping timeout: 246 seconds]
byteflame has quit [Ping timeout: 246 seconds]
dtcristo has quit [Ping timeout: 246 seconds]
<Ovius_>
trying to work out the smallest reproducible amount of code that proves it's broken as fuck
tybee[m] has quit [Ping timeout: 252 seconds]
TheGillies has quit [Ping timeout: 252 seconds]
<Ovius_>
yall having some matrix issues?
Renich has quit [Ping timeout: 255 seconds]
braidn[m] has quit [Ping timeout: 255 seconds]
weston_[m] has quit [Ping timeout: 276 seconds]
<FromGitter>
<drosehn> I wonder if it'd help to follow the write with a `sleep` for a very short amount of time. Something so crystal knows it can switch threads. or fibers, I guess I should say.
<Ovius_>
Nope
<Ovius_>
drosehn: Two second sleep makes no difference
<jsn->
when built with --release, dies on connection attempt most of the time
<FromGitter>
<drosehn> Ah well. It was something of a long-shot guess. I haven't run into problems like this.
rohitpaulk has quit [Ping timeout: 248 seconds]
<Ovius_>
It's a shame
<jsn->
not always, but at least 50% for my tries
<Ovius_>
After quite a while of consideration I picked Crystal to write an orchestration system in
<Ovius_>
and find out that it has a serious language bug before I can even get reliable interconnect
<Ovius_>
just my luck lol
<Ovius_>
guess I'll try .. nim?
<jsn->
well, i tried nim, came to crystal like a week ago, not looking back (still)
<Ovius_>
I mean
<Ovius_>
I'd like to use crystal, it seems nice
<Ovius_>
But it's not quite there yet
<FromGitter>
<OldhamMade> hey all, what's the best way to define a recursively nested type if I'm using alias? for example, if one to create a directory tree
<FromGitter>
<OldhamMade> I'm looking for something like `alias Node = Hash(String, Array(Node))`
<Ovius_>
Nim docs are shocking
<Ovius_>
I feel like I'm just going to end up writing machine code soon
gcds has quit [Remote host closed the connection]
<jsn->
Ovius_, but come one, at least in crystal e.g. UNIXServer mostly works, in Nim you can't even create async unix domain listening socket without jumping through some ridiculous undocumented ugly hoops
<FromGitter>
<asterite> Ovius_: I thought you said it also happens without tls
<Ovius_>
jsn-: Yeah, I just glanced at the docs and noticed that
<Ovius_>
asterite: Unfortunately I was mistaken
<Ovius_>
seems to be related to OpenSSL
<FromGitter>
<asterite> Ah, ok...
<Ovius_>
Actually
<Ovius_>
I'm going to go for rust I think
<Ovius_>
have needed an excuse to learn it
rohitpaulk has joined #crystal-lang
hightower4 has quit [Remote host closed the connection]
rohitpaulk has quit [Remote host closed the connection]
<crystal-gh>
[crystal] HCLarsen opened pull request #5145: Demonstrate Parameters for HTTP::Client (master...master) https://git.io/vd5Vu
Yxhuvud has quit [Remote host closed the connection]
<jsn->
in my real application it also happens to UNIXServer, but I can't reproduce it in minimal test case
<FromGitter>
<opensas> @asterite what would you recommend to use instead of NamedTuples? a struct and the record macro?
<oprypin>
yeah how to reproduce this..
<FromGitter>
<opensas> I still find a bit confusing what structure is more appropriate for each use case
<oprypin>
opensas, others have no context on what you're saying
<oprypin>
if unsure, use a struct
<jsn->
NamedTuple are very tempting because you have such a nice immediate value syntax for that
<FromGitter>
<opensas> sorry, I was talking about this: ⏎ ⏎ > Nevermind. I guess the only way to solve this is by removing NamedTuple from the language, it was probably a mistake. Like double splat. Too ambitious
<jsn->
with struct, you have to declare it, define fields, create a constructor, call the constructor
<oprypin>
jsn-, not if you use `record` macro
<jsn->
with named tuple you just a = {x: 1, b: "something"}
<FromGitter>
<asterite> opensas: probably depends on the use case
<FromGitter>
<opensas> > **<jsn->** with struct, you have to declare it, define fields, create a constructor, call the constructor ⏎ have a look at http://devdocs.io/crystal/api/0.23.0/toplevel#record(name,*properties)-macro
DTZUZO_ has joined #crystal-lang
<jsn->
yeah, thanks, didn't know about that; that's definitely an improvement (perhaps worth adding to the book?), but still a bit more clunky than named tuples
DTZUZO has quit [Ping timeout: 255 seconds]
<FromGitter>
<paulcsmith> @opensas Wow thanks for posting. The docs look great there and the methods are searchable. Nice!
<Yxhuvud>
named tuples have a lot of competition with regular tuples, hashes, records etc. It does some things neither does as well as it does, but the overlapping of functionality make it quite seldom tehy are actually useful.
<FromGitter>
<opensas> I usually use NamedTuples to temporally store related values into something nicer and easier to follow than an array, and pass them around as methods parameters. Having named keys makes them auto-documented
<jsn->
also, named tuple have nice immutability; array_of_structs[1].field += 1 seems to be a silent error now (not sure), but array_of_tuples[i][:field] = 1 is a very loud error (right?), which is good
<jsn->
[:field] syntax in named tuples bothers me, though
<oprypin>
yep that's terrible
<jsn->
other than that, i actually like them
<FromGitter>
<opensas> > @opensas Wow thanks for posting. The docs look great there and the methods are searchable. Nice! ⏎ ⏎ yeah, devdocs is pretty cool, one tip: I bookmarked ´´´http://devdocs.io/#q=cr%20%s´´´ with the "cr" keyboard and I only have to type "cr record" in the browser address bar to get directly to the documentation
<oprypin>
asterite yeah programming is the one exception
<FromGitter>
<OldhamMade> easy to know what is what there, whereas one could forget which order the second's args should be in without looking up the definition
<oprypin>
OldhamMade, you realize you could write `Person.new(room_number: 1, name: "bob", age: 26)` ?
<oprypin>
or how about `Person.new("bob", room_number: 1, age: 26)` ?
<FromGitter>
<OldhamMade> ah, no -- but then that's not clear in the docs
<oprypin>
i mean,... docs of one feature are not obligated to document all related syntax
<FromGitter>
<OldhamMade> agreed
<oprypin>
it does have `Point.new y: 2` tho
<oprypin>
(i still dont know how people justify omitting brackets in `new` call)
<FromGitter>
<OldhamMade> heh, I definitely agree with that statement :D
<Yxhuvud>
I always use brackets if I care about the return value, which I typically do when it comes to calls to 'new'
<FromGitter>
<OldhamMade> oh... records don't have a `to_json` like hash, namedtuple, etc...
<oprypin>
yeah it's not a core defining feature of records. besides, json is not required by default
claudiuinberlin has quit [Quit: My MacBook has gone to sleep. ZZZzzz…]
<FromGitter>
<OldhamMade> true. I'm just playing about with it. currently I'm trying to define a tree of items, recursively... seems you can define this recursively with a record, but since I can't cast it to json to return via an API, looks like I'm back to defining some other structure
<oprypin>
OldhamMade, `struct` with `JSON.mapping` is also very easy
<FromGitter>
<OldhamMade> eg `record Node, name : String, children : Array(Node)` seems to work
jokke has quit [Quit: WeeChat 1.9]
fryguy9 has joined #crystal-lang
fryguy9 has quit [Client Quit]
jokke has joined #crystal-lang
<crystal-gh>
[crystal] funny-falcon opened pull request #5146: Alternative hash function (master...althasher) https://git.io/vd5D9
claudiuinberlin has joined #crystal-lang
<FromGitter>
<Papierkorb> Ovius_, that doesn't look like a bug to me at all. The main fiber quits before the sockets buffer may have been written.
<FromGitter>
<Papierkorb> Oh with OpenSSL? Yeah that has another buffer layer built-in.
<oprypin>
Papierkorb, i suspect that adding a sleep would not help
<FromGitter>
<Papierkorb> ... What about a good old fashioned flush?
<oprypin>
have u seen the actual error?
<FromGitter>
<Papierkorb> Not in the logs, no, didn't say there was an error
<oprypin>
i wrote it in my message
<oprypin>
soon after
<FromGitter>
<Papierkorb> Just that the process "dies" after a connection attempt. Well, from that minimal example, yes, it should exit basically right away after accepting the connection.
<oprypin>
but it exits before, according to the error
<FromGitter>
<Papierkorb> Oh that bug. I'm hitting it too in a custom HTTPServer tool.
<oprypin>
and the error also does not reproduce on latest Crystal. suspiciously after there was a bug fix in libc accept call
<RX14>
didnt we fix that bug
<FromGitter>
<Papierkorb> I didn't put much time into it just yet
<oprypin>
RX14, you fixed *a* bug
<FromGitter>
<Papierkorb> On master you mean RX14?
<RX14>
no oprypin
<RX14>
i broke it
<RX14>
someone else fixed it
<RX14>
the accept errno
<RX14>
iirc
<RX14>
it's fixed on master
<oprypin>
lol ok
<RX14>
oh wait no
<RX14>
that bug was introduced on master too
<RX14>
i'm 90% sure
<RX14>
99%
<RX14>
so idk
<oprypin>
but it was certainly very bad before you even touched it
<RX14>
hmm
<RX14>
bisect it
<FromGitter>
<Papierkorb> But hopefully it's fixed in the next release that hopefully happens soon
<oprypin>
so maybe this is the manifestation of the theoretical failure we were trying to come up with
<RX14>
i love a good automated bisect
<FromGitter>
<Papierkorb> That bug alone would deserve a patch release
<oprypin>
i tried bisecting but it does not reproduce reliably
<RX14>
:(
<FromGitter>
<Papierkorb> Yeah I get it about 1 in 10 attempts only
<FromGitter>
<Papierkorb> Well, "only", 10% is still quite large
<RX14>
so run it 100 times :)
<oprypin>
like u need to spawn 2 processes one of which hangs and check for a crash and do that many times
<RX14>
all the more reason to script it
<oprypin>
my for loop hung
<FromGitter>
<Papierkorb> There should be specs that do such sanity checks. Just try to create 1k connections in various combinations
<RX14>
sure, write them.
<FromGitter>
<Papierkorb> I'm right now not convinced I should contribute directly to crystal. I'm not looking for a "Nah" closed comment, or PRs laying there for months
<oprypin>
that's the spirit
<FromGitter>
<mixflame> do you guys recommend any SMTP mailer service besides sendgrid? Or am I just being dumb and should use sendgrid? It had bugs last tie I tried
<FromGitter>
<Papierkorb> It depends on what exactly you're looking for. You can always use your own local SMTP if you use your own mail server already anyway.
<FromGitter>
<mixflame> I don't. I am starting a Crystal consultancy (ruby too) and I just want to send messages to me through my site with SMTP.cr
<FromGitter>
<mixflame> ive never been able to set up SMTP successfully or run any mail servers
<FromGitter>
<Papierkorb> There's also mailchimp. But I've never tried/used neither sendgrid nor mailchimp
<FromGitter>
<mixflame> sendgrid is good when it works. their mailer was broken last time... I could try mailchimp
<FromGitter>
<Papierkorb> Have you tried contacting their customer services?
<FromGitter>
<mixflame> no I didn't. that's a good ide
<FromGitter>
<mixflame> idea*
<Yxhuvud>
we use sendgrid at work. It works. But our setup is way above and beyond what most people need.
<Yxhuvud>
perhaps there are simpler alternatives
DTZUZU has quit [Ping timeout: 248 seconds]
DTZUZU has joined #crystal-lang
<crystal-gh>
[crystal] asterite opened pull request #5147: Playground: missing instrumentation of HashLiteral (master...bug/4670-fix-hash-playground) https://git.io/vd55t
<Yxhuvud>
threads like the siphash thread makes me wish for default types to generics. default to one implementation but allow the other easily.
<crystal-gh>
[crystal] funny-falcon opened pull request #5148: Make Array to be workable as a queue, ie respect push+shift pattern. (master...array_queue) https://git.io/vd5bc
<RX14>
well hopefully it wont be surprising for much longer
<oprypin>
RX14, what, everyone will suddenly learn the basics of computer science?
<jsn->
no, they'll make it (almost) O(1), violating the basics of computer science, just like ruby does
<RX14>
>violating the basics of computer science
<RX14>
no just using another data structure
<jsn->
obviously :)
<RX14>
not that we;ll ever hange Array(T) to List(T) or Vec(T)
<RX14>
change*
<FromGitter>
<asterite> In my mind it's ok for Array#shift to be O(n). It's like doing array.insert(pos, value) and asking "what, that's o(n)? but that could be O(1) if it were implemented with rops"
<FromGitter>
<asterite> *ropes
* jsn-
is actually fine with Deque, just spoiled by ruby
<RX14>
sure it's fine but if it's so easy...
<oprypin>
inb4 30 comments and PR closed
<FromGitter>
<asterite> I actually think funny falcon's PR is ok and we could merge it. I still have my worries about 4 more bytes per each array, but I don't know if that's something to worry about
<RX14>
30?
<RX14>
more like 300
<FromGitter>
<asterite> I mean, 4 bytes in every array just to optimize shift
<RX14>
eh
<oprypin>
asterite, it does not change `shift` in any way, how does that work?
<RX14>
uhh yes it does oprypin
<RX14>
i can see the diff right now
<oprypin>
right, github is just terrible
<RX14>
@asterite isn't it 8 bytes?
<RX14>
since it's an extra pointer
<FromGitter>
<asterite> Oh, right! :-o
<jsn->
i have this silly question about about implementing something like bytecode dispatch in crystal, something like loop { case next_op ... end }
<RX14>
tbh we should store a i32 offset where we realloc(@buffer - offset)
<RX14>
which keeps the diff small since @buffer has no change of meaning
<RX14>
but also we avoid the extra 4 bytes
<oprypin>
ah yes, let the bikeshed begin
<RX14>
but really im not sure if it matters
<FromGitter>
<Papierkorb> So .. if they want a queue type of thing .. why don't they use a data structure that's suitable for that?
<RX14>
we already do a 2-dereference to even get to the array
<oprypin>
cuz ruby lol
<jsn->
currently, when i do this, CPU branch predictor in loop / case is completely useless. can something be done about it? (like nim's .computedGoto. pragma or something)?
<RX14>
oprypin, look at that diff
<RX14>
isn't it so innocent?
<oprypin>
i made my prediction
<RX14>
but bikeshedding is so fun
<oprypin>
yeah i like it in most cases
<RX14>
except we happen to be wanting to get stuff done
<oprypin>
i confused myself. this optimization divides the complexity by a constant but the constant happens to be log(N) ?
<RX14>
jsn-, we typically leave optimizations up to LLVM
<oprypin>
better admit i have no idea what i'm talking about
<jsn->
RX14, yeah, but it doesn't do anything in this case. if there were gotos in crystal, i could use that, but there aren't any
<jsn->
my current best implementation uses crystal's tail call elimination as a poor man's goto, and it does the job done, but sure doesn't look pretty
<oprypin>
jsn-, so please use `case`/`when` and make sure that each branch is integer-equivalent
<FromGitter>
<Papierkorb> a `case` with simple cases should be turned into a jumptable (Not that I've checked)
<oprypin>
jsn-, there is no tail call elimination
<jsn->
oprypin, i did that, performance with loop / case is still worse
<RX14>
yes there is oprypin
<jsn->
oprypin, you're wrong, there is TCE, only in --release :)
<RX14>
its just heuristic based
<RX14>
instead of reliable
<RX14>
LLVM has heuristics of how to compile switch statements jsn-
<jsn->
llvm does that, i suppose
<FromGitter>
<Papierkorb> jsn-, also, have you profiled this? iirc, intel has tools that can collect branch prediction behaviour
<RX14>
you're stuck with those
<oprypin>
jsn-, proof of "performance with loop / case is still worse" pls
<RX14>
i guess llvm wont compile that to a jump table
<oprypin>
jsn-, ok you convinced me at least about validity of what you're comparing
<RX14>
those macros tho
<RX14>
surely methods taking ins would get inlined
<RX14>
and be essentially the same speec
<RX14>
and be essentially the same speed
<jsn->
well, it's tedious to write all that stuff repeatedly by hand
<oprypin>
"methods taking ins"?
<RX14>
jsn-, i mean literally replacing your macros with methods
<RX14>
and trusting them to be inlined
<oprypin>
well we just wrongly suggested to trust some other thing
<jsn->
RX14, ah, perhaps; they are macros because initially i wanted to have lvalue macros
<jsn->
like private macro c; ins & 7; end
<jsn->
like private macro c; r[ins & 7]; end, sorry
<jsn->
so you could c = a + b, or something
<oprypin>
eek
<jsn->
unfortunately, apparently crystal can't do that
<oprypin>
whew
<RX14>
thats very fortunate
<jsn->
:)
<RX14>
that crystal prevents you from creating abominations
<jsn->
well, perhaps you shouldn't look at c/goto.c then :)
<RX14>
jsn-, just for info
<RX14>
what processor are you running on
<jsn->
model name : Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
<RX14>
ok
<RX14>
upgrade to haswell
<RX14>
switch will be the same speed
<RX14>
intel fixed their indirect jump branch predictor
<RX14>
:)
<jsn->
yeah, i heard they did improve that a bit
<jsn->
let's see
<RX14>
try a VPS
<RX14>
or some newer dedi
<oprypin>
maybe carc.in lol
<RX14>
pls
<RX14>
you cant do --release there
<oprypin>
oh :/
<jsn->
no, i don't have haswells around, apparently
<jsn->
anyone?
<RX14>
oh yeah i do
<RX14>
my laptop is 7th gen
<RX14>
i forgot lol
<crystal-gh>
[crystal] asterite opened pull request #5149: Compiler: don't type generic type instance var initialization on non-instantiated generics (master...bug/4291-generic-type-initialization) https://git.io/vddfu
<RX14>
but i guess the results are multiple seconds different
<RX14>
so its fine
<jsn->
crystal's results also vary a lot
<jsn->
like, +- second or more
<RX14>
gc?
<RX14>
hmm
<jsn->
so, no use for precision
<RX14>
try GC_DONT_GC=true
<jsn->
it will get out of memory then?
<RX14>
idk, do you allocate much?
<jsn->
this thing allocs *alot*
<RX14>
surely you're benchmarking the memory management
<RX14>
not the loop so much
<RX14>
idk
<jsn->
no, see the readme
<jsn->
especiall the C part
<jsn->
also, the difference between switch.cr and tail-call.cr
<FromGitter>
<asterite> ``` r = StaticArray(UInt32, 8).new(0_u32)```
<FromGitter>
<asterite> Well, I wanted to write two lines...
<FromGitter>
<asterite> Using `r = StaticArray(UInt32, 8).new(0_u32)` instead of `r = Array.new 8, 0_u32` improves it by 7 seconds in my case
<jsn->
total time may be very well dominated by memory allocations, but i do care about dispatch efficiency, and it makes some difference
<RX14>
i guess C doesn't do (as many) bound checks as crystal does too?
<jsn->
asterite, wow! yeah, definitely an improvement, thanks! not 7 seconds, but about 2 in my case
<RX14>
jsn-, guess what
<jsn->
[tail-call]
<RX14>
C goto was 18.186
<RX14>
C switch was 16.820
<jsn->
RX14, thanks, very interesting
<oprypin>
RX14, and C switch here is equivalent sequence of ifs anyway?
<RX14>
i havent looked at how it's compiled
<oprypin>
cpus are crazy. just read about branch prediction and pipeline
<RX14>
yeah
<RX14>
watching the mill CPU talks was very enlightening
<oprypin>
if it is a sequence of ifs, would it mean it does branch prediction nested several levels deep?
<RX14>
it taught me a lot about old CPUI architecture while showing you a cool new interesting one
<jsn->
oprypin, it doesn't care about levels, i think, only about the location of branch instruction
<RX14>
the problem with branch prediction and case statements is that it predicts on every branch
<RX14>
whereas a case can only exit once
<RX14>
and so the best branch precition would be to predict which branch was taken
<RX14>
so you can mispredict more then 2 times
<RX14>
jsn-, crystal switch is 23.8 ish
<RX14>
crystal tco is 29.8
<jsn->
with or without asterite's patch?
<RX14>
uarch makes a huge difference here
<RX14>
without
<oprypin>
Papierkorb, i just realized that your usage of bindgen_likely is likely a performance disadvantage
<jsn->
thanks!
olbat[m] has joined #crystal-lang
<oprypin>
Papierkorb, actually nevermind, i confused it with something else. cant be a performance disadvantage if the misprediction can literally happen only once
<RX14>
jsn-, thats with no thermal throttling at 3.1Ghz
<RX14>
and a free core
<RX14>
so it's likely close to utilizing 1 core 100%
<RX14>
i.e. there's likely very little randomness in timings due to other factors
<jsn->
tail-call is obviously a bit more heavy in other parts, so if branch prediction is working for both, tail-call should be worse
<RX14>
i consistently get within 0.5s between multiple runs
<RX14>
jsn-, looks like you need a new laptop lol
<jsn->
RX14, no way :) a new colo box is not completely out of the question, though :)
<RX14>
its so interesting how much faster it is
<RX14>
22.5 vs 18s
<jsn->
well, on my laptop now switch.cr is 41 seconds, tail-call.cr is 38 seconds
<RX14>
thats like a 20% improvement
<RX14>
and your processor has a 100Mhz advantage on turbo frequency
<RX14>
those small ipc improvements really add up
<jsn->
btw, on my laptop both versions seems to jump from core to core all the time
<RX14>
sure
<jsn->
but that doesn't happen for e.g. C versions
<jsn->
why?
<RX14>
the GC is multithreaded
<jsn->
ah
<jsn->
yeah, i had to use GOMAXPROC=1 or something to get good results from golang versions