Google's Go & Exceptions

Yigal Chripun yigal100 at gmail.com
Sun Jan 31 06:30:46 PST 2010


On 27/01/2010 02:57, Justin Johansson wrote:
> Ary Borenszweig wrote:
>> Walter Bright wrote:
>>> Justin Johansson wrote:
>>>> (1) For some reason (possibly valid only in an historic context), I
>>>> have this great aversion to throwing exceptions from inside C++
>>>> constructors. From memory, I once threw an exception from inside a
>>>> constructor
>>>> with an early C++ compiler and wound up with stack corruption or
>>>> something like that, and consequently I developed the practice of
>>>> forever more avoiding throwing from inside a C++ constructor.
>>>
>>> I'm a believer in the methodology that a constructor should be
>>> "trivial" in that it cannot fail (i.e. cannot throw). I'm probably in
>>> the minority with that view, but you shouldn't feel like you're doing
>>> the wrong thing when you stick to such a style.
>>
>> auto x = new BigInt(someString);
>>
>> How do you implement BigInt's constructor without being able to throw
>> an exception? Or would you do it like:
>>
>> auto x = BigInt.fromString(someString);
>>
>> to be able to throw? (just to obey the "no throw in constructors"...
>> but that's not as trivial as the previous form)
>
> A factory method is the way to go. Different languages give you
> different means for achieving this design pattern but nevertheless
> all such means make for the better factoring of code.
>
> In C++ there are three means :-
>
> (1) Use of static class member, so your example would like like this:
>
> BigInt x = BitInt::fromString( someString);
>
> (2) Use of () function call operator overload on a factory class
> so your example would now look like this
>
> BigIntFactory bigIntFactory; // may be statically declared
> BigInt x = bigIntFactory( someString);
>
> (3) Global function, which I won't discuss any futher for obvious reasons.
>
> In D, similar to C++, though function call () operator overload is
> effected in much cleaner fashion with D's absolutely wonderful
> static opCall. So your example would look something like this
> (as said earlier I haven't done D for 6 months so pls forgive
> any error in detail) :
>
> class BigInt
> {
> static BigInt opCall( someString)
> {
> if (!validate( someString))
> throw someError;
>
> // extract data for BitInt instance somehow
> // from string .. maybe tied into validate function
>
> byte[] bigIntData = ...
>
> return new BigInt( bigIntData);
> }
>
> this( byte[] bigIntData)
> {
> this.bigIntData = bigIntData;
> }
>
> private: byte[] bigIntData;
>
> // other BigInt methods ...
>
> }
>
> Now in D,
>
> BigInt x = BigInt( someString);
>
>
>
> In Java, well, let's not discuss that here. :-)
>
> In Scala you have "companion classes" that go hand-in-hand with
> the regular class. Scala uses companion classes to reduce the
> noise that the static class members introduce in other languages.
>
> (Example anybody?)
>
>
> Summary for D:
>
> It really isn't that much work to use D's static opCall() to
> good effect and, IMHO, complex designs do end up a lot cleaner.
> As they say, necessity is the mother of invention. It seems to
> me that both Scala and D have been driven by necessity in the
> design of companion classes and static opCall respectively.
>
> Cheers
> Justin Johansson

Factories are a hack to overcome limitations of the language, mainly the 
fact that constructors aren't virtual.
The above solution(s) have two main drawbacks: testability and 
Multi-threading will be affected.







More information about the Digitalmars-d mailing list