I have become accustomed to the way that purer OO languages (SmallTalk and Objective-C, for example) treat constructors and how that can be used as a form of scalability in design.
Why Java and C++ have limitations:
Using the approach of a constructor being special costs a class the ability to make intelligent decisions. This means that a constructor must give the caller an instance of the type that the user specified or throw some kind of exception to fail. This means that design paradigms such as a class cluster cannot be implemented without some kind of convention to ask the newly-constructed object to recreate itself as something more specialized. This may not seem like a problem to developers who are not used to how more generic OO languages work. However, I will outline the advantage from the other side, below.
How purer OO languages leverage this difference:
In a language such as SmallTalk or Objective-C, a constructor does not exist as some special entity. To instantiate an object, you ask the class to give you an instance. The important thing to note here is that it doesn't need to give you an instance of itself. This gives rise to the approach of passing this class method some arguments which describe the object you want, and it gives you a subclass of itself which is best suited to your needs.
This may not sound like a big deal except that the code asking for the new instance doesn't need to know anything about these subclasses. The only thing it needs to know is that the new instance should respond to the methods that the parent object claims it will. Thus, the user code always treats the new instance as a member of the class that it wants to think it is. Note that it may be something totally bogus but that isn't really a problem because it requires someone going out of their way to make meaningless code (and, in the case of Objective-C, ignoring a bunch of compiler warnings).
Objective-C's spin on this: The Class Cluster design pattern
What makes this even cleaner (in that it moves more decision making to safe code) is the approach that Objective-C takes with two-step initialization. For those of you not familiar with Objective-C, most objects are initialized by first asking the class for an instance and then asking that instance to initialize itself (the initializer just returns the instance). This is useful because the allocation class method returns an instance of a temporary class which knows how to do nothing except for receive these initialization methods which, in turn, cause it to return yet a different object (traditionally, another sub-class of the parent). Thus, when the dust has cleared, each object serves some purpose: the parent defines an interface and implements common code, the temporary class knows how to decide which one of its siblings to create, and the other sub-classes can focus on handling their specific formulations of the cluster's task.
This is part of the reason why complaints like why can't I just say "[MyClass new]"? (as stated by many starting Objective-C developers) tend to go away once the developer becomes used to the immense power (and elegant simplicity) of this approach. The new class method is provided to simply call [[MyClass alloc] init] but its use is often viewed as being similar to the training wheels on a bike and is discouraged.
What this really means:
This approach allows any class to grow into a class cluster without breaking code (since the knowledge of the cluster is limited to the class cluster, itself.
It is a good reason (among the countless others) to not try to shoe-horn concepts from other languages into another one.
(sorry if this is a little meaningless, I haven't slept in quite some time)