Tuesday, August 29, 2006

Interfaces in Delphi / Win32

Craig Stuntz comments on my remarks about interfaces in Delphi / Win32:
Regarding interfaces, I'd argue that Delphi Win32 interfaces are more similar to .NET interfaces than COM interfaces are to COM+ 2.0 (a.k.a. .NET) interfaces insofar as they don't completely dictate lifetime management. In Delphi Win32 I can (and frequently do) override reference counting and use interfaces to provide multiple interface inheritance of classes without reference-counted lifetime management of instances.
Sure. Delphi/Win32's interfaces are a superset of COM interfaces; they include support for native Delphi types (such as AnsiString), and when one is working in single-language / single-vendor (taking BCB into account) environment, it can be useful to discard the language-neutral COM conventions. That doesn't stop the Delphi compiler from performing all the refcounting operations anyway, though.
I can't cast from an interface to an object, but in other respects it's pretty similar to what I do with interfaces in .NET. The underlying mechanisms are very different, yes (e.g., GUIDs as IIDs), but in the end I find myself doing similar things in code.

When you say interfaces are different in Delphi Win32 and .NET you seem to be talking about lifetime management.

I'm talking about slightly more than that. I'm talking about the basic services that IUnknown provides: lifetime management (AddRef and Release) and interface negotiation (QueryInterface). All Delphi/Win32 interfaces derive from an interface that supports these three operations (whether it's IInterface or IUnknown depending on version). Delphi/Win32 implements interface casting (in so far as it does at all, excluding Supports() etc.) through calls to QueryInterface, via 'as'. Delphi/Win32 doesn't support 'as' casting unless the interface has a GUID, a COM-ism. Delphi/Win32 classes can dynamically change which interfaces they support (within or without COM rules) by explicitly implementing QueryInterface() - that won't work in .NET (I use IServiceProvider for this). All COM interfaces consumed in Delphi in the orthodox way (ignoring the old Delphi 2 stuff) are also Delphi/Win32 interfaces. Delphi/Win32 interfaces and COM interfaces are basically made of the same "stuff", with the same binary format.

.NET interfaces are entirely different; they're a runtime feature, and they aren't a binary standard. They're not ref-counted. They don't have the same layout. Casting is defined by the implementing class, and can't be dynamically changed (RealProxy etc. aside). They don't require GUIDs for full support. COM interfaces get wrapped in runtime callable wrapper (RCW), rather than being actual .NET interfaces.

But the lifetime management features in Delphi Win32 are something I generally try to work around because (1) I mostly don't use them for COM and (2) I find having two wildly different lifetime management schemes coexisting inconvenient. When I work in .NET I use the GC; I would find doing a mixture of GC and explicit allocation / disposal messy. Similarly, I only want my object instances reference counted in Win32 when I can't avoid it, like when I must use COM. Otherwise I want to do things explicitly, for the sake of consistency.
Sure - but you have to do this yourself! Delphi's TInterfacedObject, the normal base for a class supporting interfaces, implements COM rules. I think it can even be useful to work within the COM rules too, when restricted to Win32-only code, since the automated ref-counted GC supports shared ownership fairly well.

Delphi Native Closures, Part II

A few days back, I made a post on the difficulties of implementing closures in a non-GC language.

Craig Stuntz made a comment:

Barry, I don't see how this problem is any different than in operator overloading, which is already supported in Win32, albeit in very limited conditions. So there's a fourth possibility not mentioned in your list, which is to only support it for functions with argument data types such as strings and value types which can be simply cleaned up. It's far from ideal, but given the OO example not unprecedented.
I agree with Craig re possibilities, there are more ways to slice it - but some slices are bigger than others! In my previous post, I cut things into two basic slices: how to free the delegate, and which captured variables to free. Of the two, the first one is about 90% (or more, FinalizeRecord in the Delphi RTL can do the second job) of the problem.

I don't agree with the comparison to operator overloading. Implementing closures is far more complex than operator overloading, because closures aren't limited to traditional Standard Pascal downward funargs; they can live long after the creating frame goes away. That isn't the case for temporaries created through support for operator overloading. The bulk of the work would be in putting the stack frame on the heap and refcounting it, and in implementing reference counting on every Delphi Win32 method pointer. I could then see people (ab)using COM interfaces to get deterministic destruction, effectively the same as the notional 'finalization' section I described.

Lest one think that one could get away without refcounting by limiting closure support to downward funargs, well, that would be a problem: closures gain a lot of power through composability. By composability in this context, I mean the ability to write a function that takes a function and returns a function, where the returned function is a function of the argument function, and thus relies on closure or some other way of tracking the passed in argument.

I should make that concrete. Consider this predicate, in C#:

public static Predicate<T> Not<T>(Predicate<T> pred)
{
    return delegate(T value) { return !pred(value); };
}
This snippet can't be implemented with just downward funargs because the stack frame of Not disappears when Not returns.

This is the heart of the problem: not only a transformation of stack into heap (of the lexically closed & captured variables etc.), but implementing refcounting everywhere a method pointer exists. Whether or not simple types like string and record and interface (and thus 'simple types' is open ended) are supported or not, is relatively trivial.

Another thing this brings up: the (ab)use of COM interfaces to implement simplify lifetime management of plain old Delphi objects, something which effectively would add the power of a 'finalization' section, without being explicit about it. It gets at another issue in my earlier post: the divergence of .NET and Win32 forms of Delphi. How important is it that the two are the same? Because interfaces don't work in a similar way at all in .NET, they're completely different. They're so different they probably deserve different names.

Monday, August 28, 2006

Specfiying Ownership

Raymond Chen's post today, railing against boolean parameters, reminds me of a small detail that made one of my APIs easier to use.

The reason boolean parameters are bad is that it's often hard to figure out, from reading the code, what 'true' and 'false' refers to. Raymond points to StreamReader's constructor overload, StreamReader(Stream, bool). In this case, the boolean argument applies to the ownership of the stream - that is, will the StreamReader dispose of the Stream when it itself is disposed? Update:No it doesn't - a salutary reminder of the problem with boolean arguments! It indicates whether or not the StreamReader pays attention to byte order marks. In any case, my comment below refers to resource ownership.

For this situation in my own APIs, where transferral of ownership needs to be flexible, I use a little enum:

/// <summary>
/// Describes who controls a resource that is transferred between objects.
/// Useful for negotiating who should call IDisposable.Dispose when done.
/// </summary>
public enum ResourceOwnership
{
    /// <summary>
    /// Don't change the status quo regarding ownership of any resources.
    /// </summary>
    Preserve,
    
    /// <summary>
    /// The ownership is transferred to the callee in the case of a resource setter, 
    /// or transferred to the caller in the case of a resource getter.
    /// </summary>
    Transfer
}
I'm not 100% happy with the name of the first option, Preserve, but I can't think of a better one. Anyway, the little insight behind the enum is that rather than thinking about source and destination ownership as you interact with a class and hand it a resource, you think about how you're changing the existing ownership (i.e. transfer) or preserving the status quo. From a calculus perspective, the enum describes the derivative of the ownership, rather than the ownership itself. I find this works better than a boolean, which tries to describe the ownership directly, and also better than a special-purpose enum which contextualizes the ownership.

Saturday, August 26, 2006

Delphi Closures / Anonymous Delegates

Fredrik Haglund's post today reminded me of a post I made in the newsgroups about the difficulty of implementing anonymous delegates or closures in Delphi.

I'm a big fan of closures, as I've written about them in the past. I hope that Delphi gets some form of anonymous delegate, closure or lambda or some similar feature, while also being less verbose than local procedures and functions. Indeed, with LINQ coming along in the next version of C# and its corresponding .NET version, there'll be a requirement to integrate with it. LINQ pretty much needs lambdas, as well as expression trees, for good integration.

The problem comes in implementing closures in native code. It would be unfortunate if Delphi, the language, diverged further between the two main platforms it supports, .NET and Win32. Closures gain much (if not most) of their power by capturing local variables and arguments. If any captured local variables refer to object instances whose lifetime is logically associated with the lifetime of the stack frame which creates the closures, how does one ensure that those objects will get freed?

For example, in C# 2.0, one can write:

using System;

static class App
{
    static Action<string> CreatePrefixer(string prefix)
    {
        return delegate(string value)
        {
            Console.WriteLine("{0}: {1}", prefix, value);
        };
    }

    static void Main()
    {
        Action<string> prefixer = CreatePrefixer("foo");
        prefixer("bar");
        prefixer("baz");
    }
}
This keeps things simple by only using native .NET types, but hopefully it can illustrate the problem. By calling CreatePrefixer(), one creates an argument value (i.e. similar to a local - I'd have made it a local, but I wanted to keep the sample simple) in the stack frame associated with the CreatePrefixer() invocation, called "prefix". This value is captured by the created anonymous delegate, which is returned. That means that "prefix" must live on beyond the lifetime of the stack frame. So, the questions come:

  1. How do you free the returned delegate?
    • Manually? Delphi users aren't used to freeing procedures or functions of object.
    • Refcounted? Is there a type system difference between existing method pointers and these new delegates (confusing) or would all method pointers now be refcounted (wasteful)? What if you got a cycle? A cycle involving method pointers would be extremely hard to spot since the graph depends on the runtime execution flow graph, much harder than a cycle in data structures, which is part of the statically declared data structure graph (assuming no funny stuff with typecasting).
  2. How do you free the captured variables?
    • How do you know which ones the stack frame has ownership semantics over? In Native Delphi, strings have the nice property of being reference counted, so the solution is trivial for that datatype, so long as we are informed when the delegate is no longer needed. But what if it's an arbitrary user-defined datatype?
    • Should the anonymous delegate automagically create code to call TObject.Free?
    • Should there be a "destructor" or "finalization" block in the inline delegate definition? And won't this code be ignored for .NET execution?

For that last option, consider something like:

program Test;

type
  TActionOfString = procedure(const s: string) of object;

function CreatePrefixer(const prefix: string): TActionOfString;
begin
  Result := procedure(const value: string)
    begin
      Writeln(prefix, ': ', value);
    finalization
      // An optional section, any finalization to execute
      // when the anonymous delegate ultimately goes out of scope.
    end;
end;

var
  prefixer: TActionOfString;
begin
  prefixer := CreatePrefixer('foo');
  prefixer('bar');
  prefixer('baz');
end.
These two problems are why this construct is (to the best of my knowledge) typically restricted to garbage collected languages. Should Native Delphi have an optional compile mode that simultaneously turns on this language feature, and links in a conservative GC similar to the Boehm collector (which is currently used by Mono)?

Two other alternatives are possible: only support closures in the .NET compiler, but not in the native compiler; or don't support them at all.

Friday, August 25, 2006

Attribute Design

Krzysztof Cwalina is running a little poll attribute design on his blog. I made a comment, but I thought I'd post my thoughts here too.

The question is: is it better to have (i) lots of different attributes, or (ii) fewer attribute but use enumerations in the constructor? Naturally, this dichotomy is limited to those attributes that don't have any other arguments, i.e. only "marker" attributes.

  1. Attributes
    • [Foo]
    • [Bar]
    • [Baz]
  2. Enumeration
    • [Foo(Kind.Foo)]
    • [Foo(Kind.Bar)]
    • [Foo(Kind.Baz)]

In many ways, it seems to me to be analogous to writing several methods versus one method with parameters. It depends! How related are the attributes? Enums are quite discoverable - all the options pop up when you type in the enum name. With multiple methods / attributes, it's harder to find the related group.

If the different attributes / methods aren't closely related, then it would be wrong to conflate them into an enum.

What about user extensibility? With methods / attributes, one can define new classes / descendants and add new methods / classes that look just like the old ones. With the enums, they're baked in. This can be both good and bad - it's more encapsulated etc, less risk of confusion.

Another aspect: types for a purpose versus flexible types. Sometimes, people who are beginners to a problem look for something which is the perfect solution. Trouble is, most people's problems are diverse. This can lead to a large number of "simple" types for solving each particular class of problem, but the overall result is that the solution space is *more* complex because there's more of it. Beginners and experts alike become frustrated; the first daunted, the other feeling the clutter. In this light, fewer types that are configurable sounds better - leading to the attributes with enum arguments approach. But then - only if it makes sense!

A rule of thumb: if the attributes would probably start or end with a common prefix or suffix, then it would probably make more sense to use an enum instead.

Wednesday, August 23, 2006

The Nature of Blogging

Interesting post about the nature of blogging.

Capability-based Security

A post on Raymond Chen's blog happened to coincide with a paper I was reading, Capability Myths Demolished. More on capabilities.

It's interesting to see how our existing systems and solutions, and how popular they are, subtly influence the way we see the world. It's all about assumptions - if you don't question them, you're likely to be stuck in a local maximum, rather than wandering out to find a better maxima elsewhere.

I recommend reading the paper. It's written in a relatively colourful style, somewhat less dry and academic than some. Just thinking about the details of implementing a usable capability-based system has me thinking about how it influences other things, involving system maintainability etc. I've always thought that ACLs are a pain to manage and that Unix's 3*3 bits + sundry are better, if not for power, then for usability. I can see ways for capability-based systems to be even better, especially for things like elevating security privileges (like in Linux, MacOS X, Vista), and running less-trusted applications in the current user's account.

Food for thought.

Monday, August 21, 2006

Blogger is Odd

Blogger is an odd service. A number of times now, when editing past posts, it's switched the syndication feed to summaries. When I go into preferences etc., I see that the syndication is set to full, just like I expected. So, after I republish everything, it's back to normal.

Sigh.

Blogger API

I grew tired of using the Blogger web interface, so I wrote an offline editor. I've spent yesterday evening and an hour or two today on it. I didn't like any of the existing editors I've tried - I don't need WYSIWYG, I just need the raw HTML. I can put classes etc. on the HTML as required, and style them later.

Primary thing I wanted was a nice editor to edit with. That's why I'm using the code editor from SharpDevelop (ICSharpCode) - the minimum I wanted was auto-indent, but it has quite a bit more than that (even if it does have some minor bugs).

My offline editor is simply a cache of notes, waiting to be sent. No configuration needed, really - autosave when you're editing and closing, autoload on startup.

This may mean that I post somewhat more often than I did, but in shorter snippets. It should reduce the barrier to posting.

Update: Now I've got to find a way to avoid Blogger escaping my HTML :) As I read the docs, the Atom payload type '<content type="html"> is supposed to take escaped HTML. That's what I'm sending - XML-escaped HTML - but it looks like it's being treated by Blogger as 'xhtml' or similar, and dumped out verbatim.

Ref: Meaning of type attribute

Maybe it's a namespace issue. More experimentation required.

Strange. I had an Atom namespace in the root. I commented it out and posted again, but got a null pointer Java exception on the Google / Blogger server side, so I put it back - and now it just works! If you're missing the namespace, this is what you get from Blogger:

java.lang.NullPointerException
 at com.google.blogger.xapi.EntryToPostTranslator.translate(EntryToPostTranslator.java:80)
 at com.google.blogger.xapi.PostFeedProvider.bloggerInsert(PostFeedProvider.java:176)
 at com.google.blogger.xapi.BlogFeedProvider$2.call(BlogFeedProvider.java:214)
 at com.google.blogger.xapi.BlogFeedProvider$2.call(BlogFeedProvider.java:213)
 at com.google.blogger.xapi.BlogFeedProvider.serviceRequest(BlogFeedProvider.java:254)
 at com.google.blogger.xapi.BlogFeedProvider.insert(BlogFeedProvider.java:212)
 at com.google.gdata.provider.IntrospectableProvider.insert(IntrospectableProvider.java:95)
 at com.google.gdata.servlet.GDataServlet.processInsertOperation(GDataServlet.java:468)
 at com.google.gdata.servlet.GDataServlet.doPost(GDataServlet.java:387)
 at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
I wrote my little client in C#, but I didn't use the Blogger C# library currently on Google Code - it has Java-itis, factories and interfaces everywhere without clear purpose.

Sunday, August 20, 2006

Closure variable capture in Ruby and C#, compared

A couple of posts on Larry O'Brien's blog piqued my interest, because they're about one of my favourite things - anonymous delegates. Specifically: In the first post, Larry says:
The proposal has slightly cleaner syntax than what is in C# but I believe would reprise an issue that C# has, in that "captured outer variables" are shallow copies.
However, in the second, he contrasts the behaviour of two programs, one in C# and the other in Ruby. The implication appears to be that Ruby treats variable capture in closures differently from C# - and that was my first thought too. However, a brief experiment with Ruby showed that the different semantics has nothing to do with closures at all, and in fact it's all down to C#'s for loop.

So, here's the first program, edited slightly for length (and to remove Console.ReadKey, which doesn't play nicely with Cygwin rxvt):

using System; 
using System.Collections.Generic; 
 
delegate void VoidDelegate(); 
 
class Program
{ 
    public static void Main() 
    { 
        List<VoidDelegate> closures = new List<VoidDelegate>(); 
        //Create a bunch of closures
        for (int i = 0; i < 10; i++) 
        { 
            VoidDelegate myClosure = delegate
            { 
                //Capture outer variable
                Console.WriteLine(i); 
            }; 
            closures.Add(myClosure); 
        }
        
        foreach (VoidDelegate closure in closures) 
        { 
            closure(); 
        }
        
        Console.ReadLine();
    } 
}
If you're familiar with C# 2.0, you'll know that when run, this program will print out '10' for ten lines. This is because there's only one instance of the variable 'i', and that instance is captured by each delegate. Because the for loop changes the value of i, at the end of the loop every delegate will have a capture of the same variable, whose value is 10. That's why each closure prints '10'.

Larry contrasts the above program with this, in Ruby:

closures = Array.new() 

#Create a bunch of closures
10.times { | i | 
  myClosure = lambda { 

    #Capture outer variable
    puts(i)
  }
  closures.push(myClosure)
} 

closures.each { | myClosure | 
  myClosure.call()
}
This, of course, prints each number from 0 to 9.

Now, one might draw the conclusion from this that Ruby's closures are different from C#'s closures. That wouldn't be the right conclusion though - Ruby's variable capture is actually no different from C#. The difference is all down to the scope of the loop variable. I'll demonstrate it by writing cross-idiomatic translations of the two programs - i.e. writing the Ruby program in C#, and the C# program in Ruby, trying hard to preserve semantics.

First, I'll write the Ruby program in C#. The difference is down to the chosen iteration primitive: in Ruby, it's a method of numbers which accepts a code block as an argument (at least, that's the primive Larry's chosen), while in C#, it's the 'for' statement. So, to get the Ruby behaviour in C#, I'll have to write a Times method:

using System;
using System.Collections.Generic;

public static class App
{
    delegate void Method();
    
    public static void Times(int iterations, Action<int> action)
    {
        for (int i = 0; i < iterations; ++i)
            action(i);
    }
    
    static void Main()
    {
        List<Method> methods = new List<Method>();
        
        Times(10, delegate(int i)
        {
            methods.Add(delegate
            {
                Console.WriteLine(i);
            });
        });
        
        foreach (Method m in methods)
            m();
    }
}
I can even use this as a gratuitous chance to use C# 3.0 LINQ Preview, with its extension methods and more concise lambda expressions:
using System;
using System.Collections.Generic;

static class App
{
    delegate void Method();
    
    static void Times(this int iterations, Action<int> action)
    {
        for (int i = 0; i < iterations; ++i)
            action(i);
    }
    
    static void Main()
    {
        List<Method> methods = new List<Method>();
        
        10.Times(i => 
        {
            methods.Add(() => Console.WriteLine(i));
        });
        
        methods.ForEach(m => m());
    }
}
Don't worry, I don't think it's much more readable either :) Anyway, both of these two C# programs, following an emulation of a Ruby loop primitive, produce the numbers 0 to 9. That's because they capture a new instance of the variable each time, in an argument.

Now for the Ruby version of the original C#. Here, the Ruby for loop over a range is sufficient to demonstrate behaviour similar to C# (forgive my horrible Ruby, I'm only a beginner :):

closures = Array.new() 

for i in 0..9
    closures.push lambda { puts(i) }
end

closures.each { | myClosure | 
  myClosure.call()
} 
This, similarly to the C# version, prints out '9' ten times, because it's captured the single instance of 'i'. I'll get even closer to the C# implementation. The C# for-loop, as in other C-based languages, is syntax sugar for something like this:

for (<initialStatement>; <condition>; <loopExpression>)
    <body>

// Translates to...

{
    <initialStatement>;
    while (<condition>)
    {
        {
            <body>
        }
        <loopExpression>;
    }
}

// ... with extra braces to reflect the C#/Java/C++ style scoping.

So, onwards to a Ruby transliteration of this (but not translating the scoping, which in Ruby appears to be limited to code blocks (e.g. lambdas) and methods, not compound statements):
closures = Array.new() 

i = 0
while i < 10
    closures.push lambda { puts(i) }
    i = i + 1
end

closures.each { | myClosure | 
    myClosure.call()
} 
This prints '10' ten times.

So, there it is. Ruby's closures don't do any deeper copying of variables than C#, and with some of the looping primitives, they're even susceptible to the same downsides. An advantage Ruby has is the way its closures mesh well as arguments to methods, resulting in fairly clean language extensions. That means that one need never directly use Ruby's 'for', 'while' or 'loop' primitives to implement loops - but that's a matter of style.

It's interesting that Java's proposed closure syntax has this composability feature in common with Ruby.

Tuesday, August 08, 2006

Programming language design philosophy: C++'s value orientation

Whenever I think of the C++ programming language, my heart sinks a little. I think the language has a set of features that, taken together, add up to less than the sum of its parts. I had occasion recently to think about what exactly it was about C++ that I didn't like, apart from the cryptic nature of template errors (mainly down to the lack of concepts), the lack of features that a GC environment permits (such as closures), and the ill-defined integral types and strange pointer compatibility rules inherited from historical machine architectures, and the #include / C linker model of modularity, and iostreams, and lack of a consistent, cohesive style for libraries, and lack of agreement on a string type. Come to think of it, there's quite a few things I don't like about C++. Anyway, I only want to deal with one issue here - C++'s value oriented programming.

To me, there's really one thing about C++ that makes it stand out against all the other popular industrial programming languages, when it comes to basic language features: it's taken the idea of 'user-defined types' about as far as it can go. This goes beyond simple object orientation, or even operator overloading. In particular, to permit library definitions of things like smart, reference-counted pointers (like Boost's shared_ptr) and dynamically sizable arrays and strings (such as std::basic_string and std::vector), there's some key requirements: copy constructors, assignment operator overloading, and destructors, with strong guarantees about being automatically called. They're required so that classes which aren't simply blittable can do the required bookkeeping. For example, classes might use dynamic allocation in a non-GC environment, so they need to call new / delete etc. as necessary to maintain the right ownership of data that member pointers refer to.

Now, those features, in isolation, aren't too bad. If they didn't exist, the user would have to do all the tedious, repetitious bookkeeping themselves, and that would be error prone. Throwing exceptions into the mix is what really causes problems. It was Herb Sutter's Exceptional C++, Item 10 which opened my eyes to the big problem - referring to writing a Pop() method on a Stack. When writing a function that returns a value of a user-defined type (such as a member function of a template class, or a template function), that function can't protect against an exception being thrown in the copy constructor. If it can't protect against an exception, then it can't be strongly exception-safe if it also modifies data, because it's not possible to roll back when an exception is thrown in the copy constructor. All this is one of the reasons that C++'s std::stack::pop() doesn't return the popped value.

Unfortunately, it's not very easy to guarantee that a useful copy constructor won't throw an exception. One of the handiest uses for a copy constructor is to make a deep copy of data that the class has dynamically allocated. That means that it's probably going to call operator new, which can throw if there's not enough memory. Even if it didn't throw or the nothrow variant is used, there's no easy way to return an error code instead, so an exception is pretty much required.

How much of a limitation is that, really? I actually don't think it's a big limitation. Not many systems deal very gracefully in extremely memory-constrained situations. Probably the best way to deal with it is not to run into an exception at all, by calculating up-front how much memory is going to be needed early on in a call stack, and throwing an exception if the required amount + slack isn't available. Of course, that tactic isn't rock-solid for several reasons, including race conditions with allocation on other threads, and the difficulty and flattening of abstraction in making the required calculation.

There's more to this value orientation. The construction of new value types that are supposed to work just as well as builtin types uses the same keywords (struct and class) as the keywords to create more traditional object-oriented types (i.e. Java-style reference types), focused on things like polymorphism and dynamic dispatch. Thing is, writing correct value types is far harder than writing correct Java-style types, and C++ has some features that seem to make value types the default.

It's only with value-oriented types that you need to deal with copy constructors, assignment operators and implicit and explicit type conversions. All you need to do in C++ to create a copy constructor or an implicit type conversion is have only one argument to your type's constructor, and C++ will automagically call your constructor, sometimes when you least expect it (e.g. calling a function with the wrong type, which happens to match a constructor). Hence, the requirement for an 'explicit' keyword which prevents this behaviour when it's undesireable. Similarly, C++ automatically creates an assignment operator that will copy the binary data in the class, and it permits object slicing - copying a subtype into a supertype location and lopping off everything that made the subtype a subtype, almost as if you could turn a mammal into an earlier, sea-based life form by chopping off its legs.

On the other hand, this capability permits some pretty neat functionality - the fact that std::basic_string or CComPtr in the ATL can be implemented without extending the language or modifying the compiler is admirable. I just wonder if it cost too much. One thing I'm certain of, from my prejudiced OO and functional (where appropriate) perspective: the strong lean towards value orientation over and above Java-style reference-based object orientation is a flaw in C++. Programming languages, above all things, should keep the principle behind the "Pit of Success" foremost, and always make the natural way of phrasing the solution to a problem the correct way.

Of course, the best practices that determine the natural solution adjust slowly over the years. But when did common domain objects like Person, Car and Account ever need to act like integers, freely copyable and duplicated hither and thither? I'm not sure they ever did, so I'm not inclined to let C++ off the hook just for historical reasons.