ChanServ changed the topic of #crystal-lang to: The Crystal programming language | | Fund Crystal's development: | GH: | Docs: | Gitter:
Elouin has quit [Quit: Ping timeout (120 seconds)]
Elouin has joined #crystal-lang
Starfoxxes has joined #crystal-lang
_ht has joined #crystal-lang
_ht has quit [Remote host closed the connection]
jmdaemon has quit [Ping timeout: 268 seconds]
Starfoxxes has quit [Ping timeout: 268 seconds]
Starfoxxes has joined #crystal-lang
Sankalp has quit [Ping timeout: 245 seconds]
Sankalp has joined #crystal-lang
ur5us has joined #crystal-lang
ur5us has quit [Ping timeout: 268 seconds]
Sankalp has quit [Ping timeout: 268 seconds]
ur5us has joined #crystal-lang
Sankalp has joined #crystal-lang
hightower3 has joined #crystal-lang
hightower2 has quit [Ping timeout: 252 seconds]
ur5us has quit [Ping timeout: 240 seconds]
jmdaemon has joined #crystal-lang
jmd_ has joined #crystal-lang
jmdaemon has quit [Ping timeout: 252 seconds]
<FromGitter> <plambert> I have a class like `class Foo(T); end` and I have a method like `def succ(thing : T); thing.responds_to?(:succ) ? thing.succ : thing.responds_to?(:next_float) ? thing.next_float : raise "#{thing}: does not have a succ or next_float method"; end`
<FromGitter> <plambert> Is it possible to do this with a macro, such that whatever T is, it's figured out at compile time and I'm not evaluating the conditional every time?
<FromGitter> <plambert> Or does the compiler do that optimization already?
<FromGitter> <Blacksmoke16> it wouldnt compiler it whatever `T` is doesnt have that method
<FromGitter> <Blacksmoke16> essentially duck typed
<FromGitter> <Blacksmoke16> another option would be define like two modules that have one of the methods as abstract defs. then can have a `succ` overload for each
<FromGitter> <Blacksmoke16> this approach would error because of no valid overload on the method, instead of on the method call within the method
<FromGitter> <plambert> So I can drop the check for :next_float and just do `thing.responds_to?(:succ) ? thing.succ : thing.next_float` and let the compiler tell me if I pass it something with neither of those methods?
<FromGitter> <Blacksmoke16> is `thing` going to be a custom type you define?
<FromGitter> <plambert> No, it's always some sort of Int or Float
<FromGitter> <Blacksmoke16> oh
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <Blacksmoke16> tada?
<FromGitter> <plambert> That should do the trick; the compiler will know which to use at compile time, so no performance hit. Yay!
<FromGitter> <Blacksmoke16> another option would be have a single method but use some macro code to define the body of the method based on `T`
<FromGitter> <Blacksmoke16> ```code paste, see link``` []
<FromGitter> <Blacksmoke16> something like that
<FromGitter> <plambert> I'm trying the first one. Once it works, I'll probably try to move to the second, because I like it better. :)
<FromGitter> <Blacksmoke16> might have to do like `T < Int`and `elseif T < Float` then an `else` that does like `T.raise "#{@type} only supports Int | Float types"`
<FromGitter> <plambert> Is there an equivalent of "responds_to?" in macros?
<FromGitter> <Blacksmoke16> `.has_method?` iirc
<FromGitter> <Blacksmoke16> 👍
<FromGitter> <Blacksmoke16> shouldnt really need to use `.has_method?` if you only need to support int and float types, as its define on the base type so you could just base things on the type versus checking for the method