August 08, 2007
janderson wrote:
> Sean Kelly wrote:
>> BCS wrote:
>>>
>>> Fat chance, most of D's advantages don't exist in under ~5000 LOC and anything over that and the NSA won't touch it. Besides there isn't 20+ years of best practices in how to right secure software in D (as this is in C)
>>
>> I'd think DBC would be a perk, if nothing else.  Assuming the NSA currently uses C, that is.
> 
> I thought NSA used ADA it was designed for such purposes.

By my understanding, Ada was largely intended for robust systems control, while I would guess that much of the code written at the NSA is for in-house problem solving and that the safety provided by Ada isn't typically necessary.  I think it's likely that the NSA most often uses mainstream languages for the bulk of its work, tending towards systems-oriented languages for their speed.


Sean
August 10, 2007
eao197 wrote:
> However sometimes is good to know that some method doesn't throw exception at all (it could be necessary for exception safety, like C++ convection that swap() methods and destructors are exception free). So I suppose to introduce 'nothrows' modifier as a sign that some routine is exception free:

The compiler can support this. It'd have to add more metadata to precompiled libraries, but that's okay. The ddocs could then (optionally?) include information on what exceptions the function throws directly and what other exceptions can be thrown on invocation.

So I don't see any reason for the programmer to have to manually do all this.

-cbw
August 10, 2007
On Fri, 10 Aug 2007 06:03:10 +0400, Christopher Wright <dhasenan@gmail.com> wrote:

> eao197 wrote:
>> However sometimes is good to know that some method doesn't throw exception at all (it could be necessary for exception safety, like C++ convection that swap() methods and destructors are exception free). So I suppose to introduce 'nothrows' modifier as a sign that some routine is exception free:
>
> The compiler can support this. It'd have to add more metadata to precompiled libraries, but that's okay. The ddocs could then (optionally?) include information on what exceptions the function throws directly and what other exceptions can be thrown on invocation.
>
> So I don't see any reason for the programmer to have to manually do all this.

There are one important use case where the compiler can't detect which exceptions are thrown by a method: polymorphism and late binding. Imagine:

class EventHandler
  {
    abstract void handle_input();
    abstract void handle_output();
    abstract void handle_exception();
    ...
  }

class SelectReactor : Reactor
  {
    void
    reactor_event_loop()
      {
        while( true )
          {
             EventHandler[] input_ready_handlers = detect_input_ready_handlers();
             foreach( h; input_ready_handlers )
               h.handle_input();
             ...
          }
      }
  }

