In the second case you’re using a language construct, not a command. It’s output isn’t transmitted down the pipeline in the way you’re expecting and so Sort has no input.
These are not different “forms” of the same thing. They’re two deeply different things that have the same name. Unfortunately.
The foreach in this is a language construct. The construct is not a cmdlet, and does not return a value to the pipeline. Instead, the end of the pipeline is reached inside of script block and the value it sent to the default output.