I have a few requirements before implementing my next program - hopefully a programming language exists that can do the following:
The user is able to determine the number and types of arguments a function will take.
eg. foo(int a, String b, int c) can be queried
to return 3 or [int, String, int]
Are these absurd requirements or does some language implement them as basic techniques of reflection?
I know that you prefer a statically-typed language, but if you consider a dynamically-typed one Smalltalk may be a good fit, since everything is an object (classes and methods are no exception ot this rule) and thus everything can be manipulated (not only queried, but also changed). Going to your requirements:
Given a class (or interface) C, the programming language allows the user access to a list of all classes which extend/implement C.
In Smalltalk there is no built-in notion of interface (though I think that I've seen extensions that added support for it). However, you can:
Number subclasses
answers {Fraction. Float. Integer}
.Number allSubclasses
answers an OrderedCollection(Fraction Float Integer ScaledDecimal SmallInteger LargePositiveInteger LargeNegativeInteger)
You can also find all classes that implement a given selector (pop
in this case):
SystemNavigation default allClassesImplementing: #pop
answers {ContextPart. FileSystemGuide. LIFOQueue. Stack}
As you can see, defining an "Interface" object to query for classes that implement a set of methods is quite easy (just have a collection of method names and query for classes implementing each of them, adding the classes to a set). However if you want to explicitly state in the class that it implements an interface, then you'll need to do more work.
The programming language allows the user to iterate through all the variables and methods of a class.
Point instVarNames
answers #('x' 'y')
Point allMethods
answers a collection of CompiledMethod
s (the object that represents a method)
Point allSelectors
answers a collection of all the method names that an instance of that class can answer to.
The user is able to determine the number and types of arguments a function will take.
In this case you interact with compiled methods and ask them for the number of arguments they need (there is no notion of parameter type):
(Point methodNamed: #x) numArgs
answers 0, since it is just a getter.
(Point methodNamed: #+) numArgs
answers 1
This is just a small preview of the reflective capabilities of Smalltalk; if you want to go deeper you can check out some of these links:
HTH