Learning by Teaching

Docendo discimus or Learning by Teaching, is one of good method to improve yourself (or at least, myself).

Learning by teaching gives you better experience, knowledge and skills, and can be very useful, compared to learning by yourself or from other. It is because in order to teach someone, you will need to know the answer from the problem beforehand, or at least has an expertise in the case. Also, teaching requires you to be able to explain the method correctly and presenting the knowledge. In other words, converting Tacit Knowledge to Explicit Knowledge. Not other than that, you must proof your knowledge and defend it from any disagreements.

Has an Expertise in the Case

You cannot teach or giving knowledge if you do not has an expertise in the case. Some exceptions may be for seniority or positional power, but it is another topic. It means that if you already can teach, you already has some level of expertise in the case. It is a good indicator to measure yourself.

If you need to teach, answering question or giving knowledge, it means that you need to know the field and becoming an expert at that field too. It forces you to learn. Even when teaching or after that (evaluation) you can still learning from your teaching. It is a very good improvement.

Able to Explain

Sherlock Holmes said once in his book Study in Scarlet, It was easier to know it than to explain why I know it. If you were asked to prove that two and two made four, you might find some difficulty, and yet you are quite sure of the fact. It is not an easy thing to explain something that you know and most of the time, it is easier for you to understand it yourself.

That is one of good reason why learning by explaining is better than learning by yourself. If you already can teach or explaining the knowledge, it means that you already have the knowledge in a good level. If you do not know the knowledge itself, how can you explain it?

Defend from any Disagreement

