Re: Checked vs unchecked exceptions

2017-07-07 Thread Moritz Maxeiner via Digitalmars-d

On Friday, 7 July 2017 at 18:48:31 UTC, Marco Leise wrote:

Am Thu, 06 Jul 2017 13:16:23 +
schrieb Moritz Maxeiner :

That's right, but still one can distill general ideas and leave 
implementations details aside. Pretty much like the Platonic 
Ideal. Then you look at what the complaints are with the 
current implementation and see if you can satisfy all sides.


The requirement checked exceptions impose on all functions to 
declare their respective exception set is not an implementation 
detail, but part of the definition.
With regards to the general ideas: That's what my writing about 
exception sets, tehir inference, and nothrow analysis were 
(supposed to be) about.
Unless, however, whatever one eventually tries to get into the 
language (if that is even attempted) conforms to the preexisting 
definition of checked exceptions (which I'm as certain as I can 
reasonably be won't make it into D), calling it that will only 
serve to cloud the issue and alienate people.
Personally, I would call a system with the exception set of a 
function being (optionally) declarable as "declarable 
exceptions", but that might still be too close to "checked 
exceptions" not to illicit screams of horror.




[...]

I.e. everything stays the same until a programmer needs a 
verification of what (s)he should/could handle right away, what 
needs to be wrapped and what can be passed further up the call 
chain. That's close to impossible now in deeply nested code.


If one replaces the `@check_exceptions` with `nothrow` the above 
is essentially what one should get if one enhances the (static) 
nothrow analysis (as I mentioned in an earlier post) to 
essentially treat a scope implicitly as nothrow if the aggregated 
exception set (as determined by the compiler) is empty.

Or more succinct: Infer `nothrow` for normal functions, as well.

In other cases an exception is only thrown when an incorrect 
argument is passed. Knowing (statically) that you pass only 
good values you can catch the exception and turn it into an 
assert instead of passing it up the call chain, potentially 
allowing the caller to be nothrow.


There are two cases here:
 - the function takes untrusted user data:
   Violations are valid runtime behaviour -> Exceptions, error 
codes, split in validation and processing function pair with the 
second being executed only after the first has successfully 
validated the input data (and thus transformed it into trusted 
program data), etc.

 - the function takes trusted program data:
   Violations are bugs -> assert, Error, DbC, etc.



Re: Checked vs unchecked exceptions

2017-07-07 Thread Marco Leise via Digitalmars-d
Am Thu, 06 Jul 2017 13:16:23 +
schrieb Moritz Maxeiner :

> On Thursday, 6 July 2017 at 11:01:26 UTC, Marco Leise wrote:
> > Am Thu, 06 Jul 2017 01:31:44 +
> > schrieb Moritz Maxeiner :
> >  
> >> But to be clear (and the title and description of any DIP
> >> addressing this should reflect this):
> >> These are not checked exceptions, because checked exceptions
> >> would require bar to declare its exception set manually.  
> >
> > Yep, absolutely clear. Just like "auto a = 1" does not declare
> > a variable as we all know declarations start with a type.  
> 
> Red herring.
> […]
> 
> ---
> void foo() throws AExp throws BExc { ... }
> void bar1() { foo(); } // Checked exceptions require this to 
> result in a compilation error
> void bar2() throws AExc throws BExc { foo(); } // this must be 
> used for checked exceptions
> ---

You are right, it was a red herring. The code example makes it
very obvious that inference means letting the exceptions slip
through unchecked and out of main() in the wildest case.

> Invalid premise. The definition of checked exceptions is de facto 
> fixed by Java [1], because it not only coined the term but 
> remains the only major PL to use them.

That's right, but still one can distill general ideas and
leave implementations details aside. Pretty much like the
Platonic Ideal. Then you look at what the complaints are with
the current implementation and see if you can satisfy all
sides.

I don't know if this is any good beyond an example of a
different implementation of checked exceptions, but here is
one option against the "every function in the call chain
accumulates more and more 'throws' declarations":

  /**
   * Throws:
   *   ZeroException when i is 0
   *   NonZeroException when i is not 0
   */
  void foo(int i) {
if (i == 0) throw new ZeroException();
throw new NonZeroException();
  }

  void bar(int i) @check_exceptions {
foo(i);  // Error: The following exceptions are not
  handled:
 // ZeroException thrown from foo() when i is 0
 // NonZeroException thrown from foo() when i is not 0
  }

I.e. everything stays the same until a programmer needs a
verification of what (s)he should/could handle right away,
what needs to be wrapped and what can be passed further up the
call chain. That's close to impossible now in deeply nested
code.

Resource unavailability prone to race conditions can often be
handled by asking the user to fix the issue and continue for
example (including network, disk space, RAM, video encoding
hardware slots, exclusive microphone use).

In other cases an exception is only thrown when an incorrect
argument is passed. Knowing (statically) that you pass only
good values you can catch the exception and turn it into an
assert instead of passing it up the call chain, potentially
allowing the caller to be nothrow.
-- 
Marco



Re: Checked vs unchecked exceptions

2017-07-07 Thread Biotronic via Digitalmars-d

On Thursday, 6 July 2017 at 14:59:10 UTC, Crayo List wrote:
On Wednesday, 5 July 2017 at 21:05:04 UTC, Ola Fosheim Grøstad 
wrote:

On Wednesday, 5 July 2017 at 15:48:33 UTC, Crayo List wrote:

What happens to the 3000 direct and indirect calls to open() ?

Notice how the 'interface' has not changed, only the 
implementation.


No, the exception spec is part of the interface whether it is 
in the function declaration  or not.


I disagree!
Once an interface is defined you should be able to alter the 
implementation all you want without impacting client code!


Correct. And throwing a different kind of exception changes the 
interface, and *does* impact client code. Consider:


void fun() {
try {
gun();
} catch (GoodException goodEx) {
// Ignore
} catch (Exception badEx) {
FireZeeMissiles();
}
}

void gun() {
throw new GoodException ();
}

Now J. Random Programmer decides to change gun()'s implementation:

void gun() {
throw new BadException();
}

If your assertion that this doesn't change the interface and 
doesn't impact the client is correct, no missiles will be fired. 
Sadly, this is not the case, and Switzerland is now wiped off the 
map.


--
  Biotronic


Re: Checked vs unchecked exceptions

2017-07-06 Thread Crayo List via Digitalmars-d
On Wednesday, 5 July 2017 at 21:05:04 UTC, Ola Fosheim Grøstad 
wrote:

On Wednesday, 5 July 2017 at 15:48:33 UTC, Crayo List wrote:

What happens to the 3000 direct and indirect calls to open() ?

Notice how the 'interface' has not changed, only the 
implementation.


No, the exception spec is part of the interface whether it is 
in the function declaration  or not.


I disagree!
Once an interface is defined you should be able to alter the 
implementation all you want without impacting client code!



Such a change could be
fatal in any system.


No idea what you mean here.

What you should do is to specify what Exceptions are thrown 
across module borders. That means you should recast the 
internal exceptions into module-level exceptions.


I don't need to do anything since I don't have a problem. I don't 
understand what are you helping me with. I pointed out how 
checked exceptions 'leak' internal implementation, that was all.







Re: Checked vs unchecked exceptions

2017-07-06 Thread Moritz Maxeiner via Digitalmars-d

On Thursday, 6 July 2017 at 11:01:26 UTC, Marco Leise wrote:

Am Thu, 06 Jul 2017 01:31:44 +
schrieb Moritz Maxeiner :


But to be clear (and the title and description of any DIP
addressing this should reflect this):
These are not checked exceptions, because checked exceptions
would require bar to declare its exception set manually.


Yep, absolutely clear. Just like "auto a = 1" does not declare
a variable as we all know declarations start with a type.


Red herring.
Checked exceptions are well defined - not just implemented - (by 
Java as the de facto authority for the term) as requiring the 
declaration of all exceptions (that aren't inherited from some 
special class, in Java's case `RuntimeException`, in D's it would 
be `Error`) that may be thrown by a function as a result of its 
body being executed [1]. If even a single function is allowed to 
have its exception set defined by inference (instead of 
declaration), you are not implementing checked exceptions.


---
void foo() throws AExp throws BExc { ... }
void bar1() { foo(); } // Checked exceptions require this to 
result in a compilation error
void bar2() throws AExc throws BExc { foo(); } // this must be 
used for checked exceptions

---


Instead of defining checked exceptions how it bests fits all
your posts in this thread, why not say "Checked exceptions as
implemented in Java were a good idea, had they allowed the
compiler to infer them where possible."


Invalid premise. The definition of checked exceptions is de facto 
fixed by Java [1], because it not only coined the term but 
remains the only major PL to use them.



Of course we can still call those inferred checked exceptions
something else. ;o)


