Static Checker for Immutability in Kotlin

An immutable object is an object whose state cannot be modified after it is created. Immutable objects have several desirable properties, of which the two most important ones relevant to this post are:

  • They are inherently thread-safe: being read-only, they can be accessed safely from separate threads without having to worry about unexpected state or overwriting changes.
  • They can act as value objects: two value objects created equal should remain equal, which is guaranteed when they are unable to change state.

Therefore, it is common to implement objects as immutable, and software frameworks may require/expect polymorphic objects passed to their APIs to be immutable. Unfortunately, correctly implementing an object as immutable relies on the developer’s expertise in most mainstream OOP languages (it cannot be enforced by the programming language).

Data classes in Kotlin certainly simplify creating value objects: an equals, hashCode, and copy function are automatically generated. However, data classes are not immutable by default! Kotlin still allows defining var members on data classes, and adding members of mutable types.

True guarantees for immutability would have to be baked in to the programming language/compiler, or verified using a static checker. While proposals to support immutability in Kotlin exist, a fully functional static checker for Kotlin is already available—detekt.

Detekt contains a rule out of the box to verify whether all members in data classes are specified as val, but does not verify whether those members are immutable types. Furthermore, not all immutable objects should necessarily be implemented as data classes, and there might be cases in which mutability in data classes is desirable.

Having a need to enforce developers that extend base types in a framework I am working on as immutable and/or as data classes, I implemented a detekt plugin which enables verifying whether concrete classes are implemented as specified according to annotations applied to base types (e.g., @Immutable and @ImplementAsDataClass).

For example, the following implementation will warn NotImmutable is not implemented as immutable when running the static checker since Mutable.foobar is specified as var:

class Mutable( var foobar: Int ) 

class NotImmutable( val mutable: Mutable ) : Base

interface Base

The plugin is definitely not complete yet, in that it does not verify all cases which may be mutable, but it already catches a majority of errors and as an open-source contribution on GitHub I hope other might take an interest and contribute to the project.

List of Strongly-Typed Objects Acting Like Enum in Kotlin

Suppose you have a list of object instances (Kotlin’s concept for singleton classes) that are logically related to one another and you therefore want to group them together, but also want to provide direct (non-index- or iterator-based) access to them, similar to how you access an enum.

How would you go about doing that in Kotlin?

As an example, take the following DataType interface and implementing object Geolocation:

interface DataType { val typeName: String }

object GeolocationType : DataType
    override val typeName: String = "geolocation"

    fun create( longitude: Double, latitude: Double ) =
        Pair( longitude, latitude )

Imagine many more DataType‘s: WeightType, StepcountType, etc. Now you want to provide a list of SupportedTypes containing all the types your codebase supports, but you also want to provide direct access to that list, so that the create() method (and other potential type-specific members) for Geolocation can be called.

While enums in Kotlin are fairly powerful—they largely behave like normal classes and can implement interfaces—they do not support generic type parameters and (as far as I could figure out) enum values cannot be instantiated based on existing instances. You could let the enum implement the interface of the instances you want to represent and override all methods redirecting them to the wrapped instance, but:

  • This introduces an intermediate instance, which might not be desirable for equality checking.
  • Does not provide access to type-specific members, such as create() in the example given.
  • Leads to heavy code bloat which is no fun to maintain.
enum class SupportedTypes : DataType
        override val typeName = GeolocationType.typeName

        // This method can't be accessed!
        fun create( longitude: Double, latitude: Double ) =
            GeolocationType.create( longitude, latitude )

Instead, I opted to create the following base class …

open class EnumObjectList<T>
    private constructor( private val list: MutableList<T> ) :
    List<T> by list
    constructor() : this( mutableListOf() )

    protected fun <TAdd : T> add( item: TAdd ): TAdd =
        item.also { list.add( it ) }

.. and use it as follows:

object SupportedTypes : EnumObjectList<DataType>()
    val GEOLOCATION = add( GeolocationType )

This now allows to iterate all supported types, just like enums or a list, but also to get the full type information (including generics) when accessing the member directly:

val supportedTypeNames = { it.typeName }

val data = SupportedTypes.GEOLOCATION.create( 42.0, 42.0 )

For a real-world use case, which this simplified example was based on, check out PhoneSensorMeasure.SamplingSchemes in the project for which I introduced this base class.

