ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.31.1 | 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
<FromGitter> <tenebrousedge> πŸ‘
<alex```> :D
* FromGitter * tenebrousedge watches *El ESpinazo del Diablo*
<alex```> is it worth?
<FromGitter> <tenebrousedge> it's pretty high up my list of best movies
<alex```> k
<alex```> dl in progress :D
<FromGitter> <tenebrousedge> it's a great ghost story, and secretly a political allegory
<alex```> I’m dl it with spanish audio / english subtitles
<FromGitter> <sam0x17> is there a way I can directly cast a `StaticArray(UInt8, 32)` to a `Bytes` (which is just `Slice(UInt8)`)?
<alex```> never heard spanish movies
<alex```> hope the accent with sound good to my ears
<FromGitter> <tenebrousedge> @sam0x17 you tried `as`?
<FromGitter> <sam0x17> ya know, I really should
<FromGitter> <sam0x17> doh
<alex```> xD
<FromGitter> <tenebrousedge> I think `slice` has some helpful methods though
<FromGitter> <Blacksmoke16> is also https://crystal-lang.org/api/master/Object.html#unsafe_as(type:T.class)forallT-instance-method
<FromGitter> <Blacksmoke16> ⚠️ danger zone ⚠️
<FromGitter> <sam0x17> hah thats fine I'm already using `unsafe_as` on the same line
<FromGitter> <Blacksmoke16> :p πŸ‘
<FromGitter> <sam0x17> I should prob try going directly to `Bytes` -- I just wish I could specify the size of the bytes somehow in the cast
<FromGitter> <sam0x17> actually, that is why this won't work directly --- slices store their size
<FromGitter> <sam0x17> yeah, ok, so the loop I am doing copying is necessary
<FromGitter> <sam0x17> ok we good
<FromGitter> <sam0x17> was basically trying to see if I'm missing out on a more efficient way of doing: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da3bf15809de9699f325ed0]
<FromGitter> <Blacksmoke16> `data = Bytes.new sizeof({{@type}})`
<FromGitter> <sam0x17> true, that is better
<FromGitter> <Blacksmoke16> or store the size then use that var everywhere you need the size
<FromGitter> <sam0x17> point taken
<FromGitter> <sam0x17> I'm more concerned about whether I need to do that copying loop on line 3
<FromGitter> <sam0x17> I think its inevitable though
<FromGitter> <sam0x17> but there may be a more efficient way of doing the actual loop
<FromGitter> <Blacksmoke16> cant you do like
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/Slice.html#new(pointer:Pointer(T),size:Int,*,read_only=false)-class-method
<FromGitter> <Blacksmoke16> that
<FromGitter> <sam0x17> yeah that's what I do when @type is a class / non-`Value`
<FromGitter> <sam0x17> turns out that stops working on primitives
<FromGitter> <Blacksmoke16> dunno
<FromGitter> <sam0x17> aka for anything that is passed by value, the pointer trick doesn't seem to work
<FromGitter> <sam0x17> I'm satisfied if nothing jumped out at you
<FromGitter> <sam0x17> it's probably good enough
<FromGitter> <sam0x17> thx
<FromGitter> <Blacksmoke16> granted i know like almost nothing about pointers and shit so yea :p
<FromGitter> <sam0x17> I do but not in crystal per say
<FromGitter> <sam0x17> doing a byte-by-byte copy is inevitable for my use case
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/String.html#to_unsafe:Pointer(UInt8)-instance-method
<FromGitter> <sam0x17> I just want to make sure that the way I'm doing said copy isn't stupidly inefficient
<FromGitter> <Blacksmoke16> would that solve the String primitive problem?
return0e has joined #crystal-lang
<FromGitter> <sam0x17> string actually works fine it's the only primitive that does because its a pointer
<FromGitter> <sam0x17> what's even funnier is if I take my type and put it in a tuple, I can use the pointer method on the tuple
<FromGitter> <sam0x17> but this is just fine
<FromGitter> <ImAHopelessDev_gitlab> @hypercore I am, and I love it. hbu?
<FromGitter> <sam0x17> yeah, that's what I do on strings and classes etc
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <sam0x17> too bad there isn't just a global `.to_bytes` on `Object` but that's what I've implemented basically I just gave it a different name in case that collides with something
<FromGitter> <Blacksmoke16> could just add it to each type
<FromGitter> <sam0x17> I include a module on `Object`
<FromGitter> <Blacksmoke16> or add it to Object then override on types that need diff logic
<FromGitter> <sam0x17> and then I have one case for `Value` things and another case for everything else
teardown has quit [Read error: Connection reset by peer]
<FromGitter> <sam0x17> it's the code you helped me with earlier
<FromGitter> <Blacksmoke16> case statement within `Value`?
teardown has joined #crystal-lang
<FromGitter> <Blacksmoke16> i was picturing something like https://github.com/crystal-lang/crystal/blob/master/src/json/to_json.cr
<FromGitter> <sam0x17> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da3c184809de9699f326fe1]
<FromGitter> <sam0x17> and actually now that the signature has changed I can simplify the second case
return0e has quit [Ping timeout: 268 seconds]
<FromGitter> <sam0x17> oh nvm
<FromGitter> <sam0x17> it does have to be that
<FromGitter> <sam0x17> second case is probably broken because I think there are a few bits before the instance variables
<FromGitter> <Blacksmoke16> could you do something with https://crystal-lang.org/api/master/IO/ByteFormat.html ?
<FromGitter> <sam0x17> for ints and floats, yeah
<FromGitter> <Blacksmoke16> gotcha
<FromGitter> <sam0x17> I had another method using pointerof for the second case like you said and I'm not sure why I removed it now that I'm looking at things again
<FromGitter> <sam0x17> oh yeah, I'm planning on "structifying" classes automatically based on their instance variables
<FromGitter> <sam0x17> and then everything is `Value`
<FromGitter> <sam0x17> because if I just take the raw memory of a class, and there are references nested in there, I'll be getting bytes for the references
<FromGitter> <sam0x17> so I have to pack these in a careful way where I can re-construct them without any references to the old memory space
<FromGitter> <tenebrousedge> are you sure this approach will work?
<FromGitter> <sam0x17> the memory layout is simple enough that it really should
<FromGitter> <sam0x17> everything is just a bunch of instance variables (ignoring class methods and class variables for a moment)
<FromGitter> <sam0x17> each instance variable is either a `Value` or a `Reference`
<FromGitter> <sam0x17> if it's a `Reference`, do some special logic so I know when I am re-constructing it that I need to create an object in memory and have the reference point to that
<FromGitter> <sam0x17> if it's a `Value`, just store its bytes directly
<FromGitter> <sam0x17> do that recursively, and that's it, you can represent any set of crystal objects (ignoring class variables again) in a binary block of data and hopefully reconstruct it with the caveat that the memory addresses will be different
<FromGitter> <sam0x17> class / module level stuff I could probably support too, I just don't want to wrap my head around that atm
<FromGitter> <tenebrousedge> do you need to?
<FromGitter> <asterite> What are you trying to do?
<FromGitter> <sam0x17> I'm making a real repl
teardown has quit [Read error: Connection reset by peer]
<FromGitter> <sam0x17> so I need to be able to re-create the objects in the previous context
<FromGitter> <sam0x17> without having crazy side effects like re-running database queries etc
<FromGitter> <asterite> When dumping values, do you dump the values pointed by instance variables, possibly recursively?
<FromGitter> <sam0x17> yes that's the idea
<FromGitter> <asterite> Cool
<FromGitter> <sam0x17> if it's a Reference, I'm going to recursively process it until everything is `Value`, and then do some special packing and logic to re-create that
teardown has joined #crystal-lang
<FromGitter> <sam0x17> yeah, I'm pretty excited xD
<FromGitter> <asterite> So something like Ruby's Marshal?
<FromGitter> <sam0x17> most languages this would be impossible
<FromGitter> <sam0x17> pretty much
<FromGitter> <asterite> Nixe
<FromGitter> <sam0x17> I didn't know ruby had that but I know that from .NET
<FromGitter> <tenebrousedge> could you split off that part into a separate lib?
<FromGitter> <sam0x17> way back in the day I used .NET's "serialization" (really memory dumping) to do fun stuff with states
<FromGitter> <sam0x17> I plan to
<FromGitter> <asterite> I tried to do it in the past and failed. I think the language is not ready for that yet, but I'm always surprised to see others do things I thought were impossible
<FromGitter> <sam0x17> this basic functionality would be really useful
<FromGitter> <sam0x17> well since I'm just trying to do it in the context of a repl, I think I can get away with some things not working
<FromGitter> <tenebrousedge> @asterite were there any specific pain points you encountered?
<FromGitter> <sam0x17> I really just need the local instance variables to work mostly
<FromGitter> <asterite> The main issue I faced was virtual types (a type that can be it or any of its subclasses) and unions, I can't remember
<FromGitter> <asterite> I should try it again
<FromGitter> <sam0x17> I'm just gonna try this route of ignoring what something is other than in terms of whether it is a Reference or a Value
<FromGitter> <sam0x17> I'm hoping that this stubborn approach gets around all the bs with unions, but I don't know
<FromGitter> <sam0x17> it was really easy for the people who did this in Rust since everything is a struct
<FromGitter> <sam0x17> they've had a repl for some time (though it is just a package, not core)
<FromGitter> <tenebrousedge> which is the primary Rust repl?
<FromGitter> <sam0x17> I'll dig it up
<FromGitter> <sam0x17> some googler made it
<FromGitter> <tenebrousedge> there was a bug for it that seemed to still be open
<FromGitter> <sam0x17> hah it's actually really hard to find https://github.com/google/evcxr
<FromGitter> <sam0x17> yeah, I have no interest in a rust repl -- that's one language where it would be so painful fighting with the borrow checker why bother
<FromGitter> <sam0x17> no joke I've kept a rails version of my company's app up-to-date just so I can use `rails console`
<FromGitter> <sam0x17> until I have a working crystal repl that I like
<FromGitter> <tenebrousedge> :/
<FromGitter> <sam0x17> so every time I have db migration I just replicate it on the ruby side and I've done the same with changes to models xD
<FromGitter> <sam0x17> but yeah I'll make a main package for the basic functionality and then people can build thing's like pry, etc
<FromGitter> <sam0x17> *shard
<FromGitter> <sam0x17> would be cool if we could figure out tab completion -- might be able to have some macros dump that information at the end of compilation that the repl can then use
<FromGitter> <sam0x17> this is why I like crystal though -- the language will let you do stuff like this
<FromGitter> <asterite> so, I was able to marshal and unmarshal unions. Previously we didn't have the `Union` type to which you could attach class methods so that was a blocker. With virtual types it's a bit different but maybe still possible, I'll give it a try
<FromGitter> <sam0x17> πŸ‘
alex``` has quit [Ping timeout: 276 seconds]
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
<FromGitter> <sam0x17> is there a way I can force-write an instance variable?
<FromGitter> <sam0x17> e.g. an equivalent to `obj.@something = something`
<FromGitter> <tenebrousedge> you'd need a macro, pretty sure
<FromGitter> <tenebrousedge> or maybe you could write `Object#instance_variables` ?
<FromGitter> <sam0x17> new question -- how can I check if a `@type` is equal to `Object`? when I'm doing it and it is `Object`, `@type == Object` is false
<FromGitter> <tenebrousedge> `is_a?`
<FromGitter> <sam0x17> (in a macro)
<FromGitter> <sam0x17> `\{% elsif @type != Object %}`
<FromGitter> <Blacksmoke16> try lik` <=`
<FromGitter> <sam0x17> ok
<FromGitter> <watzon> What was the recommended way to handle recursive aliases again?
<FromGitter> <tenebrousedge> struct, innit?
<FromGitter> <sam0x17> hmm it's still not acting as expected
<FromGitter> <sam0x17> what's funny is when I print out `{{@type}}` it is Object, but that part of the macro is running even though it is encased in `\{% elsif @type <= Object %}`
f1refly has quit [Ping timeout: 252 seconds]
<FromGitter> <tenebrousedge> @watzon I just remember that JSON::Any (https://github.com/crystal-lang/crystal/blob/master/src/json/any.cr#L20) does this, and look it up there
<FromGitter> <watzon> Ahh true
f1refly has joined #crystal-lang
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
<FromGitter> <sam0x17> so my only remaining problem now is force writing instance variables. It's trickier than it sounds when doing it generically
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
<FromGitter> <sam0x17> yeah for whatever reason it's like this macro block isn't running: ⏎ ⏎ `````` [https://gitter.im/crystal-lang/crystal?at=5da3e9d5809de9699f336bae]
<FromGitter> <Blacksmoke16> `@type.instance_vars` only works within a method
<FromGitter> <sam0x17> ahhhh
<FromGitter> <sam0x17> that explains everything
<FromGitter> <Blacksmoke16> you can use a case and iterate over ivers within your `set_property` method
<FromGitter> <sam0x17> thats what I originally did
<FromGitter> <sam0x17> but ran into problems with restrictions on doing unsafe_as involving Object
<FromGitter> <sam0x17> I'll try to re-do it
teardown has quit [Read error: Connection reset by peer]
<FromGitter> <sam0x17> should I use a symbol to refer to the instance variable name? that's what I did before
teardown has joined #crystal-lang
<FromGitter> <Blacksmoke16> doesnt really matter
<FromGitter> <sam0x17> yeah actually I got it I think I had a bug somewhere else thx!!
<FromGitter> <sam0x17> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da3ecd6158cfd6735286cab]
<FromGitter> <sam0x17> that seems to work just fine
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <sam0x17> (obviously will convert to case / when)
chemist69 has quit [Ping timeout: 246 seconds]
chemist69 has joined #crystal-lang
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
<FromGitter> <ImAHopelessDev_gitlab> dammn Hashes inside Arrays are powerful af
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
<FromGitter> <sam0x17> anyone know a way of creating a "blank" instance of a class when there is no 0-arg constructor? (can be hacky, unsafe_as, etc, just need something that will always work assuming I am going to then set the instance variables one by one)
<FromGitter> <sam0x17> actually scratch that, that isn't my problem
<FromGitter> <sam0x17> my problem is I have a "blank" instance, but I can't find sizeof the instance vars because they are all zeroed out so when I try to do sizeof(typeof(blah.@some_var)) I get a seg fault :/
return0e has joined #crystal-lang
<FromGitter> <Blacksmoke16> isnt that what instance_sizeof is for?
<FromGitter> <sam0x17> oh, true point
return0e has quit [Ping timeout: 240 seconds]
<FromGitter> <sam0x17> that's not my problem actually, I'm already using instance_sizeof where appropriate
ht_ has joined #crystal-lang
<FromGitter> <sam0x17> I'm basically doing this: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da3fbc6158cfd673528d1b9]
<FromGitter> <sam0x17> seg faults in the `force_write!` call
<FromGitter> <Blacksmoke16> and whats that method look like again?
<FromGitter> <sam0x17> and `force_write!` normally works fine, so basically crystal will segfault if you try to set an instance variable that has its memory set to 0 (or anything invalid)
<FromGitter> <sam0x17> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da3fc4e8e2e9a7c6bf40ec1]
teardown has quit [Read error: Connection reset by peer]
<FromGitter> <sam0x17> ignore the `Dumper` module, that's old
teardown has joined #crystal-lang
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <sam0x17> I'm thinking I might have to macro insert a zero-arg constructor into every class, which would be a little overly invasive
<FromGitter> <sam0x17> its so close to working too
ht_ has quit [Quit: ht_]
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
<FromGitter> <sam0x17> ok I figured it out -- have to use `{{var.type}}` instead of `typeof(obj.@{{var}})`
<FromGitter> <sam0x17> don't know why I thought i had to do that
<FromGitter> <sam0x17> it now actually works, and I found a way to do 99% of it with pure generics
<FromGitter> <sam0x17> e.g.: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4093557c2517c6a051f0a]
teardown has quit [Read error: Connection reset by peer]
teardown has joined #crystal-lang
absolutejam4 has joined #crystal-lang
absolutejam4 has quit [Ping timeout: 240 seconds]
<FromGitter> <sam0x17> ^ problem with above: T.instance_vars doesn't work
absolutejam4 has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
HumanG33k has joined #crystal-lang
<FromGitter> <bajro17> Can someone send me link of this list shards it will be good to have
<FromGitter> <bajro17> I guess it was before on crystal github wiki
<FromGitter> <bajro17> but now I cant find ti
<FromGitter> <bajro17> it*
<FromGitter> <firejox> try unintialized to create blank instance?
<FromGitter> <gdotdesign> @bajro17 you mean this one? https://crystalshards.xyz/
<FromGitter> <bajro17> no
<FromGitter> <bajro17> there is list of shards what will be good to have
<FromGitter> <gdotdesign> oh
<FromGitter> <bajro17> I remember in this list was graphql
<FromGitter> <gdotdesign> this one then? https://github.com/crystal-community/crystal-libraries-needed
dwdv_ has joined #crystal-lang
DTZUZO has quit [Ping timeout: 264 seconds]
<FromGitter> <bajro17> @gdotdesign thank you this is what I search :)
<FromGitter> <gdotdesign> πŸ‘
return0e has joined #crystal-lang
return0e has quit [Ping timeout: 240 seconds]
absolutejam4 has quit [Ping timeout: 268 seconds]
absolutejam4 has joined #crystal-lang
absolutejam4 has quit [Ping timeout: 265 seconds]
return0e has joined #crystal-lang
<FromGitter> <sam0x17> @firejox thanks for the uninitialized tip -- I have a workaround, but thats much cleaner
absolutejam4 has joined #crystal-lang
DTZUZO has joined #crystal-lang
DTZUZO has quit [Remote host closed the connection]
<FromGitter> <firejox> πŸ‘
flaviodesousa has joined #crystal-lang
alex``` has joined #crystal-lang
DTZUZO has joined #crystal-lang
DTZUZO has quit [Ping timeout: 240 seconds]
<FromGitter> <andrius> That's for websockets, I shall process multiple chained events in on_message (they are JSON structures). What do you guys thing about class Multiple logic? https://play.crystal-lang.org/#/r/7su3
<FromGitter> <sam0x17> @asterite @Blacksmoke16 here it is 100% working on primitives, structs, strings, and classes that may have any of those things as members: https://play.crystal-lang.org/#/r/7su4
<FromGitter> <sam0x17> I'll have to branch out and try unions and some more exotic things next, but the basic approach seems to work
<FromGitter> <sam0x17> oh and bonus points if anyone knows how I can avoid doing the `\{% if true %}` just to get some of those macros to work
<FromGitter> <sam0x17> @tenebrousedge ^
<FromGitter> <sam0x17> when I'm packing anything that isn't a primitive, I pack it as `first_instance_variable_size`, `first_instance_variable_bytes`, `second_instance_variable_size`, etc..
absolutejam4 has quit [Ping timeout: 268 seconds]
absolutejam4 has joined #crystal-lang
absolutejam has joined #crystal-lang
absolutejam4 has quit [Read error: Connection reset by peer]
<FromGitter> <firejox> @sam0x17 just `\{% begin %}` `\{% end %}` ?
DTZUZO has joined #crystal-lang
DTZUZO has quit [Remote host closed the connection]
<FromGitter> <asterite> @sam0x17 Cool! But what is `Foo` has a reference to `Foo` or some other `Reference` type?
<FromGitter> <asterite> Plus it seems for String you just marshal the memory address. If some code runs between marshalling and unmarshalling and those strings become unreachable, the GC will collect them and marshalling will fial
<FromGitter> <asterite> fail
<FromGitter> <ilanpillemer> and that would intermittent creating Heisenbugs?
<FromGitter> <asterite> yup
<livcd> asterite: do you think there's any chance Crystal might get a corporate support from Shopify ?
<FromGitter> <absolutejam_gitlab> bit of a leap from the tweet, isn't it? πŸ˜†
<livcd> well they just recently hired Chris Seaton
gangstacat has joined #crystal-lang
absolutejam has quit [Ping timeout: 265 seconds]
Human_G33k has joined #crystal-lang
Human_G33k has quit [Remote host closed the connection]
Human_G33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 265 seconds]
absolutejam has joined #crystal-lang
DTZUZO has joined #crystal-lang
<FromGitter> <naqvis> @sam0x17 not sure if you had a chance to look into msgpack-crystal (https://github.com/crystal-community/msgpack-crystal)? This shard yields the same outcome as what your provided example. ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da485ecdbf67667345ae7d2]
flaviodesousa has quit [Quit: KVIrc 4.9.3 Aria http://www.kvirc.net/]
MasterdonX has joined #crystal-lang
masterdonx2 has quit [Ping timeout: 268 seconds]
<FromGitter> <asterite> livcd: no idea. And Chris Seaton is working more in Ruby and Truffle, not Crystal
<dwdv_> Another noob question: why is `File.read_lines`, for example, not implemented as `each_line(...).to_a` and instead accumulating elements explicitly?
<FromGitter> <tenebrousedge> There is an `each_line`
<FromGitter> <ilanpillemer> I just figured out I dont need modules or classes.
<FromGitter> <tenebrousedge> that sounds like a scary realization
<erdnaxeli> dwdv_: good question
<FromGitter> <tenebrousedge> dwdv_ the core code is frequently written that way
<FromGitter> <tenebrousedge> it's probably slightly more efficient
<FromGitter> <tenebrousedge> see also `enumerable#count`
<FromGitter> <tenebrousedge> which uses an explicit accumulator instead of `reduce(0)`
<FromGitter> <ilanpillemer> how do you read one char at a time from STDIN?
<dwdv_> Hm, looking at the logs it seems like `to_a` was added later than `read_lines`, might just be the case that no one felt like touching these procedures.
<FromGitter> <tenebrousedge> benchmark them
<FromGitter> <ilanpillemer> Aha `gets(1)`
<FromGitter> <bajro17> @ilanpillemer check line 114
<FromGitter> <bajro17> I think this is best for performance
<FromGitter> <ilanpillemer> gets(1) works well it seems
<FromGitter> <Blacksmoke16> @ilanpillemer could also do `STDIN.each_char { |char| ... }`
<FromGitter> <ilanpillemer> @Blacksmoke16 that seems more idiomatic.
<FromGitter> <ilanpillemer> than thios
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <ilanpillemer> ```c = gets(1) ⏎ while c != nil ⏎ puts(c) ⏎ c = gets(1) ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5da48c6889acff6ff5f4d714]
<FromGitter> <Blacksmoke16> :p
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/IO.html#each_char(&block):Nil-instance-method
<FromGitter> <ilanpillemer> ```STDIN.each_char do |c| ⏎ puts(c) ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5da48cb2f1c89c0758e9b951]
<FromGitter> <Blacksmoke16> πŸ‘
<FromGitter> <ilanpillemer> Feels less like `c` now
<FromGitter> <asterite> Also `STDIN.reach_char`
<FromGitter> <asterite> I mean `STDIN.read_char`
<FromGitter> <ilanpillemer> will that stream?
<FromGitter> <ilanpillemer> I want to stream
<FromGitter> <ilanpillemer> I guess one of them doesnt stream?
<FromGitter> <ilanpillemer> read char is more semantically correct
rohitpaulk has joined #crystal-lang
<FromGitter> <ilanpillemer> hmm.. read_char doesnt take a block
<FromGitter> <tenebrousedge> you can wrap it in `Iterator` if you like
<FromGitter> <tenebrousedge> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da48dc84afd703a4edb8381]
<FromGitter> <Blacksmoke16> at that point just do
<FromGitter> <Blacksmoke16> ```iter = STDIN.each_char ⏎ iter.next ⏎ iter.next``` [https://gitter.im/crystal-lang/crystal?at=5da48dde809de9699f37f042]
<FromGitter> <asterite> Yes πŸ‘ , `STDIN.each_char` is the Iterator version (or the block version)
<FromGitter> <ilanpillemer> gets(1) and read_char seem similar
<FromGitter> <ilanpillemer> I guess there are differences though
ht_ has joined #crystal-lang
absolutejam has quit [Ping timeout: 240 seconds]
<FromGitter> <sam0x17> all, thanks for the tips ⏎ @naqvis I had not looked at msgpack but I'll definitely check it out
<FromGitter> <naqvis> πŸ‘
<FromGitter> <sam0x17> @naqvis will it work with completely arbitrary classes, structs, and crystal objects?
<FromGitter> <naqvis> yeah, it does
<FromGitter> <sam0x17> nice
<FromGitter> <sam0x17> if that's the case I can use that as a starting point for a repl then
<FromGitter> <naqvis> it also nicely handles references
<FromGitter> <sam0x17> very nice
<FromGitter> <sam0x17> does it add any methods to implementers?
<FromGitter> <wontruefree> it is a bummer msgpack is not used more
<FromGitter> <sam0x17> for me to use this, the first step would likely be to add it to `Object` so everything is automatically serializable
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da494f880e62056e402f872]
<FromGitter> <ilanpillemer> is there no similar way to puts, to not send a newline?
<FromGitter> <ilanpillemer> or must I use `print`?
<FromGitter> <tenebrousedge> I think there's a `STDOUT#<<`
<FromGitter> <tenebrousedge> `print` is a thing too
<FromGitter> <sam0x17> ah, thx
<FromGitter> <naqvis> @wontruefree *MessagePack* format might not be used anymore, but implementation might be a good starting point for @sam0x17 use-case. Just my two cents πŸ˜†
rohitpaulk has quit [Remote host closed the connection]
<hypercore> would you guys use crystal for a production web app?
<FromGitter> <tenebrousedge> depends on the app
<hypercore> or would you pick something that's been around longer, i.e. a better tested framework
<hypercore> like a saas app
<FromGitter> <tenebrousedge> Crystal is production-ready as far as I'm concerned
<FromGitter> <tenebrousedge> but it depends on what I'm making. If it needed performance above all, I would want Crystal
<FromGitter> <bajro17> there is already a lot of apps in production
<FromGitter> <tenebrousedge> if I can glue together 99% of the app from existing Rails libraries and don't need the performance, I'll go with Rails
<hypercore> because you're more familiar/experienced with rails?
<FromGitter> <tenebrousedge> I'm just as comfortable in Crystal as Ruby, the determining factor is whether the libraries I need exist already. For most of my projects dev time is the strongest limiting factor
<FromGitter> <tenebrousedge> when I am working in Rails, the idea of spinning off components to Crystal libraries or mini-services is never far from my thoughts
<FromGitter> <sam0x17> devops in crystal is still a half open problem. Yes there is Raven.cr so we can at least use Sentry.io for error tracking, but without a `rails console`-like repl (I don't count ICR, because it re-runs all previous commands on each new input line, which is super dangerous for devops), it is hard to do the database / error introspection one is accustomed to doing in `rails`. That said, I'm working on such a repl
<FromGitter> ... right now xD
<FromGitter> <sam0x17> another open problem is the fragility of crystal development dependencies -- people doing crystal in lambdas *need* static compilation to always work, so it's a constant struggle to keep good alpine docker images working, and update the packages on said docker images to the latest flavor of the week to ensure that things like the `HTTP::Server` can compile statically
<FromGitter> <sam0x17> conversely, and for whatever reason, in Rust I've never had something fail to statically compile. I don't know why exactly, it could be that they implement in Rust a lot of the things that we delegate to third party libraries in crystal
<FromGitter> <sam0x17> if libevent, pcre, openssl, the boehm-gc, libxml, etc, were all ported to native crystal and maintained in the standard library (would be incredibly hard), that problem would vanish
<FromGitter> <sam0x17> libxml and libyaml in particular seem like natural candidates to be re-written in crystal. Openssl is and always will be a pain point for pretty much every language right now.
<FromGitter> <sam0x17> another alternative would be to write a shard that provides portable building of dependencies, with its own library of "recipes" for things like openssl, etc, that will always "just work" by setting up the appropriate shared libraries and environment variables in the local file structure without the need for root or changing any files outside of the current shard's directory.
<FromGitter> <tenebrousedge> :/
<FromGitter> <sam0x17> but hey, I use crystal in production
gangstacat has quit [Quit: Ĝis!]
<FromGitter> <Blacksmoke16> kinda related, we use a lot of https://symfony.com/doc/current/console.html
<FromGitter> <Blacksmoke16> other "shards" you install also register their own
<FromGitter> <tenebrousedge> PHP gives me a sad
<FromGitter> <Blacksmoke16> so in the end you get like `php app/console doctrine:migrations:migrate`
<FromGitter> <Blacksmoke16> which makes for a pretty nice API for semi common tasks, not as free as a console but are at least reusable/testable
<FromGitter> <Blacksmoke16> plus since the console is essentially a "binary" could point bash commands and stuff at it
<FromGitter> <ilanpillemer> PHP is worse than JavaScript.
<FromGitter> <Blacksmoke16> a more complete crystal version of doing that might be handy, to me at lest
<FromGitter> <Blacksmoke16> tl;dr write testable/reusable one-off crystal scripts that have access to your models/code
<FromGitter> <ilanpillemer> Crystal makes neat scripts.
<FromGitter> <ilanpillemer> I realized that today.
<FromGitter> <tenebrousedge> it's good for that. Ruby is too
<FromGitter> <ilanpillemer> I didnt like the ruby ecosystem when I explored it.
<FromGitter> <ilanpillemer> That rvm thing was maddening.
<FromGitter> <ilanpillemer> 10 years ago
<FromGitter> <ilanpillemer> I guess it's probably different now
<FromGitter> <ilanpillemer> Well maybe less than 10 but more than 6
<FromGitter> <ilanpillemer> Are their console libraries. So for example I can do a graphical console thing?
<FromGitter> <tenebrousedge> For Crystal? I don't know of any
<FromGitter> <ilanpillemer> I want to try do game of life in Crystal in the console.
<FromGitter> <ilanpillemer> So you would update the console positions
<FromGitter> <ilanpillemer> x,y coords in the terminal iow
<FromGitter> <ilanpillemer> Are their primitives in Crystal that would allow it?
gangstacat has joined #crystal-lang
gangstacat has quit [Client Quit]
<FromGitter> <watzon> There are a few projects with bindings to ncurses, but they haven't historically been well maintained. Here is the one that was updated most recently https://github.com/SamualLB/ncurseshttps://github.com/SamualLB/ncurses
dannyAAM has quit [Quit: znc.saru.moe : ZNC 1.6.2 - http://znc.in]
dannyAAM has joined #crystal-lang
gangstacat has joined #crystal-lang
Human_G33k has quit [Remote host closed the connection]
<FromGitter> <dscottboggs> Im getting an error when attempting to cross-compile crystal for ARM. Am I missing a dependency or what?
<FromGitter> <dscottboggs> http://cloud.tams.tech/s/ETjbDGgWr4266bT
Human_G33k has joined #crystal-lang
<FromGitter> <dscottboggs> Sorry I don't seem to be able to send an image from mobile.
<FromGitter> <tenebrousedge> @dscottboggs this seems relevant (https://github.com/crystal-lang/crystal/issues/7535)
<FromGitter> <ilanpillemer> @asterite thanks for the link!
<FromGitter> <ilanpillemer> exactly what I was looking for. πŸ‘ŒπŸ‘
<FromGitter> <ilanpillemer> emojis ftw
<FromGitter> <ilanpillemer> I guess this is how its done.
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4c3fa39d0c70757ac6f91]
<FromGitter> <asterite> oh, cool idea to use emojis :-)
<FromGitter> <ilanpillemer> I saw a demo when somone live coded pacman in the console, using emjois.
<FromGitter> <ilanpillemer> changes everything!
<FromGitter> <ilanpillemer> these examples are great, I assume the code is done idiomatically?
<FromGitter> <asterite> I don't know. I think in small scripts we do things a bit differently. For example I wouldn't regularly add methods to IO, but if it's just for a final app/script then it's fine
<FromGitter> <ilanpillemer> πŸ‘
<FromGitter> <asterite> Also, since you are doing AOC I have my solutions in https://github.com/asterite/adventofcode2016 and similarly named repos, and user yxhuvud has some pretty cool solutions too (he might have more idiomatic Crystal code)
<FromGitter> <asterite> (old code might not run anymore due to recent breaking changes, though)
<FromGitter> <ilanpillemer> Thanks!
<FromGitter> <ilanpillemer> before I write it myself, is there a permutations call that allows a closure over all permutations?
<FromGitter> <ilanpillemer> I just looked at enumerable and dont seem to see one
<FromGitter> <ilanpillemer> Oh. I see its on Array
<FromGitter> <absolutejam_twitter> > PHP is worse than JavaScript
<FromGitter> <absolutejam_twitter> As weird as it may be, I prefer writing php than js
<FromGitter> <ilanpillemer> wow
<FromGitter> <Blacksmoke16> new php is a bit better
<FromGitter> <absolutejam_twitter> I guess my 'PHP' is laravel
<FromGitter> <Blacksmoke16> i.e. with type hints and such
<FromGitter> <ilanpillemer> I would rather use ASP
<FromGitter> <tenebrousedge> I like the Psy shell
<FromGitter> <absolutejam_twitter> Js is a fucking mess
<FromGitter> <ilanpillemer> TypeScript is worse
<FromGitter> <absolutejam_twitter> At least php is bad all in a single place
<FromGitter> <absolutejam_twitter> But using a decent framework makes up for writing php
<FromGitter> <tenebrousedge> :/
<FromGitter> <absolutejam_twitter> Amber has my attention atm
<FromGitter> <absolutejam_twitter> Might do our next internal quicky app in it
<FromGitter> <absolutejam_twitter> Although, phoenix live view is ❀️
<FromGitter> <absolutejam_twitter> Spoilt for choice
<FromGitter> <watzon> imo laravel is the only good thing in PHP land
<FromGitter> <watzon> How Taylor managed to make crap glitter is beyond me, but he did it
<FromGitter> <ilanpillemer> I kind of liked coffee script.. but it loss momentum
<FromGitter> <absolutejam_twitter> Same
<FromGitter> <ilanpillemer> why is this wrong
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4d09a809de9699f39d305]
<FromGitter> <dscottboggs> @tenebrousedge thanks for the links
<FromGitter> <wontruefree> @naqvis very true I just meant I like the idea of msgpackl
<FromGitter> <bajro17> I like about amber super fast generate of everything like you dont need almost to know programming
<FromGitter> <ilanpillemer> how idiomatic is this?
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4d4b8894dee56e54284a3]
<FromGitter> <tenebrousedge> `each_with_object([] of Int320)`
<FromGitter> <tenebrousedge> or `reduce`
<FromGitter> <tenebrousedge> and you might do `each_line.count`
absolutejam has joined #crystal-lang
<FromGitter> <tenebrousedge> ```STDIN.each_line.count do |line| ⏎ valid(line.split.map(&.to_i)) ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5da4d580c87a1d28acad87c2]
<FromGitter> <ilanpillemer> nice
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4d64089acff6ff5f6f032]
<FromGitter> <tenebrousedge> :plus1:
<FromGitter> <ilanpillemer> 😁
ht_ has quit [Remote host closed the connection]
Nekka has quit [Quit: zzz]
Nekka has joined #crystal-lang
<hypercore> how would you guys compare amber, lucky and phoenix?
<hypercore> and which would you recommend?
<hypercore> in terms of github stars (if that means anything), amber and lucky are about the same now i think
<hypercore> and phoenix is far ahead
<hypercore> really liking lucky so far
<FromGitter> <ImAHopelessDev_gitlab> i found this fwiw https://www.reddit.com/r/crystal_programming/comments/8zthzl/amber_vs_lucky/
<FromGitter> <ilanpillemer> this feels like it could be written much better
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4e08e809de9699f3a531f]
<FromGitter> <tenebrousedge> I would do ⏎ ⏎ ```STDIN.each_line.(&.split.map(&.to_i)).transpose``` [https://gitter.im/crystal-lang/crystal?at=5da4e102dbf67667345d8075]
<FromGitter> <ilanpillemer> I guess you dont need the each_line then
<FromGitter> <ilanpillemer> let me try that
<FromGitter> <tenebrousedge> `.sum(&.in_groups_of(3,0).map(&->valid))`
<FromGitter> <tenebrousedge> or something like that
<FromGitter> <ilanpillemer> those are nice pointers.. now to rewrite
<FromGitter> <tenebrousedge> sorry, `.sum(&.in_groups_of(3,).count(&->valid))`
<FromGitter> <tenebrousedge> but I would probably `alias Sides = Array(Int32)`
<FromGitter> <tenebrousedge> so `.sum(&.in_groups_of(3,0).count(&->valid(Sides)))`
<FromGitter> <tenebrousedge> @ilanpillemer
<hypercore> thanks hopeless
<FromGitter> <ImAHopelessDev_gitlab> πŸ‘
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4e48c809de9699f3a7017]
<FromGitter> <ilanpillemer> slightly better
<FromGitter> <ilanpillemer> though I suspect there is a better way of doing the second part
<FromGitter> <tenebrousedge> rule of thumb: don't use `each` πŸ˜‰
<FromGitter> <tenebrousedge> the exception is if you're doing dynamic programming
<hypercore> what should you use instead?
<FromGitter> <tenebrousedge> or metaprogramming, or possibly output
<FromGitter> <tenebrousedge> in this case `sum`
<FromGitter> <ilanpillemer> what has the `sum` method?
<FromGitter> <ilanpillemer> `tr`?
<FromGitter> <tenebrousedge> enumerable
<hypercore> is this a general rule (to never to each, except for the cases you listed)?
<FromGitter> <tenebrousedge> ```alias Sides = Array(Int32) ⏎ tr.sum(&.in_groups_of(3,0).count(&->valid(Sides)))``` ⏎ ⏎ @ilanpillemer [https://gitter.im/crystal-lang/crystal?at=5da4e615f88b526fb93bfcdf]
<FromGitter> <tenebrousedge> hypercore, `each` is a last resort, where there is no possible return value that would be useful. `reduce` can be used to write all other higher-order iterators, so it's always going to be an option
<hypercore> is this "functional" reasoning?
<FromGitter> <tenebrousedge> if you have more than one variable that you're working with, `reduce` (or the closely related `each_with_object`) can be more of a pain than using `each` and external variables
<hypercore> wasn't .each very popular in ruby?
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4e69357c2517c6a0b9cf9]
<FromGitter> <tenebrousedge> sure, if you want to do it that way
<FromGitter> <tenebrousedge> `each` is very popular among Rubyists who have no idea what they're doing
<FromGitter> <ilanpillemer> ahh.. I didnt know that Proc syntax
<FromGitter> <ilanpillemer> let me learn that
<hypercore> oh lol
<hypercore> i never really used ruby, so im not sure
<FromGitter> <tenebrousedge> @ilanpillemer it's in the Crystal Book somewhere
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4e73c8e2e9a7c6bfaca93]
<FromGitter> <ilanpillemer> that book is not easy to find things in
<FromGitter> <ilanpillemer> or
<FromGitter> <tenebrousedge> there are some useful things it doesn't draw attention to
<FromGitter> <tenebrousedge> @hypercore I'm pretty opinionated about how to write Ruby/Crystal, so take what I say with a grain of salt
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4e7a5158cfd67352f9e94]
<FromGitter> <tenebrousedge> @ilanpillemer yay for one-liners :)
<FromGitter> <tenebrousedge> feel the power of the obfuscated side!
<FromGitter> <ilanpillemer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4e7f265dd8569a0d95fcb]
<FromGitter> <ilanpillemer> is that idiomatic?
<FromGitter> <tenebrousedge> more or less. The rule of thumb is that you shouldn't create a variable unless you use it more than once
<FromGitter> <tenebrousedge> but in real code you would probably break that down into methods and classes
<FromGitter> <ilanpillemer> which I don’t?
<FromGitter> <tenebrousedge> right
<FromGitter> <tenebrousedge> except for `count` which is being interpolated
<FromGitter> <ilanpillemer> but I think that is a good reason
<FromGitter> <tenebrousedge> you could do *shudder* `"part2 => %i valid triangles" % long_functional_chain`
<FromGitter> <tenebrousedge> but that would be pretty gross
<FromGitter> <ilanpillemer> what does `%` do?
<FromGitter> <tenebrousedge> sprintf
<FromGitter> <ilanpillemer> so `=> .. %` is sprintf?
<FromGitter> <tenebrousedge> `String#%`
<FromGitter> <tenebrousedge> I always have to look up the syntax whenever I use it
<FromGitter> <tenebrousedge> there's a tagged version as well that's probably better
<FromGitter> <ilanpillemer> I use sprintf all the time in `go`
<FromGitter> <tenebrousedge> I think it's `"%<count> valid triangles" % {count: 3}`
<FromGitter> <ilanpillemer> no.. no tags
<FromGitter> <ilanpillemer> ugg
<FromGitter> <tenebrousedge> well, it's considered more legible. I rarely find much use for either
<FromGitter> <ilanpillemer> once you are using `sprintf` either you are acclimated you are not. I think tags will just make it noisier.
<FromGitter> <kinxer> Yeah, but maybe someone less acclimated to `sprintf` has to read your code?
<FromGitter> <ilanpillemer> everyone should be acclimated
<FromGitter> <ilanpillemer> because if you ever have to spelunk C code and can’t read sprintf you are in trouble.
<FromGitter> <tenebrousedge> the other difference is that without tags the order of your argument array is significant, whereas the hash order is irrelevant
<FromGitter> <ilanpillemer> how to do this one idiomatically! tomorrow nights’s amusement.. (https://adventofcode.com/2016/day/4)
<FromGitter> <kinxer> @ilanpillemer I agree that we as developers should know how to read older code, but I don't think "The reader should know how to read my less clear code because they might run into it in other places" is a good argument for writing less clear code.
<FromGitter> <tenebrousedge> `sum(arr.reject)` @ilanpillemer, where `reject` is complicated
<FromGitter> <ilanpillemer> thanks for pointer.. that’s where I will start from.. and I resist the `each`.
<FromGitter> <tenebrousedge> @ilanpillemer it's probable that you will want to use `group_by(&.itself)` to group the letters, possibly followed by `transform_values(&.size)` to get the histogram
<FromGitter> <ilanpillemer> `itself` is a thing?
<FromGitter> <tenebrousedge> yup
<FromGitter> <tenebrousedge> of very specialized use
<FromGitter> <ilanpillemer> ok. notes those three calls down in a scratch pad for when I start
<FromGitter> <tenebrousedge> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5da4ec75809de9699f3aa57b]
<FromGitter> <ilanpillemer> so `transform_values` is like map on the `values`?
<FromGitter> <tenebrousedge> yep
<FromGitter> <tenebrousedge> and by inference, `group_by` returns a `Hash`
<FromGitter> <ilanpillemer> so `group by itself` creates a map of `v => v` and then the transform values, changes the value.
<FromGitter> <tenebrousedge> ``````
<FromGitter> <ilanpillemer> That’s a neat little pattern to remember
<FromGitter> <kinxer> What about `Enumerable#tally` (docs (https://crystal-lang.org/api/0.31.1/Enumerable.html#tally:Hash(T,Int32)-instance-method))?
<FromGitter> <tenebrousedge> ahhhhh
<FromGitter> <tenebrousedge> yes, that's the same thing but more concise
<FromGitter> <kinxer> I'm having trouble with this link that contains an end-parenthesis...
<FromGitter> <tenebrousedge> it uses `each_with_object(Hash(T, Int32))`, which is more performant
<FromGitter> <absolutejam_gitlab> Why are you saying not to use `.each`?
<FromGitter> <absolutejam_gitlab> Are you saying there are likely better enumerable methods, or that you should use `reduce`/`map`
<FromGitter> <tenebrousedge> there are likely to be better enumerable methods. At a minimum, `reduce` should be an option, since it can be used to write all other higher-order iterators
<FromGitter> <tenebrousedge> I mark dynamic programming as a wide range of exceptions
<FromGitter> <lbarasti> A question about `shard.yml`: what is the purpose of the field `crystal: 0.30.0`? Is that actually used by `shards` in any way? Or is it just a human readable way of saying: you should compile this shard with this version?
<FromGitter> <lbarasti> found my answer
<FromGitter> <tenebrousedge> :plus1:
absolutejam has quit [Ping timeout: 240 seconds]
absolutejam has joined #crystal-lang
<FromGitter> <Daniel-Worrall> That is actually used by crenv to determine which crystal version to run locally
<FromGitter> <Daniel-Worrall> And I just set my global to latest
absolutejam has quit [Ping timeout: 240 seconds]
<FromGitter> <lbarasti> > That is actually used by crenv to determine which crystal version to run locally ⏎ nice!
absolutejam has joined #crystal-lang
absolutejam has quit [Ping timeout: 240 seconds]
<FromGitter> <didactic-drunk> Is travis `dist: trusty` not supported?
<FromGitter> <ilanpillemer> is there a way of reordering a hash?
<FromGitter> <tenebrousedge> like `sort_by` ?
<FromGitter> <ilanpillemer> Yes
<FromGitter> <ilanpillemer> I didn't see a sort by in the API docs.
<FromGitter> <Blacksmoke16> Would have to new up a new one and rebuild it
<FromGitter> <tenebrousedge> huh, sort_by is on `Array`?
<FromGitter> <ilanpillemer> I couldn't find one on hash
<FromGitter> <tenebrousedge> yeah, apparently you're not supposed to depend on the ordering
<FromGitter> <tenebrousedge> you can to `to_a.sort_by`
<FromGitter> <ilanpillemer> Lol
<FromGitter> <tenebrousedge> I honestly think that's silly
<FromGitter> <ilanpillemer> Go forbids it by torturing you, if you do.
<FromGitter> <tenebrousedge> hashes have a very hard guarantee of being sorted by insertion in Crystal though
<FromGitter> <tenebrousedge> for one, Ari said so :P
<FromGitter> <ilanpillemer> Unless you change the key.
<FromGitter> <tenebrousedge> but also the implementation kinda depends on it
<FromGitter> <ilanpillemer> Unless you change the key, post fact
<FromGitter> <ilanpillemer> The docs say behaviour becomes undefined if you do.
<FromGitter> <tenebrousedge> you're talking about the comments in hash.cr ?
<FromGitter> <ilanpillemer> In the API doc.
absolutejam has joined #crystal-lang
<FromGitter> <tenebrousedge> I think `hash.cr` goes into detail about what happens when you do that
<FromGitter> <ilanpillemer> It says. Undefined.
<FromGitter> <ilanpillemer> That scary word.
<FromGitter> <ilanpillemer> That word that means. I wouldn't if was you
<FromGitter> <ilanpillemer> NOTE When using mutable data types as keys, changing the value of a key after it was inserted into the Hash may lead to undefined behaviour. This can be restored by re-indexing the hash with #rehash
<FromGitter> <tenebrousedge> indexing with a mutable type is probably not a good idea
<FromGitter> <tenebrousedge> mutable types aren't necessarily a great idea either
absolutejam has quit [Ping timeout: 240 seconds]
<FromGitter> <ilanpillemer> Well. What happens if you try an sort?
<FromGitter> <tenebrousedge> you'd have to create a new data structure, it seems
<FromGitter> <tenebrousedge> `hash.to_a.sort_by(&.first).to_h`
<FromGitter> <ilanpillemer> Well. If you think about how a hash is physically stored.
<FromGitter> <ilanpillemer> It's not really sortable.
<FromGitter> <tenebrousedge> I wouldn't have much of a clue, for sure
<FromGitter> <ilanpillemer> It stored so you can lookup by O(1)
<FromGitter> <ilanpillemer> Which means the hash of the value, which should ideally be unique.
<FromGitter> <ilanpillemer> Those hashed values are unlikely to be anything usefully sortable.
<FromGitter> <tenebrousedge> `hash.cr` goes over it. It uses 32 bits, of which 28 are addressable
<FromGitter> <ilanpillemer> How does it work out the hash?
<FromGitter> <tenebrousedge> I don't know o_o;; I just know `HASH_MAX_ENTRIES` is 2^28
<FromGitter> <ilanpillemer> Yeah. The hash algo itself is probably more interesting
dwdv_ has quit [Ping timeout: 250 seconds]