<FromGitter>
<pyrareae_gitlab> @kingsleyh what is the wallet desktop gui built with?
<FromGitter>
<pyrareae_gitlab> Crystal, or something else? Looks like it's an html ui
<FromGitter>
<Daniel-Worrall> stephie: in regards to dcr, meew said that was how he'd like to solve things. We have the same PR in discordrb, I was just told to make the other PR so meew could merge them together.
<FromGitter>
<Daniel-Worrall> You guys have really been merging a lot lately
<FromGitter>
<Daniel-Worrall> Or maybe I'm just paying more attention. It seems like straight-shoota has been putting in a lot of work
deavmi has quit [Ping timeout: 246 seconds]
deavmi has joined #crystal-lang
hightower2 has joined #crystal-lang
<straight-shoota>
yeah, I've been trying to reduce the backlog of pending PRs
<FromGitter>
<sanks64> Hey, guys, is there any particular reason why `Array#truncate` (a method which would remove last `n` elements from an array without modifying the original array or creating a new) does not exist? Should I send a PR to add it?
<FromGitter>
<sanks64> The closest I see is `Array#pop(n : Int32)`
<FromGitter>
<sanks64> There's also `Array#shift(n : Int)` which does the same for `n` first elements in an array
<FromGitter>
<Blacksmoke16> pretty sure both of those allocate new arrays for the data being removed tho, so not exactly the same
<FromGitter>
<asterite> @sanks64 you can do `array[..-n]`
<FromGitter>
<asterite> or `array[0..-n]` which is a bit more explicit (also try with `...` instead of `..`, not sure)
deavmi has quit [Ping timeout: 240 seconds]
<FromGitter>
<asterite> yeah, it needs to be `array[0...-n]`
<FromGitter>
<erdnaxeli:cervoi.se> you want ... to exclude n itmes
<FromGitter>
<Blacksmoke16> thats not exactly what he wants, more like
<FromGitter>
<Blacksmoke16> i could also see it being an overload of `#clear`
<FromGitter>
<sanks64> `array[0...-n]` works, but it will create a new array and it should be a bit more memory heavier than just modifying the original array
deavmi has joined #crystal-lang
<straight-shoota>
Didn't you say `Array#truncate` would not modify the original? Then it must create a new one, too
<FromGitter>
<sanks64> My bad... I meant by modifying
<straight-shoota>
gotcha
<FromGitter>
<christopherzimmerman> Do you care if the memory is freed right away or not?
<straight-shoota>
yeah, I guess a mutating alternative to `[...-n]` would be good
<FromGitter>
<sanks64> I assume it should just change the size and the dropped part will be collected by the GC?
<straight-shoota>
`arr.delete_at(-n..)` should be the mutating equivalent
hightower2 has quit [Read error: Connection reset by peer]
<straight-shoota>
memory management is an implementation detail and not relevant for the public API
<FromGitter>
<Blacksmoke16> downside is it also allocates a new array for the deleted items
<FromGitter>
<Blacksmoke16> but its deff the closest
<straight-shoota>
right
<FromGitter>
<HertzDevil> is there a variant of `#concat` that prepends and mutates an array
<FromGitter>
<HertzDevil> other than `a[0...0] = b`
<FromGitter>
<christopherzimmerman> Hmm... Is there a reason `[]` performs a full copy on the part of an array being returned?
<FromGitter>
<christopherzimmerman> I would usually expect slicing an array then modifying the slice to also modify the original
<FromGitter>
<HertzDevil> all slices are invalidated when an array reallocates itself
<FromGitter>
<sanks64> > is there a variant of `#concat` that prepends and mutates an array ⏎ `Array#unshift` probably?
<straight-shoota>
@HertzDevil, I don't think so.
<FromGitter>
<HertzDevil> `#unshift` is for a single element
<straight-shoota>
You can do `unshift(*values)` with a tuple, but that's it
<straight-shoota>
@christophzimmermann, that would be really unexpected behaviour in many situations
<FromGitter>
<HertzDevil> hmm
<straight-shoota>
if you want a reference to a subset of an array, you can use `to_unsafe`, but that's unsafe
<FromGitter>
<HertzDevil> ruby doesn't have it either
<FromGitter>
<HertzDevil> their `#prepend` is an alias for `#unshift`
<FromGitter>
<HertzDevil> difference is, you can splat arrays in ruby
<FromGitter>
<HertzDevil> for truncation there's also `a[-n..] = [] of ???`
<FromGitter>
<HertzDevil> it still needs to allocate an empty array, but that array won't have an internal buffer
<FromGitter>
<asterite> @sanks64 then `n.times { array.pop }`
<FromGitter>
<sanks64> Should be still slower than just changing the size
<FromGitter>
<HertzDevil> changing the size alone is never enough
<straight-shoota>
That's not as efficient as a dedicated method which could use @buffer.clear
<FromGitter>
<HertzDevil> the array must zero out the unused elements since otherwise the gc would think these elements are still reachable
<FromGitter>
<asterite> So, we copied `array.pop(n)` from Ruby to return an array, but it could return `nil`, I don't know... I personally never needed the returned array
<FromGitter>
<sanks64> Yeah I assume you already have the returned array if you passed it as an argument
<straight-shoota>
I guess that's similar with #delete_at
<straight-shoota>
but #pop(Int) returning an array really makes sense because #pop() returns an item
<straight-shoota>
a method that only removes and does not return any value should not be named pop
<FromGitter>
<HertzDevil> "shrink"
<straight-shoota>
"truncate" is probably already a good name
<FromGitter>
<HertzDevil> and also make it able to discard elements at the beginning
<FromGitter>
<sanks64> z64 made this implementation. He said he doesn't cares about crediting and anyone is free to PR it. Is it good enough? ⏎ ⏎ ```[1, 2, 3] ⏎ [] ⏎ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]``` [https://gitter.im/crystal-lang/crystal?at=60005be399549911fc2051af]
<straight-shoota>
or just add an overload to `clear`
<FromGitter>
<Blacksmoke16> ^
<FromGitter>
<asterite> @sanks64 what's `n` in your specific use case?
<straight-shoota>
I suppose a bit of a problem might be directionality
<straight-shoota>
you should be able to remove items from back and front of the array
<FromGitter>
<sanks64> @asterite I'm not sure I follow the question
<FromGitter>
<Blacksmoke16> `+n` removes from beginning, `-n` removes from end?
<straight-shoota>
could use positive and negative count for that like with index accessors. But would you expect arr.truncate(-n) to truncate front or back?
<FromGitter>
<asterite> @sanks64 what's the value of `n` in the place where you need it? Is it 2, is it 10, or it depends?
<FromGitter>
<sanks64> It depends
<straight-shoota>
I guess with `clear` the direction is more logical...? `arr.clear(-n)` for the end
<FromGitter>
<sanks64> I'd expect `Array#truncate` to truncate from back
<FromGitter>
<asterite> I guess... what's the full use case? Because `n.times { array.pop }` isn't that much slower than a more efficient solution
<straight-shoota>
^ that probably depends on the size of the array and the amount of truncation :D
hightower2 has joined #crystal-lang
<FromGitter>
<asterite> Without benchmarks and concrete values there's not much value to this discussion
<FromGitter>
<sanks64> I will make a benchmark, but it seems like a logical thing to have even without benchmarks
<FromGitter>
<asterite> I'm not sure. Ruby doesn't have it
Volk has joined #crystal-lang
<FromGitter>
<z64> i only wrote this out of my expectation of a simple way to do this (in implementation) that doesn't allocate, nothing else ⏎ i don't need the result of the removal, i obtained an array from an api and all i wanted to do was cap the length ⏎ https://doc.rust-lang.org/stable/src/alloc/vec.rs.html#740-757
<FromGitter>
<HertzDevil> ruby however has `#slice!` which is more general
<FromGitter>
<HertzDevil> nvm
<FromGitter>
<HertzDevil> yeah that's just our range overload for `#delete_at`
<FromGitter>
<z64> it doesn't need all that business just for trimming the array
<FromGitter>
<asterite> It seems that `truncate` in Rust truncates the vector to be of size at most n... this is different from removing the last n elements
<FromGitter>
<asterite> (and I would have expected that too)
<Andriamanitra>
yeah, i would also expect the behaviour rust has
<FromGitter>
<asterite> i wouldn't mind adding `truncate` to Array with Rust's behavior
<FromGitter>
<z64> sure. i don't have any strong feelings about the name, i'd just like the simplicity of the feature
<FromGitter>
<HertzDevil> in that case can negative size arguments mean truncating from the beginning
<Andriamanitra>
you mean from the end?
<FromGitter>
<sanks64> It would make sense, but then we don't need `#shift`?
<FromGitter>
<asterite> Okay, `truncate` is faster, but... how often do you need to call that method in that app?
<FromGitter>
<Blacksmoke16> `clear` would make more sense imo. Given you're saying you want to remove a specific amount of elements, `#truncate(size)` would imply you want to cap the size of the array to the provided value
<FromGitter>
<asterite> Because if I only benchmark `truncate(50)` vs `50.times { pop }` I get these times: 00:00:00.000000076 vs 00:00:00.000000130
<FromGitter>
<asterite> and that can't possibly be the bottleneck of the application
<FromGitter>
<z64> > #truncate(size) would imply you want to cap the size of the array to the provided value ⏎ that *is* what i want to do
<FromGitter>
<z64> .... nice gitter
<FromGitter>
<sanks64> You need an empty line
<FromGitter>
<z64> @asterite this has nothing to do with a performance problem. i just don't think that what i want to do should involve this much code underneath, when it has no need to
<FromGitter>
<sanks64> And I believe this method would be much simpler than the ton of methods we have now
<FromGitter>
<erdnaxeli:cervoi.se> from a user point of view, #truncate(n) is not much easier than #truncate(n)
<FromGitter>
<erdnaxeli:cervoi.se> if it is not for the perf, I don't see the point
<FromGitter>
<z64> Andriamanitra, that allocates a new array for the popped elements. i don't need that
<Andriamanitra>
z64: yes, but if performance is not your concern..
<FromGitter>
<erdnaxeli:cervoi.se> so you want perf
<FromGitter>
<sanks64> > from a user point of view, #truncate(n) is not much easier than #pop(n) ⏎ ⏎ It would be easier if we will make this method universal
<FromGitter>
<sanks64> You can provide an negative value and it will work both ways
<FromGitter>
<asterite> As I said, I wouldn't mind adding a `truncate` method
<FromGitter>
<asterite> :-)
<Andriamanitra>
+1 for #truncate (the way rust does it), i think #pop is good enough for easily removing n elements and #truncate could be substituted in the unlikely scenario #pop becomes a performance issue
<FromGitter>
<erdnaxeli:cervoi.se> #pop and #shift are kind of universal, several langages have them
<FromGitter>
<erdnaxeli:cervoi.se> but that's the first time I heard about #truncate
<FromGitter>
<sanks64> Fair then. I'll make a PR with how Rust does it?
<FromGitter>
<HertzDevil> that's because in other languages it's called "resize" 😂
<FromGitter>
<HertzDevil> unfortunately that wouldn't work in crystal because a mutating resize can never enlarge an array
<Andriamanitra>
i guess the difference is that resize could also make the array larger?
<FromGitter>
<sanks64> `downsize` /s
<FromGitter>
<HertzDevil> maybe you can if you always provide the default value
<FromGitter>
<asterite> Instead of a PR I would open an issue as RFC to gather some feedback from others
<FromGitter>
<sanks64> Will make an issue when I'm free
HumanG33k has quit [Read error: Connection reset by peer]
HumanG33k has joined #crystal-lang
hightower2 has quit [Ping timeout: 256 seconds]
hightower2 has joined #crystal-lang
HumanG33k has quit [Ping timeout: 265 seconds]
<FromGitter>
<naqvis> what amazes me is when people start to treat GC enabled languages as ones with working on resource constrained environments and start discussing the resource optimization. Might be just me who have such feelings :P
HumanG33k has joined #crystal-lang
<FromGitter>
<RespiteSage> Yeah, that seems like the wrong tool for the job.
<hightower2>
Folks, re. documentation, what do you potentially think of making the "Summary" section not contain the first line of method description, but to basically just contain methods listed one after another, separated by commas as usual. Then clicking them leads to their full description.
<hightower2>
Asking because countless times I've mistaken the summary as the complete documentation, not realizing that there was more below.
<FromGitter>
<Blacksmoke16> could always migrate to the mkdocs implementation 😉
<hightower2>
Also this approach where basically everything is listed in verbose format twice is strange...
<raz>
yeh, it's basically a poor man's toc
<raz>
(don't have problems with it, but remember i was also irritated the first time i saw it)
<FromGitter>
<asterite> Java does it that way (I copied it from there)
<FromGitter>
<HertzDevil> doxygen does this too
<raz>
well, it adds a lot of scrolly scrolly
<raz>
but in practice i haven't found that to be a big issue for me personally
<FromGitter>
<HertzDevil> if i'm in a hurry sometimes i just ctrl+shift+f in the entire crystal repo in vscode lmao
<raz>
sometimes? that is pretty much my default for anything :D
<hightower2>
I think we'd be pleasantly suprised if we tried to just methods separated with commas. It would almost allow to see summary of all methods on the first screen, without scrolling anything.
<hightower2>
versus the current approach where nothing is ever seen anywhere without scrolling :)
HumanG33k has quit [Read error: Connection reset by peer]
deavmi has quit [Quit: Eish! Load shedding.]
<raz>
yup, or a alphabetically sorted table with smallish font-size to save on height
<hightower2>
Also, even if we keep this current approach, why waste 4 lines (title, space, 1 line description, space) for each method when the format can be "<Name>: <oneline description>"
<FromGitter>
<HertzDevil> yard does this too
HumanG33k has joined #crystal-lang
<FromGitter>
<HertzDevil> crystal doc is closer to yard than ruby core's doc
<raz>
gladly. ruby-core doc is pretty awful
deavmi has joined #crystal-lang
<raz>
jumps between 4 different layouts all the time, i never even try to find anything there, just go straight to google
<FromGitter>
<HertzDevil> well, they have `ri` and our core doesn't come with anything like that
<FromGitter>
<HertzDevil> but then again, `ri` is good only when you know exactly which method you're looking for
deavmi has quit [Read error: Connection reset by peer]
<raz>
the only reason rubyists even know about ri is because they have to google to find out how to disable it
<raz>
to make their gem installs not take an eternity every time
<hightower2>
so true :)
<FromGitter>
<HertzDevil> not me, but i did that to the *other* doc generators gem triggers
<FromGitter>
<HertzDevil> mainly darkfish
<raz>
i just placed --no-document a decade ago, and facepalm every time i land on machine that doesn't have it yet
<raz>
it's a nice idea to have cli docs. but not at the cost of making gem unusable by default
<raz>
(ri should just generate the docs when it's first called - by one of the two people on the planet who actually use ri)
deavmi has joined #crystal-lang
hightower2 has quit [Ping timeout: 264 seconds]
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
deavmi has quit [Quit: Eish! Load shedding.]
deavmi has joined #crystal-lang
deavmi has quit [Client Quit]
deavmi has joined #crystal-lang
<Andriamanitra>
hightower2: i much prefer having all the methods visible (eg. on the side like this https://i.imgur.com/NegTXr6.png ) even after scrolling, so for me that list in the summary would just be needless clutter
deavmi has quit [Ping timeout: 272 seconds]
<oprypin>
Andriamanitra, thats exactly what mkdocstrings-crystal does
deavmi has joined #crystal-lang
deavmi has quit [Ping timeout: 246 seconds]
deavmi has joined #crystal-lang
deavmi has quit [Read error: Connection reset by peer]
duane has quit [Ping timeout: 260 seconds]
deavmi has joined #crystal-lang
duane has joined #crystal-lang
_ht has quit [Read error: Connection reset by peer]
_ht has joined #crystal-lang
hightower2 has joined #crystal-lang
DTZUZU has quit [Read error: Connection reset by peer]
<FromGitter>
<Daniel-Worrall> Do we have any plans to extend the recent `use_json_discriminator` to use a block for custom logic about what fields to check for and what values mean what type to form it into?
<FromGitter>
<Daniel-Worrall> I have 2 very similar json schemas where 1 type has a lot of nils, and the other doesn't, and it'd be great to not have to go through a lot of nil checks
<FromGitter>
<Daniel-Worrall> I may just have to do my own macro or custom json mapping code
<FromGitter>
<watzon> It would probably be a great PR if you could find something that works better. I know Ary threw that PR together in a matter of hours.
MasterdonX has quit [Ping timeout: 256 seconds]
<FromGitter>
<Daniel-Worrall> Idk how much control in the parsing there is. Maybe if I put the common types on the abstract class, then have parsing rules only based on those since they're the only common ones and there's no need to look into JSON::Any, though maybe some would prefer the JSON::Any. I guess both could be possible in the same method
<FromGitter>
<Daniel-Worrall> maybe it would yield a named tuple of args from the abstract class and any parameters passed to method as Any