Fascinating. This sounds perhaps similar in goals to http://awwx.ws/label0, though with a very different implementation.
Labels in implementation are just a hash table with weakly held references to the objects that being "labeled". The idea is that for example we could have "type" be a label that could be applied to an object and the type function would return that value when the label was present; and then (in a way somewhat similar to your idea) I could have my polymorphic functions decide to do something different with my value based on its labeled type, but the built-in Arc runtime functions continue to use it in the same way.
Where this breaks down of course is that labels can't be applied to objects such as numbers and characters that don't have a unique identity. Your approach of automatically unboxing boxed values means that we could box a number and give it a type when we wanted to.
What I like about labels is that we aren't limited to just one dimension for annotating an object like we are when using tag.
Of course, if the Arc runtime automatically unboxed values like you suggest then I could in fact store the labels with the objects themselves, and it would also work with numbers. This would make labels an extension of your idea, allowing a property list to be attached to the box instead of just a type value.
Oh, and by the way, for your interpreter: I suspect you're going to have an easier time of it if you make a meta-circular interpreter where (fn ...) evaluates to a function value. But that's just speculation, it might be better doing it your way :)