March 15, 2014
Am Fri, 14 Mar 2014 10:53:59 -0700
schrieb Walter Bright <newshound2@digitalmars.com>:

> 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 ...
>      }
>      --------

I meant really 'custom versions', not OS-related. For example cairoD wraps the cairo C library. cairo can be compiled without or with PNG support. Historically cairoD used version(CAIRO_HAS_PNG_SUPPORT) for this.

Then in cairo.d
version(CAIRO_HAS_PNG_SUPPORT)
{
   extern(C) int cairo_save_png(char* x);
   void savePNG(string x){cairo_save_png(toStringz(x))};
}

now I have to use version=CAIRO_HAS_PNG_SUPPORT when compiling cairoD, but every user of cairoD also has to use version=CAIRO_HAS_PNG_SUPPORT or the compiler will hide the savePNG functions. There are also examples where not using the same version= switches causes runtime crashes.

Compiler defined version(linux, OSX) are explicitly not affected by this issue as they are always defined by the compiler for all modules.
March 15, 2014
"bearophile"  wrote in message news:yzhcfevgjdzjtzghxtia@forum.dlang.org...

> Andrei has decided to not introduce "final by default" because he thinks it's a too much large breaking change. So your real world data is an essential piece of information to perform an informed decision on this topic (so much essential that I think deciding before having such data is void decision). So are you willing to perform your analysis on some other real D code? Perhaps dub?

If anyone wants to try this out on their code, the patch I used was to add this:

if (ad && !ad->isInterfaceDeclaration() && isVirtual() && !isFinal() &&
   !isOverride() && !(storage_class & STCvirtual) && !(ad->storage_class & STCfinal))
{
   warning(loc, "virtual required");
}

