February 20, 2012
On 19.02.2012 01:40, H. S. Teoh wrote:
> One word: internationalization. Then toString() falls flat on its face. You can't even fix this by having Phobos do the translation internally. You can't expect users of Phobos to only ever support languages that Phobos has been previously translated to, for one thing. That would be a crippling disability. T 

Its even better, i want the exception message to be shown to the user in the current locales language.
But for the logs i want it to be in english since i have to maintain systems in other countries we sold our software to.
Its easy to connect to a remote system on the other side of the world, but its not so easy to read log files in a foreign
language.
February 20, 2012
On 02/20/2012 09:17 PM, Nick Sabalausky wrote:
>
>      // Second param is optional.
>      // Not sure if this can be a template mixin or has to be string mixin.
>      mixin createException!("AcmeException", "Exception");
>
>

It can be a template mixin that mixes in a string mixin declaration.
February 20, 2012
On 02/20/2012 03:23 PM, Jonathan M Davis wrote:
> I don't see how you could possibly make that uniform. It's very non-uniform by its very nature. The handling _needs_ to be non-uniform.
> 

The handling might need to be non-uniform, but the exception hierarchy doesn't.

Not talking about i18n formatting now.
Sometimes I'd like to add a 'trait' to an exception, but find myself needing
to create a new exception type just for that, which will sit oddly in the
hierarchy.

Consider the case of rethrowing an exception with added detail.

--jm

February 20, 2012
"H. S. Teoh" <hsteoh@quickfur.ath.cx> wrote in message news:mailman.704.1329767254.20196.digitalmars-d@puremagic.com...
> On Mon, Feb 20, 2012 at 08:36:56PM +0100, Andrej Mitrovic wrote:
>> On 2/20/12, Juan Manuel Cabo <juanmanuel.cabo@gmail.com> wrote:
>> > will be trouble. Instead please do:
>> >
>> >         "The '%1$s' file's size is %2$d which is wrong"
>> >
>>
>> That is the shittiest formatting specifier ever invented. The unreadability of it is why I never, ever, use it. Python solved this nicely with its {0} {1} syntax:
>>
>> >>> print '{0} and {1}'.format('foo', 'bar')
>
> Actually, even that isn't ideal. How is the translator to know what on earth {0} and {1} are? Sometimes you need to know in order to make a good translation. This would be even better:
>
> "The ${file}'s size is ${size}, which is wrong"
>
> The usefulness of named arguments is even more apparent in complex message like this one:
>
> "${file}:${line}: Expecting ${expectedtoken}, got ${inputtoken}"
>
> Without named parameters, you'd have:
>
> "{0}:{1}: expecting {2}, got {3}"
>
> which is almost impossible to translate. What are {0} and {1}? What are {2} and {3}? Does it mean "12:30pm: expecting program to succeed, got general protection fault"?
>
> Using named parameters makes it clear this is a parser error, not something else. This difference may mean using a completely different grammatical structure to translate the message.
>

vote++; I've been drooling over the idea of named argument format strings in D for a long while.

I also agree with posix-style specifiers being barely readable. I fell in love with C#'s "Hello {1}" style at first sight, and was thrilled that Tango adopted it. Then I moved to Phobos2, and have been missing those wonderful curly braces ever since.


February 20, 2012
> ...
> Sure. Again, this is not advocating replacement of exception hierarchies with tables!
> ...
> 
> Andrei
> 

I think that the case of rethrowing an exception with added detail is the worst
enemy of clean Exception hierarchies.
The idea of Variant[string] remedies that case without creating a new exception
class just for the added fields. If that case is solved, then the tipical need
for creating new exception types that don't really aid selecting them for
catching and recovery is solved too.

--jm


February 20, 2012
On Mon, Feb 20, 2012 at 03:17:44PM -0500, Nick Sabalausky wrote: [...]
> 2. The solution fails to cover the *entire* scope of the *real* problem: Classes that need to write boilerplate ctors which merely forward to the base class's ctors.  This issue is *not* limited to Exceptions, but Andrei's proposes solution *only* covers the case with Exceptions.
> 
> A better solution has already been proposed:
> 
>     class AcmeException : Exception
>     {
>         mixin inheritCtors!();  // Actual name open for bikeshedding
>     }

Somewhere in this giant thread, somebody has proposed that there should be language support for implicitly inheriting base class ctors. That is, if you write:

	class Base {
		this(string, int, float) { ... }
	}

	class Derived : Base { }

then the compiler will automatically insert this into Derived:

	this(string s, int i, float f) {
		super(s, i, f);
	}

I think this is a very useful mechanism that should be added to D. It will eliminate a lot of ctor boilerplate that you have to put in derived classes (not just exceptions, but in general). For example, if you have:

	class Base {
		this(string) {...}
		this(int) {...}
		this(float) {...}
	}

then currently, *every single derived class* must write wrappers to forward ctor arguments to each of those ctors, if they want to provide the same construction API as the base class. With the proposed enhancement, you'd just "inherit" all of the ctors automatically. (Not in the strict sense of inherit, but the compiler will create forwarding ctors for you automatically.)


