Coming from Siemens or Modicon, the first shock of Logix is what's missing: there are no %I0.0 addresses anywhere. Every value is a named tag with a data type. The only question that matters is scope โ is this tag controller-wide, or private to one program? Get scope right and your programs never step on each other.
Two programs โ Infeed and Palletizer โ each with their own tags, plus a controller-scoped pool everyone shares. Switch the view to a program and watch which tags it can actually reach: its own program-scoped tags and every controller tag, but never the other program's private tags. That's why both can safely own a tag called Step.
Switch to Palletizer and notice its Step is a different tag from Infeed's Step โ same name, separate memory, zero conflict. Controller tags (LineSpeed, EStop_OK, all I/O) stay visible to both. Encapsulation without a single address.
A tag's data type decides what it holds. Beyond the atomics, Logix has predefined structures (a TIMER is a tag with .ACC, .PRE, .DN members) and you build your own with UDTs.
An alias tag is Logix's nod to readability: StartPB can alias Local:1:I.Data.0 so your rungs read in plain English while still pointing at real I/O. The tag database, not an address map, is the heart of the program.
Two programs each declare a program-scoped tag named Step. Is that a problem?