Folks, After some experimentation, it seems that the \peek_* family of functions don't work well inside l3prg conditionals; source3.pdf seems to bear this out in the justification for \__peek_def:nnnn. On TeX.SE, Clemens Niederberger posted an answer to the specific question I'd posed; see <http://tex.stackexchange.com/a/64351/2966>. It works well, but it's built on recursive expansion of macros with :w specifiers that I'm really not understanding. I'm thinking, therefore, that I'm better off getting help implementing the functionality I want in parts. What sorts of restrictions are there on the use of \l_peek_token inside the true-code & false-code branches of the \peek_* functions? Is it reasonable to use \__peek_def:nnnn to generate something like \peek_unconditional:TF? (The false-code branch should never execute, I expect.) Actually, it's \peek_unconditional_remove:T I think I need. The general outline I'm thinking of is something like this: \tl_new:N \g_jcs_matchlist_tl \tl_new:N \g_jcs_ignorelist_tl \tl_new:N \l_jcs_ignored_tokens_tl \cs_new:Npn \jcs_peek_in_matchlist_ignore_ignorelist:TF #1#2 { \tl_clear:N \l_jcs_ignored_tokens_tl \__jcs_peek_in_matchlist_ignore_ignorelist_aux:TF #1#2 } \cs_new:Npn \__jcs_peek_in_matchlist_ignore_ignorelist_aux:TF #1#2 { \peek_unconditional_remove:T { \tl_if_in:N?TF \g_jcs_ignorelist_tl { something involving \l_peek_token } { \tl_put_right:N? \l_jcs_ignored_tokens_tl { something involving \l_peek_token } keep looking, probably by recursing } { \tl_use:N \l_jcs_ignored_tokens_tl \tl_if_in:N?TF \g_jcs_matchlistlist_tl { something involving \l_peek_token } {#1} {#2} } } } Does this sound like the correct path to head down? --Joel