Around line 623 in func.c (exact line doesn't matter, just stick it in with the rest of the checks)

I also had to disable the "static member functions cannot be virtual" error. 

March 15, 2014
I don't think that the virtual-by-default is the most important aspect of the language, so I can live with it (even if I strongly dislike it). What actually scares me is this:

On Saturday, 15 March 2014 at 11:59:41 UTC, Marco Leise wrote:

> One message that this sends out is that a proposal, even with
> almost complete lack of opposition, an in-depth discussion,
> long term benefits and being in line with the language's goals
> can be turned down right when it is ready to be merged.

A decision was taken, being backed by several people, work had begun (yebbiles pulls) and now the proposal gets reverted out of the blue.
Somehow makes me wonder how the future of D is decided upon. To me, it really feels like it's made by last-second decisions. I think it can really make a bad impression to newcomers.

> I neither see a small vocal faction intimidating (wow!) the
> leadership, nor do I see a dictate of the majority.
Agree. But I think that the "vocal faction intimidating" was just a horrible choice of words, with no harmful intent. Just like the "But we nearly lost a major client over it." used at the begin of the thread.
March 15, 2014
On 3/15/2014 2:21 AM, Paulo Pinto wrote:
> In any language with properties, accessors also allow for:
>
> - lazy initialization
>
> - changing the underlying data representation without requiring client code to
> be rewritten
>
> - implement access optimizations if the data is too costly to keep around

You can always add a property function later without changing user code.

March 15, 2014
On 2014-03-15 18:18:27 +0000, Walter Bright <newshound2@digitalmars.com> said:

> On 3/15/2014 2:21 AM, Paulo Pinto wrote:
>> In any language with properties, accessors also allow for:
>> 
>> - lazy initialization
>> 
>> - changing the underlying data representation without requiring client code to
>> be rewritten
>> 
>> - implement access optimizations if the data is too costly to keep around
> 
> You can always add a property function later without changing user code.

In some alternate universe where clients restrict themselves to documented uses of APIs yes. Not if the client decides he want to use ++ on the variable, or take its address, or pass it by ref to another function (perhaps without even noticing).

And it also breaks binary compatibility.

If you control the whole code base it's reasonable to say you won't bother with properties until they're actually needed for some reason. It's easy enough to refactor your things whenever you decide to make the change.

But if you're developing a library for other to use though, it's better to be restrictive from the start... if you care about not breaking your client's code base that is. It basically comes to the same reasons as to why final-by-default is better than virtual-by-default: it's better to start with a restrictive API and then expand the API as needed than being stuck with an API that restricts your implementation choices later on.

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

March 15, 2014
On Saturday, 15 March 2014 at 08:32:32 UTC, Paulo Pinto wrote:
> Am 15.03.2014 06:29, schrieb deadalnix:
>> On Saturday, 15 March 2014 at 04:03:20 UTC, Manu wrote:
>>> That said, function inlining is perhaps the single most important API
>>> level
>>> performance detail, and especially true in OO code (which advocates
>>> accessors/properties).
>>
>> OOP say ask, don't tell. Accessors, especially getters, are very anti
>> OOP. The haskell of OOP would prevent you from returning anything from a
>> function.
>
> What?!?
>
> Looking at Smalltalk, SELF, CLOS and Eiffel I fail to see what you mean, given that they are the grand daddies of OOP and all have getters/properties.
>

And LISP is grand daddy of functional, and do not have most of the features of modern functional languages.

OOP is about asking the object to do something, not getting infos from an object and acting depending on that. In pseudo code, you'd prefers

object.DoTheJob()

to

auto infos = object.getInfos();
doTheJob(infos);

If you push that principle to the extreme, you must not return anything. Obviously, most principle pushed to the extreme often become impractical, btu here you go.

Now, what about a processing that would give me back a result ? Like the following:

auto f = new File("file");
writeln(f.getContent());

Sound cool, right ? But you are telling not asking. You could do:

interface FileProcessor {
    void processContent(string);
}

class WritelnFileProcessor : FileProcessor {
    void processContent(string s) { writeln(s); }
}

auto f = new File("file");
f.process(new WritelnFileProcessor());

This has several advantages that I don't have much time to expose in detail. For instance, the FileContentProcessor could have more methods, so it can express a richer interface that what could be returned. If some checks need to be done (for security reasons for instance) you can ensure withing the File class that they are done properly. It makes things easier to test. You can completely change the way the file class works internally without disturbing any of the code that use it, etc ...

However, this is clear that it come at a cost. I don't doubt an OO language pushing this to the extreme would see concept that confuse everybody emerging, pretty much like monads confuse the hell out of everybody in functional languages.
March 15, 2014
> However, this is clear that it come at a cost. I don't doubt an OO language pushing this to the extreme would see concept that confuse everybody emerging, pretty much like monads confuse the hell out of everybody in functional languages.

Looks like explicit continuation passing style to me. So "OO done right" means "Human compiler at work"...
March 15, 2014
On Saturday, 15 March 2014 at 18:18:28 UTC, Walter Bright wrote:
> On 3/15/2014 2:21 AM, Paulo Pinto wrote:
>> In any language with properties, accessors also allow for:
>>
>> - lazy initialization
>>
>> - changing the underlying data representation without requiring client code to
>> be rewritten
>>
>> - implement access optimizations if the data is too costly to keep around
>
> You can always add a property function later without changing user code.

In many situations you can't. As was already mentioned, ++ and taking the address of it were two such situations.

ABI compatibility is also a large problem (less so in D for now, but it will be in the future). Structs change, positions change, data types change. If users use your struct directly, accessing its fields, then once you make even a minor change, their code will break in unpredictable ways. This was a huge annoyance for me when trying to deal with libjpeg. There are multiple versions and these versions have a different layout for the struct. If the wrong library is linked, the layout is different. Since it's a D binding to a C file, you can't just use the C header which you know to be up to date on your system, instead you have to make your own binding and hope for the best. They tr
y to work around this by making you pass in a version string when creating the libjpeg structs and failing if this string does not exactly match what the loaded version. This creates a further mess. It's a large problem, and there's talk of trying to eventually deprecate public field access in libjpeg in favour of accessors like libpng has done (though libpng still uses the annoying passing in version since they did not use accessors from the start and some fields remained public). Accessors are absolutely required if you intend to make a public library and exposed fields should be avoided completely.
March 15, 2014
On 3/15/2014 2:22 AM, Jacob Carlborg wrote:
> On Friday, 14 March 2014 at 18:06:47 UTC, Iain Buclaw wrote:
>
>>     else version (OSX) {
>>         version (PPC)
>>            iSomeWackyFunction();
>>         else
>>            SomeWackyFunction();   // In hope there's no other Apple hardware.
>
> There's also ARM, ARM64, x86 32bit and PPC64.

Right, there should not be else clauses with the word "hope" in them. They should be "static assert(0);" or else be portable.

March 15, 2014
On Saturday, 15 March 2014 at 20:15:16 UTC, Araq wrote:
>> However, this is clear that it come at a cost. I don't doubt an OO language pushing this to the extreme would see concept that confuse everybody emerging, pretty much like monads confuse the hell out of everybody in functional languages.
>
> Looks like explicit continuation passing style to me. So "OO done right" means "Human compiler at work"...

Sound like you are enjoying criticize OOP, but so far, you didn't come up with anything interesting. Please bring something to the table or cut the noise.