March 14, 2014
On Friday, 14 March 2014 at 20:45:35 UTC, Paulo Pinto wrote:
> Am 14.03.2014 19:50, schrieb H. S. Teoh:
>> The real code had been moved elsewhere, you see, and
>> whoever moved the code "kindly" decided to leave the old copy in the
>> original file inside an #if 0 block, "for reference", whatever that
>> means. Then silly old me came along expecting the code to still be in
>> the old place, and sure enough it was -- except that unbeknownst to me
>> it's now inside an #if 0 block. Gah!)
>>
>>
>> T
>>
>
>
> Ouch! I feel your pain.
>
> This type of experience is what lead me to fight #ifdef spaghetti code.
>
> --
> Paulo

I hate code "commented out" in an "#if 0" with a passion. Just... Why?
March 14, 2014
On Friday, 14 March 2014 at 20:45:35 UTC, Paulo Pinto wrote:
> Am 14.03.2014 19:50, schrieb H. S. Teoh:
>> On Fri, Mar 14, 2014 at 07:29:27PM +0100, Paulo Pinto wrote:
>>> Am 14.03.2014 19:06, schrieb Iain Buclaw:
>>>> On 14 March 2014 17:53, Walter Bright <newshound2@digitalmars.com> wrote:
>>>>> On 3/14/2014 10:26 AM, Johannes Pfau wrote:
--snip---
>> +1. Once versioned code gets more than 2 levels deep, it becomes an
>> unreadable mess. The .di approach is much more manageable.
>>
>>
>>> Back on my C/C++ days at work, any conditional code would be killed
>>> by me during code reviews.
>> [...]
>>
>> Ah, how I wish I could do that... over here at my job, parts of the code
>> are a nasty rats'-nest of #if's, #ifdef's, #ifndef's, and "functions"
>> that aren't defined anywhere (they are generated by macros, including
>> their names!). It used to be relatively sane while the project still
>> remained a single project... Unfortunately, about a year or so ago, the
>> PTBs decided to merge another project into this one, and by "merge" they
>> meant, graft the source tree of the other project into this one, hack it
>> with a hacksaw until it compiles, then call it a day. We've been
>> suffering from the resulting schizophrenic code ever since, where some
>> files are compiled when configuring for platform A, and skipped over and
>> some other files are compiled when configuring for platform B (often
>> containing conflicting functions of the same name but with incompatible
>> parameters), and a ton of #if's and #ifdef's nested to the n'th level
>> got sprinkled everywhere in the common code in order to glue the
>> schizophrenic mess into one piece. One time, I spent almost an hour
>> debugging some code that turned out to be inside an #if 0 ... #endif
>> block. >:-(  (The real code had been moved elsewhere, you see, and
>> whoever moved the code "kindly" decided to leave the old copy in the
>> original file inside an #if 0 block, "for reference", whatever that
>> means. Then silly old me came along expecting the code to still be in
>> the old place, and sure enough it was -- except that unbeknownst to me
>> it's now inside an #if 0 block. Gah!)
>>
>>
>> T
>>
>
>
> Ouch! I feel your pain.
>
> This type of experience is what lead me to fight #ifdef spaghetti code.
>
> --
> Paulo

Yeah, having had to deal with macro spaghetti when porting code to new platforms, I completely agree with Walter on this one.  Whatever small inconveniences are caused by not allowing any logic inside or with version checks is made up for many times over in clarity and maintenance down the line.
March 14, 2014
On 14 Mar 2014 18:30, "Paulo Pinto" <pjmlp@progtools.org> wrote:
>
> Am 14.03.2014 19:06, schrieb Iain Buclaw:
>>
>> On 14 March 2014 17:53, Walter Bright <newshound2@digitalmars.com> wrote:
>>>
>>> On 3/14/2014 10:26 AM, Johannes Pfau wrote:
>>>>
>>>>
>>>> I use manifest constants instead of version identifiers as well. If a version identifier affects the public API/ABI of a library, then the library and all code using the library always have to be compiled with the same version switches(inlining and templates make this an even bigger problem). This is not only inconvenient, it's also easy to think of examples where the problem will only show up as crashes at runtime. The only reason why that's not an issue in phobos/druntime is that we only use compiler defined versions there, but user defined versions are almost unusable.
>>>
>>>
>>>
>>> Use this method:
>>>
>>>
>>>      --------
>>>      import wackyfunctionality;
>>>      ...
>>>      WackyFunction();
>>>      --------
>>>      module wackyfunctionality;
>>>
>>>      void WackyFunction() {
>>>          version (Linux)
>>>            SomeWackyFunction();
>>>          else version (OSX)
>>>              SomeWackyFunction();
>>>          else
>>>              ... workaround ...
>>>      }
>>>      --------
>>
>>
>>
>> Some years down the line (and some platform testing) turns into:
>>
>> --------
>> module wackyfunctionality;
>>
>> void WackyFunction() {
>>      version (Linux) {
>>          version (ARM)
>>              _SomeWackyFunction();
>>          else version (MIPS)
>>             MIPS_SomeWackyFunction();
>>          else version (X86)
>>             SomeWackyFunction();
>>          else version (X86_64)
>>             SomeWackyFunction();
>>          else
>>            ... should be some wacky function, but workaround for general
case ...
>>      }
>>      else version (OSX) {
>>          version (PPC)
>>             iSomeWackyFunction();
>>          else
>>             SomeWackyFunction();   // In hope there's no other Apple
hardware.
>>      }
>>      else version (OpenBSD) {
>>        /// Blah
>>      }
>>      else version (Haiku) {
>>        /// Blah
>>      }
>>      else
>>          ... workaround ...
>> }
>> --------
>>
>
>
> That is why the best approach is to have one module per platform specific
code, with a common interface defined in .di file.
>

Don't tell me, tell the druntime maintainers.  :)


March 14, 2014
Andrei Alexandrescu píše v Pá 14. 03. 2014 v 08:17 -0700:
> On 3/14/14, 4:37 AM, Daniel Murphy wrote:
> > "Walter Bright"  wrote in message news:lfu74a$8cr$1@digitalmars.com...
> >
> >> > No, it doesn't, because it is not usable if C introduces any virtual methods.
> >>
> >> That's what the !final storage class is for.
> >
> > My mistake, I forgot you'd said you were in favor of this.  Being able to 'escape' final certainly gets us most of the way there.
> >
> > !final is really rather hideous though.
> 
> A few possibilities discussed around here:
> 
> !final
> ~final
> final(false)
> @disable final
> 
> I've had an epiphany literally a few seconds ago that "final(false)" has the advantage of being generalizable to "final(bool)" taking any CTFE-able Boolean.
> 
> On occasion I needed a computed qualifier (I think there's code in Phobos like that) and the only way I could do it was through ugly code duplication or odd mixin-generated code. Allowing computed qualifiers/attributes would be a very elegant and general approach, and plays beautifully into the strength of D and our current investment in Boolean compile-time predicates.
> 
> 
> Andrei
> 

First I think have something like

@disable(final,nothrow) would be the best way, but than I think about it
and realize that final(false) is much more better.

Only advantege of @disable(all) or @disable(something, something_else)
is we can disable more things more easily. But I almost never have
needed this.


March 14, 2014
On Friday, 14 March 2014 at 20:51:09 UTC, monarch_dodra wrote:
> On Friday, 14 March 2014 at 20:45:35 UTC, Paulo Pinto wrote:
>> Am 14.03.2014 19:50, schrieb H. S. Teoh:
>>> The real code had been moved elsewhere, you see, and
>>> whoever moved the code "kindly" decided to leave the old copy in the
>>> original file inside an #if 0 block, "for reference", whatever that
>>> means. Then silly old me came along expecting the code to still be in
>>> the old place, and sure enough it was -- except that unbeknownst to me
>>> it's now inside an #if 0 block. Gah!)
>>>
>>>
>>> T
>>>
>>
>>
>> Ouch! I feel your pain.
>>
>> This type of experience is what lead me to fight #ifdef spaghetti code.
>>
>> --
>> Paulo
>
> I hate code "commented out" in an "#if 0" with a passion. Just... Why?

Because one does not know how to use git.

PS: This sarcastic note also exists with mercurial flavor.
March 14, 2014
On Friday, 14 March 2014 at 22:06:13 UTC, Daniel Kozák wrote:
> First I think have something like
>
> @disable(final,nothrow) would be the best way, but than I think about it
> and realize that final(false) is much more better.
>

If I may, final!false . We have a syntax for compile time
parameter. Let's be consistent for once.

The concept is solid and is the way to go. DIP anyone ?
March 14, 2014
On Friday, March 14, 2014 08:17:08 Andrei Alexandrescu wrote:
> On 3/14/14, 4:37 AM, Daniel Murphy wrote:
> > "Walter Bright" wrote in message news:lfu74a$8cr$1@digitalmars.com...
> > 
> >> > No, it doesn't, because it is not usable if C introduces any virtual methods.
> >> 
> >> That's what the !final storage class is for.
> > 
> > My mistake, I forgot you'd said you were in favor of this. Being able to 'escape' final certainly gets us most of the way there.
> > 
> > !final is really rather hideous though.
> 
> A few possibilities discussed around here:
> 
> !final
> ~final
> final(false)
> @disable final
> 
> I've had an epiphany literally a few seconds ago that "final(false)" has
> the advantage of being generalizable to "final(bool)" taking any
> CTFE-able Boolean.
> 
> On occasion I needed a computed qualifier (I think there's code in Phobos like that) and the only way I could do it was through ugly code duplication or odd mixin-generated code. Allowing computed qualifiers/attributes would be a very elegant and general approach, and plays beautifully into the strength of D and our current investment in Boolean compile-time predicates.

That sounds like a good approach and could definitely reduce the number of static ifs in some generic code (though as Daniel points out, I'm not sure how common that really is).

- Jonathan M Davis
March 15, 2014
On 2014-03-14 20:51:08 +0000, "monarch_dodra" <monarchdodra@gmail.com> said:

> I hate code "commented out" in an "#if 0" with a passion. Just... Why?

Better this:


#if 0
...
#else
...
#endif


than this:


/*
...
/*/
...
//*/


-- 
Michel Fortin
michel.fortin@michelf.ca
http://michelf.ca

March 15, 2014
On Saturday, 15 March 2014 at 00:00:48 UTC, Michel Fortin wrote:
> On 2014-03-14 20:51:08 +0000, "monarch_dodra" <monarchdodra@gmail.com> said:
>
>> I hate code "commented out" in an "#if 0" with a passion. Just... Why?
>
> Better this:
>
>
> #if 0
> ...
> #else
> ...
> #endif
>
>
> than this:
>
>
> /*
> ...
> /*/
> ...
> //*/

/+
...
/*+//*//+*/
...
//+/
March 15, 2014
On 3/14/2014 5:06 AM, Manu wrote:
> In my experience, API layout is the sort of performance detail that library
> authors are much more likely to carefully consider and get right. It's higher
> level, easier to understand, and affects all architectures equally.
> It's also something that they teach in uni. People write books about that sort
> of thing.
> Not to say there aren't terrible API designs out there, but D doesn't make
> terrible-api-design-by-default a feature.
> Stuff like virtual is the sort of thing that only gets addressed when it is
> reported by a user that cares, and library authors are terribly reluctant to
> implement a breaking change because some user reported it. I know this from
> experience.
> I can say with confidence, poor API design has caused me less problems than
> virtual in my career.
>
> Can you honestly tell me that you truly believe that library authors will
> consider, as a matter of common sense, the implications of virtual (the silent
> default state) in their api?
> Do you truly believe that I'm making a big deal out of nothing; that I will
> never actually, in practise, encounter trivial accessors and properties that
> can't inline appearing in my hot loops, or other related issues.
>
> Inline-ability is a very strong API level performance influence, especially in a
> language with properties.
>
> Most programmers are not low-level experts, they don't know how to protect
> themselves from this sort of thing. Honestly, almost everyone will just stick
> with the default.


I find it incongruous to take the position that programmers know all about layout for performance and nothing about function indirection? It leads me to believe that these programmers never once tested their code for performance.

I know what I'm doing, and even I, when I don't test things, always make some innocuous mistake that eviscerates performance. I find it very hard to believe that final-by-default will fix untested code.

And the library APIs still are fixable. Consider:

    class C {
        void foo() { ... }
    }

and foo() needs to be final for performance, but we don't want to break existing users:

    class C {
        void foo() { foo2(); }
        final void foo2() { ... }
    }