Disagreement may comes from other source. The worst type of disagreement by comes from those who has better expertise in the fields (someone that has been respected as masters, such as Martin Fowler for OOP design). In order to prove that your knowledge is correct (or at least acceptable), you must have some ability to protect it from any disagreements. (well in this case, I don't want to mention the worst type of agreement in an organization, that is disagreement from people who has the power, and the disagreement comes from their taste themselves)

Some published books are good to be referenced as sources. Because if you cannot explain the knowledge well, or cannot defend it, you can use the reference as your shield. Published book is good because it is well written, mostly easy to understand and accepted by most people. Moreover, it is written by experts in the fields, improving the correctness (as described in the first point here). The authors itself, is already at a level that is able to defend their statements from disagreements.

Don't worry if you find that your statements cannot be protected. It means that you still need to learn. Moreover, you can learn from the disagreement as the starting point, and begin research from it. At the moment you know the facts that can be used to defend it, you begin to make statements again, and the process iterated itself. It only means that whether your statement can be protected or not, it has learning process in it, and it is good.

Conclusion

Learning by teaching is a good thing to do to improve yourself. Most of the time, you need to do some other types of learning before teaching, so it only leads to some process of learning.

Programming Idealism, Avoiding Hungarian Notation

Hungarian Notation

From wikipedia, hungarian notation is an identifier naming convention in computer programming, in which the name of a variable or function indicates its type or intended use. There are two types of Hungarian notation: Systems Hungarian notation and Apps Hungarian notation.
System Hungarian is intended to emphasize the variable's type. It is extremely useful in interpret / dynamic language such as javascript or php, and useless at all in static programming language. Especially in compiled oop language such as Java and C#, where data contract and type casting is the major problem, it has no benefit at all.
Apps Hungarian is intended to describe the functionality of given variable, regardless of it's type. As Joel Spoolsky has been explained in his article, there are some variable that is prone to error, even though already has compiled-type checking. One of his example is between unsafe and safe string (encoded html tags for example), in which the type is same but serve different purpose.
The article is posted at 2005. It means it already there for more than 7 years around. Given current ability of compiler and programming language, what can we do to improve the design?

Problem

There lies one and only one problem in Joel's solution, that is the code can still pass compilation phase. As stated by Mark Seeman in his article, faster feedback means less costs to correct errors. Ideally, it is the best when we can get all the system's error during compilation phase, but it mostly impossible for some reasons (such as parsing error or business rule error, in which cannot be caught by compiler). In short, you need to create compile error as much as possible to catch wrong code, rather than getting run time exceptions.

The Proposed Design

Using Joel's example for safe and unsafe string, we need to create a design where we can handle safe and unsafe string which can give compile error. By using C# syntax, as usual for oop language, first I define some classes. The class is for unsafe string.

public class DecodedHtmlString
{
    public DecodedHtmlString(string decodedString)
    {
        this.decodedString = decodedString;
    }

    private string decodedString;
    public override string ToString()
    {
        return decodedString;
    }
}

Simple enough. It gives no benefit but gives you a self-documenting data type. The class represent a html string in a decoded way, and no encoding happen here. Next, for the safe (encoded string).

public class EncodedHtmlString
{
    public EncodedHtmlString(DecodedHtmlString decodedString)
    {
        this.encodedString = System.Web.HttpUtility.HtmlEncode(decodedString.ToString());
    }

    private string encodedString;
    public override string ToString()
    {
        return encodedString;
    }
}

Again, a self explaining class accepting encoded string from a decoded string. Now we want to make both of the classes communicate each other. We have several options such as type casting or static parsing, which is easy enough in C# that I won't explain. In here I will do constructor injection and To type casting instead. For the DecodedHtmlString, we add a constructor and ToEncodedHtmlString method:

    public DecodedHtmlString(EncodedHtmlString encodedString)
    {
        this.decodedString = System.Web.HttpUtility.HtmlDecode(encodedString.ToString());
    }
    public EncodedHtmlString ToEncodedHtmlString()
    {
        return new EncodedHtmlString(this);
    }

And for the EncodedHtmlString side:

    public static EncodedHtmlString FromEncodedString(string encodedString)
    {
        EncodedHtmlString result = new EncodedHtmlString();
        result.encodedString = encodedString;
    }
    public DecodedHtmlString ToDecodedHtmlString()
    {
        return new DecodedHtmlString(this);
    }

Consumer

Let's see from consumer point of view:

string unsafeString = Request.Forms["CUSTOM_INPUT"]; // input from form
string safeString = System.Web.HttpUtility.HtmlEncode(unsafeString); // encoded safe string for reference
DecodedHtmlString decoded;
EncodedHtmlString encoded;

// initial creation
decoded = new DecodedHtmlString(unsafeString); // correct
encoded = EncodedHtmlString.FromEncodedString(safeString); //correct

// type casting
encoded = decoded.ToEncodedHtmlString(); // correct
encoded = new EncodedHtmlString(decoded); // also correct
decoded = encoded.ToDecodedHtmlString(); // correct
decoded = new DecodedHtmlString(encoded); // also correct

// wrong initial creation
decoded = new DecodedHtmlString(safeString); // wrong
encoded = EncodedHtmlString.FromEncodedString(unsafeString); //wrong

// to primitive
unsafeString = decoded.ToString(); // correct
safeString = encoded.ToString(); // correct

// wrong to primitive
unsafeString = encoded.ToString(); // wrong
safeString = decoded.ToString(); // wrong

We got 4 possible wrong code, that is from primitive and to primitive parameter assignment, and for other scenarios it is correct. Now let's see whether we can exploit the data type validation with parameter accepting data type.

public void WriteToDatabase(EncodedHtmlString encoded)
{
    string encodedString = encoded.ToString();
    // doing with encodedString
}

WriteToDatabase(unsafeString); // compile error
WriteToDatabase(safeString); // compile error
WriteToDatabase(decoded); // compile error
WriteToDatabase(encoded); // correct

Now we got 3 compile error and one correct code. If you favor to get a compile error, it is an improvement since now you can protect myself from 3 possible parameter assignment errors. And if you carefully using the two data types instead of passing from primitive string, it will be fine. The only two things that can pass the compile error is when casting to primitive, or from primitive.

But hey, isn't most of the operation (at least safe and unsafe string) is using primitive type? If we take account Response.Write and Database operations, it is very clear that most of the critical operation is using primitive type. (even for url, etc). Moreover, we add 2 more classes for this design.

Conclusion

We can get the design where we will receive compile error instead of run time error or buggy code. However, we still cannot get one hundred percent buggy-code free with this design, and most of the operations are error-prone here. Additionally, it introduces two dependent classes as well, making it more tight coupling.

In the end, it is still the framework's support that do the decide. If the framework support the Encoded and Decoded datatype by default, and suggesting you to use the datatype instead of primitives, maybe it is worth it. However, with current framework design, it is very unlikely for this design to give decent benefit.