<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`?
<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
<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> 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>
<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 %}`
<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
<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>
<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]
<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>
<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
<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
<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>
<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
<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>
<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>
<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>
<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