I seem to have been beaten to my explanation here, but I feel like I can expand a little. Cycles is designed to be an OSL-capable Monte Carlo renderer; it takes as long as it has to to output layers of specified quality, and takes everything in the scene (usually) into account to do this. This means that determining an RGB value for a particular closure requires an entire rendering of all items to be sure about—and it would mean that it would need to be that for every single ray.
In theory, you actually could do this, but no one would—this would be the gross number of individual rays contacting the material in question, multiplied by the time to render the rest of the scene anyway (and if it's glossy or translucent and might self-reflect, for all I know the sun would explode before that render finished). This is why for OSL-like closures, data can go in, but it can't come out until the material program has already been run. It's just impractical, and the quality bonus would be dwarfed by the amount of time taken.
However, Eevee isn't a true ray tracer. It's rasterization based. This is why it can render so incredibly quickly, actually; and final RGB color doesn't entirely rely on knowledge of the environment around the element. For this reason, given that Eevee renders images about a dozen times faster than Cycles, and that detailed environmental knowledge isn't usually necessary for Eevee to determine an RGB value, the notion of running a closure and outputting an RGB vector has been opened up. It's now, at least relatively, trivial; if you don't mind breaking compatibility with Cycles or (I think) Octane later.
I still feel that it's almost always more efficient to reference what you need of the color before you stuff it into the BSDF closure, but hey, everybody's on some kind of a deadline and sometimes the simplicity is worth it. It still effectively requires a rendering, it's just happening within your shader now instead of exclusively after it.