ChanServ changed the topic of #crystal-lang to: The Crystal programming language | https://crystal-lang.org | Fund Crystal's development: https://crystal-lang.org/sponsors | GH: https://github.com/crystal-lang/crystal | Docs: https://crystal-lang.org/docs | Gitter: https://gitter.im/crystal-lang/crystal
<FromGitter> <Blacksmoke16> yea idt you can do that
<FromGitter> <manveru:matrix.org> i'm not sure how that'd work as a method
<FromGitter> <Blacksmoke16> wont be able to iterate the ivars within a method, and you of cant create a method while you're in a method
<FromGitter> <Blacksmoke16> just manually create the constructor
<FromGitter> <Blacksmoke16> or use a macro to generate it if you really want
<FromGitter> <manveru:matrix.org> yeah... a macro doesn't really give much in this case then :)
<FromGitter> <Blacksmoke16> you could do like `def_constructor nomad_base_url : URI, ...`
<FromGitter> <manveru:matrix.org> sure, but `def initialize(@nomad_base_url : URI)` is pretty much the same and less confusing
<FromGitter> <Blacksmoke16> exactly :)
<FromGitter> <Blacksmoke16> this is a case of macro over complicating something that is simple
<FromGitter> <manveru:matrix.org> i'm mostly exploring macros at this point, so was just wondering how recursive it can get :)
<FromGitter> <Blacksmoke16> I *think* there's away you can get this to work, but it's not recommended, give me a sec
<FromGitter> <manveru:matrix.org> i could generate Nomad::Config when creating Common::Config though, that should cause less problems i think
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60f370e2ec10653d5a479cb8]
<FromGitter> <manveru:matrix.org> just trying to reduce the number of places to change when i change options, while giving sub-commands only the minimum set of options they need for easier testing and invocation, while avoiding accidental dependencies
<FromGitter> <manveru:matrix.org> oh, that is kinda cool :)
<FromGitter> <manveru:matrix.org> didn't know _ => _ was a thing
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <Blacksmoke16> i will say, yes it *works* but im not a fan at all of this mutable concept approach
<FromGitter> <Blacksmoke16> imo it still over complicates the process of just defining a constructor manually
<FromGitter> <manveru:matrix.org> yeah
<FromGitter> <manveru:matrix.org> i'll try one other idea i just had though
<FromGitter> <Blacksmoke16> Mmk
<FromGitter> <manveru:matrix.org> i think it'd be beneficial to encode the hierarchy in a single pass instead of throwing it all over the code
<FromGitter> <manveru:matrix.org> not sure if i'll like the result, but gotta try it anyway :)
<FromGitter> <Blacksmoke16> Fwiw, constructors are inherited
<FromGitter> <manveru:matrix.org> yeah
<FromGitter> <Blacksmoke16> 👌
<FromGitter> <manveru:matrix.org> atm i have for example a server that needs options [a,b,c], and it calls sub-components that require options [b] or [a,c], or [c,d] etc...
<FromGitter> <manveru:matrix.org> each sub-component can be called without the server, in which case you would only need to pass their specific options
<FromGitter> <manveru:matrix.org> so inheritance is a bit weird there...
<FromGitter> <Blacksmoke16> Are these like config values, or like unique types
<FromGitter> <manveru:matrix.org> mostly configs
<FromGitter> <manveru:matrix.org> should be immutable after initial parsing
<FromGitter> <Blacksmoke16> Have you considered passing in a single config obj versus specific values?
<FromGitter> <manveru:matrix.org> yeah
<FromGitter> <manveru:matrix.org> but that means i'd need to make the value types either optional, or use totally wrong default values...
<FromGitter> <Blacksmoke16> How so?
<FromGitter> <manveru:matrix.org> or the user has to pass 50 options even if that command would only need 2 or so
<FromGitter> <Blacksmoke16> How are the values provided?
<FromGitter> <manveru:matrix.org> either config file, cli flags, url params, default values, or env vars
<FromGitter> <Blacksmoke16> Gotcha
<FromGitter> <manveru:matrix.org> here's an older version of the actual code: https://github.com/input-output-hk/bitte-ci/blob/main/src/bitte_ci/config.cr
<FromGitter> <manveru:matrix.org> so that pass-the-full config approach is what i had before, and it sucked :)
<FromGitter> <manveru:matrix.org> when you wanna run db migrations, all you need is the db url, for example
<FromGitter> <manveru:matrix.org> but it will fail for not finding a github token...
<FromGitter> <Blacksmoke16> You could use lazy getters maybe
<FromGitter> <manveru:matrix.org> at that point it may fail at runtime, which also sucks
<FromGitter> <Blacksmoke16> Only would try to load when called, but would raise if not available
<FromGitter> <Blacksmoke16> Or really, maybe even getter! Would be sufficient here
<FromGitter> <manveru:matrix.org> anw, i gotta get some sleep, thanks for the feedback :)
<FromGitter> <Blacksmoke16> o/
ua_ has quit [Ping timeout: 265 seconds]
ua_ has joined #crystal-lang
ua_ has quit [Ping timeout: 268 seconds]
lucf117 has quit [Quit: Leaving]
ua_ has joined #crystal-lang
<FromGitter> <postmodern:matrix.org> @didactic-drunk: should we add Process.fork to crystal-posix? @kevinsjoberg was asking about lack of `Process.fork`. https://gist.github.com/postmodern/a98e68dff96163b5f234cd9de1c5c75d
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 268 seconds]
f1reflyylmao is now known as f1refly
<FromGitter> <mjfiano:matrix.org> I'm trying to solve a visibility issue. ⏎ I have private class method `self.foo` at the module level in one file, and in another file I have a struct defined in the same module. I would like some of the instance methods of the struct to be able to use the private foo method at the module level, but I cannot fully qualify it, and it is not part of the struct so I'm not sure if this is possible. I'm
<FromGitter> ... trying to write a file of private helper methods that are used in several other files/structs
<FromGitter> <mjfiano:matrix.org> Cancel that. I seemed to have figured out the right incantation to extend the module with private methods according to `crystal doc`.
<kevinsjoberg> @postmodern, great idea!
miihael has joined #crystal-lang
miihael has quit [Quit: Client closed]
<FromGitter> <Blacksmoke16> @mjfiano:matrix.org could you just make it protected
<FromGitter> <postmodern:matrix.org> @didactic-drunk @kevinsjoberg hmm nevermind, looks like `Process.fork` does exist but isn't documented / part of the private API. https://github.com/crystal-lang/crystal/blob/1.1.0/src/process.cr#L62
<FromGitter> <mjfiano:matrix.org> @Blacksmoke16: Maybe, though I'm not sure what that means for module methods...the docs talk about instances. I found a way with private though.
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/bktx
<FromGitter> <mjfiano:matrix.org> @Blacksmoke16: Interesting. I did something like this: https://play.crystal-lang.org/#/r/bkuh
<FromGitter> <mjfiano:matrix.org> Mine probably doesn't do exactly what I expect. ⏎ ⏎ Also, stupid question: I've never seen the double colon syntax for module name as in your example...where is this documented?
<FromGitter> <Blacksmoke16> It's equivalent to creating two modules and nesting them
<FromGitter> <mjfiano:matrix.org> Is there a convention when naming methods that side-effect their instance? Some languages use a `!` suffix.
<FromGitter> <naqvis> yes, Crystal follows same conventions. methods ending with bang represents inline mutation. stdlib have few of them
<FromGitter> <mjfiano:matrix.org> Thank you
<FromGitter> <naqvis> similarly methods returning bool are usually end with `?`
<FromGitter> <Blacksmoke16> ! Can also represent methods that raise, while ? Returns nil
<FromGitter> <Blacksmoke16> But I see more of like .foo and.foo? Versus .foo! And.foo?
<FromGitter> <mjfiano:matrix.org> FYI: This convention is very old, derived from Scheme (a Lisp)
<FromGitter> <mjfiano:matrix.org> I think I decided on classes over structs. pass-by-value is sort of convoluting my API already.
<FromGitter> <mjfiano:matrix.org> re: yesterday's discussion
<FromGitter> <Blacksmoke16> 👍 usually the suggested approach is just use classes to start
<FromGitter> <Blacksmoke16> then can fix bottlenecks as needed, OR if the obj is for immutable and small
<FromGitter> <mjfiano:matrix.org> Yeah I chose structs first because this is ultimately going to be for high performance math routines used in math visualization animations
<FromGitter> <mjfiano:matrix.org> But that was a mistake...for now
<FromGitter> <Blacksmoke16> are you created a lot of objects in a loop or something?
<FromGitter> <Blacksmoke16> that would prob be noticable diff
<FromGitter> <mjfiano:matrix.org> The math routines will typically have 2 different methods for each...one that allocates, and one that mutates...so, using classes should be fine, and I can always mutate a pre-allocated object before the loop
<FromGitter> <mjfiano:matrix.org> I mean I can always mutate inside the loop, a pre-existing object
<FromGitter> <mjfiano:matrix.org> My Lisp code I'd like to replace is over-optimized. I create temporary objects at init time and never allocate at runtime...heh
<FromGitter> <Blacksmoke16> 👍 sounds like a plan
<FromGitter> <mjfiano:matrix.org> One thing that I still haven't gotten used to is blocks. It's very strange how methods are not first-class functions, coming from Lisp and a bit of Rust.
<FromGitter> <Blacksmoke16> Hm?
<FromGitter> <mjfiano:matrix.org> top-level variables being inaccessible in methods, intentionally restricting closures in favor of a separate construct (blocks).
<FromGitter> <mjfiano:matrix.org> I'm just not sure why that is the case compared to first-class functions. Maybe I don't fully understand blocks
<FromGitter> <Blacksmoke16> Have you read about procs?
<FromGitter> <mjfiano:matrix.org> Yeah, and I don't know how that differs from a lambda/anonymous function in other languages.
<FromGitter> <Blacksmoke16> It's the same concept
<FromGitter> <Blacksmoke16> A method with a block is similar to a method that accepts an anonymous callback function
<FromGitter> <mjfiano:matrix.org> Yeah...it's just confusing me because lambda calculus is so simple and doesn't require any of that to do the same things.
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <mjfiano:matrix.org> ```code paste, see link``` ⏎ ⏎ Interestingly, this can be called as a fully-qualified method: `Origin.=~(a, b, rel_tol: c, abs_tol: d)`, or a binary operator without qualification if the defaults are sufficient: `a =~ b`. I'm not sure why the former requires qualification. [https://gitter.im/crystal-lang/crystal?at=60f469ef67b72e1bfe1b3e4a]
<FromGitter> <mjfiano:matrix.org> I think mayhbe my code is wrong and it is calling the wrong overload
<FromGitter> <mjfiano:matrix.org> No it is calling the same method in both cases.
<FromGitter> <mjfiano:matrix.org> I think everything is fine actually. If anyone has any suggestions for improvements on this snippet, I'd appreciate it: https://play.crystal-lang.org/#/r/bky9
lucf117 has joined #crystal-lang
<FromGitter> <Blacksmoke16> you can just do `property x : Float64, y : Float64`
<FromGitter> <Blacksmoke16> save you 2 lines :p
<FromGitter> <mjfiano:matrix.org> Oh thanks
<FromGitter> <mjfiano:matrix.org> I just found what I think is a very minor compiler bug
<FromGitter> <Blacksmoke16> oh?
<FromGitter> <mjfiano:matrix.org> I tried to see if I could overload `==` instead of `=~`, and the error message says I'm trying to define a setter with more than 1 parameter. I know why this is the case, but maybe a special-cased error for arity-overloading == should exist
<FromGitter> <Blacksmoke16> pretty sure thats moreso an accepted limitation
<FromGitter> <Blacksmoke16> related https://github.com/crystal-lang/crystal/issues/10397
<FromGitter> <mjfiano:matrix.org> Odd
<FromGitter> <mjfiano:matrix.org> I would expect <, > to be symmetrical with <=, <=.
<FromGitter> <mjfiano:matrix.org> err <=, >=
<FromGitter> <Blacksmoke16> right, hence the bug :p
<FromGitter> <Blacksmoke16> which would be more likely to make the others only 1 arg as well
<FromGitter> <mjfiano:matrix.org> Has a stropping feature been shut down yet, like Nim?
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <mjfiano:matrix.org> Stropping lets the user re-use reserved keywords in a different context, usually by escaping the symbol in some way. In Nim for example, you can define an `==` function by wrapping it in backticks
<FromGitter> <Blacksmoke16> ah no, the Crystal way would use a diff word
<FromGitter> <mjfiano:matrix.org> Ah k
<FromGitter> <mjfiano:matrix.org> I suppose I would have to manually define my property methods if I were to use a static array as storage and I wanted to map those x, y names to indices?
<FromGitter> <Blacksmoke16> im pretty sure that offers no benefit over a struct with getters
<FromGitter> <mjfiano:matrix.org> I'm using a class, and for different vector lengths, and especially matrices, it'd allow me to write iteration macros to define a lot of routines for all shapes simultaneously
<FromGitter> <Blacksmoke16> you meant to use a static array as a property within the class?
<FromGitter> <Blacksmoke16> mean*
<FromGitter> <mjfiano:matrix.org> Yep
<FromGitter> <Blacksmoke16> cant you also just store a struct in the class?
<FromGitter> <Blacksmoke16> be easier than knowing what index is what
<FromGitter> <mjfiano:matrix.org> Are you familiar with GLSL?
<FromGitter> <Blacksmoke16> nope
<FromGitter> <oprypin:matrix.org> mfiano (https://matrix.to/#/@mjfiano:matrix.org): what's your question
<FromGitter> <mjfiano:matrix.org> I want to implement "swizzling", with a macro. That means, for a 2-dimensional vector that has an X and Y property, a macro would generate permutations of the accessors: x, y, xx, yy, yx
<FromGitter> <mjfiano:matrix.org> I have done such in Nim before. Just trying to figure out the best way with Crystal
<FromGitter> <oprypin:matrix.org> mfiano (https://matrix.to/#/@mjfiano:matrix.org): well if your question can be more generally rephrased as "generate GLSL at compile time", here you go: https://gist.github.com/ba18db84e5e55ddc6d07a661062ae186
<FromGitter> <mjfiano:matrix.org> No no
<FromGitter> <oprypin:matrix.org> but like... why doesnt it solve your problem
<FromGitter> <mjfiano:matrix.org> This is not for generating GLSL in any way. It is for CPU computations. I was just pointing at the feature in GLSL
<FromGitter> <oprypin:matrix.org> mfiano (https://matrix.to/#/@mjfiano:matrix.org): ok nevermind. then you can just use macros, yeah
<FromGitter> <oprypin:matrix.org> i would suggest to still use a struct as storage, not a static array
<FromGitter> <mjfiano:matrix.org> I would like to use classes, containing an array, in order to support chained methods (mutations that return `self`)
<FromGitter> <mjfiano:matrix.org> pass by value would prevent that
<FromGitter> <Blacksmoke16> static arrays are also pass by value
<FromGitter> <mjfiano:matrix.org> Right, but I wouldn't be returning them
<FromGitter> <Blacksmoke16> so then just use a struct within the class and return `self` as you would?
<FromGitter> <oprypin:matrix.org> you can use classes but they're too heavy if you want to store many vectors
<FromGitter> <oprypin:matrix.org> methods on structs can be chained but they're always by-copy, that is true
<FromGitter> <mjfiano:matrix.org> Yeah, I want the user-facing type to be a class for this reason. The storage is up for debate
<FromGitter> <mjfiano:matrix.org> internal storage*
<FromGitter> <mjfiano:matrix.org> oprypin (https://matrix.to/#/@oprypin:matrix.org): Are you a game developer? Your github looks interesting
<FromGitter> <oprypin:matrix.org> mfiano (https://matrix.to/#/@mjfiano:matrix.org): i really want to make a game but i'm not good at it
<FromGitter> <mjfiano:matrix.org> I worked on a game from scratch for about 10 years and never finished. It takes a lot of time, and code is the least amount of time, which...says a lot
<FromGitter> <mjfiano:matrix.org> These days I pretty much have given up and just like to write math visualizations; games without the game-y part :)
<FromGitter> <oprypin:matrix.org> oh my
<FromGitter> <mjfiano:matrix.org> Do you have a repo that sets up/explains the embedded crystal shader stuff?
<FromGitter> <oprypin:matrix.org> mm definitely no explanation of it. i just tore these out of my private repository
<FromGitter> <mjfiano:matrix.org> Ah ok
<FromGitter> <oprypin:matrix.org> it's just plain https://crystal-lang.org/api/ECR.html though. and you can ask questions if it's unclear
<FromGitter> <mjfiano:matrix.org> When am I required to `require` modules from the stdlib. The ones I've used so far (`Math` and `Random`) seem to be accessible without importing them.
<FromGitter> <Blacksmoke16> only some of the more non-standard ones like json, yaml, uuid, option_parser etc
<FromGitter> <mjfiano:matrix.org> Ok. It's nice the prelude includes useful things and I don't have to keep importing the same stuff everywhere
<FromGitter> <Blacksmoke16> mhm
<FromGitter> <Blacksmoke16> reall you'd only have to include them once
<FromGitter> <Blacksmoke16> its not like JS or something where you need the imports in every file
<FromGitter> <mjfiano:matrix.org> Yeah I meant like for each project I am used to including a bunch of common stuff from the language core
<FromGitter> <mjfiano:matrix.org> There's probably multiple things wrong here. Help? :) https://play.crystal-lang.org/#/r/bkz0
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/bkz5
<FromGitter> <mjfiano:matrix.org> :think
<FromGitter> <mjfiano:matrix.org> Well I had an array for a reason. I will need to take sub slices of it in more complicated functions
<FromGitter> <Blacksmoke16> but regarding you're actual issue, you're calling the argless constructor, which would leave `@data` uninitialized, hence the error
<FromGitter> <Blacksmoke16> your*
<FromGitter> <Blacksmoke16> `{x, y}` would actually be of type `Tuple(Float64, Float64)`
ur5us has joined #crystal-lang
<FromGitter> <Blacksmoke16> is the idea that index 0 is x and index 1 is y?
<FromGitter> <mjfiano:matrix.org> Yes
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/bkzp
<FromGitter> <Blacksmoke16> i still dont understand why you want the static array tho
<FromGitter> <mjfiano:matrix.org> It will matter more for matrices tbh, where I'm processing individual rows or columns at a time.
<FromGitter> <Blacksmoke16> how would you model that with static arrays? like 2 array or something?
<FromGitter> <mjfiano:matrix.org> No idea how it maps to Crystal yet. Here is how I did the same in Nim with a static array as storage (and was able to re-use a lot of code because of it): https://git.mfiano.net/mfiano/origin.nim/src/branch/master/src/origin/vec.nim#L7
<FromGitter> <Blacksmoke16> 404
<FromGitter> <mjfiano:matrix.org> 1 sec
<FromGitter> <mjfiano:matrix.org> fixed
<FromGitter> <Blacksmoke16> hmm
hightower3 has quit [Ping timeout: 252 seconds]
<FromGitter> <mjfiano:matrix.org> To answer your question, no, it'd be a single flat array
<FromGitter> <mjfiano:matrix.org> It makes some things easy, like extracting a column from a matrix to a vector: https://git.mfiano.net/mfiano/origin.nim/src/branch/master/src/origin/mat.nim#L589-L595
<FromGitter> <Blacksmoke16> are there only ever going to be like 2..4 types?
<FromGitter> <Blacksmoke16> idk, nvm, deff not familiar with this stuff
<FromGitter> <mjfiano:matrix.org> 2-4 for vectors.
<FromGitter> <mjfiano:matrix.org> The matrices I need are the same sizes squared: 4, 9, 16
<FromGitter> <mjfiano:matrix.org> which means rows x cols
<FromGitter> <mjfiano:matrix.org> But, np. I'm almost ready to take a break for today
ur5us has quit [Ping timeout: 255 seconds]
<FromGitter> <mjfiano:matrix.org> oprypin (https://matrix.to/#/@oprypin:matrix.org): Were you talking about size or instruction overhead wrt classes vs structs?