Make typeof a builtin [Was: incorrectly flagging bad use?]
bug.myr:5: x used before definition [1]
use std
const main = {
var x
std.put("{}", std.typeof(x))
x = 1
std.exit(x)
}
This is actually an error I saw when running mbld test on the std lib and the fmt tests failed to compile. I think you might have already known about this to some degree.
This is correct -- std.typeof() is a hacky function defined in lib/std/introspect.myr, not a builtin. So the compiler has no way of knowing it never reads from 'x', which means that the flagging is correct.
typeof() should probably be converted to a builtin.
All the type definitions in std should maybe move to a new builtin package in that case. I'll look at the code and see if I can manage this change.
Not entirely sure what changes you're suggesting here, honestly.
Right now, the whole introspection api is a turd, though -- it's the thing I'm least happy with in libstd, so if you've got a good idea of what it should look like and what the implementation should be, I'd be happy to see major changes to make it not suck.
The problems, as I see them:
- You need dummy variables everywhere to use it.
- There is no good way to iterate what a value contains, you basically need to roll your own parallel iteration on top of std.introspect and the varargs api.
- The code is ugly.
What I meant was:
- make typeof a keyword and a node type in the compiler (I just noticed you have typesof(@)).
- break the dependency of the typeof node on std.typedesc by making a new package which just contains the typedesc union. (You mentioned you didn't want the compiler to depend on std).
Ok. So, that's close to what I was thinking, but I don't think std.Ty___ need to be built in.
The thing that's happening right now with typesof() is that it's a varargs function (it's defined in the same file, just read a bit farther down). Right now, the only compiler involvement with type descriptions is injecting the hidden argument into the variadic argument list.
So, to recap: Varargs functions look like this, as far as ABI is concerned:
const varfunc : (__hidden_type_description : byte#, args : @t1, on : @t2, stack : @t3, -> ...)
The hidden type description is for a tuple of all the function args, so typeof() takes the tuple description returned by typesof(), and returns the first tuple element.
This can mostly remain the same, just with a typeof() (or typedesc, or whatever) operator that directly evaluates to the type description.
The other thing that I think might be worth doing is thinking about unifying the varargs API and the introspection API, so that the values inside a type can be walked over, but that's a separate task.