Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can you be DRY with a programming language that doesn't have Reflection? [closed]

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.

like image 989
Adam Gent Avatar asked Jun 28 '10 17:06

Adam Gent


3 Answers

You don't.
But you can keep the repetitions close to each other so when changing something, you see something else has to be changed too.

For example, I wrote a JSON-Parser that outputs objects, a typical call looks like this:

struct SomeStruct
{
        int a;
        int b;
        double c;

        typedef int serializable;
        template<class SerializerT> void serialize(SerializerT& s)
        {
                s("a",a)("b",b)("c",c);
        }
};

Sure, when you add a field, you have to add another field in the function, but maybe you don't want to serialize that field (something you'd have to handle in languages with reflection, too), and if you delete a field without removing it from the function, the compiler will complain.

like image 103
tstenner Avatar answered Sep 20 '22 20:09

tstenner


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/ )

like image 40
Herbert Sitz Avatar answered Sep 20 '22 20:09

Herbert Sitz


  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.

like image 32
jyoungdev Avatar answered Sep 24 '22 20:09

jyoungdev