Duck Typing Dichotomy

Posted on July 4, 2006. Filed under: ColdFusion |

So it seems after attending the CFUnited 2006 conference that yet another feud is brewing in the Coldfusion community. The all eternal question is arising – to duck type or not to duck type. I can see it now, next year we will have the Duck Type Celebrity Death Match between Sean Corfield and Hal Helms against……well…….no one yet……..hey…….maybe that Simon guy will throw on the gloves again.

For those of you sitting at home going quackers maybe I can help explain.

Duck typing is the basic concept of not typing CF functions and function arguments. This simply means you leave off the ‘returntype’ and ‘type’ attributes in cffunction and cfargument tags, respectively. So why would someone want to do that….I’m glad you asked.

Let’s pretend you have two different objects, a car object and a plane object. These objects are clearly different and cannot really be subclassed (one cannot extend the other by nature). However, they may have many similar functions. Let’s suppose they both have high level functions that passengers may want to call, namely, GetIn(), BuckleSeatBelt(), and EnjoyRide(). Although the functions have the same names the details are quite different. For instance, getting into a car means opening the door and stepping in. Getting into a plane involves climbing stairs or walking through the tunnel to the aircraft. The same could be said for EnjoyRide(), in a car you might listen to music but in a plane you might want to order a Pepsi. Clearly we have two objects with the same function names but the code in the functions are different.

Now, let’s say we have a Transportation() function that calls the three functions GetIn(), BuckleSeatBelt(), EnjoyRide(). We will pass it the mode of transportation and let it call the functions for us. If we type the Transportation() function argument we must provide the cfargument type=Car or type=Plane but we cannot define both. Therefore we might create two functions, one that accepts cars and one that accepts planes. This would be the method of choice in language that supports true polymorphism (two identically named functions that take different argument types), however, CF does not support this type of polymorphism. So the next best thing is to take away the type attribute of the cfargument tag. That way either object can be passed in and have their functions invoked.

There are other scenarios where duck typing is essential.  Since Coldfusion is in the minority of languages that actually allows you to do it we should definitely take advantage. However, there are downsides.  For instance, what if you are working on a large development project and you spot another developers function that you want to use. It requires 5 parameters but displays no type attribute information. How do you know what to pass that function? Well, either you hope the developer left a nice comment for you (and we know how common that is) or you can look through his code (ok you can stop laughing now). Neither solution is good.

Another point to throw into the mix is that it takes time for CF to type check at runtime. If you have a function that is continually called with multiple paramters that contain types then CF must check those types everytime before the function is run. Taking out the types can speed up the run time of the application.

My advice would be to use typing when you are developing an API that will be used by other developers, however, you should then strip out the typing information as part of your build process.  This will allow you to keep typing information on the development environment but not in production when performance counts.  If you are not developing API code,  or you are the only person that will be working with the code, or you need duck typing to tackle a particular problem then take out the typing information in development as well as production.

That should sum up the issue, shoot me a comment on your thoughts.

Advertisements

Make a Comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

16 Responses to “Duck Typing Dichotomy”

RSS Feed for Loch’s Block Comments RSS Feed

Thanx for a great summary of duck typing and a supportive p.o.v.!

Note that you never “need” duck typing if you own all the code but the alternative is that horrible “kitchen sink” base class (Hal advocates this in some of his articles, Simon “mostly” uses this approach too – although Simon’s base class changes from application to application).

As for documentation, anyone who isn’t use hint= on every cfcomponent, cffunction and cfargument needs to be lined up against the wall…

Hi There,

Great summary!

If anyone is interested, Adam Haskell has posted a nice Regex for pulling the typing out as part of an ant build script.

http://cfrant.blogspot.com/

Best Wishes,
Peter

but what if you really need to ensure that your code wants to deal not with a duck (female) but a drake (male) or even a mallard? they all .Quack(), .Paddle() and .PooOnTheGrass().

don’t you run the risk of filling up the components and calling routines with code to interegate this, when a simple cfargument type=”org.wildlife.mallard” would do?

sorry to ask but I’m just comming up for air after lots of C# and Java and it just feels “backwards” to me….

thanx

skeptic, yeah, that’s exactly the point: use duck typing when you *don’t* need to know the type and regular typing when you *do*

Of course, you can also use getMetadata(obj).name to find out the type of a duck 🙂

The RegEx approach was mentioned during Sean’s Duck Typing talk at CFUNITED. While I see the approach being used, I can’t say I’m a big fan of it. What happens if you’re trying to diagnose a bug in production and it turns out it has to do with the duck typing? You’re going to have developers tearing their hair out trying to figure out why perfectly normal looking code should be functioning fine in production only to find out that something in the build process stripped out the returntypes on everything and now a string is being passed into a function when an object was expected, or something along those lines.

Duck typing is an advanced development concept and, unfortunately, it was being promoted by supposed “CF Gurus” at CFUNITED as the best way to improve the performance of your application. I know that this isn’t what proponents of the technique such as Hal Helms, Sean Corfield, and Joe Rinehart had in mind when they discussed their use of it in their work, but, alas, this is where the discussion has primarily been redirected. (And no, they aren’t the “gurus” I’m speaking of.)

With all the debate on the merits of frameworks and duck typing, the vast majority of those involved in the discussion are forgetting that their database is more than likely going to be the true performance bottleneck in any application. To me, Duck Typing is an “edge case” development technique that should be reserved strictly for low-level API development. Anything “above” that should properly use the appropriate typing for clarity.

