[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