Re: D Binding to GUI libraries

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/22/18 1:08 AM, Gerald wrote:
On Monday, 22 October 2018 at 04:41:08 UTC, Nick Sabalausky (Abscissa) 
wrote:

On 10/21/18 1:13 PM, Russel Winder wrote:

[...]


First of all, minor nitpick: Unless some bombshell news occurred that 
I managed to miss, Ubuntu pushes their own Unity, NOT Gnome. Yes, 
that's still GTK, but still...accuracy...FWIW.


To be accurate, Ubuntu announced the dropping of Unity back in April 
2017. Current versions of Ubuntu use Gnome.


https://phoronix.com/scan.php?page=news_item&px=Ubuntu-Dropping-Unity


Wow! I really am out of the loop then. That is SERIOUSLY *MEGATON*-level 
announcement. I'm shocked that I missed it. I would never have even 
guessed. Thanks for the input!


Chalk me up as one who prefers Gnome over KDE. I like the clean UI that 
gnome provides and the adherence to a common HIG. KDE is way too fussy 
and busy for my taste. I also don't agree this is a minority viewpoint.


Like Russell though I'm glad there is choice and people can use what 
they prefer be it Gnome, KDE, Mate, Cinnamon, XFCE, i3 or whatever.


I would also be white happy to see D support Qt as well just to have 
more options.




Fair enough. For me, I find GTK/Gnome to be chunky (ex: problematic 
overuse of margins/padding) and Apple-level "zee must conform!" (ie: 
under-use of configuration). That, and an outright bad file-chooser ;)


But, it's possible I might agree with you if we were talking KDE's 
defaults - I don't actually use KDE's defaults. But that's kinda my 
point though: KDE is based around the philosophy of configurability, 
whereas Gnome (while admittedly does have a certain level of 
configurability) it very intentionally designed around a philosophy of 
conformity being superior to configurability.


But more importantly than anything else, it seems we all clearly agree: 
The key (and beauty) of Linux is "user's choice", not "GTK vs Qt".


Most distro maintainers want their distro to be as popular as possible. 
If KDE was a slam dunk like you imply they should be jumping over 
themselves to make it the default yet they do not. When Ubuntu dropped 
Unity they had a perfect opportunity to make KDE (or something else) the 
default yet they did not.


Personally, I think you're underestimating the group-think factor in 
modern software management. From a managerial perspective, there are a 
LOT of VERY STRONG motivations for promoting conformity over 
configurability. Not the least of which is "That's the way of 
Apple/Facebook/etc, and Apple/Facebook/etc are extremely 
popular/successful".


That, combined with both modern tech's current focus on "buzz" and 
"popularity", AND the practical software-dev-management benefits gained 
from disregarding the user as anything but collective commodity, creates 
a VERY potent motivator to prioritize similarly-minded projects over a 
purely population-driven decision.


Re: D Binding to GUI libraries

2018-10-21 Thread Neia Neutuladh via Digitalmars-d
On Mon, 22 Oct 2018 00:41:08 -0400, Nick Sabalausky (Abscissa) wrote:
> Ultimately, everything points to the same thing: Those who actually CARE
> about GTK/Gnome/Unity vs Qt/KDE, typically prefer Qt/KDE. The rest are
> just swing votes.

Unity 7 and prior for the desktop use Nux, an OpenGL-based widget toolkit. 
Unity 8 and all mobile versions of Unity use Qt. The application set that 
Ubuntu shipped with Unity was, I think, heavier on the GTK+ side.

I can't answer for "typical" users, but I've preferred GTK+ since 2005. Qt 
applications feel a bit off to me, and the standard themes were all 
weirdly bubbly. And while I've used probably a dozen window managers and 
at least four desktop environments, I've been on MATE for several years 
now.

> As for the distros choice of "which do we make default?", that's really
> no surprise and implies nothing significant: The tech industry's current
> runway-fashion wind direction is clearly "The user should adapt to the
> software", not the other way around. Thus fully explains GTK/GNOME/Unity
> as the gatekeepers' current suggestions. Just like Win/Mac: "Actual user
> opinions: not relevant."

RedHat provides a lot of support and development for GNOME. That makes it 
a relatively attractive option for other distros.


Re: D alternative for node.js's socket.IO?

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/21/18 11:59 PM, Neia Neutuladh wrote:

On Sun, 21 Oct 2018 23:05:06 -0400, Nick Sabalausky (Abscissa) wrote:

I'm afraid I'm not familiar with socket.io, and the homepage doesn't
seem to tell me much (it doesn't even say whether it uses TCP or UDP).
But that said, in D, the gold-standard for pretty much *anything*
related to networking and sockets is Vibe.D: http://vibed.org/


socket.io is a mix of XMLHttpRequest, websockets, and maybe long polling,
based on HTTP of course. It's all Javascript, designed for a browser as a
client and Node.js as a server.



Ahh, ok, I see. (Can't believe they couldn't have just said so on their 
currently-vapid homepage!) If that's the case, then Vibe.D's existing 
HTTP and TCP support is perfectly sufficient, and will probably also 
result in FAR simpler user code due to the lack of necessity for 
callbacks. At least on the server side, anyway. If the client side is 
inside a web browser, then just like ANY language that isn't JS, you'd 
still have have to (directly or indirectly) deal with the fact that 
JS/Webasm is really the ONLY Turing-complete code naively supported by 
modern browsers.


But, unless I'm being overly pessimistic (entirely possible), that does 
suggest a possible important area of improvement for libs such as Spasm: 
a simple no-brainer, common websockets-based API common to both client 
and vibe.d-based server.


Re: Need help with setting up LDC to cross-compile to Android/ARM

2018-10-21 Thread H. S. Teoh via Digitalmars-d
On Sat, Oct 20, 2018 at 09:51:28AM +, Joakim via Digitalmars-d wrote:
> On Friday, 19 October 2018 at 22:19:31 UTC, H. S. Teoh wrote:
[...]
> > Haha, I feel so silly now.  NDK r13b does not seem to have the
> > sysroot subdir required by the clang build command, that's why it
> > couldn't find the system headers.  So I ditched r13b and installed
> > r17b instead, and now I can build the runtime successfully!
> 
> Ah, that makes sense, that NDK is ancient, ;) it came out two years
> ago:
> 
> https://developer.android.com/ndk/downloads/revision_history

Well, it was what came with my distro, and I had just installed it
without much thought as to how recent it was or whether LDC would
support it.


> Official D support for Android was added to ldc 1.4 last September,
> which was after NDK r15c came out, when they switched to that sysroot
> directory with unified headers for all Android versions, so that's
> what ldc uses.  Before that, each Android version had its headers in a
> separate directory, which isn't supported by LDC.

Thanks for the info, updated the wiki page.


[...]
> > On a side note, the last section on that page mentions not knowing
> > how to create a keystore from scratch; actually, it's very simple
> > with the `keytool` utility that comes with the Oracle JRE.  I added
> > the steps on the talk page.  The only thing I'm unsure about is
> > whether keytool is available natively on Android.  If not, then
> > you'll have to generate the keystore on a PC and copy it over to
> > Android afterwards.
> 
> From scratch meaning without using keytool, ie OpenSSL or some other
> hashing/fingerprinting tool alone, because keytool isn't available in
> the Termux app. As mentioned at the end of the wiki page, I used to
> manually edit the apk hashed manifests using OpenSSL alone until that
> apksigner tool was added later.

I see.  Anyway, if openssl works then IMO it's so much the better than
the walled garden that is keytool / Java keystore.


T

-- 
Creativity is not an excuse for sloppiness.


Re: D Binding to GUI libraries

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/21/18 1:29 PM, Russel Winder wrote:

No, D should not forget DWT. It's one of the few (they only?) D GUI
toolkit that has a native look and feel.

Apart from GtkD on GTK+ systems, and dqml, QtE5, qtD, and dqt on Qt,
and wxD on wxWidgets. Qt and wxWidgets pride themselves on being able
to use native frameworks underneath – I have no personal evidence as I
only use GNOME, I am not a good data point.


Qt is well-known for going to great lengths, and achieving at least a 
certain degree of success, to have a native look-n-feel. (Regardless of 
how well they may or may not have succeeded compared to wx). It is a 
key, deliberate goal for Qt.


GTK, OTOH, is famous for its outright CONTEMPT for native look-n-feel.

It's even true just on Linux itself: Qt makes attempts to fit in on 
Gnome/Unity. Gtk not only doesn't, but also unapologetically killed off 
the most popular and widespread Qt/KDE-compatability module in *a mere 
POINT RELEASE*. And then they proceeded to rationalize it. And not one 
of them ever did move one muscle to rectify it, or even acknowledge any 
possibility of making a questionable move. (And don't even get me 
started on the multi-decade clusterfuck that is the GTK file-chooser.)


Qt makes effort for native look-n-feel.

GTK is INFAMOUS for having outright CONTEMPT for native look-n-feel.

There is NO comparison, whatsoever.


Re: D Binding to GUI libraries

2018-10-21 Thread Gerald via Digitalmars-d
On Monday, 22 October 2018 at 04:41:08 UTC, Nick Sabalausky 
(Abscissa) wrote:

On 10/21/18 1:13 PM, Russel Winder wrote:

[...]


First of all, minor nitpick: Unless some bombshell news 
occurred that I managed to miss, Ubuntu pushes their own Unity, 
NOT Gnome. Yes, that's still GTK, but still...accuracy...FWIW.


To be accurate, Ubuntu announced the dropping of Unity back in 
April 2017. Current versions of Ubuntu use Gnome.


https://phoronix.com/scan.php?page=news_item&px=Ubuntu-Dropping-Unity



But more importantly, "prefer" is vague a weasel word in this 
situation. The claim is that the distros "prefer" GTK over Qt. 
The *reality* is far more simple: The installers for the 
distros give you a choice between Gnome, KDE and (on Ubuntu) 
Unity, and Gnome/Unity just happen to often be the default. 
That's the *only* thing that "prefer" means in this context, so 
let's call a spade a spade: It's a common installer default. 
That's all.


Furthermore, regardless of what distro you've installed, KDE 
can always be installed and used. And (unless things have 
changes since last I looked) every single one of the distros 
you mention maintain the full set of KDE packages in their 
repositories.


So yes, saying that GTK "won" over Qt is hyperbolic nonsense. 
Does it have a slight dominance WRT Linux DE's? Yes. 
Unfortunately. But that's like claiming a victor between iOS 
and Android: BOTH still have significant user-bases. BOTH are 
still actively developed with no end even remotely in sight. 
BOTH are still relevant and will remain so for the foreseeable 
future. So long as they both coexist (and the GNU/Linux 
ecosystem actively promotes coexistence of competitors - which 
it does), any claim of a victor, or of one competitor "winning" 
over another, IS, yes, hyperbolic nonsense.


Plus, as others have said, industry tends to take Qt more 
seriously than GTK anyway. So once again, hyperbolic nonsense 
to claim GTK "won".



[...]


I believe this is pretty much exactly my own point, too ;) Ie, 
regardless of the Win/Mac crowds unfortunate misconceptions, 
Linux is about choice, not about one option "winning" over 
another. Thus, for one competitor to defeat another in Linux, 
the loser would have to either cease to exist, or become 
extremely marginalized. Note that "extremely marginalized" is a 
far, far stronger notion than "not majority" or "not the 
default of the options given by the installer".



[...]


Ditto for Qt. Which again, is a key part of my point.

But that said, out of all the people I've come across who use a 
GTK-based DE (ie, Gnome or Unity), very few of them, if any, do 
so because they like GTK apps better than Qt apps (Or the 
GTK-file chooser over the Qt file-chooser ;)). The vast 
majority of the time, it's simply because they *don't object* 
to Gnome/Unity and merely go along with it - *not* because they 
consider it superior to KDE, nor because they prefer GTK apps 
to Qt apps.


Chalk me up as one who prefers Gnome over KDE. I like the clean 
UI that gnome provides and the adherence to a common HIG. KDE is 
way too fussy and busy for my taste. I also don't agree this is a 
minority viewpoint.


Like Russell though I'm glad there is choice and people can use 
what they prefer be it Gnome, KDE, Mate, Cinnamon, XFCE, i3 or 
whatever.


I would also be white happy to see D support Qt as well just to 
have more options.


For that matter, out of those people I've come across who DO 
have a significant preference regarding "GTK app" vs "Qt app", 
the vast majority of people who actually care are on the "Qt 
UI" side. Out of the minority who prefer GTK apps, the majority 
are GTK or Gnome developers themselves. (BTW, Note, in ALL of 
this, I'm referring to GTK/Qt UI, not GTK/Qt API. Just to 
clarify.) On top of that, it's no secret that GNOME 3 triggered 
an exodus of GNOME developers, and for very well-known reasons. 
But there's no such equivalent for KDE.
I have no doubt there *are* people out there who do consider 
GTK/Gnome/Unity superior to KDE/Qt, and Ihave no intention to 
claim that they are "wrong". But in my experience, such people 
account for a vast *minority* of GTK/Gnome/Unity users.


Not in my experience.

Ultimately, everything points to the same thing: Those who 
actually CARE about GTK/Gnome/Unity vs Qt/KDE, typically prefer 
Qt/KDE. The rest are just swing votes.


As for the distros choice of "which do we make default?", 
that's really no surprise and implies nothing significant: The 
tech industry's current runway-fashion wind direction is 
clearly "The user should adapt to the software", not the other 
way around. Thus fully explains GTK/GNOME/Unity as the 
gatekeepers' current suggestions. Just like Win/Mac: "Actual 
user opinions: not relevant."


Most distro maintainers want their distro to be as popular as 
possible. If KDE was a slam dunk like you imply they should be 
jumping over themselves to make it the default yet they do not. 
When Ubuntu dropped U

Re: D Binding to GUI libraries

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/21/18 1:13 PM, Russel Winder wrote:

On Sun, 2018-10-21 at 04:15 -0400, Nick Sabalausky (Abscissa) via
Digitalmars-d wrote:

[…]

That's pure nonsense: It's Linux - unless one option actually goes
away
(KDE is still actively used and developed), then there's no such
thing
as one "winning" over the other.


Hardly nonsense. Debian, Ubuntu, Fedora all prefer GNOME over KDE, so
GTK+ over Qt.


First of all, minor nitpick: Unless some bombshell news occurred that I 
managed to miss, Ubuntu pushes their own Unity, NOT Gnome. Yes, that's 
still GTK, but still...accuracy...FWIW.


But more importantly, "prefer" is vague a weasel word in this situation. 
The claim is that the distros "prefer" GTK over Qt. The *reality* is far 
more simple: The installers for the distros give you a choice between 
Gnome, KDE and (on Ubuntu) Unity, and Gnome/Unity just happen to often 
be the default. That's the *only* thing that "prefer" means in this 
context, so let's call a spade a spade: It's a common installer default. 
That's all.


Furthermore, regardless of what distro you've installed, KDE can always 
be installed and used. And (unless things have changes since last I 
looked) every single one of the distros you mention maintain the full 
set of KDE packages in their repositories.


So yes, saying that GTK "won" over Qt is hyperbolic nonsense. Does it 
have a slight dominance WRT Linux DE's? Yes. Unfortunately. But that's 
like claiming a victor between iOS and Android: BOTH still have 
significant user-bases. BOTH are still actively developed with no end 
even remotely in sight. BOTH are still relevant and will remain so for 
the foreseeable future. So long as they both coexist (and the GNU/Linux 
ecosystem actively promotes coexistence of competitors - which it does), 
any claim of a victor, or of one competitor "winning" over another, IS, 
yes, hyperbolic nonsense.


Plus, as others have said, industry tends to take Qt more seriously than 
GTK anyway. So once again, hyperbolic nonsense to claim GTK "won".




People coming from Windows or macOS are genreally unaware of the notion
of choice when it comes to UI. That Linux provides a choice is clearly
alien to them. That I have chosen GNOME over KDE is a personal choice,
but I like having the choice: I like that others can choose KDE or
Cinnamon or whatever.



I believe this is pretty much exactly my own point, too ;) Ie, 
regardless of the Win/Mac crowds unfortunate misconceptions, Linux is 
about choice, not about one option "winning" over another. Thus, for one 
competitor to defeat another in Linux, the loser would have to either 
cease to exist, or become extremely marginalized. Note that "extremely 
marginalized" is a far, far stronger notion than "not majority" or "not 
the default of the options given by the installer".



[…]

Programmers writing GUI apps often like GTK. Nobody else does. From
a
programmer standpoint, it may very well be nice. But that's
irrelevant,
because from the user standpoint, GTK is, and has always been, a
steaming pool of diarrhea, even if you ARE using GNOME/Unity.


GTK+ is fine and dandy. That you do not like it is your choice, and
that is fine.



Ditto for Qt. Which again, is a key part of my point.

But that said, out of all the people I've come across who use a 
GTK-based DE (ie, Gnome or Unity), very few of them, if any, do so 
because they like GTK apps better than Qt apps (Or the GTK-file chooser 
over the Qt file-chooser ;)). The vast majority of the time, it's simply 
because they *don't object* to Gnome/Unity and merely go along with it - 
*not* because they consider it superior to KDE, nor because they prefer 
GTK apps to Qt apps.


For that matter, out of those people I've come across who DO have a 
significant preference regarding "GTK app" vs "Qt app", the vast 
majority of people who actually care are on the "Qt UI" side. Out of the 
minority who prefer GTK apps, the majority are GTK or Gnome developers 
themselves. (BTW, Note, in ALL of this, I'm referring to GTK/Qt UI, not 
GTK/Qt API. Just to clarify.) On top of that, it's no secret that GNOME 
3 triggered an exodus of GNOME developers, and for very well-known 
reasons. But there's no such equivalent for KDE.


I have no doubt there *are* people out there who do consider 
GTK/Gnome/Unity superior to KDE/Qt, and Ihave no intention to claim that 
they are "wrong". But in my experience, such people account for a vast 
*minority* of GTK/Gnome/Unity users.


Ultimately, everything points to the same thing: Those who actually CARE 
about GTK/Gnome/Unity vs Qt/KDE, typically prefer Qt/KDE. The rest are 
just swing votes.