Non-generic Wrapper instead of Base Class or Interface

A common solution to treating a generic type as non-generic is to implement an interface or make the generic type extend from a non-generic base class. Among other reasons, this allows you to instantiate a collection of generic types. There are varying implementations of this pattern, but they all seem to share this common strategy. In this article I present an alternate approach favoring composition over inheritance which I argue is more appropriate in circumstances where the intent is to break type safety.

To clarify, I will follow Steven Lowe’s argumentation on misuse of inheritanceSemantically, the statement “SomeType<T> is SomeType” is not always true; SomeType<T> is not a proper subtype of SomeType when the base type exposes type-specific bits (as Jon Skeet puts it). In this case the extending type imposes more restrictions than the base type. When there is a need to expose type-specific bits (implying type casts are involved), using inheritance does not follow the Liskov substitution principle (LSP). Regardless, such subtypes seem common. Just consider Microsoft’s List<T> implementing a non-generic IList which to quote Eric Lippert, “is a bit odd, since List for any type other than object does not fulfill the full contract of IList”.

From this it becomes clear there are real-world scenarios where a generic type needs to be accessed in a non-generic way (e.g. during reflection as I argued previously). Type safety is temporarily broken, leaving it is up to the caller to guarantee only the correct types are used. How then to improve on the following common implementation? Note that since the non-generic interface is implemented explicitly, the caller consciously needs to cast to ISomeType, somewhat alleviating the problem of possible misuse.

public interface ISomeType
    object Value { get; set; }

public class SomeType<T> : ISomeType
    public T Value { get; set; }

    // Explicit implementation (cast to ISomeType needed to be used).
    object ISomeType.Value
        get { return this.Value; }
        set { this.Value = (T)value; }

We need a non-generic interface but are given a generic interface, so why not apply the adapter pattern?

An adapter helps two incompatible interfaces to work together. […] Interfaces may be incompatible but the inner functionality should suit the need.

Since the class we are trying to create an adapter for is generic, our adapter implementation needs to be generic too. However, we can expose the non-generic interface which will be used by the client. Just like a usual adapter, the non-generic wrapper contains the adaptee and refers all of the IAdaptor calls to it, casting to T where necessary.

public interface IAdaptor
    object Value { get; set; }

class NonGenericWrapper<T> : IAdaptor
    private readonly Adaptee<T> _adaptee;

    public NonGenericWrapper(Adaptee<T> adaptee)
        _adaptee = adaptee;

    public object Value
        get { return _adaptee.Value; }
        set { _adaptee.Value = (T) value; }

Furthermore, to facilitate the creation of this non-generic wrapper (and in addition hiding its implementation) the wrapper can optionally be initialized from within the adaptee and added as a member. This approach seems similar to how user interface controls in .NET expose the window handle they operate on as a member variable, allowing for unsafe operations when the control class does not offer the required functionality.

public class Adaptee<T>
    public T Value { get; set; }

    public IAdaptor NonGeneric { get; private set; }

    public Adaptee()
        NonGeneric = new NonGenericWrapper<T>(this);
Pattern which can be used to expose a non-generic interface from within a generic class.
Pattern which can be used to expose a non-generic interface from within a generic class.

This approach still requires boiler-plate code to be written and maintained (NonGenericWrapper<T>), but no longer breaks the Liskov substitution principle. Ideally creating non-generic wrappers can be automated, of which I created an early prototypical solution before (not functional in all scenarios). Until then, this solution provides a more robust implementation for complex scenarios using generics, like collections of generic types with varying type parameters on which the same operations need to be performed. This might be the topic of a future post.

Generic TypeConverter for XAML

TypeConverter‘s in WPF are part of the underlying mechanism which allow you to assign values to attributes of complex types within XAML using plain strings. For example, whenever you specify Point‘s.

<LinearGradientBrush StartPoint="0,0" EndPoint="1,1" />

Typically, you specify a TypeConverter for a certain type by applying the TypeConverterAttribute to it.

[TypeConverterAttribute( typeof( PointConverter ) )]
public struct Point : IFormattable

Since attribute arguments cannot use type parameters, this prevents you from specifying a generic TypeConverter for a generic class. I came across this issue while implementing a type converter to support specifying instances of my generic Interval class from XAML. The following is not possible.

// attribute argument cannot use type parameters
[TypeConverter( typeof( IntervalTypeConverter<T, TSize> ) )]
public class Interval<T, TSize>

