January 12, 2015
On 1/12/2015 6:57 AM, Martin Nowak wrote:
> The general solution in functional programming is error chaining.
> An example, C is a function that reads in lines of a program and B is a function
> that takes all those lines and counts words.
> C will either return an error or lines and B will either immediately return that
> error to A or convert the lines to word counts.
> This works especially well with function chaining, because you can hide the
> error propagation in a generic chaining method (called map).
>
> http://danielwestheide.com/blog/2012/12/26/the-neophytes-guide-to-scala-part-6-error-handling-with-try.html


Yes, it still appears to be just a wrapper around returning two values, and that has to be done for everything.

There's another downside to returning two values - extra code is generated, and it consumes another register. It allocates very scarce resources to rare cases - not a recipe for high performance.

January 12, 2015
On Monday, 12 January 2015 at 21:11:44 UTC, Walter Bright wrote:
> There's another downside to returning two values - extra code is generated, and it consumes another register. It allocates very scarce resources to rare cases - not a recipe for high performance.

In server applications there is no such thing as a rare case though and this trade-off looks quite appealing.
January 12, 2015
On Mon, Jan 12, 2015 at 08:32:57PM +0000, deadalnix via Digitalmars-d wrote:
> On Monday, 12 January 2015 at 13:33:40 UTC, John Colvin wrote:
[...]
> >Interesting little rant about exceptions (and more), from the author of a large and successful project in C++     http://250bpm.com/blog:4
> 
> Exception in C++ is different. It is full of pitfalls and generally a usability disaster. I can understand that C++ dev do not like exception, but that say more about C++ than it does about exceptions.

I used to throw char* in C++. 'Nuff said. :-)


T

-- 
This is a tpyo.
January 12, 2015
On Monday, 12 January 2015 at 18:07:55 UTC, Adam D. Ruppe wrote:
> On Monday, 12 January 2015 at 17:57:10 UTC, H. S. Teoh via Digitalmars-d wrote:
>> Still, #9584 had some discussions about doing lazy stack trace
>> construction, which was costing most of the time, but I don't remember if that was actually implemented.
>
> Yea, it was (I did it myself for posix, someone else did it on Windows), led to gigantic speed boosts, unless you are printing the trace, of course, when it has to be generated.

Can you elaborate on the technical details of that stunt ? When you need to build the trace, you often have unwinded part of the stack, so it does seems hard to build it lazily.
January 12, 2015
On Monday, 12 January 2015 at 20:32:59 UTC, deadalnix wrote:
> On Monday, 12 January 2015 at 13:33:40 UTC, John Colvin wrote:
>> On Monday, 12 January 2015 at 11:09:01 UTC, Walter Bright wrote:
>>> On 1/12/2015 3:02 AM, Tobias Pankrath wrote:
>>>> As far as I understand is, it requires each component to settle on the same
>>>> discriminated union that packs the error and result, which he calles Result but
>>>> is usually Choice in F#.
>>>>
>>>> Now in D we use the opDot to chain components, which works since we have UFCS.
>>>> In F# there a simply three different opDots: >>, >>= and >=> which take care of
>>>> the adaption.
>>>
>>> Or we could just use exceptions, which require none of that.
>>
>> Interesting little rant about exceptions (and more), from the author of a large and successful project in C++     http://250bpm.com/blog:4
>
> Exception in C++ is different. It is full of pitfalls and generally a usability disaster. I can understand that C++ dev do not like exception, but that say more about C++ than it does about exceptions.

Back when C++ got exceptions I never understood why so much paper was being wasted explained them, with articles on "The C/C++ Users Journal" and "C++ Report".

Having learned exceptions in more sane languages, they just felt natural to me.

But then it hit me, many of the issues are caused by the compatibility with C semantics and the pay only for what you use mantra.

--
Paulo
January 12, 2015
Walter Bright:

> Yes, it still appears to be just a wrapper around returning two values, and that has to be done for everything.