T

-- 
Жил-был король когда-то, при нём блоха жила.
February 20, 2012
On 2/20/12 1:04 PM, foobar wrote:
> On Monday, 20 February 2012 at 17:47:35 UTC, Andrei Alexandrescu wrote:
>> On 2/20/12 11:32 AM, foobar wrote:
>>> On Monday, 20 February 2012 at 17:12:17 UTC, Andrei Alexandrescu wrote:
>>>> On 2/20/12 11:08 AM, Mafi wrote:
>>>>> If it's supposed to be simple factorization, then you should replace
>>>>> "throw r" with "return r". Then the name of that function doesn't make
>>>>> much sense anymore. But then you can better search for throw in user
>>>>> code and the stack traces aren't obfuscated anymore.
>>>>>
>>>>> throw createEx!AcmeException("....");
>>>>
>>>> I think that's a great idea, thanks.
>>>>
>>>> Andrei
>>>
>>> I fail to see the point in this. Why is the above better than
>>> throw AcmeException("....");
>>>
>>> If you want to avoid boilerplate code in the definition of
>>> AcmeException, this can be better accomplished with a mixin.
>>
>> The advantage is that e.g. the compiler can see that flow ends at
>> throw. Other languages have a "none" type that function may return to
>> signal they never end.
>>
>> Andrei
>
> I meant -
> what's the benefit of:
> throw createEx!AcmeException("....");
> vs.
> throw AcmeException("....");
>
> As far as I can see, the former has no benefits over the simpler latter
> option.

That's simply a workaround for non-inherited constructors - nothing more should be read into it.

Andrei


February 20, 2012
I don't think the Condition should be an Exception. I think it should provide a method that throw.

class Condition {
    void throw() pure {           // Or make it abstract
        throw new Exception();
    }
}

If no handler is found, this method is called. The handler can also call it.

It is very important to separate the Condition and the Exception. Several Condition may use the same Exception.

BTW, I don't think that something that can be implemented as lib should be added in the core language.

Condition may be use using something like raise(new MyCondition(params)); with raise from std.condition .

Alternatively, we could go metaprogramming for Condition, just like we did for Range.

Le 20/02/2012 21:18, H. S. Teoh a écrit :
>
>> 6/ This mecanism is provided as a lib.
>
> Not necessarily; it would be nice to have language support. But at least
> it's implementable as a lib (as I've shown), so we don't have to invest
> the time and effort to implement language support until we're sure it's
> a good idea, after thorough testing with the lib.
>
>
>> 7/ The mecanism is provided as a richer way to use Exceptions.
>>
>> Is it a solid base to start on ? I seems we need to start working on
>> std.condition ;) BTW, do we need language support to implement that ?
>> I don't think so, but I'm quite new to the issue.
>
> I'm not sure yet, but probably language support is be needed to reduce
> the amount of syntax you need to write just to define Conditions. Unless
> we can figure out a clever way of using templates or mixins or some such
> to make it easier to write.
>
> Ideally, you'd want to declare Conditions inside the catch block of the
> function, instead of making a separate class definition outside. But I'm
> not sure how to make such a thing work if the handler needs to know what
> methods are available in the first place. Perhaps a compromise is to use
> some templates with mixins to generate code for the Condition subclass
> and for the custom catch block for handling recovery strategies.
>
> Also, another issue that's still unclear to me is, if no handler is
> found and the Condition gets thrown, does it still make sense to throw
> the Condition object? Because once the stack unwinds, the recovery
> methods are probably no longer meaningful. Also, the fact that no
> handler was found means that no handler will ever be found, so the stack
> will just unwind to a catch block. And it's doubtful that at that level,
> the recovery options encoded in the Condition are usable at all.
>
> So some parts of this system need some rethinking.
>
>
> T
>

February 20, 2012
On 2/20/12 1:13 PM, Sean Kelly wrote:
> On Feb 20, 2012, at 9:55 AM, deadalnix wrote:
>>
>> And so variant is the way to go ?
>>
>> Clearly, this is a very strong arguement in favor of typed
>> Exception, that provide usefull information about what went wrong.
>> This is a safe approach.
>>
>> Because this Variant stuff is going to require massive ducktyping
>> of Exceptions, with all possible errors involved. The keys in the
>> Variant[string] will depend on the Exception the dev is facing.
>> This should be avoided and should warn us about the requirement of
>> typed Exceptions.
>
> I think its debatable whether a Variant[string] or string[string] is
> ideal here, but either way I think the point of the table is for
> localized error messages.  I wouldn't expect any data relevant for
> filtering the exception within the table.

Exactly.

The need for Variant instead of string is mainly to distinguish numeric info from string info when doing things like singular vs. plural or Arabic numeral rendering vs. textual ("one", "two" etc).


Andrei

February 20, 2012
PS: The more I think of this solution, the more I like it. It is really great !

It is more performant, avoid throwing when not necessary, and allow to do more. This is definitively something we should dig.