ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Fund Crystal's development: | GH: | Docs: | Gitter:
<FromGitter> <> `with elt yield` worked, but not with `&.round`...had to be `{ round }
<FromGitter> <Blacksmoke16> the former should work if you just do `yield elt`
<FromGitter> <Blacksmoke16> iirc `with .. yield` is kinda buggy in some cases
<FromGitter> <Blacksmoke16> so :shrug:
<FromGitter> <> Pretty nifty, it works
<FromGitter> <> This will do until I macroize things, thanks
<FromGitter> <Blacksmoke16> ๐Ÿ‘
<FromGitter> <> I'm not quite sure how I'd call element_wise for this one though, as it takes a second argument: โŽ โŽ ```code paste, see link``` []
<FromGitter> <Blacksmoke16> prob just keep it as is?
<FromGitter> <> There's a bunch like that. They all have the same pattern, just additional args
<FromGitter> <Blacksmoke16> id say just go with a macro imo
<FromGitter> <Blacksmoke16> even if you have a helper private method its still just boilerplate
<FromGitter> <> I'm feeling a little intimidated by Crystal macros still
<FromGitter> <> Spent last night trying to figure out the basics from reading the docs...couldn't apply it to my own code
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <Blacksmoke16> assumes the method name is the same as the method called on the element, but could easily work around that if thats not what you want
<FromGitter> <> In my case, I'd only want to generate the method body, not the whole method, supplying the name of the method called on the element
<FromGitter> <> and therefor without a hard-coded list of strings too
<FromGitter> <didactic-drunk> @postmodern @kevinsjoberg Absolutely if possible but I don't know how to handle fork. โŽ โŽ ```code paste, see link``` []
<FromGitter> <Blacksmoke16> why would it matter?
<FromGitter> <didactic-drunk> I think asterite said it's going away because of this problem with `-Dpreview_mt`. Fork won't be possible when MT is out of preview
ur5us has quit [Ping timeout: 255 seconds]
ua__ has quit [Ping timeout: 250 seconds]
ua__ has joined #crystal-lang
ua__ has quit [Ping timeout: 268 seconds]
<FromGitter> <> @Blacksmoke16: I took your advice ๐Ÿ˜€
<FromGitter> <Blacksmoke16> ๐Ÿ‘
<FromGitter> <> Wrote the crappiest macro/mixin ever
<FromGitter> <Blacksmoke16> hmm
<FromGitter> <Blacksmoke16> i have an idea
<FromGitter> <> This is intended to be included on all 3 of my vector types. I may split it up into 2 mixins, for the methods that don't make sense for matrices
<FromGitter> <Blacksmoke16> ```code paste, see link``` โŽ โŽ I think that should work []
<FromGitter> <Blacksmoke16> or even `element_wise frac { elt - elt.floor }`
<FromGitter> <> Idea is to try to get rid of all references to `@x`, `@y`, etc so it's DRY for the related types
<FromGitter> <> Oh, lemme read
<FromGitter> <Blacksmoke16> also fwiw `out` is a keyword so prob wouldn't be a bad idea to pick something else
<FromGitter> <Blacksmoke16> technically works, but going to mess up highlighting
<FromGitter> <> I mean, that doesn't save any code by expanding into a toplevel definition, and imho isn't as easy to scan the file
<FromGitter> <Blacksmoke16> ๐Ÿค” how do you figure that doesn't save any code?
<FromGitter> <> re: `out`: ok
<FromGitter> <> 9-11 are 3 lines. so is 24-26 in mine?
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <> I could just as well do that with mine since they're short, albeit a bit differently
<FromGitter> <> The benefit is I instantly know they are `def`s, and syntax highlighting gives my brain less to process when quickly scanning a source file
<FromGitter> <> Correct me if I'm wrong :)
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <> But I'll think about it. You have given me nothing but good suggestions this week and I am a bit tired now and about to quit, so we'll see. Thank you
ur5us has joined #crystal-lang
<FromGitter> <Blacksmoke16> o/
<FromGitter> <Blacksmoke16> on an unrelated note, is this output expected?
<FromGitter> <Blacksmoke16> i would have expected the output from
ua__ has joined #crystal-lang
<FromGitter> <Blacksmoke16> looks to be a regression in `0.31.0`
ua__ has quit [Ping timeout: 255 seconds]
ua__ has joined #crystal-lang
<FromGitter> <mattrberry> Out of curiosity, are there downsides to a type system that supports something like this?
ur5us has quit [Ping timeout: 240 seconds]
<FromGitter> <HertzDevil> crystal-lang/crystal#8232
<raz> `if foo = bar` should be a syntax error
<raz> i keep seeing it in crystal code used as a workaround for .try and .not_nil!. people want their code to be fluent to read, but replacing warts with traps is not a solution :(
<FromGitter> <HertzDevil> they are fluent to read unless you come from c
<raz> in many (most?) languages assignment in conditional is a compiler warning or even error. and i think for good reason.
<FromGitter> <HertzDevil> even in c++ `if (auto y = dynamic_cast<Derived *>(x))` is perfectly fine and fluent
<raz> no, that's a warning C4706
<FromGitter> <HertzDevil> and in many, they aren't
<FromGitter> <HertzDevil> also for good reasons
<FromGitter> <HertzDevil> c++ compilers are not required to emit that warning so it's not the language that's responsible here
<FromGitter> <HertzDevil> you could see if ameba warns about that, but crystal itself should not disallow `if foo = bar`
<raz> i think the bigger problem is that crystal not only allows but even encourages it
<FromGitter> <HertzDevil> if you think that's a bigger problem you could try to replace all occurrences in the standard library plus the compiler and see how many others think disallowing that is the job of the compiler and not a linter
sagax has joined #crystal-lang
<raz> hm, i think it relates to designing for experts vs mortals. of course it's not a problem for compiler & stdlib authors. they intuitively structure their code to avoid nil to begin with. the mortals (like me) are often not that smart. so they more frequently end in a situation where they have to choose between ugly (not_nil / try), trappy (if =) or going back and refactoring all the things.
<raz> it compounds because shards and external data often also don't avoid nil as much as they should/could.
ur5us has joined #crystal-lang
<FromGitter> <> raz, i always said assignment should require parentheses around it, then it's a bit more visible
<FromGitter> <> > *<raz>* in many (most?) languages assignment in conditional is a compiler warning or even error. and i think for good reason. โŽ โŽ that is not true though
ur5us has quit [Ping timeout: 246 seconds]
<straight-shoota> raz, why do you think assignment in a condition is problematic?
<raz> oprypin_: +1 - i think that would make it less trappy at least
<raz> oprypin_, straight-shoota: well i guess the formal complaint would be because it's a trap (typo risk). not sure how much that matters in practice as the compiler probably catches most accidental mix-ups. but my personal complaint is more about readability. i don't expect assignments within an `if`, have to double-take almost every time i see it. kotlin's solution feels cleaner to me, they made the safe-nav operators convenient (even added elvis-op) and
<raz> assigment in conditional is verboten.
<raz> oprypin_: well i think it's at least a warning in most languages & linters that i know. golang allows it but then scopes the var to the if-block. it just seems odd that crystal promotes something that is widely considered a gotcha to a suggested pattern. :/
<raz> oprypin_: rubocop seems to agree with your idea, too
<straight-shoota> I guess this is a very subjective topic. I don't have any issues with such assignments, it seems logical to me.
<straight-shoota> When I write `if foo = some_nilable` I think that very clearly expresses the intent that the branch depends on `some_nilable` being non-nil.
<straight-shoota> You could write `foo = some_nilable; if foo` as well. And I definitely prefer that if `foo` is used outside the conditional as well.
<straight-shoota> But if `foo` is just used as non-nil inside the branch, combining it with the condition itself seems like a good idea to me.
<raz> yup would agree it's subjective. mostly bumping into it because i'm in a rather nil-ridden environment atm (working with protobuf where everything can be nil basically at any time). i just feel like the current nil-handling still reflects wishful thinking a bit too much over practicality. the argument for keeping `.not_nil!` and `.try` as unwieldy as they are was to motivate users to avoid them. but then at the same time we have this little backdoor (if =)
<raz> which allows avoidance throug a questionable pattern. imho the kotlin way of making safe-nav convenient is a better compromise.
<raz> (discl: then again, i don't have much exp with kotlin. perhaps their solution in turn leads to less "nil-avoidance" in the community because they don't hurt as much to deal with. hm.)
<straight-shoota> what's cotlin's solution?
<straight-shoota> *kotlin
<raz> - similar to crystal but syntax is more convenient, closer to ruby in that regard (`?.` instead of `.try &`)
<raz> (eh sorry, my link hit a bit too low, you gotta scroll up a bit to "Safe calls")
<FromGitter> <asterite> Regarding `if foo = ...`, I proposed being able to use `if foo := bar` in conditionals to avoid this issue, but it wasn't well received. I think it would have made things much clearer for some
<straight-shoota> raz, `try` or a safe navigation operator can't really replace a proper conditional. They are related but different use cases IMO.
<straight-shoota> An equivalent alternative to `if foo = some_nilable` would be `foo = some_nilable; if foo` (or maybe a dedicated assignment operator as @asterite mentioned)
notzmv has quit [Remote host closed the connection]
notzmv has joined #crystal-lang
<raz> yup true. but with more convenient navigation fewer people would reach for `if foo = nilable`. i think atm that mainly happens because they want to avoid the ugly `.try` or `.not_nil!` that would otherwise be required.
<raz> (as mentioned in kotlin `if foo = anything` is not allowed at all. i imagine they may have had a similar discussion in their past)
<straight-shoota> Hm, I've never used `if foo = nilable` instead of `foo.try {}`
<xyhuvud> why would `if foo = nilable` be bad in the first place?
<raz> when it's followed by a longer block, or worse, when the var is then used outside of that block, it can be quite confusing
<xyhuvud> you don't get to avoid it for @instance variables anyhow, so you might as well embrace it.
<straight-shoota> TIL *_with_index is not limited to integer index
<straight-shoota> >> (0..4).each_with_index('a') { |x, i| puts "#{i}: #{x}" }
<DeBot_> straight-shoota: a: 0 - more at
<raz> that's neat, now we just need a use-case for it :D
<straight-shoota> printing ordered lists (like `list-style-type: lower-alpha` in CSS)
<raz> that might get a bit nasty after 25 items ;P
<straight-shoota> replacing `i += 1` by `i = i.succ` makes it even more generically useful
<straight-shoota> all good with succ + String:
<raz> ha!
<FromGitter> <alexherbo2> how to get Crystal on macOS M1 ?
<FromGitter> <alexherbo2> I tried `brew install crystal` and with `--build-from-source`
<FromGitter> <> I am not that familiar with generics in Crystal, and I'm wondering if they are similar to Nim or Rust in that I can restrict a generic type parameter inline. The following is a Nim function definition, where `T` is restricted to be of type `Vec`, which is used for both arguments and the return type. How can I do similar with Crystal, without a type alias or relying on the inferred call site types?
<FromGitter> ... โŽ โŽ ```proc abs[T: Vec](o: var T, v: T): var T = ...``` []
<FromGitter> <Blacksmoke16> not in that way, would have to be within one of the methods in a macro
<FromGitter> <Blacksmoke16> i.e. not something the lang supports atm
<FromGitter> <> I see, thanks.
<straight-shoota> This would be an example of a macro-based type restriction:
<FromGitter> <asterite> another way would be to use a helper method: `def foo(x : T, v : T) : T; foo_helper(x, v); end; def foo_helper(x : Vec, v : Vec)`. So both have to be the same type, and both have to be Vec
<FromGitter> <> Yeah I'm not a fan of making the body less readable to restrict a type or two
<FromGitter> <> Also not realy a fan of Nim's inline restriction...would like a more readable `where` or even overloading `forall`
<FromGitter> <Blacksmoke16> to be clear you could put that 1 line macro in the constructor and thats all you'd need
<FromGitter> <> I think I want to see the information in the `signature` where it belongs
<straight-shoota> one day we'll hopefully get that =)
<FromGitter> <Blacksmoke16> yea thats not a thing atm, but can emulate it yourself for 1 line
Guest68 has joined #crystal-lang
<FromGitter> <Blacksmoke16> so :shrug: could be worse
Guest68 has quit [Client Quit]
<FromGitter> <asterite> Yes, it's definitely not hard to implement, we just need to come up with a syntax and do it :-)
<FromGitter> <> :) Sure, not a deal breaker for me. I like Crystal's "for humans" philosophy, and adding line noise is not in line with that :)
<FromGitter> <> Regardless, it is one thing I would use a lot if it was a thing.
<FromGitter> <> I might play around with a macro sometime...for now it's not really needed. Thanks!
ua__ has quit [Ping timeout: 258 seconds]
ua__ has joined #crystal-lang
<FromGitter> <> @Blacksmoke16: Where is `out` used, or is it just a reserved keyword?
<FromGitter> <> Aha
<FromGitter> <> I thought about your macro generating the entire `def` instead of mine just generating the body, and I decided on mine, for a couple reasons. 1) The readability as mentioned. 2) I would like to selectively choose which ones to annotate as always inlined, 3) I would like to add additional logic to some methods.
<FromGitter> <> I'm trying to write a class method that initializes an Indexable type with random floats. โŽ โŽ ```code paste, see link``` โŽ โŽ This works, but I am wondering if this can be done more concisely/in one line instead of 3. Don't really want to macro around this if the language has something I could use that I don't know about. []
<straight-shoota> I don't think this is much about the language, more about the API of your type
<FromGitter> <> Perhaps.
<FromGitter> <> I am thinking you are implying I write a `new` that takes a block. That would help at least.
<riza> why not just put it in the initialize method?
hightower2 has joined #crystal-lang
<FromGitter> <Blacksmoke16> its prob not in shardbox
<FromGitter> <Blacksmoke16> its a manual registry remember
<hightower2> ah so, didn't remember offhand, thanks
<hightower2> finds it, but also only if trying by '' rather than just 'tasko'
sorcus has quit [Ping timeout: 255 seconds]
<FromGitter> <> Does the `break` statement break from the first `while` in its dynamic scope? Or are blocks handled specially by inlining to allow `loop` to have a block with a `break` statement?
<FromGitter> <Blacksmoke16> not sure, would have to test it
<FromGitter> <> If you're curious enough to test it ping me when you do, otherwise I'll say here when I have a compiler on hand.
<riza> @suskeyhose check out and test it right now!
sorcus has joined #crystal-lang
<FromGitter> <asterite> break breaks from the closest block or while/until, whichever comes first
<FromGitter> <> Didn't expect my tiny compile time warning patch to get a heart from Mรผller ๐Ÿ˜ฎ
<FromGitter> <> I'm curious how `loop` works then. In code like โŽ โŽ ```loop do โŽ break โŽ end``` โŽ โŽ wouldn't the break exit the yield block and then just continue the loop? []
<FromGitter> <> It seems like this would work more like skip than break
<FromGitter> <> srasu ( you might be thinking of `next`. When you `break` its argument (or nil) becomes the value of the whole `loop` expression.
<FromGitter> <> Right, I guess I was just curious how this deals with environments where the break isn't in the lexical scope of a while directly, but is only there via (potentially several layers of) blocks
<FromGitter> <> I think maybe loop is a macro that expands to a while? Not a hundred on that
<FromGitter> <> riza: That is one thing that confuses me, when to use `initialize` vs `new`, despite reading the docs and fully understanding what is written.
<FromGitter> <> it's like C++ placement new vs new. allocate is like malloc(sizeof(T)), then you call initialize to make it valid. If you call new it does both for you.
<FromGitter> <> I'm sorry but I was smart and chose to ignore C++ as much as I could after C :)
<FromGitter> <> Or rather, when to define an `initialize` with a block as opposed to `new`
<FromGitter> <> Oh, then for C it's like this: โŽ โŽ ```code paste, see link``` []
<FromGitter> <> Since crystal auto-defines new to do this for you, you should only define your own new if you need to change that malloc call to allocate your structure differently.
<FromGitter> <> I'll think about this. Currently I do the following to initialize my ivars for my vec2, and also allow 0-1 arity construction: โŽ โŽ ```code paste, see link``` []
<riza> overloaded constructors are one of the few places I've cared to redefine new, but for most everyday purposes #initialize is sufficient
<FromGitter> <> how about โŽ โŽ ```code paste, see link``` []
<FromGitter> <> Good to know I'm not alone then
<riza> you can easily just declare #initialize multiple times too for the different aritys
<riza> yeah, like @suskeyhose's example
<FromGitter> <Blacksmoke16> i usually use `.new` as a means to transform arguments to match the initializer
<FromGitter> <> Can you give an example within the current context of when you *should* define new, or does it not apply in any way you can think here?
<FromGitter> <Blacksmoke16> ```def = 0.0) โŽ new value, value โŽ end โŽ โŽ def initialize(@x, @y); end``` []
<FromGitter> <> As an absolute newbie with no knowledge of the allocation scheme and only reading what I have in the reference docs, I'd prefer only redefining for changes to the allocation scheme, doing overrides for initialize, and if absolutely needed making a self.of method for alternate construction methods which use the same allocation scheme.
<riza> there are certainly performance considerations with allocating and such ahead of time, I just never need that
<FromGitter> <> You mean like making object pools and then overriding new and finalize to just mess with the object pool?
<FromGitter> <> Ok, I see. I will switch to overriding `initialize` from now on unless I need to change the allocation strategy.
<FromGitter> <> THat makes the most sense to me now that I understand it better.
<FromGitter> <> ๐Ÿ‘
<FromGitter> <> I guess I defined new for extra constructors because it mapped better to my brain, probably because it is a *class* method.
<FromGitter> <> The specialness of initialize confused me
<FromGitter> <> That's fair.
<FromGitter> <> What about the `new` method that prompted this question early today? โŽ โŽ ```code paste, see link``` []
<FromGitter> <> Since my struct is `Indexable` I do this to allow passing a block
<FromGitter> <Blacksmoke16> thats probably fine
<FromGitter> <> Example usages: โŽ โŽ ```code paste, see link``` []
<FromGitter> <> Yeah, that makes sense to me if Crystal doesn't provide a way to pass a block via initialize normally
<FromGitter> <> That I'm not sure of, but thank you!
<FromGitter> <> Anyone ever wish there was a way to mixin a module with instance and class methods and it doing the logical thing, rather than choosing how they are converted with `include` vs `extend`?
<FromGitter> <> I finally see the answer to my question. A break inside a block breaks from the method that called the block
<FromGitter> <> Which makes me curious about this โŽ โŽ ```code paste, see link``` โŽ โŽ does it print "hey"? []
<riza> @mjfiano yeah, that's the exact situation I was referring to when I said I use new sometimes to overload.
<FromGitter> <> Ah
<riza> @suskeyhose the semantics of the break operator in crystal (and ruby) are a bit counterintuitive because of the way that loops are generally implemented -- as blocks
<riza> this is also true of `next`
<FromGitter> <>
<FromGitter> <> That answered my question
<FromGitter> <> I'm guessing I need a macro to make this generic using `Indexable` instead of x/y/z/w in order to make a mixin that can be added to 2d, 3d and 4d vectors? The short-circuiting behavior of `&&` tells me yes โŽ โŽ ``` def <=>(other : self) โŽ @x <=> other.x && @y <=> other.y โŽ end``` []
<FromGitter> <> I'm just hoping macros are expanded after type merging
<riza> make it generic meaning accept any number of operands to that comparison? like to be able to compare some XY with another XY and some XYZ with another XYZ, etc?
<FromGitter> <> Make it generic as in, using `each` or something from `Indexable` rather than the logic explicitly needing to know about the ivars
<FromGitter> <> But I think we meant the same thing
<riza> you could either: ditch individual ivars and have an array which represented the set -- you could do this with generics easily
<riza> or you can use a macro to build out the guts of the class
<FromGitter> <asterite> you can break from a block where there's no `while` at all. The `break` goes a GOTO to the end of the called method (done with LLVM)
<FromGitter> <asterite> check how struct comparison is implemented:
<FromGitter> <> Thanks
<FromGitter> <Blacksmoke16> ๐Ÿ˜ฌ
<FromGitter> <Blacksmoke16> im sure there's a better way...
<raz> i wish... but all these things can be nil and i can't change it (protobuf). i tried rewriting it in a bunch of ways. but it seems my only choices are spreading it out over 6 variable assignments or, well, this.
<FromGitter> <> oh dear
<FromGitter> <Blacksmoke16> if you know all of this stuff is not nilable is there a reason its nilable in the first place?
<FromGitter> <Blacksmoke16> im not super familiar with protobuf, but isn't the idea that you dont make everything nilable?
ur5us has joined #crystal-lang
<raz> well it's a "oneof". `request.item.obj` tells me which attr is set, so i can then look it up as `request.item[ request.item.obj ]`. i'm afraid all of these things are legally nil'able in this situation, but i'm still trying to find a better way
<FromGitter> <> heh could be a union of namedtuples
<raz> - this version also works.
<FromGitter> <> (with exactly one key each)
<raz> but that's what my complain from earlier was about, i don't find it exactly clearer to read
<FromGitter> <Blacksmoke16> are you the only one using these types?
<FromGitter> <Blacksmoke16> could leverage `getter!`
<FromGitter> <Blacksmoke16> just would have to know when to do `.item?` versus `.item`
<raz> hmmm that sounds like an idea. i may try a pr on
<FromGitter> <Blacksmoke16> a quick look suggests they already support that
<FromGitter> <Blacksmoke16> `required` ones are not nilable, `optional` are
<raz> yea, but in proto3 everything is optional (don't get me started...)
<FromGitter> <Blacksmoke16> welp
<riza> might as well write in node then
<raz> heureka.not_nil!
<raz> that was actually easy to add... phew
<raz> i'll just add me a helper for that has lookup, too, then it'll be pretty
<raz> hash*
<hightower2> Seems a couple presentations are not among the recordings.. e.g. Ary's or btate's.. What's up with that?
<hightower2> (from the crystal conf, of course)
<hightower2> ah could be in main track
sorcus has quit [Quit: WeeChat 3.2]
hightower2 has quit [Ping timeout: 268 seconds]
hightower2 has joined #crystal-lang
deavmi has quit [Quit: No Ping reply in 180 seconds.]
deavmi has joined #crystal-lang
xyhuvud has quit [Ping timeout: 255 seconds]
yxhuvud has joined #crystal-lang
hightower2 has quit [Ping timeout: 255 seconds]
rbpynet1 has joined #crystal-lang
rbpynet1 has quit [Quit: WeeChat 2.8]
<FromGitter> <> I have a few types which all `include` some partial types. These modules are never intended to be seen be the user, such as in generated documentation pages with `crystal doc`, but I can't exactly make them private either if I want to include them in other modules/types, and protected doesn't seem to work on modules, so I'm not really sure if Crystal has a solution for me...
<FromGitter> <> The mixins are purely for DRY/maintenance reasons
<FromGitter> <Blacksmoke16> `# :nodoc:`
<FromGitter> <> Any ideas?
<FromGitter> <> Oh hmm, that might be what I'm looking for :)
<FromGitter> <> That does work, however, perhaps it's me being picky but it'd be nice if the types that include a `:nodoc:` module didn't generate docs with references to the hidden module, as it currently does with "Instance methods inherited from module..."
ur5us has quit [Ping timeout: 255 seconds]
<FromGitter> <Blacksmoke16> you'd probably need to have public methods in each type that delegate to the module
<FromGitter> <Blacksmoke16> otherwise the docs are correct, those methods dont actually live in the type, they come from that module
ur5us has joined #crystal-lang
<straight-shoota> I think the docs generator is not handling things like this very nicely
<straight-shoota> If you want this mixin to be completely invisible, maybe you could just use a macro that generates these methods.
<FromGitter> <> I see. This is not a big deal really, and delegates/macro would be more trouble than its worth.
<FromGitter> <> Thanks for the pointers. I'm happy enough with :nodoc:
hexology has quit [Quit: hex on you ...]
<FromGitter> <Blacksmoke16> @straight-shoota related to, so is the current output actually correct?
hexology has joined #crystal-lang
<straight-shoota> Yes, the behaviour is correct and as expected. The documentation is just wrong.
<FromGitter> <Blacksmoke16> hm, whats the reasoning when not using a buffered channel that the output is โŽ โŽ ```code paste, see link``` []
<FromGitter> <Blacksmoke16> shouldnt the first send cause the receive to print the value?
<FromGitter> <Blacksmoke16> which is how it worked before
<straight-shoota> Channel#send doesn't immediately yield to a waiting receiver, it just enqueues it (so it get's resumed when the scheduler reschedules)
<straight-shoota> So on `send(1)`, the receiving fiber is enqueued, on `send(2)`, there's no waiting receiver and no queue, so the channel triggers a reschedule.
<FromGitter> <Blacksmoke16> i guess to me it seems more like a regression as it used to work one way and now works a diff way
<FromGitter> <Blacksmoke16> when the thing that changed it was MT, which maybe its a byproduct of supporting MT versus a regression
<straight-shoota> No, I think it's a fix really. The previous behaviour was not correct. At least not what you would expect from the specifics of a channel.
<straight-shoota> Even an unbuffered channel has essentially a virtual one-element buffer for when there's already a receiver waiting.
<straight-shoota> MT required to overhaul these things and make them work correctly.
FromGitter has quit [Ping timeout: 255 seconds]
oprypin_ has quit [Ping timeout: 255 seconds]
oprypin has joined #crystal-lang
FromGitter has joined #crystal-lang
<FromGitter> <Blacksmoke16> i usually define a `ClassMethods` module within the one partial type, then add a like `macro inherited; extend ClassMethods; end;`
<FromGitter> <> I can't seem to get that to work. Maybe I'm doing it wrong...
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <Blacksmoke16> sorry
<FromGitter> <Blacksmoke16> `macro included` ๐Ÿ™ˆ
<FromGitter> <> Still trying unsuccessfully. My project is too spread out and unfinalized to publish it yet. I may have to try to isolate the problem on or smth :/
<FromGitter> <Blacksmoke16> gl
<FromGitter> <> works fine as separate modules tho
hightower2 has joined #crystal-lang
<FromGitter> <> where is `included` documented?
<FromGitter> <> Ah...I was doing it correctly, but I believe I ran into a compiler bug I should file, due to my own mistake though. I have a `A::B` module that does `include A` (don't ask why), and this works until you add an `included` hook. Probably gives up fully resolving due to cyclic graph
hightower2 has quit [Ping timeout: 240 seconds]