Reflection
Reflection in Klyn starts with type(...) and expands into metadata about members,
inheritance, annotations, generics, and more. This is especially useful for tooling, tests, and
framework-style code.
Type
import klyn.math
r = Rational(1, 3)
metadata = type(r)
print(metadata.name)
print(metadata.fullName)
interface Worker:
public run() as Void
metadata = type(Worker)
assert metadata.isInterface
assert metadata.isAbstract
Reflection exposes whether a type is public, abstract, final, native, an interface, an enum, or an annotation.
import klyn.math
metadata = type(Rational(1, 3))
attrs = metadata.getAttributes()
props = metadata.getProperties()
methods = metadata.getMethods()
You can inspect declared members, retrieve a member by name, and choose whether inherited members should be included.
import klyn.reflection
method = Application.type.getMethod("time")
if method is Invocable<Object>:
result = method.invoke([] as Object[])
print(result)
Invocable<R> is the common reflection-level contract for functions obtained
dynamically, methods, and constructors. Its arguments use Object[] because their
signature is runtime metadata. For ordinary callbacks and lambda parameters, prefer the complete
structural form (P1, P2) -> R, which the compiler can validate statically. The two
models are intentionally distinct and no implicit conversion erases a structural signature into
an Invocable<R>.
class CredentialSink:
public writeonly property credential as String
sink = CredentialSink()
property = type(sink).getProperty("credential")
assert property.isWriteonly
assert not property.isReadonly
property.setValue(sink, "temporary secret")
Reflected properties preserve their source contract. isReadonly identifies a
getter-only property and isWriteonly identifies a setter-only property. Calling
setValue() on a readonly property or getValue() on a write-only property
raises TypeError; reflection never bypasses accessor visibility.
import klyn.collections
metadata = type(List<Int>)
print(metadata.isGenericInstantiation)
print(metadata.genericParameterCount)
print(metadata.genericParameterNames())
annotation Audited:
pass
metadata = type(Audited)
print(metadata.isAnnotation)
Reflection can also expose annotations attached to types and members, which is how test frameworks and metadata-driven tooling discover annotated declarations.