Justin Cormack wrote: > On Tue, Jun 12, 2012 at 3:27 PM, Mike Pall <mike-1206@xxxxxxxxxx> wrote: > > Well, it's not that difficult to do for the pointer case. But I'd > > rather go for parameterized types, e.g. > > > > ffi.typeof("$ *", foo_t) > > ffi.typeof("struct { $ k; $ v; }[?]", foo_t, bar_t) > > > > But I'm not sure whether the complexity is really worth it. > > > Not sure about that either - never really needed anything like that in a C > context. That's because C is statically typed. C++ added templates to overcome this limitation (somewhat). We can certainly do better in Lua. ;-) Actually, it wasn't that difficult to add parameterized types to the FFI. The feature is now in git HEAD. No docs, yet, but you can already play with it: The '$' character is the marker to be replaced with parameters in a C type declaration: * A ctype or a cdata parameter is interpreted like an anonymous typedef. You can use that to construct derived types, e.g. ffi.typeof("$*", ct) is a pointer to ct, or "$[10]" is a 10 element array. Unlike simplistic string concatenation, this works for all cases (e.g. pointers to function pointers). * A string parameter is treated like an identifier or keyword, except the string is _not_ parsed again or split into words (this isn't simple textual substitution). You can use that for field names, function names, argument names etc. [I'm pondering whether I should drop the keyword and type lookup on the string. That would allow you to use arbitrary names for fields, even when they collide with keywords or typedefs. I may change that before writing the docs.] * A number parameter is treated as an integer. You can use that to construct fixed size arrays. In some contexts you may prefer this over VLAs. It works for multi-dimensional types, too. E.g.: local matrix_t = ffi.typeof("uint8_t[$][$]", width, height) ... local m = matrix_t() Only ffi.typeof() and ffi.cdef() parse parameterized types. The other functions, e.g. ffi.new(), don't do that, because they already take other arguments (e.g. initializers). I guess it would be too confusing to mix two kinds of arguments. Anyway, parameterized types are a nice tool, but you'll want to use it sparingly! The typical scenarios where you'd use templates in C++ come to mind: e.g. construct a stack or a queue of an arbitrary type. These need to create an array of the element type, which is now really easy to do. [Justin's use case] Another example are derived types of anonymous structs. This avoids pollution of the struct namespace. [Henk's use case] I'm sure you'll come up with a lot more use cases. --Mike