During compilation of SelectReactor the compiler can't determine which exception could be thrown by descendants of EventHandler. So it is a programmer's task to specify exceptions in 'throws' clause (like in Java/Spec#) or declare that method doesn't throw exception at all in 'nothrows' clause (like throw() in C++).

-- 
Regards,
Yauheni Akhotnikau
August 10, 2007
eao197 wrote:
> On Wed, 08 Aug 2007 15:38:14 +0400, Bruno Medeiros <brunodomedeiros+spam@com.gmail> wrote:
> 
>> Bill Baxter wrote:
>>> Nick Sabalausky wrote:
>>>> "Rioshin an'Harthen" <rharth75@hotmail.com> wrote in message news:f974u9$9k1$1@digitalmars.com...
>>>>> "Walter Bright" <newshound1@digitalmars.com> kirjoitti viestissä news:f95leh$hn4$1@digitalmars.com...
>>>>>> It might be one of those things like exception specifications where everyone says it's a good idea but guiltily hate in secret <g>.
>>>>> Exception specification *is* a good idea. Although I do hate it - try to remember what a specific method may throw when you write your code, especially if the error is ambiguous like "Unhandled exception" it's really irritating - but I hate unspecified exceptions even more, as the problem then is to even remember to put in the necessary try-catch-finally blocks.
>>>>
>>>> Not to start a big big debate on it, but my own personal feeling on that (after having used a fair amount of it) is that the specification of exceptions belongs in generated documentation (whether javadoc-style or as part of the IDE as with "some_function() -> Called By..."). I normally prefer having to explicity specify things (yea, strong-typing fan here ;) ), but personally, I find it overkill in this case. (Not to mention it gave me flashbacks of writing C/C++ headers. j/k ;) ).
>>>  I agree with this 100%.  With check exceptions it just becomes too annoying and verbose.  Without them, often it is too difficult to find out what exceptions are possible for a function to throw.
>>>  So the right place seems to be an analysis / doc-generation tool / IDE.
>>>  --bb
>>
>> Interesting thing I'd like to mention, again about how IDEs affect the language design and influence it's advantages and disadvantages.
>> I too find checked exceptions annoying, but this is an example of a language disadvantage has been practically nullified by the IDE (JDT).
>>
>> First I took a slightly modified ExceptionAdapter class such as the one from Bruce Eckel's article:
>> http://www.mindview.net/Etc/Discussions/CheckedExceptions
>> (basicly ExceptionAdapter is class that wraps a checked exception in an unchecked exception, allowing it to be thrown unchecked)
>> So when you have something like this:
>>    foo.doSomething(); // throws a normal exception
>> and Java will complain that an exception is thrown, you add this:
>>    try {
>>      foo.doSomething(); // throws a normal exception
>>    } catch(FooException fe) {
>>      ExceptionAdapter.unchecked(fe);
>>    }
>> and there is no longer a compiler error (unchecked is a static method that wraps the exception), without having needed to put throws clauses in all method along the call hierarchy.
>> This is an interesting workaround, but it is still annoying to have to write that try-catch code whenever an exception is thrown.
>> The second part is where JDT comes in. Whenever you have this:
>>    foo.doSomething(); // throws a normal exception
>> the IDE compiler will show and highlight the error, and then you can press Ctrl+1 on the error (Quick-Assist), showing a list of possible fixes, one of them being "Surround with Try-Catch". If you select it, JDT will automatically add the try-catch code, like this:
>>    try {
>>      foo.doSomething(); // throws a normal exception
>>    } catch(FooException fe) {
>>      // TODO: catch exception here
>>    }
>> Note that the catch clause is automatically set to the thrown exception. But furthermore you can change the template of code that is created with this try-catch quick-fix, so that instead of the "// TODO:" line, you put the "ExceptionAdapter.unchecked(...);" line. So now whenever this quick fix is invoked, it will automatically generate all necessary code, and you're now able to avoid the checked exception problem with just a few keystrokes (Ctrl+1, Down, Enter). :)
>> As an added bonus, if some time you feel the need to rigorously specify your code, you can then search for calls of the ExceptionAdapter.unchecked method, to find points where you can turn unchecked exceptions into checked ones.
> 
> I don't agree (almost complitely). Checked expession is not simply annoying. Sometimes they lead to bad-style and erroneous code. For example imagine you redefine some method:
> 
> class MySpecializedClass extends SomeGeneralClass
> {
>   public void someMethod() throws DomainSpecificException { ... }
> }
> 
> but you need to use temporary file in someMethod() implementation (or need to run some external tool, or need to use some crypto library). And File.createTempFile throws IllegalArgumentException or IOException or SecurityException, but no one of them is in someMethod 'throws' clause.
> 
> In such case you have only two possibilities: wrap the exception which is thrown by File.createTempFile into some another exception (it is good if DomainSpecificException allows that, but in an usual case it don't) or catch and hide the original exception. As I seen in the past many developers prefered catch and hide exception. And this is not a good approach I think.
> 
> So in my opinion it is better to write code which doesn't depend on particular kind of exception. Assumption that any part of code could throws any kind of exception lead to more reliable software (Erlang is an evidence).
> 

I don't see how that is disagreeing with what I said before. Note that the above doesn't hide the exception (as in, make it disappear), it gets re-thrown as an unchecked exception.

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
August 10, 2007
On Fri, 10 Aug 2007 14:15:47 +0400, Bruno Medeiros <brunodomedeiros+spam@com.gmail> wrote:

>
> I don't see how that is disagreeing with what I said before. Note that the above doesn't hide the exception (as in, make it disappear), it gets re-thrown as an unchecked exception.
>

Umm... I'm sorry, I thought that 'ExceptionAdapter.unchecked(fe)' simply hides exception.

But initaly I was disagree with that:

>> an example of a language disadvantage has been practically nullified by the IDE (JDT).

Easy method of incapsulating exception into unchecked one doesn't repair flaw in the language design.

-- 
Regards,
Yauheni Akhotnikau
August 10, 2007
eao197 wrote:
> On Fri, 10 Aug 2007 14:15:47 +0400, Bruno Medeiros <brunodomedeiros+spam@com.gmail> wrote:
> 
>>
>> I don't see how that is disagreeing with what I said before. Note that the above doesn't hide the exception (as in, make it disappear), it gets re-thrown as an unchecked exception.
>>
> 
> Umm... I'm sorry, I thought that 'ExceptionAdapter.unchecked(fe)' simply hides exception.
> 

No, it doesn't do that. And indeed it would be bad if it did.

> But initaly I was disagree with that:
> 
>>> an example of a language disadvantage has been practically nullified by the IDE (JDT).
> 
> Easy method of incapsulating exception into unchecked one doesn't repair flaw in the language design.
> 

It fixes it well enough for me. :)

-- 
Bruno Medeiros - MSc in CS/E student
http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
August 10, 2007
The old aliasing trick will still cause problems.

(The 'override' keyword won't solve the problem in the following case.)

  class A {
    void foo(int);
    void foo(long);
  }

  class B : A {
    alias A.foo foo;
    override void foo(int);
  }

  void bar(B b) {
    short val = 1;

    b.foo(val);  //calls 'foo(int)'
  }

Now 'foo(short)' is added to 'A':

  void bar(B b) {
    short val = 1;

    b.foo(val);  //calls 'foo(short)'
  }


Solutions:

(1) The aliasing trick will be banned (argh).

or

(2) One can overload final functions only (ermmm).

Or, to solve the hijacking problem once and for all:

(3) No implicit type casting with function calls.

Somehow (3) seems appealing (but I'm probably just too tired).
I go to sleep now... ;)




On Sun, 05 Aug 2007 21:47:18 +0300, Walter Bright <newshound1@digitalmars.com> wrote:
> I want to continue a bit in the Overloading/Inheritance thread which is getting a little long, on a closely related issue which I find to be important, but so rarely referred to that I had to come up with a name for it - hijacking.
>
> Hijacking is when code A depends on B, and then when seemingly unrelated code C is modified, then A's behavior silently changes. Here's an example from C++:
>
> --A.h--
> void foo(long i);
>
> --B.c--
> #include "A.h"
> #include "C.h"
> ...
> foo(3);    // calls A's foo(long)
> --------
>
> Let's say A.h and C.h are developed by different people. In C.h, the developer adds:
>
> --C.h--
> void foo(int i);
> -----
>
> This does something completely different from A.h's foo(long), because they just happened to share the same name. Now, when B.c is recompiled, it's call to foo is silently *hijacked* by C.h's foo.
>
> Because of C++'s overloading rules and lack of modularity, there's no way to programmatically defend against this. Instead, one has to rely on coding conventions (such as using a unique package prefix name on all symbols, like A_foo() and C_foo()).
>
> So how does this relate to the overloading/inheritance issues? Consider:
>
> ----A.d----
> class A
> {
>      ...
> }
> -----B.d----
> import A;
> class B : A
> {
>      void foo(long);
> }
> ...
> void bar(B b)
> {
>      b.foo(3);   // calls B.foo(long)
> }
> ----
>
> Let's say A.d comes from some third party library. Now the developer of A decides to add some functionality to class A, and adds the member function foo(int):
>
> ----A.d---
> class A
> {
>      void foo(int);
> }
> ------------
>
> Now our hapless B programmer has his calls to B.foo(long) silently hijacked to A.foo(int) (under Java rules). I don't see any reasonable way for B to defend against this. Certainly, developer A doesn't have any idea who is deriving from A (and that's the point of polymorphism) - but should he be disallowed from adding *any* method names? And the hapless B developer, he wrote class B years ago and no longer quite remembers how it works, he just recompiles it and now it silently fails.
>
> So, this is one case where I feel C++ got it right, and Java didn't.
>
> (P.S. It's not a compiler implementation issue, nor is it a runtime performance issue.)

August 11, 2007
Kristian Kilpi wrote:
> 
> The old aliasing trick will still cause problems.
> 
> (The 'override' keyword won't solve the problem in the following case.)
> 
>   class A {
>     void foo(int);
>     void foo(long);
>   }
> 
>   class B : A {
>     alias A.foo foo;
>     override void foo(int);
>   }
> 
>   void bar(B b) {
>     short val = 1;
> 
>     b.foo(val);  //calls 'foo(int)'
>   }
> 
> Now 'foo(short)' is added to 'A':
> 
>   void bar(B b) {
>     short val = 1;
> 
>     b.foo(val);  //calls 'foo(short)'
>   }

I don't think this is a problem, because the B author explicitly and deliberately opened the door to this, therefore he is taking responsibility for it.
August 11, 2007
Walter Bright wrote:
> Kristian Kilpi wrote:
>>
>> The old aliasing trick will still cause problems.
>>
>> (The 'override' keyword won't solve the problem in the following case.)
>>
>>   class A {
>>     void foo(int);
>>     void foo(long);
>>   }
>>
>>   class B : A {
>>     alias A.foo foo;
>>     override void foo(int);
>>   }
>>
>>   void bar(B b) {
>>     short val = 1;
>>
>>     b.foo(val);  //calls 'foo(int)'
>>   }
>>
>> Now 'foo(short)' is added to 'A':
>>
>>   void bar(B b) {
>>     short val = 1;
>>
>>     b.foo(val);  //calls 'foo(short)'
>>   }
> 
> I don't think this is a problem, because the B author explicitly and deliberately opened the door to this, therefore he is taking responsibility for it.

Yes and no.

At the time the author wrote "alias A.foo foo;" they were allowing void foo(long), not void foo(short).

Yes, they still "opened the door to this" because D's current behaviour is to pull all overloads past/present/future.

Perhaps being able to specify overloads exactly would in some cases be of benefit, eg.

alias A.foo(long) foo;

Regan
August 11, 2007
Regan Heath wrote:
> Walter Bright wrote:
>> Kristian Kilpi wrote:
>>>
>>> The old aliasing trick will still cause problems.
>>>
>>> (The 'override' keyword won't solve the problem in the following case.)
>>>
>>>   class A {
>>>     void foo(int);
>>>     void foo(long);
>>>   }
>>>
>>>   class B : A {
>>>     alias A.foo foo;
>>>     override void foo(int);
>>>   }
>>>
>>>   void bar(B b) {
>>>     short val = 1;
>>>
>>>     b.foo(val);  //calls 'foo(int)'
>>>   }
>>>
>>> Now 'foo(short)' is added to 'A':
>>>
>>>   void bar(B b) {
>>>     short val = 1;
>>>
>>>     b.foo(val);  //calls 'foo(short)'
>>>   }
>>
>> I don't think this is a problem, because the B author explicitly and deliberately opened the door to this, therefore he is taking responsibility for it.
> 
> Yes and no.
> 
> At the time the author wrote "alias A.foo foo;" they were allowing void foo(long), not void foo(short).
> 
> Yes, they still "opened the door to this" because D's current behaviour is to pull all overloads past/present/future.
> 
> Perhaps being able to specify overloads exactly would in some cases be of benefit, eg.
> 
> alias A.foo(long) foo;
> 
> Regan

Honestly, we need some ability to specify more of a function/method's signature in the general case anyhow.  (Return type isn't really important, since it can't be different without at least one parameter difference)  This would help with the super-aliasing case above, /and/ with the address operator.

void foo (int);
void foo (char[]);

Currently:
&foo => *(foo(int))

Proposed:
&foo         => *(foo(int)) or ambiguity error?
&foo(int)    => *(foo(int))
&foo(char[]) => *(foo(char[]))

Currently:
alias foo bar; // all foo's

Proposed:
alias foo         bar; // all foo's
alias foo(int)    bar; // just this one
alias foo(char[]) bar; // ditto

The only thing that might get interesting is whether the compiler can easily distinguish (&foo()) as "take the address of a function foo with no params" versus "take the address of the result of function foo".  (Is that even legal?  Or useful?)

-- Chris Nicholson-Sauls
1 2 3 4 5 6
Next ›   Last »