As for the distros choice of "which do we make default?", that's really 
no surprise and implies nothing significant: The tech industry's current 
runway-fashion wind direction is clearly "The user should adapt to the 
software", not the other way around. Thus fully explains GTK/GNOME/Unity 
as the gatekeepers' current suggestions. Just like Win/Ma

Re: D alternative for node.js's socket.IO?

2018-10-21 Thread Neia Neutuladh via Digitalmars-d
On Sun, 21 Oct 2018 23:05:06 -0400, Nick Sabalausky (Abscissa) wrote:
> I'm afraid I'm not familiar with socket.io, and the homepage doesn't
> seem to tell me much (it doesn't even say whether it uses TCP or UDP).
> But that said, in D, the gold-standard for pretty much *anything*
> related to networking and sockets is Vibe.D: http://vibed.org/

socket.io is a mix of XMLHttpRequest, websockets, and maybe long polling, 
based on HTTP of course. It's all Javascript, designed for a browser as a 
client and Node.js as a server.

When socket.io was first created, websockets were *relatively* new, and a 
lot of Windows/IE users were still on IE8/9, so it probably made a fair 
bit of sense to use a tool that could provide okay-ish support for all 
browsers and better support for newer browsers. But there's little reason 
to use it today.

The docs leave much to be desired.

> For a realtime multiplayer games though, that's notoriously a whole
> different can of worms. For that, you definitely do need UDP (which
> again, Vibe.D supports). But, UDP being what it is, you'd still need to
> design your program to handle UDP's inherently unguaranteed nature.
> Vibe.D doesn't have a gaming-oriented networking system built on top of
> UDP.

And since the person's probably communicating between browser clients, 
WebRTC is likely the most practical target there.

https://github.com/koldi/webrtc-dlang


Re: D Binding to GUI libraries [was Interesting Observation from JAXLondon]

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/21/18 7:36 AM, Andre Pany wrote:


While talking about bindings, do not forget Delphi. It has still a good 
eco system. Combining Delphi's advanced Runtime reflection capabilities 
with D's advanced compile reflection capabilities opens this eco system.


I created a proof of concept and the results were really promising. 
Using Delphi components is very easy and the wrapper code on D side is 
very thin.


Even clicking together a Firemonkey ui in Delphi and writing all code in 
D works fine.


Delphi is available for windows,  Mac os,  Android and IPhone. Linux 
support is somehow planned. It is free for personal use.


See an example here 
https://github.com/andre2007/delta-fmx-10-2-1/blob/master/examples/gui1/source/app.d 



Due to very limited time resources I have no time to work on this 
specific topic at the moment but everyone is free to use these base 
research results.


Side remark: Lazarus (free pascal) is planning to add the same advanced 
Runtime reflection capabilities as Delphi.




Interesting, thanks for the info. I'm somewhat ashamed to say I didn't 
know Delphi was still around!


For those younger programmers out there, Delphi is a Pascal-based system 
that was key in popularizing what we used to call "RAD" tools ("Rapid 
Application Development") such as Visual Basic, and the modern 
GUI-builder tools they've evolved (or devolved?) into.


I have to admit, I've somehow managed to write code all the way from the 
late 1980's through today without ever learning or writing any Pascal. 
But I do know Delphi was very respectable back in the day (with a 
somewhat Basic-like, but more capable, syntax), so it's nice to know 
it's still around and even supports modern mobile, which is really kinda 
cool.


Re: D alternative for node.js's socket.IO?

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/21/18 4:58 PM, Fleel wrote:

On Sunday, 21 October 2018 at 20:41:41 UTC, JN wrote:

On Sunday, 21 October 2018 at 20:14:46 UTC, Fleel wrote:
Does anyone know of a good D alternative for the socket.IO server 
(https://socket.io)? I would like to transition my server from 
node.js to D, but I can't find any D equivalents to socket.IO. (I've 
seen http://socket.io.dub.pm, but it is dead). Are there any good D 
libraries that can do the same thing as socket.IO? Thanks!


I'm afraid I'm not familiar with socket.io, and the homepage doesn't 
seem to tell me much (it doesn't even say whether it uses TCP or UDP). 
But that said, in D, the gold-standard for pretty much *anything* 
related to networking and sockets is Vibe.D: http://vibed.org/


If the network/socket functionality you're looking for exists in D, then 
it's probably in either the standard library or in Vibe.D. If what 
you're looking for doesn't exist, then it can certainly be built on top 
of Vibe.D.




Can std.socket provide a realtime connection between the client(web 
browser) and the server, like for a chatroom or realtime multiplayer game?


For something like a chatroom, and the vast majority of any networking 
you'd want to do, Vibe.D definitely can. Plain old ordinary TCP is 
perfectly sufficient for something like chatrooms, and Vibe.D supports 
TCP clients/servers very well. For other things, Vibe.D had equally good 
support for UDP. So that alone makes Vibe.D universally useful, plus the 
way its job system works gives you all the benefits of async networking 
code without having to deal with the mess of callback-oriented programming.


For a realtime multiplayer games though, that's notoriously a whole 
different can of worms. For that, you definitely do need UDP (which 
again, Vibe.D supports). But, UDP being what it is, you'd still need to 
design your program to handle UDP's inherently unguaranteed nature. 
Vibe.D doesn't have a gaming-oriented networking system built on top of UDP.


You could also look into ZeroMQ: https://code.dlang.org/packages/zeromq 
I haven't used ZeroMQ myself though, so no promises about how well it 
works, but it may be worth looking into.


Re: D T-Shirts

2018-10-21 Thread Mike Parker via Digitalmars-d

On Monday, 22 October 2018 at 01:08:11 UTC, Manu wrote:

FWIW, I'm disappointed with the quality of my dman shirt; I've 
put it
through the wash no more than 3-4 times and the print is 
aggressively

deteriorating with each wash.
I don't tend to wear it because it's disintegrating so fast. 
I'm just
kinda keeping it for dconf or something. I'd like it if I could 
wear

it regularly.
I don't have any other shirts exhibiting this effect. The shirt 
itself
feels high quality, but the print is not. I suggest changing 
t-shirt

vendor.


That's the first feedback I've received on it, thanks. I'll look 
into it.




Re: We need an internal keyword.

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/20/18 11:17 PM, 12345swordy wrote:
So that classes can share some of their variables but not others in a 
module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


I've always felt the same.

I certainly don't intend this as a way to say "just accept it and forget 
about it", but FWIW, I've learned to live with it: I just regard 
accessing such privates from outside their class/struct to be bad style. 
I mean, I agree it's not ideal, but at least it doesn't prevent me from 
getting things done. Again, FWIW.


That said though, it *can* sometimes be helpful for tests and debugging 
to be able to reach into a class/struct and muck about with the 
privates. (tee hee). But FWIW, I do agree. If D were my own language, 
I'd probably have done it a little differently: I would've taken the 
current "private" behavior and called it something like "module", and 
made "private" behave the way it does in other languages.




Re: shared - i need it to be useful

2018-10-21 Thread Joakim via Digitalmars-d

On Monday, 22 October 2018 at 00:22:19 UTC, Manu wrote:
On Sun, Oct 21, 2018 at 2:35 PM Walter Bright via Digitalmars-d 
 wrote:


On 10/21/2018 2:08 PM, Walter Bright wrote:
> On 10/21/2018 12:20 PM, Nicholas Wilson wrote:
>> Yes, but the problem you describe is arises from implicit 
>> conversion in the other direction, which is not part of the 
>> proposal.

>
> It's Manu's example.

Then I don't know what the proposal is. Pieces of it appear to 
be scattered over numerous posts, mixed in with other text,


No no, they're repeated, not scattered, because I seem to have 
to keep repeating it over and over, because nobody is reading 
the text, or perhaps imaging there is a lot more text than 
there is.


I told you this is what happens with forum posts 4 days ago, yet 
you didn't listen:


https://forum.dlang.org/post/fokdcnzircoiuhrhz...@forum.dlang.org


opinions, and handwavy stuff.


You mean like every post in opposition which disregards the 
rules and baselessly asserts it's a terrible idea? :/



There's nothing to point to that is "the proposal".


You can go back to the OP, not a single detail is changed at 
any point, but I've repeated it a whole bunch of times 
(including in direct response to your last post) and the 
summary has become more concise, but not different.


1. Shared has no read or write access to data
2. Functions with shared arguments are threadsafe with respect 
to

those arguments
  a. This is a commitment that must be true in _absolute terms_ 
(there
exists discussion about the ways that neighbours must not 
undermine

this promise)
  b. There are numerous examples demonstrating how to configure 
this
(TL;DR: use encapsulation, and @trusted at the bottom of the 
stack)


If you can find a legitimate example where those rules don't 
hold, I

want to see it.
But every example so far has been based on a faulty premise 
where

those 2 simple rules were not actually applied.


Put it all together in a 2-3 page proposal elsewhere, so he 
doesn't have to hunt everything out in a blizzard of forum posts.


I responded to your faulty program directly with the correct 
program, and you haven't acknowledged it. Did you see it?


I suggest you and Manu write up a proper proposal. Something 
that is complete, has nothing else in it, has a rationale, 
illuminating examples, and explains why alternatives are 
inferior.


I have written this program a couple of times, including in 
direct

response to your last sample program.
You seem to have dismissed it... where is your response to that
program, or my last entire post?


For examples of how to do it:

https://github.com/dlang/DIPs/tree/master/DIPs

Trying to rewrite the semantics of shared is not a simple 
task, doing multithreading correctly is a minefield of "OOPS! 
I didn't think of that!" and if anything cries out for a DIP, 
your and Manu's proposal does.


Yes, I agree it's DIP worthy. But given the almost nothing but 
overt

hostility I've received here, why on earth would I waste my time
writing a DIP?
I put months into my other DIP which sits gathering dust... if 
this
thread inspired any confidence that it would be well-received I 
would
make the effort, but the critical reception we've seen here 
is... a

bit strange.
It's a 2-point proposal, the rules are **SO SIMPLE**, which is 
why I
love it. How it can be misunderstood is something I'm having 
trouble
understanding, and I don't know how to make it any clearer than 
I
already have; numerous times over, including in my last reply 
to you,

which you have ignored and dismissed it seems.

Please go back and read my response to your last program.


He did not say to write a full DIP, just a proposal, so he knows 
exactly what you mean, just as I said. It will require a DIP 
eventually, but he didn't ask you to write one now.


Re: shared - i need it to be useful

2018-10-21 Thread Neia Neutuladh via Digitalmars-d
On Sun, 21 Oct 2018 17:35:38 -0700, Manu wrote:

> On Sun, Oct 21, 2018 at 3:15 PM Neia Neutuladh via Digitalmars-d
>  wrote:
>> If we only used your proposal and only used @safe code, we wouldn't
>> have any data races, but that's only because we wouldn't have any
>> shared data. We'd have shared *variables*, but they would not contain
>> any data we could read or alter, and that's pretty much useless.
> 
> I've shown an implementation of Atomic(T) 3 times now... no response any
> time. Why is it being dismissed? Do I need to write it more times?
> This is a clear demonstration of how to build the foundation of the
> @safe threadsafe stack.

Yes, Atomic can be implemented here as @trusted code, and maybe using 
@safe compiler intrinsics for some situations. That's useful! But it's not 
*enough*.

It would require a lot of work to refit existing code to using only atomic 
operations, and it would end up looking rather clunky a lot of the time. 
If you're doing anything complex with a complex object graph, you're going 
to have a terrible time. You need to copy that object graph (atomically), 
which is going to be expensive and provides non-trivial restrictions on 
what you can store.

So I'm not keen on a world in which all multithreading is using atomic 
structs.

Unless, when you were talking about Atomic, you actually meant a wrapper 
containing some sort of lock, allowing you to submit arbitrary delegates 
to mutate the data within in a serialized way, similar to Atila Neves's 
fearless library. Which really stretches the definition of "atomic".

>> Currently, it helps because casting unshared to shared is not @safe,
>> because it makes it trivial to get multiple threads with unshared
>> references to the same data.
> 
> No no, that's a massive smell. That means anytime anyone wants to
> distribute something, they need to perform unsafe casts. That's not
> okay.

Casting thread-local to shared makes it easy to cause errors, and that's 
why it's a massive smell. Making it silent doesn't eliminate the smell.

> 100% of my SMP code works with my proposal, and something close to 0%
> works with shared as it is today. (assuming we desire @safe interaction,
> which we do, because threading is hard enough already!)

You want un-shared things to implicitly cast to shared. You don't want to 
have to allocate anything as shared, and you do want to pass absolutely 
anything to any thread.

You can write a @trusted assumeShared function, analogous to assumeUnique, 
to accomplish that. It would be slightly more awkward than what you're 
proposing, but it accomplishes one of your two goals: convert non-shared 
things to shared things in @safe code.

The other goal in your proposal is for some code that currently compiles 
not to. So you should be able to write the code you want, albeit with an 
increased risk of bugs. Or you could write a template that wraps a shared 
thing and forbids field access and assignment.

>> And that's when you're using shared as expected rather than doing
>> something weird.
> 
> No, I *expect* to use shared in @safe code, and not write any unsafe
> code ever. shared doesn't model a useful interaction now, not in any
> way.
> 
> Today, access to shared data members are unrestricted and completely
> unsafe

Yes, and that's bad and should be changed.

> passing data into something like a parallel-for requires unsafe
> casts.

Or allocating data as shared, which is the recommended way, because that 
makes absolutely certain that, from the start, no code has an un-shared 
copy of that data. No casts needed.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Monday, 22 October 2018 at 00:55:00 UTC, Timon Gehr wrote:

On 22.10.18 02:46, Nicholas Wilson wrote:

On Monday, 22 October 2018 at 00:38:33 UTC, Timon Gehr wrote:

I just did,


Link please?



https://forum.dlang.org/post/pqii8k$11u3$1...@digitalmars.com


That contains no code.

Not all of the parties that participate in the data race are in 
@trusted code.


There are two cases of @trusted code, bad and good. Bad trusted 
code can indeed be misused by @safe code to corrupt memory. Good 
trusted code cannot.


What part of the proposal breaks the type system? The implicit 
conversion to shared implies that the passed to function is @safe 
iff all the functions it calls are @safe only call function with 
that parameter to other shared @safe functions _OR_ they are 
@trusted.


The point of @trusted is modularity: you manually check 
@trusted code according to some set of restrictions and then 
you are sure that there is no memory corruption.


Yes. And?


Re: D T-Shirts

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 5:35 PM Mike Parker via Digitalmars-d
 wrote:
>
> On Sunday, 21 October 2018 at 20:04:02 UTC, Fleel wrote:
> > It would be awesome if there were T-Shirts with D-man on them.
> > I would totally buy one, and would help to support the
> > foundation too...
>
> We've got a store coming, with t-shirts and other items. D-man
> shirts will not be there, though. That's what we're using for our
> donor t-shirts:
>
> https://opencollective.com/dlang

FWIW, I'm disappointed with the quality of my dman shirt; I've put it
through the wash no more than 3-4 times and the print is aggressively
deteriorating with each wash.
I don't tend to wear it because it's disintegrating so fast. I'm just
kinda keeping it for dconf or something. I'd like it if I could wear
it regularly.
I don't have any other shirts exhibiting this effect. The shirt itself
feels high quality, but the print is not. I suggest changing t-shirt
vendor.


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 5:55 PM Timon Gehr via Digitalmars-d
 wrote:
>
> On 22.10.18 02:45, Manu wrote:
> > On Sun, Oct 21, 2018 at 5:35 PM Timon Gehr via Digitalmars-d
> >  wrote:
> >>
> >> On 21.10.18 20:46, Manu wrote:
>  Shared data is only useful if, at some point, it is read/written, 
>  presumably by
>  casting it to unshared in @trusted code. As soon as that is done, you've 
>  got a
>  data race with the other existing unshared aliases.
> >>> If such a race is possible, then the @trusted function is not
> >>> threadsafe, so it is not @trusted by definition.
> >>> You wrote a bad @trusted function, and you should feel bad.
> >>> ...
> >>
> >> I wonder where this "each piece of code is maintained by only one person
> >> and furthermore this is the only person that will suffer if the code has
> >> bugs" mentality comes from. It is very popular as well as obviously
> >> nonsense.
> >>
> >>> The simplest way to guarantee that no unsafe access is possible is to
> >>> use encapsulation to assure no unregulated access exists.
> >>
> >> This only works if untrusted programmers (i.e. programmers who are only
> >> allowed to write/modify @safe code) are not allowed to change your
> >> class. I.e. it does not work.
> >
> > Have you ever cracked open std::map and 'fixed' it because you thought
> > it was bad?
> > Of course not. Same applies here. Nobody 'fixes' core.atomic.Atomic
> > without understanding what they're doing.
> >
>
> You are not proposing to let core.atomic.Atomic convert to shared
> implicitly, you are proposing to do that for all classes.

You can always implicitly convert to shared.
Where did I ever say anything like that? I'm sure I've never said
this. How do these transformations of what I've said keep happening?

> > You seem to be stuck on the detail whether you can trust the @trusted
> > author though...
>
> Again: the @safe author is the problem.

I don't follow. The @safe author is incapable of doing threadsafety
violation. They can only combine threadsafe functions.
They can certainly produce a program that doesn't work, and they are
capable of ordering issues, but that's not the same as data-race
related crash bugs.


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 5:40 PM Timon Gehr via Digitalmars-d
 wrote:
>
> On 21.10.18 21:04, Manu wrote:
> > On Sun, Oct 21, 2018 at 12:00 PM Timon Gehr via Digitalmars-d
> >  wrote:
> >>
> >> On 21.10.18 17:54, Nicholas Wilson wrote:
> >>>
>  As soon as that is done, you've got a data race with the other
>  existing unshared aliases.
> >>>
> >>> You're in @trusted code, that is the whole point. The onus is on the
> >>> programmer to make that correct, same with regular @safe/@trusted@system
> >>> code.
> >>
> >> Not all of the parties that participate in the data race are in @trusted
> >> code. The point of @trusted is modularity: you manually check @trusted
> >> code according to some set of restrictions and then you are sure that
> >> there is no memory corruption.
> >>
> >> Note that you are not allowed to look at any of the @safe code while
> >> checking your @trusted code. You will only see an opaque interface to
> >> the @safe code that you call and all you know is that all the @safe code
> >> type checks according to @safe rules. Note that there might be an
> >> arbitrary number of @safe functions and methods that you do not see.
> >>
> >> Think about it this way: you first write all the @trusted and @system
> >> code, and some evil guy who does not like you comes in after you looks
> >> at your code and writes all the @safe code. If there is any memory
> >> corruption, it will be your fault and you will face harsh consequences.
> >> Now, design the @safe type checking rules. It won't be MP!
> >>
> >> Note that there may well be a good way to get the good properties of MP
> >> without breaking the type system, but MP itself is not good because it
> >> breaks @safe.
> >
> > Show me. Nobody has been able to show that yet. I'd really like to know 
> > this.
> >
>
> I just did,

There's no code there... just a presumption that the person who wrote
the @trusted code did not deliver the promise they made.

> but if you really need to, give me a non-trivial piece of> correct 
> multithreaded code that accesses some declared-unshared field
> from a shared method and I will show you how the evil guy would modify
> some @safe code in it and introduce race conditions. It needs to be your
> code, as otherwise you will just claim again that it is me who wrote bad
> @trusted code.

You can pick on any of my prior code fragments. They've all been ignored so far.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Monday, 22 October 2018 at 00:46:04 UTC, Walter Bright wrote:
That's what I was referring to, and Manu's example. It doesn't 
work, as I pointed out.


I'm pretty sure it does, but please repeat it.

We will eventually. This started as a "please point out any 
problems with this" and has probably outlived that phase.


You'll need to address the issues raised here in the DIP.


That is a given. You would do well to heed it for your own DIPs.


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 5:50 PM Walter Bright via Digitalmars-d
 wrote:
>
> On 10/21/2018 4:12 PM, Nicholas Wilson wrote:
> > On Sunday, 21 October 2018 at 21:32:14 UTC, Walter Bright wrote:
> >> On 10/21/2018 2:08 PM, Walter Bright wrote:
> >>> On 10/21/2018 12:20 PM, Nicholas Wilson wrote:
>  Yes, but the problem you describe is arises from implicit conversion in 
>  the
>  other direction, which is not part of the proposal.
> >>>
> >>> It's Manu's example.
> >>
> >> Then I don't know what the proposal is. Pieces of it appear to be scattered
> >> over numerous posts, mixed in with other text, opinions, and handwavy 
> >> stuff.
> >> There's nothing to point to that is "the proposal".
> >
> > The proposal is:
> >
> > Implicit conversion _to_ shared, e.g. passing it to a thread entry point, 
> > and
> > not implicit conversion _from_ shared (just like implicit const 
> > conversions).
>
> That's what I was referring to, and Manu's example. It doesn't work, as I
> pointed out.
>
>
> >> I suggest you and Manu write up a proper proposal. Something that is 
> >> complete,
> >> has nothing else in it, has a rationale, illuminating examples, and 
> >> explains
> >> why alternatives are inferior.
> >
> > We will eventually. This started as a "please point out any problems with 
> > this"
> > and has probably outlived that phase.
>
> You'll need to address the issues raised here in the DIP.

Would you please respond to my messages, and specifically, respond to
the code that I presented to you in response to your broken example.
Or any of my earlier fragments throughout this thread. I've shared
quite a few, and so far, nobody has ever produced a criticism of any
of my fragments. They've just been skipped over.
But the one aimed directly at your own most recent sample program
addresses your program directly.


Re: shared - i need it to be useful

2018-10-21 Thread Timon Gehr via Digitalmars-d

On 22.10.18 02:46, Nicholas Wilson wrote:

On Monday, 22 October 2018 at 00:38:33 UTC, Timon Gehr wrote:

I just did,


Link please?



https://forum.dlang.org/post/pqii8k$11u3$1...@digitalmars.com


Re: shared - i need it to be useful

2018-10-21 Thread Timon Gehr via Digitalmars-d

On 22.10.18 02:45, Manu wrote:

On Sun, Oct 21, 2018 at 5:35 PM Timon Gehr via Digitalmars-d
 wrote:


On 21.10.18 20:46, Manu wrote:

Shared data is only useful if, at some point, it is read/written, presumably by
casting it to unshared in @trusted code. As soon as that is done, you've got a
data race with the other existing unshared aliases.

If such a race is possible, then the @trusted function is not
threadsafe, so it is not @trusted by definition.
You wrote a bad @trusted function, and you should feel bad.
...


I wonder where this "each piece of code is maintained by only one person
and furthermore this is the only person that will suffer if the code has
bugs" mentality comes from. It is very popular as well as obviously
nonsense.


The simplest way to guarantee that no unsafe access is possible is to
use encapsulation to assure no unregulated access exists.


This only works if untrusted programmers (i.e. programmers who are only
allowed to write/modify @safe code) are not allowed to change your
class. I.e. it does not work.


Have you ever cracked open std::map and 'fixed' it because you thought
it was bad?
Of course not. Same applies here. Nobody 'fixes' core.atomic.Atomic
without understanding what they're doing.



You are not proposing to let core.atomic.Atomic convert to shared 
implicitly, you are proposing to do that for all classes.



You seem to be stuck on the detail whether you can trust the @trusted
author though...


Again: the @safe author is the problem.



Re: shared - i need it to be useful

2018-10-21 Thread Walter Bright via Digitalmars-d

On 10/21/2018 4:12 PM, Nicholas Wilson wrote:

On Sunday, 21 October 2018 at 21:32:14 UTC, Walter Bright wrote:

On 10/21/2018 2:08 PM, Walter Bright wrote:

On 10/21/2018 12:20 PM, Nicholas Wilson wrote:
Yes, but the problem you describe is arises from implicit conversion in the 
other direction, which is not part of the proposal.


It's Manu's example.


Then I don't know what the proposal is. Pieces of it appear to be scattered 
over numerous posts, mixed in with other text, opinions, and handwavy stuff. 
There's nothing to point to that is "the proposal".


The proposal is:

Implicit conversion _to_ shared, e.g. passing it to a thread entry point, and 
not implicit conversion _from_ shared (just like implicit const conversions).


That's what I was referring to, and Manu's example. It doesn't work, as I 
pointed out.



I suggest you and Manu write up a proper proposal. Something that is complete, 
has nothing else in it, has a rationale, illuminating examples, and explains 
why alternatives are inferior.


We will eventually. This started as a "please point out any problems with this" 
and has probably outlived that phase.


You'll need to address the issues raised here in the DIP.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Monday, 22 October 2018 at 00:38:33 UTC, Timon Gehr wrote:

I just did,


Link please?



Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 5:35 PM Timon Gehr via Digitalmars-d
 wrote:
>
> On 21.10.18 20:46, Manu wrote:
> >> Shared data is only useful if, at some point, it is read/written, 
> >> presumably by
> >> casting it to unshared in @trusted code. As soon as that is done, you've 
> >> got a
> >> data race with the other existing unshared aliases.
> > If such a race is possible, then the @trusted function is not
> > threadsafe, so it is not @trusted by definition.
> > You wrote a bad @trusted function, and you should feel bad.
> > ...
>
> I wonder where this "each piece of code is maintained by only one person
> and furthermore this is the only person that will suffer if the code has
> bugs" mentality comes from. It is very popular as well as obviously
> nonsense.
>
> > The simplest way to guarantee that no unsafe access is possible is to
> > use encapsulation to assure no unregulated access exists.
>
> This only works if untrusted programmers (i.e. programmers who are only
> allowed to write/modify @safe code) are not allowed to change your
> class. I.e. it does not work.

Have you ever cracked open std::map and 'fixed' it because you thought
it was bad?
Of course not. Same applies here. Nobody 'fixes' core.atomic.Atomic
without understanding what they're doing.

You seem to be stuck on the detail whether you can trust the @trusted
author though... that is a reasonable point of debate, but it's a
slightly separate topic. I am confident that the number of @trusted
functions required to found a useful stack are low, probably countable
with fingers, and always in a library.

If we can put aside that point of debate just for now; whether you
feel the @trusted author can be trusted, assuming that they can, does
the model work? Can you break the model as I have presented it?
If not; if the model is sound, then we can begin the discussion you're
alluding to and talk about opportunities to improve on static
guarantees for @trusted authors, or ways to communicate their
responsibility clearly, and patterns to assure success.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Monday, 22 October 2018 at 00:32:35 UTC, Timon Gehr wrote:
This only works if untrusted programmers (i.e. programmers who 
are only allowed to write/modify @safe code) are not allowed to 
change your class. I.e. it does not work.


This is the basis of the current @safe/@trusted/@system model.
Are you saying it is useless?


Re: shared - i need it to be useful

2018-10-21 Thread Timon Gehr via Digitalmars-d

On 21.10.18 21:04, Manu wrote:

On Sun, Oct 21, 2018 at 12:00 PM Timon Gehr via Digitalmars-d
 wrote:


On 21.10.18 17:54, Nicholas Wilson wrote:



As soon as that is done, you've got a data race with the other
existing unshared aliases.


You're in @trusted code, that is the whole point. The onus is on the
programmer to make that correct, same with regular @safe/@trusted@system
code.


Not all of the parties that participate in the data race are in @trusted
code. The point of @trusted is modularity: you manually check @trusted
code according to some set of restrictions and then you are sure that
there is no memory corruption.

Note that you are not allowed to look at any of the @safe code while
checking your @trusted code. You will only see an opaque interface to
the @safe code that you call and all you know is that all the @safe code
type checks according to @safe rules. Note that there might be an
arbitrary number of @safe functions and methods that you do not see.

Think about it this way: you first write all the @trusted and @system
code, and some evil guy who does not like you comes in after you looks
at your code and writes all the @safe code. If there is any memory
corruption, it will be your fault and you will face harsh consequences.
Now, design the @safe type checking rules. It won't be MP!

Note that there may well be a good way to get the good properties of MP
without breaking the type system, but MP itself is not good because it
breaks @safe.


Show me. Nobody has been able to show that yet. I'd really like to know this.



I just did, but if you really need to, give me a non-trivial piece of 
correct multithreaded code that accesses some declared-unshared field 
from a shared method and I will show you how the evil guy would modify 
some @safe code in it and introduce race conditions. It needs to be your 
code, as otherwise you will just claim again that it is me who wrote bad 
@trusted code.


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 3:15 PM Neia Neutuladh via Digitalmars-d
 wrote:
>
> On Sun, 21 Oct 2018 12:04:16 -0700, Manu wrote:
> > On Sun, Oct 21, 2018 at 12:00 PM Timon Gehr via Digitalmars-d
> >  wrote:
> >> Note that there may well be a good way to get the good properties of MP
> >> without breaking the type system, but MP itself is not good because it
> >> breaks @safe.
> >
> > Show me. Nobody has been able to show that yet. I'd really like to know
> > this.
>
> If we only used your proposal and only used @safe code, we wouldn't have
> any data races, but that's only because we wouldn't have any shared data.
> We'd have shared *variables*, but they would not contain any data we could
> read or alter, and that's pretty much useless.

I've shown an implementation of Atomic(T) 3 times now... no response
any time. Why is it being dismissed? Do I need to write it more times?
This is a clear demonstration of how to build the foundation of the
@safe threadsafe stack.

> To use your proposal, we need to cast data back from shared to unshared.
> When it's unshared, we need to make sure that exactly one thread has a
> reference to that data as unshared.

No, you just need to make sure that access is atomic or synchronised
in a proper way, and if you do cast away shared in some low-level
@trusted function, make sure that reference doesn't escape.
You can do it, I have faith.

> And @safe *should* help us with that.

Totally.

> Currently, it helps because casting unshared to shared is not @safe,
> because it makes it trivial to get multiple threads with unshared
> references to the same data.

No no, that's a massive smell. That means anytime anyone wants to
distribute something, they need to perform unsafe casts. That's not
okay.
Modeling shared-ness/unshared-ness is not *useful* in any way that I
have been able to identify. Modelling what it means to be threadsafe
is useful in every application I've ever written.
100% of my SMP code works with my proposal, and something close to 0%
works with shared as it is today. (assuming we desire @safe
interaction, which we do, because threading is hard enough already!)

> And that's when you're using shared as
> expected rather than doing something weird.

No, I *expect* to use shared in @safe code, and not write any unsafe
code ever. shared doesn't model a useful interaction now, not in any
way.

Today, access to shared data members are unrestricted and completely
unsafe, passing data into something like a parallel-for requires
unsafe casts.


Re: shared - i need it to be useful

2018-10-21 Thread Timon Gehr via Digitalmars-d

On 21.10.18 20:46, Manu wrote:

Shared data is only useful if, at some point, it is read/written, presumably by
casting it to unshared in @trusted code. As soon as that is done, you've got a
data race with the other existing unshared aliases.

If such a race is possible, then the @trusted function is not
threadsafe, so it is not @trusted by definition.
You wrote a bad @trusted function, and you should feel bad.
...


I wonder where this "each piece of code is maintained by only one person 
and furthermore this is the only person that will suffer if the code has 
bugs" mentality comes from. It is very popular as well as obviously 
nonsense.



The simplest way to guarantee that no unsafe access is possible is to
use encapsulation to assure no unregulated access exists.


This only works if untrusted programmers (i.e. programmers who are only 
allowed to write/modify @safe code) are not allowed to change your 
class. I.e. it does not work.


Re: D T-Shirts

2018-10-21 Thread Mike Parker via Digitalmars-d

On Sunday, 21 October 2018 at 20:04:02 UTC, Fleel wrote:
It would be awesome if there were T-Shirts with D-man on them. 
I would totally buy one, and would help to support the 
foundation too...


We've got a store coming, with t-shirts and other items. D-man 
shirts will not be there, though. That's what we're using for our 
donor t-shirts:


https://opencollective.com/dlang


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 2:35 PM Walter Bright via Digitalmars-d
 wrote:
>
> On 10/21/2018 2:08 PM, Walter Bright wrote:
> > On 10/21/2018 12:20 PM, Nicholas Wilson wrote:
> >> Yes, but the problem you describe is arises from implicit conversion in the
> >> other direction, which is not part of the proposal.
> >
> > It's Manu's example.
>
> Then I don't know what the proposal is. Pieces of it appear to be scattered 
> over
> numerous posts, mixed in with other text,

No no, they're repeated, not scattered, because I seem to have to keep
repeating it over and over, because nobody is reading the text, or
perhaps imaging there is a lot more text than there is.

> opinions, and handwavy stuff.

You mean like every post in opposition which disregards the rules and
baselessly asserts it's a terrible idea? :/

> There's nothing to point to that is "the proposal".

You can go back to the OP, not a single detail is changed at any
point, but I've repeated it a whole bunch of times (including in
direct response to your last post) and the summary has become more
concise, but not different.

1. Shared has no read or write access to data
2. Functions with shared arguments are threadsafe with respect to
those arguments
  a. This is a commitment that must be true in _absolute terms_ (there
exists discussion about the ways that neighbours must not undermine
this promise)
  b. There are numerous examples demonstrating how to configure this
(TL;DR: use encapsulation, and @trusted at the bottom of the stack)

If you can find a legitimate example where those rules don't hold, I
want to see it.
But every example so far has been based on a faulty premise where
those 2 simple rules were not actually applied.

I responded to your faulty program directly with the correct program,
and you haven't acknowledged it. Did you see it?

> I suggest you and Manu write up a proper proposal. Something that is complete,
> has nothing else in it, has a rationale, illuminating examples, and explains 
> why
> alternatives are inferior.

I have written this program a couple of times, including in direct
response to your last sample program.
You seem to have dismissed it... where is your response to that
program, or my last entire post?

> For examples of how to do it:
>
> https://github.com/dlang/DIPs/tree/master/DIPs
>
> Trying to rewrite the semantics of shared is not a simple task, doing
> multithreading correctly is a minefield of "OOPS! I didn't think of that!" and
> if anything cries out for a DIP, your and Manu's proposal does.

Yes, I agree it's DIP worthy. But given the almost nothing but overt
hostility I've received here, why on earth would I waste my time
writing a DIP?
I put months into my other DIP which sits gathering dust... if this
thread inspired any confidence that it would be well-received I would
make the effort, but the critical reception we've seen here is... a
bit strange.
It's a 2-point proposal, the rules are **SO SIMPLE**, which is why I
love it. How it can be misunderstood is something I'm having trouble
understanding, and I don't know how to make it any clearer than I
already have; numerous times over, including in my last reply to you,
which you have ignored and dismissed it seems.

Please go back and read my response to your last program.


Re: We need an internal keyword.

2018-10-21 Thread 12345swordy via Digitalmars-d
On Sunday, 21 October 2018 at 21:48:22 UTC, Laurent Tréguier 
wrote:

On Sunday, 21 October 2018 at 17:09:05 UTC, 12345swordy wrote:

[...]


It's not "my" solution. It's D's solution. I perfectly 
understand why you'd want this and I would probably make use of 
a private/internal difference myself if it was available.


If you already know about this solution however, I don't even 
know why you're starting this thread; since changing the 
behavior of private would be a major language change breaking 
tons of existing codebases, plus it would require adding yet 
another keyword.


Given that this conversation has happened before and things 
haven't changed, I'm very doubtful that it could happen at any 
point in time, sadly.


If the cost out way the benefits then I simply introduce the 
"strict" keyword to avoid code breakage, or introduce the 
optional module scoping.


-Alex


Re: We need an internal keyword.

2018-10-21 Thread 12345swordy via Digitalmars-d
On Sunday, 21 October 2018 at 19:53:35 UTC, Jonathan M Davis 
wrote:
On Saturday, October 20, 2018 9:17:23 PM MDT 12345swordy via 
Digitalmars-d wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


Well, if you feel strongly enough about it, you can always 
create a DIP to try to change things, but I think that I can 
quite safely say that you have pretty much no chance of it 
getting accepted. Walter has been quite clear on this topic 
when it has been discussed previously (and there was a major 
discussion on it not very long ago). It is very much on purpose 
that access is controlled at the module level, and if your 
module is large enough that it is actually causing problems for 
a class or struct to not be able to disallow access of its 
members to other symbols in the module, then the module is too 
large, and the class should be put in a separate module. We 
already have full control of who can access the members of a 
class or struct by controlling which module or package its in 
and what else is in that module or package with it. If you want 
greater control without splitting up your modules more (at 
least as far as importing goes), you can always take advantage 
of public imports to split the code itself into more modules 
while making it possible to get all of the symbols with a 
single import statement.


Certainly, if we had internal or friend or other mechanisms for 
more fine-grained control without doing it at the module-level, 
it would eliminate the need to put code into separate modules 
in some cases, but it would also complicate the language, and 
what we have works quite well in general.


If you don't like the fact that member access is done at the 
module level, then I'm sorry, but overall, this really seems to 
be a philosphical complaint and not a practical one, and Walter 
has made his stance on it very clear. Based on what he's said 
previously, you would need very strong, practical arguments for 
why it's causing actual bugs in programs and why the current 
approach is not cutting it to stand any chance of convincing 
Walter. And honestly, I have never seen anyone come up with an 
argument that was particularly good in that regard. It mostly 
seems to come down to folks simply objecting to the idea that 
anything inside a module would have access to a class' private 
members rather than that it's actually caused bugs. In 
practice, it's usually either actually useful, or it doesn't 
matter.


Either way, simply making post stating that you think that we 
should have the feature isn't going to get you anywhere. If you 
want it, you'll need to find a way to convince Walter.


- Jonathan M Davis
I do plan to write a DIP on this, no question about it. However 
walter have been shown to change his mind unexpectedly. (Remember 
the "mangle symbol only" discussion that manu had argue in favor 
of, which we all thought he sternly opposed to, only to changed 
his mind at the last minute, when a pull request shown up?)


Yes I am aware of the previous discussion regarding this. How can 
I forget about it as that guy who complain about it resort to 
imposter other people including me.


https://forum.dlang.org/thread/vpxoidaqfbfrnnsep...@forum.dlang.org?page=1


However that guy didn't property explain why this was an issue. 
The issue is encapsulation and the traditional get and set 
functions for security checking and value checking, etc, before 
setting the value, retrieving the value and after setting the 
value. Programmers such my self sometimes find it easier to 
maintain classes if they are put in the same file, rather than in 
each own file.
The "package" solution brought up by another user risk the 
possibility of making things more complicated and harder to 
maintain than it should be, when working with code that is 
considerably small spread across multiple files.


I have two solutions in mind:
A.)Introduce the keyword "strict" for the other keywords private 
and protected  only class and structs to prevent being accessed 
from outside the class in the same module by accident.

Example:
class A
{
strict private int x;// This can't be shared in module
strict protected int y; //ditto
private int x; //This can be shared in module
protected int y; //ditto
}
B.)Get rid of the "one module per file" restriction by 
introducing optional module scoping to allow multiple modules in 
a file to allow easy package creation for code that is consider 
to be small without having to maintain multiple files.

Module C;
Module A // Module A in the C package
{

}
module B // AKA B.A
{

}

-Alex


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 11:31 AM Manu  wrote:
>
> On Sun., 21 Oct. 2018, 2:55 am Walter Bright via Digitalmars-d,
>  wrote:
> >
> > On 10/20/2018 11:24 AM, Manu wrote:
> > > This is an unfair dismissal.
> >
> > It has nothing at all to do with fairness. It is about what the type system
> > guarantees in @safe code. To repeat, the current type system guarantees in 
> > @safe
> > code that T* and shared(T)* do not point to the same memory location.
> >
> > Does your proposal maintain that or not? It's a binary question.
>
> By the definition Nick pulled from Wikipedia and posted for you a few
> posts back, yes, my proposal satisfies Wikipedia's definition of no
> aliasing. I understand that property is critical, and I have carefully
> designed for it.
>
> > > I'm not sure you've understood the proposal.
> > > This is the reason for the implicit conversion. It provides safe
> > > transition.
> >
> > I don't see any way to make an implicit T* to shared(T)* safe, or vice 
> > versa.
> > The T* code can create more aliases that the conversion doesn't know about, 
> > and
> > the shared(T)* code can hand out aliases to other threads. So it all falls 
> > to
> > pieces.
>
> T* can't make additional T* aliases on other threads; there can only
> be one thread with T*.
> shared(T)* can not make a T*.
> shared(T)* has no read or write access, so it's not an alias of T* by
> Wikipedia's definition.
>
> Only threadsafe functions can do anything to T.
> The leap of faith is; some @trusted utility functions at the bottom of
> the shared stack makes a promise that it is threadsafe, and must
> deliver that promise.
> I don't think this is unreasonable; this is the nature of @trusted
> functions, they make a promise, and they must keep it.
> If the trusted function does not lie, then the chain of trust holds
> upwards through the stack.
>
> The are very few such trusted functions in practise. Like, similar to
> the number of digits you have.
>
> > Using a 'scope' qualifier won't work, because 'scope' isn't transitive,
> > while shared is, i.e. U** and shared(U*)*.
>
> I don't think I depend on scope in any way.
> That was an earlier revision of thinking in an older thread.
>
> >  > I'm not sure how to clarify it, what can I give you?
> >
> > Write a piece of code that does such an implicit conversion that you argue 
> > is
> > @safe. Make the code as small as possible. Your example:
> >
> >  > int* a;
> >  > shared(int)* b = a;
> >
> > This is not safe.
> >
> >  Manu's Proposal ---
> > @safe:
> > int i;
> > int* a = &i;
> > StartNewThread(a); // Compiles! Coder has no idea!
> >
> > ... in the new thread ...
> > void StartOfNewThread(shared(int)* b) {
> >
> >  ... we have two threads accessing 'i',
> >  one thinks it is shared, the other unshared,
> >  and StartOfNewThread() has no idea and anyone
> >  writing code for StartOfNewThread() has no way
> >  to know anything is wrong ...
> >
> >  lockedIncrement(b);  // Data Race!
> > }
>
> This program doesn't compile. You receive an error because it is not safe.
> The function is `lockedIncrement(int*)`. It can't receive a shared
> argument; the function is not threadsafe by my definition.
> You have written a program that produces the expected error that
> alerts you that you have tried to do un-@safe and make a race.
>
> Stanislav produced this same program, and I responded with the correct
> program a few posts back.
> I'll repeat it here; the @safe program to model this interaction is:
>
> @safe:
>
> // function is NOT threadsafe by my definition, can not be called on
> shared arguments
> void atomicIncrement(int*);
>
> struct Atomic(T)
> {
>   // encapsulare the unsafe data so it's inaccessible by any unsafe means
>   private T val;
>
>   // perform the unsafe cast in a trusted function
>   // we are able to assure a valid calling context by encapsulating
> the data above
>   void opUnary(string op : "++")() shared @trusted {
> atomicIncrement(cast(T*)&val); }
> }
>
> Atomic!int i;
> Atomic!int* a = &i;
> StartNewThread(a); // Compiles, of course!
> ++i; // no race
>
> ... in the new thread ...
> void StartOfNewThread(shared(Atomic!int)* b) {
>   ... we have two threads accessing 'i', one has thread-local access,
> this one has a restricted shared access.
>   here, we have a shared instance, so we can only access `b` via
> threadsafe functions.
>   as such, we can manipulate `b` without fear.
>   ++i; // no race!
> }
>
>
> > Your proposal means that the person writing the lockedIncrement(), which is 
> > a
> > perfectly reasonable thing to do, simply cannot write it in a way that has a
> > @safe interface
>
> Correct, the rules of my proposal apply to lockedIncrement(). They
> apply to `shared` generally.
> lockedIncrement() is not a threadsafe function. You can't call it on a
> shared instance, because `int`s API (ie, all intrinsic operations) are
> not threadsafe.
> lockedIncrement() can't promise threadsafe access to `shared(int)*`,
> so the a

Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 22:12:18 UTC, Neia Neutuladh wrote:

On Sun, 21 Oct 2018 12:04:16 -0700, Manu wrote:
On Sun, Oct 21, 2018 at 12:00 PM Timon Gehr via Digitalmars-d 
 wrote:
Note that there may well be a good way to get the good 
properties of MP without breaking the type system, but MP 
itself is not good because it breaks @safe.


Show me. Nobody has been able to show that yet. I'd really 
like to know this.


If we only used your proposal and only used @safe code, we 
wouldn't have any data races,


Only of the @trusted implementation is thread safe, which it 
_should_ be. This is the same caveat as non threaded 
-@safe/@tusted code.


but that's only because we wouldn't have any shared data. We'd 
have shared *variables*, but they would not contain any data we 
could read


Reads must be atomic.


or alter, and that's pretty much useless.

To use your proposal, we need to cast data back from shared to 
unshared.


Yes but this is in the @trusted implementation that forms the 
basis of your threadsafety.


When it's unshared, we need to make sure that exactly one 
thread has a reference to that data as unshared.


Nod.


And @safe *should* help us with that.


Nod.

Currently, it helps because casting unshared to shared is not 
@safe,


This remains the case, and should be done (enforced by the 
compiler) only in @trusted/@system code as a basis for thread 
safe, @safe code.


because it makes it trivial to get multiple threads with 
unshared references to the same data.


That is @trusted or @system code and therefore is the programmers 
responsibility.


And that's when you're using shared as expected rather than 
doing something weird.


That forms the basis of your thread safe stack. From there on, 
the basis that shared arguments to functions are treated safely 
in the presence of threading means that code that calls the 
@trusted implementations is @safe.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 21:32:14 UTC, Walter Bright wrote:

On 10/21/2018 2:08 PM, Walter Bright wrote:

On 10/21/2018 12:20 PM, Nicholas Wilson wrote:
Yes, but the problem you describe is arises from implicit 
conversion in the other direction, which is not part of the 
proposal.


It's Manu's example.


Then I don't know what the proposal is. Pieces of it appear to 
be scattered over numerous posts, mixed in with other text, 
opinions, and handwavy stuff. There's nothing to point to that 
is "the proposal".


The proposal is:

Implicit conversion _to_ shared, e.g. passing it to a thread 
entry point, and not implicit conversion _from_ shared (just like 
implicit const conversions).


Shared disables reads and writes

 Your confusion results from the use of atomic add which, in 
Manu's examples had a different signature than before.


I suggest you and Manu write up a proper proposal. Something 
that is complete, has nothing else in it, has a rationale, 
illuminating examples, and explains why alternatives are 
inferior.


We will eventually. This started as a "please point out any 
problems with this" and has probably outlived that phase.



Trying to rewrite the semantics of shared is not a simple task,


Not as much as trying to explain it! Having talked to Manu in 
person it is much easier to understand.


doing multithreading correctly is a minefield of "OOPS! I 
didn't think of that!"


The above case in point, this is about assuming your 
implementation of thread safe primitives are thread safe 
(@trusted) that you use it correctly (@safe).





Re: shared - i need it to be useful

2018-10-21 Thread Neia Neutuladh via Digitalmars-d
On Sun, 21 Oct 2018 12:04:16 -0700, Manu wrote:
> On Sun, Oct 21, 2018 at 12:00 PM Timon Gehr via Digitalmars-d
>  wrote:
>> Note that there may well be a good way to get the good properties of MP
>> without breaking the type system, but MP itself is not good because it
>> breaks @safe.
> 
> Show me. Nobody has been able to show that yet. I'd really like to know
> this.

If we only used your proposal and only used @safe code, we wouldn't have 
any data races, but that's only because we wouldn't have any shared data. 
We'd have shared *variables*, but they would not contain any data we could 
read or alter, and that's pretty much useless.

To use your proposal, we need to cast data back from shared to unshared. 
When it's unshared, we need to make sure that exactly one thread has a 
reference to that data as unshared. And @safe *should* help us with that. 
Currently, it helps because casting unshared to shared is not @safe, 
because it makes it trivial to get multiple threads with unshared 
references to the same data. And that's when you're using shared as 
expected rather than doing something weird.


Manu's `shared` vs the @trusted promise

2018-10-21 Thread ag0aep6g via Digitalmars-d
It took me a while to understand Manu's idea for `shared`, and I suspect 
that it was/is the same for others. At the same time, Manu seems 
bewildered about the objections. I'm going to try and summarize the 
situation. Maybe it can help advance the discussion.



(1) How Does Manu's `shared` Interact with @trusted?

With Manu's `shared`, there is implicit conversion from non-`shared` to 
`shared`. It would essentially become a language rule. For that rule to 
be sound, any access to `shared` data must be @system. And more 
challengingly, @system/@trusted code must be written carefully with the 
new rule in mind.


(Manu, you might say that the conversion follows from `shared` methods 
being "guaranteed threadsafe", but I think it's easier to reason this 
way. Anyway, potayto potahto.)


The consequence is: In @trusted code, I have to make sure that I have 
exclusive access to any `shared` data that I use. If code that is not 
under my control can obtain a non-`shared` view of the same data, I have 
failed and my @trusted code is invalid.


An example in code (just rehashing code given by Manu):


struct Atomic
{
private int x;

void incr() shared @trusted
{
/* ... atomically increment x ... */
}

/* If this next method is here, the one above is invalid. It's the
responsibility of the author of the @trusted code to make sure
that this doesn't happen. */

void badboy() @safe { ++x; } /* NO! BAD! NOT ALLOWED! */
}



(2) What's Wrong with That?

The @trusted contract says that an @trusted function must be safe when 
called from an @safe function. That calling @safe function might be 
located in the same module, meaning it might have the same level of 
access as the @trusted function.


That means, Atomic.incr is invalid. It's invalid whether Atomic.badboy 
exists or not. It's invalid because we can even possibly write an 
Atomic.badboy. That's my interpretation of the spec, at least.


But according to Manu, Atomic.incr is fine as long as there's no 
Atomic.badbody that messes things up. So it looks like we're expected to 
violate the @trusted contract when dealing with Manu's `shared`. But 
when we routinely have to break the rules, then that's a sign that the 
rules are bad.



(3) Maybe It Can Be Made to Work?

There might be a way to implement Atomic without breaking the @trusted 
promise:



struct Atomic
{
shared/*!*/ int x;

void incr() shared @trusted { /* ... */ }

/* Now this gets rejected by the compiler: */
void badboy() @safe { ++x; } /* compiler error  */
}


With a `shared int x` there's no way that @safe code might access it, so 
the @trusted promise is kept.


Manu, I don't know if marking fields like this is compatible with your 
plans. But it would address the @safe-ty issue, I think.


However, even if it's possible to reconcile Manu's `shared` with @safe 
and @trusted, that doesn't mean it's automatically golden, of course. It 
would be an enormous breaking change that should be well thought-out, 
scrutinized, planned, and executed.


Re: We need an internal keyword.

2018-10-21 Thread Laurent Tréguier via Digitalmars-d

On Sunday, 21 October 2018 at 17:48:08 UTC, Neia Neutuladh wrote:

On Sun, 21 Oct 2018 08:40:36 +, Laurent Tréguier wrote:
This is by design; the D way of dealing with this would be to 
split the module into a package with multiple modules.


This is often a usable way of doing things, but sometimes not 
so much. If you're writing a script for use with dub --single 
or rdmd, you lose a lot of convenience if you use multiple 
files. It might also take a lot of time to split things up once 
static constructors get involved.


As far as single file scripts go, I don't think something like 
100% perfect encapsulation is always required. A single file 
script is usually a quick way to do a specific thing once or 
twice, and not a persistent project demanding the best code 
quality.


Re: We need an internal keyword.

2018-10-21 Thread Laurent Tréguier via Digitalmars-d

On Sunday, 21 October 2018 at 17:09:05 UTC, 12345swordy wrote:
I know what the current design is!! You have zero tools in 
regarding to allowing class to share certain variables but not 
others in the same module! Create a module for every class is 
taking all or nothing approach, when there is a reasonable 
middle ground.
Your package solution just make things more unnecessarily 
complicated then warranted


It's not "my" solution. It's D's solution. I perfectly understand 
why you'd want this and I would probably make use of a 
private/internal difference myself if it was available.


If you already know about this solution however, I don't even 
know why you're starting this thread; since changing the behavior 
of private would be a major language change breaking tons of 
existing codebases, plus it would require adding yet another 
keyword.


Given that this conversation has happened before and things 
haven't changed, I'm very doubtful that it could happen at any 
point in time, sadly.


Re: D alternative for node.js's socket.IO?

2018-10-21 Thread Neia Neutuladh via Digitalmars-d
On Sun, 21 Oct 2018 20:58:23 +, Fleel wrote:
> Can std.socket provide a realtime connection between the client(web
> browser) and the server, like for a chatroom or realtime multiplayer
> game?

Yes, but it will be a bit of work -- you'd need to implement a webserver 
by hand that can upgrade an HTTP request to a websocket. It probably 
wouldn't be *that* hard, but vibe.d already has support for both HTTP 
servers and websockets.

This does mean changing the javascript code, but from what I saw last time 
I used it, socket.io provides little advantage over plain websockets.


Re: shared - i need it to be useful

2018-10-21 Thread Walter Bright via Digitalmars-d

On 10/21/2018 2:08 PM, Walter Bright wrote:

On 10/21/2018 12:20 PM, Nicholas Wilson wrote:
Yes, but the problem you describe is arises from implicit conversion in the 
other direction, which is not part of the proposal.


It's Manu's example.


Then I don't know what the proposal is. Pieces of it appear to be scattered over 
numerous posts, mixed in with other text, opinions, and handwavy stuff. There's 
nothing to point to that is "the proposal".


I suggest you and Manu write up a proper proposal. Something that is complete, 
has nothing else in it, has a rationale, illuminating examples, and explains why 
alternatives are inferior.


For examples of how to do it:

https://github.com/dlang/DIPs/tree/master/DIPs

Trying to rewrite the semantics of shared is not a simple task, doing 
multithreading correctly is a minefield of "OOPS! I didn't think of that!" and 
if anything cries out for a DIP, your and Manu's proposal does.


Re: shared - i need it to be useful

2018-10-21 Thread Walter Bright via Digitalmars-d

On 10/21/2018 12:20 PM, Nicholas Wilson wrote:
Yes, but the problem you describe is arises from implicit conversion in the 
other direction, which is not part of the proposal.


It's Manu's example.


Re: shared - i need it to be useful

2018-10-21 Thread Stanislav Blinov via Digitalmars-d

On Sunday, 21 October 2018 at 19:22:45 UTC, Manu wrote:
On Sun, Oct 21, 2018 at 5:50 AM Stanislav Blinov via 
Digitalmars-d  wrote:


Because the whole reason to have `shared` is to avoid the 
extraneous checks that you mentioned above,


No, it is to assure that you write correct not-broken code.


You can do that without `shared`.

and only write actual useful code (i.e. lock-write-unlock, or 
read-put-to-queue-repeat, or whatever), not busy-work (testing 
if the file is open on every call).


`shared` is no comment on performance. You have written a slow 
locking API.
If you care about perf, you would write a completely different 
API that favours perf.

This not impossible, nor even particularly hard.


You're conflating your assumptions about the code with the topic 
of this discussion. I can write a million examples and you'll 
still find a million reasons to talk about how they're 
incorrectly implemented, instead of focusing on merits or 
disadvantages of your proposal with the code given as is.


If you have a `shared` reference, it better be to existing 
data.


I mean, if I dereference a pointer, it had better not be null!


Why would you share a null pointer?


That's why having `shared` and un-`shared`
references to the same data simultaneously is not safe: you 
can't guarantee in any way that the owning thread doesn't 
invalidate

the data through it's non-`shared` reference while you're doing
your threadsafe `shared` work; you can only "promise" that by
convention (documentation).


The owning thread is not a special actor. Your reasoning is 
wonky here.


Why have it then at all? If it's not a "special" actor, just make 
all shared data `shared`. But your proposal specifically targets 
the conversion, suggesting you *do* need a special actor.



And I have partially-read or partially-written data.


I expect you flushed before killing the file.


So? The threads still weren't done yet.

Or Maybe I call closeFile(), main thread continues and opens 
another file,

which gives the same file descriptor, `shared` references to
FileHandle which the user forgot to wait on continue to work
oblivious to the fact that it's a different file now.


It's wild to suggest that ANY design for `shared` should 
somehow deal with the OS recycling a file handle...


I'm not suggesting that at all, you've completely misrepresenting 
what I'm saying by splitting a quote.


And it's still not an un-@safe crash! It's just a program with 
a bug.


Ok, if you say that sticking @safe on code that can partially 
piece together data from unrelated sources is fine, then sure.



> I'm going to assume that `shareWithThreads()` was implemented
> by an 'expert' who checked the function results for errors...


But you can only find out about these errors in 
`waitForThreads`, the very call that the user "forgot" to make!


...what?


Please suggest another way of handling errors reported by other 
threads. More `shared` state?



[ ... snip ... ]


You have to concede defeat at this point.


I agree. No matter how hard I try or how many times I ask you to 
demonstrate, I still fail to see the value in assuming @safe 
implicitly conversion of mutable data to shared. Instead of 
defending your proposal, you chose to attack the opposition. 
You've defeated me, flawless victory.



Destroy my proposal with another legitimately faulty program.


Is there a point? I post code, you: "nah, that's wrong". Steven 
posts code, you: "nah, that's wrong". Timon posts code, you: 
"nah, that's wrong". Walter posts code, you: "nah, that's 
wrong"... What's right then?


Re: D alternative for node.js's socket.IO?

2018-10-21 Thread Fleel via Digitalmars-d

On Sunday, 21 October 2018 at 20:41:41 UTC, JN wrote:

On Sunday, 21 October 2018 at 20:14:46 UTC, Fleel wrote:
Does anyone know of a good D alternative for the socket.IO 
server (https://socket.io)? I would like to transition my 
server from node.js to D, but I can't find any D equivalents 
to socket.IO. (I've seen http://socket.io.dub.pm, but it is 
dead). Are there any good D libraries that can do the same 
thing as socket.IO? Thanks!


Is std.socket not sufficient? It should be, at least for TCP 
connections. For UDP you could use something like Enet, there 
are Enet bindings in Derelict.


Can std.socket provide a realtime connection between the 
client(web browser) and the server, like for a chatroom or 
realtime multiplayer game?


Re: D T-Shirts

2018-10-21 Thread welkam via Digitalmars-d

On Sunday, 21 October 2018 at 20:04:02 UTC, Fleel wrote:
It would be awesome if there were T-Shirts with D-man on them. 
I would totally buy one, and would help to support the 
foundation too...


well that cost 100$+


Re: D T-Shirts

2018-10-21 Thread Fleel via Digitalmars-d

On Sunday, 21 October 2018 at 20:35:20 UTC, Manu wrote:
On Sun., 21 Oct. 2018, 1:05 pm Fleel via Digitalmars-d, < 
digitalmars-d@puremagic.com> wrote:


It would be awesome if there were T-Shirts with D-man on them. 
I would totally buy one, and would help to support the 
foundation too...




Lucky for you, they exist, and you can acquire one by 
supporting the d foundation! ;)


Really? I was looking for them and I couldn't find any. Where do 
I get one?


Re: D alternative for node.js's socket.IO?

2018-10-21 Thread JN via Digitalmars-d

On Sunday, 21 October 2018 at 20:14:46 UTC, Fleel wrote:
Does anyone know of a good D alternative for the socket.IO 
server (https://socket.io)? I would like to transition my 
server from node.js to D, but I can't find any D equivalents to 
socket.IO. (I've seen http://socket.io.dub.pm, but it is dead). 
Are there any good D libraries that can do the same thing as 
socket.IO? Thanks!


Is std.socket not sufficient? It should be, at least for TCP 
connections. For UDP you could use something like Enet, there are 
Enet bindings in Derelict.


Re: D Binding to GUI libraries

2018-10-21 Thread Patrick Schluter via Digitalmars-d

On Sunday, 21 October 2018 at 18:24:30 UTC, Jacob Carlborg wrote:

On 2018-10-21 19:29, Russel Winder wrote:

But who apart from Eclipse and JetBrains uses Java for desktop 
GUI

applications?


There's probably a ton of business/enterprise applications that 
are written in Java.


But I don't care for that, that's why I'm using D :)


I do not have Eclipse to check, but the JetBrains IDEs
(at least CLion, GoLand, IntelliJ IDEA, and PyCharm) ship 
Swing, SWT,

and JavaFX in their systems.


Not sure what you mean with "ship" here. Swing and JavaFX are 
shipped with Java.


Eclipse itself is built using SWT.

Swing, and I believe SWT, have somewhat old architectures for 
GUI
frameworks where GTK+, Qt, and wxWidgets have moved on. But 
this may

just be opinion rather than agreed "fact".


I haven't use these other frameworks so I don't know what's 
consider old architecture and modern architecture.



Apart from GtkD on GTK+ systems


Linux doesn't have a "native" GUI in the same sense as macOS 
and Windows.


, and dqml, QtE5, qtD, and dqt on Qt,
and wxD on wxWidgets. Qt and wxWidgets pride themselves on 
being able
to use native frameworks underneath – I have no personal 
evidence as I

only use GNOME, I am not a good data point.


Qt is not native, at least not on macOS. Are any of the Qt D 
bindings actually useful? wxD seems very old, D1 old, is that 
useable?


When I said that DWT is basically the only native D toolkit, I 
failed to also include: up to date (as in working with the 
latest compiler), working and cross-platform.


I like it and I'm looking forward that it gets beyond swt 3.4.
I ported my Java GUI SWT program to D and it was a breeze to do. 
I didn't even require to change the structure of the app and the 
class hierarchy. There was only the file and string handling that 
I had to change, in fact make so much more readable and efficient.
There were some difficulties because of compiler issues in 
version 2.7x, but those were resolved and everything went smooth 
after that.


Re: D T-Shirts

2018-10-21 Thread Manu via Digitalmars-d
On Sun., 21 Oct. 2018, 1:05 pm Fleel via Digitalmars-d, <
digitalmars-d@puremagic.com> wrote:

> It would be awesome if there were T-Shirts with D-man on them. I
> would totally buy one, and would help to support the foundation
> too...
>

Lucky for you, they exist, and you can acquire one by supporting the d
foundation! ;)

>


D alternative for node.js's socket.IO?

2018-10-21 Thread Fleel via Digitalmars-d
Does anyone know of a good D alternative for the socket.IO server 
(https://socket.io)? I would like to transition my server from 
node.js to D, but I can't find any D equivalents to socket.IO. 
(I've seen http://socket.io.dub.pm, but it is dead). Are there 
any good D libraries that can do the same thing as socket.IO? 
Thanks!


D T-Shirts

2018-10-21 Thread Fleel via Digitalmars-d
It would be awesome if there were T-Shirts with D-man on them. I 
would totally buy one, and would help to support the foundation 
too...


Re: We need an internal keyword.

2018-10-21 Thread Jonathan M Davis via Digitalmars-d
On Saturday, October 20, 2018 9:17:23 PM MDT 12345swordy via Digitalmars-d 
wrote:
> So that classes can share some of their variables but not others
> in a module.
>
> IE.
>
> class A
> {
> internal int A; //This is shared in the module
> private int B; // But not this.
> }
>
> No need to reintroduce the "Friend" feature from cpp.

Well, if you feel strongly enough about it, you can always create a DIP to
try to change things, but I think that I can quite safely say that you have
pretty much no chance of it getting accepted. Walter has been quite clear on
this topic when it has been discussed previously (and there was a major
discussion on it not very long ago). It is very much on purpose that access
is controlled at the module level, and if your module is large enough that
it is actually causing problems for a class or struct to not be able to
disallow access of its members to other symbols in the module, then the
module is too large, and the class should be put in a separate module. We
already have full control of who can access the members of a class or struct
by controlling which module or package its in and what else is in that
module or package with it. If you want greater control without splitting up
your modules more (at least as far as importing goes), you can always take
advantage of public imports to split the code itself into more modules while
making it possible to get all of the symbols with a single import statement.

Certainly, if we had internal or friend or other mechanisms for more
fine-grained control without doing it at the module-level, it would
eliminate the need to put code into separate modules in some cases, but it
would also complicate the language, and what we have works quite well in
general.

If you don't like the fact that member access is done at the module level,
then I'm sorry, but overall, this really seems to be a philosphical
complaint and not a practical one, and Walter has made his stance on it very
clear. Based on what he's said previously, you would need very strong,
practical arguments for why it's causing actual bugs in programs and why the
current approach is not cutting it to stand any chance of convincing Walter.
And honestly, I have never seen anyone come up with an argument that was
particularly good in that regard. It mostly seems to come down to folks
simply objecting to the idea that anything inside a module would have access
to a class' private members rather than that it's actually caused bugs. In
practice, it's usually either actually useful, or it doesn't matter.

Either way, simply making post stating that you think that we should have
the feature isn't going to get you anywhere. If you want it, you'll need to
find a way to convince Walter.

- Jonathan M Davis





Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 19:07:37 UTC, Nicholas Wilson wrote:

On Sunday, 21 October 2018 at 09:50:09 UTC, Walter Bright wrote:
Your proposal makes that impossible because the compiler would 
allow unshared data to be implicitly typed as shared.


Yes, but not the other way around.


Whoops that should read


Your proposal makes that impossible


No

because the compiler would allow unshared data to be 
implicitly typed as shared.


Yes, but the problem you describe is arises from implicit 
conversion in the other direction, which is not part of the 
proposal.


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 5:50 AM Stanislav Blinov via Digitalmars-d
 wrote:
>
> On Sunday, 21 October 2018 at 05:47:14 UTC, Manu wrote:
>
> >> And yet, if we're lucky, we get
> >> a consistent instacrash. If we're unlucky, we get memory
> >> corruption, or an unsolicited write to another currently open
> >> file, either of which can go unnoticed for some time.
>
> > Woah! Now this is way off-piste..
> > Why would get a crash? Why would get memory corruption? None of
> > those things make sense.
>
> Because the whole reason to have `shared` is to avoid the
> extraneous checks that you mentioned above,

No, it is to assure that you write correct not-broken code.

> and only write actual
> useful code (i.e. lock-write-unlock, or read-put-to-queue-repeat,
> or whatever), not busy-work (testing if the file is open on every
> call).

`shared` is no comment on performance. You have written a slow locking API.
If you care about perf, you would write a completely different API
that favours perf.
This not impossible, nor even particularly hard.

> If you have a `shared` reference, it better be to existing
> data.

I mean, if I dereference a pointer, it had better not be null!

> If it isn't, the program is invalid already: you've shared
> something that doesn't "exist" (good for marketing, not so good
> for multithreading).

I mean, if I dereference a pointer, it had better not be null!

> That's why having `shared` and un-`shared`
> references to the same data simultaneously is not safe: you can't
> guarantee in any way that the owning thread doesn't invalidate
> the data through it's non-`shared` reference while you're doing
> your threadsafe `shared` work; you can only "promise" that by
> convention (documentation).

The owning thread is not a special actor. Your reasoning is wonky here.
Lets say there is no owning instance, only a collection of shared
instances... any one of them can theoretically do an operation that
interferes with the others.
That's issues for general threading, and no design for `shared` can
(or should) interact with that problem. That's a problem for
architecture.

> > So, you call closeFile immediately and read/write start
> > returning null.
>
> And I have partially-read or partially-written data.

I expect you flushed before killing the file.

> Or Maybe I
> call closeFile(), main thread continues and opens another file,
> which gives the same file descriptor, `shared` references to
> FileHandle which the user forgot to wait on continue to work
> oblivious to the fact that it's a different file now.

It's wild to suggest that ANY design for `shared` should somehow deal
with the OS recycling a file handle...
And it's still not an un-@safe crash! It's just a program with a bug.

> It's a
> horrible, but still @safe, implementation of FileHandle, yes, but
> the caller (user) doesn't know that, and can't know that just
> from the interface. The only advice against that is "don't do
> that", but that's irrespective of your proposal.

No proposal can (or should) address these issues. You're concerned
with an issue that is so far left-field at this stage.
Programming languages don't validate that you wrote a working bug-free program.

> > I'm going to assume that `shareWithThreads()` was implemented
> > by an
> > 'expert' who checked the function results for errors. It was
> > detected that the reads/write failed, and an error "failed to
> > read file" was emit, then the function returned promptly.
> > The uncertainty of what happens in this program is however
> > `shareWithThreads()` handles read/write emitting an error.
>
> But you can only find out about these errors in `waitForThreads`,
> the very call that the user "forgot" to make!

...what?

> [ ... snip ... ]

You have to concede defeat at this point.

Destroy my proposal with another legitimately faulty program.


> I understand that. So... it would seem that your proposal focuses
> more on @safe than on threadsafety?

I am trying to achieve @safe-ty _with respect to threadsafety_.

'threadsafety' with respect to "proper program operation" is a job for
programmers, and program architecture.
No language attribute can make your program right.


Re: shared - i need it to be useful

2018-10-21 Thread 12345swordy via Digitalmars-d

On Sunday, 21 October 2018 at 18:45:15 UTC, Walter Bright wrote:
I'd like to add that if the compiler can prove that a T* points 
to a unique T, then it can be implicitly cast to shared(T)*. 
And it does so, like the result of .dup can be so converted.


This can be achieved by using the unique struct and enforce the 
uniqueness at compile time.


https://github.com/dlang/phobos/blob/master/std/typecons.d#L130


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 09:50:09 UTC, Walter Bright wrote:

 Manu's Proposal ---
@safe:
int i;
int* a = &i;
StartNewThread(a); // Compiles! Coder has no idea!

... in the new thread ...
void StartOfNewThread(shared(int)* b) {

... we have two threads accessing 'i',
one thinks it is shared, the other unshared,
and StartOfNewThread() has no idea and anyone
writing code for StartOfNewThread() has no way
to know anything is wrong ...

lockedIncrement(b);  // Data Race!


No, does not compile, lockedIncrement takes an int*
Error cannot convert shared(int)* to int*

Your proposal means that the person writing the 
lockedIncrement(), which is a perfectly reasonable thing to do,


Indeed.

simply cannot write it in a way that has a @safe interface, 
because the person writing the lockedIncrement() library 
function has no way to know that the data it receives is 
actually unshared data.


It does, it takes an int* which is not implicitly convertible to 
given an shared(int)*



I.e. @trusted code is obliged to proved a safe interface.


Yes.

Your proposal makes that impossible because the compiler would 
allow unshared data to be implicitly typed as shared.


Yes, but not the other way around.



Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 12:00 PM Timon Gehr via Digitalmars-d
 wrote:
>
> On 21.10.18 17:54, Nicholas Wilson wrote:
> >
> >> As soon as that is done, you've got a data race with the other
> >> existing unshared aliases.
> >
> > You're in @trusted code, that is the whole point. The onus is on the
> > programmer to make that correct, same with regular @safe/@trusted@system
> > code.
>
> Not all of the parties that participate in the data race are in @trusted
> code. The point of @trusted is modularity: you manually check @trusted
> code according to some set of restrictions and then you are sure that
> there is no memory corruption.
>
> Note that you are not allowed to look at any of the @safe code while
> checking your @trusted code. You will only see an opaque interface to
> the @safe code that you call and all you know is that all the @safe code
> type checks according to @safe rules. Note that there might be an
> arbitrary number of @safe functions and methods that you do not see.
>
> Think about it this way: you first write all the @trusted and @system
> code, and some evil guy who does not like you comes in after you looks
> at your code and writes all the @safe code. If there is any memory
> corruption, it will be your fault and you will face harsh consequences.
> Now, design the @safe type checking rules. It won't be MP!
>
> Note that there may well be a good way to get the good properties of MP
> without breaking the type system, but MP itself is not good because it
> breaks @safe.

Show me. Nobody has been able to show that yet. I'd really like to know this.


Re: shared - i need it to be useful

2018-10-21 Thread Timon Gehr via Digitalmars-d

On 21.10.18 17:54, Nicholas Wilson wrote:


As soon as that is done, you've got a data race with the other 
existing unshared aliases.


You're in @trusted code, that is the whole point. The onus is on the 
programmer to make that correct, same with regular @safe/@trusted@system 
code.


Not all of the parties that participate in the data race are in @trusted 
code. The point of @trusted is modularity: you manually check @trusted 
code according to some set of restrictions and then you are sure that 
there is no memory corruption.


Note that you are not allowed to look at any of the @safe code while 
checking your @trusted code. You will only see an opaque interface to 
the @safe code that you call and all you know is that all the @safe code 
type checks according to @safe rules. Note that there might be an 
arbitrary number of @safe functions and methods that you do not see.


Think about it this way: you first write all the @trusted and @system 
code, and some evil guy who does not like you comes in after you looks 
at your code and writes all the @safe code. If there is any memory 
corruption, it will be your fault and you will face harsh consequences. 
Now, design the @safe type checking rules. It won't be MP!


Note that there may well be a good way to get the good properties of MP 
without breaking the type system, but MP itself is not good because it 
breaks @safe.


Re: shared - i need it to be useful

2018-10-21 Thread Walter Bright via Digitalmars-d
I'd like to add that if the compiler can prove that a T* points to a unique T, 
then it can be implicitly cast to shared(T)*. And it does so, like the result of 
.dup can be so converted.


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun, Oct 21, 2018 at 3:00 AM Walter Bright via Digitalmars-d
 wrote:
>
> On 10/20/2018 11:08 AM, Nicholas Wilson wrote:
> > You can if no-one else writes to it, which is the whole point of Manu's
> > proposal. Perhaps it should be const shared instead of shared but still.
>
> There is no purpose whatsoever to data that can be neither read nor written.

There is no primitive type with implicit threadsafety... nor need there be.
Shared data simply can not be read or written in any threadsafe
manner. This is a rock-solid reality, and the type system needs to
reflect that reality as a fundamental premise.
Only from there can we start to define meaningful threadsafety.

All threadsafe interactions with anything involve calling functions.
It's completely reasonable to make `shared` inhibit all read and write
access to data. We can only call shared methods, because only
real-code can implement threadsafety.

> Shared data is only useful if, at some point, it is read/written, presumably 
> by
> casting it to unshared in @trusted code. As soon as that is done, you've got a
> data race with the other existing unshared aliases.

If such a race is possible, then the @trusted function is not
threadsafe, so it is not @trusted by definition.
You wrote a bad @trusted function, and you should feel bad.

The simplest way to guarantee that no unsafe access is possible is to
use encapsulation to assure no unregulated access exists.


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun., 21 Oct. 2018, 2:55 am Walter Bright via Digitalmars-d,
 wrote:
>
> On 10/20/2018 11:24 AM, Manu wrote:
> > This is an unfair dismissal.
>
> It has nothing at all to do with fairness. It is about what the type system
> guarantees in @safe code. To repeat, the current type system guarantees in 
> @safe
> code that T* and shared(T)* do not point to the same memory location.
>
> Does your proposal maintain that or not? It's a binary question.

By the definition Nick pulled from Wikipedia and posted for you a few
posts back, yes, my proposal satisfies Wikipedia's definition of no
aliasing. I understand that property is critical, and I have carefully
designed for it.

> > I'm not sure you've understood the proposal.
> > This is the reason for the implicit conversion. It provides safe
> > transition.
>
> I don't see any way to make an implicit T* to shared(T)* safe, or vice versa.
> The T* code can create more aliases that the conversion doesn't know about, 
> and
> the shared(T)* code can hand out aliases to other threads. So it all falls to
> pieces.

T* can't make additional T* aliases on other threads; there can only
be one thread with T*.
shared(T)* can not make a T*.
shared(T)* has no read or write access, so it's not an alias of T* by
Wikipedia's definition.

Only threadsafe functions can do anything to T.
The leap of faith is; some @trusted utility functions at the bottom of
the shared stack makes a promise that it is threadsafe, and must
deliver that promise.
I don't think this is unreasonable; this is the nature of @trusted
functions, they make a promise, and they must keep it.
If the trusted function does not lie, then the chain of trust holds
upwards through the stack.

The are very few such trusted functions in practise. Like, similar to
the number of digits you have.

> Using a 'scope' qualifier won't work, because 'scope' isn't transitive,
> while shared is, i.e. U** and shared(U*)*.

I don't think I depend on scope in any way.
That was an earlier revision of thinking in an older thread.

>  > I'm not sure how to clarify it, what can I give you?
>
> Write a piece of code that does such an implicit conversion that you argue is
> @safe. Make the code as small as possible. Your example:
>
>  > int* a;
>  > shared(int)* b = a;
>
> This is not safe.
>
>  Manu's Proposal ---
> @safe:
> int i;
> int* a = &i;
> StartNewThread(a); // Compiles! Coder has no idea!
>
> ... in the new thread ...
> void StartOfNewThread(shared(int)* b) {
>
>  ... we have two threads accessing 'i',
>  one thinks it is shared, the other unshared,
>  and StartOfNewThread() has no idea and anyone
>  writing code for StartOfNewThread() has no way
>  to know anything is wrong ...
>
>  lockedIncrement(b);  // Data Race!
> }

This program doesn't compile. You receive an error because it is not safe.
The function is `lockedIncrement(int*)`. It can't receive a shared
argument; the function is not threadsafe by my definition.
You have written a program that produces the expected error that
alerts you that you have tried to do un-@safe and make a race.

Stanislav produced this same program, and I responded with the correct
program a few posts back.
I'll repeat it here; the @safe program to model this interaction is:

@safe:

// function is NOT threadsafe by my definition, can not be called on
shared arguments
void atomicIncrement(int*);

struct Atomic(T)
{
  // encapsulare the unsafe data so it's inaccessible by any unsafe means
  private T val;

  // perform the unsafe cast in a trusted function
  // we are able to assure a valid calling context by encapsulating
the data above
  void opUnary(string op : "++")() shared @trusted {
atomicIncrement(cast(T*)&val); }
}

Atomic!int i;
Atomic!int* a = &i;
StartNewThread(a); // Compiles, of course!
++i; // no race

... in the new thread ...
void StartOfNewThread(shared(Atomic!int)* b) {
  ... we have two threads accessing 'i', one has thread-local access,
this one has a restricted shared access.
  here, we have a shared instance, so we can only access `b` via
threadsafe functions.
  as such, we can manipulate `b` without fear.
  ++i; // no race!
}


> Your proposal means that the person writing the lockedIncrement(), which is a
> perfectly reasonable thing to do, simply cannot write it in a way that has a
> @safe interface

Correct, the rules of my proposal apply to lockedIncrement(). They
apply to `shared` generally.
lockedIncrement() is not a threadsafe function. You can't call it on a
shared instance, because `int`s API (ie, all intrinsic operations) are
not threadsafe.
lockedIncrement() can't promise threadsafe access to `shared(int)*`,
so the argument is not shared.

Your program made the correct compile error about doing unsafety, but
the location of the compile error is different under my proposal;
complexity is worn by the shared library author, rather than every
calling user ever.
I think my proposal places the complexity in the right location.
`shared`

Re: D Binding to GUI libraries

2018-10-21 Thread Jacob Carlborg via Digitalmars-d

On 2018-10-21 19:29, Russel Winder wrote:


But who apart from Eclipse and JetBrains uses Java for desktop GUI
applications?


There's probably a ton of business/enterprise applications that are 
written in Java.


But I don't care for that, that's why I'm using D :)


I do not have Eclipse to check, but the JetBrains IDEs
(at least CLion, GoLand, IntelliJ IDEA, and PyCharm) ship Swing, SWT,
and JavaFX in their systems.


Not sure what you mean with "ship" here. Swing and JavaFX are shipped 
with Java.


Eclipse itself is built using SWT.


Swing, and I believe SWT, have somewhat old architectures for GUI
frameworks where GTK+, Qt, and wxWidgets have moved on. But this may
just be opinion rather than agreed "fact".


I haven't use these other frameworks so I don't know what's consider old 
architecture and modern architecture.



Apart from GtkD on GTK+ systems


Linux doesn't have a "native" GUI in the same sense as macOS and Windows.

, and dqml, QtE5, qtD, and dqt on Qt,

and wxD on wxWidgets. Qt and wxWidgets pride themselves on being able
to use native frameworks underneath – I have no personal evidence as I
only use GNOME, I am not a good data point.


Qt is not native, at least not on macOS. Are any of the Qt D bindings 
actually useful? wxD seems very old, D1 old, is that useable?


When I said that DWT is basically the only native D toolkit, I failed to 
also include: up to date (as in working with the latest compiler), 
working and cross-platform.


--
/Jacob Carlborg


Re: We need an internal keyword.

2018-10-21 Thread Neia Neutuladh via Digitalmars-d
On Sun, 21 Oct 2018 08:40:36 +, Laurent Tréguier wrote:
> This is by design; the D way of dealing with this would be to split the
> module into a package with multiple modules.

This is often a usable way of doing things, but sometimes not so much. If 
you're writing a script for use with dub --single or rdmd, you lose a lot 
of convenience if you use multiple files. It might also take a lot of time 
to split things up once static constructors get involved.


Re: D Binding to GUI libraries [was Interesting Observation from JAXLondon]

2018-10-21 Thread Russel Winder via Digitalmars-d
On Sun, 2018-10-21 at 12:54 +0200, Jacob Carlborg via Digitalmars-d
wrote:
> 
[…]
> As has been stated elsewhere, it's working on Windows and macOS but 
> looks very alien on macOS. When I was in school I wrote a program
> using 
> C# (Mono) and GTK on macOS. GTK seemed to be the best alternative
> (for 
> using with Mono) back then. During the development of that program a 
> beta or alpha version of GTK was released with support for a native
> main 
> menu on macOS, the rest was non-native. Not sure how it looks like
> now.

I tried GTK+ on OSX (*) a few weeks back using all the stuff from
Homebrew. It started an X server, so definitely not native GUI
framework. At least not directly.

(*) El Capitan. Apple in its infinite wisdom has decided my MBP is too
old to have any OS more recent than that.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



signature.asc
Description: This is a digitally signed message part


Re: D Binding to GUI libraries

2018-10-21 Thread Russel Winder via Digitalmars-d
On Sun, 2018-10-21 at 12:49 +0200, Jacob Carlborg via Digitalmars-d
wrote:
> On 2018-10-21 09:33, Russel Winder wrote:
> 
> > The SWT framework is being replaced with JavaFX, so should D forget
> > DWT
> > and do something similar?
> 
> Where do you get that idea? SWT (and therefore DWT) is using the
> native 
> drawing operations of the OS.

But who apart from Eclipse and JetBrains uses Java for desktop GUI
applications? I do not have Eclipse to check, but the JetBrains IDEs
(at least CLion, GoLand, IntelliJ IDEA, and PyCharm) ship Swing, SWT,
and JavaFX in their systems.

Swing, and I believe SWT, have somewhat old architectures for GUI
frameworks where GTK+, Qt, and wxWidgets have moved on. But this may
just be opinion rather than agreed "fact".
 
> No, D should not forget DWT. It's one of the few (they only?) D GUI 
> toolkit that has a native look and feel.

Apart from GtkD on GTK+ systems, and dqml, QtE5, qtD, and dqt on Qt,
and wxD on wxWidgets. Qt and wxWidgets pride themselves on being able
to use native frameworks underneath – I have no personal evidence as I
only use GNOME, I am not a good data point.

I do know though that a decade ago I was a fan of wxWidgets exactly
because it was a wrapper around native look and feel and better than
Qt. GTK+ doesn't really play that game.
 
-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



signature.asc
Description: This is a digitally signed message part


Re: D Binding to GUI libraries

2018-10-21 Thread Russel Winder via Digitalmars-d
On Sun, 2018-10-21 at 08:42 +, Paolo Invernizzi via Digitalmars-d
wrote:
> […]
> 
> Linux is not only the desktop, and Qt simply dominates in 
> industrial, medical and automation sector, that's where the money 
> is.
> 
> Qt is pushing strongly on the embedded marked, bare metal or 
> linux (kernel) based...

Which means that D not having a good play in the Qt space is a big
barrier to adoption. This means it ought to be a strategic goal to have
a (and I think I mean one here) D binding to Qt and QML.
 
-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



signature.asc
Description: This is a digitally signed message part


Re: D Binding to GUI libraries

2018-10-21 Thread Russel Winder via Digitalmars-d
On Sun, 2018-10-21 at 04:15 -0400, Nick Sabalausky (Abscissa) via
Digitalmars-d wrote:
> […]
> 
> That's pure nonsense: It's Linux - unless one option actually goes
> away 
> (KDE is still actively used and developed), then there's no such
> thing 
> as one "winning" over the other.

Hardly nonsense. Debian, Ubuntu, Fedora all prefer GNOME over KDE, so
GTK+ over Qt.

> It IS a big problem that far too many people (mainly developers
> coming 
> directly from the Windows world who have decided to half-ass a Linux 
> port) have decided to erroneously equate "Linux" with "GTK-based DE" 
> these days, but that's a far cry from saying that GTK/GNOME/Unity
> "won 
> out" over Qt/KDE.

People coming from Windows or macOS are genreally unaware of the notion
of choice when it comes to UI. That Linux provides a choice is clearly
alien to them. That I have chosen GNOME over KDE is a personal choice,
but I like having the choice: I like that others can choose KDE or
Cinnamon or whatever.

[…]
> Programmers writing GUI apps often like GTK. Nobody else does. From
> a 
> programmer standpoint, it may very well be nice. But that's
> irrelevant, 
> because from the user standpoint, GTK is, and has always been, a 
> steaming pool of diarrhea, even if you ARE using GNOME/Unity.

GTK+ is fine and dandy. That you do not like it is your choice, and
that is fine.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



signature.asc
Description: This is a digitally signed message part


Re: We need an internal keyword.

2018-10-21 Thread 12345swordy via Digitalmars-d
On Sunday, 21 October 2018 at 08:40:36 UTC, Laurent Tréguier 
wrote:

On Sunday, 21 October 2018 at 03:17:23 UTC, 12345swordy wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


This is by design; the D way of dealing with this would be to 
split the module into a package with multiple modules. The A 
class would be in its own module, and use `package` where you 
used `internal` so that other modules in the same package can 
have access to it.
Using a package.d package module 
(https://dlang.org/spec/module.html#package-module), you can 
still use the multiple modules just as if they were a single 
module.


Instead of a source tree like this:

source
|
+-some
  |
  +-thing.d

You'd end up with a source tree like this:

source
|
+-some
  |
  +-thing
|
+-package.d
|
+-a.d
|
+-rest_of_the_stuff.d

Where package.d publicly imports a.d and rest_of_the_stuff.d, 
so `import some.thing` would still work.
I know what the current design is!! You have zero tools in 
regarding to allowing class to share certain variables but not 
others in the same module! Create a module for every class is 
taking all or nothing approach, when there is a reasonable middle 
ground.
Your package solution just make things more unnecessarily 
complicated then warranted





Re: shared - i need it to be useful

2018-10-21 Thread Neia Neutuladh via Digitalmars-d
On Sat, 20 Oct 2018 22:47:14 -0700, Manu wrote:
> Looking at the meat of the program; you open a file, and distribute it
> to do accesses (I presume?)
> Naturally, this is a really weird thing to do, because even if the API
> is threadsafe such that it doesn't crash and reads/writes are
> serialised, the sequencing of reads/writes will be random, so I don't
> believe any sane person (let alone an expert) would write this
> program... but moving on.
> Then you wait for them to finish, and close the file.
> 
> Fine. You have a file with randomly interleaved data... for whatever
> reason.

I'd expect almost every nontrivial multithreaded program to do this. It's 
called a log file.

You don't need to read data pointed at by a log file, but you do need to 
read the FILE* or the file descriptor.

Database-like things using a journal file might need a shared file for 
both reading and writing.

> So, you call closeFile immediately and read/write start returning null.

You start threads. You give them access to the log file. You wait for the 
threads to exit. Then you close the file.


Re: shared - i need it to be useful

2018-10-21 Thread Nicholas Wilson via Digitalmars-d

On Sunday, 21 October 2018 at 09:58:18 UTC, Walter Bright wrote:

On 10/20/2018 11:08 AM, Nicholas Wilson wrote:
You can if no-one else writes to it, which is the whole point 
of Manu's proposal. Perhaps it should be const shared instead 
of shared but still.


There is no purpose whatsoever to data that can be neither read 
nor written.


Indeed but there is a subtle difference between that and Manu's 
proposal: access through the shared variable may not have 
non-atomic reads, not no reads.


Shared data is only useful if, at some point, it is 
read/written,


Yes


presumably by casting it to unshared in @trusted code.


That is one way to do it, others include atomics  and other 
@trusted primitives


As soon as that is done, you've got a data race with the other 
existing unshared aliases.


You're in @trusted code, that is the whole point. The onus is on 
the programmer to make that correct, same with regular 
@safe/@trusted@system code.




Re: We need an internal keyword.

2018-10-21 Thread luckoverthere via Digitalmars-d

On Sunday, 21 October 2018 at 03:17:23 UTC, 12345swordy wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


I feel like if this is a problem your Module has too much in it 
and you should refactor it into more than 1 module. If you need 
to protect a module from itself then I feel like there is too 
much in it, essentially.


Re: D Binding to GUI libraries [was Interesting Observation from JAXLondon]

2018-10-21 Thread welkam via Digitalmars-d

On Saturday, 20 October 2018 at 16:37:07 UTC, Atila Neves wrote:
I've also realised that there are parts of C++ that are 
probably unstranslatable no matter what I do.


This can be solved with good gui. It need to look like meld on 
linux where original cpp and translated d files are side by side 
and parts of untranslatable code visibly marked so the user can 
translate it by hand.


Re: We need an internal keyword.

2018-10-21 Thread Basile B. via Digitalmars-d

On Sunday, 21 October 2018 at 03:17:23 UTC, 12345swordy wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


I partially agree because Object Pascal uses `strict private` for 
this. IIRC they needed at some point to make this for their 
Objective-C compatibility. I find it occasionally useful for 
example to enforce the usage of the getters method over their 
matching fields (if they do lazy update, lazy init, or such 
things). So far in D the way to do this is to put the stuff that 
has to be strictly private (or internal if you prefer) in a 
dedicated module.


This suggestion comes semi-regularly on the forum and last time 
it did, the whole topic got very unfriendly so while i partially 
agree i have to say that i don't really care. It's a small 
sympathetic feature, but i can live without.


Baz.


Re: shared - i need it to be useful

2018-10-21 Thread Simen Kjærås via Digitalmars-d
On Sunday, 21 October 2018 at 13:24:49 UTC, Stanislav Blinov 
wrote:

On Sunday, 21 October 2018 at 11:25:16 UTC, aliak wrote:
When I say ok, I mean assuming the implementer actually wrote 
correct code. This applies to any shared method today as well.


This ("ok") can only be achieved if the "implementor" (the 
"expert") writes every function self-contained, at which point 
sharing something from user code becomes a non-issue (i.e. it 
becomes unnecessary). But that's not a very useful API. As soon 
as you have more than one function operating on the same data, 
the onus is on the user (the caller) to call those functions in 
correct order, or, more generally, without invalidating the 
state of shared data.


The onus is *always* on the user to write function calls in the 
correct order, multi-threading or not. We expect programmers to 
be able to figure out why this doesn't print 'Hello world!':


void main() {
import std.stdio;
string hello;
writeln(hello);
hello = "Hello world!";
}

We also expect writeln to be written in such a way that it 
doesn't corrupt random data or cause life-threatening situations 
just because hello was uninitialized upon calling writeln, and 
assigned afterwards. We should expect the same of multi-threaded 
programs.


This places the onus of writing thread-safe code on the writer of 
the multi-threaded equivalent of writeln and string.opAssign. 
Only this way can the user of the library write code and not 
expect things to blow up in their face.


--
  Simen


Re: Truly @nogc Exceptions?

2018-10-21 Thread welkam via Digitalmars-d

On Thursday, 20 September 2018 at 10:48:35 UTC, Atila Neves wrote:
What's the fix? Have the compiler insert a call to the 
exception's destructor at the end of the `catch(scope 
Exception)` block.


If I understood you correctly then we have same idea. If 
exception is not handled or re thrown then scope "exits" trough 
scope(failure) in which case no deallocation should be performed 
and only if scope "exits" trough scope(success), meaning 
exception/s were handled, destructors need to be called.


To make exceptions nogc we need destructors that are aware of how 
scope was exited like:


~ this(exit) ( ) {}
~ this(success) ( ) {}
~ this(failure) ( ) {}

With this its easy to make all exceptions nogc


Re: shared - i need it to be useful

2018-10-21 Thread Simen Kjærås via Digitalmars-d
On Sunday, 21 October 2018 at 12:45:43 UTC, Stanislav Blinov 
wrote:

On Sunday, 21 October 2018 at 05:47:14 UTC, Manu wrote:
On Sat, Oct 20, 2018 at 10:10 AM Stanislav Blinov via 
Digitalmars-d  wrote:


Synchronized with what? You still have `a`, which isn't 
`shared` and doesn't require any atomic access or 
synchronization. At this point it doesn't matter if it's an 
int or a struct. As soon as you share `a`, you can't just 
pretend that reading or writing `a` is safe.


`b` can't read or write `a`... accessing `a` is absolutely 
safe.


It's not, with or without your proposal. The purpose of sharing 
`a` into `b` is to allow someone to access `*a` in a threadsafe 
way (but un-@safe, as it *will* require casting away `shared` 
from `b`). That is what's making keeping an unshared reference 
`a` un-@safe: whoever accesses `*a` in their @trusted 
implementations via `*b` can't know that `*a` is being 
(@safe-ly!) accessed in a non-threadsafe way at the same time.


Then someone has not done their job. Since the pieces of code 
that will actually use the un-@safe building blocks at the bottom 
are few and far between, it is reasonable to assume that an 
expert will be writing this code, and that such code be placed in 
a separate module where all access to the shared type is 
controlled.


It seems you expect regular users to have calls to atomicOp!"++" 
scattered all over their code. I find this an unreasonable 
expectation, and fully agree that this will lead to problems.



Someone must do something unsafe to undermine your 
threadsafety... and
if you write unsafe code and don't know what you're doing, 
there's

nothing that can help you.


Ergo, it follows that anyone that is making an implicit cast 
from mutable to shared better know what they're doing, which 
mere mortal users (not "experts") might not. I.e. it's a way to 
giving a loaded gun to someone who never held a weapon before.


No.


Close does not promise threadsafety itself (but of course, it 
doesn't violate read/write's promise, or the program is 
invalid).


Yep, and that's the issue. It SHALL NOT violate threadsafety, 
but it can't promise such in any way :(


Can you demonstrate any system that can promise something like 
that? (apart from all-immutable)



read and write will appropriately check their file-open state 
each time they perform their actions.


Why? The only purpose of giving someone a `shared` reference is 
to give a reference to an open file. `shared` references can't 
do anything with the file but read and write, they would expect 
to be able to do so.


Because otherwise it's not thread-safe. Exactly as you point out, 
the owner could call closeFile before some other thread was 
finished writing. If the implementer of FileHandle fails to take 
this into account, then no, it's not thread-safe.



I'm going to assume that `shareWithThreads()` was implemented  
by an
'expert' who checked the function results for errors. It was 
detected that the reads/write failed, and an error "failed to 
read file" was emit, then the function returned promptly.

The uncertainty of what happens in this program is however
`shareWithThreads()` handles read/write emitting an error.


But you can only find out about these errors in 
`waitForThreads`, the very call that the user "forgot" to make!


Of course not. You can throw exceptions, you could add a 
destructor that reports on these errors, you could set an error 
flag somewhere and check that every now and then. The fact that 
you've managed to write a horribly broken API under MP and can't 
see a way to do better inside that system does not necessarily 
mean the problem is with MP.


--
  Simen


Re: shared - i need it to be useful

2018-10-21 Thread Simen Kjærås via Digitalmars-d

On Sunday, 21 October 2018 at 09:58:18 UTC, Walter Bright wrote:

On 10/20/2018 11:08 AM, Nicholas Wilson wrote:
You can if no-one else writes to it, which is the whole point 
of Manu's proposal. Perhaps it should be const shared instead 
of shared but still.


There is no purpose whatsoever to data that can be neither read 
nor written. Shared data is only useful if, at some point, it 
is read/written, presumably by casting it to unshared in 
@trusted code. As soon as that is done, you've got a data race 
with the other existing unshared aliases.


No, because every part of the public interface has to work 
together to ensure thread-safety.


This code is invalid (but compiles) under MP:

module A;
struct S {
private int n;
void foo() @safe {
n--; // Not thread-safe
}
void bar() shared @trusted {
atomicOp!"++"(n.assumeUnshared);
}
}

module B;
import A;
void passToOtherThread(shared(S)*); // Calls S.bar()

void main() {
S* s = new S();
passToOtherThread(s);
s.foo();
}

The reason: foo() breaks bar()s promise of thread-safety. This 
means that S does not provide a thread-safe interface. It would 
be nice if the compiler could statically notice that, but I don't 
see how that'd work.


Now, for a thread-safe version:

module A;
struct S {
int n;
void foo() @trusted {
atomicOp!"--"(n); // Thread-safe
}
void bar() shared @trusted {
atomicOp!"++"(n.assumeUnshared);
}
}

module B;
import A;
void passToOtherThread(shared(S)*); // Calls S.bar()

void main() {
S* s = new S();
passToOtherThread(s);
s.foo();
}

In this case, passToOtherThread is free to call S.bar as often as 
it may feel like, since atomic operations are used in every 
possible access to S.n. This is true even though one thread has 
unshared access and other threads have shared access.


--
  Simen


Re: shared - i need it to be useful

2018-10-21 Thread Simen Kjærås via Digitalmars-d

On Sunday, 21 October 2018 at 09:50:09 UTC, Walter Bright wrote:

On 10/20/2018 11:24 AM, Manu wrote:

This is an unfair dismissal.


It has nothing at all to do with fairness. It is about what the 
type system guarantees in @safe code. To repeat, the current 
type system guarantees in @safe code that T* and shared(T)* do 
not point to the same memory location.


Does your proposal maintain that or not? It's a binary question.


No. Instead, it proposes something more useful: once cast to 
shared(T)*, only thread-safe operations may be performed on it.




> int* a;
> shared(int)* b = a;

This is not safe.


Under MP, this is perfectly safe - you can do nothing with a 
shared(int)*, except call un-@safe, non-thread-safe functions on 
it, which will *fail to compile* under @safe.




 Manu's Proposal ---
@safe:
int i;
int* a = &i;
StartNewThread(a); // Compiles! Coder has no idea!

... in the new thread ...
void StartOfNewThread(shared(int)* b) {

... we have two threads accessing 'i',
one thinks it is shared, the other unshared,
and StartOfNewThread() has no idea and anyone
writing code for StartOfNewThread() has no way
to know anything is wrong ...

lockedIncrement(b);  // Data Race!
}


Someone's messed up if they've marked lockedIncrement @safe - 
under MP, it shouldn't be. lockedIncrement is a very low-level 
piece of functionality, and should be @system. It also shouldn't 
take a shared(int)*, but a int*, forcing an unsafe cast and 
making it obvious the code is un@safe.


--
  Simen


Re: shared - i need it to be useful

2018-10-21 Thread Stanislav Blinov via Digitalmars-d

On Sunday, 21 October 2018 at 11:25:16 UTC, aliak wrote:
On Saturday, 20 October 2018 at 16:41:41 UTC, Stanislav Blinov 
wrote:
Those are not "ok". They're only "ok" under Manu's proposal so 
long as the author of C promises (via documentation) that 
that's indeed "ok". There can be no statically-enforced 
guarantees that those calls are "ok", or that issuing them in 
that order is "ok". Yet Manu keeps insisting that somehow 
there is.


No he is not insisting you can statically enforce thread safety.


I stand corrected, it would seem so.

When I say ok, I mean assuming the implementer actually wrote 
correct code. This applies to any shared method today as well.


This ("ok") can only be achieved if the "implementor" (the 
"expert") writes every function self-contained, at which point 
sharing something from user code becomes a non-issue (i.e. it 
becomes unnecessary). But that's not a very useful API. As soon 
as you have more than one function operating on the same data, 
the onus is on the user (the caller) to call those functions in 
correct order, or, more generally, without invalidating the state 
of shared data.


Re: shared - i need it to be useful

2018-10-21 Thread Stanislav Blinov via Digitalmars-d

On Sunday, 21 October 2018 at 05:47:14 UTC, Manu wrote:
On Sat, Oct 20, 2018 at 10:10 AM Stanislav Blinov via 
Digitalmars-d  wrote:


Synchronized with what? You still have `a`, which isn't 
`shared` and doesn't require any atomic access or 
synchronization. At this point it doesn't matter if it's an 
int or a struct. As soon as you share `a`, you can't just 
pretend that reading or writing `a` is safe.



`b` can't read or write `a`... accessing `a` is absolutely safe.


It's not, with or without your proposal. The purpose of sharing 
`a` into `b` is to allow someone to access `*a` in a threadsafe 
way (but un-@safe, as it *will* require casting away `shared` 
from `b`). That is what's making keeping an unshared reference 
`a` un-@safe: whoever accesses `*a` in their @trusted 
implementations via `*b` can't know that `*a` is being 
(@safe-ly!) accessed in a non-threadsafe way at the same time.


Someone must do something unsafe to undermine your 
threadsafety... and
if you write unsafe code and don't know what you're doing, 
there's

nothing that can help you.


Ergo, it follows that anyone that is making an implicit cast from 
mutable to shared better know what they're doing, which mere 
mortal users (not "experts") might not. I.e. it's a way to giving 
a loaded gun to someone who never held a weapon before.



Today, every interaction with shared is unsafe.


Nod.

Creating a safe interaction with shared will lead to people not 
doing unsafe things at every step.


Triple nod.


Encapsulate it all you want, safety only remains a
contract of convention, the language can't enforce it.


You're talking about @trusted code again. You're fixated on 
unsafe interactions... my proposal is about SAFE interactions. 
I'm trying to obliterate unsafe interactions with shared.


I know... Manu, I *know* what you're trying to do. We (me, Atila, 
Timon, Walter...) are not opposing your goals, we're pointing out 
the weakest spot of your proposal, which, it would seem, would 
require more changes to the language than just disallowing 
reading/writing `shared` members.



module expertcode;

@safe:

struct FileHandle {
 @safe:

 void[] read(void[] storage) shared;
 void[] write(const(void)[] buffer) shared;
}

FileHandle openFile(string path);
// only the owner can close
void closeFile(ref FileHandle);

void shareWithThreads(shared FileHandle*); // i.e. generate a
number of jobs in some queue
void waitForThreads(); // waits until all
processing is done

module usercode;

import expertcode;

void processHugeFile(string path) {
 FileHandle file = openFile(path);
 shareWithThreads(&file);// implicit cast
 waitForThreads();
 file.closeFile();
}


This is a very strange program...


Why? That's literally the purpose of being able to `share`: you 
create/acquire a resource, share it, but keep a non-`shared` 
reference to yourself. If that's not required, you'd just create 
the data `shared` to begin with.


I'm dubious it is in fact "expertcode"... but let's look into 
it.


You're fixating on it being file now. I give an abstract example, 
you dismiss it as contrived, I give a concrete one, you want to 
dismiss it as "strange".


Heh, replace 'FileHandle' with 'BackBuffer', 'openFile' with 
'acquireBackBuffer', 'shareWithThreads' with 
'generateDrawCommands', 'waitForThreads' with 
'gatherCommandsAndDraw', 'closeFile' with 'postProcessAndPresent' 
;)


File handle seems to have just 2 methods... and they are both 
threadsafe. Open and Close are free-functions.


It doesn't matter if they're free functions or not. What matters 
is signature: they're taking non-`shared` (i.e. 'owned') 
reference. Methods are free functions in disguise.


Close does not promise threadsafety itself (but of course, it 
doesn't violate read/write's promise, or the program is 
invalid).


Yep, and that's the issue. It SHALL NOT violate threadsafety, but 
it can't promise such in any way :(


I expect the only possible way to achieve this is by an 
internal mutex to make sure read/write/close calls are 
serialised.


With that particular interface, yes.

read and write will appropriately check their file-open state 
each time they perform their actions.


Why? The only purpose of giving someone a `shared` reference is 
to give a reference to an open file. `shared` references can't do 
anything with the file but read and write, they would expect to 
be able to do so.


What read/write do in the case of being called on a closed 
file... anyones guess? I'm gonna say they do no-op... they 
return a null pointer to indicate the error state.


Looking at the meat of the program; you open a file, and 
distribute it to do accesses (I presume?)


Naturally, this is a really weird thing to do, because even if 
the API is threadsafe such that it doesn't crash and 
reads/writes are
serialised, the sequencing of reads/writes will be random, so I 
don't believe any sane person (let alone an expert) would w

Re: D Binding to GUI libraries [was Interesting Observation from JAXLondon]

2018-10-21 Thread Andre Pany via Digitalmars-d
On Sunday, 21 October 2018 at 01:32:22 UTC, Nick Sabalausky 
(Abscissa) wrote:

On 10/20/18 6:28 AM, Gregor Mückl wrote:


Even though web and mobile UIs seem to be the rage at the 
moment, I believe a solid support for desktop UIs is very 
important for a general purpose language, if it wants to be 
successful in the market.


I think that may be doubly true in the case of D, given D's 
focus on efficiency. HTML-based interfaces (whether web or app) 
are notoriously rife with inefficiencies: That's likely to be a 
major turn-off for exactly the very same audiences that D would 
appeal to most.


While talking about bindings, do not forget Delphi. It has still 
a good eco system. Combining Delphi's advanced Runtime reflection 
capabilities with D's advanced compile reflection capabilities 
opens this eco system.


I created a proof of concept and the results were really 
promising. Using Delphi components is very easy and the wrapper 
code on D side is very thin.


Even clicking together a Firemonkey ui in Delphi and writing all 
code in D works fine.


Delphi is available for windows,  Mac os,  Android and IPhone. 
Linux support is somehow planned. It is free for personal use.


See an example here 
https://github.com/andre2007/delta-fmx-10-2-1/blob/master/examples/gui1/source/app.d


Due to very limited time resources I have no time to work on this 
specific topic at the moment but everyone is free to use these 
base research results.


Side remark: Lazarus (free pascal) is planning to add the same 
advanced Runtime reflection capabilities as Delphi.


Kind regards
Andre


Re: shared - i need it to be useful

2018-10-21 Thread aliak via Digitalmars-d
On Saturday, 20 October 2018 at 16:41:41 UTC, Stanislav Blinov 
wrote:
Those are not "ok". They're only "ok" under Manu's proposal so 
long as the author of C promises (via documentation) that 
that's indeed "ok". There can be no statically-enforced 
guarantees that those calls are "ok", or that issuing them in 
that order is "ok". Yet Manu keeps insisting that somehow there 
is.


No he is not insisting you can statically enforce thread safety.

When I say ok, I mean assuming the implementer actually wrote 
correct code. This applies to any shared method today as well.




Re: More zero-initialization optimizations pending in std.experimental.allocator?

2018-10-21 Thread Per Nordlöw via Digitalmars-d

On Saturday, 20 October 2018 at 15:10:38 UTC, Nathan S. wrote:
are there more zero-initializations that can be optimized in 
std.experimental.allocator?


I looked and identified low-hanging fruit in 
std.mutation.initializeAll & moveEmplace and in 
std.typecons.RefCounted (PR #6698), and in 
std.conv.emplaceInitializer (PR #6461).


What did you search for to find these?

Other opportunities would rely on being able to identify if 
it's ever more efficient to write `memset(&x, 0, 
typeof(x).sizeof)` instead of `x = typeof(x).init` which seems 
like the kind of optimization that belongs in the compiler 
instead.


So in which cases is `memset` faster than assignment?

Thanks!


Re: shared - i need it to be useful

2018-10-21 Thread Stanislav Blinov via Digitalmars-d

On Sunday, 21 October 2018 at 09:58:18 UTC, Walter Bright wrote:

On 10/20/2018 11:08 AM, Nicholas Wilson wrote:
You can if no-one else writes to it, which is the whole point 
of Manu's proposal. Perhaps it should be const shared instead 
of shared but still.


There is no purpose whatsoever to data that can be neither read 
nor written. Shared data is only useful if, at some point, it 
is read/written, presumably by casting it to unshared in 
@trusted code. As soon as that is done, you've got a data race 
with the other existing unshared aliases.


Just a thought: if a hard requirement is made on `shared` data to 
be non-copyable, a @safe conversion could be guaranteed. But it 
can't be implicit either:


shared(T) share(T)(T value) if (!is(T == shared) && 
!isCopyable!T) {

shared(T) result = move(value);
return result;
}

struct ShareableData {
@disable ; // Generated by 
compiler in presence of `shared` members and/or `shared` methods


/* ... */
}

void sendToThread(T)(shared T* ptr) @safe;

void usage() @safe {
int x;
sendToThread(&x); // Error: 'x' is not shared
shared y = x; // Ok
sendToThread(&y); // Ok


ShareableData data;
sendToThread(&data); // Error: 'data' is not shared
auto p = &data;
sendToThread(p); // Error: *p is not shared

auto sharedData = share(move(data));
sendToThread(&sharedData); // Ok

auto yCopy = y;   // Error: cannot copy 'shared' y
auto dataCopy = sharedData; // Error: cannot copy 'shared' 
sharedData


ShareableData otherData;
sendToThread(cast(shared(ShareableData)*) &otherData); // 
Error non-@safe cast in @safe code

}

And again, we're back to 'once it's shared, it can't be @safe-ly 
unshared', which ruins the distinction between owned and shared 
references, which is one of the nicer properties that Manu's 
proposal seems to want to achieve :(


Re: D Binding to GUI libraries [was Interesting Observation from JAXLondon]

2018-10-21 Thread Jacob Carlborg via Digitalmars-d

On 2018-10-20 11:25, Russel Winder wrote:


GtkD works very well for me. But I guess GTK+ has a reputation of not
working on Windows and macOS. Once a reputation is established it is
nigh on impossible to refute.


As has been stated elsewhere, it's working on Windows and macOS but 
looks very alien on macOS. When I was in school I wrote a program using 
C# (Mono) and GTK on macOS. GTK seemed to be the best alternative (for 
using with Mono) back then. During the development of that program a 
beta or alpha version of GTK was released with support for a native main 
menu on macOS, the rest was non-native. Not sure how it looks like now.


--
/Jacob Carlborg


Re: D Binding to GUI libraries

2018-10-21 Thread Jacob Carlborg via Digitalmars-d

On 2018-10-21 09:33, Russel Winder wrote:


The SWT framework is being replaced with JavaFX, so should D forget DWT
and do something similar?


Where do you get that idea? SWT (and therefore DWT) is using the native 
drawing operations of the OS.


No, D should not forget DWT. It's one of the few (they only?) D GUI 
toolkit that has a native look and feel.


--
/Jacob Carlborg


Re: D Binding to GUI libraries [was Interesting Observation from JAXLondon]

2018-10-21 Thread Jacob Carlborg via Digitalmars-d

On 2018-10-21 03:25, Nick Sabalausky (Abscissa) wrote:


What about DWT? It seemed pretty good from what I could tell, though I
still haven't ventured into D GUIs just yet myself. Are there issues
people have with DWT? Or WxD?


DWT is currently stuck at SWT version 3.4 and no macOS version is 
available yet. I'm working on a tool that will automatically port the 
Java code that will hopefully fix this.


--
/Jacob Carlborg


Re: shared - i need it to be useful

2018-10-21 Thread Walter Bright via Digitalmars-d

On 10/20/2018 11:08 AM, Nicholas Wilson wrote:
You can if no-one else writes to it, which is the whole point of Manu's 
proposal. Perhaps it should be const shared instead of shared but still.


There is no purpose whatsoever to data that can be neither read nor written. 
Shared data is only useful if, at some point, it is read/written, presumably by 
casting it to unshared in @trusted code. As soon as that is done, you've got a 
data race with the other existing unshared aliases.




Re: shared - i need it to be useful

2018-10-21 Thread rikki cattermole via Digitalmars-d

On 21/10/2018 10:41 PM, Manu wrote:
On Sun., 21 Oct. 2018, 2:05 am Walter Bright via Digitalmars-d, 
mailto:digitalmars-d@puremagic.com>> wrote:


On 10/20/2018 11:30 AM, Manu wrote:
 > You can write an invalid program in any imaginable number of ways;
 > that's just not an interesting discussion.

What we're discussing is not an invalid program, but what guarantees
the type
system can provide.

D's current type system guarantees that a T* and a shared(T)* do not
point to
the same memory location in @safe code.


My proposal guarantees that too, but in a more interesting way, because 
it opens the door to a whole working model. And it's totally @safe.


To get them to point to the same memory location, you've got to dip
into @system
code, where *you* become responsible for maintaining the guarantees.


My model preserves that property. Why do you think I'm running that 
static guarantee?


It's all irrelevant if you don't express any mechanism to *do* anything. 
Shared today does not have any use. It simply expresses that data *is* 
shared, and says nothing about what you can do with it.
If you don't express a safe mechanism for interacting with shared data, 
then simply expressing the distinction of shared data really is 
completely uninteresting.
It's just a marker that's mixed up in a bunch of unsafe code. I'm no 
more satisfied than I am with C++.


Shared needs to do something; I propose that it strictly models 
operations that are threadsafe and semantic restrictions required to 
support that, and then you have a *usage* scheme, which is safe, and API 
conveys proper interaction.. not just an uninteresting marker.


I'm genuinely amazed that you're not intrigued by a @safe shared 
proposition. Nobly likes @safe more than you.


I could run our entire SMP stack 100% @safe.

I am going to fork D with this feature one way or another. It's the most 
meaningful and compelling opportunity I've seen in ever. If there's ever 
been a single thing that could truly move a bunch of C++ programmers, 
this is it. C++ can do a crappy job of modelling most stuff in D, but it 
simply can't go anywhere near this, and I've been working on competing 
C++ models for months.
SMP is the future, we're going all-in this generation. Almost every 
function in our codebase runs in an SMP environment... And I was 
staggered that I was able to work this definition through to such a 
simple and elegant set of rules.
I can't get my head around why people aren't more excited about this... 
fully @safe SMP is huge!


I'm excited, but you need to write a DIP even if preliminary which shows 
both new semantics but also shows both working and current code to 
compare them.




Re: shared - i need it to be useful

2018-10-21 Thread Walter Bright via Digitalmars-d

On 10/20/2018 11:24 AM, Manu wrote:

This is an unfair dismissal.


It has nothing at all to do with fairness. It is about what the type system 
guarantees in @safe code. To repeat, the current type system guarantees in @safe 
code that T* and shared(T)* do not point to the same memory location.


Does your proposal maintain that or not? It's a binary question.


I'm not sure you've understood the proposal.
This is the reason for the implicit conversion. It provides safe
transition.


I don't see any way to make an implicit T* to shared(T)* safe, or vice versa. 
The T* code can create more aliases that the conversion doesn't know about, and 
the shared(T)* code can hand out aliases to other threads. So it all falls to 
pieces. Using a 'scope' qualifier won't work, because 'scope' isn't transitive, 
while shared is, i.e. U** and shared(U*)*.


> I'm not sure how to clarify it, what can I give you?

Write a piece of code that does such an implicit conversion that you argue is 
@safe. Make the code as small as possible. Your example:


> int* a;
> shared(int)* b = a;

This is not safe.

 Manu's Proposal ---
@safe:
int i;
int* a = &i;
StartNewThread(a); // Compiles! Coder has no idea!

... in the new thread ...
void StartOfNewThread(shared(int)* b) {

... we have two threads accessing 'i',
one thinks it is shared, the other unshared,
and StartOfNewThread() has no idea and anyone
writing code for StartOfNewThread() has no way
to know anything is wrong ...

lockedIncrement(b);  // Data Race!
}
--- Current D ---
@safe:
int i;
int* a = &i;
StartNewThread(a);   // Danger, Will Robinson! Does Not Compile!
StartNewThread(cast(shared(int)*) a) // Danger, Will Robinson!
 // Unsafe Cast! Does Not Compile!
---

Your proposal means that the person writing the lockedIncrement(), which is a 
perfectly reasonable thing to do, simply cannot write it in a way that has a 
@safe interface, because the person writing the lockedIncrement() library 
function has no way to know that the data it receives is actually unshared data.


I.e. @trusted code is obliged to proved a safe interface. Your proposal makes 
that impossible because the compiler would allow unshared data to be implicitly 
typed as shared.


Re: shared - i need it to be useful

2018-10-21 Thread Manu via Digitalmars-d
On Sun., 21 Oct. 2018, 2:05 am Walter Bright via Digitalmars-d, <
digitalmars-d@puremagic.com> wrote:

> On 10/20/2018 11:30 AM, Manu wrote:
> > You can write an invalid program in any imaginable number of ways;
> > that's just not an interesting discussion.
>
> What we're discussing is not an invalid program, but what guarantees the
> type
> system can provide.
>
> D's current type system guarantees that a T* and a shared(T)* do not point
> to
> the same memory location in @safe code.
>

My proposal guarantees that too, but in a more interesting way, because it
opens the door to a whole working model. And it's totally @safe.

To get them to point to the same memory location, you've got to dip into
> @system
> code, where *you* become responsible for maintaining the guarantees.
>

My model preserves that property. Why do you think I'm running that static
guarantee?

It's all irrelevant if you don't express any mechanism to *do* anything.
Shared today does not have any use. It simply expresses that data *is*
shared, and says nothing about what you can do with it.
If you don't express a safe mechanism for interacting with shared data,
then simply expressing the distinction of shared data really is completely
uninteresting.
It's just a marker that's mixed up in a bunch of unsafe code. I'm no more
satisfied than I am with C++.

Shared needs to do something; I propose that it strictly models operations
that are threadsafe and semantic restrictions required to support that, and
then you have a *usage* scheme, which is safe, and API conveys proper
interaction.. not just an uninteresting marker.

I'm genuinely amazed that you're not intrigued by a @safe shared
proposition. Nobly likes @safe more than you.

I could run our entire SMP stack 100% @safe.

I am going to fork D with this feature one way or another. It's the most
meaningful and compelling opportunity I've seen in ever. If there's ever
been a single thing that could truly move a bunch of C++ programmers, this
is it. C++ can do a crappy job of modelling most stuff in D, but it simply
can't go anywhere near this, and I've been working on competing C++ models
for months.
SMP is the future, we're going all-in this generation. Almost every
function in our codebase runs in an SMP environment... And I was staggered
that I was able to work this definition through to such a simple and
elegant set of rules.
I can't get my head around why people aren't more excited about this...
fully @safe SMP is huge!

>


Re: shared - i need it to be useful

2018-10-21 Thread Simen Kjærås via Digitalmars-d

On Sunday, 21 October 2018 at 09:04:34 UTC, Walter Bright wrote:

On 10/20/2018 11:30 AM, Manu wrote:
You can write an invalid program in any imaginable number of 
ways;

that's just not an interesting discussion.


What we're discussing is not an invalid program, but what 
guarantees the type system can provide.


D's current type system guarantees that a T* and a shared(T)* 
do not point to the same memory location in @safe code.


To get them to point to the same memory location, you've got to 
dip into @system code, where *you* become responsible for 
maintaining the guarantees.


The only difference between this and Manu's proposal is when you 
need to dip into @system code - in MP it's perfectly fine for the 
pointers to be equal, but when you want to read from or write to 
the address, you'll need to use @system. In other words, the dip 
into @system happens deeper in the codebase, meaning more code 
can be @safe.


--
  Simen


Re: shared - i need it to be useful

2018-10-21 Thread Walter Bright via Digitalmars-d

On 10/20/2018 11:30 AM, Manu wrote:

You can write an invalid program in any imaginable number of ways;
that's just not an interesting discussion.


What we're discussing is not an invalid program, but what guarantees the type 
system can provide.


D's current type system guarantees that a T* and a shared(T)* do not point to 
the same memory location in @safe code.


To get them to point to the same memory location, you've got to dip into @system 
code, where *you* become responsible for maintaining the guarantees.


Re: We need an internal keyword.

2018-10-21 Thread Laurent Tréguier via Digitalmars-d

On Sunday, 21 October 2018 at 03:17:23 UTC, 12345swordy wrote:
So that classes can share some of their variables but not 
others in a module.


IE.

class A
{
internal int A; //This is shared in the module
private int B; // But not this.
}

No need to reintroduce the "Friend" feature from cpp.


This is by design; the D way of dealing with this would be to 
split the module into a package with multiple modules. The A 
class would be in its own module, and use `package` where you 
used `internal` so that other modules in the same package can 
have access to it.
Using a package.d package module 
(https://dlang.org/spec/module.html#package-module), you can 
still use the multiple modules just as if they were a single 
module.


Instead of a source tree like this:

source
|
+-some
  |
  +-thing.d

You'd end up with a source tree like this:

source
|
+-some
  |
  +-thing
|
+-package.d
|
+-a.d
|
+-rest_of_the_stuff.d

Where package.d publicly imports a.d and rest_of_the_stuff.d, so 
`import some.thing` would still work.


Re: D Binding to GUI libraries

2018-10-21 Thread Paolo Invernizzi via Digitalmars-d

On Sunday, 21 October 2018 at 07:33:45 UTC, Russel Winder wrote:

The GTK/Qt battle on Linux was won by GTK+2 hence GNOME over 
KDE as the default for Debian and Fedora. Whether this was 
right or wrong is left as a choice for the reader!


Linux is not only the desktop, and Qt simply dominates in 
industrial, medical and automation sector, that's where the money 
is.


Qt is pushing strongly on the embedded marked, bare metal or 
linux (kernel) based...


- Paolo


Re: Interesting Observation from JAXLondon

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/21/18 1:47 AM, Joakim wrote:


Simple, C++ is increasingly seen as irrelevant by those choosing a new 
language, so D's real competition is now Go, Rust, Swift, Nim, Zig, etc. 
These are people who want to write "fast code fast," well except for 
Rust users, who value ownership more.


Never confuse "relevancy" with "buzz".

Most of worst ideas in this industry stem from the hipsters who can't 
figure out there's a difference.


Re: D Binding to GUI libraries

2018-10-21 Thread Nick Sabalausky (Abscissa) via Digitalmars-d

On 10/21/18 3:33 AM, Russel Winder wrote:

On Sat, 2018-10-20 at 21:25 -0400, Nick Sabalausky (Abscissa) via
Digitalmars-d wrote:

I've heard a lot of very good things about GtkD, and honestly, I have
no
doubts about any of it. Unfortunately though, the main problem with
GtkD
is simply GTK itself :(


The GTK/Qt battle on Linux was won by GTK+2 hence GNOME over KDE as the
default for Debian and Fedora. Whether this was right or wrong is left
as a choice for the reader!


That's pure nonsense: It's Linux - unless one option actually goes away 
(KDE is still actively used and developed), then there's no such thing 
as one "winning" over the other.


It IS a big problem that far too many people (mainly developers coming 
directly from the Windows world who have decided to half-ass a Linux 
port) have decided to erroneously equate "Linux" with "GTK-based DE" 
these days, but that's a far cry from saying that GTK/GNOME/Unity "won 
out" over Qt/KDE.



I think GTK+3 is actually really quite nice, somewhat nicer than Qt.
However if D had a Qt binding in play as good as the GtkD binding is to
GTK+, then maybe I could be convinced to use Qt. No way am I going to
use C++ for desktop GUI applications, and Rust is the only other option
just now.


Programmers writing GUI apps often like GTK. Nobody else does. From a 
programmer standpoint, it may very well be nice. But that's irrelevant, 
because from the user standpoint, GTK is, and has always been, a 
steaming pool of diarrhea, even if you ARE using GNOME/Unity.


Re: D Binding to GUI libraries

2018-10-21 Thread Russel Winder via Digitalmars-d
On Sat, 2018-10-20 at 21:25 -0400, Nick Sabalausky (Abscissa) via
Digitalmars-d wrote:
> […]
> 
> And KDE.

Not entirely true, you can run KDE application on a GNOME system, and I
assume GNOME application on a KDE system.

> I've heard a lot of very good things about GtkD, and honestly, I have
> no 
> doubts about any of it. Unfortunately though, the main problem with
> GtkD 
> is simply GTK itself :(

The GTK/Qt battle on Linux was won by GTK+2 hence GNOME over KDE as the
default for Debian and Fedora. Whether this was right or wrong is left
as a choice for the reader!

I think GTK+3 is actually really quite nice, somewhat nicer than Qt.
However if D had a Qt binding in play as good as the GtkD binding is to
GTK+, then maybe I could be convinced to use Qt. No way am I going to
use C++ for desktop GUI applications, and Rust is the only other option
just now.

[…]
> 
> What about DWT? It seemed pretty good from what I could tell, though
> I 
> still haven't ventured into D GUIs just yet myself. Are there issues 
> people have with DWT? Or WxD?

The SWT framework is being replaced with JavaFX, so should D forget DWT
and do something similar? If yes the QtE5 or dqml are the way forward
since the QML engine of Qt is the equivalent of JavaFX.

Putting effort into wxD is the same sort of effort needed for either
qtD or dqt, would it be better to back Qt or wxWidgets? 

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



signature.asc
Description: This is a digitally signed message part


Re: D Binding to GUI libraries [was Interesting Observation from JAXLondon]

2018-10-21 Thread Russel Winder via Digitalmars-d
On Sat, 2018-10-20 at 16:37 +, Atila Neves via Digitalmars-d wrote:
> […]
> 
> It turns out that translating C++ is *hard*. Partly because the 
> language is huge and complicated, but also partly because 
> libclang isn't all it's cracked up to be. But... dpp is probably 
> a few full work days away from being to #include . 
> Hopefully with the translation actually working.

This I can believe, but isn't the D-side problem only to be able to
link to C++ libraries. Given previous emails this morning, clearly my
current thoughts are creating D bindings for Qt and wxWidgets. 

> […]
> 
> * std::is_reference is untranslatable: there are no reference 
> types in D. It's likely to get used with SFINAE, and while that 
> is translatable by hand, I have no idea how I'd write an 
> algorithm to figure out SFINAE when it happens and translate that 
> to template constraints in D.

From what I hear at ACCU conferences, most C++ programmers can't handle
SFINAE properly.

-- 
Russel.
===
Dr Russel Winder  t: +44 20 7585 2200
41 Buckmaster Roadm: +44 7770 465 077
London SW11 1EN, UK   w: www.russel.org.uk



signature.asc
Description: This is a digitally signed message part


  1   2   >