ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Fund Crystal's development: | GH: | Docs: | Gitter:
<FromGitter> <> Ah the issue is not as bad as that actually, but still unsure how to solve it.
<FromGitter> <> One class method in `ClassMethods` has a default argument value specified to be a constant. This constant id is guaranteed to exist in all types that include `Bar`, but with a different value for each type.
<FromGitter> <> and the ultimate problem when getting rid of red herrings, is that this constant cannot be resolved at parse time, since it depends on the type that includes it
<FromGitter> <> Interesting problem
<FromGitter> <> On another note, I'm curious if any other languages have something like the namespaces/partial type duality, as it is new to me and I think it is pretty clever. Does Ruby do this, was this feature inspired by other similar concepts, or is this unique to Crystal?
<FromGitter> <Blacksmoke16> it's basically copied from ruby
<FromGitter> <Blacksmoke16> PHP also has
<FromGitter> <> I see. It is a nice idea.
<FromGitter> <> "Note that most search and filter methods traverse an Enumerable eagerly, ⏎ producing an Array as the result. For a lazy alternative refer to ⏎ the Iterator and Iterable modules." ⏎ ⏎ Does this apply to `#all?`, and if so, what is an efficient way to do it if I have `Iterable`? []
<FromGitter> <Blacksmoke16> `all?` returns a `bool`
<FromGitter> <Blacksmoke16> meaning it'll iterate the entire collection as is
<FromGitter> <Blacksmoke16> ``` def all? ⏎ each { |e| return false unless yield e } ⏎ true ⏎ end``` ⏎ ⏎ is all it is []
<FromGitter> <> Great, yeah dumb question
<FromGitter> <Blacksmoke16> @straight-shoota one more time regarding that buffered channel bug
<FromGitter> <Blacksmoke16> if you add ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <Blacksmoke16> with a buffer size of 4, the first value takes care of the initial receive, 2 and 3 should fill that buffer, but it doesnt switch on the 4th value?
<FromGitter> <Blacksmoke16> buffer size of 2 rather*&
<FromGitter> <Blacksmoke16> oh wait, it does, but then there isn't anything to get it to execute that fiber again which is why it doesnt print the after message
<FromGitter> <Blacksmoke16> nvm
ur5us has quit [Ping timeout: 255 seconds]
ur5us has joined #crystal-lang
<FromGitter> <> How would I do the equivalent of `Enumerable#all?(&)`, except get access to the index as an argument (along with the existing object)?
<FromGitter> <Blacksmoke16> do you just want to find the first element that is true?
<FromGitter> <Blacksmoke16> or?
<FromGitter> <> ```code paste, see link``` ⏎ ⏎ I want to do something like this, with `idx` bound of course []
<FromGitter> <Blacksmoke16> id prob just copy the `.all?` method into your code and use `each_with_index` instead
<FromGitter> <Blacksmoke16> or if you want define an `all_with_index` if you dont want to override the actual all method
<FromGitter> <> Ok thanks.
<FromGitter> <Blacksmoke16> > oh wait, it does, but then there isn't anything to get it to execute that fiber again which is why it doesnt print the after message ⏎ ⏎ and no, im still confused. Is the buffer actually 1 more than what you specify. Otherwise why else would it print 2, 3, and 4 versus just 2 and 3
<FromGitter> <Blacksmoke16> and if you add 5 it outputs ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ which makes sense expect it printed 3 values with a buffer of 2? []
<FromGitter> <Blacksmoke16> except*
f1reflyylmao has joined #crystal-lang
f1refly has quit [Ping timeout: 255 seconds]
f1reflyylmao is now known as f1refly
<FromGitter> <Blacksmoke16> or maybe it's not really like a hard cutoff like im thinking and more like a way to tell the channel to trigger a reschedule when its buffer is full, which in this case value 4 "overflows" the buffer resulting in that reschedule
<FromGitter> <Blacksmoke16> as opposed to the next opportunity
<FromGitter> <> ```code paste, see link``` ⏎ ⏎ I'm still a little confused when working with blocks. This works, but how would this be rewritten to inline the functionality of `all_with_index?`, as this is the only usage of it and it doesn't deserve its own method? []
<FromGitter> <Blacksmoke16> prob like
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <> Oh I see now.
<FromGitter> <> That clears up more than I care to admit
<FromGitter> <Blacksmoke16> :P
<FromGitter> <> Hmm, if I mixin a module with a `new` method by using `extend`, I get "... is not expected to be invoked with a block, but a block was given". Works fine copy/pasting this `new` into every final type though. Ideas?
<FromGitter> <Blacksmoke16> Yes
<FromGitter> <> Where can I find the list of available macro variables like `@type`, `@def`, and `@top_level`?
<FromGitter> <Blacksmoke16> by virtue of you adding another constructor the others are no longer invocable i think
<FromGitter> <> Oh
<FromGitter> <Blacksmoke16> i *think* that's true, but don't quote me
<FromGitter> <> Ok, about the macro variable list, does one exist? I tried searching and only see those 3 mentioned in passing in the reference docs
<FromGitter> <Blacksmoke16> those are the only 3
<FromGitter> <> Nothing in the api docs from what i see either
<FromGitter> <> Aha!
<FromGitter> <> Thank you. I'm trying to figure out how I can get at the inner right-most type string name of a module path gotten with `@type`.
<FromGitter> <> Oh that was a mouthful. It's getting late
<FromGitter> <Blacksmoke16> `"::").last`
<FromGitter> <> Ok so string manip it is
<FromGitter> <Blacksmoke16> ye
<FromGitter> <Blacksmoke16> i always wondered what the `.identify` method is for on `StringLiteral`
<FromGitter> <Blacksmoke16> ` # => "Foo__Bar"` 🤔
<FromGitter> <> wonder if I can rely on the order of `#instance_vars` being how they are defined...
<FromGitter> <Blacksmoke16> wew, apparently this is why :P
<FromGitter> <Blacksmoke16> probably
<FromGitter> <Blacksmoke16> dunno if it'll help your use case but you can pass numbers as generic args
<FromGitter> <> Ok last question before I pass out? How do I newline split up long `io << foo << bar << baz << ...` chains so the parser is happy? :)
<FromGitter> <Blacksmoke16> ```io << foo << bar << baz ⏎ io << one << two << three ⏎ ...``` []
<FromGitter> <Blacksmoke16> really could have each `<<` on its own line as well
<FromGitter> <Blacksmoke16> :shrug:
<FromGitter> <> ah makes sense. Thanks a lot, night!
<FromGitter> <> Going to have to figure out how to get the *name* of an ivar tomorrow...
<FromGitter> <Blacksmoke16> if you're iterating over `@type.instnace_vars` its just `.name`
<FromGitter> <> in a `{% for ivar in @type.instance_vars %} ... {% end %}` I tried something like `io << {{}} << " " << {{ivar}}` and got the value duplicated instead of the name, which makes me believe its a quoting issue, but I'm afk so I'll try any suggestions tomorrow.
<FromGitter> <Blacksmoke16> might need ``
<FromGitter> <Blacksmoke16> otherwise it'll prob invoke the getter instead of the name
ur5us has quit [Remote host closed the connection]
ur5us has joined #crystal-lang
ua__ has quit [Ping timeout: 255 seconds]
ur5us has quit [Remote host closed the connection]
ur5us has joined #crystal-lang
ua_ has joined #crystal-lang
ur5us has quit [Ping timeout: 255 seconds]
ur5us has joined #crystal-lang
hightower2 has joined #crystal-lang
notzmv has quit [Read error: Connection reset by peer]
ur5us has quit [Ping timeout: 252 seconds]
<FromGitter> <> I woke up today with a couple questions: ⏎ ⏎ 1) Why isn't `#[]=` included in indexable? Do I always have to implement this if it is always the same (apart from assigning) as `#unsafe_fetch`? ⏎ ⏎ 2) If I have a struct with an array as its only ivar, is there a more convenient way to make the struct Indexable besides defining `#unsafe_fetch` that just forwards to the array's version? I'm not
<FromGitter> ... really familiar with delegates but thinking they are the key here. []
<FromGitter> <> I see how delegate is used now, and it is the answer to #2. New question: Is there a technical reason why the `#[]=` methods with `Range` parameters from `Array` are not included for `StaticArray` (or a `Slice` of one)? I'm sad I can't assign into subranges of a homogeneous array.
notzmv has joined #crystal-lang
<FromGitter> <> mfiano ( indexable is about ability to read by index. ability to write by index wasn't seen as common enough and big enough to implement a generic module for
<FromGitter> <> Fair enough. Any reasoning for only being able to write a single index with StaticArray?
<FromGitter> <> mfiano ( ability to assign to a range is very powerful and includes resizing of the array.
<FromGitter> <> staticarray can't be resized so there would be too many cases where the only way out would be too raise a runtime exception in the general case
<FromGitter> <> That is true. If it's doing bounds checking already though, it can be implemented for SA to not dynamic grow the heap memory (since it's not heap memory)
<FromGitter> <> It is looking like my types are going to be structs wrapping a regular dynamic Array then
<FromGitter> <> I might pay for allocation/fragmentation with lots of objects, so not sure yet though
<FromGitter> <> Regarding the discussion in crystal#10976 is the cause behind the invalid memory access of some actions unknown? Do these segmentation faults happen in practice or is the CI just overwhelmed? Sad to see everything with a red cross :(
sorcus has joined #crystal-lang
hightower2 has quit [Remote host closed the connection]
hightower2 has joined #crystal-lang
Vexatos_ has joined #crystal-lang
jhass|off has joined #crystal-lang
straight- has joined #crystal-lang
hexology- has joined #crystal-lang
wolfshappen_ has joined #crystal-lang
iskra has joined #crystal-lang
hexology has quit [Ping timeout: 255 seconds]
jhass has quit [Ping timeout: 255 seconds]
maria_elis has quit [Ping timeout: 255 seconds]
Vexatos has quit [Ping timeout: 255 seconds]
dostoyevsky2 has quit [Ping timeout: 255 seconds]
wmoxam_ has quit [Ping timeout: 255 seconds]
wolfshappen has quit [Ping timeout: 255 seconds]
straight-shoota has quit [Ping timeout: 255 seconds]
wmoxam has joined #crystal-lang
dostoyevsky2 has joined #crystal-lang
dostoyevsky2 has joined #crystal-lang
dostoyevsky2 has quit [Changing host]
<FromGitter> <BracketsFlower_twitter> Hey you can refer this resource on System arraycopy() method in java -
<FromGitter> <> Where is the macro control flow and other keywords listed in the docs, such as `{% for ... %}`
<FromGitter> <> Hmm I suppose there is no repeat loop
<FromGitter> <Blacksmoke16> hm?
<FromGitter> <> Trying to generate a call to `initialize value, value, value` where the number of "value"s is the length of the splatted macro argument
<FromGitter> <> Hmm, I guess I could do this, but it seems macro writing in Crystal is a lot of DRY violations, unless I'm not experienced. ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <> Just seems odd that I have to bind a variable to iterate N times, and I can't even use an underscore
<FromGitter> <> (line 19 above)
Stephie- is now known as Stephie
ua_ has quit [Remote host closed the connection]
<FromGitter> <> My first library is finished, code-wise, and I'm pretty happy with it. I still have to do docs and specs which will take a long time given the number of defs, but yay
ua_ has joined #crystal-lang
<FromGitter> <Blacksmoke16> nice one!
<FromGitter> <> I saved a considerable amount of complexity and duplicated code by wrapping a staticarray and forwarding missing, instead of all the nonsense i had to do before
<FromGitter> <> i think srasu suggested that, or whoever it was, thanks
<FromGitter> <> oh i guess it's suskeyhose over on gitter
<FromGitter> <> Is there a recommended style guide apart from the rather short one on the web site? I was looking to see what magic number this language recommends for max columns :)
<FromGitter> <Blacksmoke16> i dont think there is one
<FromGitter> <Blacksmoke16> i usually just make it so i dont have to scroll :p
dostoyevsky2 has quit [Quit: leaving]
dostoyevsky2 has joined #crystal-lang
deavmi has quit [Ping timeout: 256 seconds]
deavmi has joined #crystal-lang
hightower2 has quit [Ping timeout: 252 seconds]
deavmi has quit [Ping timeout: 276 seconds]
notzmv has quit [Ping timeout: 240 seconds]
<FromGitter> <> Well, I hope the macro writing DSL grammar is on the list of things to improve. This is definitely not as powerful as Lisp.
<riza> @mjfiano - what are you looking for that you aren't finding?
<FromGitter> <Blacksmoke16> only related things that i know of are like and
<FromGitter> <> I mentioned one thing just below the code snippet above
<FromGitter> <> methods in macro land is the issue discussing most of my concerns though
<FromGitter> <Blacksmoke16> yea it uses a subset of the stdlib methods
<riza> ah yeah, for sure.
<FromGitter> <Blacksmoke16> fwiw i think you can improve this a bit
<riza> the inability to repeatedly inject a macro has suffered me many times
<FromGitter> <> I get that nothing can possibly be as powerful as Lisp, without actually being Lisp, because once you add homoiconicity to a language that enables powerful macros taking advantage of the full language instead of a DSL, you can practically call it a Lisp
<FromGitter> <> But a little more will go a long way
<FromGitter> <> However, despite being a huge Lisp fan, I stay away from macros unless I have to, unlike a lot of people that grow old trying to bend the language to do cool new things. However, when I actually do need to write a macro for some syntactic abstraction or boilerplate reduction, I need access to the language at compile time, not some tiny subset of it.
<FromGitter> <Blacksmoke16> fwiw you could do like `{% for i in 0..4 %}`
<FromGitter> <> I am by no means trying to bash Crystal though. Its balance of simplicity and power is what drove me to try it, and I am very pleased with that. Lisp is pretty much 1000% power.
<FromGitter> <> Yes, the "loop n times" instead of "loop over some collection/range" can be simulated like that, though I would have liked to use `_` in place of `i` to convey meaning to the reader.
<FromGitter> <Blacksmoke16> `_idx` :shrug:
<FromGitter> <> Bringing over the `times` method would almost be enough, except need some concise DSL to account for when the count is the length of a sequence, but still don't want to bind any e or i vars
<FromGitter> <> </nitpick> The real issue is DRY violation as that issue discusses. I think a lot of people would be happy with work done in that area
<FromGitter> <Blacksmoke16> hm `0..collection.size`
<FromGitter> <Blacksmoke16> you also have `.each` and `.map` available
<FromGitter> <Blacksmoke16> kinda
<FromGitter> <> How would you use them in macroland?
<FromGitter> <Blacksmoke16>
<FromGitter> <Blacksmoke16> you have macro level variables that you could use it to set, but you'd have to use `for in` if you wanted to iterate over them and generate code
<FromGitter> <> Oh sure, that'll just return a sequence for you to do whatever with, like `{% for ... %}` :)
<FromGitter> <Blacksmoke16> e.g.
<FromGitter> <> That latest snippet answered an unrelated question I was going to ask.
<FromGitter> <> I assumed right, that you can bind compile-time variables like that
<FromGitter> <Blacksmoke16> also quite a bit of complex logic using this feature if you wanted to poke around
<FromGitter> <> Oh athena suite is your pet? I see that all over 😆
<FromGitter> <> Never made the connection
<FromGitter> <Blacksmoke16> code is super gross because you cant reuse anything, but it would look much better with
<FromGitter> <Blacksmoke16> haha yea it is
<FromGitter> <> It seems to be one of the most solid projects for sure
<FromGitter> <> Sadly, I don't do any webdev these days anymore, so might use the logger or one of the decoupled things if anything.
<FromGitter> <Blacksmoke16> logger is built into the stdlib
<FromGitter> <> Fair enough. Well there was one athena project i was thinking of using, but I forget what it was
<FromGitter> <Blacksmoke16> there is a CLI/console framework component that is currently in a working state, I just need to finish the docs on it tho
<FromGitter> <Blacksmoke16> other than that, can deff use them independently. E.g. like the validator or serializer etc
<FromGitter> <> Which project of yours (or other) would you say has the best docs? I would like to take a look at the tricks from the masters :)
<FromGitter> <Blacksmoke16> they're all pretty well documented
<FromGitter> <> (I am not very great at writing docs, probably because I have too many forever projects to get to that point)
<FromGitter> <Blacksmoke16> is fairly easy with crystal since it handles the bulk of the work if you give argument/return type restrictions
<FromGitter> <Blacksmoke16> then you just need to fill in contextual information and examples
<FromGitter> <Blacksmoke16> to tie everything together
<FromGitter> <> Did you have to jump through a lot of hoops to get the style of the generated API docs to be like the Crystal website instead of that plain purple theme that is the default? I would prefer doing as minimal webdev as possible :)
<FromGitter> <> hmm
<FromGitter> <Blacksmoke16> isnt too bad, mostly just config but the default purple one would deff be easier as you have to do pretty much nothing
<FromGitter> <Blacksmoke16> and just setup CI to deploy it to GH pages
notzmv has joined #crystal-lang
<FromGitter> <> I'm actually surprised Crystal isn't used much for gamedev after looking at the library space. Seems like it'd be a great language for that.
<FromGitter> <> Probably moreso to do with the user count
deavmi has joined #crystal-lang
<FromGitter> <asterite> Depending on how many lines of code a game usually has, I think having to compile the app in release mode all the time to get something fast (good FPS) and waiting 5+ minutes for that is probably not good. So I'm not sure Crystal is good for real world game development
<straight-> Game dev is not just about FPS though
<FromGitter> <asterite> What do you mean?
<FromGitter> <> I hear that, though often times you shouldn't need very fast performance when testing, unless you have a complex physics system or something.
<FromGitter> <> So debug builds should be acceptable
<FromGitter> <> Gamedev is about trying to compute as much as you can on the GPU, getting it there in time if not all up front, and then moving it back to the CPU when you need prettier graphics :P
<FromGitter> <asterite> Makes sense. Yeah, maybe you get decent fps in debug builds
<FromGitter> <> Rust's compiler is pretty slow and their gamedev community seems to be really ramping up since the last couple years, and the compiler was about 3x slower a few years ago when it first started picking up.
<FromGitter> <> Though I hear they are trying to leverage dynamic runtime dispatch more to account for all the monomorphism eating compile times.
<FromGitter> <> Does crystal use boehm?
deavmi has quit [Read error: Connection reset by peer]
<FromGitter> <asterite> Interesting. But I know that Rust has modular compilation, so maybe it's slow the first time? No idea how well that's optimized
<FromGitter> <asterite> Yes, it uses boehm, but just because it works out of the box without us having to do much work. Crystal could use a different GC, eventually
<FromGitter> <> I hear it's slow because the transitive dependency graph often contains many different versions of the same libraries, and all their functions are monomorphized. I'm not sure if it does DCE or not for this though.
deavmi has joined #crystal-lang
<FromGitter> <> Think it's more a case of, the language has a large library ecosystem and encourages lots of re-use, plus fundamental monomorphic behavior, over a slow compiler. Can't really compare it to Crystal in either regard.
<FromGitter> <> yet, anyway
<FromGitter> <asterite> I know oprypin has written some games, also I think in Windows
<FromGitter> <> Does Crystal have concurrent hash tables?
<FromGitter> <RespiteSage> Someone may have implemented them, but I don't know.
<FromGitter> <> Would like to see a lockless one with CAS or something
<FromGitter> <> That has been a huge complaint with my Lisp work anyway
deavmi has quit [Ping timeout: 265 seconds]
deavmi has joined #crystal-lang
deavmi has quit [Ping timeout: 255 seconds]
deavmi has joined #crystal-lang
<FromGitter> <> rust does whole-program optimization from source which includes DCE
<FromGitter> <RespiteSage> I feel like I constantly have this question, but is there a way to access the actual, compile-time type of a generic type within a class instantiation but not in a method?
<FromGitter> <RespiteSage> Like ⏎ ⏎ ```class Indigent(T) ⏎ {% puts T %} ⏎ end ⏎ ⏎ a = Indigent(Int32).new``` []
<FromGitter> <RespiteSage> Except it actually works.
<FromGitter> <Blacksmoke16> idt because `T` is only specific to an instance
<FromGitter> <RespiteSage> Hm... Okay.
<FromGitter> <RespiteSage> I was wanting to set constants based on what type it is (specifically, MIN/MAX).
<FromGitter> <RespiteSage> I bet I could do those as getters and set them in the initializer, though.
<FromGitter> <asterite> Constants will be inside `Indigent`, not `Indigent(Int32)`
<FromGitter> <asterite> That is, you can't have constants have different values depending on T
<FromGitter> <asterite> Plus you can't do `Indigent(Int32)::MAX` (I think that doesn't even parse)
<FromGitter> <andriusch> Hello, I have this code: ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ I don't understand why casting an element in the hash works, but casting the whole hash doesn't? Are there alternatives to what I'm trying to achieve (essentially index objects by type & by id)? []
<FromGitter> <> straight-shoota: Why does Shardbox have roughly 1/6 of the shards as some of the other databases? Yours is my favorite still though
<FromGitter> <RespiteSage> Okay, that makes sense. Thank you for the clarification.
<FromGitter> <Blacksmoke16> shardbox is manually curated, the others scrape github/gitlab and stuff
<FromGitter> <> Ah I see.
<FromGitter> <Blacksmoke16> @andriusch because how would that work if the hash also contained a cat?
<FromGitter> <Blacksmoke16> and because is typed as `Animal` that would be possible
<FromGitter> <RespiteSage> @andriusch It has to do with how generic types are implemented in Crystal. Other people are more able to explain why, but the basic idea is that even if `T` "inherits" from `U`, `A(T)` does *not* inherit from `A(U)`.
<FromGitter> <RespiteSage> In this particular case, you could use `dogs = animals[Dog].transform_values &.as(Dog)` on your last line.
<FromGitter> <Blacksmoke16> whats the end goal of this? what are you wanting to do?
<FromGitter> <andriusch> ah got it, makes sense that `Hash(Int32, Dog) < Hash(Int32, Cat)` is not true
<FromGitter> <andriusch> I want to store objects based on their type & id in a hash
<FromGitter> <andriusch> all objects would inherit from some class, so it made sense to me to use `Hash(Animal.class, Hash(Int32, Animal))` as type definition
<riza> if you're using ints as keys, why not an array?
<riza> Hash(Animal.class, Array(Animal))
<FromGitter> <Blacksmoke16> and do what with this hash? like whats the end goal?
<FromGitter> <andriusch> I don't want to use array since ids are not sequential, I don't think array would solve my problem though
<FromGitter> <Blacksmoke16> are the ids not related to the instance?
<FromGitter> <Blacksmoke16> like ``
<FromGitter> <andriusch> not exactly, more like each id can have multiple types of objects associated to it
<FromGitter> <andriusch> e.g. an object with id = 1 can have a cat & a dog associated to it
<FromGitter> <andriusch> object with id = 2 only has a cat
<FromGitter> <andriusch> while object with id = 3 has an opposum
<FromGitter> <Blacksmoke16> would it be easier to use a struct instead of a hash, then you could give a name to these IDs, with getters to get the related animals?
<FromGitter> <andriusch> once the objects are stored I want to be able to retrieve: ⏎ an object based on type & id ⏎ all objects based on type
<FromGitter> <andriusch> there could potentially be >100 type of objects, I don't really want to define 100 properties on struct
<FromGitter> <andriusch> and same for ids
<FromGitter> <Blacksmoke16> hmm fair enough
<FromGitter> <asterite> You can just make it so that a Dog and a Cat are not equal by `==`, and that they also have different `hash` values. Then you can simply have `Set(Animal)`
<FromGitter> <asterite> Oh, but you need to be able to retrieve all dogs and cats, I see...
<FromGitter> <andriusch> thanks for your help, I guess I'll go with `animals[Dog].transform_values &.as(Dog)` since it doesn't seem there are better alternatives
<FromGitter> <Blacksmoke16> yea prob best you're going to get. Hashes can be kinda annoying to work with but i cant really think of another way
ur5us has joined #crystal-lang
<FromGitter> <> So it's a long shot but figure I'll ask anyway: My biggest problem seems to be trying to come up with an ordering that compiles with regard to `require`ing the proper files where they are needed. It seems to get really confused sometimes when I `include` or `extend` a module. I sort of wish I could just `require "./project/*` in a file in src/, but a real solution seems to be repeating the
<FromGitter> ... same `require`s in different files. I have no idea what I'm doing wrong, if anything, because I'm really not used to programming in such an OOP way, and mixins even less so. Has anyone ran into these sorts of problems before, and how did you get used to it/find something that works? Can anyone recommend some tutorials for ... []
<FromGitter> <> Also sometimes it blows up when I use `include` by itself, and I have to wrap it in `macro included` fairly often.
<FromGitter> <> It's quite maddening, because I don't see anything wrong with a fairly simple project.
<FromGitter> <Blacksmoke16> i found what works for me is to just require everything manually within your main entrypoint file
<FromGitter> <> That's what I first tried, and infact I'm reading that file right now lol
<FromGitter> <Blacksmoke16> with external libs at the top, then one off files, then globs
<FromGitter> <Blacksmoke16> that covers *most* things, are still a few cases where i may need to require something in a specific file. For example the exceptions dir, most of them require `http_exception` i could have prob added that as a one off require before the directory but :shrug: didn't think it was worth it
<FromGitter> <Blacksmoke16> so i guess tl;dr is like, global things in main file, then sometimes specific requires within directories as needed
<FromGitter> <Blacksmoke16> > Also sometimes it blows up when I use `include` by itself, and I have to wrap it in `macro included` fairly often. ⏎ ⏎ got an example of this?
<FromGitter> <> So would you say that you recommend explicitly listing every file and very rarely use the glob except for collections of order independent submodules?
<FromGitter> <Blacksmoke16> pretty much yea
<FromGitter> <> I have always preferred to do a serial load order myself in Lisp, manually toposorting it as I develop so that sounds like what I prefer
<FromGitter> <Blacksmoke16> however you do it, just need to ensure things are required before they're used, that's the key point
<FromGitter> <Blacksmoke16> having every file require everything it needs is a bit overkill
<FromGitter> <> Maybe doing it that way will solve a lot of my problems. The setup that has been giving me grief is a main file doing `require "./origin/*`, and then trying to get the requires right in that directory. That sounds like a recipe for failure now that I actually typed it out 😆
hightower2 has joined #crystal-lang
<FromGitter> <Blacksmoke16> totally could still use the glob, but require the common things before
<FromGitter> <> True, I haven't come up with a hierarchy I like yet (only a handful of files)
<FromGitter> <> So mostly working with a flat directory
<FromGitter> <Blacksmoke16> is suggested to group things by namespace
<FromGitter> <Blacksmoke16> i.e. `exceptions` live in `Athena::Routing::Exceptions` namespace
<FromGitter> <Blacksmoke16> etc
<FromGitter> <> and that maps to src/athena/routing/exceptions/?
<FromGitter> <Blacksmoke16> technically `src/exceptions`
<FromGitter> <Blacksmoke16> i dont use that extra directory, but otherwise would be like `src/athena/exceptions`
<FromGitter> <Blacksmoke16> i guess i kinda use the org/repo name as the first two components to that
<FromGitter> <> Ok, well it works explicitly listing each file in toposorted order. I'll work on organizing by concept next.
<FromGitter> <> Unrelated:
<FromGitter> <> What is an easy way to test the expansion of a macro you're in the process of writing? The crystal vim plugin has a function for this but it is bugged half the time. So I guess, what is the builtin way, and is there any 3rd party improvement, or utilities for writing macros in general?
<FromGitter> <Blacksmoke16> wouldn't that just be testing the functionality it generates?
<FromGitter> <Blacksmoke16> dont really need to test the macro part of it specifically
<FromGitter> <> I would like to see the generated code is what it is supposed to be before testing functionality. I've caught subtle errors that way in my years of macro writing.
<FromGitter> <Blacksmoke16> ohh i see
<FromGitter> <Blacksmoke16> add a `{{debug}}` to the end of the macro
<FromGitter> <> I see. Not sure how I missed that in the api docs. Would have been nice when I wrote the macros earlier.
<FromGitter> <> Very nice
<FromGitter> <> Are there any common general utility libraries for Crystal?
<FromGitter> <> Things that got rejected for the stdlib, or things useful for everyday programming that didn't make it into the language yet for some reason or other?
<FromGitter> <Blacksmoke16> Like what?
<FromGitter> <Blacksmoke16> There are some, but depends on what you are doing exactly
<FromGitter> <Blacksmoke16> I'd definitely suggest using tho
ua_ has quit [Ping timeout: 256 seconds]
<FromGitter> <> I have that and so far. I meant like general purpose utilities. Lisp has "alexandria", which includes necessities like correct macro writing macros such as once_only I discussed before, pattern matching stuff, etc etc
<FromGitter> <Blacksmoke16> Can't say I've heard of I also use Athena's spec component sometimes, but other than that nothing comes to mind stdlib usually has everything I need.
<FromGitter> <> is basically pp! but with color, line numbers, etc, and can use in the middle of expressions
<FromGitter> <Blacksmoke16> Fair enough
<FromGitter> <> Ok so
<FromGitter> <> In my main src/ file I have this and only this:
<FromGitter> <> ```require "./origin/scalar" ⏎ require "./origin/shared" ⏎ require "./origin/vector"``` []
<FromGitter> <> In it starts out like this: ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <> The `include` compiles if I put it in a `macro included` though
<FromGitter> <> These are the errors that drive me crazy because I don't see where they are coming from.
<FromGitter> <> I only have 3 files, and this is the last file parsed
<FromGitter> <> should have already been loaded and the module defined...
<FromGitter> <Blacksmoke16> Do you have this all pushed up atm?
<FromGitter> <> No but I could
<FromGitter> <> Give me a minute
hightower2 has quit [Ping timeout: 276 seconds]
<FromGitter> <>
<FromGitter> <> Hey Mr. Grant, my stalker :)
<FromGitter> <Blacksmoke16> what were you running to get that?
<FromGitter> <>
<FromGitter> <> I didn't think to run that, because the semantic analyzer in nim showed the aforementioned error in my buffer upon saving
<FromGitter> <> s/vim/vim/
<FromGitter> <> err nim -> vim. must be almost that time :/
<FromGitter> <> The test code I have under those 3 requires is: ⏎ ⏎ ```code paste, see link``` []
<FromGitter> <Blacksmoke16> thz
<FromGitter> <Blacksmoke16> worked fine for me?
<FromGitter> <> :/
<FromGitter> <Blacksmoke16> sure you dont have anything else going on?
<FromGitter> <> I'm positive. everything else is checked in
<FromGitter> <Blacksmoke16> what's `crystal --version` say?
<FromGitter> <Blacksmoke16> and like `crystal env`
<FromGitter> <> ⏎ ⏎ This is what I see when I save that file
<FromGitter> <> 1) 0.0
<FromGitter> <Blacksmoke16> ohh, let me make that not a macro now
<FromGitter> <> ```code paste, see link``` []
<FromGitter> <Blacksmoke16> ah ok
<FromGitter> <Blacksmoke16> i kno why
<FromGitter> <Blacksmoke16> no nvm
<FromGitter> <> can you even repro?
<FromGitter> <Blacksmoke16> yea i get `Error: undefined method 'rand' for Origin::Vector2.class`
<FromGitter> <> Good, it's not just me
<FromGitter> <Blacksmoke16> i think i see the problem tho
<FromGitter> <> So yeah, if you can figure out why the macro hook makes it work, i might be able to figure out why i get tons of these similar problems
<FromGitter> <Blacksmoke16> by including `Origin::Shared` that triggers the `macro included` hook which extends the class methods on `Origin::Vector`, but by wrapping that in another `macro included` makes it not expand until `Origin::Vector` is included in the actual `Vector*` types
<FromGitter> <> I think my mind just imploded
<FromGitter> <Blacksmoke16> i'd argue maybe modules aren't the best solution here versus some parent structs?
<FromGitter> <> Well inheritance graph is going to get hairy...i have a lot to add
<FromGitter> <> I'd rather use mixins if possible
<FromGitter> <Blacksmoke16> but if the mixins are included in every type, doesnt that defeat the purpose?
<FromGitter> <Blacksmoke16> basically recreating the same structure, but in a diff way
<FromGitter> <> So I guess the 2 solutions I see are ⏎ 1) Copy the `include Origin::Shared` into each concrete type instead of once in the Vector mixin. ⏎ 2) I already forgot because I'm tired :(
<FromGitter> <> Well right now, yes it does defeat the purpose. It might get a little hard to model with inheritance later on
<FromGitter> <> Shared is intended to be stuff common to all math base math types (vectors, matrices, and quaternions). Vector is stuff common to all vectors (but Vector3 is special and will define more stuff for itself), and then there will be higher order math types making use of these 3 base types or varying dimensions
<FromGitter> <> It's a rather large project, about 20kloc of Lisp
<FromGitter> <Blacksmoke16> even if you have methods defined on parent types, you can override them
<FromGitter> <Blacksmoke16> but fair enough
<FromGitter> <> I suppose I could try inheritance tomorrow if you think it is a better fit
<FromGitter> <> Really, I'm used to functional programming and a very different kind of OOP (methods not associated with classes at all with multiple dispatch)
<FromGitter> <> So this way of coding is very new to me
<FromGitter> <Blacksmoke16> idk what other stuff you have to do, but atm it seems like it might be better
<FromGitter> <> That's good enough for me. Thanks for taking a peek
<FromGitter> <> Wait, Crystal is single inheritance right?
<FromGitter> <Blacksmoke16> yes
<FromGitter> <> This may be difficult already then...but I'll think about it tomorrow
<FromGitter> <Blacksmoke16> 😬 worth looking into at least
ur5us has quit [Ping timeout: 240 seconds]
ur5us has joined #crystal-lang
<FromGitter> <> Are class/struct-level constants inherited?
<FromGitter> <Blacksmoke16> looks like it yes
<FromGitter> <> Ok that's one thing over mixins then