views:

242

answers:

4

Any programming language that does not have a suitable reflection mechanism I find seriously debilitating for rapidly changing problems.

It seems with certain languages its incredible hard or not possible to do:

  • Convention over Configuration
  • Automatic Databinding
  • AOP / Meta programming

with out reflection.

Some example languages that do not have some sort of programmatic reflection are: C, C++, Haskell, OCaml. I'm sure there are plenty more.

To show you can example of DRY (Don't Repeat Yourself) being violated by most of these languages is when you have to write Unit Tests. You almost always need to register your test cases in these languages outside of where you define the test.

How do programmers of these languages mitigate this problem?

EDIT: Common languages that do have reflection for those that do not know are: C#, Java, Python, Ruby, and my personal favorite F# and Scala.

EDIT: The two common approaches it seems are code instrumentation and code generation. However I have never seen instrumentation for C.

Instead of just voting to close, could some one please comment on why this should be closed and I'll delete the post.

+1  A: 

One nice example for C++ unit testing is cxxtest: http://cxxtest.tigris.org/. It uses convention and a python script to generate your C++ test suite by post-processing your C++ with python.

A good way to think about getting around restrictions in languages is Michael Feathers' notion of "seams". A seam is a place where your program can be changed without changing the code. For example, in C the pre-processor and linker provide seams. In C++ polymorphism is another place. In more dynamic languages like where you can change method definitions, or reflect, you get even more flexibility. Without the seams things can be more complicated and sometimes you just don't want to try to hammer a nail with your shoe but rather go with the flow of the tool at hand.

Paul Rubel
@paulrubel I get a feeling that preprocessing is what these languages do. Some people think reflection is code smell. I think preprocessing is far worse. +1 for the link
Adam Gent
The thing that saves the day here is that the results of the python script are regenerated each time they are needed, it's not like a wizard where you keep the generated code around and need to modify it.
Paul Rubel
@paulrubel Ill have to check out "seams". I wish I could give you another +1 for your excellent edit.
Adam Gent
@Adam: Preprocessing worse than reflection? But where does reflection data come from? Preprocessing.
Zan Lynx
@Zan Lynx I might be missing something but I mean compiler preprocessing like the C Pre Processor. I guess what you are saying is the compiler adds meta data to the type (ie reified types) could be counted as preprocessing.
Adam Gent
@Adam: Yes, exactly. In C/C++ it is still *called* a preprocessor but all compilers I know of integrate that into the compiler so it isn't really "pre" anything. So I would rate Java's reflection generation as being at the same processing stage.
Zan Lynx
+2  A: 

I think it's a matter of degree. Reflection is just one very powerful method of avoiding repetition.

Any time you generalize a function from a specific case you are using DRY principle, the more general you make it the more DRY it is. Just because some languages don't get you where you get with reflection doesn't mean there aren't DRY ways of programming with them. They may not be as DRY, but that doesn't mean they don't have their own unique advantages which in total sum may outweigh the advantages of using a language that has reflection. (For example, speed consequences from heavy use of reflection could be a consideration.)

Also, one method of getting something like the DRY benefits of reflection with a language that doesn't support it is by using a good code-generation tool. In that case you modify the code for different cases once, in the code generation template, and the template pushes it out to different instances in code. (I'm not saying whether or not using code generation is a good thing, but with a good "active" generator it is certainly one way of getting something like the DRY benefit of reflection in a language that doesn't have reflection. And the benefits of code generation go beyond this simple benefit. I'm thinking of something like CodeSmith, although there are many others: http://www.codesmithtools.com/ )

Herbert Sitz
+3  A: 
tstenner
Unfortunately that doesn't fix the Unit Test problem. +1 for the answer
Adam Gent
+2  A: 
  1. Abstractly, do more at runtime, without the benefits of things like compile-time type checking (you have to essentially write your own type-checking routines) and beautiful code. E.g., use a table instead of a class. (But if you did this, why not use a dynamically-typed language instead?) This is often bad. I do not recommend this.

  2. In C++, generic programming techniques allow you to programmatically include members of a class (is that what you want to do?) via inheritance.

apollodude217
Aye. Option 1 is essentially applying the old "Anything can be solved with another level of indirection." maxim.
caf