However, you can write a non-generic TypeConverter which is capable of converting strings to several different target types. When using XAML you can obtain a IDestinationTypeProvider service through the context which is passed to the ConvertFrom method. From here you can retrieve the fully specified target type, including generic type parameters. Through reflection you can then call a Parse method on the specific type to take care of initializing an instance of the desired type. An example for Interval can be found in my library.

public override object ConvertFrom(
    ITypeDescriptorContext context,
    CultureInfo culture,
    object value )
    var typeProvider =
      (IDestinationTypeProvider)context.GetService( typeof( IDestinationTypeProvider ) );
    Type targetType = typeProvider.GetDestinationType();

    // ... convert to desired target type using a parsing method

    return base.ConvertFrom( context, culture, value );

However, it is important to note that this type provider will only work for XAML, since the IDestinationTypeProvider service is only provided by XAML’s ServiceProviderContext. It is thus not desirable to add this TypeProvider to types which work independent from XAML, like my Interval class. In addition this would require referencing the System.Xaml assembly.

How then to make XAML use this type provider without applying the attribute to the type definition? One option is applying the TypeConverter attribute on a per-property basis.

The per-property type converter technique is particularly useful if you choose to use a property type from Microsoft .NET Framework or from some other library where you cannot control the class definition and cannot apply a TypeConverterAttribute there.

However, this implies a lot of redundancy, having to apply the attribute to every property of that specific type. Using TypeDescriptor.AddAttributes() you can assign a TypeConverter at runtime.

  typeof( Interval<,> ),
  new TypeConverterAttribute( typeof( IntervalTypeConverter ) ) );

Any subsequent TypeDescriptor.GetConverter() call will then return the converter for the specified type. Unfortunately this does not work for XAML, since XAML does not seem to take component modifications at runtime into account. Therefore, in order for this to work, we need to implement this runtime behavior ourselves. Recall that XAML does load TypeConverter‘s specified in TypeConverterAttribute‘s. We can thus use a special type converter which redirects its implementation to a converter loaded through TypeDescriptor to hook into XAML’s type conversion runtime. I implemented a RedirectTypeConverter which can be used as a base class for this exact purpose. Each of its methods first ensures the converter is initialized using TypeDescriptor, and then redirects the call to this converter. When TypeDescriptor.GetConverter( _type ) returns the redirecting type converter itself, this means no converter was specified using TypeDescriptor, hence no conversion is supported for this type.

protected RedirectTypeConverter( Type type )
	_type = type;

public override object ConvertFrom(
	ITypeDescriptorContext context,
	CultureInfo culture,
	object value )
	return _converter.ConvertFrom( context, culture, value );

public void InitializeConverter()
	if ( _converter != null )

	_converter = TypeDescriptor.GetConverter( _type );
	if ( _converter.GetType() == GetType() )
		string message = string.Format(
		  "Conversion failed. Converter for {0} is missing in TypeDescriptor.", _type );
		throw new InvalidOperationException( message );
class RedirectIntervalTypeConverter : RedirectTypeConverter
	public RedirectIntervalTypeConverter()
		: base( typeof( Interval<,> ) )

Applying this converter using TypeConverterAttribute to generic types thus allows redirecting type conversion to a converter which supports multiple target types in environments which provide information about the target type (like XAML using IDestinationTypeProvider). You only need to add the converter once, and it will be supported for all of your dependency properties using them.

  typeof( Interval<,> ),
  new TypeConverterAttribute( typeof( IntervalTypeConverter ) ) );

Interval: Generic Ranges in C#

There is no doubt about it; out of all the programming languages I ever experimented with, C# has offered me the most streamlined positive development experience so far. It is a modern, ever-evolving language, which now that C# and the whole .NET framework is turning to open source, is guaranteed an even greater future. However, some core constructs commonly available in other languages, like intervals which I introduce an implementation of in this post, are missing. E.g., Ruby has had Ranges for quite some time.

A Range represents an interval—a set of values with a beginning and an end.

Straightforward, but due to the lack of support for generic calculations in C#, a hassle to implement. However, as introduced by Marc Gravell, with some runtime compilation trickery involving expression trees, far from out of reach. I’ve had an Interval class within my core library for quite some time, but just now refactored it to also support more complex intervals, e.g. an interval between two DateTime instances, which thus represents a TimeSpan.

