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> <riffraff169> yeah, just create a dispatch table....hash key being name, value being proc, then call the proc when a key matches
<FromGitter> <riffraff169> could even have it be a list of procs, that can be called in order... and can change them dynamically if needed... basically like hooks
<Guest64> i was thinking something similar as well. i may be able to make a hash of string, proc() work to my liking
<Guest64> thanks for the ideas
wmoxam has quit [Ping timeout: 256 seconds]
wmoxam has joined #crystal-lang
ua__ has quit [Excess Flood]
ua__ has joined #crystal-lang
lucf117 has joined #crystal-lang
lucf117 has quit [Remote host closed the connection]
ua__ has quit [Ping timeout: 255 seconds]
ua__ has joined #crystal-lang
jhass[m] has quit [*.net *.split]
ua__ has quit [Ping timeout: 240 seconds]
ua__ has joined #crystal-lang
<FromGitter> <wyhaines> @guest64 Macros create code in the place where the macro is called. Also, macros can not call other macros -- they look like methods, but they aren't really methods. However, macros do have access to constants. So you could have your first macro, the one that defines a proc, inject data into a constant that a later macro, involved with the case statement creation, accesses to build said case statement.
[R] has quit [Quit: No Ping reply in 180 seconds.]
[R] has joined #crystal-lang
ua__ has quit [Read error: Connection reset by peer]
fifr[m] has quit [Quit: Bridge terminating on SIGTERM]
jhass[m] has joined #crystal-lang
fifr[m] has joined #crystal-lang
user1 has joined #crystal-lang
user1 has quit [Quit: WeeChat 3.0.1]
user1 has joined #crystal-lang
user1 has quit [Client Quit]
rem has joined #crystal-lang
f1refly has quit [Quit: see ya in hell]
f1refly has joined #crystal-lang
jrayhawk has quit [Ping timeout: 256 seconds]
jrayhawk has joined #crystal-lang
rem has quit [Quit: WeeChat 3.0.1]
Guest64 has quit [Quit: Client closed]
Guest64 has joined #crystal-lang
<Guest64> thanks for the advice, im trying to use a hash to contain my map of String, Proc, but while trying to add my procs to the hash I get this error:
<Guest64> ProcMap = Hash(String, Proc).new
<Guest64> Error: can't use Proc(T, R) as generic type argument yet, use a more specific type
<FromGitter> <Blacksmoke16> you need to type your proc
<FromGitter> <Blacksmoke16> `Proc(String, Int32)` e.g. if it accepts a string an returns an int32
<Guest64> each proc has diufferent types, how can i make that work with the hash
<Guest64> IE each proc added to the hash do not share the same definition
<FromGitter> <Blacksmoke16> that's going to be painful
<FromGitter> <Blacksmoke16> what are these procs used for?
<Guest64> thats hard to explain without going into depth of the project. the procs are basically synonyms of existing libc functions which their pointer address is returned back to the dynamic linker during the binding stage to determine which function symbol points to which function
<FromGitter> <Blacksmoke16> might be able to wrap these procs in structs
<FromGitter> <Blacksmoke16> somethign like
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60eb28b423fd26511da75568]
<FromGitter> <Blacksmoke16> the gist of it is that you cant have a hash with type of `Proc`, would need to specify the types of procs that can be in the hash
<FromGitter> <Blacksmoke16> i suppose technically the macro approach you wanted to take would work around this by defining a hash literal, which would essentially type itself
<Guest64> hmm, wrapping the procs inside a struct might work. i never thought of that
<Guest64> could you expand more on this hash literal you speak of?
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/biyi
<FromGitter> <Blacksmoke16> the type of literal hashes are inferred based on the values in the literal
<FromGitter> <Blacksmoke16> but hashes with a lot of unioned types is kinda meh
<Guest64> yea thats probably going to be messy since these procs vary in arguments from 0 to 6 with various types ranging from simply ints up to pointers to structs
<Guest64> although thats neat that works like that. ill keep that in mind
<Guest64> Blacksmoke16: I am having a bit of trouble implementing a simple test for your callable suggest: https://play.crystal-lang.org/#/r/biyo im probably not doing this right at all heh
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/biyq
<FromGitter> <Blacksmoke16> prob not going to be that easy when you add more, as the compiler wont be able to guarantee that the value returned from the hash has that method with those arguments
<Guest64> hmm yes, i will have to ponder about that. thanks for the assistance
<FromGitter> <Blacksmoke16> are the string keys anything significant?
<FromGitter> <wyhaines> Yeah, it won't work once you add a second struct.
<Guest64> the string keys are just a way to fetch the correct proc pointer from the hash to return to the dynamic linker. the dynamic linker actually gives me a char*, but i convert it to a string for use.
<FromGitter> <wyhaines> I've been down this road when I built my `#send` implementation. :)
<Guest64> if it matters im attempting to implement rtld-audit for fun and experience: https://man7.org/linux/man-pages/man7/rtld-audit.7.html
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/biyx
<Guest64> i have everything working, im just testing new theories and ways to generate code
<FromGitter> <Blacksmoke16> if the strings are just a way to know what the proc is, you can make the proc's class the key of the hash
<FromGitter> <Blacksmoke16> could also ofc have a `#get` method that returns the related `Callable` instance that you could then directly invoke `#call` on
<FromGitter> <Blacksmoke16> but i just combined them into 1 method
<FromGitter> <wyhaines> Yeah. You can't get away from storing the class/type of Proc or Struct somewhere, in some form.
lucf117 has joined #crystal-lang
jrayhawk has quit [Ping timeout: 268 seconds]
jrayhawk has joined #crystal-lang
<Guest64> random question: is there a way for crystal to expand macros in other files, then move the expanded code into another file for use? if that makes any sense.
<Guest64> i wish there was better docs for macros somewhere. it seems to have all these cool features but i cant make heads or tails of them
<FromGitter> <Blacksmoke16> you already asked this and we answered it twice :P
<FromGitter> <Blacksmoke16> ☝️ July 11, 2021 1:45 AM (https://gitter.im/crystal-lang/crystal?at=60ea85817473bf3d781b8751)
<Guest64> ha, i suppose i did, my bad
<FromGitter> <Blacksmoke16> i will say that mutable constant approach is kinda a smell
<FromGitter> <Blacksmoke16> im still of the opinion you dont even need a macro
<Guest64> i guess the problem i am trying to solve is that i have all these function prototypes that vary radically, but the internal body consists mostly of the same method calls plus a bit of dynamic logic based on the function being called, hence the yeild in the macro. i think in the end i was just exploring different options so that i did not have to
<Guest64> write boilerplate 50+ times
<FromGitter> <wyhaines> A macro generates code only in the location in which it is executed. ⏎ ⏎ However.....you can make what you want to do work with macros. ⏎ ⏎ Macros have access to constants. ... [https://gitter.im/crystal-lang/crystal?at=60eb40f17b5a415e65ddec2d]
<FromGitter> <Blacksmoke16> i.e. in the previous example the logic that was like `arg0 + arg1` is the stuff thats unique per proc? but there is also common logic between them all?
<Guest64> yes corrent, a fair bit of common logic
<Guest64> im reading https://crystal-lang.org/api/1.0.0/Crystal/Macros/TypeNode.html atm like wyhaines suggested
<FromGitter> <wyhaines> TypeNode just shows you what you have access to within a TypeNode. i.e. `#constants`, so you can iterate constants.
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/bizd
<FromGitter> <wyhaines> The fact that macros have access to constants means that you can use them to store and gather information from a wide variety of locations, and use it in a central location.
<FromGitter> <Blacksmoke16> auto registers proc types in the collection type, and shows how you can do before/after logic
<FromGitter> <Blacksmoke16> can remove the `#register` method then too
<Guest64> wait i am a bit confised here. you can use {% %} and {{ }} outside of a macro def block?
<FromGitter> <Blacksmoke16> yes, this is also macro code
<FromGitter> <Blacksmoke16> `macro some_name` are reusable portions of macro code, but you can also use the macro code outside of them
<FromGitter> <Blacksmoke16> the end result is the same. Code generated by the macro code is included where it's called as if you manually typed it
<Guest64> okay, that is pretty cool now, im starting to understand this system a bit more
<Guest64> thanks for the aid
<FromGitter> <Blacksmoke16> Np
f1refly has quit [Quit: see ya in hell]
f1refly has joined #crystal-lang
<Guest64> wynhaines: just to circle back on what you said. if i define a proc with a constant such as MY_PROC = -> (){}, if i used {% Proc.constants %} I should be returned an array of all constants that contain a proc?
<FromGitter> <Blacksmoke16> no
<Guest64> im just trying to understand the macros and typenode system as a whole now, outside of my project
<FromGitter> <Blacksmoke16> sec
<FromGitter> <Blacksmoke16> https://play.crystal-lang.org/#/r/bizh
<FromGitter> <Blacksmoke16> you're basically mutating the value of a constant at compile time
<FromGitter> <Blacksmoke16> which you could then later iterate over in other macro code
<FromGitter> <Blacksmoke16> However at this point, it has less use cases with the introduction of annotations
<Guest64> Blacksmoke16: yea your example makes sense, but i was referring to when wynhaines said that you can use `#constants` to iterate constants
<Guest64> unless i mistoook what he was meaning
<FromGitter> <Blacksmoke16> ah that would be like
<FromGitter> <Blacksmoke16> ```code paste, see link``` [https://gitter.im/crystal-lang/crystal?at=60eb5666f2b4077d6bbfa336]
<Guest64> hmm that gives me some ideas to test out. is there a way to access constants at the top level, or only within class/struct objects?
<FromGitter> <Blacksmoke16> That example is on the top level
<FromGitter> <Blacksmoke16> Oh
<FromGitter> <Blacksmoke16> I think that'll be possible in the next version, until then it's probably still a good practice to namespace your stuff
<Guest64> true
<Guest64> https://www.bookstack.cn/read/crystal-lang/syntax_and_semantics-macros.md i found this and things are starting to click together now. thanks again
ur5us has joined #crystal-lang
<FromGitter> <wyhaines> @guest64 -- I can give you a little example of the kinds of thing that I am talking about in a bit.
<FromGitter> <wyhaines> @guest64 -- ⏎ ⏎ ```code paste, see link``` ⏎ ⏎ You are still going to have problems with types, though, if you have a single hash that holds everything. ... [https://gitter.im/crystal-lang/crystal?at=60eb6ef5d2556414f55bc114]
ua_ has joined #crystal-lang
notzmv has quit [Ping timeout: 252 seconds]
ua_ has quit [Ping timeout: 252 seconds]
ua_ has joined #crystal-lang
ua_ has quit [Ping timeout: 268 seconds]
ua_ has joined #crystal-lang