June 18, 2022
On 6/18/2022 2:42 AM, Max Samukha wrote:
> You might have based your decisions on the feedback by the vociferous few while there is the silent majority whose opinion is unknown. I've been familiar with D since around 2006 and never voiced my opinion about the module-level private until now.

Not even Andrei agreed with me. Not a single person that I recall.

Anytime one interfaces with humans, inconsistency turns out to be desirable.

Here's another inconsistency:

  void func()
  {
      int a;
      {
         int a;  // error
      }
   }
June 18, 2022
On 6/18/2022 8:01 AM, Dennis wrote:
> On Saturday, 18 June 2022 at 09:42:40 UTC, Max Samukha wrote:
>> Yes, that's a good one. I still believe it wasn't worth the special case.
> 
> What special case? Using `;` as an empty statement instead of `{}` is not allowed anywhere in D as far as I can tell.

It's not allowed as an empty statement.
June 19, 2022
On Saturday, 18 June 2022 at 17:38:21 UTC, deadalnix wrote:
>
> More importantly, modules are the unit of abstraction over implementation. When I open a module, I see all the code that implement everything that's in the module. If there is something in there that I shouldn't see, then it shouldn't be in the module.
>
> It's very simple really.

Modules are an ideal form of encapsulation for procedural like programming.

D makes for a nice language for procedural like progamming.

The problem is, D claims to support OOP, using classes -> "The object-oriented features of D all come from classes." - https://dlang.org/spec/class.html

However, when you put this claim to the test, you suddenly find there is no language mechanism to apply one of the most important principles in OOP, which is information hiding -> of course I mean this in the context of code within a module.

The idea that all data within a class is global to the module, and therefore mutable, by default, is inconsistent with the claim that D makes.

Worse even, there is no language option to change this, let alone enforce it (at compile time).

Information hiding is central to the concept of a concrete type, which in OOP, is what a class is -> a concrete type.

OK. So how do you apply the principle of information hiding in D. Well, you put the class that needs this, into it's own module.