Without further ado, an example of what using this looks like in practice.

// Mockup of a GUI element and mouse position.
var timeBar = new { X = 100, Width = 200 };
int mouseX = 180;

// Find out which date on the time bar the mouse is positioned on,
// assuming it represents whole of 2014.
var timeRepresentation = new Interval<int>( timeBar.X, timeBar.X + timeBar.Width );
DateTime start = new DateTime( 2014, 1, 1 );
DateTime end = new DateTime( 2014, 12, 31 );
var thisYear = new Interval<DateTime, TimeSpan>( start, end );
DateTime hoverOver = timeRepresentation.Map( mouseX, thisYear );

// If the user clicks, zoom in to this position.
double zoomLevel = 0.5;
double zoomInAt = thisYear.GetPercentageFor( hoverOver );
Interval<DateTime, TimeSpan> zoomed = thisYear.Scale( zoomLevel, zoomInAt );

// Iterate over the interval, e.g. draw labels.
zoomed.EveryStepOf( TimeSpan.FromDays( 1 ), d => DrawLabel( d ) );

As you might notice, the timeRepresentation interval has just one generic parameter (Interval<int>), whereas thisYear has two (Interval<DateTime, TimeSpan>). The less generic (one type parameter) class is a simple wrapper around the more generic base type which has two type parameters; the first denotes the type used to represent any position within the range, whereas the second type is used to represent differences between these positions. When these types are the same, the simplified wrapper can be used. Likewise, a TimeInterval wrapper can easily be created if you find Interval to be too verbose.

Worth noting here to understand how it works under the covers is the constructor which sets two public static fields used during operations when conversions to double are needed. Arguably, this could be improved by having a factory creating the intervals and using constructor injection instead.

public TimeInterval( DateTime start, bool isStartIncluded, DateTime end, bool isEndIncluded )
	: base( start, isStartIncluded, end, isEndIncluded )
	ConvertDoubleToSize = d => new TimeSpan( (long)Math.Round( d ) );
	ConvertSizeToDouble = s => s.Ticks;

Once you start incorporating the notion of an interval in your programming arsenal you will be amazed by the opportunities which present themselves where to use them! Some actual examples within my core library:

To get an impression of the full range of currently supported operations, check out the unit tests.

Generic Attributes in C#

As awesome as C# is, once you want to do some more advanced stuff with attributes, you quickly run into several limitations. There is even a Microsoft Connect entry on this issue.

  • Attributes can’t be generic, since a generic type cannot derive from ‘Attribute’.
  • An attribute argument must be a constant expression, typeof expression or array creation expression of an attribute parameter type.

Using TypeDescriptor and a whole bunch of custom code these limitations can be overcome. In this post I will describe an easier straightforward way by which to create something similar to generic attributes, ignoring the second issue for now. In future posts I will discuss how and where these attributes can be used for something I previously called attribute metabehavior.

The idea is quite straightforward; although attributes can’t be generic, nothing prevents you from adding generic instances to them. These instances can later be extracted at run time using reflection. The trick of course is initializing the generic instance. Once you know the Activator class can create instances by knowing their Type definition, the solution becomes self-evident. By simply passing the generic type as an argument to the attribute, instance creation can be delegated to Activator. Optional constructor arguments can also be passed as attribute arguments.

public class BehaviorAttribute : Attribute
	/// <summary>
	///   The dynamically created instance of the type passed to the constructor.
	/// </summary>
	public object DynamicInstance { get; private set; }

	/// <summary>
	///   Create a new attribute and initialize a certain type.
	/// </summary>
	/// <param name = "dynamicType">The type to initialize.</param>
	/// <param name = "constructorArguments">
	///   The arguments to pass to the constructor of the type.
	/// </param>
	public BehaviorAttribute(
		Type dynamicType,
		params object[] constructorArguments )
		DynamicInstance =
			Activator.CreateInstance( dynamicType, constructorArguments );

This attribute can then be be applied as follows:

class Answer<T>
	public T Value;

	public Answer( T value )
		Value = value;

[BehaviorAttribute( typeof( Answer<int> ), 42 )]
class TheWorld {}

Using ordinary reflection, the instance can be extracted.

Type type = typeof( TheWorld );
var behavior = (BehaviorAttribute)type
    .GetCustomAttributes( typeof( BehaviorAttribute ), false ).First());
