I do not really understand your question, and I still wonder what a "abstruct" from your other thread is.
But do you know that you can use typedesc as proc parameters? So you can declare class methods or static methods as known from other languages like Python, see
https://forum.nim-lang.org/t/5331
If that does not help maybe you can explain in more detail what you really need for what.
Yes! I know it.
I will explain the detail. I want to make an object that have data and do some operation among these data. These data and operation should be settable by user. For example, the following code will do such thing, i.e. proc f in S can be set any function like +, *, min, max.
type S =
a, b:int
f: proc(x, y:int):int
proc do_operation(s:S):int = s.f(s.a, s.b)
var s = S(a:3, b:4, f:proc(x, y:int):int=x+y)
echo s.do_operation()
Then, I wonder if the proc f can be static. If we can, the operation may be fast. I assume the proc may be called huge number of times. So, I asked above question.
Also, I want these class with generics. (I wrote it as "abstrut". But I may misunderstand the word abstruct)
I hope you will understand.
When you use callbacks like
type S2[T;F:static[proc(a:T, b:T):T]] = object # can be defined
discard
The slowness is if those callback are actually closure that would be dynamically allocated. Instead you can ensure that the call is from a proc that is statically defined elsewhere with the {.nimcall.} pragma (or {.cdecl.} if accessible from C).
type S2[T;F: proc(a:T, b:T):T {.nimcall.}] = object # can be defined
discard
Alternatively, use inline templates like mapIt, filterIt and friends from sequtils https://nim-lang.org/docs/sequtils.html#18
Thanks! Then, I can define object S2 and call it. But I cannot call the static function...
type S2[T;F:proc(a:T, b:T):T {.nimcall.} ] = object # can be defined
discard
var s2 = S2[int,f]() # can be defined
echo s2.f(3, 4) # cannot call
Associated types/statics must use the shorthand from the type declaration like
type S2[T;F:proc(a:T, b:T):T {.nimcall.} ] = object # can be defined
discard
var s2 = S2[int,f]() # can be defined
echo s2.T # Returns int
echo s2.F(3, 4) # should return your proc, but that's an untested codepath
That said, even I who tried a lot of crazy things with generics and static didn't try to use static procs so here be dragons.
Just use
type S2[T] = object
discard
type Callback[T] = proc(a, b: T): T
This is intriguing, I had to have a play with the dragon.
type
S[F:static[proc(a,b:int):int{.nimcall.}]] = object
proc fadd(a,b:int):int{.nimcall.} = a+b
proc fmul(a,b:int):int{.nimcall.} = a*b
type
Sadd =S[fadd]
#Smul =S[(a,b)=>a*b] nope, has to be static
Smul = S[fmul]
proc go[T](x:S[T],a,b:int):int = (T)(a,b)
var x=Sadd()
var y=Smul()
echo x.go(3,4)
echo y.go(3,4)
I am not helping.@shirleyquirk
Yeah! I know that static proc without generics is barely possible. I want to try such kind of modification with generics like the following. For now, static[auto] (although which is not using generics) is temporal solution. This is also dragon...
nim
type
S[T;F:static[proc(a,b:T):T{.nimcall.}]] = object
proc fadd(a,b:int):int{.nimcall.} = a+b
proc fmul(a,b:int):int{.nimcall.} = a*b
type
Sadd =S[int, fadd]
#Smul =S[(a,b)=>a*b] nope, has to be static
Smul = S[int, fmul]
proc go[T, F](x:S[T, F],a,b:int):int = (F)(a,b)
var x=Sadd()
var y=Smul()
echo x.go(3,4)
echo y.go(3,4)