The main point to note really is that the expl3 language was never intended for document level usage just like the internals of LaTeX2e (having @ in their names) are not supposed to show up there. Instead those languages have been developed to support package development.

Thus within a LaTeX2e package the conventions of LaTeX2e are automatically set up (which is basically @ being a letter) and within a LaTeX3 package the conventions for LaTeX3 are automatically enabled.

However, sometimes it is necessary to add/update code in the preamble of a document and recognizing this, LaTeX2e offers \makeatletter and \makeatother and LaTeX3/expl3 offers \ExplSyntaxOn and \ExplSyntaxOff. But those are for preamble usage and in general it is better to put such code into a package, which could then be reused.

So you could think of providing a command that does the necessary work for you, e.g., \boxednumbers which does everything including the matrix command, e.g.,

tikz was designed under 2e conditions and it doesn't know about expl3 conventions.

So executing tikz commands that do parsing in the middle of expl3 code is likely to cause trouble, which is why we can't simply execute \node in that loop, but instead build a line of code to be executed later. For the same reason I had to say row~ sep instead of row sep as the normal space vanishes within expl3 code.
So in summary the mix and match of 2e code with expl3 is a little tricky in places.