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
Liothen has quit [Read error: Connection reset by peer]
Liothen has joined #crystal-lang
Liothen has quit [Read error: Connection reset by peer]
Liothen has joined #crystal-lang
Liothen has quit [Read error: Connection reset by peer]
alexherbo2 has joined #crystal-lang
Liothen has joined #crystal-lang
alexherbo28 has quit [Ping timeout: 272 seconds]
Liothen has quit [Read error: Connection reset by peer]
Liothen has joined #crystal-lang
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 240 seconds]
alexherbo2 has quit [Ping timeout: 246 seconds]
chachasmooth has quit [Ping timeout: 260 seconds]
chachasmooth has joined #crystal-lang
<FromGitter> <scriptmaster> My vote is towards "@[Annotation]" while C# has a syntax of [Annotation] and java with @Annotation this looks like both combined :) And I come from a strong .Net/.Net core background, so most of us who worked in Dell and DellEMC have been comfortable with named annotations, for example, [Bind(Exclude="Id")] and seen people write answers easily in my interviews with them as well.
<FromGitter> <scriptmaster> and rustlang has adopted #[] #[actix_web::main] #[get("/")]
<FromGitter> <scriptmaster> also, looks like you had a type on your forum post (missing the closing ] ): ⏎ ⏎ @[MyAnn(name: "foo") ⏎ def foo ⏎ {{ @def.annotation(MyAnn)[:name] }} ... [https://gitter.im/crystal-lang/crystal?at=5f7d3557eb6dbd77f905d3c0]
<FromGitter> <Blacksmoke16> oops :p
<FromGitter> <Blacksmoke16> PHP is adopting `<<MyAnnotation>>`
<FromGitter> <Blacksmoke16> https://wiki.php.net/rfc/attributes_v2
<FromGitter> <scriptmaster> Another reason/points why single line annotations/attributes are better than block like, is when writing multiple annotations
<FromGitter> <scriptmaster> annotation MyAnn1 ⏎ annotation Two ⏎ ⏎ ```# too much blocks``` ⏎ ... [https://gitter.im/crystal-lang/crystal?at=5f7d363eb949c45310c738f7]
<FromGitter> <Blacksmoke16> i usually just do `annotation Two; end`
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <scriptmaster> ah ok, like that
<FromGitter> <scriptmaster> @[MyAnn(name: "cassandra")] looks more familiar/likable to me :)
<FromGitter> <Blacksmoke16> i looked into making a prototype of my rfc, updating the parsing logic is going to be the tricky part i think
<FromGitter> <Blacksmoke16> like if you see `@[Annotation]` would have to store some state saying next type is an annotation
<FromGitter> <Blacksmoke16> and prevent non `class`/`struct` types from having it
yukai has joined #crystal-lang
<FromGitter> <scriptmaster> PHP not supporting named params is limiting `...doesn't support named params...`mentioned in their RFC
<FromGitter> <Blacksmoke16> its coming in PHP 8 iirc
<FromGitter> <scriptmaster> One of my side-project is a DSL (similar to revenj-jvm and .net) outputting, crystal, rust, golang, .net core, (java and php can be included in future) and some more in future too: vlang, zig
<FromGitter> <scriptmaster> so your RFC will help :)
<FromGitter> <Blacksmoke16> Will help me too ha
<FromGitter> <Blacksmoke16> However I wouldn't plan on it happening soon
<FromGitter> <scriptmaster> sorry, I also do a lot of perf-tests and benchmarks, a quick question about concurrency in crystal, thought I might ask: the techempower benchmarks in the last two rounds are showing rustlang at the peaks, while crystal is at 50% marks when I actually tried and compare on my cloud VM, crystal is at 30K and actix-rust is at only 21K, while golang is at 16K could that be because of my cloud VM RAM
<FromGitter> ... configuration, or has the concurrency in crystal changed recently after Round 19 that I can assume Round 20 will show crystal slightly above/towards rust ?
<FromGitter> <Blacksmoke16> Crystal is only single threaded by default atm
<FromGitter> <scriptmaster> I compared crystal-raw and actix-raw
<FromGitter> <Blacksmoke16> You can opt into MT mode tho
<FromGitter> <scriptmaster> reading this based on search from your keyword: https://forum.crystal-lang.org/t/slow-performance-of-channels-in-mt-mode/1980
<FromGitter> <Blacksmoke16> Crystal http server has concurrency but not parallelism by default
<FromGitter> <scriptmaster> I understand the difference, I like the Channel implementation as well - looks good to me..
<FromGitter> <scriptmaster> and preforking is not really a big feature..
<FromGitter> <scriptmaster> however, a really-nice-to-have
<FromGitter> <scriptmaster> if such a language feature or a lib is available for HTTP I would do 2*numCPUs threads sharing the same listening socket
<FromGitter> <scriptmaster> I couldn't find on in awesome-crystal yet (still looking)
<FromGitter> <christopherzimmerman> @vinyll_gitlab right now, https://github.com/crystal-data/num.cr is going to be the closest thing to `numpy` in Crystal. It's should actually be faster in most cases. Are there any specific statistical methods you are looking for?
<FromGitter> <christopherzimmerman> If so, feel free to open up an issue for them, and I'm sure it won't take too long to implement efficiently. In terms of binding to numerical libraries, I do bind to BLAS/LAPACKE (many different implementations are supported) under the hood, as well as support OpenCL routines on a GPU, so you should find lots of stuff to mess around with.
yukai has quit [Ping timeout: 260 seconds]
woodruffw has quit [Ping timeout: 272 seconds]
woodruffw has joined #crystal-lang
sorcus has joined #crystal-lang
alexherbo2 has joined #crystal-lang
_whitelogger has joined #crystal-lang
gangstacat_ is now known as gangstacat
ryanprior has quit [Quit: killed]
psydroid has quit [Quit: killed]
return0e[m] has quit [Quit: killed]
ryanprior has joined #crystal-lang
psydroid has joined #crystal-lang
return0e[m] has joined #crystal-lang
ryanprior has quit [*.net *.split]
psydroid has quit [*.net *.split]
sorcus has quit [*.net *.split]
Liothen has quit [*.net *.split]
deavmi has quit [*.net *.split]
badeball has quit [*.net *.split]
sorcus has joined #crystal-lang
ryanprior has joined #crystal-lang
psydroid has joined #crystal-lang
deavmi has joined #crystal-lang
badeball has joined #crystal-lang
Liothen has joined #crystal-lang
<FromGitter> <j8r> are method overloads expanded to if/else if conditions by the compiler?
<FromGitter> <asterite> yes
<FromGitter> <asterite> well, it depends on which overloads
<FromGitter> <asterite> like, different number of arguments is determined at compile-time, different types of an argument is if/elsif at runtime
<FromGitter> <j8r> ha yes, nice
<FromGitter> <j8r> Here for me that's unions, so logically it will be if/else to dispatch at runtime
<FromGitter> <j8r> like this https://carc.in/#/r/9sw2
<FromGitter> <j8r> I go to case/in then, less code
<FromGitter> <Blacksmoke16> case/in is nice if the code is simple, overloads are nicer because you can document them and is cleaner if theres a lot of lines
<FromGitter> <j8r> I wonder how the compiler handle an union like `one_or_two.run`, where `one_or_two : One | Two`
<FromGitter> <HertzDevil> it requires both `One#run()` and `Two#run()` to exist
<FromGitter> <HertzDevil> and the type of `one_or_two.run` is the union of the return types of these two methods
<FromGitter> <j8r> sure, I mean, on the compiler side
<FromGitter> <j8r> `run(one_or_two)` expands to conditions, but not `one_or_two.run()` I guess
<FromGitter> <j8r> how can I know "easily" this kind of things? Once, I generated LLVM IR, but the code was huge :/
<FromGitter> <christopherzimmerman> How does that work with generics? Are generic methods turned into overloads at compile time and then use the same if/elsif at runtime?
<FromGitter> <j8r> I never get the "free variable" methods, for me they are generic methods (`def met(a : T) forall T`)
<FromGitter> <j8r> they are likely expanded by the compiler yes
<FromGitter> <j8r> a bit like macros I would say (not sure, I don't know the compiler)
<FromGitter> <Blacksmoke16> my understanding is the compiler makes a method for each concrete T
<FromGitter> <Blacksmoke16> as if you had an overload for each
<FromGitter> <j8r> yep, otherwise it won't be possible to use inside macros like `{{ T }}`
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <HertzDevil> i believe every union instance has a discriminator (*probably* `T.crystal_instance_type_id`) and then the generated code determines the run-time type of `one_or_two` with that
Liothen has quit [Read error: Connection reset by peer]
<FromGitter> <naqvis> @j8r I just ran a simple test and IR generated for union is if/elsif
<FromGitter> <HertzDevil> also i was thinking about the tuple map situation
Liothen has joined #crystal-lang
<FromGitter> <HertzDevil> https://carc.in/#/r/9swl this is what i have
<FromGitter> <j8r> @naqvis how do you know where to search on the huge IR code?
<FromGitter> <naqvis> search for classname and/or method name
<FromGitter> <naqvis> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f7dcd83ed7be16b3cc290d1]
<FromGitter> <HertzDevil> yeah the constants 545 and 546 there should be `One.crystal_instance_type_id` and `Two.crystal_instance_type_id`
<FromGitter> <HertzDevil> if you use `is_a?` or `case` the same checks should appear somewhere else
<FromGitter> <j8r> thanks @naqvis . ⏎ ... being able to read IR is another topic 😅
<FromGitter> <naqvis> lol
<FromGitter> <naqvis> true
<FromGitter> <naqvis> This is IR generated for above `get` method ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f7dcf00b949c45310c8d3f2]
<raz> database wisdom of the day: never use a boolean when you can use a timestamp instead
<FromGitter> <Blacksmoke16> yes, `deleted_at` is much more useful than `is_deleted`
<raz> exactly 👍
<FromGitter> <naqvis> I wish Crystal has support for functor :P
<FromGitter> <naqvis> it already allowed so majority of operator loading, don't know why it doesn't allow functor
<FromGitter> <naqvis> C++ allows via `()` operator overloading, JVM languages like Kotlin, Scala also does the same
<FromGitter> <hugopl> functor syntax doesn't match with ruby/crystal optional `()`, so better just create a method called `call`, hehe
<FromGitter> <hugopl> since there's no way to distinguish if `foo = Foo.new; foo` meant `foo = Foo.new; foo();` or `foo = Foo.new; foo #noop;`
<FromGitter> <naqvis> compiler already knows that `foo` is an object so any invocation of `()` can be treated like a call to some specific method call
<FromGitter> <naqvis> that's how compiler does the trick in other languages
<FromGitter> <naqvis> so in reality `foo()` is same as calling `foo.()`
<FromGitter> <naqvis> or it could be something else like `foo()` is same as `foo.invoke()`
<FromGitter> <Blacksmoke16> php has that, `__invoke()`
<FromGitter> <Blacksmoke16> think ruby does too if you define a `def call` method
<FromGitter> <naqvis> yeah, kotlin also allows overloading of `invoke` operator fun
<FromGitter> <naqvis> and compiler translates the call of `foo()` to `foo.invoke()`
<FromGitter> <Blacksmoke16> ib4 formatter removes the `()` :P
<FromGitter> <naqvis> yeah, so if there is support for functor, then formatter might get changed as well :P
<oprypin> @naqvis: there is support for a functor, it's with call()
<oprypin> the bracket syntax is specifically for method calls
<oprypin> you could have foo=bar; foo() and that would still be self.foo()
<FromGitter> <hugopl> in crystal/ruby... how it would distinguish `hey = functor` (hey gets the same ref of functor) from `hey = functor` (hey gets the result of functor call)
<FromGitter> <hugopl> IMO there's no good way, so better just keep using `.call` :-)
<FromGitter> <naqvis> oprypin thanks, but seems either i couldn’t get you or we are talking about different things
<FromGitter> <naqvis> dot method invocation is already a thing
<FromGitter> <naqvis> i was talking about overloading method invocation operator, so that invoking () is same as calling a defined method on that object
<oprypin> naqvis, there is no method invocation operator
<oprypin> the syntax is `<thing>.foo(x)` where neither `<thing>.foo` nor `(x)` mean anything by themselves, only together
<FromGitter> <naqvis> hmmmm
<FromGitter> <naqvis> isn’t just parens are optiional when invoking method?
<FromGitter> <naqvis> so ‘foo(x)’ is same as ‘foo x’
<oprypin> yes but that's syntax sugar
<oprypin> the thing that's more complicated is just `foo`
<oprypin> cuz i think its meaning can change due to a local variable
<FromGitter> <naqvis> how come?
<oprypin> but even that is just an exception to the rule
<oprypin> naqvis, https://carc.in/#/r/9szy
<oprypin> in stark contrast to https://carc.in/#/r/9szz
<FromGitter> <naqvis> naaahh
<FromGitter> <naqvis> methods are defined in types
<oprypin> just tab between those 2 examples
<FromGitter> <naqvis> and compliler definitely knows which is an object of which type
<oprypin> i suppose the 1st example proves that
<FromGitter> <naqvis> your example is more shadowing
<FromGitter> <naqvis> not method invication
<FromGitter> <naqvis> sorry for typos
<FromGitter> <naqvis> typing on phone sucks
<FromGitter> <naqvis> lol
<oprypin> but shadowing in some shape *is* the problem with your suggestion
<oprypin> actually i can't quite grasp what the actual problem is so nvm
<FromGitter> <naqvis> i was talking about ‘function objects in C++’
<FromGitter> <naqvis> other languages offer different mechanisms for same
<FromGitter> <naqvis> php, scala, kotlin, python
<FromGitter> <naqvis> blacksmoke mentioned ruby also have similar thing
<oprypin> naqvis, yea you use them with `func.call(..)`
<oprypin> php, scala, kotlin, python don't have the syntax limitation of omitting brackets in function calls
<FromGitter> <naqvis> ‘call’ is just a method defined in Proc
<FromGitter> <naqvis> and it isnt some magic, its just call the func pointer in backend
<oprypin> right
<FromGitter> <naqvis> ruby also allows to invoke proc via [] instead of .call
<FromGitter> <naqvis> so you can invoke Proc foo as foo[x]
<FromGitter> <naqvis> thats kind of giving that functor functionality
<FromGitter> <naqvis> but thats limited to Proc
alexherbo23 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 260 seconds]
alexherbo23 is now known as alexherbo2
<FromGitter> <asterite> when the parser sees `foo()`, that's a call to a method `foo` in that scope, regardless of whether there's a `foo` variable in scope or not. Same as Ruby. That's why you can't overload `()`
<FromGitter> <asterite> well, mainly what all of you have been saying... the reason is that parentheses are optional when calling methods
<FromGitter> <asterite> `foo.bar()`... is that calling the method `bar`, then invoking that if it returns a `Proc`, or is that calling the method `bar`
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
Andriamanitra has joined #crystal-lang
<oprypin> thats what i've been saying
<oprypin> [21:03:43] <oprypin> in stark contrast to https://carc.in/#/r/9szz
<oprypin> [20:19:13] <oprypin> you could have foo=bar; foo() and that would still be self.foo()
<oprypin> i think the limitation is two-fold. just parentheses-less by itself is possible to overcome. but it's also the implicit `self` that's killing it
ua has quit [Ping timeout: 240 seconds]
ua has joined #crystal-lang
<oprypin> how can i diagnose why GC never cleans kicks in when i allocate a particular kind of object in a loop?
andremedeiros has quit [Quit: ZNC 1.8.2 - https://znc.in]
andremedeiros has joined #crystal-lang
<oprypin> + getting a way worse behavior on Ubuntu (6 GiB and growing) vs Arch (stops after 1.5 GiB)
yukai has joined #crystal-lang
<oprypin> i have continued writing on that issue, made a very interesting explanation (though it is just a guess)
badeball has quit [Ping timeout: 240 seconds]
badeball has joined #crystal-lang
<FromGitter> <aaaScript> @oprypin btw thanks for the Dear Imgui bindings. It's a pretty nifty library. I was wondering if you ever had any issues with adding fonts. I've followed the instructions on one of your examples (basically clearing the font and adding the new one, same instructions on the imgui-sfml font readme), however, it seems to crash the application after a few seconds of use. Kind of stumped on it and haven't been able
<FromGitter> ... to figure it out.
<oprypin> i'm allocating 1000 objects which are tiny from Crystal's perspective but actually each of them sub-allocate a big memory region that GC doesn't know about.
<oprypin> so i was thinking, perhaps the GC just concludes "yep only 1000 tiny objects, i won't even bother collecting that"
<oprypin> aaaScript, i mean,... most people have issues with fonts in imgui, but please elaborate :) the full program, please, at least?
<oprypin> one thing is, in the example i ignored some part of the advice here https://github.com/eliasdaler/imgui-sfml#fonts-how-to `// clear fonts if you loaded some before (even if only default one was loaded)` - yea, i didnt do that. but it worked fine for me so i was like whatever
<oprypin> doesnt matter, just show me the program
<FromGitter> <aaaScript> Yup. For example here's something I have that crashes: https://gist.github.com/aaaScript/80fdf7a449beddacab499c39d3287fd9
<oprypin> mm feels good to see actual usage of the project 😊😊😂
<FromGitter> <aaaScript> It's just loading the font, setting a style, and drawing some windows.
<FromGitter> <aaaScript> I think the issue though is the way my frames/style are drawn maybe. If I comment that stuff out and draw the demo window it doesn't crash.
<FromGitter> <aaaScript> The error is always `Assertion failed: (!Locked && "Cannot modify a locked ImFontAtlas between NewFrame() and EndFrame/Render()!"), function ~ImFontAtlas, file cimgui/imgui/imgui_draw.cpp, line 1735.`
<FromGitter> <aaaScript> I'm also testing on MacOS. Not sure if that might contribute.
<oprypin> aaaScript, ha, interesting, i'm getting a different error `cimgui/imgui/imgui.h:1398: T& ImVector<T>::operator[](int) [with T = ImFontConfig]: Assertion `i < Size' failed.`
<FromGitter> <aaaScript> Is your Font loading?
<oprypin> i dont see anything, can't tell
<FromGitter> <aaaScript> Might need to switch the font path it's calling if your device doesn't have it in the code
<FromGitter> <aaaScript> `File.file?(font_path = "/System/Library/Fonts/Supplemental/Arial Unicode.ttf")`
<FromGitter> <aaaScript> Actually that shouldn't matter if it doesn't find it, should just load the default font then.
<FromGitter> <aaaScript> Definitely weird, since what I have is basically what's in one of your sample examples, just with styling.
<oprypin> aaaScript, yes, i've gone quite far to make the examples almost identical and it still crashed
<oprypin> aaaScript, yes.... the difference is the lack of ` ImGuiDemo.show_demo_window` aaa
<oprypin> i have no idea
<FromGitter> <aaaScript> If the `self.set_style` is removed and you include just the `show_demo_window`. It shouldn't crash.
<FromGitter> <aaaScript> I was wondering if it had maybe something to do with sfml
<oprypin> fuck
<oprypin> aaaScript, `crystal run -Dgc_none _test.cr` works, doesnt it
<oprypin> how have i never run into this problem
<FromGitter> <aaaScript> Yes actually. That works.
<FromGitter> <aaaScript> Some sort of garbage collection issue?
<oprypin> i, in my infinite genius, have hooked up the garbage collector to imgui's internals
<oprypin> and i think this bad boy is being called at some unexpected moment https://github.com/ocornut/imgui/blob/12d95055347e452c48bf663a9aa02e8338bec154/imgui_draw.cpp#L1742
<FromGitter> <aaaScript> Well that stuff is beyond me lol glad we were able to find the issue.
<oprypin> aaaScript, well there's still a lot of digging to do. possibly rethinking the whole thing 😩. thanks for the report.