The java compiler does infer an exception set for every function 
based on its body.
This is then checked against the function's exception set as 
declared in its signature.
"inferred checked exceptions" is thus an oxymoron, because it 
would mean checking the inferred exception set against itself.


[1] 
https://docs.oracle.com/javase/7/docs/api/java/lang/Exception.html


Re: Checked vs unchecked exceptions

2017-07-06 Thread Marco Leise via Digitalmars-d
Am Thu, 06 Jul 2017 01:31:44 +
schrieb Moritz Maxeiner :

> But to be clear (and the title and description of any DIP 
> addressing this should reflect this):
> These are not checked exceptions, because checked exceptions 
> would require bar to declare its exception set manually.

Yep, absolutely clear. Just like "auto a = 1" does not declare
a variable as we all know declarations start with a type.
Instead of defining checked exceptions how it bests fits all
your posts in this thread, why not say "Checked exceptions as
implemented in Java were a good idea, had they allowed the
compiler to infer them where possible."
Of course we can still call those inferred checked exceptions
something else. ;o)

-- 
Marco



Re: Checked vs unchecked exceptions

2017-07-06 Thread crimaniak via Digitalmars-d

On Thursday, 6 July 2017 at 01:31:44 UTC, Moritz Maxeiner wrote:

---
void foo() throws AException throws BException { ... }
vod bar() { foo(); }
---

works and bar's exception is inferred by the compiler to 
contain AException and BException.


But to be clear (and the title and description of any DIP 
addressing this should reflect this):
These are not checked exceptions, because checked exceptions 
would require bar to declare its exception set manually.
 Not checked in sense of Java, but Java has no deductible 
exceptions. If compiler will fail on `void bar() { foo(); } 
throws AException;` we still can call it 'checked', I think. In 
sense of D.




Re: Checked vs unchecked exceptions

2017-07-05 Thread Moritz Maxeiner via Digitalmars-d

On Wednesday, 5 July 2017 at 20:35:14 UTC, Marco Leise wrote:

Am Wed, 28 Jun 2017 11:04:58 +
schrieb Moritz Maxeiner :

One could also make an exception for bodyless functions and 
allow specification of the exception set *only* there, e.g.


---
// Allow "checked exceptions" for stubs only
void foo() throws AException throws BException;
---


Ah, come one, now that you see the need you can also embrace it 
as an option for people who want to add some documentation.


After some more consideration I would be amenable to automatic 
inference of the exception set as the default with *optional* 
manual specification, i.e.


---
void foo() throws AException throws BException { ... }
vod bar() { foo(); }
---

works and bar's exception is inferred by the compiler to contain 
AException and BException.


But to be clear (and the title and description of any DIP 
addressing this should reflect this):
These are not checked exceptions, because checked exceptions 
would require bar to declare its exception set manually.


Re: Checked vs unchecked exceptions

2017-07-05 Thread Ola Fosheim Grøstad via Digitalmars-d

On Wednesday, 5 July 2017 at 15:48:33 UTC, Crayo List wrote:

What happens to the 3000 direct and indirect calls to open() ?

Notice how the 'interface' has not changed, only the 
implementation.


No, the exception spec is part of the interface whether it is in 
the function declaration  or not. Such a change could be fatal in 
any system.


What you should do is to specify what Exceptions are thrown 
across module borders. That means you should recast the internal 
exceptions into module-level exceptions.




Re: Checked vs unchecked exceptions

2017-07-05 Thread Marco Leise via Digitalmars-d
In general, I'm of the opinion that DLL API should be fully
explicit. It's the only way you can reasonably provide
ABI stability. That means no templates, no attribute inference
and explicit exception lists if the compiler were to used them.

-- 
Marco



Re: Checked vs unchecked exceptions

2017-07-05 Thread Marco Leise via Digitalmars-d
Am Wed, 28 Jun 2017 11:04:58 +
schrieb Moritz Maxeiner :

> One could also make an exception for bodyless functions and allow 
> specification of the exception set *only* there, e.g.
> 
> ---
> // Allow "checked exceptions" for stubs only
> void foo() throws AException throws BException;
> ---

Ah, come one, now that you see the need you can also embrace
it as an option for people who want to add some documentation.

void foo()
  throws AException  // When the ant's life ends prematurely
  throws BException; // When the ant gets distracted by a lady bug

-- 
Marco



Re: Checked vs unchecked exceptions

2017-07-05 Thread Crayo List via Digitalmars-d
On Tuesday, 4 July 2017 at 10:14:11 UTC, Ola Fosheim Grøstad 
wrote:

On Monday, 3 July 2017 at 20:22:39 UTC, Crayo List wrote:
On Thursday, 29 June 2017 at 21:06:12 UTC, Ola Fosheim Grøstad 
wrote:

On Thursday, 29 June 2017 at 19:34:22 UTC, Crayo List wrote:
Checked exceptions are a horrible idea because they leak 
internal implementation details as part of the signature of 
a method directly and in a transitive manner, which of 
course is one huge aberration!


What do you mean? Exceptions that leave a module clearly 
aren't internal implementation details…


Correct!
But I said 'checked exceptions' are.


How does "checked" affect whether something is internal or not?


int open(string file)
{
 if(!exists(file))
throw new SomeException;

...
}

a few weeks later;

int open(string file)
{
if(file == null)
   threw new NullSomethingException;

 same as before
}

What happens to the 3000 direct and indirect calls to open() ?

Notice how the 'interface' has not changed, only the 
implementation.








Re: Checked vs unchecked exceptions

2017-07-04 Thread Ola Fosheim Grøstad via Digitalmars-d

On Monday, 3 July 2017 at 20:22:39 UTC, Crayo List wrote:
On Thursday, 29 June 2017 at 21:06:12 UTC, Ola Fosheim Grøstad 
wrote:

On Thursday, 29 June 2017 at 19:34:22 UTC, Crayo List wrote:
Checked exceptions are a horrible idea because they leak 
internal implementation details as part of the signature of a 
method directly and in a transitive manner, which of course 
is one huge aberration!


What do you mean? Exceptions that leave a module clearly 
aren't internal implementation details…


Correct!
But I said 'checked exceptions' are.


How does "checked" affect whether something is internal or not?


Re: Checked vs unchecked exceptions

2017-07-03 Thread Crayo List via Digitalmars-d
On Thursday, 29 June 2017 at 21:06:12 UTC, Ola Fosheim Grøstad 
wrote:

On Thursday, 29 June 2017 at 19:34:22 UTC, Crayo List wrote:
Checked exceptions are a horrible idea because they leak 
internal implementation details as part of the signature of a 
method directly and in a transitive manner, which of course is 
one huge aberration!


What do you mean? Exceptions that leave a module clearly aren't 
internal implementation details…


Correct!
But I said 'checked exceptions' are.


Re: Checked vs unchecked exceptions

2017-07-03 Thread Jonathan M Davis via Digitalmars-d
On Wednesday, June 28, 2017 21:47:56 Nick Sabalausky  via Digitalmars-d 
wrote:
> On 06/25/2017 01:38 PM, mckoder wrote:
> > I am disappointed that D doesn't have checked exceptions.
>
> Huh? Is it April 1st?

That was kind of my reaction. It has been my impression that while many
folks initially seem to think that checked exceptions are a good idea, it
has generally been accepted by the programming community at large that they
are in fact a bad idea. AFAIK, Java is the only language to have checked
exceptions, and every language that has come after has avoided them.

Regardless, based on what Walter has said previously, I think that it's
quite clear that there is zero danger of checked exceptions ever being added
to D and thus there is really no need to spend time or energy arguing about
it, which is part of why I've essentially ignored this thread (and is
probably why a lot of major posters have ignored it). I have too little time
to spend on D-related things right now as it is. LOL. On that count, I
probably shouldn't even have spent the time to reply to this...

- Jonathan M Davis



Re: Checked vs unchecked exceptions

2017-06-29 Thread Ola Fosheim Grøstad via Digitalmars-d

On Thursday, 29 June 2017 at 19:34:22 UTC, Crayo List wrote:
Checked exceptions are a horrible idea because they leak 
internal implementation details as part of the signature of a 
method directly and in a transitive manner, which of course is 
one huge aberration!


What do you mean? Exceptions that leave a module clearly aren't 
internal implementation details…




Re: Checked vs unchecked exceptions

2017-06-29 Thread Crayo List via Digitalmars-d