By the way, welcome to the blogosphere!

so Dave, your saying that duck-typing should be the exception rather than the rule?

and the heavy use of it in languages like Ruby (+ Rails) or python is up to that language to justify – no bearing on how CF should be used?

I not having a go, just curious/wanting to learn.

thanx

Zach, thank you for this post. I always enjoy posts which get me a little closer to understanding some consept.

@sean,

“As for documentation, anyone who isn’t use hint= on every cfcomponent, cffunction and cfargument needs to be lined up against the wall…”

Sorry, but with proper typing (there it is again), coding (the one function for one thing) and naming of your functions and arguments (using “x” as a variable name isn’t good practice), you don’t need be wasting your time with putting hints onto every component, function and argument.

Skeptic Sam, yes, that’s exactly what I’m saying. People like to say that ColdFusion isn’t Java. I would correct that statement and say ColdFusion isn’t Java *conceptually*. Well, you know what? ColdFusion isn’t Ruby, Python, C#, or any other language either. It has it’s own strong points, weak points, and all points in between, as do the other languages. To that end, I think it’s apples to oranges to compare duck typing between languages. ColdFusion doesn’t optimize the same as Ruby, which doesn’t optimize the same as Python. Perhaps duck typing might make sense in those languages. But as a 10-year veteran of ColdFusion development, I’ve yet to come across a situation in my work where duck typing was the best solution to a problem statement. (I don’t write frameworks, which is really the only place that I’ve seen the justification for this technique so far.)

Dave and Skeptic Sam,

You make some valid points.

I see duck typing as a tool in our development toolbox. For example, a construction worker could build a house with only a hammer, some nails, and some type of saw. And people have done that just fine for many, many years. However, most homebuilders now have huge trailers filled with hundreds of tools that they take with them on job sites. Many of those tools are considered ‘specialty’ tools and only get used a couple times a year. Of course, some builders work only ‘specialty’ projects and use them more often but everyone uses them sometime or another.

The point is these ‘specialty’ type tools are not necessarily *needed*, we’ve been developing just fine for a long time without them (this wasn’t even an issue in CF5 and earlier). However, we would be hindering ourselves by not using these new tools to provide more effecient and elegant solutions. I don’t think we should apply a liberal brush and take typing information out entirely, but to say that only frameworks could use this solution is equally as wrong in my point of view (unless you are working on trivial projects).

Zach,

Agreed. However, using your example, I’d argue that the “specialty projects” are the equivalent of an “advanced technique” in ColdFusion. That was the point I was trying to make; don’t blindly remove typing because the other voices in the community have advocated it. Further, I did not mean to imply that frameworks were the *only* place to use duck typing. Rather, I submitted that, to date, in all the ColdFusion code samples I’ve seen posted, the framework-related code posted by both Joe and Sean on their blogs have been the most pragmatic uses. I certainly have seen the “hello world” examples of duck typing, but nobody has posted “real world” code that shows why they used duck typing to solve a particular problem…even your Plane/Car example is merely a learning example, not actually implemented.

Great discussion.

Thanks for the welcome Dave!

I started a repsonse and found it to be a little long so I posted an entry:

http://cfrant.blogspot.com/2006/07/one-last-piece-on-duck-typing-then-i.html

I do advocate the use of a base type, but certainly not a “kitchen sink” approach. Rather the base class should be an abstract class that has methods that ALL CFCs should have. One example is the idea of identity so that I can tell one instance of a CFC apart from another instance.

Is such a thing useful? Let’s see. If I have an array of objects and wish to remove a specific object from the array, how can I do this? I can’t loop over the array, asking if the object I want to remove EQ the current object in the loop. CF will error out if I try this.

Although some people never find themselves in this situation according to their blogs, I find myself very often in such a situation. To me, the idea of object identity should be baked into every instance, so my base Object class has a unique ID created when the object is instantiated. I then create an equalTo method in Object.cfc that accepts a CFC and checks to see if it’s ID matches the argument’s ID. All CFCs that would normally not extend a CFC then extend Object.cfc (which I place in the CustomTags directory).

This is certainly not an orginal idea of mine. Picasso once said that good artists borrow, but great artists steal. Let’s just say I “liberated” the idea from Java.

Since I advocate duck typing (and am therefore not concerned with the type of an argument or a returntype), I also created universal “get” and “set” methods that receive an argument (x) and check to see if an actual getX or setX method exists. If it does, the universal get or set calls the specific getX or setX method. If no specific getX or setX method exists, the universal get or set references an instance variable, x.

These seem to me good examples of the usefulness of a universal base class. I’ve certainly seen the idea of a universal base class abused, with people placing things like persistence in the base class (truly a kitchen sink approach), but that is something I would discourage.

Great point. I also store the objects name (or type) in a variable within the object for that specific reason. If I need to know the objects type I just ask it. I like the base component idea – I’ll have to experiment with that.

I’m suprised how many people say that they frown on duck typing because of a Java background – introspection is a key component in Java – for instance, when pulling something off of a Vector you commonly have to find its type to work with it. If the object isn’t the type you want to work with you keep searching through the Vector – very common technique.

Duck typing is possible in Java, depending on your definition of duck typing. The original definition by David Thomas fits the Java case pretty well.

http://rickyclarkson.blogspot.com/2006/07/duck-typing-in-java-and-no-reflection.html


Where's The Comment Form?

Liked it here?
Why not try sites on the blogroll...

%d bloggers like this: