<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>
<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> 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>
<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> 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>
<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?
<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>
<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>
<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> 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>
<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> @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> 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>
<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> 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>
<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>
<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>
<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> 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> 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>
<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>
<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`