ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Fund Crystal's development: | GH: | Docs: | Gitter:
<FromGitter> <> I finally finished the specs
<FromGitter> <> What is the procedure for releasing a library/making it discoverable?
Nik- has quit [Ping timeout: 256 seconds]
ua_ has quit [Ping timeout: 256 seconds]
<FromGitter> <Blacksmoke16> Guest13: for what reason?
<FromGitter> <Blacksmoke16> publish a release on GH
<FromGitter> <Blacksmoke16> like `v0.1.0`
<FromGitter> <Blacksmoke16> the `v` is impt
ua_ has joined #crystal-lang
<FromGitter> <Blacksmoke16> also make sure what's in your `shard.yml` matches it
<FromGitter> <> @Blacksmoke16: and how is it then discoverable?
<FromGitter> <> I also don't use GitHub
<FromGitter> <Blacksmoke16> it wouldn't be in that case
<FromGitter> <Blacksmoke16> most of the shard websites just scape GH/gitlab
<FromGitter> <Blacksmoke16> there are some that are manual registries you could add it to tho
<FromGitter> <> gotcha
<FromGitter> <> Now that my library is complete, I'm going to actually compare the performance with both my CL and NIm ports
<FromGitter> <Blacksmoke16> 🎉 sounds like a plan
<FromGitter> <Blacksmoke16> ill be curious to see
<FromGitter> <> I'm just going to measure a known expensive function common used in hot paths, so may not be the best test, as there are many functions.
<FromGitter> <> Should I use `Benchmark.measure` or ``?
<FromGitter> <Blacksmoke16> `.ips`
<FromGitter> <> I don't have a comparable option for the other languages
<FromGitter> <Blacksmoke16> Ah, hmm
<FromGitter> <Blacksmoke16> Maybe just good ol time then?
<FromGitter> <> Hmm, something strange is going on
<FromGitter> <Blacksmoke16> Oh?
<FromGitter> <> Called a method 10mil times and then called `puts` after the loop. It takes about 5 seconds and prints out what I expect with `crystal run`, but with `crystal build --release && ./bin/origin` it terminates instantly and prints nothing.
<FromGitter> <Blacksmoke16> Crystal build doesn't put it in bin
<FromGitter> <> I wonder what is in bin then...
<FromGitter> <Blacksmoke16> Something you built a while ago via shards build probably
<FromGitter> <> Well results don't look too good for Crystal
<FromGitter> <> Lisp (SBCL) is incredibly fast though, so not sure how fair a comparison
deavmi has quit [Read error: Connection reset by peer]
deavmi has joined #crystal-lang
<FromGitter> <> Allocating API: ⏎ CL: 0.566s ⏎ Crystal: 1.831s ⏎ ⏎ Mutable API: ... []
<FromGitter> <Blacksmoke16> Can you share the test code?
<FromGitter> <> ```code paste, see link``` []
<FromGitter> <> I see the problem
<FromGitter> <> Well a good chunk of the time anyway
ua_ has quit [Ping timeout: 258 seconds]
<FromGitter> <mattrberry> Just curious, is there a technical reason that indirect initialization isn't supported? I'm looking at an example like this: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ I looked through the test cases in the compiler, and it looks like this one isn't explicitly tested anywhere. Is there any reason that this *could* be nilable? []
<FromGitter> <> The tested function was needlessly cloning an object. I fixed that, and the results still surprise me: ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <Blacksmoke16> thats more like it
<FromGitter> <Blacksmoke16> might be some more optimizations you can make
<FromGitter> <> Aggressively inlining all the used functions saves a little more, but still a ways off in the allocating api
ua_ has joined #crystal-lang
<FromGitter> <> The CL code uses plain old static arrays, not a class with a static array member, and they are different enough in other ways that there may be some noise between the two implementations
<FromGitter> <> and i know nothing about the memory allocator for class objects in Crystal
<Guest13> Blacksmoke16: I am abusing macros and constants to generate code, but macros do not consider __Name a constant
<Guest13> May there be a way to tell the compiler to force a variable to be constant at compile time?
<Guest13> so that my macro resolves correctly
<FromGitter> <Blacksmoke16> thats just not valid syntax afaik
<FromGitter> <Blacksmoke16> oh apparently it is
<Guest13> yea i tested it as well, but macros dont treat it like a constant
<FromGitter> <Blacksmoke16> got some example code that reproduces this?
<Guest13> sure, one sec
<FromGitter> <Blacksmoke16> 👍 and whats the reasoning for needing the `_`?
<FromGitter> <> Constants should be all caps too, like that carcin example iirc
<FromGitter> <> (unlike your example `__Name`
<FromGitter> <Blacksmoke16> thats convention, but to the compiler they just need to start with a capital letter
<Guest13> i think crystal convention is snake case constants
<Guest13> or something, but besides the point lol
<Guest13> or was it yellign snake case
<FromGitter> <Blacksmoke16> `SCREAMING_SNAKE_CASE` yes ^
<Guest13> cant recall lol
<FromGitter> <> Right, but doesn't the first character determine if it's a constant?
<Guest13> one moment with the code, have to refactor it to simplify
<FromGitter> <> There *is* the `const` keyword, that I accidental discovered, but I don't remember reading about it anywhere in the reference
<FromGitter> <> It's probably unrelated/reserved/for internal use
<FromGitter> <Blacksmoke16> 🤔
<FromGitter> <Blacksmoke16> pretty sure thats not a thing
<FromGitter> <> You're probably right. I had a not very good error message that made me think so at the time.
<FromGitter> <Blacksmoke16> oh?
<FromGitter> <> I don't remember what it was a couple weeks ago
<FromGitter> <Blacksmoke16> gotcha
<Guest13> okay done
<Guest13> prepare your brains for utter nonsense
<Guest13> theres the code with addition of what i would like to achieve
<Guest13> of course this is heavily stripped of anything remotely related to my project, but it does reflect the idea quite well
<Guest13> as you can see, when the create macro runs, __Write is not considered a constant during the APP_MAP generation
<FromGitter> <Blacksmoke16>
<FromGitter> <Blacksmoke16> yes, thats exactly the problem, because it's not a constant
<FromGitter> <Blacksmoke16> a const must start with an uppercase letter
<Guest13> yea i was hoping since __LINE__ and others were considered "constants"
<Guest13> there might be a hack
<Guest13> lol
<FromGitter> <Blacksmoke16> those are magic ones built directly into the compiler
<Guest13> shame
<FromGitter> <Blacksmoke16> why do you need them anyway?
<Guest13> this project involves library calls to functions in C land that start with double underscore
<Guest13> such as __lstat
<FromGitter> <Blacksmoke16> `fun lstat = "__lstat"() : Int32`
<Guest13> and they just dont work with my current structure, so unfortiently for me, time for a redesign
<FromGitter> <> They aren't really constants as the name implies, just like `as` and pseudo-methods
<FromGitter> <Blacksmoke16> you can give the bound C function a diff name in crystal land
<FromGitter> <Blacksmoke16> that doesnt use the `__`
<Guest13> right this conversation is making me think that is a good way to solve this
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <Blacksmoke16> yup makes sense
<Guest13> its a bit hacky but i can just transpose the underscores to the end
<FromGitter> <Blacksmoke16> im still not sold you need them at all
<FromGitter> <Blacksmoke16> but ok
<FromGitter> <Blacksmoke16> like are you wanting to do `LibSomething.__lstat`?
Guest13 has quit [Quit: Client closed]
<FromGitter> <> I don't mind too much that Crystal seems to be about 2x slower than CL at allocating as usually you try to pool objects at init time in my graphical applications and use the mutable API at runtime. It more than makes up for the loss in its mutation performance it seems.
<FromGitter> <> Anyway, I'm calling this 1.0.0 and going to start the next project to port over :)
<FromGitter> <Blacksmoke16> sure you want to start off with 1.0.0?
<FromGitter> <> I started off with 0.1.0. Now it's API is complete, and should there be any breaking changes, incrementing major is what counts, right?
<FromGitter> <Blacksmoke16> thats fair
<FromGitter> <> Why do you ask...what would you have done?
<FromGitter> <Blacksmoke16> idk, maybe just wait a bit to test things out more and such
<FromGitter> <Blacksmoke16> then you can change things w/o needing to bump a major
<FromGitter> <Blacksmoke16> if you come across things you dont like
<FromGitter> <> semver describes the public API. If I don't like that for whatever reason, and I don't see why I wouldn't as I've been using similar for many years, then I break the public API and release 2.0.0
<FromGitter> <> semver doesn't denote the quality or how i like the code
<FromGitter> <Blacksmoke16> yea thats a good point, its a port so a lot of that prob was already done
<FromGitter> <Blacksmoke16> whats next to port?
<FromGitter> <> maybe
<FromGitter> <Blacksmoke16> sounds like a plan
<FromGitter> <Blacksmoke16> why is it called "common lisp"? does that mean there is also "uncommon lisp" :P
<FromGitter> <> Lisp is a language designed in 1958 that spawned many different Lisps from the 60-70's. Common Lisp is an ANSI standard drafted in the 80's and published in 1994 that brought together the API's of the popular Lisps used at the time, because NASA and the US government wanted a standardized language.
<FromGitter> <Blacksmoke16> 👍 makes sense
<FromGitter> <> It's kind of amazing actually, in that Lisp code from the 60's still runs today on "Common Lisp" compilers. Try saying the same about C code when it is even that old. Anyway, off topic :)
<FromGitter> <Blacksmoke16> deff before my time ha
<FromGitter> <> Yeah that one is probably next to port. I am really into generative/procedural graphics algorithms/tools, and I see no work on this being done in Crystal yet, at first glance anyway.
<FromGitter> <> It seems Crystal is mostly used for webdev unfortunately, which makes sense I guess, given Ruby's killer app :)
<FromGitter> <Blacksmoke16> id say thats the most mature area yea
<FromGitter> <> I will now ask a dumb question
<FromGitter> <> Can anyone give me an obvious example of when you'd use the `Slice` type? I haven't ever used any unmanaged languages, so never had to use pointers directly...only safe language references.
<FromGitter> <> Their use to me is unclear outside of FFI in Crystal
<FromGitter> <Blacksmoke16> they can be helpful when working with IOs
<FromGitter> <Blacksmoke16> as the most common slice type is `Slice(UInt8)` aka `Bytes`
<FromGitter> <Blacksmoke16> ```bytes = 10 ⏎ bytes ⏎ bytes # => 10 bytes``` []
<FromGitter> <> Why would that be helpful over a specialized array buffer of u8's?
<FromGitter> <Blacksmoke16> where you get bounds checking versus working with a raw pointer
<FromGitter> <Blacksmoke16> performance, an array would be heap memory whereas a slice cannot be resized
<FromGitter> <> StaticArray then
<FromGitter> <Blacksmoke16> afaik i've only really seen static arrays be used to pass things to C
<FromGitter> <Blacksmoke16> so not too sure on that point
<FromGitter> <> Ok fair
<FromGitter> <Blacksmoke16> but a slice is just a safer alternative to a pointer
<FromGitter> <> I will need to be working efficiently with octet buffers in this library. Probably something to learn here :)
<FromGitter> <> Are float types tagged in Crystal?
<FromGitter> <Blacksmoke16> uhh havent heard that term before
<FromGitter> <> I mean are there any tagging bits in their representation
<FromGitter> <> In CL, a float64 must be boxed when the function isn't inlined, because they have a range of 62 bits + 2 bit tag to store type information for the compiler.
<FromGitter> <> Well 2 bits on one CL implementation anyway
<FromGitter> <Blacksmoke16> yea im not sure, would have to look at the code i guess
<FromGitter> <> I am not well versed enough to be able to tell. Maybe @HertzDevil could answer this question.
<FromGitter> <> It's just a major complaint of mine with CL. float64 return values at exit points (not across inlined function boundaries) are heap allocated
<FromGitter> <> Reading a bit about tagged pointers, it seems this is an artifact of dynamically typed languages, and probably doesn't apply to Crystal.
<FromGitter> <> By the way, crystalline has a severe memory leak.
<FromGitter> <> I might have to try Scry. Every couple days I am nearly out of RAM, with crystalline consuming 90% of it.
<FromGitter> <Blacksmoke16> 😬
<FromGitter> <elbywan> Regarding crystalline and memory usage, see:
<FromGitter> <elbywan> Tldr: The Crystal compiler code + boehm GC are causing the memory spikes, not crystalline itself.
<FromGitter> <> Thanks, however the memory grows slowly over time and is never reclaimed by the GC.
<FromGitter> <> I don't know if this is related as it's not a lot of ram at once, but small bits over time
<FromGitter> <elbywan> This is how bdwgc works
<yxhuvud> in any case, floats (and ints) in crystal is not tagged, if they are Float64, they have 64 bits. If you create a union type, the tagging will take extra space in addition to those 64 bits.
<FromGitter> <> Thanks
<FromGitter> <> and I just published my first code (library) with Crystal!
f1refly has quit [Read error: Connection reset by peer]
f1refly has joined #crystal-lang
<raz> hmm, is there a an equivalent to {% next %} in macros?
<raz> to skip an iteration inside a {% for .. in %}
<FromGitter> <naqvis> unfortunately no
<FromGitter> <naqvis> you will have to use `if else` trick
<raz> meh
<FromGitter> <naqvis> yeah, meh ++
HumanG33k has quit [Ping timeout: 255 seconds]
iskra has quit [Ping timeout: 250 seconds]
<FromGitter> <Blacksmoke16> you could do this with :)
<FromGitter> <Blacksmoke16> er, technically not but would be a bit closer as the `next` keyword would need implemented
HumanG33k has joined #crystal-lang
<FromGitter> <> I think it might be time to remove the link to in the docs, being that it has been down everytime I click from it in at least a few weeks :)
<FromGitter> <Blacksmoke16> make a PR :)
<FromGitter> <> Think I'm going to take a break from code for a while. Not looking forward to all the yak shaving required in Crystal for my next project. Be back at some point :)
<FromGitter> <Blacksmoke16> o/
<raz> `Log = ::Log.for(self)` i don't like this boilerplate line in all my classes.
<raz> but making it the default turns out trickier than i thought
* raz scratches head
<FromGitter> <> i'm confused by this... `def y(c, &b);, &b); end; y("ls"){|x| }` fails with `wrong number of block arguments (given 1, expected 0)`
<FromGitter> <> do i always need to specify the type there?
<FromGitter> <> manveru ( i think this is something about the fact that you're not specifying how many block args you're able to receive; maybe it doesn't understand passing an arbitrary number of args.
<FromGitter> <> works without types
<FromGitter> <> yep, i just found that a bit strange :)
<FromGitter> <Blacksmoke16> raz: if you want it to be the default, declare it at the first level of your namespace
<raz> but then `self` would always refer to that, no?
<FromGitter> <Blacksmoke16> you can give it a custom name
<raz> but i want every class to log under its own name
<FromGitter> <Blacksmoke16> then you'd have to do what you're doing
<FromGitter> <Blacksmoke16> do you really need that granular info tho?
<raz> yeh probably not. or rather... if i then override it it one class i wouldn't want subclasses to reverse that override again
<FromGitter> <Blacksmoke16> it should be enough for that to be some higher level thing, then could maybe have something that adds context for what thing is executing
<FromGitter> <Blacksmoke16> idk, depends on what exact context is
<raz> yea its a bit complicated, just trying to reduce boilerplate for my cow-orkers
<FromGitter> <Blacksmoke16> as afaik the only thing this thing does is allow you to filter on it. Like from class `a` i want to see all info and above, while class `b` is debug only
<raz> well, don't get me started on the filtering...
<raz> a fairly common thing i want to do is `Log.builder.bind "*", ::Log::Severity::Debug` to enable debug logging on everything. but then exclude things from it (like db.*, so i don't get every SQL statement twice from the ORM and the db driver).
<raz> doesn't seem to be possible either
<FromGitter> <Blacksmoke16> should be
<raz> don't think so. at least haven't found that magic sauce yet
<raz> #bind is additive
<FromGitter> <Blacksmoke16> maybe just do the inverse
<FromGitter> <Blacksmoke16> allow `myapp.*` only
<raz> but i want debug on everything, except the things i choose
<raz> i can't enumerate everything but then stuff gets forgotten
<raz> because*
<raz> and i don't even know the prefixes of everything :)
<raz> i guess i'll put a negative filter into my formatter
<FromGitter> <Blacksmoke16> sec
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <Blacksmoke16> bit more verbose, but a lot more control
<raz> oh... :none is the trick hmm
<raz> but i want :info there :D
<FromGitter> <Blacksmoke16> then make it info :P
<raz> hmmm... actually wait, that's exactly what i tried...
* raz rechecks his thing
<FromGitter> <Blacksmoke16> i will say that if you require something else that does it's own setup stuff it gets overwritten
<FromGitter> <Blacksmoke16> im pretty sure thats true
<raz> ok i'm an I***...
<raz> had two separate log backends there instead of binding to the same one twice
<FromGitter> <Blacksmoke16> f
<FromGitter> <Blacksmoke16> that would do it
<raz> right, thanks for the hand-holding....
* raz wanders off to bite a table
<FromGitter> <Blacksmoke16> haha np
<FromGitter> <> Is there really no native Crystal gzip/deflate decompressor?
<FromGitter> <Blacksmoke16> There is
<FromGitter> <Blacksmoke16> It's under the Compress namespace
<FromGitter> <> The stdlib just links to libz
<FromGitter> <> It's not very native :)
<FromGitter> <Blacksmoke16> Ah, I was thinking you meant not as a shard
ur5us has joined #crystal-lang
<FromGitter> <> How do I execute something only when the file is the main entrypoint, not when it's included as a library (eg in a test or repl scenario?)
avane has quit [Ping timeout: 258 seconds]
<FromGitter> <> ryanprior ( there are only hacks that i know. ⏎ ⏎ ⏎ depends if demo/run was required before subclasses got defined or after ⏎ ... []