var genericInstance = (Answer<int>)behavior.DynamicInstance;
int answer = genericInstance.Value;

What follows is up to you, how will you use this? I’ll describe a few advanced use cases in subsequent posts.

CamelCase vs underscores: Revisited

It has been 2 years since I published “CamelCase vs underscores: Scientific showdown”, and it still is easily the most visited article on this blog. Yesterday alone it got 2,614 views thanks to a forum post on Y Combinator, pretty much suppressing my normal visit rates entirely. What is it that makes it such a hot topic? Honestly, it doesn’t interest me that much anymore since there are many more important ways by which to make your code more readable; note it is code comprehension we are talking about here, not how fast you can write code! Before I outlined how the entire discussion could be made obsolete by moving away from a textual representation of code, and in my previous post I related software design principles as an act of communication to the cooperative principle in Linguistics. Nonetheless, given the immense interest this article seems to be getting I feel it’s my obligation to report on follow-up research of the previously discussed paper “To camelcase or under_score” by Binkley et al. (2009) (PDF).

In “An Eye Tracking Study on camelCase and under_score Identifier Syles” by Sharif and Maletic (2010) (PDF) the previous study is replicated but deviates from it in a few points:

  • Only programmers are used as subjects.
  • All of the subjects had experience with both styles and their preference of style was approximately split even among the groups.
  • Most of the subjects were historically trained in the underscore style. (The opposite was true in the study by Binkley et al.)
  • Eye tracking is used to measure fixation count and rate. Results from previous eye tracking studies in the domain of cognitive psychology imply that camel-cased identifiers should be more difficult to read compared to underscored identifiers.

No difference in accuracy was reported (as opposed to Binkley et al.), but on average, camel-cased identifiers took 932ms (20%) longer than underscored identifiers, in line with the 13,5% longer as reported by Binkley et al. The eye tracking results also give some insight into visual effort. Camel-cased identifiers require a higher average duration of fixations.

When interested into the details of the studies, don’t forget to read the papers yourself. I linked to them for your convenience, but if the links break you can easily find them by looking up their titles on Google Scholar.

It seems in general the subject has gotten more attention over the past 2 years in research. You can find relevant resources yourself by checking out the ‘Citing Documents’ of the discussed papers, but here are a few interesting ones:

Learning from Linguistics

Don’t worry about the title, this is a post about software design. This week I started following a Coursera course, Think Again: How to Reason and Argue. In it, the cooperative principle and its constituting maxims are presented which describe how people ideally should interact with each other. I realized the maxims apply to software design as well; after all, programming is a cooperative process, at least if you want your code to be usable by others. At the very minimum all of the maxims apply to the comments and documentation, them being language. Sometimes a direct relation to the existing design principles we follow can be drawn.

Maxim of Quantity

  1. Make your contribution as informative as is required (for the current
    purposes of the exchange).
  2. Do not make your contribution more informative than is required.

Point 1 boils down to stating everything relevant to the current situation without leaving out any important details.

public class Machine
	bool _enabled;
	public void Enable() { _enabled = true; }
	public void Disable() { _enabled = false; }

This code leaves out important information, namely the state of the machine. This should be publicly visible.

public class Machine
	public bool Enabled { get; private set; }
	public void Enable() { _enabled = true; }
	public void Disable() { _enabled = false; }

Point 2 states you should only show the relevant information. This reflects the concept of information hiding which states internal logic should be encapsulated and only a stable interface should be exposed.

Maxim of Quality

  1. Do not say what you believe to be false.
  2. Do not say that for which you lack adequate evidence.

Point 1 simply states, “do not lie”. Now you might wonder how to lie when programming, but the following is an all too common example.

catch ( Exception ) {}

Obviously this exception hasn’t been handled. Testing your software gives you the necessary evidence that your code works for the provided use cases, addressing point 2.

Maxim of Relation

  • Be relevant!

Within linguistics, being irrelevant can for example mean changing the subject when answering a question. Although possibly a long stretch, the Seperation of Concerns principle states a computer program should be separated into distinct features overlapping as little as possible. The notion of cohesion refers to the degree to which elements of a module belong together. High cohesion relates to being relevant, letting a module only perform those tasks related to each other.

Maxim of Manner

  1. Avoid obscurity of expression.
  2. Avoid ambiguity.
  3. Be brief.
  4. Be orderly.

