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
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
zorp has joined #crystal-lang
yxhuvud has quit [Quit: No Ping reply in 180 seconds.]
yxhuvud has joined #crystal-lang
zorp has quit [Read error: Connection reset by peer]
zorp has joined #crystal-lang
postmodern has quit [Ping timeout: 246 seconds]
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 272 seconds]
chachasmooth has quit [Ping timeout: 240 seconds]
chachasmooth has joined #crystal-lang
DTZUZU has joined #crystal-lang
baweaver has quit [Ping timeout: 256 seconds]
DTZUZU_ has quit [Ping timeout: 256 seconds]
_whitelogger has joined #crystal-lang
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 256 seconds]
postmodern has joined #crystal-lang
alexherbo2 has joined #crystal-lang
<postmodern> is it possible to access the fields via a Pointer(MyStruct) or do you have to copy the data to a value that you can dot-access the fields normally?
alexherbo22 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 246 seconds]
alexherbo22 is now known as alexherbo2
<postmodern> and is it generally frowned upon to re-open stdlib classes to add yor own methods? Really want to add Errno.strerror to Errno.string
alexherbo2 has quit [Ping timeout: 246 seconds]
alexherbo2 has joined #crystal-lang
<postmodern> why does Pointer(T).malloc and other pointer methods that use indexes/offsets use Ints, instead of UInts?
<postmodern> seems weird to be able to compile a Pointer(UInt8).malloc(-1)
<postmodern> it does raise an Unhandled exception, though
alexherbo2 has quit [Ping timeout: 246 seconds]
alexherbo2 has joined #crystal-lang
<FromGitter> <naqvis> > *<postmodern>* why does Pointer(T).malloc and other pointer methods that use indexes/offsets use Ints, instead of UInts? ⏎ ⏎ My understanding is that as `Int32` is default so it makes easier to call `malloc` without any extra type annotation. Internally `Pointer.malloc` validates the size and throws `ArgumentError` if you pass it a negative number.
<FromGitter> <naqvis> fwiw there is an overload in `primitives.cr` which accepts `UInt64` as size argument ` Pointer(Int32).malloc(1_u64)`
<FromGitter> <naqvis> > *<postmodern>* and is it generally frowned upon to re-open stdlib classes to add yor own methods? Really want to add Errno.strerror to Errno.string ⏎ ⏎ I would say it should be okay to use the extension functionality offered by language in a program, but usage of such in shards might confuse the users.
Flipez has quit [Read error: Connection reset by peer]
Flipez has joined #crystal-lang
oddp has joined #crystal-lang
HumanG33k has quit [Remote host closed the connection]
<yxhuvud> postmodern: use pointer.value to follow the pointer back to the original struct. That by itself should not create any copies.
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
HumanG33k has joined #crystal-lang
HumanG33k has quit [Max SendQ exceeded]
HumanG33k has joined #crystal-lang
<FromGitter> <rafmst> Hi!
<FromGitter> <rafmst> I'm trying to install Crystal on MacOS, but its taking to long and my machine is loud as an airplane right now, is this normal?
<FromGitter> <rafmst> Its stuck on the "make" process
<FromGitter> <naqvis> seems homebrew might be compiling some dependencies
<FromGitter> <rafmst> Thanks, I'll keep waiting
<FromGitter> <naqvis> 👍
oddp has quit [Quit: quit]
<postmodern> is it common for example/ programs to do `require "../src/mylib"` or is there a better way of telling `crystal build` to look in `src/`?
<FromGitter> <naqvis> common practice is to have all source code located inside `src` folder
<FromGitter> <naqvis> you can multiple sub-folders inside src
<FromGitter> <naqvis> for examples, you can use above approach
<yxhuvud> not certain I'd want to mix examples with regular code like that.
<postmodern> yxhuvud, ah interesting it uses a primitive called pointer_get. So that's how crystal hooks in the low-level stuff.
<yxhuvud> the same way I don't mix the specs into src
<postmodern> yeah examples/ only expect for testing/demo purposes. Putting examples in your src/ would be like putting spec/ in your src/ :/
<yxhuvud> postmodern: I'd probably do something similar to how it is done in the spec folder for examples.
<yxhuvud> ie a helper file requiring stuff.
<postmodern> kindof wish crystal build had like an -I flag to add src/ dirs that require could then scan
<FromGitter> <naqvis> i still prefer convention over configuration :P
<postmodern> free project idea. we should port Processing to crystal. Probably use an existing SDL library for the canvas. Basically makes writing visual/interactive programs (visualizations or digital art) super easy. So far the Processing API has been ported to JS (https://p5js.org/).
<postmodern> it's basically the "killer app" for digital artists and graphics people
<postmodern> TIL the compiler will let you return a pointer to a struct on the stack. after returning the stack will then get overwriten and corrupt your struct fields
<postmodern> yielding is safer
<yxhuvud> Yes, it is possible to trigger a use after free that way. Yielding is safer as you note, or storing the reference to the struct as an instance variable instead of a local.
deavmi_ has joined #crystal-lang
deavmi has quit [Read error: Connection reset by peer]
<oprypin> [10:52:28] <e90d7fpostmodern> is it common for example/ programs to do `require "../src/mylib"` or is there a better way of telling `crystal build` to look in `src/`?
<oprypin> afaik I'm the only one doing this. works well.
<oprypin> very unfortunately, yes, everyone what is doing require ../src
<oprypin> yxhuvud: it's not "free" if it's on the stack. gc prevents actual "use after free"
<yxhuvud> popping the stack is just another kind of freeing. *shrug*
<oprypin> no
<postmodern> oprypin, so if you also did `shards instll` the shards would go into the project root since your symlinking lib/?
<oprypin> it refers to free() which actually can release memory to the os
<oprypin> stack can't be released
<oprypin> postmodern: no that doesn't affect anything
<oprypin> cuz it's examples/lib , not lib
<yxhuvud> anyhow, use-after-free is a *category* of errors, and that includes stack related issues.
<oprypin> yxhuvud: i guess
<postmodern> oprypin, when you pointerof(data) and data is controlled by GC, does GC also link the resulting Pointer object to data?
<oprypin> postmodern: pointerof gives no guarantees and is never safe
<oprypin> and no it doesn't
<oprypin> if u do gc.malloc that is already a pointer and passing that pointer around keeps the reserved memory alive
<postmodern> oprypin, ah so you could still get user-after-free if you did pointerof(some_data_on_the_heap)
<oprypin> yes im pretty sure, unless there's some very lucky accident
<yxhuvud> well if you create a pointer to the heap then the GC will see it and keep it alive, no?
<postmodern> oprypin, just curious is there's a safe way to get a pointer, or should all crystal pointers be considered ephemeeral and unsafe
<yxhuvud> potentially not handling stuff like internal pointers?
<oprypin> postmodern: latter
<oprypin> as i understand, the actual `pointerof` call is 100%
<oprypin> equivalent to C & operation
<oprypin> with no saving graces specific to Crystal
<postmodern> yxhuvud, ideally pointers derived from objects on the heap would be connected to the object, and persist until the object on the heap was GCed AND the code using the pointer GCed it. That would in theory prevent having pointers that persist after the pointed object gets GCed
<postmodern> ah good to know
<oprypin> postmodern: a `class` has a GC pointer built into it
<oprypin> when u call a_class.to_unsafe, i think that pointer is safe to use mostly
<yxhuvud> postmodern: It is a conservative GC, so keeping a pointer *should* keep it alive unless you point to the stack or something explicitly frees it.
<oprypin> it might even keep the object alive
<oprypin> im just saying that pointerof syntax is always unsafe, not that pointers are unsafe
<yxhuvud> it does keep it alive. It is fairly easy to test.
<oprypin> so yes when you were asking about pointer to heap pointer, you meant like pointerof(a_class)
<oprypin> and that is not good
<oprypin> but u can get the actual heap pointer with a_class.to_unsafe
<postmodern> ah ha, good to know
<postmodern> might be nice to have pointerof() return a sub-class of pointer, like UnsafePointer or EphemeralPointer, so the type system can indicate the difference
<yxhuvud> I'm not certain what oprypin is trying to say. AFAIK there is no difference.
<oprypin> yxhuvud: well pointerof(a) != a.to_unsafe
<oprypin> that's very literal and at least that part should be clear
<postmodern> a.to_unsafe apparently is connected to the underlying GC managed object
<postmodern> where as pointerof is basically like getting a "spot price", except a pointer to something
<yxhuvud> well yes, to_unsafe is very much implementation dependant, and in the case of objects often point to the underlying data. Like an array having a pointer to the buffer
<oprypin> oh dang sorry I forgot that there's no default to_unsafe
<oprypin> sorry i meant a_class.as(Void*)
<postmodern> well even without a default #to_unsafe, the logic still usually relies on an ivar which is tied to the object
<postmodern> would def to_unsafe; pointerof(@struct); end be considered risky, assuming it's not immediately passed down to the C bindings layer before the object get's GCed?
<yxhuvud> assuming @struct is always initialized in initialize, I think that is how most does it.
<oprypin> postmodern: yes it's risky but it didn't stop me from doing it
<oprypin> actually pointerof @first_member is correct only for structs
<yxhuvud> just hope your C interface doesn't free the struct for you.
<oprypin> for classes it's not but you can do self.as(Void*)
<yxhuvud> Why it is not ok for instance variables in objects?
<postmodern> ah right pointerof() is a macro. I was going to suggest, why not have the Pointer objects created by pointerof() entered into GC and linked to the object in question
<oprypin> some refs to my shenanigans which are confirmed to work
<FromGitter> <mwlang> How do I explicitly check for Infinity in Crystal? I'm producing a JSON with 148k entries and in there is apparently an infinity number. `Unhandled exception: Infinity not allowed in JSON (JSON::Error)`
<FromGitter> <mwlang> this started happening after upgrading from 0.29.0 to 0.35.1
<postmodern> mwlang, f.infinite?
<FromGitter> <mwlang> perfect! thanks.
<FromGitter> <mwlang> a little confused on how to use #scan and #match to extract a string. ```pp! "-0.815%".scan(/[-|\.|\d]+/).to_s ⏎ ``` => `"[Regex::MatchData(\"-0.815\")]"` whereas I would expect a String, `"0.815"`
<FromGitter> <mwlang> in Ruby, I'd actually have a #join before that #to_s to collapse the array and get the resulting string. But crystal, `("-0.815%".scan(/[-|\.|\d]+/)).join.to_s # => "Regex::MatchData(\"-0.815\")"` is emitting the Regex::MatchData class name. almost like I'm getting the #inspect result instead of just the contents of the match.
<FromGitter> <Blacksmoke16> prob could use `String#[](regex)`
<postmodern> any reason why LibC.select and FdSet are defined, but not the crystal equivalents of FD_SET/FD_CLR? appears to just be some weird bit-masking C macros
<yxhuvud> probably either because noone has needed them or because they are not intended to be used as high level interfaces.
<postmodern> i could see FdSet being included in a C struct, so you'd need the definition around
<postmodern> LibC.select isn't very useful unless you can initialize the FdSet thing
<yxhuvud> TBH it is not obvious to me why LibC.select is there in the first place. I can see no references to it being used.
<postmodern> sort of asked this yesterday, is there a crystal-way i can use libevent to watch and fd for data (but not read it)? think someone mentioned a private method #read_wait or something?
<yxhuvud> wait_readable, yes.
<yxhuvud> and it is private in the sense that it is intentionally undocumented, not as in being uncallable.
<yxhuvud> If you need it I'd open an issue (either on github or the forum) describing your use case and see what people recommend.
<postmodern> found it in src/io/eventd.cr. isn't clear how it works. I'm guessing IO::FileDescriptor registers the fd with libeventd?
<postmodern> cool that seems to work
<postmodern> i assume there's a crystal wrapper around LibC.open(). Tempted to use the built-in IO modules/classes, but also worried about them potentially messing with the device or attempting to automtically read/buffer
<yxhuvud> I think it was possible to turn off the buffered-ness of filedescriptor, but I havn't actually tested.
<postmodern> i assume `LibC.open(path, LibC::O_RDWR | LibC::O_NONBLOCK, 0)` this could be done via `File.open(path, mode="rw"); file.blocking = false`?
<postmodern> also would probbly need to disable utf8, since it's a raw io device
<yxhuvud> you may not have to care if you read to a Slice instead of to a String.
<postmodern> yeah i think the safest option is to initialize a @io = IO::FileDescriptor, and proxy only certain method calls to it, that way a user can't accidentally call #gets on it
<postmodern> holy cow it works! i dumped 30 JPEG frames and i can see my blurry fingers moving infront of the camera
<postmodern> now to cleanup how i initialize/populate a Format object (V4L2Format struct under the hood) to set the format
<postmodern> getting closer to posting this to github
<yxhuvud> cool!
oz has quit [Read error: Connection reset by peer]
zorp has quit [Ping timeout: 240 seconds]
Human_G33k has joined #crystal-lang
HumanG33k has quit [Ping timeout: 244 seconds]
oz has joined #crystal-lang
postmodern has quit [Quit: Leaving]
mistergibson has joined #crystal-lang
<oprypin> postmodern: i think there was supposed to be a top level select method
<oprypin> libc.select is not usable because it blocks the thread. and there's just one thread in Crystal
<FromGitter> <Blacksmoke16> isnt that a thing already?
<oprypin> well yes
<oprypin> i just wasn't sure. thanks for the link
<FromGitter> <Blacksmoke16> np
<oprypin> damn what an article
balate_jeff_ has joined #crystal-lang
<oprypin> the writing style, the insight 👌
alexherbo2 has quit [Ping timeout: 240 seconds]
duane has quit [Ping timeout: 265 seconds]
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 240 seconds]
alexherbo2 has joined #crystal-lang
duane has joined #crystal-lang
alexherbo2 has quit [Quit: Ping timeout (120 seconds)]
alexherbo2 has joined #crystal-lang
alexherbo2 has quit [Ping timeout: 256 seconds]
balate_jeff_ has quit [Ping timeout: 240 seconds]
<FromGitter> <j8r> Any advantage of naming fibers through spawn?
<FromGitter> <j8r> It could be useful if there was a way to list all fibers
alexherbo2 has joined #crystal-lang
<FromGitter> <Blacksmoke16> maybe would help with identifying one as part of `Fiber.current`?
<FromGitter> <j8r> right
<FromGitter> <j8r> and with `next` and `previous`, I guess we can get a list of fibers
<FromGitter> <j8r> Will do a shard to have this runtime info and metrics
<FromGitter> <j8r> So I can know how many threads, but more importantly how many fibers are present and/or running
<FromGitter> <grkek> Henlo guize
<FromGitter> <Blacksmoke16> o/
<FromGitter> <grkek> nul byte haha
<FromGitter> <grkek> Some cunt is downvoting my reddit posts
<FromGitter> <j8r> Any Crystal alternative for https://ruby-doc.org/core-2.7.1/ObjectSpace.html ?
<FromGitter> <Blacksmoke16> can define a `finalize` method on a class, thats all im aware of
mistergibson has quit [Quit: Leaving]
balate_jeff has joined #crystal-lang
balate_jeff_ has joined #crystal-lang
balate_jeff_ has quit [Client Quit]
balate_jeff has quit [Quit: Leaving]
<raz> hmmm i don't understand this rust hype
<raz> it seems like an inferior crystal to me except for high performance cases where manual memory management is really needed
<raz> but their docs are top notch, gotta give them that
Human_G33k has quit [Remote host closed the connection]
<FromGitter> <dscottboggs_gitlab> https://carc.in/#/r/9j2r
<FromGitter> <dscottboggs_gitlab> why is this?
<FromGitter> <RespiteSage> Re Rust: I think it's also supposed to make concurrence safer, but the syntax and memory management is certainly a lot weirder and less ergonomic than Crystal.
<FromGitter> <Blacksmoke16> Only works in context of a method
Human_G33k has joined #crystal-lang
<FromGitter> <dscottboggs_gitlab> 👀 you can't iterate ivars from a class method??
<FromGitter> <dscottboggs_gitlab> shit!
<raz> agree RespitSage. certainly lots of good thinking in rust. but the good parts seem to all be mirrored in crystal with less verbose syntax
<raz> and constantly having to think where i read/write to vars, borrow, etc. is almost as painful as go-lang's if-err
<FromGitter> <dscottboggs_gitlab> crystal can never be as fast as rust due to GC. the question is whether that's worth it. You can just write your app using the GC and if you run into problems rewrite a small section to use manual C-style memory management
<raz> i was promised the computer would be doing that type of tedious, repetitive work almost 20 years ago.
<FromGitter> <j8r> Don't know about GC and fast
<FromGitter> <dscottboggs_gitlab> are you saying a runtime GC could be as fast as borrow-checking or RAII?
<raz> yea, the speed diff is a thing. rust makes sense to me where that diff is needed. but frankly... i think you have to look really long and hard to find use-cases where crystal isn't plenty fast enough.
<FromGitter> <j8r> Having no GC/free is the fastest
<FromGitter> <dscottboggs_gitlab> what, just allocate and never free?
<raz> that can make sense for many types of programs, yep
<FromGitter> <j8r> yep. Of course, it can cause problems haha
<FromGitter> <Blacksmoke16> > 👀 you can't iterate ivars from a class method?? ⏎ ⏎ No you deff can do that, but you're not doing that in your example
<FromGitter> <j8r> Yes some companies disable the GC, an restart the program regularly
<FromGitter> <j8r> IIRC Dropox with Python for example
<FromGitter> <RespiteSage> I think I'd like to learn to write Rust eventually because of the ability to generate shared libraries, because I'm often handling large amounts of data (so the speed and safer concurrency may be worthwhile), and because I want to be able to wrap my head around its weirdness, but it's not a priority for me right now, and Crystal is much more fun.
<raz> j8r: i think dropbox moved to rust ;)
<FromGitter> <dscottboggs_gitlab> https://carc.in/#/r/9j2x
<raz> +1 on much more fun
<FromGitter> <j8r> ... raz, they have moved to python 3. They have a huge code base
<FromGitter> <j8r> GC languages can be faster
<FromGitter> <dscottboggs_gitlab> @j8r I've never heard of anyone doing that, that's crazy lol... a few extremely resource-intenseive cases I've heard of allocate the exact amount needed up-front and only use that.
<FromGitter> <Blacksmoke16> https://carc.in/#/r/9j2z
<FromGitter> <j8r> Freeing memory all at once instead of little by little can be more efficient. But stop the world GC can be problematic
<raz> j8r: ah yea. looks like they moved to rust (from golang) on parts of the server-side
<FromGitter> <dscottboggs_gitlab> also I suppose if you really wanted to you could `-Dgc=none` but I wouldn't lol
<FromGitter> <dscottboggs_gitlab> fair enough I guess
<FromGitter> <dscottboggs_gitlab> @Blacksmoke16 so I need to put a verbatim block into my class method and it will work? ok then haha
<FromGitter> <Blacksmoke16> yea, you can also do something like https://play.crystal-lang.org/#/r/9i57
<FromGitter> <Blacksmoke16> use a generic of the type you want, then defer the actual parsing of the ivar/annotation data until within a class/initializer method of that other type
<FromGitter> <Blacksmoke16> and/or https://play.crystal-lang.org/#/r/9ipl, but im not sure if this is a total hack or genius ha
<FromGitter> <j8r> Sure, at https://dropbox.tech/application they talk about 4 million lines of Python. They won't go anytime soo
<FromGitter> <RespiteSage> The switch to Rust isn't the focus there, and actually the main focus of the article (why they rewrote a central feature of their code and why another organization might want to) is very interesting.
<raz> somehow the worst languages always have the most success, python, javascript
<raz> go lang
<FromGitter> <j8r> @RespiteSage was mainly responding to raz, that they switch to Rust, which is not the case
<FromGitter> <RespiteSage> Yeah, I was composing that message before you replied. :)
<raz> j8r: yea not all of it. presumably just the parts where python is too slow
<FromGitter> <j8r> But that's right that Rust gains some traction in big techs like Microsoft, Google and Dropbox
<raz> well, soon we'll have our crystal on rails and everyone will regret their bets on the wrong horse
<FromGitter> <RespiteSage> I think that @dscottboggs_gitlab's point about just focusing on rewriting/focusing on/using a faster technology for the parts that need to be faster holds, and it seems like that's what they did.
<FromGitter> <dscottboggs_gitlab> yeah it's something I've looked into pretty heavily in Crystal specifically. For practice/proof of concept, I made a file server (https://github.com/dscottboggs/cached-file-server/) which uses event-driven memory management to handle a cache of files to serve
<FromGitter> <RespiteSage> I honestly think that Crystal with bindings to Rust shared libraries could be a powerful combo because of the ease of creating bindings in Crystal and the (apparent) ease of creating shared libraries in Rust. However, I've not yet spent enough time with Rust (let alone tried that actual combo) to see if that actually makes sense. I think that even as weird as Rust is, I'd probably prefer it to C if I needed
<FromGitter> ... to write a shared library to make something faster, because C is so dangerous and I'm not an expert with it.
<FromGitter> <RespiteSage> Oh, nice. You just exposed the manual memory management from LibC and used it directly in Crystal.
<FromGitter> <dscottboggs_gitlab> yup
<raz> yup, rust is said to be nice fore shared libs
<FromGitter> <dscottboggs_gitlab> I don't think Crystal/Rust bindings are possible, unless you write an intermediary library in C which allowed them to communicate
<FromGitter> <dscottboggs_gitlab> Crystal doesn't even export shared libs at all
<FromGitter> <RespiteSage> I don't think you can bind Rust to Crystal, but Rust can compile to a native shared library that behaves like a C shared library would.
<FromGitter> <dscottboggs_gitlab> interesting. I did not know that
<raz> which you can then use from crystal, win!
<FromGitter> <dscottboggs_gitlab> I don't think it actually works that way, unfortunately https://www.reddit.com/r/rust/comments/abefuy/how_to_create_a_dynamic_rust_library_and_link_to/ed02ajs/
<FromGitter> <RespiteSage> Oh, interesting. I guess that makes sense.
<FromGitter> <dscottboggs_gitlab> It's the same in Crystal. You can technically write a Crystal file with a `fun someFun()` and export that to C, but it has to be in that C-compatible layer to be able to link
<raz> hm, bummer
<raz> then again, personally i'm more interested in the static compilation story anyway
zorp has joined #crystal-lang
<raz> shared libs are just a royal pain for deploying/distributing stuff
<raz> incremental compilation on the other hand... i want that, too
<FromGitter> <RespiteSage> I think the issues described in that Reddit thread only apply if you're distributing the Rust shared library separately from whatever is linking to it.
<FromGitter> <RespiteSage> But I haven't tried it myself, so *shrug*
<FromGitter> <RespiteSage> But if you're interested, here's the official page: https://rust-embedded.github.io/book/interoperability/rust-with-c.html
<FromGitter> <RespiteSage> The docs to do it, I mean.
<FromGitter> <dscottboggs_gitlab> > Just as when using C code in your Rust project you now need to transform data from and to a form that the rest of the application will understand. ⏎ ⏎ that's where it gets hard :/
<FromGitter> <RespiteSage> Yeah, that's true, but that's gonna be an issue if you need to doing bindings anyway.
<FromGitter> <dscottboggs_gitlab> True
<FromGitter> <dscottboggs_gitlab> Idk when I think about things like that I keep coming back to Go. There are a whole bunch of libraries for Go, and since go is strictly a subset of Crystal you could transpile the Go AST nodes into Crystal ones. I tried to write something to do this once, got hung up trying to figure out how to pass nodes directly to the compiler
<FromGitter> <dscottboggs_gitlab> I could've just generated Crystal text code but that just seems...wrong... going from source to AST, back to source, just to generate a different AST, when the compiler already has a way to turn AST into code...
<raz> in order to use go-libraries in crystal?
<raz> or a c-library through go in crystal
* raz scratches head
<FromGitter> <dscottboggs_gitlab> well it would be more like transforming an existing Go library into Crystal code, then using *that* library but yeah the goal would be to have a jumping off point from where the Go guys have already done stuff
<raz> ah got it
<raz> yea i suppose it could be useful. although i haven't been very impressed with the go ecosystem every time i looked for something.
<raz> the other day i wanted a LRU or LFU caching library. figured that's so basic, there must be like 4 different mature impls to choose from
<raz> turns out, there's not even one...
<FromGitter> <dscottboggs_gitlab> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5f330d403b68017018092ebb]
<FromGitter> <dscottboggs_gitlab> > go ecosystem every time i looked for something ⏎ ⏎ yeah idk maybe you're right haha
<FromGitter> <dscottboggs_gitlab> > turns out, there's not even one... ⏎ ⏎ Wow haha
<FromGitter> <RespiteSage> Still, anything to ease building the Crystal ecosystem would be nice.
<raz> dscottboggs_gitlab: didn't you forget a bunch of `if err`s in there :p
<raz> yea +1 on ease. but seeing how it sprouts, many people seem to find it pretty easy already :)
<FromGitter> <dscottboggs_gitlab> hahahahaha yes I'm sure the Go version would be quickly revised to remove some of the pains of using it lol
<raz> writing complex stuff in crystal is just fun. always some kinks, sure, but overall it stacks up very nicely.
<raz> go-lang doesn't stack at all. every time someone tries to write a web framework with abstractions that are not a constant pain it gets shot down because "nu-uh, not idiomatic"
<raz> thou shalt not argue with the church of the if-err
zorp has quit [Ping timeout: 256 seconds]
alexherbo2 has quit [Ping timeout: 256 seconds]
<oprypin> how can a macro optionally capture a block and detect when one was passed
<FromGitter> <Blacksmoke16> i think you can just add a `{{yield}}` and it'll just ignore it if you dont use a block