There's lot of functional theory behind such ideas.


> There's another downside to returning two values - extra code is generated, and it consumes another register. It allocates very scarce resources to rare cases - not a recipe for high performance.

I suggest to start inverting your point of view: try to look why the F#/Haskell way of managing errors is good in those languages...

In bugzilla I asked for a "maybeTo" that is similar to the "to" Phobos function, but it's @nogc nothrow because it returns an Nullable!T result.

Bye,
bearophile
January 12, 2015
On 1/12/15 1:35 PM, bearophile wrote:
> Walter Bright:
>
>> Yes, it still appears to be just a wrapper around returning two
>> values, and that has to be done for everything.
>
> There's lot of functional theory behind such ideas.
>
>
>> There's another downside to returning two values - extra code is
>> generated, and it consumes another register. It allocates very scarce
>> resources to rare cases - not a recipe for high performance.
>
> I suggest to start inverting your point of view: try to look why the
> F#/Haskell way of managing errors is good in those languages...
>
> In bugzilla I asked for a "maybeTo" that is similar to the "to" Phobos
> function, but it's @nogc nothrow because it returns an Nullable!T result.

I can't believe I agree with everything bearophile just said :o). -- Andrei
January 12, 2015
On Monday, 12 January 2015 at 21:03:43 UTC, Walter Bright wrote:
> Bringing up IEEE 754 FP exceptions as an example of it being "done right" when it is a complete failure severely damages your case.

I am bringing up exception-handling as what it is. Handling an exception involves resolving an issue and continue if suitable. Traps. Exceptions. Whatever. Has been available in CPUs since the dawn of time. It is just a means to defer decisions to the context before continuing.

The fact that this puts an unrealistic demand on library authors to be excellent designers, and language design issues, resulted in the cheap solution which basically is transactional: roll back and try again with new parameters. That is of course more inefficient than resolving the issue in situ, but easier to design.
January 12, 2015
On Monday, 12 January 2015 at 21:11:44 UTC, Walter Bright wrote:
> On 1/12/2015 6:57 AM, Martin Nowak wrote:
>> The general solution in functional programming is error chaining.
>> An example, C is a function that reads in lines of a program and B is a function
>> that takes all those lines and counts words.
>> C will either return an error or lines and B will either immediately return that
>> error to A or convert the lines to word counts.
>> This works especially well with function chaining, because you can hide the
>> error propagation in a generic chaining method (called map).
>>
>> http://danielwestheide.com/blog/2012/12/26/the-neophytes-guide-to-scala-part-6-error-handling-with-try.html
>
>
> Yes, it still appears to be just a wrapper around returning two values, and that has to be done for everything.

Yes, you wrap the return values, but it doesn't require to deal with errors in B.

> There's another downside to returning two values - extra code is generated, and it consumes another register. It allocates very scarce resources to rare cases - not a recipe for high performance.

To defend that argument we'd first have to fix our own codegen.
https://issues.dlang.org/show_bug.cgi?id=12442

It doesn't really consume the register, because the error value is only needed directly after the call for a possible early return. But of course returning tuples can be less efficient.

OT!!
Reminds me of Manu's request for more efficient register return.
www.digitalmars.com/d/archives/digitalmars/D/Multiple_return_values..._160353.html
January 12, 2015
On Monday, 12 January 2015 at 21:34:20 UTC, Paulo Pinto wrote:
> But then it hit me, many of the issues are caused by the compatibility with C semantics and the pay only for what you use mantra.

Yeah, C++ exceptions were originally so troubled that no sane person would use them, thus you did not get the culture where most code was designed for it and "C++ with no exceptions and no rtti" became a mantra... For exception handling to shine you need consistency backed by culture. It is probably the culture around languages like Java and Python that foster that.

(Most of std::C++ is optional, templated and inefficient... There is no consistent culture. Though they got some thing right with unique_ptr and new language features recently.)