<FromGitter>
<Blacksmoke16> there are still mutable, but are some gotcha, like you ran into here and what's described in the book
<FromGitter>
<mattrberry> Yeah I've seen that before in the book which is why I ended up using classes in the library I wrote last year, but after seeing the Nim behavior recently, I was wondering again *why* crystal behaves this way
<FromGitter>
<Blacksmoke16> just how structs/value types work afaik :shrug:
<FromGitter>
<Blacksmoke16> they're intended to be small, immutable things, or stateless wrappers around other reference types
<FromGitter>
<Blacksmoke16> idt thats the same thing `a[1] += 1` is the same as `a[1] = a[1] + 1` so you're just reassigning that index, not mutating it
<FromGitter>
<Blacksmoke16> which works fine because array is a reference type
<FromGitter>
<mattrberry> So my only way of accomplishing something like this would be to overload some operator on Foo, then use it as an assignment operator I guess..
<FromGitter>
<Blacksmoke16> or just use a class
<FromGitter>
<Blacksmoke16> mutable structs are kinda a smell
<FromGitter>
<mattrberry> I'm currently using classes, but I have a decent feeling this will realistically improve performance by a good margin in my *very* specific case :p
<FromGitter>
<Blacksmoke16> oh boy, guess we'll find out ha
<FromGitter>
<Blacksmoke16> maybe go for a classic immutable design in that like `.value = 1` actually does like `self.class.new value`
<FromGitter>
<Blacksmoke16> and returns a new instance of the struct?
<FromGitter>
<mattrberry> I guess this likely doesn't buy me anything though
<FromGitter>
<Blacksmoke16> dont think so
<FromGitter>
<Blacksmoke16> returning `self` still returns a copy
<FromGitter>
<mattrberry> Yup
<FromGitter>
<mattrberry> In my very specific usecase where I figured using structs might help, I effectively have an array of objects that I need to access and mutate millions of times per second. Currently, each assignment means ⏎ ⏎ 1) Fetch reference at index ⏎ 2) Follow reference to object ⏎ 3) Mutate ... [https://gitter.im/crystal-lang/crystal?at=623fb358e9cb3c52ae35b4d7]
<FromGitter>
<mattrberry> And I figured that over millions of times per second, this would make a decent difference in the runtime performance of my application
<FromGitter>
<Blacksmoke16> do a small benchmark?
<FromGitter>
<Blacksmoke16> class versus return new instance?
<FromGitter>
<Blacksmoke16> So guess it's a non issue?
ur5us has quit [Ping timeout: 240 seconds]
<FromGitter>
<mattrberry> Hmm maybe? I'm comparing to nim right now, where running this ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ in debug yields roughly equal times, while in release the structs proc runs *way* faster. I have to imagine it's being optimized out entirely, though.. I will check the generated code later [https://gitter.im/crystal-lang/crystal?at=623fcde0161ffc40d7d4ba6f]
<FromGitter>
<mattrberry> Assuming it's optimizing out the loop completely, I'll need to look into how to make it not do that before I can accurately compare
<FromGitter>
<mattrberry> I wonder if internally Nim turns the `structs[0].value = 1` into a `structs[0] = structs[0].value = 1`..
<FromGitter>
<mattrberry> Although I know I can do `var struct {.byAddr.} = structs[0]` and store a variable containing the mutable struct in the array
renich has quit [Quit: Leaving]
ur5us has joined #crystal-lang
jmdaemon has quit [Ping timeout: 240 seconds]
ur5us has quit [Ping timeout: 240 seconds]
jmdaemon has joined #crystal-lang
wolfshappen has quit [Read error: Connection reset by peer]
ur5us has joined #crystal-lang
wolfshappen has joined #crystal-lang
sagax has quit [Quit: Konversation terminated!]
<FromGitter>
<moe:busyloop.net> @Blacksmoke16: sorry to be the bearer of bad news, but the athena `accept`-header parser is broken :P
<FromGitter>
<moe:busyloop.net> that header can contain quoted strings... so #split doesn't do the right thing
<FromGitter>
<Blacksmoke16> Oh?
<FromGitter>
<Blacksmoke16> Got an example by chance?
<FromGitter>
<moe:busyloop.net> note the "quoted-string" in there (see what i did there? :p)
<FromGitter>
<Blacksmoke16> hmm
<FromGitter>
<Blacksmoke16> okay so yea i suppose it is then
<FromGitter>
<Blacksmoke16> because it would be a `quoted-pair` which allows any `VCHAR` which is any ASII character i guess
<FromGitter>
<moe:busyloop.net> yup, which makes that header amazingly expensive to parse
<FromGitter>
<moe:busyloop.net> as if the silly semicolon stuff wasn't bad enough already. i guess just mandating the client to put the tokens in order of preference would've been too easy.
<FromGitter>
<Blacksmoke16> wait
<FromGitter>
<Blacksmoke16> i just tried it and it worked fine?
<FromGitter>
<moe:busyloop.net> with a ; in quotes?
<FromGitter>
<moe:busyloop.net> i haven't tried, but from a glance thought that would bork your parser
<FromGitter>
<moe:busyloop.net> yeh, put a ; in the quotes, and another mime type after
<FromGitter>
<Blacksmoke16> `application/json;key=\"A,B,C;D\",text/html` it kinda worked, but the `D` param got cut off from the params yea
<FromGitter>
<moe:busyloop.net> yea, i don't think this matters in practice anyway. just wanted to share the joy after i bumped into it while dabbling on my own framework ;)
<FromGitter>
<moe:busyloop.net> i doubt browsers would send headers like that. and if someone wrote a client that does... PEBCAK
<FromGitter>
<Blacksmoke16> hehe, prob wait until theres a real use case to look into it :P
<FromGitter>
<Blacksmoke16> > my own framework ⏎ ⏎ Oh?
<FromGitter>
<moe:busyloop.net> no competition, no worries
<FromGitter>
<Blacksmoke16> using some athena components? ;)
<FromGitter>
<moe:busyloop.net> my whole framework prob has less lines than one of your components :P (400'ish so far)
<FromGitter>
<moe:busyloop.net> but yea, wanted to lift the accept-header logic from there after discovering what a headache it is.
<FromGitter>
<Blacksmoke16> feel free :P tis what they're there for
<FromGitter>
<Blacksmoke16> router might also be helpful
<FromGitter>
<moe:busyloop.net> nah, i got radix 💪
<FromGitter>
<Blacksmoke16> athenas is faster ;)
<FromGitter>
<moe:busyloop.net> faster than radix?
<FromGitter>
<Blacksmoke16> (optimizations are in Crystal 1.4.0 tho)
<FromGitter>
<moe:busyloop.net> hum, maybe i'll take a look. but it'll probably drag behind that whole DI-baggage, right?
<FromGitter>
<Blacksmoke16> nope, remember each component is designed to be able to be used independently outside of the framework
<FromGitter>
<jrei:matrix.org> moe (https://matrix.to/#/@moe:busyloop.net): what's your framework?
<FromGitter>
<moe:busyloop.net> not released yet. tho i feel like it might be worth a shard at some point later.
<FromGitter>
<moe:busyloop.net> @Blacksmoke16: hmmm yea i'll give it a look. although these numbers look a bit suspicious to me. :D
<FromGitter>
<jrei:matrix.org> What will be its features?
<FromGitter>
<Blacksmoke16> @moe:busyloop.net feel free to run your own benchmarks :) They're legit. PCRE2 JIT regexes are just 🚀 for this kind of usage
<FromGitter>
<jrei:matrix.org> I made one in the past which was compile time safe and generates docs, but few people were interested so 🤷