jhass changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Crystal 0.35.1 | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
<o5r> Is there any way to get all things annotated with a certain annotation at compile time? Trying to figure out a way to plug openapi definitions on top of annotations.
<FromGitter> <Blacksmoke16> All things meaning methods or types?
<o5r> good question. probably methods. the more I think about it the more I think I probably have it backwards
<FromGitter> <Blacksmoke16> Oh?
<o5r> well. it's a statically typed language with a lot of cool type stuff. i could define a few good functions to declare typed handlers. it must already exist, even.
<FromGitter> <Blacksmoke16> Hmm
<FromGitter> <Blacksmoke16> got an example of what you're trying to do?
<FromGitter> <Daniel-Worrall> Hmm... how should I loop forever unless I provide a number of iterations to complete? ⏎ ⏎ I'm thinking something like ⏎ ⏎ `````` [https://gitter.im/crystal-lang/crystal?at=5fd4114928a57c581b0a0e1d]
<FromGitter> <Daniel-Worrall> oops
<FromGitter> <Daniel-Worrall> ```unless iterations.nil? || iterations <= 0 do ⏎ # stuff ⏎ iterations -= 1 ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5fd4117b03da931ac2484de8]
<FromGitter> <Daniel-Worrall> oh no, ⏎ ⏎ ```while iterations.nil? || iterations > 0 do ⏎ # stuff ⏎ iterations -= 1 if iterations``` [https://gitter.im/crystal-lang/crystal?at=5fd411b85a63c56105254ad0]
<FromGitter> <Daniel-Worrall> Something like that? Or is there a better way
<FromGitter> <Blacksmoke16> could you just like `loop do` then add in some stuff like `break if iterations && iterations == i`
<FromGitter> <Daniel-Worrall> I just wonder if it'll optimise out
<FromGitter> <Daniel-Worrall> break also feels like a very forceful keyword, so I avoid it for no real reason
<FromGitter> <Daniel-Worrall> hmm and I can return from the break too with `var = loop ... break result`
<FromGitter> <Daniel-Worrall> What do people prefer? `{} of K => V` or `Hash(K, V).new`?
<oprypin> Daniel-Worrall, usually 1st but proponents of 2nd are more vocal
<oprypin> AAAAAAAAAAAa see i'm more vocal
<FromGitter> <Daniel-Worrall> obviously 2nd has more options, but when you just need the basic
<FromGitter> <Daniel-Worrall> Yes, you are. *pat*
<Andriamanitra> i prefer the 2nd one mostly because {} are bit of a pain on my keyboard layout
<FromGitter> <Daniel-Worrall> time to learn qwert
<FromGitter> <Daniel-Worrall> at least an English variant
<FromGitter> <Daniel-Worrall> Does a hash ever decrease its capacity?
<FromGitter> <tenebrousedge> the comments in `hash.cr` are pretty informative
<FromGitter> <Daniel-Worrall> I'm going through it now
<FromGitter> <Daniel-Worrall> I'm wondering about if I should initialise a hash with a initial capacity I know as the "max" elements it'll contain, but it'll usually hold about 1/3-1/2 of that
<FromGitter> <Daniel-Worrall> I found the bit about deleted entries not being "removed" until needed but I won't be removing
deavmi has quit [Read error: Connection reset by peer]
<FromGitter> <tenebrousedge> how many hashes are you creating?
deavmi has joined #crystal-lang
<FromGitter> <Daniel-Worrall> In this case, 1, but I'm curious on the possible optimisations I could put in place in future if/when I'm creating more hashes
<FromGitter> <Daniel-Worrall> I wanna instill some good practices in my coding, so I'm curious on the inner workings
<FromGitter> <tenebrousedge> well, the comments are more informative than I can be, but I think that I'm not often creating lots of hashes, so while I would take some effort to avoid intermediate arrays, I haven't had to worry too much about how big my hashes are
<FromGitter> <Daniel-Worrall> yeah, ty
<FromGitter> <Daniel-Worrall> I feel like there should be a hash method that does `.each.to_h`
<FromGitter> <Daniel-Worrall> like `map_hash`
<FromGitter> <tenebrousedge> `to_h` takes a block
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <Daniel-Worrall> Oh.
<FromGitter> <Daniel-Worrall> I'm dumb
<FromGitter> <tenebrousedge> mp
<FromGitter> <tenebrousedge> no
<FromGitter> <tenebrousedge> I learned about it a few AoC challenges ago, from asterite
<FromGitter> <Daniel-Worrall> I only paid attention to the one that is defined on Hash, not the one included by Enumerable
<FromGitter> <Daniel-Worrall> AoC is really giving me a lot of Iterable/Enumerable insights
<FromGitter> <tenebrousedge> I've been tormenting Enumerable for sure
<FromGitter> <tenebrousedge> but I'm behind on them
<FromGitter> <Daniel-Worrall> What we need is some better documentation
<FromGitter> <Daniel-Worrall> An intermediary between Reference and Docs
<FromGitter> <Daniel-Worrall> (by better, I mean more expansive. The docs we have are amazing, we just need *more*)
<FromGitter> <Daniel-Worrall> Or maybe some "See also" notes on methods that are related
<FromGitter> <Daniel-Worrall> What I get lost in are all the different methods with the same name but different params. Maybe some way to group these together
<FromGitter> <Blacksmoke16> oh boy, dont let girng see that
<FromGitter> <Daniel-Worrall> I have opinions, and I will share them!
<FromGitter> <Daniel-Worrall> Ooh, one thing. I can't provide a capacity to `to_h`
<FromGitter> <tenebrousedge> nope
<FromGitter> <Daniel-Worrall> I feel like I should be able to
<FromGitter> <Daniel-Worrall> At least for the block variant
<FromGitter> <Blacksmoke16> add a monkeypatch :p
<FromGitter> <Daniel-Worrall> I could
<FromGitter> <tenebrousedge> I feel like there are pretty limited situations where you need that
<FromGitter> <Daniel-Worrall> but I'd rather create an Issue and get it in for 1.0
<FromGitter> <Daniel-Worrall> Well if you're mutating a hash or array to hash, you'll get an optimisation for allocations if you pass the capacity (assuming you're not skipping any elements)
<FromGitter> <tenebrousedge> will you?
<FromGitter> <Daniel-Worrall> After I search if it already exists
<FromGitter> <tenebrousedge> I mean why not just do `arr.reduce(Hash.new(whatever size args))`
<FromGitter> <Daniel-Worrall> Can do for my case. Will RFC and see what the community thinks
<FromGitter> <Daniel-Worrall> Or is this more applicable for a forum post
<FromGitter> <tenebrousedge> I mean it sounds like a feature request
<FromGitter> <Daniel-Worrall> Indeed, so GH Issues?
<FromGitter> <tenebrousedge> yar
<FromGitter> <wontruefree> @kingsleyh
chachasmooth has quit [Ping timeout: 258 seconds]
chachasmooth has joined #crystal-lang
<FromGitter> <watzon> I'm gonna have to go back and watch all the talks I missed
<FromGitter> <watzon> Very nice to see Crystal finally having a conference though. Maybe next year we can have a physical one.
f1refly has joined #crystal-lang
f1reflyylmao has quit [Ping timeout: 240 seconds]
<FromGitter> <Daniel-Worrall> Yeah, I only got to see half of them
<FromGitter> <Blacksmoke16> I'll start preparing my keynote /s
<FromGitter> <Daniel-Worrall> I'd love a physical conference
<FromGitter> <watzon> No /s. Next year it's you and me @Blacksmoke16.
<FromGitter> <Daniel-Worrall> Just request that you come to the UK ;)
<FromGitter> <Blacksmoke16> 😎
<FromGitter> <watzon> Let's make it hard for everyone and do it in Argentina
<FromGitter> <Daniel-Worrall> Let's do it in Ary's backyard. Literally.
avane has quit [Quit: ZNC - https://znc.in]
<FromGitter> <watzon> I'm down. @asterite get ready.
avane has joined #crystal-lang
liteyear has quit [Quit: liteyear]
<hightower3> #occupyAry :)
<Andriamanitra> should String#index accept a block?
<Andriamanitra> although i guess .chars.find achieves the same thing
<FromGitter> <3n-k1> can i not use the codepoint of a Char as an enum value?
<FromGitter> <3n-k1> ```enum Cell ⏎ Floor = ('.'.ord).to_u8``` [https://gitter.im/crystal-lang/crystal?at=5fd4514228a57c581b0a93b2]
<FromGitter> <Daniel-Worrall> y'all so fast on the problems
<FromGitter> <Daniel-Worrall> (AoC)
<FromGitter> <watzon> @3n-k1 apparently not
deavmi has quit [Ping timeout: 272 seconds]
<Andriamanitra> relatively easy day compared to the last few.. probably could've gotten it faster if i wasn't trying to be fancy in stupid ways again
<FromGitter> <Daniel-Worrall> Was there a similar problem last year?
<FromGitter> <Daniel-Worrall> I feel like I remember it
<Andriamanitra> i'm sure there have been some problems with NESW movement and rotating, can't remember exactly though
<FromGitter> <Daniel-Worrall> ooh, that's a nice way of using Complex
<FromGitter> <Daniel-Worrall> I didn't think of that
<FromGitter> <3n-k1> i think i found an off by one error in the compiler?
<FromGitter> <3n-k1> ```code paste, see link``` ⏎ ⏎ but line 34 is `has_changed = true`. line 33 has the `#[]=` method call tho. is that a feature or a bug? [https://gitter.im/crystal-lang/crystal?at=5fd4616e0697c1210db80441]
<FromGitter> <Daniel-Worrall> Are you able to post a minimal reproduction?
<FromGitter> <3n-k1> gimme a sec to try
<FromGitter> <Daniel-Worrall> or the whole thing if you don't mind sharing
<FromGitter> <3n-k1> minimal repro source ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fd463fd5a63c5610525f241]
<FromGitter> <3n-k1> errors on `has_changed` with ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fd4641b9700c07b17e630c1]
<FromGitter> <Daniel-Worrall> It's not quite an off by one, it seems to just point to the next assignment in the block if one exists
<FromGitter> <Daniel-Worrall> if there are multiple assignments afterwards, it is just the next one
<FromGitter> <Daniel-Worrall> no matter where it is, how many lines there are, how indented
<FromGitter> <Daniel-Worrall> It's a weird bug
<FromGitter> <3n-k1> huh
<FromGitter> <Daniel-Worrall> probably my weirdest method to date ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fd4795c82222960e4de7d0f]
deavmi has joined #crystal-lang
ua_ has joined #crystal-lang
ua has quit [Ping timeout: 256 seconds]
_ht has joined #crystal-lang
<FromGitter> <Daniel-Worrall> Hm... while loops don't return using break
<FromGitter> <Daniel-Worrall> but loops do
<FromGitter> <Daniel-Worrall> That's an odd difference
<FromGitter> <Daniel-Worrall> I'd like to see that implemented
deavmi_ has joined #crystal-lang
deavmi has quit [Read error: Connection reset by peer]
<FromGitter> <asterite> Happy to host everyone here! I can send you a picture of my backyard and then you can decide :-)
<FromGitter> <watzon> Deal!
<raz> hmm. is there an easy way to iterate over pairs of items in an ArrayLiteral in a macro? i'm looking for sth like `{% for name, size in %w[name_a 5 name_b 6 name_c 7] %}`
<FromGitter> <Daniel-Worrall> omg, `each_with_index` has an offset param. TIL
<raz> ohh, nice, didn't know that either
<raz> anyway, n/m my question, i now solved it another way :)
<FromGitter> <Daniel-Worrall> ```(arr.size // 2).times do |i| ⏎ number = arr[2 * i] ⏎ word = arr[2*i + 1] ⏎ end``` ⏎ ⏎ but macroland [https://gitter.im/crystal-lang/crystal?at=5fd496ad55c9c37b305f1276]
<FromGitter> <Daniel-Worrall> swap number/word for name/size
<raz> yup, i realized i don't want that in the long run anyway, so went for a slightly more verbose route
<FromGitter> <Daniel-Worrall> fair
<FromGitter> <Daniel-Worrall> Hmmm `.reject(&.nil?).map(&.not_nil!)` is it possible to not have to not_nil! these?
<FromGitter> <Daniel-Worrall> I guess is it worthwhile for the compiler to detect that and cast down
<FromGitter> <Daniel-Worrall> eh, the source code is simple enough, I can just write it myself
<FromGitter> <asterite> Here's the backyard: https://photos.app.goo.gl/6rsw4MuBPVaV9BTL6
<FromGitter> <Daniel-Worrall> Enough space for 50 people. I say we go for it
<FromGitter> <watzon> Hell yes, I would very much like to come to Argentina next year
<FromGitter> <asterite> @Daniel-Worrall you can write `reject(Nil)` or `compact`
<FromGitter> <Daniel-Worrall> Sweet.
JuanMiguel has joined #crystal-lang
JuanMiguel has quit [Client Quit]
<yxhuvud> @asterite: todays aoc is an excellent example of why I prefer if Complex stays :)
<Andriamanitra> has there been talk of complex not staying? D:
<Andriamanitra> i always use complex for anything 2d, and even C has them!
<FromGitter> <asterite> yxhuvud: why?
<yxhuvud> it will be fairly obvious when you see my solution :)
<yxhuvud> (which requires me to clean it up, which is not done yet)
<Andriamanitra> mine also makes good use of complex
<FromGitter> <asterite> can you rotate a complex?
<yxhuvud> multiply by i.
<Andriamanitra> you could but i can never remember the formula so i did it the stupid way
<Andriamanitra> i wouldn't be against a method to do the rotation
<Andriamanitra> yxhuvud: nice!
<yxhuvud> the approach of separating the pos into separate variables asterite used was pretty neat too though.
<FromGitter> <asterite> I guess Complex is relatively small do it's fine if it stays in the std
<FromGitter> <asterite> I don't know if it's missing any methods, though
<yxhuvud> that may be fine, it is far from all methods on Ints that make sense on Complex anyhow.
<FromGitter> <Daniel-Worrall> The problem I have with complex is it uses float so not optimal for discreet grids
<FromGitter> <Aaron-JM> Could someone possible demonstrate the correct crystal language syntax for a lambda expression? Thanks
<FromGitter> <naqvis> @Aaron-JM Refer to Crystal Reference Blocks and Procs (https://crystal-lang.org/reference/syntax_and_semantics/blocks_and_procs.html) section
<FromGitter> <j8r> yxhuvud is Complex used instead of x,y coordinates?
<yxhuvud> usually when I use them, at least.
<FromGitter> <j8r> IMHO using a struct with x,y properties is simpler to understand. Or a tuple
<FromGitter> <j8r> Plus, you can do OOP by attaching methods
<FromGitter> <j8r> *struct or class
<oprypin> using Complex for x,y should be reserved strictly to code golf
<yxhuvud> Why?
<FromGitter> <eliasjpr> Given the big success of Raw Crystal and the possible v1 release, are there any books plan for the v1 launch? For instance a book about the crystal compiler Crystal Internals, a Book about the Standard Lib, and/or a cookbook?
<FromGitter> <j8r> It feels wrong to use complex
<oprypin> well it's just literally wrong
<FromGitter> <j8r> Why x is real, and y imaginary, and not the other way around?
<yxhuvud> j8r: either one works, though the code for rotations would change.
<yxhuvud> oprypin: No. Why do you think that?
<FromGitter> <HertzDevil> the convention of using x for real and y for imag probably comes from atan2
<FromGitter> <j8r> I'm not a methematician, but after looking at the properties of Complex in Wikipedia, I don't see how they are used in the context of 2D grids...
<FromGitter> <j8r> I just see here that Complex is used as a x,y coordinates object store
<yxhuvud> j8r: Complex numbers *is* a 2d coordinate system, which has built in really convenient ways of rotating 90 degrees.
<yxhuvud> (and FWIW, quaternions is simularly really convenient to work with for working with 3d numbers)
<FromGitter> <j8r> Complex could a generic... So, the inial numbers types would be preserved
<yxhuvud> I wouldn't mind that, but it is probably an approach limited by that the implementations for some of the methods on it is using C libraries that may or may not have all the variations you'd want.
<FromGitter> <j8r> yxhuvud I rembered using radians and atan2 for such cases, was not hard
<FromGitter> <HertzDevil> iso c complex has Float32, Float64, and long double
<FromGitter> <j8r> 90deg is Pi/2, 180 is Pi
<FromGitter> <HertzDevil> ~~not really because iso c floats aren't required to be ieee-754 single/double floats~~
<FromGitter> <j8r> I think i could use Complex for my 2D game, but I already have something working. And it will creates lots of complex, so would be a bit slower
<FromGitter> <j8r> I don't see anything complicated in Complex, I thought it would have more code...
<FromGitter> <Daniel-Worrall> Complex numbers are literally a 2d plot, not just in that it stores 2 numbers, but it is studied as such and the trig functions are strongly bound to it. I only complain about using it because it uses floats where AoC uses ints
<FromGitter> <Daniel-Worrall> A generic complex class would be nice imo
<FromGitter> <Daniel-Worrall> Do we have a good matrix shard?
o5r has quit [Ping timeout: 264 seconds]
<FromGitter> <j8r> Agree. I don't mind Complex, it is rather simple
<FromGitter> <j8r> Also there are much bigger chunks in the code base that could be removed
<FromGitter> <christopherzimmerman> @Daniel-Worrall what are you looking to use the matrices for? `Num.cr` might have what you are looking for.
<FromGitter> <christopherzimmerman> It has support for Complex matrices, as well as provides access to most plenty of linear algebra routines for them.
<hightower3> Hey why doesn't this work: https://carc.in/#/r/a3ps
<hightower3> or rather, how to make it work :)
<FromGitter> <Blacksmoke16> https://carc.in/#/r/a3pt
<hightower3> +1
<hightower3> If I have a HashLiteral or ArrayLiteral in macros, what's the most convenient way to turn this into Hash/Array?
<FromGitter> <Blacksmoke16> `{{array_literal}}`
<hightower3> Hm. seems like there is includes? on ArrayLiteral, but not has_key? on HashLiteral
<FromGitter> <Blacksmoke16> just use `#[]` and check if its `nil`
<FromGitter> <tenebrousedge> macros make me sad
<FromGitter> <erdnaxeli:cervoi.se> how can I write a test to check there is no value to read on a channel?
<FromGitter> <erdnaxeli:cervoi.se> I currently do a select with when and else, and raise in the when
<oprypin> erdnaxeli:cervoi.se, https://crystal-lang.org/api/master/Channel.html#receive?:T?-instance-method
<FromGitter> <erdnaxeli:cervoi.se> but it puts to test on error, not on failure
<FromGitter> <erdnaxeli:cervoi.se> oprypin (https://matrix.to/#/@oprypin:matrix.org): it says this method blocks
<oprypin> oops
<oprypin> your select method is good, then. i dont understand the problem
<FromGitter> <erdnaxeli:cervoi.se> the problem is that I do ⏎ ⏎ ```select ⏎ when channel.receive ⏎ raise "no value was expected" ⏎ else ⏎ end``` ⏎ ⏎ When the test fails, it raises, which is seen as an error and not a failure [https://gitter.im/crystal-lang/crystal?at=5fd5159a28a57c581b0c4f60]
<FromGitter> <Blacksmoke16> `expect_raises`?
<FromGitter> <oprypin> no but.. it should be expect not raises
<FromGitter> <erdnaxeli:cervoi.se> https://crystal-lang.org/api/master/Spec/Methods.html#fail(msg,file=__FILE__,line=__LINE__)-instance-method oh this is a thing!
<oprypin> when received = channel.receive;
<oprypin> then later `received.should be_nil`
<oprypin> oh nice fail is even better
<FromGitter> <Blacksmoke16> here's a random hash question
<FromGitter> <erdnaxeli:cervoi.se> thanks for your help :)
<FromGitter> <Blacksmoke16> is there any benefit between these two? I'm thinking they essentially equivalent? ⏎ ⏎ https://play.crystal-lang.org/#/r/a3ql
<FromGitter> <Blacksmoke16> but it feels weird the key and value is the same thing
<FromGitter> <Daniel-Worrall> > If focus is true, only this test, and others marked with focus: true, will run. ⏎ This is on the `pending` docs lol
<oprypin> Blacksmoke16, if everything is separated by a newline, then nothing is
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <Daniel-Worrall> how can a pending test ever run :^)
<oprypin> Blacksmoke16, might as well post it like https://play.crystal-lang.org/#/r/a3qn
<FromGitter> <tenebrousedge> what are you trying to do @Blacksmoke16
<FromGitter> <Blacksmoke16> keep a hash of objects identified by their object id
<FromGitter> <Blacksmoke16> that seems to be what `compare_by_identity` does
<FromGitter> <Blacksmoke16> but the fact that the key and value would be the same is kinda weird?
<FromGitter> <tenebrousedge> yes
<oprypin> Blacksmoke16, use a `Set` then??
<FromGitter> <Blacksmoke16> oh wait, in this case i think i could
<FromGitter> <Blacksmoke16> also have some hashes like `Hash(UInt64, EnumType).new` that could probably be `Hash(Parent, EnumType).new.compare_by_identity)`
<FromGitter> <Blacksmoke16> instead of manually working with object id
<oprypin> u dont even need `compare_by_identity` if u dont redefine `==`
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <Blacksmoke16> fair point
<FromGitter> <Blacksmoke16> so in reality it would prob be enough to just do `Hash(Parent, EnumType)` then
<oprypin> ye
<FromGitter> <Blacksmoke16> cool
o5r has joined #crystal-lang
<FromGitter> <Blacksmoke16> yea that cleaned up things quite a bit
DTZUZU has quit [Ping timeout: 240 seconds]
_ht has quit [Remote host closed the connection]
sorcus has quit [Quit: WeeChat 2.9]
sorcus has joined #crystal-lang
<o5r> Well this is a really interesting use of annotations: https://github.com/crystal-lang/crystal/blob/5999ae29b/src/json/serialization.cr#L156
<FromGitter> <Blacksmoke16> heh
<o5r> Blacksmoke16: that's kind of where i wanted to take my annotation stuff yesterday; OpenAPI spec at compile time would be _excellent_ for some of my use cases
<FromGitter> <Blacksmoke16> got an example of what kind of API you're looking for?
<o5r> not really yet. it's going to be for mostly run-of-the-mill REST stuff.
<o5r> for reference, what i'll try to automate
<o5r> (when i have time, someday)
<FromGitter> <Blacksmoke16> im familiar with the spec, but depending on how exactly you want it to work will determine if its possible
<FromGitter> <Blacksmoke16> like i assume you're going to need to integrate into various frameworks? or?
<hightower3> What's a good rule of thumb for deciding when I'm gonna provide initialize() with different overloads, and when I'm gonna have a series of self.from_XYZ constructors?
<FromGitter> <Blacksmoke16> depends on the context, like what reads better and such
<FromGitter> <Blacksmoke16> as there's not really a difference between `def self.new` and `def self.create` other than the name you call
<hightower3> right, ok thanks
<FromGitter> <Blacksmoke16> the former is the more ideal case when you want to just wrap the initialize calls, but the former is useful for having a more readable api
<FromGitter> <Blacksmoke16> like `SomeException.with_errors errors`
<hightower3> spot on
<o5r> Blacksmoke16: haven't gotten as far as that yet. if possible I'd like to make it as "freestanding" as possible, but I'm still really new around Crystal. This should be interesting, at any rate. Failure is also an acceptable outcome.
<FromGitter> <Blacksmoke16> 👍 im quite familiar with annotations if you want to bounce anything off me
<o5r> Thanks, I'll keep you posted!
<FromGitter> <j8r> o5r can interest you https://github.com/grip-framework/gripen
<FromGitter> <j8r> Based on the routes, it can generate an OpenAPI doc
<FromGitter> <j8r> It uses types to do so, which means no possible hand-written annotation error
<FromGitter> <j8r> hightower3 just, avoid having an initialize calling another one, use self.new instead
<FromGitter> <j8r> Less overhead
<hightower3> ok, thanks!
<hightower3> Although, won't that then allocate 2 objs, or some magic happens behind?
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <j8r> self.new is only a regular class method, vs initialize that allocates. Calling twice will do so twice
<FromGitter> <j8r> I don't knoe about `super` though, I suspect same story
<hightower3> Isn't new == (allocate + initialize), that is, it's new that allocates, not initialize?
<FromGitter> <Blacksmoke16> the compiler creates a `self.new` method based on your initialize methods
<o5r> j8r: oh that is good
<FromGitter> <j8r> No, `def initialize` creates a special `self.new` class method, which allocates
<FromGitter> <j8r> I don't know if this tip is in the Crystal Reference
<hightower3> Yes, I mean, I don't understand why is e.g. def initialize(x); self.new x[0]; end better than e.g. def initialize(x); initialize x[0]; end... I thought that the first variant would allocate 2 objects
<FromGitter> <Blacksmoke16> you do it the other way
<FromGitter> <Blacksmoke16> `def self.new` should call your initialize methods
<hightower3> Yes but I'm never defining any `new` methods explicitly
<FromGitter> <Blacksmoke16> thats what `initialize` does
<hightower3> I mean... when the code gets to the point of calling initialize(), the object has already been allocated.
<FromGitter> <Blacksmoke16> thats not true
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5fd542f555c9c37b30609504]
<FromGitter> <Blacksmoke16> the range `self.new` doesnt allocate anything until it calls the `initialize` based `new` method
<FromGitter> <j8r> It should not have been already allocated hightower3
<FromGitter> <j8r> Doing it twice is an unecessary overhead
<hightower3> I thought that the default (the automatically created) new() method does allocate+initialize. I agree that your example above of an overriden new() method doesn't allocate anything, but that's because it's been overriden.
<hightower3> I'll check the docs again, since obviously you're telling me that's not true
<FromGitter> <Blacksmoke16> its not overridden, its just an extra overload
<hightower3> yeah yeah, I mean... when you call it, it won't allocate, that's clear
<hightower3> when you call that particular overload, that is..
<FromGitter> <Blacksmoke16> correct
<hightower3> ok, time to do some reading then :)
<hightower3> I think I am right that the automatically generated new() method does allocate() + initialize(). Check the last paragraph of https://crystal-lang.org/reference/syntax_and_semantics/new%2C_initialize_and_allocate.html
<hightower3> So, with that, I don't understand j8r's comment that having one initialize which calls another initialize generates some overhead
<FromGitter> <j8r> as you said, initialize generates a new that allocates
<FromGitter> <j8r> that's why in the @Blacksmoke16 example, `self.new` is used instead of `initialize`
<hightower3> Yes, sure. But the point is to do call initialize() at one point... I would say it is the same computationally whether you call:
<hightower3> custom new (which doesn't allocate) -> default new (which allocates) -> initialize
<hightower3> or
<hightower3> default new (which allocates) -> first initialize -> second initialize
<FromGitter> <Blacksmoke16> Not sure I follow anymore
<FromGitter> <j8r> At the end, `initialize` should only be called once. If overloads are needed, use `self.new`
<hightower3> I received instruction that I should avoid calling one initialize from another initialize... and that I should be munging new()s instead.
<hightower3> So I gave this example just above (2-3 lines above), asking what's the real difference?
<FromGitter> <j8r> if you do manually, it will like doing `Myclass#allocate` multiple times - no point
<hightower3> I think that calling initialize(), in runtime, regardless how many times you do it, does not trigger any allocation. The allocation was done in new() which happened before initialize() was called.
<FromGitter> <j8r> Do benchmarks, see yourself ;)
<FromGitter> <j8r> no no
<FromGitter> <j8r> initialize, as you said, is self.new + allocate inside
<FromGitter> <j8r> it creates a self.new method, or overload, which allocates. It will do so n times when called n times
<hightower3> I think this is not in runtime -- I think this is what happens in compile time... you define your constructor args in initialize(..args..) and the compiler helpfully creates you new() method for each ..args.. types.
<hightower3> I am almost certain that initialize() does not allocate multiple times.. because if it did, then calling initialize() would be giving you different objects each time
<FromGitter> <j8r> yes, what I mean is
<FromGitter> <j8r> ```def initialize(num) ⏎ end ⏎ def initialize ⏎ new(1) ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5fd5559382222960e4e0636c]
<FromGitter> <j8r> put in a class, and call `MyClass.new`, two allocations will happen, logic
<hightower3> I don't think that's true... check this: https://carc.in/#/r/a3ri
<hightower3> You get the same address, right? and it's the same object...
<FromGitter> <Blacksmoke16> You're calling the initialize method directly, ofc that's not going to allocate
<hightower3> yes, of course. j8r told me: "hightower3 just, avoid having an initialize calling another one, use self.new instead. Less overhead"
<hightower3> And I said that I don't understand what overhead is there in one initialize calling another
<FromGitter> <j8r> I thought we can do `new` inside `initialize`...