As I said, it is a common misconception, but you do not get direct access to the table you just created in this case. Ets sets up a process which manages the table and all manipulations on this table go through messages to that process. It's all nicely wrapped behind an API that hides these messages, but they are there nevertheless. A value that has to be obtained via message passing is not a global value. There is code in the way that is controlling access, verifying legality, and in general it compiles to a whole array of stuff, as opposed to the true global variable case which can be represented by one memory save.
You have to be careful to think about this clearly. The defining characteristic of a true global is not that it can be obtained in some manner from everywhere in the program; by that standard even in Haskell everything's global, as there exists some organization of the program that would permit access of a given value from everywhere (though it would be one hell of a bastardized program). The characteristics are that everybody has direct, simultaneous access. If "ets" tables qualify as "global variables", then so do values sitting on a MySQL server; in erlang the difference between a MySQL value and an ETS value is pretty minimal, you access both via message passing. This is not a useful definition of "global value".
Now, it may still turn out that even with this level of access, it is "too free" and still subject to a reduced amount of the pain that global variables can bring. Haskell is a constructive example of a language that implicitly makes that argument and further distinguishes this case. But we don't benefit from failing to discriminate between a managed value that the manager permits anything to access the gate (albeit still in a managed fashion), and a completely unmanaged global value. They do have some similarities, but nevertheless, managed variables are nowhere near as bad as truly global variables.
If you're not careful and you come at this with fuzzy enough thinking, you'll end up spinning yourself into a tizzy where everything's the same. In fact what the situation is is that there's tens or hundreds of ever-so-slightly different cases and terms that try to cross the language barriers often have some issue, but there's still some broad patterns we can find, and if you find yourself just smooshing them all together you're going to find it hard to pick the right tool for the right job.
The point is that with the named_table option, you don't need the tid of the table to access it, you can just use the name. Which makes it a global entry point. It doesn't matter if it requires messages to make it happen, it is still an implicit dependency. The same applies to named processes, etc.
Because of that you can write this code (to piggyback on the example you are responding to):
foo(Key) ->
ets:member(global_state, Key).
Instead of:
foo(Tid, Key) ->
ets:member(Tid, Key).
In the second case, all dependencies are explicit, in the first case, there is a dependency on the atom global_state being the name of the table you are accessing.
You have to be careful to think about this clearly. The defining characteristic of a true global is not that it can be obtained in some manner from everywhere in the program; by that standard even in Haskell everything's global, as there exists some organization of the program that would permit access of a given value from everywhere (though it would be one hell of a bastardized program). The characteristics are that everybody has direct, simultaneous access. If "ets" tables qualify as "global variables", then so do values sitting on a MySQL server; in erlang the difference between a MySQL value and an ETS value is pretty minimal, you access both via message passing. This is not a useful definition of "global value".
Now, it may still turn out that even with this level of access, it is "too free" and still subject to a reduced amount of the pain that global variables can bring. Haskell is a constructive example of a language that implicitly makes that argument and further distinguishes this case. But we don't benefit from failing to discriminate between a managed value that the manager permits anything to access the gate (albeit still in a managed fashion), and a completely unmanaged global value. They do have some similarities, but nevertheless, managed variables are nowhere near as bad as truly global variables.
If you're not careful and you come at this with fuzzy enough thinking, you'll end up spinning yourself into a tizzy where everything's the same. In fact what the situation is is that there's tens or hundreds of ever-so-slightly different cases and terms that try to cross the language barriers often have some issue, but there's still some broad patterns we can find, and if you find yourself just smooshing them all together you're going to find it hard to pick the right tool for the right job.