[svn] r6463: lb/activity/2006/Jul-23.html
nazgul
svnadmin at nemerle.org
Sun Jul 23 15:12:16 CEST 2006
Log:
Blog entry about late binding
Author: nazgul
Date: Sun Jul 23 15:12:13 2006
New Revision: 6463
Added:
lb/activity/2006/Jul-23.html
Added: lb/activity/2006/Jul-23.html
==============================================================================
--- (empty file)
+++ lb/activity/2006/Jul-23.html Sun Jul 23 15:12:13 2006
@@ -0,0 +1,142 @@
+<h1>Late binding</h1>
+<p>
+ Recently one of <a href="http://snaury.googlepages.com/">Nemerle users</a>
+ played a little bit with our macro system and implemented a feature allowing
+ dynamic invocation of methods or accessing properties in a quite clean way
+ (as you probably know, Nemerle is entirely statically typed and forces your
+ code to be compliant with .NET standard object-oriented access to classes).
+ The simplest example is
+</p>
+
+<xmp class="code-csharp">
+def getLength (obj : object)
+ late obj.Length
+
+System.Console.WriteLine (getLength ("Grey goo"))
+System.Console.WriteLine (getLength ([1,2,3]))
+System.Console.WriteLine (getLength (System.Windows.Forms.LinkArea ()))
+</xmp>
+
+<p>
+ Here we just want a method to fetch the <em>Length</em> property of given object and
+ <em>late</em> keyword introduced by macro allows us to do so easily. The
+ biggest advantage here is that we do not care about the intefaces and common
+ supertypes of object we use this on, so we can apply this method to
+ <em>ANY</em> object (which is assumed to contain the correct property). The call will be
+ made using .NET's
+ <a href="http://www.devx.com/dotnet/Article/7004/0/page/2">dynamic invocation</a> feature.
+</p>
+
+<p>
+ The idea is a little bit similar to something called
+ <a href="http://en.wikipedia.org/wiki/Duck_typing">duck typing</a> (though the
+ name is a bit politically controversial in my country at the moment ;p), but
+ in case of our macros it works in a different way. We do not introduce any
+ dummy "types" for objects, which are not type-checked, but we allow user to
+ specify which parts of code should be dynamic (for more detailed specification
+ see a <a href="http://nemerle.org/Late_Binding_Macro">deciated page</a>).
+</p>
+
+<p>
+ Now the question is why is it really useful? In general I'm always heading
+ towards the perfect world and I prefer my programs to be proved being perfect
+ and safe. Type inference is a powerful Nemerle's feature, which helps here - I
+ do not need to specify types of variables and compiler can infer what I mean;
+ if it can't, it usually means I made some mistake. But here comes the problem,
+ sometimes the code we write is simply not compatible with language / platform
+ type system and compiler complains about my code even though I know it is
+ right. Let us consider another example:
+</p>
+
+<xmp class="code-csharp">
+#pragma indent
+
+using Nemerle.Late
+
+public class Pixel
+ mutable shift = 0
+ public Draw () : void
+ System.Console.Write (string (' ', shift))
+ System.Console.Write ("*")
+ public Move (dx : int) : void
+ shift += dx
+
+public class Triangle
+ public Draw () : void
+ System.Console.Write ("/^\\")
+
+def perform (x : object, with_move = false)
+ late
+ x.Draw ()
+ when (with_move)
+ x.Move (5)
+ x.Draw ()
+ System.Console.WriteLine ()
+
+perform (Pixel (), true)
+perform (Triangle ())
+</xmp>
+
+<p>
+ Now as you can see my <em>perform</em> function is quite tricky - it does not
+ call <em>Move</em> on object if I do not specify <em>with_move</em> parameter
+ to be true. So its contract is something like "calls Draw, but if we want move
+ also calls Move", which is not expressible in any simple type system
+ (e.g. .NET). With our late binding macro we just ignore the type system and
+ perform all calls dynamically. :)
+</p>
+
+<p>
+ One more thing to notice here is that usually we can avoid dynamic calls by
+ using well designed object hierarchy and interfaces (if we are not too lazy of
+ course ;) ). In our example we can easily make the call to <em>Draw</em>
+ statically safe, by introducing the <em>IDrawable</em> interface.
+</p>
+
+<xmp class="code-csharp">
+public interface IDrawable
+ Draw () : void
+
+public class Pixel : IDrawable
+ mutable shift = 0
+ public Draw () : void
+ System.Console.Write (string (' ', shift))
+ System.Console.Write ("*")
+ public Move (dx : int) : void
+ shift += dx
+
+public class Triangle : IDrawable
+ public Draw () : void
+ System.Console.Write ("/^\\")
+
+def perform (x, with_move = false)
+ x.Draw ()
+ when (with_move)
+ late x.Move (5)
+ x.Draw ()
+ System.Console.WriteLine ()
+</xmp>
+
+<p>
+ Note that now type inference comes in help - the signature
+ <em>perform (x : IDrawable, with_move : bool) : void</em> is automatically
+ guessed by compiler. The only late bound operation now is a call to
+ <em>Move</em>. To solve this we could do two things:
+</p>
+
+<ul>
+<li>write a specialized perform_with_move function, which would take
+ <em>IMovable</em> or simply <em>Triangle</em>, but this would yield code
+ duplication and additional efforts
+</li>
+<li>
+ cast to more specific type before calling Move, which makes your code a little
+ bit uglier and you must know exactly which type to cast to.
+</li>
+</ul>
+
+<p>
+ The other cases when late binding might be useful is when you use a platform's
+ feature, which is very dynamic by nature - like using types obtained through
+ COM.
+</p>
More information about the svn
mailing list