Thread Links Date Links
Thread Prev Thread Next Thread Index Date Prev Date Next Date Index

Re: textToIntevsal(s) and exceptions



Am 23.03.2015 um 20:56 schrieb Marco Nehmeier:
Am 23.03.2015 um 19:22 schrieb Oliver Heimlich:
Am 23.03.2015 um 18:14 schrieb John Pryce:
For promotion I'm undecided, and wait for advice from language
experts.
If it's part of the standard, does that make it different at
implementation
level, from making it a consequence of library design and language
features,
e.g., by using class inheritance?

Do you have an example?

No, I am hoping you, Dmitry or Marco can provide some. I was
thinking, suppose in C/C++ one has code like
   string s = "[1,2]";
   decoratedInterval x;
   x = textToInterval(s);
and textToInterval *doesn't* implement line 5 in my text above.

Is there any mechanism in the language to make it try *bare*
textToInterval, after *decorated* textToInterval sees s is not a
decorated literal, and then apply newDec?
Now I think about it, I guess the answer must be No, except by
explicitly coding it into decorated textToInterval.

I can give an example with the GNU Octave interval package (version
0.1.4), where “infsup” implements the bare textToInterval and
“infsupdec” implements the decorated textToInterval.

This implementation automatically promotes bare intervals if the user
calls an operations with mixed arguments, i. e. if at least one
operand is decorated. Whether this has been a good or bad decision
remains to be seen. Demotion does not happen automatically and the
user must explicitly call “intervalpart” for that purpose.

pkg load interval

x = infsup ("[1,2]");        # [1, 2]
y = infsupdec ("[1,2]");     # [1, 2]_com (automatic promotion cf. (5))
z = infsupdec ("[1,2]_dac"); # [1, 2]_dac

y + z # [2, 4]_dac (decorated operation evaluation)
y + x # [2, 4]_com (input x became promoted)
z + x # [2, 4]_dac (input x became promoted)


In my opinion we should avoid implicit conversion between bare and
decorated intervals
as well as using inheritance...

Example.

two classes:
     interval
     decorated_interval (inherited from interval)

if we have a user function like

     interval foo(interval x)

which is only implemented for bare intervals.

In many languages a call of foo with a decorated interval x_d will throw
the the decoration d away
because x_d is an object of decorated_interval which is inherited from
interval. Hence x_d is an interval x.

If we additionally have implicit conversion from interval to
decorated_interval like in Olivers example
than the result of this expression

     decorated_interval("[1,2]_com") + foo(
decorated_interval("[4,5]_def")  )

has the decoration com.


Marco

Yes, any demotion would be considered an error in that context. Such an error can also be very dangerous if it is buried unnoticed inside an interval arithmetic chain of computation.

However, I do not agree with Marco's conclusion to not use inheritance for that reason. A design that can prevent this kind of error, as used by libieeep1788, requires a strongly typed language. In any other language which comes to my mind—except C++—such a design would be a pain in the neck for developers and probably users too. And for what cost?

The error presented above with the function foo would be an obvious one and would not be part of a well tested library. So the function foo would reside in user space. In order to not return a decorated interval the function would have to explicitly use a bare interval constructor, since any return value from correctly working functions would be decorated. Decorated intervals are an integral part of the standard and I hope that they will be used by default in the future. In the example above, any input is decorated, so why should the function foo be implemented for bare intervals in the first place? And if so, why is a decorated variant missing?

Let me draw the big picture, why I find automatic promotion so useful. This has several reasons: 1. It is what the decorated interval constructors do when decoration information is missing, which I find convenient. 2. The decoration carries information about the course of computation. If it is missing, it should be introduced. However, that may also be problematic if it happens too late (*). 3. It simplifies exercising interval arithmetic, when also applied to coefficients (again for convenience).

For example, it consistently allows the following possibilities when writing interval arithmetic routines:

pkg load interval
x = infsupdec ("[1,2]"); # [1, 2]_com

x *= 2         # [2, 4]_com (2 became a decorated interval [2, 2]_com)
x += "1.1"     # [3.0999999999999996, 5.1000000000000006]_com
               # (1.1 became a decorated interval enclosure)
x /= "[1,2]"   # [1.5499999999999998, 5.1000000000000006]_com
               # ([1,2] became a decorated interval [1, 2]_com)
x -= "[0,Inf]" # [-Inf, +5.1000000000000006]_dac
               # ([0,Inf] became a decorated interval [0, Inf]_dac)

(*) However, it also provides a new possibility for the user to shoot himself in the foot:

x = pow (infsup (0, 1), 0) # [1, 1]
                           # (a decoration “trv” is missing)
infsupdec ("[1,2]") + x    # [2, 3]_com

As you can see in this example, it becomes dangerous to not use decorated arithmetic by default together with (late) promotion of bare intervals. As a user I could live with that risk, if I have complete control over ensuring an uninterrupted decorated computation from start to finish.

There are valid points for either allowing implicit promotion or not. I believe we all agree that implicit demotion is bad. If we allow implicit promotion within the constructors, e.g. textToInterval("[1,2]") == [1, 2]_com for the decorated variant, it is consistent to allow it elsewhere too.