Sure, you've now you've got a defacto means of hiding information (since there's no other code in the module) - but that comes at the cost of new design constraint that gets imposed on you (one class per module, always, just as a defacto means to make it into a concrete type).

But this is not OOP. Lets be really clear about this.

Therefore I find the claim, that D support OOP, to be.. dubious.

D clearly wants to be a procedural programming language, not an OOP.

I have no problem with that. All power to ya...

But please, don't make the claim that the language supports OOP, when it clearly is missing a language feature to allow a class to be a concrete type.

In OOP, private should be the default in classes, and it is usually the better choice (paraphrasing Stroustrup here).

This is why I only feel comfortable doing OOP in other languages, and not D.

The lack of a language feature to keep information private to the class (and enforce that design intention at compile time) , cannot be justified as just being a tradeoff. Rather, it was a design decision, made by Walter. It was a decision made for convenience, but at the expense of OOP.

Other languages that do support OOP, have not 'needed' to make this 'tradeoff' in order to get a cohesive language that can support OOP.

June 19, 2022

On Saturday, 18 June 2022 at 21:17:52 UTC, Walter Bright wrote:

>

Anytime one interfaces with humans, inconsistency turns out to be desirable.

No. Common mistakes is a linter/warning issue or a syntax redesign issue.

>

Here's another inconsistency:

void func()
{
int a;
{
int a; // error
}
}

More likely to be annoying as useful, now you need to refactor if you add a mixin or if you copy code.

Not being able to shadow variablenames such as «tmp» or «i» is just annoying.

June 19, 2022
On Sunday, 19 June 2022 at 00:48:12 UTC, forkit wrote:
> Information hiding is central to the concept of a concrete type, which in OOP, is what a class is -> a concrete type.
>
> OK. So how do you apply the principle of information hiding in D. Well, you put the class that needs this, into it's own module.
>
> Sure, you've now you've got a defacto means of hiding information (since there's no other code in the module) - but that comes at the cost of new design constraint that gets imposed on you (one class per module, always, just as a defacto means to make it into a concrete type).
>
> But this is not OOP. Lets be really clear about this.

It's funny that you say this, because this is exactly how information hiding works in the Common Lisp Object System:

> Like the OO systems in most dynamic languages, CLOS does not enforce
> encapsulation. Any slot can be accessed using the slot-value
> function or via (optionally auto-generated) accessor methods. To
> access it via slot-value you have to know the name of the slot. CL
> programmers use the language's package facility to declare which
> functions or data structures are intended for export.

Source: https://en.wikipedia.org/wiki/Common_Lisp_Object_System

A "package" in Common Lisp is more or less the same thing as a module in D: a namespace for symbol definitions.

If you are willing to bite the bullet here and say that CLOS is "not OOP" because it lacks encapsulation, then fair enough, but at that point I think you must admit that your idea of what counts as OOP is not shared by most developers (including Alan Kay himself, who cited Lisp as an example of OOP done right).
June 19, 2022

On Saturday, 18 June 2022 at 15:01:16 UTC, Dennis wrote:

>

On Saturday, 18 June 2022 at 09:42:40 UTC, Max Samukha wrote:

>

Yes, that's a good one. I still believe it wasn't worth the special case.

What special case? Using ; as an empty statement instead of {} is not allowed anywhere in D as far as I can tell.

The empty statement is a special case. No special cases would be allowing any statement.

June 19, 2022
On Sunday, 19 June 2022 at 02:39:52 UTC, Paul Backus wrote:
>
> ..
> It's funny that you say this, because this is exactly how information hiding works in the Common Lisp Object System:
> ...
>
> Source: https://en.wikipedia.org/wiki/Common_Lisp_Object_System
>
> A "package" in Common Lisp is more or less the same thing as a module in D: a namespace for symbol definitions.
>
> If you are willing to bite the bullet here and say that CLOS is "not OOP" because it lacks encapsulation, then fair enough, but at that point I think you must admit that your idea of what counts as OOP is not shared by most developers (including Alan Kay himself, who cited Lisp as an example of OOP done right).

Well sure. The earth rotates around the sun.

If someone tells me the sun rotates around the earth, thent I can say that is factually incorrect.

There are no 'facts' when it comes to describing what OOP is ;-)

Anyone is free to make anything up, to suit what they think it is, or should be.

But to me, an object is a self-contained encapsulated unit of abstraction. By that I mean is has control of its own state and behaviour. For this to be possible, it needs to be able to 'hide' stuff from the outside world (to ensure the outside world is not changing its state or behaviour willy nilly.. )

It escapes my comprehension, as to why D cannot provide compiler support for this design, whereas other major langauges do.

Was D targetting CLOS programmers?

Was it targetting C++ programmers, but insisting the change their way of thinking if they come over to D?

Seems like such a simple, useful feature, to be able to say "this is private to this class, so compiler, please enforce this at compile time in case anyone else tries to change me without my permission".

I've been able to do exactly this, for 20+ years! And C++ has provided this to its users for considerably longer. Even Swift, a relatively new language, can do this - no problem whatsoever.

I'd like to know what the so called 'tradeoff' is, for not having this 'option', cause is sure seems a tradeoff to help the compiler writer, and not the programmer.
June 19, 2022

On Saturday, 18 June 2022 at 21:13:07 UTC, deadalnix wrote:

>

On Saturday, 18 June 2022 at 18:02:08 UTC, Max Samukha wrote:

>

On Saturday, 18 June 2022 at 08:04:55 UTC, FeepingCreature wrote:

>

a function in a module is "on the same level" as a method in the class.

If it is on the same level, then I would expect 'foo' below to lock the mutex and run the invariant check:

synchronized class C
{
    private int x;
    private int y = 1;

    invariant() { assert(y == x + 1); }
}

void foo(C c, int x)
{
    c.x = x;
    c.y = x + 1;
}

If the argument is that synchronized and invariant are messed up, yes.

The argument is that those imply that encapsulation is on the class level while 'private' used to enforce the encapsulation is on the module level, which makes the design inconsistent. If people argue that there is no "correct" level of encapsulation (which I agree with), then 'synchronized/invariant' should align with that view.

June 19, 2022
On Sunday, 19 June 2022 at 02:39:52 UTC, Paul Backus wrote:
>
> ...
> If you are willing to bite the bullet here and say that CLOS is "not OOP" because it lacks encapsulation, then fair enough, but at that point I think you must admit that your idea of what counts as OOP is not shared by most developers (including Alan Kay himself, who cited Lisp as an example of OOP done right).

I know nothing of CLOS.

A quick read of CLOS wiki, and it seems you can turn a ceramic aardvark into a graceful Old World ruminant, at runtime!

That doesn't sound like my understanding of the open/closed principle, which is what most of us (I guess) would associate with OOP.

i.e.

"Software entities (classes, modules, functions, etc.) Should be open for extension, but closed for modification."

June 19, 2022
On Sunday, 19 June 2022 at 06:22:57 UTC, forkit wrote:
> On Sunday, 19 June 2022 at 02:39:52 UTC, Paul Backus wrote:
>>
>> ...
>> If you are willing to bite the bullet here and say that CLOS is "not OOP" because it lacks encapsulation, then fair enough, but at that point I think you must admit that your idea of what counts as OOP is not shared by most developers (including Alan Kay himself, who cited Lisp as an example of OOP done right).
>
> I know nothing of CLOS.
>
> A quick read of CLOS wiki, and it seems you can turn a ceramic aardvark into a graceful Old World ruminant, at runtime!
>
> That doesn't sound like my understanding of the open/closed principle, which is what most of us (I guess) would associate with OOP.
>
> i.e.
>
> "Software entities (classes, modules, functions, etc.) Should be open for extension, but closed for modification."

I advise getting a copy of The Art of MetaObject Protocol, a CS OOP literature gem that describes the genesis of CLOS.

https://en.m.wikipedia.org/wiki/The_Art_of_the_Metaobject_Protocol

Additionally a look into LOOP, the Xerox PARC Interlisp-D based OOP, used on their Lisp Machines variant.

https://www.softwarepreservation.org/projects/LISP/interlisp-d

Or speaking of them, the Flavors system,

https://en.m.wikipedia.org/wiki/Flavors_(programming_language)

As I already mentioned on the other thread, CS literature is full of various understandings of what is OOP all about.