<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> 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> 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> 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>
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.
<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?
<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>
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