ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.34.0 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
ur5us has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 240 seconds]
<FromGitter> <watzon> Ok shouldn't this `"Abc_one_two_three".gsub(/_(\w)/, "\\1".upcase)` return `"AbcOneTwoThree"`? It doesn't, and I'm wondering why not.
<FromGitter> <watzon> Maybe there's a better way to do this, but I basically just want to replace any underscore + letter with a capital letter
<FromGitter> <tenebrousedge> `"\\1".upcase` isn't a proc
<FromGitter> <tenebrousedge> it's an upcased string
<FromGitter> <tenebrousedge> pass a block
<FromGitter> <Blacksmoke16> Isn't that what camelcase is
<FromGitter> <tenebrousedge> plus I think you want `capitalize`
<FromGitter> <Blacksmoke16> Naw, camelcase
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/String.html#camelcase(options:Unicode::CaseOptions=Unicode::CaseOptions::None,*,lower:Bool=false)-instance-method
<FromGitter> <tenebrousedge> is there a method for that?
<FromGitter> <tenebrousedge> huh
<FromGitter> <tenebrousedge> oh boy
<FromGitter> <tenebrousedge> well, maybe that implementation is faster :/
<FromGitter> <tenebrousedge> `"Abc_one_two_three".gsub(/_(\w)/) { $1.capitalize }`
<FromGitter> <tenebrousedge> or `str.split('_').join(&.capitalize)`
ur5us has quit [Remote host closed the connection]
ur5us has joined #crystal-lang
<FromGitter> <watzon> Forgot that `gsub` took a block
<FromGitter> <tenebrousedge> `head` also takes a block
alexherbo2 has joined #crystal-lang
_ht has joined #crystal-lang
ur5us has quit [Ping timeout: 256 seconds]
_whitelogger has joined #crystal-lang
ur5us has joined #crystal-lang
zorp has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> hey
<oprypin> ImAHopelessDev_gitlab, have you seen it yet? :D
<FromGitter> <gdotdesign> hi
<FromGitter> <gdotdesign> I'm looking for intersperse method for arrays but I cannot find one, is there one with an other name or it's just not in the stdlib?
<FromGitter> <ImAHopelessDev_gitlab> 4:34 LOL :D
<FromGitter> <grkek> oprypin thats some wonderful news
<oprypin> :>
<FromGitter> <grkek> Props to you for such nice work
<FromGitter> <ImAHopelessDev_gitlab> wow, linking crsfml is nice. this is a great foundation
<FromGitter> <ImAHopelessDev_gitlab> i just installed the vs build tools last night too (had to fiddle around with some godot source code). this is like perfect timing. i'm pumped to fiddle around with this all day, thanks @oprypin !
<jhass> gdotdesign: what exactly would that do?
<FromGitter> <gdotdesign> it's like `join` but not just for string
<jhass> I don't think we have that in stdlib, no
<jhass> https://carc.in/#/r/8xlt easy enough to roll your own
<jhass> not sure I got all the edge cases in that one yet
alexherbo29 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 256 seconds]
alexherbo29 is now known as alexherbo2
<FromGitter> <ImAHopelessDev_gitlab> https://i.gyazo.com/70f94125c21de06fe6e6dd6f9af1e01b.png following the tutorial exactly. did i miss a step?
<oprypin> ImAHopelessDev_gitlab, whats in the "crystal" directory
<FromGitter> <gdotdesign> thanks :)
<oprypin> ImAHopelessDev_gitlab, i dont know lol, all looks correct
<oprypin> presumably 'src\prelude.cr' exists?
<FromGitter> <ImAHopelessDev_gitlab> yah lol
<FromGitter> <grkek> hopeless x2
<FromGitter> <ImAHopelessDev_gitlab> lmao!
<oprypin> what is going on :o
<FromGitter> <grkek> Idk I am upgrading my framework, decided to use HTTP::Server::Response
<FromGitter> <grkek> as the return type of an endpoint
<FromGitter> <grkek> makes it more flexible instead of using just strings
<oprypin> ImAHopelessDev_gitlab, just did the same thing and it works https://i.imgur.com/Ly6wAaE.png
<oprypin> ImAHopelessDev_gitlab, could you run `crystal env` to see
<FromGitter> <ImAHopelessDev_gitlab> ROFL
<FromGitter> <ImAHopelessDev_gitlab> I was using this https://github.com/faustinoaq/crystal-windows-installer
<oprypin> ah shit
<FromGitter> <grkek> HOPELESS
<FromGitter> <ImAHopelessDev_gitlab> i renamed it to crystal2.exe ALL WORKING
<FromGitter> <ImAHopelessDev_gitlab> HELL YAH
<FromGitter> <ImAHopelessDev_gitlab> AWESOME
<oprypin> ImAHopelessDev_gitlab, good job figuring that out
<jhass> could update the instructions to do PATH=foo;PATH to shadow stuff like that
<FromGitter> <ImAHopelessDev_gitlab> @oprypin ;)
<oprypin> jhass, welp it's too late now, it's all in the video
<jhass> still could catch all the copy pasta people
<FromGitter> <grkek> Can you unpack a hash?
<jhass> kinda? https://carc.in/#/r/8xm1 :D
<jhass> don't do this
<FromGitter> <grkek> Why not?
<jhass> the feature was intended like that, it's just abusing an implementation detail
<jhass> *was not, duh
<FromGitter> <grkek> Yeah, I see
<FromGitter> <grkek> as fast as I change the int to string
<FromGitter> <grkek> it fails
<jhass> yeah, since a, b = c is really just a syntax level rewrite to a = c[0]; b = c[1]
<jhass> what would you expect the result to be anyhow with string keys?
<FromGitter> <grkek> I wanted something like the elixir pattern matching
<FromGitter> <ImAHopelessDev_gitlab> i tried elixir, then took an arrow to the brain. i can't comprehend functional languages :(
<FromGitter> <grkek> It is really comfy
<FromGitter> <ImAHopelessDev_gitlab> i don't understand how objects and states exist. in crystal, we have a class/struct/hash to hold values. in those languages, i can't comprehend what holds what, it seems like nothing holds anything and it's just functions returning values 24/7.
<yxhuvud> I think that is the point!
<FromGitter> <grkek> That sums it up 90% of the time
<FromGitter> <grkek> You just push data around until you get results
<FromGitter> <alex-lairan> Hi ! ⏎ I need to create an IO that will not be flushed at \n ⏎ I need exactly the same behavior as `IO::Memory` ⏎ What can I do ? [https://gitter.im/crystal-lang/crystal?at=5ea00a3ba361221083967d9b]
<FromGitter> <grkek> Does \n really flush it?
<FromGitter> <ImAHopelessDev_gitlab> that's where my brain goes blank. let's say you have a player, they need to store `user_id`, `x`, and `y` values. throw in an inventory too (2d array). how in the world do you keep track of that stuff if you're in a quantum vacuum of functions
<FromGitter> <grkek> if yes can you link the source where you found that?
<FromGitter> <alex-lairan> @grkek it don't know, but I have ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ea00b437e8b826dab2f49de]
<FromGitter> <alex-lairan> The `output_catcher.gets_to_end` returns me `""`
<FromGitter> <alex-lairan> I need for testing purposes
<FromGitter> <grkek> If it returns "" it means it doesn't work right?
<FromGitter> <alex-lairan> it doesn't work like I want yes
<FromGitter> <alex-lairan> If I remove `\n` I get the input
ur5us has quit [Ping timeout: 240 seconds]
<FromGitter> <grkek> .to_s function works
<FromGitter> <grkek> seems like
<FromGitter> <grkek> just use .to_s instead of gets_to_end
<raz> alex-larain: you need to .rewind the IO::Memory before reading from it
<raz> it is implemented on top of cassette types
<raz> :P
<FromGitter> <grkek> it works as well but yeah
<FromGitter> <grkek> to_s must be doing the same?
<FromGitter> <grkek> I guess
<FromGitter> <naqvis> `IO::Memory` should be `rewind` before getting back the data
ur5us has joined #crystal-lang
<FromGitter> <naqvis> ```output_character.to_s``` [https://gitter.im/crystal-lang/crystal?at=5ea00e5868c6dd2fbca5a21e]
<FromGitter> <alex-lairan> Thank you ! It works now :)
<FromGitter> <naqvis> np
<FromGitter> <alex-lairan> I will use the `to_s`
<FromGitter> <grkek> I win B-)
<FromGitter> <naqvis> lol
<FromGitter> <grkek> How does one use crystal tool expand to expand macros ?
<FromGitter> <grkek> I keep on trying and it wont work
<FromGitter> <naqvis> you need to point to the line and colum where you are invoking that macro
<FromGitter> <grkek> ah
<FromGitter> <grkek> aight
ur5us has quit [Ping timeout: 252 seconds]
<FromGitter> <grkek> Does this look horrible :D ?
<FromGitter> <grkek> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ea0142c35a35031bf7b6197]
<FromGitter> <ImAHopelessDev_gitlab> to me, yes
<FromGitter> <grkek> It is a functional nightmare
<FromGitter> <grkek> Each function can be used separately to return a result
<FromGitter> <grkek> Halt can return, headers can return, json can return
<FromGitter> <ImAHopelessDev_gitlab> nodejs: callback hell! ⏎ nested parentheses: hold my beer!
<FromGitter> <grkek> it makes it more flexible
<FromGitter> <grkek> :D
<FromGitter> <grkek> Well it looks fine by me if users will be able to chain function calls that would be beneficial in the end
<FromGitter> <ImAHopelessDev_gitlab> i'm very picky with code. you could say, hopeless
<FromGitter> <grkek> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5ea0168c312a2d132c295efe]
<FromGitter> <grkek> in fact you can do that
<FromGitter> <grkek> and you get what
<FromGitter> <grkek> LISP
<FromGitter> <grkek> that is correct
<FromGitter> <ImAHopelessDev_gitlab> oh god
<FromGitter> <alex-lairan> Dude, you just broke the internet :p
<FromGitter> <grkek> It's basically functions with the same return type just recursing into eachother
<FromGitter> <grkek> You can call it function orgy if you want to
<FromGitter> <ImAHopelessDev_gitlab> sounds like a possible new fetish
<FromGitter> <grkek> MMM OH YEAH RECURSE RIGHT THERE OOOH IM COOOMING
<FromGitter> <grkek> just about right
<FromGitter> <ImAHopelessDev_gitlab> rofl
<FromGitter> <naqvis> rofl
<FromGitter> <ImAHopelessDev_gitlab> "can you go get that abstract lube bottle, honey? thanks", i need some pattern matching and recursive down there, i'm about to statically allocate some structs. we can use the heap later
<FromGitter> <grkek> Jesus man
<FromGitter> <ImAHopelessDev_gitlab> .. we really need to clean up all this memory the gc left behind
<FromGitter> <grkek> COME ON MAN
<FromGitter> <ImAHopelessDev_gitlab> 😆
<FromGitter> <naqvis> girng you are a genius lmao
<FromGitter> <naqvis> rofl
<FromGitter> <grkek> All of this context switching is hurting my back :^)
<FromGitter> <ImAHopelessDev_gitlab> LOL
alexherbo2 has quit [Quit: The Lounge - https://thelounge.chat]
<FromGitter> <naqvis> 😆
<FromGitter> <grkek> We are literally 5 y.o's
<FromGitter> <ImAHopelessDev_gitlab> i'm bored, don't got work until 17 more hours
<FromGitter> <ImAHopelessDev_gitlab> well, i will go to bed in about 10 hours
<FromGitter> <grkek> might as well oppress the minorities
<FromGitter> <grkek> eh?
<FromGitter> <ImAHopelessDev_gitlab> iuno
<FromGitter> <grkek> eh?
<FromGitter> <grkek> commit war crimes
<FromGitter> <ImAHopelessDev_gitlab> i can't, i'm statically allocated
<FromGitter> <grkek> Ill go and de-alocate my bladder :)
<FromGitter> <ImAHopelessDev_gitlab> good idea, don't want a memory leak :)
<FromGitter> <ImAHopelessDev_gitlab> or.. a dependency injection might hurt as well, be careful!
alexherbo2 has joined #crystal-lang
<FromGitter> <grkek> Imagine non-programmers reading this shit going like "what in the fuck?"
<FromGitter> <ImAHopelessDev_gitlab> hahahaha
<FromGitter> <grkek> cya later mr hopeless
<FromGitter> <ImAHopelessDev_gitlab> ttyl @grkek
<FromGitter> <rishavs> Talking of functional programming, here's a gem I just found in the f# subreddit :D ⏎ https://www.youtube.com/watch?v=ADqLBc1vFwI&feature=youtu.be
tane has joined #crystal-lang
MasterdonX has quit [Ping timeout: 256 seconds]
masterdonx2 has joined #crystal-lang
zorp has quit [Ping timeout: 256 seconds]
rocx has joined #crystal-lang
zorp has joined #crystal-lang
<oprypin> straight-shoota: did u really just rebase 10 commits and force push instead of simply merging
<FromGitter> <straight-shoota> yes
<FromGitter> <straight-shoota> why not?
<FromGitter> <straight-shoota> IMO the changes are easier to track that way
<FromGitter> <ImAHopelessDev_gitlab> :D :D :D Crystal time all day today
<oprypin> @straight-shoota: no they're not?
<oprypin> you literally change what some other user made and now we're supposed to trust you that it's the same
<oprypin> a merge conceptually represents what's happening. rebase is like doing 10 merges and discarding the originals
<FromGitter> <naqvis> Just posted crystal-fnv (https://github.com/naqvis/crystal-fnv). Crystal implementation of Fowler–Noll–Vo hash (FNV) hash. Provide 32, 64 and 128bit implementation of FNV-1 and FNV-1a ❤️
<FromGitter> <ImAHopelessDev_gitlab> interesting @naqvis !!!
<FromGitter> <straight-shoota> Yeah, conceptually that's right. But I find it hard to track in the GitHub UI. The changes are supposed to be applied on current master, not on some ancient state.
<FromGitter> <naqvis> thanks Girng
<FromGitter> <straight-shoota> An insanely huge diff and you can't tell which parts of the changes are simply representing the advanced head and what's merge conflict resolution. With rebase the conflict resultion is in every single commit which can be compared to the previous commit before the rebase, if you want to verify.
<FromGitter> <straight-shoota> But I actually don't think attribution matters much. The PR needs to be approved in total, no matter who wrote the changes. And it will be squash merged an attribute both the original author and me.
<FromGitter> <j8r> Good job @naqvis — always ready to crush new algos 😮
<FromGitter> <j8r> You know, you can just put all *.cr file in `src/`
<FromGitter> <naqvis> thanks @j8r
<FromGitter> <naqvis> yeah true, but i kind of like organizing files in sub-folders 😆
<FromGitter> <naqvis> just a personal preference
<FromGitter> <j8r> Lol – you're the boss of your projects at the end :P
<FromGitter> <naqvis> lol
<FromGitter> <j8r> May intereset @ImAHopelessDev_gitlab – I won't use it yet
<FromGitter> <j8r> Just use raw UDP, then see for further optimizations
<FromGitter> <naqvis> sounds interesting, won't hurt to look into the details of how they have achieved the reliability of tcp over udp
<FromGitter> <ImAHopelessDev_gitlab> I gave my life to TCP a few years ago
disruptek has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> why use UDP when i can just take a plane to the recipient's house? *taps head*
<FromGitter> <tenebrousedge> the best thing about UDP jokes is I don't care if you get them
<FromGitter> <ImAHopelessDev_gitlab> LOL!
<disruptek> i need to make a desktop app similar to adobe premiere but with higher performance and low memory footprint with gui as beautiful as premiere. this would be the only selling point for us. this would be my first cross platform desktop app development and i don't want to fail. seeking help. please guide me.
<FromGitter> <Blacksmoke16> https://i.imgur.com/XbC0BXZ.jpg
<disruptek> trying to decide between crystal, v, and reason
<FromGitter> <tenebrousedge> I would give up on that idea, honestly, but Crystal is not your answer
<FromGitter> <Blacksmoke16> not give up*?
<disruptek> i'm not prepared to give up.
<FromGitter> <Blacksmoke16> GUI libs are deff lacking in crystal land
<disruptek> we need to do the editing on desktop, save it to the cloud, and then apply ai to it.
<FromGitter> <tenebrousedge> also cross platform support
<disruptek> is crystal a good choice?
<FromGitter> <tenebrousedge> no
<FromGitter> <ImAHopelessDev_gitlab> if i were you, i'd use winforms with visual basic, then bind it to rust
<disruptek> what are my options for gui?
<FromGitter> <Blacksmoke16> that thread goes over the current state of things, id read thru that
<FromGitter> <tenebrousedge> Windows support is also mostly aspirational at this point
<disruptek> we will have a large team of developers.
<FromGitter> <Blacksmoke16> are always free to try to put together a prototype to see how things go
<disruptek> my job is to choose the tech stack.
<FromGitter> <Blacksmoke16> but GUI + windows im not sure will fair to well
<FromGitter> <Blacksmoke16> too*
<disruptek> it needs to have a low memory footprint as well.
<disruptek> i5 cpu with 8gb of memory.
<FromGitter> <Blacksmoke16> well to be clear, crystal doesnt fully support windows atm. so if thats a requirement then its a non starter
<disruptek> it's okay; we expect development to take at least 6 months.
<FromGitter> <tenebrousedge> okay, so I did laugh out loud at that
<FromGitter> <Blacksmoke16> im happy you want to/are looking into using Crystal, but assuming windows will be supported fully in 6months is unfortunately not really realistic
<FromGitter> <Blacksmoke16> maybe it will, but who knows
<FromGitter> <Blacksmoke16> but for if a good GUI lib and window are requirements for your project, i just dont think its the best option
<disruptek> what should i use?
<jhass> > We gonna be better than adobe in one of their core products that they have 30 years experience on. In 6 months.
<jhass> I'm sorry, but...
<FromGitter> <Blacksmoke16> i dont know, thats your job to figure out :p
<FromGitter> <Blacksmoke16> does go have any good ui libs?
<FromGitter> <naqvis> nah, go touts itself more on server side, that's why major player in cloud world are built on top of golang
<FromGitter> <ImAHopelessDev_gitlab> not sure why you just don't write this in html 5 and ship it with electron
<FromGitter> <naqvis> Girng, electron, seriously lol
<FromGitter> <tenebrousedge> that's probably not a high-performance path
<FromGitter> <Blacksmoke16> other requirement was low memory usage :trollface:
<FromGitter> <ImAHopelessDev_gitlab> give your developers a run for their money
<FromGitter> <tenebrousedge> the best option is probably to use C++, which is what Adobe did
<FromGitter> <tenebrousedge> there is no best option for duplicating the 30 years of work that went into that codebase though
<FromGitter> <naqvis> agree and use any of the GUI toolkit as almost all of them are built on C/C++
<FromGitter> <tenebrousedge> this is a terrible idea and a waste of whoever's money is funding it
<FromGitter> <tenebrousedge> but if the money is already committed and the developers are hired, pick whatever technology you want to work with at your next job
<FromGitter> <ImAHopelessDev_gitlab> @Blacksmoke16 Actually, the more memory an application uses means it has higher performance. This is why a lot of AAA games are shipped with Electron, and also high quality IDEs like VSCode too. (backed by a multi-billion-dollar company)
ht_ has joined #crystal-lang
_ht has quit [Ping timeout: 256 seconds]
ht_ is now known as _ht
<oprypin> [17:22:25] <0099cc@straight-shoota> that's what I mean: https://github.com/crystal-lang/crystal/commit/628e339a4e03c4d2bfe6a64eea4e24a280620d4a
<oprypin> -no that's just a bad way to view it. use https://github.com/crystal-lang/crystal/compare/master...628e339a4e03c4d2bfe6a64eea4e24a280620d4a - that's also how it will show in the PR
<FromGitter> <watzon> I hope LibUI keeps going strong. It would be nice to have a sane, cross platform GUI lib.
<FromGitter> <tenebrousedge> low memory use is not necessarily correlated with performance, but saying higher memory use == higher performance is overstating the case somewhat
<oprypin> i am surprised though. github has a condensed view of merges but for some reason it's not kicking in there
<FromGitter> <ImAHopelessDev_gitlab> i'm trolling lol
<oprypin> the condensed view would show *at most* the files that were changed in both master and that branch
<FromGitter> <tenebrousedge> ah. Well VSCode is a pretty good editor, but what's the saying about pigs and sufficient thrust?
<FromGitter> <ImAHopelessDev_gitlab> @watzon has left the chat
<oprypin> btw just use qt
<oprypin> qt5.cr project got literally everything right
<oprypin> it's just abandoned, no biggie
<disruptek> that's what i should use for the ui?
<FromGitter> <Blacksmoke16> it sounds like you just want to use Crystal
<disruptek> well, i have to decide.
<FromGitter> <Blacksmoke16> yes and im pretty sure the consensus is that for your needs Crystal isnt the best option
<FromGitter> <Blacksmoke16> maybe a few years from now it'll be different but :shrug:
<FromGitter> <tenebrousedge> Crystal GUI is WIP. Crystal on Windows is WIP. Writing a cross-platform GUI Crystal app is not practical, definitely not in six months
<FromGitter> <ImAHopelessDev_gitlab> do what oprypin says
<FromGitter> <ImAHopelessDev_gitlab> qt got a nice WYSIWYG form designer too
disruptek has left #crystal-lang ["-twitch #disruptek"]
disruptek has joined #crystal-lang
<disruptek> oops.
<disruptek> i can't find the qt library for crystal.
<FromGitter> <Blacksmoke16> https://github.com/Papierkorb/qt5.cr
<disruptek> danke.
<oprypin> it doesn't work tho
<FromGitter> <ImAHopelessDev_gitlab> LOL
<oprypin> it's the best but it's not currently in a working state
<FromGitter> <lagerfeuer> back with another question: I've been working on something where I use a lot of subclasses, and I came across an issue. How would I get something like this to work? https://play.crystal-lang.org/#/r/8xip
<FromGitter> <lagerfeuer> I could change the initialize method, but is there another way?
<FromGitter> <tenebrousedge> or https://play.crystal-lang.org/#/r/8xp1
<FromGitter> <tenebrousedge> same thing basicall
<jhass> oh, that's better
<jhass> https://github.com/crystal-lang/crystal/pull/9052 touches this a bit but won't make that work
<FromGitter> <lagerfeuer> ahhh, I see, thanks guys. Still pretty new, but apparently there is an issue for everything already :D
<FromGitter> <lagerfeuer> the first solution will change the return type of the function tho: https://play.crystal-lang.org/#/r/8xp6, where the second doesn't.
<FromGitter> <tenebrousedge> https://play.crystal-lang.org/#/r/8xp8
<FromGitter> <tenebrousedge> I prefer `case` I think
<FromGitter> <lagerfeuer> that's a winner, thanks!
<FromGitter> <tenebrousedge> :plus1:
<oprypin> straight-shoota, look, this merge wasnt so bad https://github.com/crystal-lang/crystal/pull/9043/commits/28421464e6ec6c27b39a8187866c950d2c25fb39 - it features the condensed view
<oprypin> maybe github gives up on the really huge merges though so perhaps you'd be right to avoid that then
<FromGitter> <j8r> disruptek Crystal is not the best for this, but on the Cloud/server side it has definitely its place
<FromGitter> <j8r> is it a proprietary app to sell to customer?
<FromGitter> <j8r> You could definitely adapt and contribute one of this https://alternativeto.net/software/adobe-premiere-pro/?license=opensource
DTZUZU has quit [Quit: WeeChat 2.7]
<FromGitter> <j8r> https://kdenlive.org/en/ is worth a shot
DTZUZU has joined #crystal-lang
<FromGitter> <jwoertink> Is there a way to check if there's a `previous_def`, but without actually running that method?
<FromGitter> <kinxer> Like this https://carc.in/#/r/8xpv ?
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Crystal/Macros/TypeNode.html#overrides?(type:TypeNode,method:StringLiteral%7CSymbolLiteral%7CMacroId):Bool-instance-method
<FromGitter> <kinxer> Oh, cool. I didn't see that.
<FromGitter> <jwoertink> ah sweet. I'll take a look at both those. Thanks
<FromGitter> <watzon> What would be the easiest way to pad a slice to a particular modulo?
<FromGitter> <watzon> I need to make sure the slice size is a multiple of 4
<FromGitter> <kinxer> What else are you basing the size on?
<FromGitter> <kinxer> Also, is it a `Bytes` or a Slice of something else?
<jhass> mmh, maybe new_size = (slice.size + 3) // 4 * 4; slice = Slice.new(slice.to_unsafe.realloc(new_size), new_size)
<jhass> unless slice.size == new_size
<FromGitter> <kinxer> What I came up with was `new_size = 4 * (slice.size // 4 + 1)` (otherwise the same), but that doesn't work if it's not a `Bytes`.
<jhass> are you sure?
<FromGitter> <kinxer> Well, I'm pretty sure `slice.size` gives the number of elements, not the number of bytes.
<FromGitter> <kinxer> I did just find `slice.bytesize`, though, so that should work.
<jhass> but pointer is generically typed too, why wouldn'T realloc operate on its type sizeof?
<FromGitter> <naqvis> my attempt to round a number to modulo of 4 😆 ⏎ ⏎ ```def modulo_4(num) ⏎ num % 4 == 0 ? num : num + (4 - (num % 4)).abs ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5ea0893e727e88014a0d38cc]
<oprypin> naqvis, well at least you realize its funny
<FromGitter> <kinxer> Ah... That's fair.
<oprypin> i think its `num // 4 * 4`
<jhass> I totally stackoverflow'ed that one tbh
<FromGitter> <naqvis> lol
<oprypin> ah jhass has the way to round it up
<FromGitter> <kinxer> I just realized mine pads an extra four bytes if the size is already 4 bytes...
<FromGitter> <kinxer> I'd go with @jhass's version.
<jhass> yeah, the one I came up with myself would do that too, so I was meh, let's look it up :D
<FromGitter> <kinxer> Wait, would it?
<jhass> yes for exact multiples
<jhass> >> 4 * (12 // 4 + 1)
<DeBot> jhass: # => 16 - https://carc.in/#/r/8xq5
<jhass> I did n + 4 - i % 4 initially which has the same issue
<jhass> eh, s/i/n/
<FromGitter> <kinxer> Wait, wasn't yours this? https://carc.in/#/r/8xq7
<FromGitter> <kinxer> > *<jhass>* mmh, maybe new_size = (slice.size + 3) // 4 * 4; slice = Slice.new(slice.to_unsafe.realloc(new_size), new_size)
<jhass> that's the one I stole from stackoverflow after I realized mine doesn't work
<FromGitter> <kinxer> Oh, okay.
<FromGitter> <manveru> ```foo = [ "bar" \ ⏎ , "baz" ]``` ⏎ ⏎ the formatter can't handle this it seems [https://gitter.im/crystal-lang/crystal?at=5ea08a5f989acc6ab7a8fc72]
<jhass> open an issue, I'll tag it with bug,formatter and MakeNowJust will send a pull request 10 minutes later :D
<oprypin> 😂
<FromGitter> <kinxer> Re `realloc`, I think it still depends on `T` (and so won't reallocate that many bytes, but space for that many elements; see https://crystal-lang.org/api/master/Pointer.html#realloc(size:Int)-instance-method ). It's probably not an issue, though, except if you're using 16-bit-width elements, since anything larger will already align at multiples of 4 bytes and anything smaller (i.e. 1-byte data) will work with
<FromGitter> ... the `realloc`. I guess you'd have to check the size to determine what to do, though, which isn't particularly simple.
<FromGitter> <watzon> Yeah it's `Bytes` @kinxer
<FromGitter> <kinxer> Oh. With bytes, just do what @jhass originally suggested.
<jhass> with anything do it!
<jhass> it's fine
<jhass> I mean I never tested this
<jhass> or used realloc in my life in any language
<jhass> but I'm pretty sure it's fine!
<FromGitter> <naqvis> jhass that will break on numbers below 4
<FromGitter> <naqvis> will truncate that to 0
<jhass> >> (3 + 3) // 4 * 4
<DeBot> jhass: # => 4 - https://carc.in/#/r/8xq8
<jhass> why you think so?
<jhass> >> (2 + 3) // 4 * 4
<DeBot> jhass: # => 4 - https://carc.in/#/r/8xq9
<oprypin> yes u need (+n-1)/n
<FromGitter> <naqvis> aahh, missed your posted formula, didn't see there was addition :trollface:
<FromGitter> <ImAHopelessDev_gitlab> good lord that code
<FromGitter> <kinxer> Just to demonstrate that it aligns to 4-element boundaries, not 4-byte boundaries.
<jhass> well yes
<jhass> not sure how you would do byte boundaries for arbitrarirly sized types
<FromGitter> <sardaukar> hello all 👋
<FromGitter> <kinxer> Unless someone has inadvisably large structs, that's probably not an issue.
<FromGitter> <ImAHopelessDev_gitlab> @sardaukar hello!
<FromGitter> <kinxer> Hey, there.
<FromGitter> <kinxer> @jhass I guess you'd just have to turn it into `Bytes` and do the alignment before serializing it (or whatever you're doing that requires the alignment).
<jhass> but would it always match up to the full a valid item length in the last element?
<FromGitter> <kinxer> Oh, certainly not always.
<FromGitter> <kinxer> If, for example, you need the byte alignment so you can encrypt your data, you'll just need to know what format the data should be in when you decrypt it and trim off that extra.
<FromGitter> <ImAHopelessDev_gitlab> how the heck do i change my avatar on gitter
<FromGitter> <Blacksmoke16> prob update it on gitlab
<jhass> come too the IRC side of things, no bothering with avatars!
<FromGitter> <ImAHopelessDev_gitlab> last time went on irc, they got my ip and ddos'd me hard
<FromGitter> <ImAHopelessDev_gitlab> my xfinity router exploded
<jhass> didn't happen to me in like 14 years now, but ok. get a cloak
<jhass> welp, what can I do for you weird windows people
<oprypin> this is Android 🤔
<FromGitter> <ImAHopelessDev_gitlab> my avatar on gitlab is my godot with crystal shard eyeballs
<FromGitter> <ImAHopelessDev_gitlab> not updated on gitter though, this sucks
<FromGitter> <tenebrousedge> probs it's gravatar
<FromGitter> <tenebrousedge> http://en.gravatar.com/
<FromGitter> <sardaukar> is there any way to render a template with Kilt using a dynamic name?
<FromGitter> <sardaukar> `Kilt.render` is a macro so it runs at compile time, right? so it's impossible?
<jhass> oh, the mIRC tripped me off :D
<FromGitter> <tenebrousedge> @sardaukar I don't know anything about Kilt, but from what you just said, yes, that's not possible. But you should be able to do something else maybe?
<FromGitter> <sardaukar> I just want to render an `.ecr` file with a name given by a config settings on a TOML file
<FromGitter> <sardaukar> I guess I could make a macro that renders *all* present `.ecr` files and then pick the right one...
<FromGitter> <tenebrousedge> could be a thing
<FromGitter> <ImAHopelessDev_gitlab> @tenebrousedge removed gitlab's avatar (default's to gravatar). setup an avatar on gravatar. did hard cache reload, now i see it, thanks
<FromGitter> <tenebrousedge> :plus1:
ur5us has joined #crystal-lang
ur5us has quit [Ping timeout: 256 seconds]
<FromGitter> <ImAHopelessDev_gitlab> guard clauses are one of the best things i've ever experienced in a programming language
<FromGitter> <ImAHopelessDev_gitlab> i just found out about them when istarted using crystal
<FromGitter> <tenebrousedge> <__<
<FromGitter> <ImAHopelessDev_gitlab> they are an aesthetic improvement as well, along with readability
<FromGitter> <tenebrousedge> they are for sure a good idea
ur5us has joined #crystal-lang
_ht has quit [Quit: _ht]
<hightower2> Hey folks, could you shed some light on the following problem (using Crystal 0.34 if it matters at all)...
<hightower2> I call a function with 3 arguments, of which the last one is literal integer 20. And the function that I call simply returns a fixed value, that's the only thing it does. Like, return 600
<hightower2> (this is because I've removed all code just to test this problem)
<hightower2> now, using Benchmark module, I see this function call executes over 700M times per second
<hightower2> But, if instead of this int 20 I call it with 20+1
<hightower2> then performance drops to only ~24M calls per secon
<hightower2> second*
<hightower2> what could be the underlying reason for that?
<FromGitter> <tenebrousedge> does it make a difference between `20 + 1` and `20.succ` ?
<hightower2> .succ too reduces performance to ~30M/s
<FromGitter> <Blacksmoke16> whats the code?
<hightower2> ok let me try extract into a play example
<FromGitter> <tenebrousedge> I'm suspicious of just about any results from `Benchmark`
<FromGitter> <Blacksmoke16> could just be the overload of overflow checking
<FromGitter> <Blacksmoke16> try with `&+`
<hightower2> the code is basically this:
<hightower2> (same argument types are used as in my real code)
<hightower2> but the play example does not exhibit this problem... it is lower performance in general, but does not show drastic difference
<FromGitter> <Blacksmoke16> using `--release` in your actual code?
<hightower2> yes yes, of course
<hightower2> the only difference is arg being 20 versus 20+1
<FromGitter> <Blacksmoke16> `try with &+`
<FromGitter> <Blacksmoke16> `20 &+ 1`
<hightower2> Using that form gets performance back to ~700M/s
<FromGitter> <tenebrousedge> o.o
<FromGitter> <Blacksmoke16> so yea, is just the overhead of overflow checking
<hightower2> how could I "fix" that? by possibly defining an explicit type of that function arg or something?
<hightower2> and/or how would I be able to tell when this check would kick in and when not?
<FromGitter> <Blacksmoke16> anytime you dont use the `&` prefixed operator
<jhass> it really doesn't have to do with the method call, benchmarking `20` vs `20+1` should show the same issue
<jhass> the overflow check adds enough code for LLVM to not eliminate or precompute
<jhass> also these kind of microbenchmarks are less than useful, I don't know why you spend on time on that
<FromGitter> <tenebrousedge> ^
<hightower2> jhass yes but I just did benchmark x = 20 vs x = 20 + 1 and it was nowhere near that severe... in fact 20+1 was faster than 20, so the difference is within measurement error
<jhass> probably eliminated
<hightower2> but 35M vs 770M drop in performance is not a micro benchmark, this is significant
<FromGitter> <tenebrousedge> the question is whether that 770M number represents anything real
<FromGitter> <tenebrousedge> which I doubt
<hightower2> it does... my complete function was running ~700M+ times per second.. compared to ~30M if I sent variable+1 as argument
<hightower2> that's how I noticed it...
<FromGitter> <tenebrousedge> bounds checking isn't a wildly intensive operation. If what your code is doing is less work for the CPU than bounds checking, then what exactly is it doing?
<FromGitter> <tenebrousedge> what non-noop thing can your CPU do 770M times per second?
<hightower2> well that's what it tells me... It runs the test for 5 seconds before reporting the results
<hightower2> the function calls LibC.strstr a couple times, and does some simple math
<hightower2> let me undo all the code removal that I did to test this problem, and then I'll tell you exactly what's the difference for the complete function
<jhass> add x.report("empty") { ) to your benchmarks and you see you're wasting your time really
<jhass> on my machine https://p.jhass.eu/7v.txt
<FromGitter> <tenebrousedge> the only thing that matters to me is how code performs under real-world conditions. Profiling > benchmarks
<jhass> ^
<FromGitter> <tenebrousedge> the odds that this apparent bottleneck is actually a real-world limiting factor are next to nil
<jhass> 700M iterations seems to be about the overhead of the IPS benchmark harness, you're not testing anything at that point
<hightower2> hmm..
<FromGitter> <tenebrousedge> `0.0B/op` is another good sign that your tests are not effective
<jhass> well... allocation free code is nice code :D
<jhass> but there too as for anything. Don't worry. Identify the bottlenecks in your application. Spend time on optimizing there
<jhass> making some micro thingy 10x faster is completely useless if some other part of your application take 10x the time and everything has to wait for it anywayss
<FromGitter> <tenebrousedge> "Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our
<FromGitter> ... opportunities in that critical 3%."
<hightower2> maybe the Benchmark module isn't accurate when functions do LibC calls, is that possible?
<jhass> unlikely
<jhass> why do you care about this? Did you identifiy a bottleneck? How, why? Is the total runtime of your program slower than you expected? How did you come up with that expectation?
<hightower2> I tested different algorithms through the benchmark module, to decide which one I'm gonna use
<jhass> and why did you decide to different algorithms? How did you decide that performance is more important for this algorithm over qualtitative measures like clarity and (being sure of) correctness?
<jhass> *to try
<hightower2> well that's theoretical discussion, I did not find that clarity of correctness were affected. It is only possible that Benchmark's results were misreporting actual values for reasons unknown to me
<FromGitter> <tenebrousedge> I don't want to say that the Benchmark module should be renamed the BS module, but testing algorithms on large real-world data sets is probably a better idea
<hightower2> I used that module in Ruby (I think it's called the same) with good success
<FromGitter> <tenebrousedge> Crystal is not Ruby
<FromGitter> <tenebrousedge> Ruby doesn't have LLVM to lie to you about what it's doing
ur5us has quit [Ping timeout: 256 seconds]
zorp has quit [Read error: Connection reset by peer]
return0e has quit [Read error: Connection reset by peer]
<hightower2> but what can it do that'd be unexpected? apply optimizations somewhere to e.g. not even call the function when the result is not used?
<hightower2> or what?
<FromGitter> <tenebrousedge> yes
zorp has joined #crystal-lang
<FromGitter> <tenebrousedge> it can absolutely do that
return0e has joined #crystal-lang
Liothen has quit [Read error: Connection reset by peer]
Liothen has joined #crystal-lang
commavir has quit [Ping timeout: 265 seconds]
<hightower2> well, I see your point, but... maybe I just don't understand why in e.g. two identical lines like benchmark(func1(arg)) and benchmark(func2(arg)), it'd choose not to call one but optimize away the other
<hightower2> s/not to/to/g
commavir has joined #crystal-lang
<jhass> well of course it needs to prove the call is side effect free
<FromGitter> <tenebrousedge> understanding exactly how LLVM is going to interpret your benchmark is a complicated subject, that I don't have a great handle on personally. Writing effective benchmarks using `Benchmark` is frequently much harder than it seems
<jhass> Writing effective benchmarks is hard, period. `Benchmark` does not and does not try to make it any easier. It only tries to make writing benchmarks in general less repetitive. That's all
zorp has quit [Ping timeout: 250 seconds]
ur5us has joined #crystal-lang
tane has quit [Quit: Leaving]
ur5us has quit [Read error: Connection reset by peer]
ur5us has joined #crystal-lang
alexherbo2 has quit [Remote host closed the connection]
zorp has joined #crystal-lang
zorp has quit [Ping timeout: 258 seconds]