On Monday, 26 June 2017 at 15:40:19 UTC, mckoder wrote:


Here's the point: with checked exceptions good programmers can 
write good code. Without checked exceptions even good 
programmers are forced to write bad code.


This statement is logically equivalent to "good code can only be 
written with checked exceptions (presumably using Java), all 
other code is bad".


Checked exceptions are a horrible idea because they leak internal 
implementation details as part of the signature of a method 
directly and in a transitive manner, which of course is one huge 
aberration!






Re: Checked vs unchecked exceptions

2017-06-28 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 06/25/2017 01:38 PM, mckoder wrote:

I am disappointed that D doesn't have checked exceptions.



Huh? Is it April 1st?


Re: Checked vs unchecked exceptions

2017-06-28 Thread Ola Fosheim Grøstad via Digitalmars-d

On Tuesday, 27 June 2017 at 16:54:08 UTC, Sebastien Alaiwan wrote:
adorned with a do-try block, or a try!, or a try?. There is no 
way, in this language, to silently throw an exception all the 
way to the top level; without paving a super-hiway for it up 
through the entire calling tree."


I don't think this is the best argument, if the programmer wants 
to reduce the number of exceptions that are propagated then the 
exception should be recast to a more abstract exception between 
module boundaries.


So the "super highway" issue is more a result of the programmer 
not being interested in structuring error-handling, but rather 
view errors as something that never should happen. Which may make 
sense in some applications, but not in all.


Re: Checked vs unchecked exceptions

2017-06-28 Thread Moritz Maxeiner via Digitalmars-d

On Wednesday, 28 June 2017 at 06:31:40 UTC, Biotronic wrote:

On Monday, 26 June 2017 at 19:31:53 UTC, Moritz Maxeiner wrote:

the good *way* to achieve this result would be the following:
- When visiting `startFoo`, the compiler automatically 
aggregates all different exceptions it may throw and stores 
the resulting set
- If `startFoo` is going to be part of a (binary) library and 
its symbol is exported, also export its exception set
- Improve the compiler's nothrow analysis such that if 
startFoo is called in scope S, but all of the exceptions in 
its exception set are caught (i.e. can't break out of scope 
S), it is treated as nothrow in S.

- Enclose the call to `startFoo` in B in a nothrow scope.


So I have this .dll. How do I specify which exceptions it 
throws?


- Static/Dynamic linking: As said in bullet point two above, the 
exception set would have to be exported (more precise: in such a 
way that it can be loaded again at compile time); there are 
several ways to go about that: Add the exception set (e.g. via 
attributes) to the function declarations in a .di file (which 
could indeed look like checked exception, except that it's auto 
generated), use a separate (binary) file with mangled functions 
names to exception set mapping, etc.

- Dynamic loading: Won't work

One could also make an exception for bodyless functions and allow 
specification of the exception set *only* there, e.g.


---
// Allow "checked exceptions" for stubs only
void foo() throws AException throws BException;
---


Re: Checked vs unchecked exceptions

2017-06-28 Thread Biotronic via Digitalmars-d

On Monday, 26 June 2017 at 19:31:53 UTC, Moritz Maxeiner wrote:

the good *way* to achieve this result would be the following:
- When visiting `startFoo`, the compiler automatically 
aggregates all different exceptions it may throw and stores the 
resulting set
- If `startFoo` is going to be part of a (binary) library and 
its symbol is exported, also export its exception set
- Improve the compiler's nothrow analysis such that if startFoo 
is called in scope S, but all of the exceptions in its 
exception set are caught (i.e. can't break out of scope S), it 
is treated as nothrow in S.

- Enclose the call to `startFoo` in B in a nothrow scope.


So I have this .dll. How do I specify which exceptions it throws?

--
  Biotronic


Re: Checked vs unchecked exceptions

2017-06-27 Thread Moritz Maxeiner via Digitalmars-d

On Wednesday, 28 June 2017 at 02:09:40 UTC, Moritz Maxeiner wrote:


---
static assert (throwsExactly!(foo, AException, BException));
void foo() { ... }
---


One could even go a bit farther and implement a mixin template 
using `typeof(this)` and do:


---
void foo()
{
mixin ThrowsExactly!(AException, BException);
}
---


Re: Checked vs unchecked exceptions

2017-06-27 Thread Moritz Maxeiner via Digitalmars-d

On Wednesday, 28 June 2017 at 01:35:32 UTC, mckoder wrote:

On Tuesday, 27 June 2017 at 22:56:47 UTC, Moritz Maxeiner wrote:


You mean the very first time you want to call it and you don't 
know the exception set yourself by looking at its signature?
Put the call in a nothrow scope and compile the module (which 
is fast in D), the compiler will then complain which 
exceptions you didn't catch (requires improvement of nothrow 
analysis [1]).




So to know what exceptions are possible you have to compile the 
code?


That, or do the even faster thing and use what's written in the 
documentation (which a sensible person might generate 
automatically, embedding the generated exception set for each 
function).

There are only two outcomes (sans compiler bugs):
- What's written there is correct -> It will compile and you're 
fine
- What's written there is incorrect -> It won't compile and tell 
you what's missing
In the 2nd case you have discovered a bug in whatever codebase 
you are using. Report it.


I consider that inferior to other solutions such as callee 
explicitly stating what exceptions it may throw, because then 
all you have to do is glance at the callee.


On the one hand you have a small one-time cost (I would go as far 
as calling it tiny, since I consider it a reasonable assumption 
for you to have the documentation open), on the other hand you 
have a one-time cost with its size depending on the call 
hierarchy level and small constant maintenance costs on every 
change.
If you consider the first inferior to the second, that's your 
call, but I disagree strongly.
That being said, nothing prevents you from putting it there 
anyway:


---
static assert (throwsExactly!(foo, AException, BException));
void foo() { ... }
---

Also, I think  explicitly stating your intent in this manner 
(by the callee not just the caller) is a good idea, to make 
sure you are not throwing some exception you didn't mean to 
throw.


Add a static assert as shown above and you're done.


Re: Checked vs unchecked exceptions

2017-06-27 Thread mckoder via Digitalmars-d

On Tuesday, 27 June 2017 at 22:56:47 UTC, Moritz Maxeiner wrote:


You mean the very first time you want to call it and you don't 
know the exception set yourself by looking at its signature?
Put the call in a nothrow scope and compile the module (which 
is fast in D), the compiler will then complain which exceptions 
you didn't catch (requires improvement of nothrow analysis [1]).




So to know what exceptions are possible you have to compile the 
code? I consider that inferior to other solutions such as callee 
explicitly stating what exceptions it may throw, because then all 
you have to do is glance at the callee. Also, I think explicitly 
stating your intent in this manner (by the callee not just the 
caller) is a good idea, to make sure you are not throwing some 
exception you didn't mean to throw.




Re: Checked vs unchecked exceptions

2017-06-27 Thread Moritz Maxeiner via Digitalmars-d

On Tuesday, 27 June 2017 at 21:47:49 UTC, jag wrote:

On Tuesday, 27 June 2017 at 19:37:24 UTC, Moritz Maxeiner wrote:


As I have pointed out, your example occurs on the *caller* 
side, not the *callee* side. The proper solution is not for 
the callee to specify which exceptions it may throw, but for 
the caller to specify which exceptions it allows the callee to 
throw (using compile time introspection on the exception set).


Can I as a programmer who wants to call a function written by 
someone else inspect the declaration of that function and know 
what exceptions are possible?


* Can I as a programmer who wants to call a function written by 
someone else inspect that function's exception set?


Yes, as explained fully here [1], shown as an idiomatic D trait 
here [2], and a template based abstraction around that trait here 
[3]. It would need to be implemented, of course, but it's not 
conceptually hard.



If no how is this supposed to work?


It was explained multiple times in this thread.

I am supposed to specify that exceptions I want to allow the 
called function to throw?


You aren't supposed to do anything, but you can do that, yes.

The called function is not going to dynamically adapt itself 
and change the list of exceptions it throws, right?


What? A function's exception set is determined by its body and 
can be aggregated by the compiler in a single recursive pass in 
the static analysis phase.


So how can I know, before running the code, what exceptions are 
possible?


You mean the very first time you want to call it and you don't 
know the exception set yourself by looking at its signature?
Put the call in a nothrow scope and compile the module (which is 
fast in D), the compiler will then complain which exceptions you 
didn't catch (requires improvement of nothrow analysis [1]).


[1] 
http://forum.dlang.org/post/uovtkvpdagzagzhya...@forum.dlang.org
[2] 
http://forum.dlang.org/post/lxejskhonjtiifvvg...@forum.dlang.org
[3] 
http://forum.dlang.org/post/fjjkqbxiznlxfstqn...@forum.dlang.org


Re: Checked vs unchecked exceptions

2017-06-27 Thread Jesse Phillips via Digitalmars-d

On Tuesday, 27 June 2017 at 06:10:52 UTC, Tobias Müller wrote:
I honestly don't understand how people that care a great deal 
about expressive type systems can be so opposed to checked 
exceptions. After all they wouldn't use 'object' for everything 
either.


Tobi


I think there is a threshold. For example, personally I am 
against the compiler refusing to compile because of an unused 
variable, or import clause. Why, because they get in the way of 
making changes. I don't want to pacify the compiler as I progress 
through the development process. Generally when the compiler 
complains about a type mismatch I actually forgot to make 
additional changes to make the new thing work.


Checked exceptions do the same thing. Call a new function, 
propagate the exception just to determine if it is a desired 
change. This very much can lead to attempting to pacify without 
properly handling.


This discussion seems to emphasize the ability to handle every 
exception type. There are certainly times I've utilized the 
ability to handle different types of exception in different ways, 
but it isn't the norm. This is likely because generally I find 
Exception to crop up because of programming logic bugs rather 
than true exceptions and in the other cases I'm not using the 
type of exception to change how I deal with a problem; if my Json 
parsing throws a Conversion exception I'm not going to handle it 
differently than when it throws an Invalid Token exception.


I however don't have much experience managing checked Exceptions. 
I remember back in the day trying to fix the long list of 
exceptions my functions could throw. I'd commonly use throws 
Exception, pondered on wrapping exceptions into my own exception 
that would then be thrown. Neither of these would be helpful to 
the original points, adding exceptions should break the contract 
and you should be able to catch specific exceptions. How is the 
ever expanding exception list of static void Main managed by 
others?


Re: Checked vs unchecked exceptions

2017-06-27 Thread jag via Digitalmars-d

On Tuesday, 27 June 2017 at 19:37:24 UTC, Moritz Maxeiner wrote:


As I have pointed out, your example occurs on the *caller* 
side, not the *callee* side. The proper solution is not for the 
callee to specify which exceptions it may throw, but for the 
caller to specify which exceptions it allows the callee to 
throw (using compile time introspection on the exception set).


Can I as a programmer who wants to call a function written by 
someone else inspect the declaration of that function and know 
what exceptions are possible? If no how is this supposed to work? 
I am supposed to specify that exceptions I want to allow the 
called function to throw? The called function is not going to 
dynamically adapt itself and change the list of exceptions it 
throws, right? So how can I know, before running the code, what 
exceptions are possible?




Re: Checked vs unchecked exceptions

2017-06-27 Thread Moritz Maxeiner via Digitalmars-d

On Tuesday, 27 June 2017 at 18:14:47 UTC, jag wrote:
As Tobias mentioned, there are safety implications to "auto" 
behavior. In the example below I am using C# and its "var" 
feature:


[...]


Your example uses variable type inference, which happens on the 
*caller* side, *not* the *callee* side, the latter of which being 
where both checked exceptions and return type inference happen.
The correct analogue to your example in the exception domain is 
thus *not* checked exceptions, but verifying the exception set 
*at the call site* (the same way you fix the variable type *at 
the call site* to `Employee`), which is exactly what you can do 
by exposing the function exception set via a trait.


Now the compiler is able to catch your mistake. This is the 
reason your code becomes safer when you express your intent 
clearly. You should have the option to state your intent 
clearly by listing the exceptions that can be thrown by a 
method.


As I have pointed out, your example occurs on the *caller* side, 
not the *callee* side. The proper solution is not for the callee 
to specify which exceptions it may throw, but for the caller to 
specify which exceptions it allows the callee to throw (using 
compile time introspection on the exception set).



In dynamic languages like Python [...]


None of this justifies putting the burden on the callee side 
(i.e. checked exceptions), instead of on the caller side (the 
latter being implementable in an idiomatic way using a trait as 
John has proposed).


Re: Checked vs unchecked exceptions

2017-06-27 Thread jag via Digitalmars-d
As Tobias mentioned, there are safety implications to "auto" 
behavior. In the example below I am using C# and its "var" 
feature:


class A {
   public static Employee getFoo() {
  return getPoorPerformingEmployee();
   }
}

This is your code, in which you are calling A which was written 
by someone else:


class B {
   var foo = A.getFoo();
   foo.fire();
}

Now another programmer changes class A as follows:

class A {
   public static Missile getFoo() {
  return new Missile();
   }
}

Guess what happens now? You intended to fire an employee, but 
instead you have fired a missile. The compiler did not catch this 
grave mistake because you did not clearly state your intent. Your 
class B compiles fine because both Employee and Missile have a 
method named fire(). You could have expressed your intent more 
clearly like this:


class B {
   Employee foo = A.getFoo();
   foo.fire();
}

Now the compiler is able to catch your mistake. This is the 
reason your code becomes safer when you express your intent 
clearly. You should have the option to state your intent clearly 
by listing the exceptions that can be thrown by a method.


In dynamic languages like Python there is less ability to state 
intent clearly. As a result in such languages fewer bugs can be 
caught at compile time. More bugs show up at run time. This may 
be acceptable if the program is intended for internal use in a 
company, because when the program crashes they can call you to 
come and fix it because you are in the next office. But when 
reliability is important then the more opportunity there is to 
express intent and have the compiler verify your code against 
your intent, the better.




Re: Checked vs unchecked exceptions

2017-06-27 Thread Moritz Maxeiner via Digitalmars-d

On Tuesday, 27 June 2017 at 16:01:37 UTC, mckoder wrote:

On Tuesday, 27 June 2017 at 11:40:02 UTC, Moritz Maxeiner wrote:


It's not at all bad code to write things down that the 
compiler could infer, quite the opposite.


Of course it is bad, because the compiler can do it better (no 
chance for a wrong exception set sans compiler bugs) and 
faster than you.


Writing it down signals _intent_ and the compiler can check 
if the implementation is matching the specification


Verifying that a function meets its specification is what 
unittests are for (asserts for runtime behaviour, static 
asserts for types).


You might as well argue that you shouldn't have to declare the 
return type of functions because the compiler can determine 
that automatically based on the types of values you are 
actually returning.


Of *course* you shouldn't have to (-> auto functions [1]).
The difference being, of course, that specifying the return type 
is always only a single type, whereas specifying the exception 
set blows up in verbosity with each additional level of call 
hierarchy.


Then write unit tests to make sure that the return type as 
determined by the compiler matches what you intended.


If you don't trust the compiler's return type inference you can 
do that, of course.
Though in contrast to the exception set there's a lot less reason 
to do so in the return type case, because it's only a single type 
not an arbitrarily large set of types.


[1] https://dlang.org/spec/function.html#auto-functions


Re: Checked vs unchecked exceptions

2017-06-27 Thread Sebastien Alaiwan via Digitalmars-d

On Tuesday, 27 June 2017 at 10:18:04 UTC, mckoder wrote:
"I think that the belief that everything needs strong static 
(compile-time) checking is an illusion; it seems like it will 
buy you more than it actually does. But this is a hard thing to 
see if you are coming from a statically-typed language."


Source: 
https://groups.google.com/forum/#!original/comp.lang.java.advocacy/r8VPk4deYDI/qqhL8g1uvf8J


If you like dynamic languages such as Python you probably agree 
with Bruce Eckel. If you are a fan of static checking then I 
don't see how you can like that.


A quote from Uncle Bob about too much static typing and checked 
exceptions:


http://blog.cleancoder.com/uncle-bob/2017/01/11/TheDarkPath.html

"My problem is that [Kotlin and Swift] have doubled down on 
strong static typing. Both seem to be intent on closing every 
single type hole in their parent languages."


"I would not call Java a strongly opinionated language when it 
comes to static typing. You can create structures in Java that 
follow the type rules nicely; but you can also violate many of 
the type rules whenever you want or need to. The language 
complains a bit when you do; and throws up a few roadblocks; but 
not so many as to be obstructionist.


Swift and Kotlin, on the other hand, are completely inflexible 
when it comes to their type rules. For example, in Swift, if you 
declare a function to throw an exception, then by God every call 
to that function, all the way up the stack, must be adorned with 
a do-try block, or a try!, or a try?. There is no way, in this 
language, to silently throw an exception all the way to the top 
level; without paving a super-hiway for it up through the entire 
calling tree."


Re: Checked vs unchecked exceptions

2017-06-27 Thread mckoder via Digitalmars-d

On Tuesday, 27 June 2017 at 11:40:02 UTC, Moritz Maxeiner wrote:


It's not at all bad code to write things down that the 
compiler could infer, quite the opposite.


Of course it is bad, because the compiler can do it better (no 
chance for a wrong exception set sans compiler bugs) and faster 
than you.


Writing it down signals _intent_ and the compiler can check if 
the implementation is matching the specification


Verifying that a function meets its specification is what 
unittests are for (asserts for runtime behaviour, static 
asserts for types).


You might as well argue that you shouldn't have to declare the 
return type of functions because the compiler can determine that 
automatically based on the types of values you are actually 
returning. Then write unit tests to make sure that the return 
type as determined by the compiler matches what you intended.




Re: Checked vs unchecked exceptions

2017-06-27 Thread Gary Willoughby via Digitalmars-d

I think it's important to understand, D is *not* Java.


Re: Checked vs unchecked exceptions

2017-06-27 Thread Moritz Maxeiner via Digitalmars-d

On Tuesday, 27 June 2017 at 06:10:52 UTC, Tobias Müller wrote:

Moritz Maxeiner  wrote:

[...]
Or, more succinct: You must either manually write things down 
the

compiler could find out in a fraction of the time via static
analysis, or cheat the system; both cases are bad code.


It's not at all bad code to write things down that the compiler 
could

infer, quite the opposite.


Of course it is bad, because the compiler can do it better (no 
chance for a wrong exception set sans compiler bugs) and faster 
than you.


Writing it down signals _intent_ and the compiler can check if 
the implementation is matching the specification


Verifying that a function meets its specification is what 
unittests are for (asserts for runtime behaviour, static asserts 
for types).
With a function set trait there's nothing stopping you from 
writing a template that allows you to do the following:


---
void foo() { ... }

unittest
{
static assert (throws!(foo, AException));
static assert (throwsAll!(foo, AException, BException));
static assert (throwsAny!(foo, AException, CException));
static assert (!throws!(foo, CException));
}
---

which would be idiomatic D, giving you not only the same 
guarantees as checked exceptions (without the downsides), but 
also even more versatility by allowing arbitrary checks on the 
exception set.



which gives you additional security.


This has nothing to do with security; you may be thinking of 
safety.


Additionally it allowes the compiler to do the checks locally 
which is much

easier.


Easier to implement in the compiler, yes. That's precisely why I 
called it a compiler deficiency compared to exposing the function 
exception set, which is more advanced.


Function signatures are interfaces which should be 
self-contained IMO, i.e. it should not be necessary to examine 
the function body.
That's what signatures are for. At very least for public 
interfaces.


Sure, but since a function's signature in D does not include its 
exception set (be they checked or not), that point is moot.


I honestly don't understand how people that care a great deal 
about expressive type systems can be so opposed to checked 
exceptions. After all they wouldn't use 'object' for everything 
either.


For exactly the reasons I have already explained.


Re: Checked vs unchecked exceptions

2017-06-27 Thread mckoder via Digitalmars-d

On Tuesday, 27 June 2017 at 06:10:52 UTC, Tobias Müller wrote:


It's not at all bad code to write things down that the compiler 
could infer, quite the opposite.
Writing it down signals _intent_ and the compiler can check if 
the implementation is matching the specification which gives 
you additional security.
Additionally it allowes the compiler to do the checks locally 
which is much easier.


Function signatures are interfaces which should be 
self-contained IMO, i.e. it should not be necessary to examine 
the function body. That's what signatures are for. At very 
least for public interfaces.


I honestly don't understand how people that care a great deal 
about expressive type systems can be so opposed to checked 
exceptions. After all they wouldn't use 'object' for everything 
either.




Bravo! These are very important points!

FWIW, Bruce Eckel who is so often quoted by people who are 
opposed to checked exceptions comes from a dynamic language 
background. Here's a relevant quote by Bruce Eckel:


"I think that the belief that everything needs strong static 
(compile-time) checking is an illusion; it seems like it will buy 
you more than it actually does. But this is a hard thing to see 
if you are coming from a statically-typed language."


Source: 
https://groups.google.com/forum/#!original/comp.lang.java.advocacy/r8VPk4deYDI/qqhL8g1uvf8J


If you like dynamic languages such as Python you probably agree 
with Bruce Eckel. If you are a fan of static checking then I 
don't see how you can like that.


Re: Checked vs unchecked exceptions

2017-06-27 Thread Ola Fosheim Grøstad via Digitalmars-d

On Monday, 26 June 2017 at 21:00:24 UTC, Guillaume Boucher wrote:
I would say that the overload without exceptions is the 
"standard" one.


The C++ assumption is that exceptions are slow. So what the text 
you referenced says is that it provides an alternative mechanism 
for situations where you are testing for failure, e.g. accessing 
something that isn't present to see if it exists. It is a 
performance/convenience alternative.


Although that "nothrow design" is rather clumsy and inconvenient 
since you have to provide the error object yourself as a 
parameter.


It is rather clear though that C++ std lib relies heavily on 
exceptions.


[Citation needed]


No citation needed. RAII + exceptions has been extensively 
described by Stroustrup as a main code structuring mechanism for 
C++ since the 1980s. Basic data structures like std::vector is 
designed with that in mind. C++ programmers that turn off 
exceptions also have to be careful with many areas of C++ 
std::lib.





Re: Checked vs unchecked exceptions

2017-06-27 Thread Tobias Müller via Digitalmars-d
Moritz Maxeiner  wrote:
> [...]
> Or, more succinct: You must either manually write things down the 
> compiler could find out in a fraction of the time via static 
> analysis, or cheat the system; both cases are bad code.

It's not at all bad code to write things down that the compiler could
infer, quite the opposite.
Writing it down signals _intent_ and the compiler can check if the
implementation is matching the specification which gives you additional
security.
Additionally it allowes the compiler to do the checks locally which is much
easier.

Function signatures are interfaces which should be self-contained IMO, i.e.
it should not be necessary to examine the function body. That's what
signatures are for. At very least for public interfaces.

I honestly don't understand how people that care a great deal about
expressive type systems can be so opposed to checked exceptions. After all
they wouldn't use 'object' for everything either.

Tobi



Re: Checked vs unchecked exceptions

2017-06-26 Thread Sebastien Alaiwan via Digitalmars-d

On Monday, 26 June 2017 at 17:44:15 UTC, Guillaume Boucher wrote:
On Monday, 26 June 2017 at 16:52:22 UTC, Sebastien Alaiwan 
wrote:
Checked exceptions allow a lot more precision about what types 
of exceptions a function can throw.


I totally agree that this is a problem with D right now.
This wasn't my point! I don't think there's a problem with D not 
having CE.
I was just pointing out the difference between "nothrow" 
specifications and CE.


Re: Checked vs unchecked exceptions

2017-06-26 Thread Moritz Maxeiner via Digitalmars-d

On Tuesday, 27 June 2017 at 00:29:53 UTC, crimaniak wrote:

On Monday, 26 June 2017 at 19:31:53 UTC, Moritz Maxeiner wrote:


And the good *way* to achieve this result would be the 
following:
- When visiting `startFoo`, the compiler automatically 
aggregates all different exceptions it may throw and stores 
the resulting set
- If `startFoo` is going to be part of a (binary) library and 
its symbol is exported, also export its exception set
- Improve the compiler's nothrow analysis such that if 
startFoo is called in scope S, but all of the exceptions in 
its exception set are caught (i.e. can't break out of scope 
S), it is treated as nothrow in S.

- Enclose the call to `startFoo` in B in a nothrow scope.
 After preparing my message I read tail of the thread and see 
your vision very close to mine. 


I wouldn't call it a vision, since I personally don't need it.
It's just that I consider checked exceptions as an excuse for not 
improving a deficient compiler.




So listing exceptions that can be thrown is a good thing 
because it helps you write more reliable code.


It is a bad thing because you force a human to do a machine's 
job.
This is a bad necessity, but a necessary opportunity. Sometimes 
you need to be sure that the compiler's vision matches yours.


I would need a concrete example that's not either solved by the 
steps mentioned in my post, or using compile time introspection 
on a function's exception set (as shown in John's idiomatic 
proposal [1]).


[1] 
http://forum.dlang.org/post/lxejskhonjtiifvvg...@forum.dlang.org


Re: Checked vs unchecked exceptions

2017-06-26 Thread crimaniak via Digitalmars-d

On Monday, 26 June 2017 at 19:31:53 UTC, Moritz Maxeiner wrote:


And the good *way* to achieve this result would be the 
following:
- When visiting `startFoo`, the compiler automatically 
aggregates all different exceptions it may throw and stores the 
resulting set
- If `startFoo` is going to be part of a (binary) library and 
its symbol is exported, also export its exception set
- Improve the compiler's nothrow analysis such that if startFoo 
is called in scope S, but all of the exceptions in its 
exception set are caught (i.e. can't break out of scope S), it 
is treated as nothrow in S.

- Enclose the call to `startFoo` in B in a nothrow scope.
 After preparing my message I read tail of the thread and see 
your vision very close to mine. 


So listing exceptions that can be thrown is a good thing 
because it helps you write more reliable code.


It is a bad thing because you force a human to do a machine's 
job.
This is a bad necessity, but a necessary opportunity. Sometimes 
you need to be sure that the compiler's vision matches yours.




Re: Checked vs unchecked exceptions

2017-06-26 Thread crimaniak via Digitalmars-d

On Sunday, 25 June 2017 at 17:38:14 UTC, mckoder wrote:

I am disappointed that D doesn't have checked exceptions.


Warning, Google translate is used! (sorry)

I fully support mckoder with regard to exceptions. This is a 
great advantage of Java. I think, the problem with the 
introduction of verified exceptions in D is rather psychological, 
as the authors and the community mostly came from C++. Indeed, in 
C++, the checked exceptions failed, but I think this is more a 
failure of C++ than the ideas of checked exceptions. The Java 
experience has shown that this is a powerful tool that really 
helps to write reliable programs. Most of the arguments against 
exceptions are somewhat similar to the arguments of language 
lovers with a weak dynamic typing, by which listing argument 
types seems tedious. The relevant objection is that there is a 
problem with lambdas. I think everyone who started using the 
stream API in Java 8 was faced with this problem. But who said 
that you need to exactly repeat the approach of Java? When I 
encountered this problem, I tried to write an analog of this API, 
only with support for exceptions. As a result, the root of the 
problem was easily identified. In Java, each exception type 
thrown is an additional method parameter, similar to the input 
parameters, and there are no variadic templates for them. The 
correct implementation should have some TypeTuple for all the 
types thrown. And the possibility of calculating it. The 
following thoughts should be considered as speculative, I 
understand that these ideas will not be accepted.
Take for start the system adopted in Java. Now add 'throws auto'. 
This does not mean 'throws Exception'! This means that the 
compiler must determine what exceptions this method or function 
throws. Now add a default - all functions where there are no 
throws are treated like 'throws auto'. What does this give us? 
The old code without throws continues to work, since exceptions, 
except for intercepted ones, successfully pop up to main() and 
are caught by runtime. But as soon as the author began to denote 
throws or nothrows, he gets all the benefits of the Java 
exception system. In addition, if the lower layer has changed, 
the intermediate layers that delegate the exceptions above do not 
need to be rewritten, only the code that deals directly with the 
exception processing and declares it with throws or nothrows will 
be affected. (I think that you should not abuse this, libraries 
that are supplied as a separate product should still encapsulate 
the underlying exceptions in their own).


In addition, now the specification of 'throws A, B, C' lowered to 
'throws ExceptionTypeTyple! (A, B, C)'. What does it give? We 
easily write templates that work with functions with any number 
of types of throws exceptions, and this can be handled according 
to the same rules as the other template parameters of the method.


Re: Checked vs unchecked exceptions

2017-06-26 Thread Guillaume Boucher via Digitalmars-d
On Monday, 26 June 2017 at 18:42:24 UTC, Ola Fosheim Grøstad 
wrote:
On Monday, 26 June 2017 at 17:44:15 UTC, Guillaume Boucher 
wrote:
Java uses A, Rust/Go use B.  C++ uses B to some extend (e.g. 
in std::experimental::filesystem).


The C++17 filesystem api provides two alternatives, the 
standard filesystem_error exception and an output-paramater for 
capturing os-specific error codes. I'm not quite sure why they 
provide both, but I guess performance and the ability to 
compile for  runtimes with exceptions turned off could explain 
it.


Quoting the C++ standard:

Filesystem library functions often provide two overloads, one 
that
throws an exception to report file system errors, and another 
that sets an error_code.


[Note: This supports two common use cases:

   - Uses where file system errors are truly exceptional
 and indicate a serious failure.
 Throwing an exception is an appropriate response.
   - Uses where file system errors are routine
 and do not necessarily represent failure.
 Returning an error code is the most appropriate response.
 This allows application specific error handling, including 
simply ignoring the error.


 -- end note]


I would say that the overload without exceptions is the 
"standard" one.


It is rather clear though that C++ std lib relies heavily on 
exceptions.


[Citation needed]



Re: Checked vs unchecked exceptions

2017-06-26 Thread Guillaume Boucher via Digitalmars-d

On Monday, 26 June 2017 at 17:50:47 UTC, Moritz Maxeiner wrote:
I have tried using such Monads in D, but in the end it always 
ended up being too verbose or too hard to read compared to 
using exceptions or even simple error codes (with 0 == no 
error).


I haven't tried that yet, tbh.  visit is nice, but can't always 
be used.  So I guess unless D introduces syntax for pattern 
matching, it will always be verbose.


In that case a reference to an error code would be the most 
viable design in D.




Re: Checked vs unchecked exceptions

2017-06-26 Thread Moritz Maxeiner via Digitalmars-d

On Monday, 26 June 2017 at 18:31:50 UTC, jag wrote:

On Monday, 26 June 2017 at 17:43:08 UTC, Moritz Maxeiner wrote:
Here's the point: with checked exceptions good programmers 
can write good code.


With checked exceptions any programmer is forced to
a) annotate every single function with the complete aggregate 
of the exceptions that may be thrown by itself or the 
functions it calls
b) violate checked exceptions and limit its callers by marking 
itself as throwing a parent exception




Here's an example C# pseudocode to illustrate the problem:


No need, you can assume the people discussing this are familiar 
with the issue, it's not new.




class A {
   public static void startFoo() {
  if (/* Foo is not installed */)
  throw new FooNotInstalled();
  // ...
   }
}

Programmer B calls the above code like this:

class B {
   try {
  A.startFoo();
   }
   catch (FooNotInstalled) {
  // Tell user to purchase Foo
   }
}

Later programmer A updates his code because there are newer 
versions of Foo and he needs the newest version:


class A {
   public static void startFoo() {
  if (/* Foo is not installed */)
  throw new FooNotInstalled();
  if (/* Foo version is too old */)
  throw new FooVersionTooOld();
  // ...
   }
}

Now the code written by Programmer B crashes even though it 
compiles file. That's bad.


Had this been Java, programmer would be would be alerted to the 
fact that he needs to decide what do do if the version of Foo 
is too old. This is good.


And the good *way* to achieve this result would be the following:
- When visiting `startFoo`, the compiler automatically aggregates 
all different exceptions it may throw and stores the resulting set
- If `startFoo` is going to be part of a (binary) library and its 
symbol is exported, also export its exception set
- Improve the compiler's nothrow analysis such that if startFoo 
is called in scope S, but all of the exceptions in its exception 
set are caught (i.e. can't break out of scope S), it is treated 
as nothrow in S.

- Enclose the call to `startFoo` in B in a nothrow scope.



So listing exceptions that can be thrown is a good thing 
because it helps you write more reliable code.


It is a bad thing because you force a human to do a machine's job.



Re: Checked vs unchecked exceptions

2017-06-26 Thread Ola Fosheim Grøstad via Digitalmars-d

On Monday, 26 June 2017 at 17:44:15 UTC, Guillaume Boucher wrote:
Java uses A, Rust/Go use B.  C++ uses B to some extend (e.g. in 
std::experimental::filesystem).


The C++17 filesystem api provides two alternatives, the standard 
filesystem_error exception and an output-paramater for capturing 
os-specific error codes. I'm not quite sure why they provide 
both, but I guess performance and the ability to compile for  
runtimes with exceptions turned off could explain it.


It is rather clear though that C++ std lib relies heavily on 
exceptions.




Re: Checked vs unchecked exceptions

2017-06-26 Thread jag via Digitalmars-d

On Monday, 26 June 2017 at 17:43:08 UTC, Moritz Maxeiner wrote:
Here's the point: with checked exceptions good programmers can 
write good code.


With checked exceptions any programmer is forced to
a) annotate every single function with the complete aggregate 
of the exceptions that may be thrown by itself or the functions 
it calls
b) violate checked exceptions and limit its callers by marking 
itself as throwing a parent exception




Here's an example C# pseudocode to illustrate the problem:

Programmer A writes this C# code:

class A {
   public static void startFoo() {
  if (/* Foo is not installed */)
  throw new FooNotInstalled();
  // ...
   }
}

Programmer B calls the above code like this:

class B {
   try {
  A.startFoo();
   }
   catch (FooNotInstalled) {
  // Tell user to purchase Foo
   }
}

Later programmer A updates his code because there are newer 
versions of Foo and he needs the newest version:


class A {
   public static void startFoo() {
  if (/* Foo is not installed */)
  throw new FooNotInstalled();
  if (/* Foo version is too old */)
  throw new FooVersionTooOld();
  // ...
   }
}

Now the code written by Programmer B crashes even though it 
compiles file. That's bad.


Had this been Java, programmer would be would be alerted to the 
fact that he needs to decide what do do if the version of Foo is 
too old. This is good.


So listing exceptions that can be thrown is a good thing because 
it helps you write more reliable code. If you are lazy you can 
always defeat the system by declaring your method as throwing a 
parent (or the root) exception class, in which case it is no 
worse than C#.




Re: Checked vs unchecked exceptions

2017-06-26 Thread Moritz Maxeiner via Digitalmars-d

On Monday, 26 June 2017 at 17:44:15 UTC, Guillaume Boucher wrote:
It is very well possible to use option B in D.  The most 
convenient one is making functions nothrow and use 
Algebraic!(T, ErrorCode), or, for void functions, have a 
parameter "ref ErrorCode".
If all functions in Phobos would either follow that pattern or 
provide an alternative nothrow overload, I would consider that 
problem solved.


I have tried using such Monads in D, but in the end it always 
ended up being too verbose or too hard to read compared to using 
exceptions or even simple error codes (with 0 == no error).


Re: Checked vs unchecked exceptions

2017-06-26 Thread Guillaume Boucher via Digitalmars-d

On Monday, 26 June 2017 at 16:52:22 UTC, Sebastien Alaiwan wrote:
Checked exceptions allow a lot more precision about what types 
of exceptions a function can throw.


I totally agree that this is a problem with D right now.  If you 
want to catch all errors, how are you supposed to remember what 
std.file.readText throws?  Or std.file.mkdir?


There are two solutions to this problem that I know of:

A) Checked exceptions
B) Error codes that can't be implicitly ignored

Java uses A, Rust/Go use B.  C++ uses B to some extend (e.g. in 
std::experimental::filesystem).


In my opinion, option B better than A because checked exceptions 
are incredibly verbose.  However, both are better than nothing 
(which is the current state of D right now).


It is very well possible to use option B in D.  The most 
convenient one is making functions nothrow and use Algebraic!(T, 
ErrorCode), or, for void functions, have a parameter "ref 
ErrorCode".
If all functions in Phobos would either follow that pattern or 
provide an alternative nothrow overload, I would consider that 
problem solved.


Re: Checked vs unchecked exceptions

2017-06-26 Thread Moritz Maxeiner via Digitalmars-d

On Monday, 26 June 2017 at 15:40:19 UTC, mckoder wrote:
On Monday, 26 June 2017 at 15:15:54 UTC, Steven Schveighoffer 
wrote:


No, checked exceptions leads to this (maybe not for you, but 
for 90% of developers out there):


void foo()
{
   functionWithException();
}

compiler: foo throws, and you need to handle or declare the 
exceptions it throws


void foo()
{
   try {
 functionWithException();
   } catch(Exception e) {} // shut up compiler
}



Why wouldn't you instead write:

void foo() throws Exception // shut up compiler
{
   functionWithException();
}

That's easier, and no worse than C# even though you have 
defeated checked exceptions.


Because that's even worse.
The `try catch` as least takes responsibility for handling the 
error - even if it is just intentionally ignoring it.
Your version delegates the responsibility up the call chain 
(which is in and of itself fine), but it - as you even stated - 
prevents the caller from using checked exceptions, i.e. you're 
cheating the system.


Here's the point: with checked exceptions good programmers can 
write good code.


With checked exceptions any programmer is forced to
a) annotate every single function with the complete aggregate of 
the exceptions that may be thrown by itself or the functions it 
calls
b) violate checked exceptions and limit its callers by marking 
itself as throwing a parent exception


Or, more succinct: You must either manually write things down the 
compiler could find out in a fraction of the time via static 
analysis, or cheat the system; both cases are bad code.


Re: Checked vs unchecked exceptions

2017-06-26 Thread Ola Fosheim Grøstad via Digitalmars-d

On Monday, 26 June 2017 at 16:35:51 UTC, jmh530 wrote:
Just curious: how are checked exceptions different from setting 
nothrow as the default? Like you would have to write:


void foo() @maythrow
{
   functionWithException();
}

So for instance, you could still use your "//shut up compiler" 
code with the nothrow default.


I think the basic argument was that if throws-anything is the 
default expectation then people won't feel like silencing thrown 
exceptions, but allow them to propagate freely. Of course, if the 
function is marked nothrow then they still will have to silence 
any exceptions before returning, so same issue.


But, I am pretty convinced that this has more to do with tooling 
than usability. If the tooling is not created with evolving 
exceptions spec in mind then it becomes tedious to update the 
throw specification for functions higher up in the call-chain.


Another issue is that a function that takes a lambda/function as 
parameters will have to cover any exception that the parameter 
lambdas/function can throw as well. Which actually might be a 
good thing, as it forces you to think more clearly about where 
exceptions originate from: what-if-the-foreign-lambda throws an 
exception?


But it does have implications for how you work.




Re: Checked vs unchecked exceptions

2017-06-26 Thread Sebastien Alaiwan via Digitalmars-d

On Monday, 26 June 2017 at 16:35:51 UTC, jmh530 wrote:
Just curious: how are checked exceptions different from setting 
nothrow as the default? Like you would have to write:


void foo() @maythrow
{
   functionWithException();
}

So for instance, you could still use your "//shut up compiler" 
code with the nothrow default.


Checked exceptions allow a lot more precision about what types of 
exceptions a function can throw.


Re: Checked vs unchecked exceptions

2017-06-26 Thread jmh530 via Digitalmars-d
On Monday, 26 June 2017 at 15:15:54 UTC, Steven Schveighoffer 
wrote:


No, checked exceptions leads to this (maybe not for you, but 
for 90% of developers out there):


void foo()
{
   functionWithException();
}

compiler: foo throws, and you need to handle or declare the 
exceptions it throws


void foo()
{
   try {
 functionWithException();
   } catch(Exception e) {} // shut up compiler
}




Just curious: how are checked exceptions different from setting 
nothrow as the default? Like you would have to write:


void foo() @maythrow
{
   functionWithException();
}

So for instance, you could still use your "//shut up compiler" 
code with the nothrow default.


Re: Checked vs unchecked exceptions

2017-06-26 Thread Ola Fosheim Grøstad via Digitalmars-d
On Monday, 26 June 2017 at 15:15:54 UTC, Steven Schveighoffer 
wrote:

void foo()
{
   try {
 functionWithException();
   } catch(Exception e) {} // shut up compiler
}

So it ends up defeating the purpose. The exception is not 
properly handled, either inside or outside the function.


That's a poor argument, this will be caught in code reviews. You 
might as well use the same argument against returning error codes 
or optionals. Yes, it is possible to ignore them… and?





Re: Checked vs unchecked exceptions

2017-06-26 Thread mckoder via Digitalmars-d
On Monday, 26 June 2017 at 15:15:54 UTC, Steven Schveighoffer 
wrote:


No, checked exceptions leads to this (maybe not for you, but 
for 90% of developers out there):


void foo()
{
   functionWithException();
}

compiler: foo throws, and you need to handle or declare the 
exceptions it throws


void foo()
{
   try {
 functionWithException();
   } catch(Exception e) {} // shut up compiler
}



Why wouldn't you instead write:

void foo() throws Exception // shut up compiler
{
   functionWithException();
}

That's easier, and no worse than C# even though you have defeated 
checked exceptions.


Here's the point: with checked exceptions good programmers can 
write good code. Without checked exceptions even good programmers 
are forced to write bad code. It is impossible to prevent bad 
programmers from writing bad code, so that should not even be a 
goal, but enabling good programmers to write good code should be 
a goal.




Re: Checked vs unchecked exceptions

2017-06-26 Thread Steven Schveighoffer via Digitalmars-d

On 6/25/17 1:38 PM, mckoder wrote:

I am disappointed that D doesn't have checked exceptions.

C++ and C# also don't have checked exceptions. Java has checked 
exceptions. Having programmed extensively in all these languages I can 
say with confidence that checked exceptions is the most important thing 
missing in C++ and C#. Around the time C# was released there was a lot 
of debate around the topic of checked vs unchecked exceptions and this 
created an impression that Java's use of checked exceptions was 
"controversial". In fact it is a feature every modern language should have.


No, checked exceptions leads to this (maybe not for you, but for 90% of 
developers out there):


void foo()
{
   functionWithException();
}

compiler: foo throws, and you need to handle or declare the exceptions 
it throws


void foo()
{
   try {
 functionWithException();
   } catch(Exception e) {} // shut up compiler
}

So it ends up defeating the purpose. The exception is not properly 
handled, either inside or outside the function.


You can get into a long discussion if you want, I'm not going there. 
Bottom line: D *will not* have checked exceptions, Walter has said so 
many times. If that's a deal killer, you should probably stick with 
Java. Sorry, don't want to waste your time.


-Steve


Re: Checked vs unchecked exceptions

2017-06-26 Thread mckoder via Digitalmars-d

On Sunday, 25 June 2017 at 18:00:46 UTC, Eugene Wissner wrote:

http://forum.dlang.org/post/ullvxbfqeuztwecxc...@forum.dlang.org



As suggested by the post in above link I searched for "Walter 
checked exceptions". I found a few posts where Walter points to 
an article written by Bruce Eckel. Though the link to Eckel's 
article no longer works, I am familiar with Eckel's arguments, 
and I even exchanged emails with Eckel back in 2003 on this 
topic. Suffice to say I believe Eckel is wrong on this topic.


Bruce Eckel argues that checked exceptions forces you to write 
bad code (catch Exception base class) and Walter mentions this. 
Eckel is wrong. The opposite is true. Lack of checked exceptions 
forces you to catch Exception base class in order to prevent 
crashes. If you know what exceptions are possible then you can 
catch just those exceptions. If you don't know then you have to 
rely on testing to find out what exceptions are possible but you 
will never get an exhaustive list through testing since tests can 
never be 100% comprehensive for non-trivial programs. So you end 
up catching Exception base class, thus swallowing exceptions. I 
have seen lots of large code bases in C# and Java written by very 
good developers, and I can tell you that experience has proven 
that "catch (Exception)" is common in C# code bases and rarely 
seen in Java code bases.


Re: Checked vs unchecked exceptions

2017-06-25 Thread Ola Fosheim Grøstad via Digitalmars-d

On Sunday, 25 June 2017 at 17:38:14 UTC, mckoder wrote:
Exceptions that can be thrown by a method should be part of the 
contract of that method. Changing the list of the list of 
exceptions that can be thrown by a method is just like changing 
the parameters of the method. This is something that should 
cause calling code to fail to compile. This will allow you to 
inspect the calling code and decode how to deal with the new 
exception.


I think the reason it didn't work out for C++ to specify the 
exceptions is that you need good IDE support for it and C++ was 
to a large extent a language where people wrote code in basic 
editors.


message. I have a lot of respect for Anders Hejlsberg (my first 
programming language was Turbo Pascal) but he is completely 
wrong on this topic.


Turbo Pascal as a language was so-so, but the IDE was very 
productive.




Re: Checked vs unchecked exceptions

2017-06-25 Thread Eugene Wissner via Digitalmars-d

http://forum.dlang.org/post/ullvxbfqeuztwecxc...@forum.dlang.org

On Sunday, 25 June 2017 at 17:38:14 UTC, mckoder wrote:

I am disappointed that D doesn't have checked exceptions.

C++ and C# also don't have checked exceptions. Java has checked 
exceptions. Having programmed extensively in all these 
languages I can say with confidence that checked exceptions is 
the most important thing missing in C++ and C#. Around the time 
C# was released there was a lot of debate around the topic of 
checked vs unchecked exceptions and this created an impression 
that Java's use of checked exceptions was "controversial". In 
fact it is a feature every modern language should have.


Exceptions that can be thrown by a method should be part of the 
contract of that method. Changing the list of the list of 
exceptions that can be thrown by a method is just like changing 
the parameters of the method. This is something that should 
cause calling code to fail to compile. This will allow you to 
inspect the calling code and decode how to deal with the new 
exception.


When the exception that can be thrown by a method is not known 
you don't know what exceptions to catch and what exceptions to 
pass through to callers. You can't rely on documentation 
because the documentation is not verified be the compiler and 
so is not reliable. All you can do is to run the program a few 
times, see what exceptions you get and handle them. Even if you 
are able to determine the full list of exceptions using this 
strategy, a future revision of the called method can throw a 
new exception and cause your program to crash. As a result, in 
large C# code bases it is common to see catching the base 
Exception class because this is the only way to prevent a 
crash. This causes exceptions to be "swallowed" because higher 
level code that is actually prepared to handle certain 
exceptions never get the exception.


With Java this problem doesn't exist. When you call a function 
you know exactly what exceptions can be thrown and you can 
catch (or pass through) exactly those exceptions. There is no 
need to catch the base exception class.


When you have multiple implementations of an interface (such as 
database connectivity layer) and each of those implementations 
can throw a completely disjoint set of exceptions there is no 
way to write polymorphic code that can recover from errors.


Anders Hejlsberg, designer of C# doesn't think people care to 
catch specific exceptions, which is why C# doesn't have checked 
exceptions. (See http://www.artima.com/intv/handcuffs.html ) 
"They're not going to handle any of these exceptions. There's a 
bottom level exception handler around their message loop. That 
handler is just going to bring up a dialog that says what went 
wrong and continue." Also: "The exception handling should be 
centralized.." In other words, he thinks all people want to do 
with exceptions is catch the base Exception class and display a 
message. I have a lot of respect for Anders Hejlsberg (my first 
programming language was Turbo Pascal) but he is completely 
wrong on this topic.


Regarding the versioning issue discussed by Anders Hejlsberg, 
my response is that throwing a new exception is like changing 
the signature of a function. You want callers to be alerted 
that they need to update their code! This means the calling 
code should fail to compile until it is updated.





Checked vs unchecked exceptions

2017-06-25 Thread mckoder via Digitalmars-d

I am disappointed that D doesn't have checked exceptions.

C++ and C# also don't have checked exceptions. Java has checked 
exceptions. Having programmed extensively in all these languages 
I can say with confidence that checked exceptions is the most 
important thing missing in C++ and C#. Around the time C# was 
released there was a lot of debate around the topic of checked vs 
unchecked exceptions and this created an impression that Java's 
use of checked exceptions was "controversial". In fact it is a 
feature every modern language should have.


Exceptions that can be thrown by a method should be part of the 
contract of that method. Changing the list of the list of 
exceptions that can be thrown by a method is just like changing 
the parameters of the method. This is something that should cause 
calling code to fail to compile. This will allow you to inspect 
the calling code and decode how to deal with the new exception.


When the exception that can be thrown by a method is not known 
you don't know what exceptions to catch and what exceptions to 
pass through to callers. You can't rely on documentation because 
the documentation is not verified be the compiler and so is not 
reliable. All you can do is to run the program a few times, see 
what exceptions you get and handle them. Even if you are able to 
determine the full list of exceptions using this strategy, a 
future revision of the called method can throw a new exception 
and cause your program to crash. As a result, in large C# code 
bases it is common to see catching the base Exception class 
because this is the only way to prevent a crash. This causes 
exceptions to be "swallowed" because higher level code that is 
actually prepared to handle certain exceptions never get the 
exception.


With Java this problem doesn't exist. When you call a function 
you know exactly what exceptions can be thrown and you can catch 
(or pass through) exactly those exceptions. There is no need to 
catch the base exception class.


When you have multiple implementations of an interface (such as 
database connectivity layer) and each of those implementations 
can throw a completely disjoint set of exceptions there is no way 
to write polymorphic code that can recover from errors.


Anders Hejlsberg, designer of C# doesn't think people care to 
catch specific exceptions, which is why C# doesn't have checked 
exceptions. (See http://www.artima.com/intv/handcuffs.html ) 
"They're not going to handle any of these exceptions. There's a 
bottom level exception handler around their message loop. That 
handler is just going to bring up a dialog that says what went 
wrong and continue." Also: "The exception handling should be 
centralized.." In other words, he thinks all people want to do 
with exceptions is catch the base Exception class and display a 
message. I have a lot of respect for Anders Hejlsberg (my first 
programming language was Turbo Pascal) but he is completely wrong 
on this topic.


Regarding the versioning issue discussed by Anders Hejlsberg, my 
response is that throwing a new exception is like changing the 
signature of a function. You want callers to be alerted that they 
need to update their code! This means the calling code should 
fail to compile until it is updated.