Re: Polymorphism? Passing arguments

2017-11-03 Thread Martin via Digitalmars-d-learn

ok, thanks you very much for the information.




Re: Polymorphism? Passing arguments

2017-11-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, November 04, 2017 01:52:06 Martin via Digitalmars-d-learn 
wrote:
> Thank you for the answer
>
> On Saturday, 4 November 2017 at 01:35:41 UTC, Adam D. Ruppe wrote:
> > Why are these ref?
> > Just taking ref away from both of those will likely fix your
> > problems.
>
> because without it i get the error "Program exited with code -11"
>
> The thing is, somwhere deeper in `setRelation` i call two
> functions:
> ```
> public void addChild(ref Node child) {
>this.children ~= &child;
> }
>
> public void setParent(ref Node parent) {
>this.parent = &parent;
> }
> ```

Okay, classes are reference types in D just like they are in Java or C#.
They do not live on the stack like they do in C++ (for that, you'd use a
struct, which has no inheritance). Class references are basically pointers.
Taking the address of a class reference is taking the address of the
variable on the stack. If T is a class, then

T foo = getSomeT();
T* bar = &foo;

in D would be more or less equivalent to this in C++:

T* foo = getSomeT();
T** bar = &foo;

By making the parameter ref, you are then getting the address of the class
reference in the caller, whereas without it, you're getting the address of
the class reference of the callee, and that then goes away when the function
exits - which is why things blow up on you. But they'll blow up the same way
once the variable in the class reference that you passed in goes out of
scope, and you try to use the addresses that you stored.

If you ever use & with a class in D, you're almost certainly doing something
wrong.

If typeof(this.parent) is Node, then setParent should be able to just accept
the Node without ref and assign it to this.parent, and this.parent is then
going to be pointing to the same object that the Node you passed to
setParent was pointing to. There should be no need for pointers or &.

I would suggest that you read this online book:

http://ddili.org/ders/d.en/index.html

It should help you with all of the basic stuff in D like this. If you want
to know about classes specifically, then you can skip straight to the
chapter on classes:

http://ddili.org/ders/d.en/class.html

but I expect that you'll benefit from reading the whole thing.

- Jonathan M Davis



Re: Polymorphism? Passing arguments

2017-11-03 Thread Martin via Digitalmars-d-learn

Thank you for the answer

On Saturday, 4 November 2017 at 01:35:41 UTC, Adam D. Ruppe wrote:

Why are these ref?
Just taking ref away from both of those will likely fix your 
problems.


because without it i get the error "Program exited with code -11"

The thing is, somwhere deeper in `setRelation` i call two 
functions:

```
public void addChild(ref Node child) {
  this.children ~= &child;
}

public void setParent(ref Node parent) {
  this.parent = &parent;
}
```




Re: Polymorphism? Passing arguments

2017-11-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, November 04, 2017 01:22:05 Martin via Digitalmars-d-learn 
wrote:
> I have a interface
> `interface Node {...}`
>
> and some classes implementing Node:
> ```
> class Text : Node {...}
> class Element : Node {...}
> ```
> and a function like this:
> `public void setRelation(ref Node parent , ref Node child) {...}`
>
> if i do this it works:
> ```
> Node root = new Element("root");
> Node text = new Text("blah");
> setRelation(root ,  text);
> ```
>
> but this does not:
> ```
> Node root = new Element("root");
> setRelation(root , new Text("blah"));
> ```
>
> >Error: function Nodes.setRelation (ref Node parent, ref Node
> >child) is not callable using argument types (Node, Text)
>
> Why is this? Text implements Node. This is how i do it in other
> Languages - How can would be this possible in D?

The problem really doesn't have anything to do with the types involved. It
has to do with ref. ref only accepts lvalues, not rvalues. So, you can't
pass it the result of new or the result of any function that returns by
value. The first example works, because you're passing variables, which are
lvalues. So, if you remove ref from parent and child, then you won't have
any problems like this, and unless you're planning on altering which objects
parent and child refer to, there's really no reason to have them be marked
with ref.

- Jonathan M Davis



Re: Polymorphism? Passing arguments

2017-11-03 Thread Adam D. Ruppe via Digitalmars-d-learn

On Saturday, 4 November 2017 at 01:22:05 UTC, Martin wrote:

`public void setRelation(ref Node parent , ref Node child)


Why are these ref?

A lot of people coming from C++ use ref in places you shouldn't 
use it in D. Remember, in D, a class object is implicitly ref, so 
doing `ref Object` is more like `Object**` or `Object&&` - often 
more direction than you need and want.


Just taking ref away from both of those will likely fix your 
problems.



setRelation(root , new Text("blah"));


In this case, it definitely will. An explicit ref in D must refer 
to a variable name, not just an object. Since `new Text()` has no 
variable name, it cannot be ref.


Why is this? Text implements Node. This is how i do it in other 
Languages - How can would be this possible in D?


But, even if it were legal to do what you're trying on ref 
semantics, this would still be broken polymorphism! Consider the 
following:


Text text = new Text();
Node n = text; // legal, Text implements Node
n = new Element(); // also legal, Element impls Node too

bt:

Text text = new Text();
Node* n = &text; // subtly different than above...
*n = new Element(); // ...because this would be bad news
// what is text now?


If the compiler allowed that pointer (or the ref, same deal), you 
would have overwritten a Text object with an Element, breaking 
the type system.



This is also the reason why a Text[] will not cast to a Node[], 
even though an individual Text is a Node.


Polymorphism? Passing arguments

2017-11-03 Thread Martin via Digitalmars-d-learn

I have a interface
`interface Node {...}`

and some classes implementing Node:
```
class Text : Node {...}
class Element : Node {...}
```
and a function like this:
`public void setRelation(ref Node parent , ref Node child) {...}`

if i do this it works:
```
Node root = new Element("root");
Node text = new Text("blah");
setRelation(root ,  text);
```

but this does not:
```
Node root = new Element("root");
setRelation(root , new Text("blah"));
```
Error: function Nodes.setRelation (ref Node parent, ref Node 
child) is not callable using argument types (Node, Text)


Why is this? Text implements Node. This is how i do it in other 
Languages - How can would be this possible in D?


Re: private keyword dont appear to do anything

2017-11-03 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Nov 03, 2017 at 05:59:20PM -0600, Jonathan M Davis via 
Digitalmars-d-learn wrote:
> On Friday, November 03, 2017 16:32:52 H. S. Teoh via Digitalmars-d-learn 
> wrote:
> >  Perhaps the solution is to go the
> > one-overload-set-per-file route, with std/algorithm/package.d
> > basically importing everything underneath. :-P 
> >
> > (Shhh, don't tell Andrei, or we'll get another lecture about wasting
> > time on worthless things while more important things are left to
> > do.)
> 
> Actually, when Daniel and I were trying to talk Walter into adding the
> package.d feature so that std.datetime could be split up without
> breaking code, Walter made a comment about how he didn't see any
> problem with there being a function per module. So, he might be on
> board with code arrangements along those lines, but I have no idea
> about Andrei.

I got chastised by Andrei for doing the std.algorithm split.  He only
conceded after I stated that I couldn't run the std.algorithm unittests
on my PC anymore because it was taking up GBs of memory.  Based on that
I'm assuming he would likely be opposed to yet another refactoring of
std.algorithm. :-D


> Personally, I think that splitting stuff up that far makes it a pain
> to deal with, even if it might help the implementation sometimes. It's
> already really annoying that I have to figure out which module
> something in std.algorithm is in now, because the style check junk
> that has been added to Phobos requires that you not only use selective
> imports but that you use the module that it's directly in, so you
> can't do something like
> 
> import std.algorithm : map;
> 
> but instead have to go figure out which module it's currently living
> in and add that after std.algorithm.

If we split everything into its own module, presumably the module would
be named after the function itself, and would inherit directly from the
top-level std.algorithm package.  So it would be a simple matter of
going to std/algorithm/${function_name}.d to find the code, which
arguably would be *simpler* than it is today.

But again, I'm not seriously proposing this, and I doubt we'd actually
do it anyway.  The sheer amount of effort involved, plus potential user
code breakage (explicit imports of std.algorithm.searching, for example,
would break, unless we keep searching.d around as just a bunch of public
imports, which is kinda ugly), yielding only marginal benefits.  I just
don't see W & A approving of something like that.


[...]
> Where you risk running into serious problems is where you have a large
> module full of interdependent stuff, because then it's all highly
> coupled and hard to keep track of, so it becomes hard to understand
> and maintain.  You can have the same problems across modules, but when
> you split stuff up across modules, it tends to force you to think
> about things differently so that you don't make everything so highly
> coupled - though a bad programmer (or a good programmer having a bad
> day) can make any code a mess.
[...]

"Real Programmers can write assembly code in any language." :-D


T

-- 
Winners never quit, quitters never win. But those who never quit AND never win 
are idiots.


Re: private keyword dont appear to do anything

2017-11-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, November 03, 2017 16:32:52 H. S. Teoh via Digitalmars-d-learn 
wrote:
>  Perhaps the solution is to go the
> one-overload-set-per-file route, with std/algorithm/package.d basically
> importing everything underneath. :-P 
>
> (Shhh, don't tell Andrei, or we'll get another lecture about wasting
> time on worthless things while more important things are left to do.)

Actually, when Daniel and I were trying to talk Walter into adding the
package.d feature so that std.datetime could be split up without breaking
code, Walter made a comment about how he didn't see any problem with there
being a function per module. So, he might be on board with code arrangements
along those lines, but I have no idea about Andrei.

Personally, I think that splitting stuff up that far makes it a pain to deal
with, even if it might help the implementation sometimes. It's already
really annoying that I have to figure out which module something in
std.algorithm is in now, because the style check junk that has been added to
Phobos requires that you not only use selective imports but that you use the
module that it's directly in, so you can't do something like

import std.algorithm : map;

but instead have to go figure out which module it's currently living in and
add that after std.algorithm.

Of course, I also don't generally have a problem with large modules. They
_can_ become large enough to become a problem, but I've found that I have a
much higher tolerance for how much goes in a single file than many of the D
devs seem to have. IMHO, the main thing that starts causing problems with
large modules is when you start doing stuff like using attribute labels like

@safe:

or attribute blocks like

@safe
{
}

because then it becomes difficult to know which attributes actually apply to
a piece of code.

Most stuff is self-contained enough that having a bunch of stuff in a single
module frequently isn't a real problem. So, if they're related enough, I
have no problem with it. But good organization is arguably difficult to get
right and highly subjective - just like naming stuff is.

Where you risk running into serious problems is where you have a large
module full of interdependent stuff, because then it's all highly coupled
and hard to keep track of, so it becomes hard to understand and maintain.
You can have the same problems across modules, but when you split stuff up
across modules, it tends to force you to think about things differently so
that you don't make everything so highly coupled - though a bad programmer
(or a good programmer having a bad day) can make any code a mess.

- Jonathan M Davis



Re: private keyword dont appear to do anything

2017-11-03 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Nov 03, 2017 at 04:30:21PM -0600, Jonathan M Davis via 
Digitalmars-d-learn wrote:
> On Friday, November 03, 2017 14:52:22 H. S. Teoh via Digitalmars-d-learn 
> wrote:
[...]
> > Arguably, many of these large flat files ought to be split up into
> > smaller files.  For example, std.algorithm.* and std.range.* all
> > tend to be conglomerations of basically-independent groups of
> > structs and functions.  Iota and Cycle never interact with each
> > other, and neither of them interacts with Recurrence, yet these all
> > sit in the same file.
> >
> > Seems to me like a typical case of low cohesion, which, according to
> > the ideals of encapsulation, ought to be grounds for splitting up
> > the file into self-contained parts.
> >
> > But of course, there are pragmatic reasons for the way things
> > currently are.
> 
> If you take that to the extreme, you just end up with a function per
> module, which is pretty ridiculous IMHO (though that may be what you
> mean by pragmatic reasons).

It's not that ridiculous if you consider that some of the more
heavily-used Phobos functions are actually not individual functions, but
overload sets.  I know we have been trying to merge some of the
unnecessary overload sets for other reasons, but some of these overload
sets can get pretty big.  Compound that with the long string of
unittests associated with each overload, that has accumulated from a
long string of bug fixes, etc., and you have pretty good justification
for keeping just that single overload set in its own file, together with
its associated unittests, and potentially also other paraphrenalia like
enums or other declarations used by the overload set, but not used
anywhere else.


> And really, free functions like that are exactly the sort of places
> where encapsulation tends not to matter much, because there's nothing
> to encapsulate beyond the guts of the functions themselves, which are
> already encapsulated.

Arguably, once a function grows past a certain length, it's time to
break it down into more manageable pieces.  Having a function sit in its
own file gives you a nice working space for this sort of refactoring,
without worrying about namespace conflicts with unrelated code.

Still, I agree that some degree of judgment is involved here.  If we're
talking about a simple function that will never grow past 5-10 lines, it
does seem a little pointless to keep it in its own file, just to adhere
to some ideal of encapsulation.

But IME, with Phobos code even simple functions eventually grow into
multi-page monsters over time, once you start adding type-specific
specializations to deal with performance issues and the like.  Just look
at std.algorithm.searching.find, for example.  Several different
overloads, and static if blocks within an overload, sometimes on the
lengthy side depending on the specific optimization being implemented.
Arguably we should factor out some of the static if blocks or overloads
into separate private functions for easier future maintenance /
management if more specializations are added, or we need to balance
between different optimizations based on different factors. Static-if /
else blocks just aren't very conducive to this sort of thing.  And being
able to do this in a file dedicated to .find would be cleaner than
having to do surgery in a 4600-line file (and having to deal with
potential merge conflicts with other unrelated changes to the same file
-- though git is so good at this that one generally doesn't run into
much of a problem).


> The situation is very different from something like std.container
> where you have types which have member variables which could be
> protected from access by other stuff in their modules if private
> worked differently.

Well, std.container *has* been split into submodules per container type.
I think that's a much better organization than in std.algorithm.*.


> Figuring out a good way to organize a bunch of free functions is
> difficult (as evidenced by the fact that plenty of folks have a hard
> time remembering what is where inside of std.algorithm and std.range),
> but that's really not an encapsulation problem, just a code
> organization problem.
[...]

 Perhaps the solution is to go the
one-overload-set-per-file route, with std/algorithm/package.d basically
importing everything underneath. :-P 

(Shhh, don't tell Andrei, or we'll get another lecture about wasting
time on worthless things while more important things are left to do.)


T

-- 
All problems are easy in retrospect.


Re: private keyword dont appear to do anything

2017-11-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, November 03, 2017 14:52:22 H. S. Teoh via Digitalmars-d-learn 
wrote:
> On Fri, Nov 03, 2017 at 05:43:55PM -0400, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> > On 11/3/17 5:08 PM, Nathan S. wrote:
> > > On Friday, 3 November 2017 at 20:01:27 UTC, Jonathan M Davis wrote:
> > > > Most folks are surprised by this behavior
> > >
> > > I found it surprising at first but now any other way seems absurd to
> > > me.  None of the benefits of data encapsulation apply to code
> > > written five lines away in the same file.
> >
> > I also enjoy the mechanism, but I have to call this out as incorrect.
> > Encapsulation is about being able to prove to yourself exactly how an
> > object's private data can possibly be manipulated. It's not just 5
> > lines away, it's the whole file you have to review.
> >
> > If you have large flat files like Phobos, then encapsulation is
> > essentially impossible to review.
>
> [...]
>
> Arguably, many of these large flat files ought to be split up into
> smaller files.  For example, std.algorithm.* and std.range.* all tend to
> be conglomerations of basically-independent groups of structs and
> functions.  Iota and Cycle never interact with each other, and neither
> of them interacts with Recurrence, yet these all sit in the same file.
>
> Seems to me like a typical case of low cohesion, which, according to the
> ideals of encapsulation, ought to be grounds for splitting up the file
> into self-contained parts.
>
> But of course, there are pragmatic reasons for the way things currently
> are.

If you take that to the extreme, you just end up with a function per module,
which is pretty ridiculous IMHO (though that may be what you mean by
pragmatic reasons). And really, free functions like that are exactly the
sort of places where encapsulation tends not to matter much, because there's
nothing to encapsulate beyond the guts of the functions themselves, which
are already encapsulated. The situation is very different from something
like std.container where you have types which have member variables which
could be protected from access by other stuff in their modules if private
worked differently.

Figuring out a good way to organize a bunch of free functions is difficult
(as evidenced by the fact that plenty of folks have a hard time remembering
what is where inside of std.algorithm and std.range), but that's really not
an encapsulation problem, just a code organization problem.

- Jonathan M Davis



Re: How to use containers in lock based concurrency

2017-11-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, November 03, 2017 21:23:02 Nathan S. via Digitalmars-d-learn 
wrote:
> Is this advice from 2015 outdated? I found it while I was
> wrestling with shared data structures, and after reading I
> stopped doing that.
>
> https://p0nce.github.io/d-idioms/#The-truth-about-shared
>
> >The truth about shared
> >It's unclear when and how shared will be implemented.
> >Virtually noone use shared currently. You are better off
> >ignoring it at this moment.

That advice was wrong when it was written. Plenty of folks don't understand
how to use shared properly, and there are lots of folks who cop out and use
__gshared instead, but shared _does_ work, even if it's annoying to use, and
__gshared is only intended for C globals. Using it on D objects is just
begging for problems, because the type system will treat them as
thread-local even though they're not. So, using __gshared can lead to
subtle, hard-to-find bugs that shared code won't have.

One of the problems with shared has been that it hasn't been used where it
should be (e.g. core.sync.mutex didn't use it, but I think that that's been
fixed now), making it harder to write shared code than it should be.
However, a lot of it just comes down to the fact that everyone balks at the
fact that shared requires casting to use properly. You rarely simply call
functions on shared objects, because if you did, there would be race
conditions. Rather, the way that shared should normally be used is
essentially:

shared(MyObject) mySharedObject;
// ...

synchronized(mutexForMySharedObject)
{
auto myObj = cast(MyObject)mySharedObject;
// do stuff with myObj
// ...

// make sure that at this point, there are no thread-local references
// to mySharedObject which have escaped.
}

// And here, after the lock is released, we should just have the shared
// reference again.

It would be nice if we had a way to use shared that didn't require explicit
casting like that, but that code is essentially would you would do in a C++
program that was correctly dealing with objects shared across threads except
that the C++ program wouldn't have to cast away shared, because it puts
everything in shared memory whether it's actually used on multiple threads
or not, and its type system doesn't help you segregate code that operates on
objects that are used across threads. The annoyances with D's shared come
from it preventing you from doing stuff that actually isn't thread-safe and
requiring you to go to extra effort to then use the objects. What we end up
with is a bit like @safe and @trusted in that most of the code does not use
shared objects and has any shared objects that it does have explicitly
marked that way, and then there are small sections of code where you do the
risky thing that requires scrutiny where you cast away shared and operate on
it as if it were thread-local - of course, with a lock to ensure that it's
actually safe to operate on the object as thread-local, but all of that
requires that the programmer manually verify it rather than the compiler
being able to guarantee it for you like it can be preventing you from doing
stuff with shared objects that isn't thread-safe.

In principle, synchronized classes as described in TDPL are supposed to at
least partially solve the casting problem, because they would guarantee that
the objects don't escape from the synchronized class, allowing the compiler
to safely remove the outer layer of shared on member variables so that you
get that automatic cast - but only for the outer layer of shared (since they
can't guarantee that no other references to the data exist beyond the outer
layer). So, synchronized classes would only partially solve the problem. But
regardless, we don't actually have synchronized classes at the moment - just
synchronized functions - so we don't get even that much right now.

There is occasionally talk about overhauling shared in order to improve it,
but I think that most of that has to do with better defining spec-wise
what's going on with the memory model. We may very well be able improve some
of how shared is used as well, but fundamentally, it's very difficult to
guarantee that no other references could be mucking around with an object in
a given piece of code such that the compiler can automatically cast away
shared for you. As with @trusted, it requires the programmer to do the right
thing and verify that they're doing the right thing.

- Jonathan M Davis



Re: private keyword dont appear to do anything

2017-11-03 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Nov 03, 2017 at 05:43:55PM -0400, Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 11/3/17 5:08 PM, Nathan S. wrote:
> > On Friday, 3 November 2017 at 20:01:27 UTC, Jonathan M Davis wrote:
> > > Most folks are surprised by this behavior
> > 
> > I found it surprising at first but now any other way seems absurd to
> > me.  None of the benefits of data encapsulation apply to code
> > written five lines away in the same file.
> 
> I also enjoy the mechanism, but I have to call this out as incorrect.
> Encapsulation is about being able to prove to yourself exactly how an
> object's private data can possibly be manipulated. It's not just 5
> lines away, it's the whole file you have to review.
> 
> If you have large flat files like Phobos, then encapsulation is
> essentially impossible to review.
[...]

Arguably, many of these large flat files ought to be split up into
smaller files.  For example, std.algorithm.* and std.range.* all tend to
be conglomerations of basically-independent groups of structs and
functions.  Iota and Cycle never interact with each other, and neither
of them interacts with Recurrence, yet these all sit in the same file.

Seems to me like a typical case of low cohesion, which, according to the
ideals of encapsulation, ought to be grounds for splitting up the file
into self-contained parts.

But of course, there are pragmatic reasons for the way things currently
are.


T

-- 
Государство делает вид, что платит нам зарплату, а мы делаем вид, что работаем.


Re: private keyword dont appear to do anything

2017-11-03 Thread Steven Schveighoffer via Digitalmars-d-learn

On 11/3/17 5:08 PM, Nathan S. wrote:

On Friday, 3 November 2017 at 20:01:27 UTC, Jonathan M Davis wrote:

Most folks are surprised by this behavior


I found it surprising at first but now any other way seems absurd to me. 
None of the benefits of data encapsulation apply to code written five 
lines away in the same file.


I also enjoy the mechanism, but I have to call this out as incorrect. 
Encapsulation is about being able to prove to yourself exactly how an 
object's private data can possibly be manipulated. It's not just 5 lines 
away, it's the whole file you have to review.


If you have large flat files like Phobos, then encapsulation is 
essentially impossible to review.


-Steve


Re: private keyword dont appear to do anything

2017-11-03 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Nov 03, 2017 at 09:08:56PM +, Nathan S. via Digitalmars-d-learn 
wrote:
> On Friday, 3 November 2017 at 20:01:27 UTC, Jonathan M Davis wrote:
> > Most folks are surprised by this behavior
> 
> I found it surprising at first but now any other way seems absurd to
> me.  None of the benefits of data encapsulation apply to code written
> five lines away in the same file.

This is a good point. :-)

Though in practice, source files do tend to get long... I've had to work
with source files over 8000+ lines long, and having encapsulation
between two distant parts of the file can be useful.  However, even
then, one can argue that any benefits of encapsulation you may have are
already negated by the very-not-encapsulated practice of an 8000-line
long source file, so the point is moot anyway.


T

-- 
Don't get stuck in a closet---wear yourself out.


Re: How to use containers in lock based concurrency

2017-11-03 Thread Nathan S. via Digitalmars-d-learn
Is this advice from 2015 outdated? I found it while I was 
wrestling with shared data structures, and after reading I 
stopped doing that.


https://p0nce.github.io/d-idioms/#The-truth-about-shared


The truth about shared
It's unclear when and how shared will be implemented.
Virtually noone use shared currently. You are better off 
ignoring it at this moment.


Re: private keyword dont appear to do anything

2017-11-03 Thread Nathan S. via Digitalmars-d-learn
On Friday, 3 November 2017 at 20:01:27 UTC, Jonathan M Davis 
wrote:

Most folks are surprised by this behavior


I found it surprising at first but now any other way seems absurd 
to me. None of the benefits of data encapsulation apply to code 
written five lines away in the same file.


Re: private keyword dont appear to do anything

2017-11-03 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, November 03, 2017 13:43:15 rikki cattermole via Digitalmars-d-
learn wrote:
> Visibility modifiers like private, and public are to the module not the
> scope.
>
> "Symbols with private visibility can only be accessed from within the
> same module."
>
> This is how module based languages work, a bit more useful then to the
> scope approach IMO. An easy mistake to make.
>
> https://dlang.org/spec/attribute.html#visibility_attributes

To be fair, there are times where it would arguably be desirable to restrict
private to a struct or class, so it's not all wonderful, but it does mean
that we don't have to have the extra complication of friend functions like
C++ does (which I believe is the biggest motivation for it). And if a module
is so large that you can't make sure that nothing is accessing private
struct or class members when it shouldn't, then the module is probably
overly large and/or complicated.

Most folks are surprised by this behavior, and occasionally, they complain
about it, but in practice, the only real problem that I'm aware of is that
you can sometimes write unit tests which work just because they're in the
module, and the code doesn't work when used outside of the module. But even
that tends to be only an occasional problem.

- Jonathan M Davis



Re: How to use containers in lock based concurrency

2017-11-03 Thread crimaniak via Digitalmars-d-learn

On Friday, 3 November 2017 at 12:42:29 UTC, ANtlord wrote:
Hello! I can't get how to use double linked list in 
concurrency. Please help.

...
I get a compile error onlineapp.d(8): Error: template 
std.container.dlist.DList!string.DList.insertFront cannot 
deduce function from argument types !()(string) shared,


One Does Not Simply get the non-shared object and use in the 
shared code. (/Boromir mode)


For me, it was useful to read this: 
http://www.informit.com/articles/article.aspx?p=1609144&seqNum=11




Re: COM/OLE advanced questions

2017-11-03 Thread Guillaume Piolat via Digitalmars-d-learn
On Friday, 3 November 2017 at 12:24:43 UTC, Guillaume Piolat 
wrote:

On Friday, 3 November 2017 at 10:50:27 UTC, Kagamin wrote:


It only looks at the name.



I'll test if that name needs to be "IUnknown" or the exact 
"core.sys.windows.unknwn.IUnknown", since I'm in @nogc and not 
necessarily on Windows, so I can't inherit from 
core.sys.windows.unknwn.IUnknown (but still need a COM-like 
layout).


The answer is that "IUnknown" is all that is needed, no matter 
what the fully qualified name.




Re: private keyword dont appear to do anything

2017-11-03 Thread LunaticWare via Digitalmars-d-learn
On Friday, 3 November 2017 at 12:43:15 UTC, rikki cattermole 
wrote:
Visibility modifiers like private, and public are to the module 
not the scope.


"Symbols with private visibility can only be accessed from 
within the same module."


This is how module based languages work, a bit more useful then 
to the scope approach IMO. An easy mistake to make.


https://dlang.org/spec/attribute.html#visibility_attributes


thank you


Re: COM/OLE advanced questions

2017-11-03 Thread Guillaume Piolat via Digitalmars-d-learn
On Friday, 3 November 2017 at 12:20:43 UTC, Guillaume Piolat 
wrote:

On Friday, 3 November 2017 at 02:30:59 UTC, evilrat wrote:
My guess it will work fine when derive from any 
extern(Windows) interface(that's right, not class) that has 
base 3 methods(AddRef, Release, QueryInterface)


I'll test that scenario and see if the layout is the same.


And you were right in this.


Re: COM/OLE advanced questions

2017-11-03 Thread Guillaume Piolat via Digitalmars-d-learn

Answering my own questions:

On Thursday, 2 November 2017 at 14:22:56 UTC, Guillaume Piolat 
wrote:
Question 1. Is it mandatory to inherit from 
core.sys.windows.unknwn.IUnknown, or just having an interface 
named "IUnknown" validate it for being a COM interface?


Deriving from an interface named "IUnknown", in whatever module, 
with whatever actual methods, make the compiler consider it a 
"COM interface", which applies semantic restrictions.


The actual layout is _separated_ from the compiler considering it 
as a "COM interface", and one can achieve the exact desired 
layout with a IUnknown-like interface named in other way. One can 
test this with `delete interfaceInstance`.


The only layout effect of having the compiler consider it like 
COM interface, is that derived class will become "COM classes" 
whose only effects seems to be extern(System) as default linkage 
type.


So: you don't need the compiler to follow COM ABI, it just makes 
it easier.



Question 2. If this fails, may I emulate COM vtable layout with 
extern(C++) class? I wonder what the exact differences are 
anyway between extern(C++) and the special IUnknown.


extern(C++) is indeed very flexible, with no virtual methods, 
whereas COM objects will have at least 8.

However this doesn't seem needed.


Question 3. It seems I can inherit both from A D object and a 
COM interface. What will be the choosen layout?


Should not be a problem.
The problem I had was my inability to override a base class 
methods since I forgot extern(D). This problem is talked about in 
the spec: https://dlang.org/spec/interface.html#com-interfaces


How to use containers in lock based concurrency

2017-11-03 Thread ANtlord via Digitalmars-d-learn
Hello! I can't get how to use double linked list in concurrency. 
Please help.


Providing code


import std.stdio;
import std.container;


synchronized class SocksQueue {
private shared(DList!string) _queue;
public void f(string data) {
this._queue.insertFront(data);
}
}

void main(string[] args)
{
}

I get a compile error onlineapp.d(8): Error: template 
std.container.dlist.DList!string.DList.insertFront cannot deduce 
function from argument types !()(string) shared, candidates are:

/dlang/dmd/linux/bin64/../../src/phobos/std/container/dlist.d(441):
std.container.dlist.DList!string.DList.insertFront(Stuff)(Stuff stuff)

https://run.dlang.io/gist/3afff560fe3b2f439272c3ee3adcebd0?compiler=dmd


Re: private keyword dont appear to do anything

2017-11-03 Thread rikki cattermole via Digitalmars-d-learn
Visibility modifiers like private, and public are to the module not the 
scope.


"Symbols with private visibility can only be accessed from within the 
same module."


This is how module based languages work, a bit more useful then to the 
scope approach IMO. An easy mistake to make.


https://dlang.org/spec/attribute.html#visibility_attributes


private keyword dont appear to do anything

2017-11-03 Thread LunaticWare via Digitalmars-d-learn
hello, being new to D i assumed that the private keyword would 
work as in C++, but writing this code, i excepted it to throw an 
error at compile time, it appear to not doing anything, is there 
something i am doing wrong ?


--
import std.stdio;

class Foo
{
private int id = 10;
}

struct Bar
{
private int id = 20;
}

void main()
{
auto foo = new Foo;
Bar bar;

foo.id = 15;
bar.id = 25;

writeln(foo.id);
writeln(bar.id);
}

// RDMD OUTPUT
// 15
// 25



Re: COM/OLE advanced questions

2017-11-03 Thread Guillaume Piolat via Digitalmars-d-learn

On Friday, 3 November 2017 at 10:50:27 UTC, Kagamin wrote:


It only looks at the name.



I'll test if that name needs to be "IUnknown" or the exact 
"core.sys.windows.unknwn.IUnknown", since I'm in @nogc and not 
necessarily on Windows, so I can't inherit from 
core.sys.windows.unknwn.IUnknown (but still need a COM-like 
layout).





Re: COM/OLE advanced questions

2017-11-03 Thread Guillaume Piolat via Digitalmars-d-learn

On Friday, 3 November 2017 at 02:30:59 UTC, evilrat wrote:
You can't(or maybe you can but that is not a true COM). COM is 
Windows tech. It is backed up by OLE or whatever server it is.


What happens is that I translate a SDK which provides "COM-like" 
objects, on Windows and Mac (claiming ABI compatibility) and I'd 
like to know if I'll be able to use the COM facilities in D. No 
class will need registering.



My guess it will work fine when derive from any extern(Windows) 
interface(that's right, not class) that has base 3 
methods(AddRef, Release, QueryInterface)


I'll test that scenario and see if the layout is the same.


Re: COM/OLE advanced questions

2017-11-03 Thread Kagamin via Digitalmars-d-learn
On Thursday, 2 November 2017 at 14:22:56 UTC, Guillaume Piolat 
wrote:
Question 1. Is it mandatory to inherit from 
core.sys.windows.unknwn.IUnknown, or just having an interface 
named "IUnknown" validate it for being a COM interface?


   If yes, then how am I supposed to use COM interfaces in 
other OSes? core.sys.windows.unknwn.IUnknown is defined under 
version(Windows).


I suppose you will need a bunch of definitions. One strange thing 
is that core.sys.windows defines GUID with alignment 1, which I 
expect to differ on other platforms.



   I wonder what the exact compiler hook is.


I only looks at the name.

Question 2. If this fails, may I emulate COM vtable layout with 
extern(C++) class? I wonder what the exact differences are 
anyway between extern(C++) and the special IUnknown.


Depends on implementation. XPCOM uses straight C++ ABI on linux, 
so look what you want to work with.


Question 3. It seems I can inherit both from A D object and a 
COM interface. What will be the choosen layout?


Shouldn't matter, interface defines ABI, how it's implemented is 
irrelevant - that's the very idea behind COM. It's actually legal 
to implement interfaces with composition, the caller still 
doesn't see anything.