Can anyone explain from a language/environment agnostic perspective the difference between these two notions?
Also is there a set of conditions that programming languages need to satisfy in order to be reflective and/or introspective?
And if there is, what are these conditions?
The Wikipedia article has a pretty decent summary:
In computing, type introspection is the ability of a program to examine the type or properties of an object at runtime. Some programming languages possess this capability.
Introspection should not be confused with reflection, which goes a step further and is the ability for a program to manipulate the values, meta-data, properties and/or functions of an object at runtime. Some programming languages, e.g. Java, also possess that capability.
Take a statically typed, compiled program:
SomeType function foo(int i) {
return new SomeType(i);
}
All the types are known and enforced at compile time, the program shouldn't even compile if it doesn't satisfy its own explicit type constraints. Dynamic programming languages don't typically exhibit this kind of rigidness, the types of variables aren't necessarily known at compile time. They may look more like this:
function foo(i) {
return new SomeType(i);
}
The function can't guarantee what i
is exactly, it's just passing it through. That may or may not cause problems somewhere, the type system can't help here. This kind of error checking is then typically relegated to userland code, for which such code needs introspection capabilities:
function foo(i) {
if (!is_int(i)) {
throw new InvalidArgumentException;
}
return new SomeType(i);
}
Where exactly to draw the line between introspection and reflection is somewhat debatable. One may say introspection is anything that allows code to test what something is ("What am I?"), whereas reflection is the ability to manipulate the program structure itself. For instance, a PHP example:
$ref = new ReflectionClass('Foo');
$foo = $ref->newInstanceWithoutConstructor();
The above code circumvents running the constructor of class Foo
when creating a new instance of it. That's code manipulation at runtime. In practice though, the reflection API in PHP also contains introspection capabilities. Some of these capabilities are a duplicate of what can be done with "lower" introspection capabilities. E.g.:
$ref = new ReflectionClass($obj);
if ($ref->getName() == 'Foo') ...
if ($obj instanceof Foo) ...
Both snippets essentially do the same thing, but one uses reflection and the other what would be called introspection. As you see, there's hardly a clear dividing line. However, reflection is typically more powerful than introspection. For instance, in PHP you have to use the reflection API to get information about the types of arguments a function accepts. That's just "passive" introspection, but belongs to the reflection API. This is mostly a matter of practical implementation though.
In short, by the general definition, to be introspective a program needs to be able to examine parts of itself at runtime and execute different code based on this information. A reflective program beyond that can change its own code execution rules at runtime, for example opting not to invoke a constructor, which is otherwise a mandatory operation as defined by the language.