This has been my weekend/evening project the past 10 days or so. I compared to ksh93 (from the Ubuntu software store) wherever there weren't conflicts with zsh-native features, even managing to crash ksh93 several times in the process. Attached is the patch with the C code changes. It'd be nice, Roman, if you could run your benchmarks on this to see if I've slowed down any other shell operations. The next two patches will cover tests and documentation. When a reference is created, it's necessary to determine the scope in which to find the referenced parameter. Since a reference can name an array element, this involves separating the base parameter name from the subscript. I've overloaded the "base" and "width" fields in struct param to save both the scope (locallevel) and the offset of the subscript, to avoid having to search for the subscript again when the reference is expanded. There is a little redundant scanning to validate subscripts when the reference is created; this follows ksh93 (the alternative would be to fail at the time of expansion). One difference from ksh93 is that you can't convert scalars into namerefs, e.g., both with this and in ksh93: typeset -n foo=bar typeset +n nameref leaves behind a scalar $foo with value bar. but only in ksh93: foo=bar typeset -n foo foo=thing assigns bar=thing. In this implementation typeset -n first unsets foo, so instead of foo "pointing at" bar, it ends up "pointing at" thing. This eliminates a bunch of special cases for exported and tied parameters, etc., and it seems easy enough to write: typeset +n foo typeset -n foo=$foo if that's what you wanted. If I have a sudden inspiration I'll do a follow-up patch. Named references can't have any other attributes, and attempting to add an attribute to a named reference generates a warning. However, existing prohibited attribute changes (such as trying to turn a special scalar into an array) are fatal errors, so I've left comments wondering whether that would instead be appropriate here. With respect to zsh/param/private parameters, it's presently prohibited to have a "public" reference to a private parameter. It might be possible to change this if someone can think of a use case. There is one glitch: if the reference is created before the parameter is declared private, and the private local is NOT hiding something in an outer scope, then the reference does not retroactively generate an error and assignments to the reference are silent no-ops. I moved around a little bit of not-directly-related signal handling in params.c so that we're not calling zfree() outside of queue_signals() blocks. That makes the order of unqueue_signals() and zfree() consistent at least throughout assignsparam(). I also removed "kz" from TYPESET_OPTSTR in zsh.h -- as far as I can tell they should never have been there in the first place.