Being brief means conveying something as concise as possible. Well, for starters don’t repeat yourself! Your interfaces/APIs should be unambiguous and as clear as possible. There are many examples of this, but here’s two.

class Controller { ... }        // Obscure.
public int GetWeight() { ... }  // Ambiguous.

Lastly, be orderly. Don’t place everything in one namespace, and code consistently. Follow the conventions in your current work environment, as this will lead to the least surprises.

Programming is very much a linguistic act and thus we could probably learn a thing or two from linguistics and social sciences in general.

Programs must be written for people to read, and only incidentally for machines to execute. – Abelson & Sussman, Structure and Interpretation of Computer Programs

Don’t Repeat Yourself as a Lifestyle

Yesterday I saw a truly inspiring talk by Bret Victor where he explains his guiding principle in life and work.

“Ideas are very important to me. I think that bringing ideas into the world is one of the most important things that people do. […] Creators need an immediate connection with what they are creating.” – Bret Victor

It’s quite a lengthy talk, but the crux of it doesn’t boil down to just this principle. He goes on to describe why he follows this principle. What motivates him.

“When I see a violation of this principle, I don’t think of that as an opportunity. […] Ideas are very precious to me, and when I see ideas dying, it hurts; I see a tragedy. To me it feels like a moral wrong, it feels like an injustice, and if I think there is anything I can do about it, I feel it is my responsibility to do so; not opportunity, but responsibility.” – Bret Victor

Although Bret spends a great amount of time demonstrating some very imaginative interfaces, the bottom line of the talk isn’t about him showing off his principle, but meant to inspire you in finding your own, and why technology can play an important role in that.

“As a technologist you can recognize the wrong in the world. You can have a vision for what a better world could be, and you can dedicate yourself to fighting for a principle. Social activists typically fight by organizing, but you can fight by inventing.”

“I’m not saying you that you have to live this way. I’m not saying that you should live this way. What I’m saying is that you can, that this lifestyle is an option that’s available to you.” – Bret Victor

Only this morning I realized what this principle could be for me.

The DRY (Don’t Repeat Yourself) principle states: Every piece of knowledge must have a single, unambiguous, authoritative representation within a system. – The Pragmatic Programmer

I’ve always held this fundamental software development principle in high regard, but just as the original intent of the statement wasn’t solely about preventing duplicate code I realize now I assign even more importance to it. For me it transcends software development.

I’m writing this while I’m on the train, on my way to work. I spend quite a lot of time on train travel, having to go from Belgium, to The Netherlands and to England. It’s mind-numbing having to take the same routes over and over again, week after week, but the ability to work or read while I do so helps me cope with that. Doing the same trips by car would drive me insane. It’s only one of the many indications in life which cause me to believe that repetition is a cause of dread.

Although I didn’t interpret it as such before, the past few years it has been my personal goal to attempt eliminating any form of repetition. Everything I feel strongly about revolves around eliminating the need to do the same things over and over again. From changing the way a community works by working towards a more constructive environment in which to have discussions so arguments no longer need to be repeated over and over again, to eliminating the need of ever having to write an unnecessary piece of code again. The thesis I am currently working on is inspired by the fact that people waste too much of their time managing and switching between different activity contexts. It’s repetitive work which could be solved by using an Activity-Based Computing system.

The wonderful thing about technology is that it’s a perfect enabler to attain that goal, but I realize now it is not only what defines me as a developer, but also as a person. Some people might call me lazy because I don’t like doing daily chores. They might be right, I rather work on things which prevent me from having to do something ever again. I like my work as much as I do because it’s non-repetitive by nature, unless you end up in a mindless work environment where you are considered to be nothing more than a Code Monkey.

I believe I found my personal guiding principle, what’s yours?

Downcasting, what’s up with that?

Just a short post today, or a question rather, on what must be the easiest subject I’ve written about yet. Though, I’ve caught myself making errors against it often. Nowadays I’m extra cautious when writing about inheritance.

What do you think about first when you hear “up”?

graph upviagra-pills

What do you think about first when you hear “down”?

down graph.png


Now, how do we programmers interpret upcasting and downcasting?


You upcast to an object which can do less, and you downcast to an object which can do more.

What’s up with that?

UPDATE: I have since started a discussion on this on Programmers Stack Exchange.