ChanServ changed the topic of #crystal-lang to: The Crystal programming language | http://crystal-lang.org | Crystal 0.33.0 | Fund Crystal's development: http://is.gd/X7PRtI | GH: https://github.com/crystal-lang/crystal | Docs: http://crystal-lang.org/docs/ | API: http://crystal-lang.org/api/ | Gitter: https://gitter.im/crystal-lang/crystal
MasterdonX has quit [Ping timeout: 260 seconds]
MasterdonX has joined #crystal-lang
_ht has quit [Remote host closed the connection]
ur5us has joined #crystal-lang
<FromGitter> <tenebrousedge> @Blacksmoke16 how do I access a block in a macro that's not an explicit arg?
<FromGitter> <Blacksmoke16> mm, got an example?
<FromGitter> <tenebrousedge> just ⏎ ⏎ ```def foo ⏎ yield 1 ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e5477ef901209179b39c78c]
<FromGitter> <tenebrousedge> there's an implicit block because of yield
<FromGitter> <Blacksmoke16> try like `block_arg`
<FromGitter> <tenebrousedge> as far as I can tell that's only explicit block args
<FromGitter> <Blacksmoke16> what do you want to access here? the 1?
<FromGitter> <Blacksmoke16> or just know that it can be executed with a block?
<FromGitter> <tenebrousedge> I want the arity of the passed-in block
<FromGitter> <Blacksmoke16> ah so like `yield 1,2` would be 2?
<FromGitter> <tenebrousedge> yes
<FromGitter> <Blacksmoke16> mmm
<FromGitter> <tenebrousedge> I want something like: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e5479528f8af6553a00cce1]
<FromGitter> <Blacksmoke16> i cant even seem to get `block_arg` to do anything
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/8mc9
<FromGitter> <tenebrousedge> yeah :/
<FromGitter> <Blacksmoke16> id file a bug
<FromGitter> <tenebrousedge> really?
<FromGitter> <Blacksmoke16> maybe? sure seems as if the block arg is never there
<FromGitter> <Blacksmoke16> even if the method yields/has `&block`
<FromGitter> <tenebrousedge> huh `&block` doesn't work either?
<FromGitter> <Blacksmoke16> no thats what i had in that playground link
<FromGitter> <tenebrousedge> you're right
<FromGitter> <tenebrousedge> huh
<FromGitter> <tenebrousedge> @Blacksmoke16 https://github.com/crystal-lang/crystal/issues/5334
<FromGitter> <Blacksmoke16> ah huh
<FromGitter> <Blacksmoke16> that would do it
<FromGitter> <tenebrousedge> well dang
<FromGitter> <tenebrousedge> @Blacksmoke16 any other way of getting what I want there, that you can think of?
<FromGitter> <tenebrousedge> the trivial use-case would be `[1,2,3].reduce(0, &.+)` but the actual thing that I wanted it for was that I had an array of `Procs` and I wanted to do `arr.reduce([] of String, &.call)`
<FromGitter> <tenebrousedge> maybe just a separate `fold` method?
<FromGitter> <Blacksmoke16> hmm, could you type it?
<FromGitter> <tenebrousedge> nah, screws up the other `reduce` calls
<FromGitter> <Blacksmoke16> hm :/
<FromGitter> <tenebrousedge> okay, this doesn't work how I want anyway :/
<FromGitter> <Blacksmoke16> :sad:
<FromGitter> <tenebrousedge> IKR? dreams == crushed
<FromGitter> <tenebrousedge> maybe tomorrow I'll be smarter
* FromGitter * Blacksmoke16 needs to think of a way to handle resolving types in the correct order
<FromGitter> <Blacksmoke16> i.e. if a depends on b, b needs to be defined first
<FromGitter> <smalls12> how do you deal with an empty struct from a header file when creating a binding in crystal; I'm getting empty structs not allowed when trying to build
<FromGitter> <smalls12> the contents of the struct is hidden inside the c library im building a binding for
<FromGitter> <smalls12> that was a bit vague so some more details are the expected behavior for this library is that you create a pointer to this structure and the library will allocate it internally
<FromGitter> <smalls12> so I need to create a pointer to this struct, and then pass the double pointer into the library
<FromGitter> <Blacksmoke16> `In this way we pass a pointer of status_ptr to the function for it to fill its value.`
<FromGitter> <smalls12> I have attempted something similar ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e548bcd1be0ff01d5a8bdca]
<FromGitter> <smalls12> but I get this
<FromGitter> <smalls12> `Module validation failed: Cannot allocate unsized type`
<FromGitter> <Blacksmoke16> what is `type`?
<FromGitter> <Blacksmoke16> it would have to be an actual type class
<FromGitter> <Blacksmoke16> like `Int32`, or `MyType`
<FromGitter> <smalls12> hmm
<FromGitter> <smalls12> its a structure from the c header
<FromGitter> <smalls12> its defined like this
<FromGitter> <smalls12> `typedef var_s var_t`
<FromGitter> <smalls12> I made a corresponding type inside crystal
<FromGitter> <smalls12> oh well here is part of the issue
<FromGitter> <smalls12> `type MyCrystalVar = Void`
<FromGitter> <smalls12> hmm
<FromGitter> <smalls12> so I guess it boils down to
<FromGitter> <smalls12> how do I make the structure in crystal that comes from a c header
<FromGitter> <smalls12> I've seen other examples which look to completely spell out the contents of the structure, like from the libcurl bindings
<FromGitter> <Blacksmoke16> then like `uninitialized MyStruct`?
<FromGitter> <smalls12> right
<FromGitter> <smalls12> but since the structure's implementation is hidden
<FromGitter> <smalls12> I have to declare an empty structure
<FromGitter> <smalls12> which the compiler does not allow
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <smalls12> if it is just a requirement for crystal, I could make a pull request to update the c header with a way to return an implemented structure instead of passing in the double pointer
<FromGitter> <smalls12> i'll keep poking around, thanks :)
<FromGitter> <Blacksmoke16> gl, maybe someone more familiar with C could help more :p
<FromGitter> <smalls12> s'all good :D
HumanGeek has joined #crystal-lang
fifr has quit [Ping timeout: 260 seconds]
dostoyevsky has quit [Ping timeout: 260 seconds]
Human_G33k has quit [Ping timeout: 260 seconds]
commavir has quit [Ping timeout: 260 seconds]
fifr has joined #crystal-lang
DTZUZU has quit [Read error: Connection reset by peer]
dostoyevsky has joined #crystal-lang
commavir has joined #crystal-lang
DTZUZU has joined #crystal-lang
postmodern has joined #crystal-lang
<FromGitter> <christopherzimmerman> For abstract types just use void pointers and cast if you need to, although I mainly use aliases. I do it a lot for my Opencl bindings https://github.com/crystal-data/opencl.cr
<FromGitter> <christopherzimmerman> Unfortunately there isn’t a way to take advantage of “out”
<postmodern> when working with raw IO, is it wise to directly use LibC.open() or use File, and pass #fd down to your low-level ioctls?
DTZUZU has quit [Ping timeout: 255 seconds]
<FromGitter> <Blacksmoke16> `fd` might offer some interoperability gains?
<postmodern> well it's a file descriptor pointing to a /dev/video0 device. I did notice there's some nice logic in IO::FileDescriptor already for handling open vs closed state, which made me think twice
_whitelogger has joined #crystal-lang
<postmodern> ah had to remove the Macros:: namespace
<FromGitter> <watzon> Ok I want to know the rationale behind this
<FromGitter> <watzon> You can't return from a captured block, so...
DTZUZU has joined #crystal-lang
<FromGitter> <watzon> Actually my error is weird, because it's saying I can't use `yield`. I don't get it.
<FromGitter> <Blacksmoke16> `next`?
<FromGitter> <Blacksmoke16> or `break`
<FromGitter> <watzon> So this is what it doesn't like ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e54a7089c3b2f07f7161ffa]
<FromGitter> <watzon> Apparently because of the way `find` is written, this isnt' possible
<postmodern> is there some helper method to convert Errno.value into the string value, or do i have to add my own String.new(LibC.strerror(Errno.value)) helper?
<FromGitter> <watzon> Well this is a downer
<postmodern> Blacksmoke16, ah that's sort of what i want, but i want the original message from libc
ur5us has quit [Ping timeout: 272 seconds]
<FromGitter> <watzon> I hate myself for writing this, but it's the only thing that works. Wtf. ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e54adaffa9f20553b4ca1a5]
<FromGitter> <watzon> You should be able to break out of a captured block
<postmodern> holy cow my v4l2 bindings are starting to work!
<postmodern> also wow i love how crystal can convert a Flags enum to a String. Makes print debugging this super slick.
<FromGitter> <wontruefree> I made a prime number generator. https://github.com/wontruefree/prime
<FromGitter> <wontruefree> kind of an initial pass
Seich has quit [Ping timeout: 246 seconds]
Seich has joined #crystal-lang
postmodern_ has joined #crystal-lang
postmodern has quit [Ping timeout: 272 seconds]
<postmodern_> what's the crystal equiv for enum_for(__method__)? do i have to create a class that includes Enumerable for the desired enumerable object, or can i just wrap the enumerating method?
_whitelogger has joined #crystal-lang
_ht has joined #crystal-lang
_ht has quit [Client Quit]
_ht has joined #crystal-lang
<FromGitter> <yxhuvud> postmodern: `String.new(LibC.strerror(errcode))` can give you the original string from libc.
<FromGitter> <yxhuvud> There might be better ways though ..
<FromGitter> <yxhuvud> Oh, you had found that already. nm
<postmodern_> can i not use macros in the values of an enum definition?
<postmodern_> RGB332 = v4l2_fourcc('R', 'G', 'B', '1') # 8 RGB-3-3-2
<postmodern_> Error: unexpected token: R
Human_G33k has joined #crystal-lang
HumanGeek has quit [Ping timeout: 240 seconds]
<FromGitter> <mavu> does maybe anyone have any thoughts on this error I get when linking on RaspberryPI? ⏎ https://forum.crystal-lang.org/t/llvm-problem-linking-on-arm/1750
sorcus has quit [Ping timeout: 246 seconds]
sorcus has joined #crystal-lang
<FromGitter> <yxhuvud> postmodern: how is the macro defined?
<FromGitter> <yxhuvud> (not saying it is possible or not, but with only that as a sample it is hard to go further).
<FromGitter> <yxhuvud> That doesn't look like a enum definition but rather some usage of enum values. But anyhow, my guess is that you need to invoke a method on the typenodes in the macro. Not certain which one, macros really ain't my strong suite. (ie, instead of `{{a}}` do `{{a.id}}` or some such.
<FromGitter> <yxhuvud> Also I dunno if invoking the macro with Chars is the best idea.
<postmodern_> hmm {{ a.id }} emits to literal R, not 'R'
<postmodern_> this is to define the pixel formats, which are traditionall defined using four characters, or a four character code (fourcc)
<FromGitter> <yxhuvud> It might be that the macro needs to emit a complete ast-node. Meaning that enum values (and more commonly, case branches) don't work by themselves but that the macro needs to emit the whole enum.
<FromGitter> <yxhuvud> Case branches is definitely limited by that, but I don't know about enum values.
<postmodern_> why can't a macro just emit a numerical expression?
<postmodern_> or lvalue, if you will
<postmodern_> oddly enough i successfully defined a similar macro ioctl_ioc which accepts Char literals and does bitwise math on them, although it'
<postmodern_> * it's used to assign values of constants, not within an enum.
<FromGitter> <yxhuvud> It might not be actual lvalues, but rather special syntax, inside enums. But I don't know - I'm just guessing.
<FromGitter> <straight-shoota> postmodern why are you using a macro in the first place? There is really no macro logic involved. You should be able to use a normal method instead: ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e5516208f8af6553a023f1e]
<postmodern_> straight-shoota, valid point. Although this is inside a lib and v4l2_fourcc was originally a #define
<FromGitter> <straight-shoota> `#define` is a C construct and different from Crystal macros
<postmodern_> straight-shoota, #define are basically C macros, but do raw string replacement during preprocessing
<FromGitter> <straight-shoota> In Crystal you simply don't need a macro for that because constants can be assigned any expression. The expression is evaluated at runtime when the constant is accessed for the first time.
<FromGitter> <yxhuvud> Yeah, crystal macros is somewhere in the between of raw text substituion like c macros and hygienic macros.
<postmodern_> straight-shoota, also doesn't look like enums allow method calls, only constant values
<FromGitter> <yxhuvud> it does make sense to force them to be defined at compile-time..
<postmodern_> i'm guessing things like (1 << 2) are considered constants, as all the inputs/outputs are known at compile time, where as 'A'.ord << 1 can't really be known at compile time
<FromGitter> <straight-shoota> Yes, enum values are different
<FromGitter> <straight-shoota> I missed that you're using it to assign enum values.
<postmodern_> we're that constants allow method calls in their values, but not enums
<postmodern_> *weird
<postmodern_> couldn't i do all of the bit math at the macro level?
<FromGitter> <straight-shoota> Yeah it looks weird, but as far as I understand, it is necessary because enum values need to be known at compile time.
<FromGitter> <straight-shoota> Not sure about the specific reasons though
<FromGitter> <straight-shoota> Macro interpreter misses `CharLiteral#ord` for example, so that's not going to be easy to implement as macro
<FromGitter> <Blacksmoke16> could probably add it if we had https://github.com/crystal-lang/crystal/pull/8836 😉
<FromGitter> <straight-shoota> Yeah, that would probably be a good usecase for that
<FromGitter> <straight-shoota> But really, just `CharLiteral#ord` would probably already work
<postmodern_> will come back to this tomorrow
postmodern_ has left #crystal-lang ["Leaving"]
<FromGitter> <straight-shoota> Enum values can have math expressions, so this works: ⏎ ⏎ ```enum Linux : UInt32 ⏎ RGB332 = 82 | 71 << 8 | 66 << 16 | 49 << 24 ⏎ end``` ⏎ ⏎ Macro would just need to transform CharLiteral to NumberLiteral. [https://gitter.im/crystal-lang/crystal?at=5e551b861c4f1707f8cc8272]
darkstardevx has quit [Remote host closed the connection]
darkstardevx has joined #crystal-lang
<FromGitter> <straight-shoota> @Sija I won't pollute the comment thread anymore. We're definitely not at the point to look at individual stylistic details. The current PR helps discussing the overall design on a concrete example. But there are still open issues discuss before we settle on anything.
<FromGitter> <christopherzimmerman> Is there a way to have a default value as a macro argument?
<FromGitter> <christopherzimmerman> ```macro blast(name, *args, prefix = "")```
<FromGitter> <Blacksmoke16> prob would have to go before the splat
<FromGitter> <christopherzimmerman> Hmm, I must be doing something else wrong, since this works
<FromGitter> <christopherzimmerman> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e554817901209179b3bca49]
<FromGitter> <Blacksmoke16> that works since you're using it via a named arg
<FromGitter> <Blacksmoke16> which would not get mixed up in the splat args
<FromGitter> <christopherzimmerman> Yea, that's my use case, the prefix is only used about once every 100 invocations of the macro, I don't want to have to explicitly stick it everywhere
<FromGitter> <j8r> @Blacksmoke16 what do you think, is it better to have response objects or a response handler?
<FromGitter> <j8r> My issue is: by looking at https://petstore.swagger.io/, I don't know how we could have documentation for possible responses without response objects
<FromGitter> <j8r> *automatically generated, of course
<FromGitter> <Blacksmoke16> https://github.com/crystal-lang/crystal/issues/8353 could prob use that to know the possible errors it could throw
<FromGitter> <j8r> hum not really that far
<FromGitter> <Blacksmoke16> i use both for athena, if an action returns an `ART::Response` that is used, otherwise the return value gets JSON serialized
<FromGitter> <j8r> I except to have `ValidationError | User | InvalidID` as a result
<FromGitter> <Blacksmoke16> would they not be just exceptions?
<FromGitter> <Blacksmoke16> like `raise BadRequest.new "invalid body"`
<FromGitter> <Blacksmoke16> is how i handle it
<FromGitter> <j8r> because of the issue you mentioned :P
<FromGitter> <j8r> and also exceptions are notoriously slow
<FromGitter> <j8r> if a backtrace is not useful, no need to unwind the stack
<FromGitter> <Blacksmoke16> maybe if you raise a bunch, but raising one exception isnt going to be the end of the world
<FromGitter> <j8r> sure - but I can easily avoid it, so I do :)
<FromGitter> <j8r> BTW, there no question about it because of the issue you pointed. So we need to use proper types
<FromGitter> <Blacksmoke16> fair enough
<FromGitter> <Blacksmoke16> id argue the ease of use would out weigh the perf impact tho
<FromGitter> <j8r> maybe but then the swagger docs won't be automatically generated
<FromGitter> <Blacksmoke16> assuming each "error" has the same structure it would be doable
<FromGitter> <j8r> I don't follow?
<FromGitter> <Blacksmoke16> `@[Exception(NotFound, "If a user could not be found")]`?
<FromGitter> <watzon> @wontruefree here's my prime number generator based on Ruby's https://github.com/watzon/tgcrypto.cr/blob/master/src/tgcrypto/utils/prime.cr
<FromGitter> <j8r> yes, it is not automatic @Blacksmoke16
<FromGitter> <j8r> it's brittle to do this
<FromGitter> <Blacksmoke16> yea not without some meta programming enhancements to get exceptions that are raised within a method
<FromGitter> <watzon> I've got RSA kind of working too, I think. But I still need to implement the ability to save to and read from a encoded RSA file
yxhuvud has joined #crystal-lang
<FromGitter> <christopherzimmerman> Completely finished the wrapper for ClBlast last night. For one million element matrices. This is going to be super helpful for learning libraries. ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e554e70ef8d646099cf8b68]
<FromGitter> <watzon> Damn that's a nice jump in speed
<yxhuvud> @watzon: Doesn't openssl provide a prime generator?
<FromGitter> <christopherzimmerman> It will be even faster in practice, since I have to allocate the return matrix each time I call the function, but any library can take advantage of only allocating once and continually assigning to the existing matrix.
<FromGitter> <watzon> I'm sure they do, but I am aiming for pure Crystal solutions. They provide RSA too.
<FromGitter> <watzon> Which would be a lot easier to implement lol
<FromGitter> <j8r> For now I will keep the doc generation fairly simple, no annotations. ⏎ I'll improve later, if the project gains traction
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Blacksmoke16> sounds like a plan
<FromGitter> <wout> When including `Enumerable`, `each` should be implemented. Given I have a `getter items : Array(T)`, is the example below the right way to implement each?
<FromGitter> <wout> ```def each(&block : T -> _) ⏎ @items.each { |e| yield e } ⏎ end``` [https://gitter.im/crystal-lang/crystal?at=5e5559505cd3836098cafa04]
<FromGitter> <wout> It works, but is that how it should be?
<FromGitter> <tenebrousedge> you can omit the block argument
<FromGitter> <watzon> You can also do `@items.each(&block)`
<FromGitter> <tenebrousedge> but what's the goal here?
<FromGitter> <watzon> I avoid omitting block arguments, and type them whenever possible, because otherwise you can't pass other blocks into it.
<FromGitter> <tenebrousedge> why are we wrapping `Array` with something that does the same thing?
<FromGitter> <wout> @watzon That's what I did before, but it throws an error.
<FromGitter> <watzon> Hmm what's the error?
<FromGitter> <tenebrousedge> can't you just forward methods to `@items` ?
<FromGitter> <watzon> Tbh I think `Enumerable` and `Iterable` need some fixing
<FromGitter> <tenebrousedge> how?
<FromGitter> <wout> @tenebrousedge It a `struct List` with `JSON::Serializable` included, where `@items` is extracted from JSON.
<FromGitter> <tenebrousedge> `forward_missing_to @items`
<FromGitter> <Blacksmoke16> could also do `delegate .each, to: @items`
<FromGitter> <watzon> I was forced to do this last night because of how `find` is implemented in `Enumerable` ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e555a23ed27b13c42fcaa0a]
<FromGitter> <watzon> I hate it, but it works
<FromGitter> <watzon> Mostly because captured blocks can't break, yield, or return
<FromGitter> <tenebrousedge> but you can wrap them in a proc that does that, no?
<FromGitter> <watzon> Procs are the same
<FromGitter> <wout> @watzon This is the error with `@items.each(&block)`
<FromGitter> <wout> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e555a889c3b2f07f7180656]
<FromGitter> <watzon> Ahhh yeah
<FromGitter> <watzon> See that's the problem
<FromGitter> <Blacksmoke16> right just use `next`
<FromGitter> <Blacksmoke16> `next e`?
<FromGitter> <watzon> It's not his code
<FromGitter> <watzon> That's in `enumerable.cr`
<FromGitter> <wout> @Blacksmoke16 `delegate each, to: @items` is much better indeed. Thanks!
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Blacksmoke16> ah
<FromGitter> <Blacksmoke16> that return is prob redundant, since it would inherently be the return value
<FromGitter> <watzon> This is what I mean when I say they need to be fixed, and the compiler probably needs an update as well to at least allow breaking in captured blocks
<FromGitter> <watzon> Because next doesn't always work apparently
<FromGitter> <watzon> Afaik next just skips the current iteration and goes on to the next one
<FromGitter> <Blacksmoke16> right
<FromGitter> <Blacksmoke16> if you want to totally leave the block, skipping future iterations you would use `break`
<FromGitter> <watzon> But you can't in a case like this https://gitter.im/crystal-lang/crystal?at=5e555a23ed27b13c42fcaa0a
<FromGitter> <tenebrousedge> but why are you trying to do that?
<FromGitter> <Blacksmoke16> can you make a playground link?
<FromGitter> <j8r> I have a strange bug
<FromGitter> <Blacksmoke16> welcome to the club
<FromGitter> <j8r> haha!
<FromGitter> <watzon> @tenebrousedge I had to wrap `find` since the one Enumerable comes with is broken if you attempt to use another block for `each`
<FromGitter> <j8r> works: https://carc.in/#/r/8mgr ⏎ not work: https://carc.in/#/r/8mgq
<FromGitter> <Blacksmoke16> @j8r possibly related to since it has no children, it gets lumped into the parent type or something
<FromGitter> <watzon> Here's a good, although contrived, example of what's going on https://carc.in/#/r/8mgw
<FromGitter> <watzon> Actually this is probably closer to my actual issue https://carc.in/#/r/8mgy
<FromGitter> <tenebrousedge> https://carc.in/#/r/8mh0
<FromGitter> <watzon> See the issue though? That shouldn't be necessary.
<FromGitter> <watzon> You should be able to pass a block in directly no issue
<FromGitter> <tenebrousedge> I am failing to see the issue, as it happens. I don't see much benefit in typing block arguments
<FromGitter> <wout> @tenebrousedge Just tried `forward_missing_to @items` for fun, but it throws the following error:
<FromGitter> <wout> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e555dbd8f8af6553a030869]
<FromGitter> <watzon> There is a major benefit, in that you can pass blocks around that way.
<FromGitter> <watzon> Also the compiler helps you if you're not returning the right thing
<FromGitter> <watzon> And it helps documentation
<FromGitter> <tenebrousedge> @wout interesting. You could omit `Enumerable` then
<FromGitter> <tenebrousedge> there doesn't seem to be a need for the containing struct to be enumerable per se if it's just delegating that functionality to a component property
<FromGitter> <watzon> Unless you want to be able to pass it in to something that requires something be `Enumerable`
<FromGitter> <wout> @tenebrousedge Yeah, you're right. That works as expected.
<FromGitter> <watzon> @Blacksmoke16 you can't make annotations for `fun` declarations right?
<FromGitter> <wout> @watzon That won't be the case I think.
<FromGitter> <watzon> Then you should be good
<FromGitter> <Blacksmoke16> @watzon should be able to, stdlib uses it for like https://crystal-lang.org/reference/syntax_and_semantics/c_bindings/callbacks.html#raises-attribute
<FromGitter> <Blacksmoke16> idk how you would interact with it tho, as the ones that allow you to are prob baked into the compiler
<FromGitter> <watzon> Yeah idk
<FromGitter> <watzon> Wtf is going on github?
<FromGitter> <Blacksmoke16> its having issues
<FromGitter> <Blacksmoke16> https://www.githubstatus.com/
<FromGitter> <watzon> Damn it haha
<FromGitter> <j8r> There is a way @Blacksmoke16
<FromGitter> <j8r> The user can add a rescue block, then return the exception
<FromGitter> <j8r> 2lines more to add in fact
<FromGitter> <Blacksmoke16> is a way for what?
<FromGitter> <j8r> For handling exceptions, and being shown in the apidocs
<FromGitter> <j8r> I guess the Exception type will be addes to the Proc's return types
<FromGitter> <j8r> I'm afraid it will only be `Exception`, and not more restricted like `InvalidIDError`
<FromGitter> <Blacksmoke16> wouldnt be a problem if you just `raise InvalidIDError.new` :p
<FromGitter> <j8r> The Proc won't be typed correctly
<FromGitter> <j8r> I find exceptions not very type safe
<FromGitter> <Blacksmoke16> i mean an exception is inherently an error, so you would have global logic to handle it
<FromGitter> <Blacksmoke16> way i handle it in athena is defining an `HTTException < Exception` class, that i have HTTP specific exceptions inherit from that control the code/message of the response
<FromGitter> <Blacksmoke16> if an exception is not an `HTTPException` it 500s
<FromGitter> <j8r> Handling it is not an issue, it is knowing what route can return (errors or not)
<FromGitter> <Blacksmoke16> yea thats not something you can do atm
ua has quit [Ping timeout: 272 seconds]
<FromGitter> <Blacksmoke16> without some way for the user to define the codes that route could return
<FromGitter> <j8r> The only way is to return a proper type, then any other undefined errors are 500
<FromGitter> <Blacksmoke16> yup
<FromGitter> <j8r> I think the best way is to let user raise if they want, but miss api docs
<FromGitter> <Blacksmoke16> could you just allow a way to define what status codes that route can return?
<FromGitter> <j8r> Or return proper types, and have more info in the docs
<FromGitter> <Blacksmoke16> then from there you essentially have most of what you need
<FromGitter> <j8r> I think the http status should depend on the object returned, not the route
<FromGitter> <j8r> Add an annotation to it for the status code, description and examples for docs
<FromGitter> <j8r> WDYT?
<FromGitter> <Blacksmoke16> that could work
ua has joined #crystal-lang
<FromGitter> <j8r> Usually there are multiple return types for routes
<FromGitter> <Blacksmoke16> not really tho
<FromGitter> <Blacksmoke16> what would an example of that be?
<FromGitter> <wontruefree> @watzon here is the prime I extracted github.com/wontruefree/prime
<FromGitter> <watzon> Nice 👍
<FromGitter> <watzon> I added a couple extra methods to my implementation, but if you wanted to include them I'll just add your shard as a dependency
<FromGitter> <watzon> I see `Prime` itself is missing an `instance` property
<FromGitter> <christopherzimmerman> @watzon I forgot to mention last night, I almost finished up a generic kernel generator for the opencl implementation that should make it usable even if the methods you need aren't implemented. ⏎ ⏎ ```Num.runcl(acl, :+, 2.0, :/, bcl, :*, 3.0) ⏎ # acl + 2 / bcl * 3``` ⏎ ⏎ If you and the neuralegion people start using it, hopefully I can iron out of the kinks quickly.
<FromGitter> <watzon> Oh how interesting
<FromGitter> <watzon> That's pretty cool
<FromGitter> <watzon> If you made `runcl` a macro you could probably just do it like this `Num.runcl(acl + 2.0 / bcl * 3)` and separate each piece into tokens.
<FromGitter> <watzon> Granted I don't know what the code looks like. Just an observation.
<FromGitter> <wontruefree> @watzon yeah I am still working on it. It is hard to figure out the interface without an implementation
<FromGitter> <christopherzimmerman> Ah that would be awesome too, new project for tonight :P
<FromGitter> <watzon> Have fun!
<FromGitter> <wontruefree> part of it is I was not sure if a singleton can be GC
<FromGitter> <watzon> Hmm good question
<FromGitter> <watzon> Idk either
<FromGitter> <wontruefree> in a real project does it matter
<FromGitter> <wontruefree> I think you will always be holding onto caches of large arrays of ints at least
<FromGitter> <wontruefree> so I was messing with it but I need to measure it more
<FromGitter> <wontruefree> or use it in a project
<FromGitter> <watzon> Something I did notice in my implementation is that something definitely isn't getting garbage collected, and not even cleaned on exit
<FromGitter> <wontruefree> It probably wont matter unless it gets deployed on a heroku instance or something
<FromGitter> <watzon> When running `#each` and just writing all of the results to the terminal it was using a very large amount of RAM, and when I exited that RAM wasn't being cleaned
<FromGitter> <wontruefree> interesting
<FromGitter> <watzon> But I actually wonder if that was my terminal's infinite scrollback...
<FromGitter> <watzon> Now that I think of it
<FromGitter> <wontruefree> probably because when crystal exits I think it releases all the memory back to the OS
<FromGitter> <watzon> Yeah and the OS is supposed to clean it
<FromGitter> <watzon> I'd be willing to bet turning off infinite scrollback would fix that problem
<FromGitter> <wontruefree> yeah I dont know if it would matter for your lib
<FromGitter> <wontruefree> but if someone used the crypto lib to build a telegram client it might hold on to a lot of memory per client
<FromGitter> <watzon> Which wouldn't be great
<FromGitter> <mavu> Is it possible to compile crystal programs without GC? And is there a way to check if the GC is working?
<FromGitter> <watzon> Does anyone know if it's possible to get an integer's bitsize? Not the bitsize for the integer type, but the smallest amount of bits that a particular integer fits into.
<FromGitter> <watzon> @mavu pretty sure there's a `--no-gc` flag or something.
<FromGitter> <christopherzimmerman> Like checking if an Int32 can fit into a UInt8 without overflow?
<FromGitter> <watzon> Basically, but I actually want to get the size in bits for an algorithm
<FromGitter> <watzon> Basically I'll be modifying a number outside of a while loop and I want to stop the loop when a number is above a specific bit size
<FromGitter> <watzon> Only way I can think of right now is to use `IO::ByteFormat` to decode the int to bytes and multiply that size by 8
<FromGitter> <watzon> But I actually don't think that would work either
<FromGitter> <watzon> Actually doing `int.to_s(2)` returns a binary string which should be equal to the bit length
<FromGitter> <watzon> But it's not very efficient
<FromGitter> <christopherzimmerman> Are you doing this for a lot of numbers?
<FromGitter> <watzon> Potentially
<FromGitter> <watzon> This is basically what I'm trying to accomplish https://github.com/Legrandin/pycryptodome/blob/master/lib/Crypto/PublicKey/RSA.py#L431
<FromGitter> <watzon> Excuse the Python lol
<FromGitter> <christopherzimmerman> If you're doing it on a lot of numbers at once, you could stick the integers in a tensor, and treat it as a view of UInt8, so you'll get something like: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ Then the size is just the index of the last non-zero along the first axis. [https://gitter.im/crystal-lang/crystal?at=5e557b47901209179b3c6152]
<FromGitter> <christopherzimmerman> It has the benefit of being very memory efficient, since the data is never copied.
<FromGitter> <christopherzimmerman> The setup code for that was: ⏎ ⏎ ```a = Tensor.random(0...1000, [4, 1]) ⏎ puts a.view(UInt8)``` [https://gitter.im/crystal-lang/crystal?at=5e557b7e5cd3836098cb6bad]
<FromGitter> <watzon> https://carc.in/#/r/8mhl
<FromGitter> <watzon> Would you look at that
<FromGitter> <watzon> Found a pop count algorithm
<FromGitter> <tenebrousedge> hmmm
* FromGitter * tenebrousedge condemns it as witchcraft
<FromGitter> <watzon> Lmao
<FromGitter> <watzon> I feel like this could be a beneficial thing to have in the standard library
<FromGitter> <watzon> Could probably improve the performance of `Int#to_s` ever so slightly
<FromGitter> <watzon> Used this algorithm https://en.wikipedia.org/wiki/Hamming_weight
<FromGitter> <tenebrousedge> why not use the second or third ones tho?
<FromGitter> <watzon> I actually am in my library, that was just a test
<FromGitter> <watzon> I wonder what systems have "slow multiplication" though
<FromGitter> <j8r> @Blacksmoke16 usually, an endpoint can return a success or several possible errors
ur5us has joined #crystal-lang
<FromGitter> <j8r> https://petstore.swagger.io/
<FromGitter> <Blacksmoke16> right but wouldnt they all be of the same structure so it wouldnt matter as much
<FromGitter> <Blacksmoke16> i.e. a 400 versus 404 would just be diff message/code in the body
<FromGitter> <asterite> @watzon https://carc.in/#/r/8mi7
<FromGitter> <watzon> Fuck it's already there? I missed it lol
<FromGitter> <asterite> :-D
<FromGitter> <watzon> And here I thought I was clever
<FromGitter> <asterite> It's an LLVM primitive
<FromGitter> <watzon> Ahh well that makes sense
<FromGitter> <watzon> Now I need a good, fast way to generate a random set of bits
<FromGitter> <j8r> popcount sounds like popcorn
<FromGitter> <watzon> `random_bytes` works, but I need to be able to operate on the bits
<FromGitter> <watzon> @j8r 😂 a little bit
<FromGitter> <j8r> I suppose you need safe random?
<FromGitter> <watzon> Would be ideal
<FromGitter> <watzon> Since this is for RSA
<FromGitter> <j8r> I wonder what is `#next_u`...
<FromGitter> <watzon> next `UInt32` maybe?
<FromGitter> <j8r> Wouldn't it fit your use case?
<FromGitter> <watzon> I guess I can probably convert the byte array to a `BigInt` and then use bitwise operations on that
<FromGitter> <Blacksmoke16> https://crystal-lang.org/api/master/BitArray.html maybe kinda useful?
<FromGitter> <watzon> I was wondering if there was something like that
<FromGitter> <watzon> Never used it before
<FromGitter> <j8r> I think we can avoid using an intermediary Byte array
<FromGitter> <watzon> No way to generate a random `BitArray` as far as I can tell
<FromGitter> <watzon> But this seems to work ⏎ ⏎ ```bytes = Random.new.random_bytes(1024 // 8) ⏎ bits = bytes.unsafe_as(BitArray)``` [https://gitter.im/crystal-lang/crystal?at=5e558a293e6ef64161753200]
<FromGitter> <Blacksmoke16> could initialize one, then randomly set each bit?
<FromGitter> <Blacksmoke16> like
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/8mie
<FromGitter> <kinxer> It seems like a `BitArray` constructor that takes a block might be useful.
<FromGitter> <watzon> Hmm I was thinking that this library's `Integer.bitsize` was like `popcount`, but it's not.
<FromGitter> <j8r> It's said that BitArray is stored as an UInt32 internally
<FromGitter> <watzon> https://carc.in/#/r/8mix
<FromGitter> <watzon> This is actually what I need
<FromGitter> <watzon> But as far as random bits it seems like that will work @Blacksmoke16, thanks
<FromGitter> <j8r> There is also `to_s 2`
<FromGitter> <watzon> Yeah but that creates an unneeded string
<FromGitter> <watzon> I'm aiming for speed and efficiency as much as I can
<FromGitter> <watzon> Lol looks like `BitArray#map` functions return an actual array. That's unfortunate.
<FromGitter> <j8r> You will need to do BitArray operations?
<FromGitter> <kinxer> I feel like that ought to be in stdlib.
<FromGitter> <watzon> @kinxer I agree
<FromGitter> <watzon> Also actually implementing `#map` would be nice
<FromGitter> <kinxer> I'm torn about `#map`. `BitArray` includes `Indexable`, so its implementation of `#map` *should* return an array. However, there should also be a method to map to a `BitArray`.
<FromGitter> <kinxer> That's what you want to do, right?
<FromGitter> <watzon> Exactly
<FromGitter> <watzon> I feel like any `#map` ideally should return the same type that you're mapping over
<FromGitter> <kinxer> I think that would start breaking type guarantees from `Enumerable`.
<FromGitter> <watzon> Now I just need to be able to convert the bit array to an integer to check if it's prime...
<FromGitter> <kinxer> @watzon This is my worry: a developer will be expecting this (https://carc.in/#/r/8mky) based on `Enumerable`, but they'll get this (https://carc.in/#/r/8mkz) instead.
<FromGitter> <watzon> I wouldn't be if the library doesn't include Indexible
<FromGitter> <watzon> I just expect map to return the same type I'm mapping
<FromGitter> <watzon> If I wanted an array I could call `to_a`
<FromGitter> <j8r> @watzon https://carc.in/#/r/8ml1
<FromGitter> <watzon> 👏
<FromGitter> <j8r> Too bad that there is no method to give a UInt32 to the BitArray of the stdlib
<FromGitter> <j8r> That's what the constructor do by default, UIn32::MAX or MIN
<FromGitter> <watzon> Right now I'm just fighting with trying to turn a `BitArray` into an integer when I don't know the size of the integer
<FromGitter> <watzon> Well technically I do
<FromGitter> <j8r> What type of integer?
<FromGitter> <watzon> But I really don't want to make a hash of bit size to Int class
<FromGitter> <watzon> They'll all be unsigned ints, but they could be any size
<FromGitter> <kinxer> It sounds like what you need is `BigInt`.
<FromGitter> <watzon> I do
<FromGitter> <watzon> But I don't have a way to turn a bit array into a BigInt
<FromGitter> <j8r> https://carc.in/#/r/8ml2
<FromGitter> <watzon> `IO::Bytformat::Decode` hasn't been implemented for `Big` types
<FromGitter> <watzon> What the fuck is this madness and how did I not know about it?
<FromGitter> <watzon> I had no idea you could do `type.@variable`
<FromGitter> <kinxer> Oof.
<FromGitter> <j8r> I just looked at the implementation ;)
<FromGitter> <kinxer> It's not great to do.
<FromGitter> <watzon> :facepalm:
<FromGitter> <j8r> Yes, not great
<FromGitter> <kinxer> You're breaking encapsulation pretty severely.
<FromGitter> <j8r> It's usually done for low level stuff
<FromGitter> <watzon> Not great, but if it's the only way to access something you need
<FromGitter> <kinxer> Yeah, I guess that's fair.
<FromGitter> <j8r> The best would be a proper API for this
<FromGitter> <j8r> Create a BitArray from an UInt32, get back this UInt32
<FromGitter> <j8r> Perhaps an issue can be open? If there is a valid use case
<FromGitter> <watzon> Hmm @j8r `b.@bits.value.to_i` doesn't actually give a correct number
<FromGitter> <tenebrousedge> `to_i` or `to_i(2)` ?
<FromGitter> <watzon> Well it's a `UInt32`
<FromGitter> <tenebrousedge> hmmmm
<FromGitter> <j8r> Real from?
<FromGitter> <j8r> I guess the size of the BitArray has to be tweaked
<FromGitter> <mavu> So, I was trying to follow but, do I understand correctly that you are trying to take the bitstream/bitarray and turn it into INTs ? Of different size?
<FromGitter> <j8r> https://carc.in/#/r/8mlj
<FromGitter> <j8r> I am not familiar enough with low level to have a perfect BitArray size
<FromGitter> <watzon> @mavu basically what it comes down to is this: I need to generate a random integer of a given bit size and then check if it's prime, repeating until it is.
<FromGitter> <watzon> The problem is generating the random integer of a given bit size.
<FromGitter> <j8r> First, you have to convert this bit size to UInt32
<FromGitter> <mavu> Ahh. so you generate random bits, and want to turn that into a int of the desired size.
<FromGitter> <watzon> Yep that's what I'm trying
<FromGitter> <j8r> Then use https://crystal-lang.org/api/master/Random.html#rand(range:Range(Int,Int)):Int-instance-method
<FromGitter> <mavu> does this maybe help?
<FromGitter> <watzon> Unfortunately not for this case
<FromGitter> <watzon> @j8r how would that work? That would work for a given range I guess, but how do I determine the start and stop point for a given bit size?
<FromGitter> <watzon> It also unfortunately doesn't work for BigInt's, and if the given bit size is 1024 or 2048, as it's likely to be, I'm going to need `BigInt` support
<FromGitter> <j8r> You know the size of bits you want, right?
<FromGitter> <watzon> Yes
<FromGitter> <watzon> But I also do need to be able to generate a 5 bit integer, or a 73 bit integer, or a 287 bit integer. So relying on the built in sizes isn't going to help me much.
<FromGitter> <watzon> If they say `Prime.random(12)` I need to return a random prime that fits into exactly 12 bits. Doesn't matter what type I actually return. It could be a `UInt16`, `BigInt`, whatever. It's just the bit width of the actual number that matters.
<FromGitter> <j8r> Ok!
_ht has quit [Remote host closed the connection]
<FromGitter> <watzon> Such is the problem 😅
<FromGitter> <j8r> Yeah :]
<FromGitter> <j8r> I will look at the Random internals
<FromGitter> <watzon> If `BitArray` had a `to_s` that actually returns the binary rather than `BitArray[01010101]` I could pass that string into a `BigInt`
<FromGitter> <watzon> I may have to monkey patch it
<FromGitter> <j8r> I think I got it
<FromGitter> <watzon> Yeah?
<FromGitter> <j8r> https://carc.in/#/r/8mm0
<FromGitter> <j8r> Remains converting an integer to a bit equivalent
<FromGitter> <j8r> Man
<FromGitter> <j8r> I am close
<FromGitter> <j8r> https://carc.in/#/r/8mmb
<FromGitter> <kinxer> https://carc.in/#/r/8mmf
<FromGitter> <kinxer> Does require that string, though.
<FromGitter> <watzon> Orrrr
<FromGitter> <watzon> Maybe
<FromGitter> <watzon> https://carc.in/#/r/8mmk
<FromGitter> <mavu> how about this ? Do it manually? (assuming little endian, and also not sure if its even correct :-) )
<FromGitter> <watzon> I don't necessarily like using a string, but it doesn't require any patching and handles BigInts
<FromGitter> <mavu> https://carc.in/#/r/8mml
<FromGitter> <mavu> could have cleaned it up a bit sorry...
<FromGitter> <j8r> Works: https://carc.in/#/r/8mn0
<FromGitter> <watzon> Lol I was gonna say @mavu, what am I looking at?
<FromGitter> <j8r> Sure it uses a string, but not sure that using BitArray will be faster
<FromGitter> <watzon> @j8r only problem is I need a min too
<FromGitter> <j8r> What would it be?
<FromGitter> <watzon> 0 doesn't work, because then it's 1 bit to the given number of bits
<FromGitter> <kinxer> @j8r https://carc.in/#/r/8mn3
<FromGitter> <j8r> It can be done like the max
<FromGitter> <mavu> https://carc.in/#/r/8mn1 ⏎ I'm still not sure if I understood the problem, but This is supposed to take the Bits and make a bigint out of them.
<FromGitter> <watzon> Yeah that's what I'm gonna do
<FromGitter> <j8r> @mavu the inter is too big
<FromGitter> <mavu> but what ever you two are sharing there looks a lot more concise :)
<FromGitter> <watzon> Has to do `to_big_i` too, but I got that
<FromGitter> <j8r> No need of big
<FromGitter> <j8r> Just use `UInt64`
<FromGitter> <mavu> I thought someone mentioned 1000 bits?
<FromGitter> <watzon> I cant guarantee the bit size will fit in a UInt64
<FromGitter> <mavu> ohh. got that wrong.
<FromGitter> <j8r> Sorry I meant @kofno
<FromGitter> <watzon> My main use case is going to be defaulting to 1024 bits
<FromGitter> <j8r> @kinxer
<FromGitter> <j8r> (Sorry)
<FromGitter> <j8r> So, put it in a string or bytes then
<FromGitter> <mavu> wait. how do you squeeze 1024 bits into UInt64?
<FromGitter> <mavu> shouldn't that only be 64*8 bits?
<FromGitter> <j8r> Right
<FromGitter> <j8r> So what's the issue now, size?
<FromGitter> <watzon> Yeah, hence the reason I'm using a `BigInt`. I need to return an integer, but that integer may end up being larger than even a UInt128.
<FromGitter> <watzon> The range method does work great though
<FromGitter> <j8r> Ok, I guess with BigInt inside the range will do the trick
<FromGitter> <watzon> Now I just have to deal with checking if a potentially very large number is prime
<FromGitter> <watzon> But this stuff works. Thanks guys!
<FromGitter> <j8r> You're welcome!
<FromGitter> <mavu> Just curious, what did you end up using now?
<FromGitter> <watzon> Basically this ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e55a2c4476ff13c43b4930e]
<FromGitter> <watzon> Checking very large numbers for primality is taxing though
<FromGitter> <mavu> The smalles number with the given number of bytes is allways 1, isn't it?
<FromGitter> <watzon> Actually it should probably be the other way around
<FromGitter> <watzon> 1000000 ⏎ instead of ⏎ 0000001
<FromGitter> <mavu> ahhh, smalles number that actually needs to be that many bytes. yes.
<FromGitter> <watzon> Hmm never mind haha. How I have it currently it's always generating the correct number of bytes.
<FromGitter> <kinxer> Your application actually requires that the number is the smallest number that requires that number of bytes?
<FromGitter> <watzon> Well the range does
<FromGitter> <watzon> I need the smallest possible and the largest possible
<FromGitter> <kinxer> But the 256-bit range really shouldn't include 1?
<FromGitter> <kinxer> 'Cause the number of possible integers in the range you're setting is actually half of your bit-length.
<FromGitter> <kinxer> Since you're essentially just setting the first bit to 1 and then randomizing the rest.
<FromGitter> <watzon> Yeah that's what I was thinking. For some reason flipping the numbers around made things weird
<FromGitter> <watzon> Is there a bitwise function that will shift bits and set all the bits to 1?
<FromGitter> <tenebrousedge> shift bits which way?
<FromGitter> <watzon> Left
<FromGitter> <watzon> Actually I don't need that
<FromGitter> <watzon> I don't think so anyway
<FromGitter> <tenebrousedge> okay
<FromGitter> <watzon> To get the min size I should be able to do this `BigInt.new(1) << (nbits - 1) + 1`
<FromGitter> <watzon> And the max is just `BigInt.new(1) << nbits`
<FromGitter> <tenebrousedge> wotay
<FromGitter> <kinxer> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e55a725101adb4160c80f52]
<FromGitter> <kinxer> That's equivalent to what you meant above, I think.
<FromGitter> <watzon> Yeah I think it's basically the same haha
<FromGitter> <tenebrousedge> `** (n -1)` == `** n.pred`
<FromGitter> <watzon> I think a left shift may be faster than an exponential operation though
<FromGitter> <watzon> I just did this ⏎ ⏎ ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=5e55a7a31be0ff01d5aba8b5]
<FromGitter> <mavu> ``````from = ( "1" + "0" * (nbits - 1) ).to_big_i(2)``` ⏎ or this should work too, right?
<FromGitter> <watzon> It should, just not as fast
<FromGitter> <kinxer> @tenebrousedge Oh, yeah. I forgot about `#pred`. I think `n - 1` is more clear, though.
<FromGitter> <kinxer> @watzon The left shift may be faster, but it might also be that LibGMP (which handles the arbitrary-precision math) just shifts behind the scenes when doing powers of 2.
<FromGitter> <watzon> That's very true
<FromGitter> <kinxer> Since performance seems to be a pretty important factor for you, you should probably work up a realistic implementation test and try both (or just use shifting, if you think it's just as clear).
<FromGitter> <watzon> Yeah I probably will. I'll be doing a lot of performance tweaking at some point, and benchmarking along the way.
<FromGitter> <watzon> We need a good profiling tool for Crystal
<FromGitter> <tenebrousedge> @kinxer if writing `n - 1` needs parentheses I prefer `pred`
<FromGitter> <kinxer> Fair enough. :)
postmodern has joined #crystal-lang
<postmodern> why doesn't CRC32 inherit from Digest? They seem to have similar APIs/uses.
<FromGitter> <watzon> /watzon shrugs
* FromGitter * watzon shrugs
<FromGitter> <watzon> There are a lot of issues with the Crypto layer
<postmodern> also appears CRC32 is just a wrapper around LibZ
<postmodern> was thinking about porting my digest-crc ruby lib over. Ended up inheriting from Digest::Base for all of the CRC algos.
<FromGitter> <watzon> Might be worth it
<FromGitter> <watzon> Crystal could not have enough crypto resources at this point
<FromGitter> <watzon> We're severely lacking
<postmodern> arg how the heck do you get a raw Char object out of a Macros::CharLiteral
<FromGitter> <Blacksmoke16> example?
<FromGitter> <Blacksmoke16> should just be able to do like `char = {{ char.id }}`
<FromGitter> <Blacksmoke16> or maybe w/o the `.id`