Re: Mallocator and 'shared'

2017-02-13 Thread Kagamin via Digitalmars-d-learn

On Sunday, 12 February 2017 at 20:08:05 UTC, bitwise wrote:
Given that both the data and the method are 'shared', a caller 
should know that race conditions are possible and that they 
should aquire a lock before accessing either of them...or so it 
would seem.


Thread unsafe methods shouldn't be marked shared, it doesn't make 
sense. If you don't want to provide thread-safe interface, don't 
mark methods as shared, so they will not be callable on a shared 
instance and thus the user will be unable to use the shared 
object instance and hence will know the object is thread unsafe 
and needs manual synchronization.


ps Memory barriers are a bad idea because they don't defend from 
a race condition, but they look like they do :) use 
std.concurrency for a simple and safe concurrency, that's what 
it's made for.


Alias type with different initialiser.

2017-02-13 Thread Bastiaan Veelo via Digitalmars-d-learn

Hi,

In Extended Pascal, you can derive from a basic type and change 
the default initialiser like so:


  type int1 = integer value 1;
  var i : int1;
  ii : int1 value 2;
  assert(i = 1);
  assert(ii = 2);

I have it working in D, but it seems a little clumsy. Is there a 
better way?



  struct initial(T, T val)
  {
  private T _payload = val;
  alias _payload this;

  static initial opCall(T v)
  {
  initial s;
  s._payload = v;
  return s;
  }
  }

  unittest
  {
  alias initial!(int, 1) int1;
  int1 i;
  assert(i == 1);
  int1 ii = 2;
  assert(ii == 2);
  }



Re: Alias type with different initialiser.

2017-02-13 Thread Daniel Kozak via Digitalmars-d-learn

Dne 13.2.2017 v 16:28 Bastiaan Veelo via Digitalmars-d-learn napsal(a):


Hi,

In Extended Pascal, you can derive from a basic type and change the 
default initialiser like so:


  type int1 = integer value 1;
  var i : int1;
  ii : int1 value 2;
  assert(i = 1);
  assert(ii = 2);

I have it working in D, but it seems a little clumsy. Is there a 
better way?



  struct initial(T, T val)
  {
  private T _payload = val;
  alias _payload this;

  static initial opCall(T v)
  {
  initial s;
  s._payload = v;
  return s;
  }
  }

  unittest
  {
  alias initial!(int, 1) int1;
  int1 i;
  assert(i == 1);
  int1 ii = 2;
  assert(ii == 2);
  }


https://dlang.org/phobos/std_typecons.html#.Typedef


Re: Alias type with different initialiser.

2017-02-13 Thread Daniel Kozak via Digitalmars-d-learn

Dne 13.2.2017 v 17:40 Daniel Kozak napsal(a):


Dne 13.2.2017 v 16:28 Bastiaan Veelo via Digitalmars-d-learn napsal(a):


Hi,

In Extended Pascal, you can derive from a basic type and change the 
default initialiser like so:


  type int1 = integer value 1;
  var i : int1;
  ii : int1 value 2;
  assert(i = 1);
  assert(ii = 2);

I have it working in D, but it seems a little clumsy. Is there a 
better way?



  struct initial(T, T val)
  {
  private T _payload = val;
  alias _payload this;

  static initial opCall(T v)
  {
  initial s;
  s._payload = v;
  return s;
  }
  }

  unittest
  {
  alias initial!(int, 1) int1;
  int1 i;
  assert(i == 1);
  int1 ii = 2;
  assert(ii == 2);
  }


https://dlang.org/phobos/std_typecons.html#.Typedef

or you can use Proxy

https://dlang.org/phobos/std_typecons.html#.Proxy

struct initial(T, T val)
{
  private T _payload = val;
  mixin Proxy!_payload;
  this(T v)
  {
_payload = v;
  }
}

unittest
{
  alias initial!(int, 1) int1;
  int1 i;
  assert(i == 1);
  int1 ii = 2;
  assert(ii == 2);
}


Re: Mallocator and 'shared'

2017-02-13 Thread Moritz Maxeiner via Digitalmars-d-learn

On Monday, 13 February 2017 at 14:20:05 UTC, Kagamin wrote:
Thread unsafe methods shouldn't be marked shared, it doesn't 
make sense. If you don't want to provide thread-safe interface, 
don't mark methods as shared, so they will not be callable on a 
shared instance and thus the user will be unable to use the 
shared object instance and hence will know the object is thread 
unsafe and needs manual synchronization.


To be clear: While I might, in general, agree that using shared 
methods only for thread safe methods seems to be a sensible 
restriction, neither language nor compiler require it to be so; 
and absence of evidence of a useful application is not evidence 
of absence.


On Monday, 13 February 2017 at 14:20:05 UTC, Kagamin wrote:
ps Memory barriers are a bad idea because they don't defend 
from a race condition, but they look like they do :)


There are two very common pitfalls in non-sequential programming 
with regards to reads/writes to memory shared between threads:
Issue 1: Sequencing/Interleaving of several threads into the 
logical memory access order

Issue 2: Reordering of code within one thread

Code that changes semantics because of issue 1 has race 
conditions; fixing it requires synchronization primitives, such 
as locking opcode, transactional memory, etc.


Code that changes semantics because of issue 2 may or may not 
have race conditions, but it definitely requires memory barriers.


Claiming that memory barriers are a bad idea because they don't 
defend against race conditions, but look like they do (when 
that's what synchronization is for) is similar enough to saying 
airbags in cars are a bad idea because they don't keep your body 
in place, but look like they do (when that's what seat belts are 
for).
My point here being that I don't understand what made you state 
that memory barriers look like they deal with race conditions, as 
they have nothing to do with that.


To be clear: Synchronization (the fix for race conditions) does 
not help you to deal with issue 2. If my last example had instead 
been


---
__gshared int f = 0, x = 0;
Object monitor;

// thread 1
synchronized (monitor) while (f == 0);
// Memory barrier required here
synchronized (monitor) writeln(x)

// thread 2
synchronized (monitor) x = 42;
// Memory barrier required here
synchronized (monitor) f = 1;
---

you'd still need those memory barriers. Also note that the 
synchronization in the above is not needed in terms of semantics. 
The code has no race conditions, all permutations of the 
(interleaved) memory access order yield the same output from 
thread 1. Also, since synchronization primitives and memory 
barriers have different runtime costs, depending on your hardware 
support and how they are translated to that support from D, 
there's no "one size fits all" solution on the low level we're on 
here.


My opinion on the matter of `shared` emitting memory barriers is 
that either the spec and documentation[1] should be updated to 
reflect that sequential consistency is a non-goal of `shared` 
(and if that is decided this should be accompanied by an example 
of how to add memory barriers yourself), or it should be 
implemented. Though leaving it in the current "not implemented, 
no comment / plan on whether/when it will be implemented" state 
seems to have little practical consequence - since no one seems 
to actually work on this level in D - and I can thus understand 
why dealing with that is just not a priority.


On Monday, 13 February 2017 at 14:20:05 UTC, Kagamin wrote:
use std.concurrency for a simple and safe concurrency, that's 
what it's made for.


I agree, message passing is considerably less tricky and you're 
unlikely to shoot yourself in the foot. Nonetheless, there are 
valid use cases where the overhead of MP may not be acceptable.


[1] https://dlang.org/faq.html#shared_guarantees


Re: Alias type with different initialiser.

2017-02-13 Thread Bastiaan Veelo via Digitalmars-d-learn

On Monday, 13 February 2017 at 16:40:02 UTC, Daniel Kozak wrote:

https://dlang.org/phobos/std_typecons.html#.Typedef


Thanks for the pointers. Both Typedef and Proxy create types that 
don't mix with the base type, which I want to the contrary. So I 
guess I'll go with


struct Initial(T, T val)
{
private T _payload = val;
alias _payload this;

static Initial opCall(T v)
{
Initial s;
s._payload = v;
return s;
}

static T init()
{
return val;
}
}

unittest
{
alias Initial!(int, 1) int1;
int1 i;
assert(i == 1);
int1 ii = 2;
assert(ii == 2);
assert(ii.init == 1);
assert(int1.init == 1);

void f(int val)
{
assert(val == 1);
}
f(i);

int i0;
assert(i0 == 0);
i = i0;
assert(i == 0);
assert(i.init == 1);
i0 = ii;
assert(i0 == 2);
assert(i0.init == 0);
}



Re: Alias type with different initialiser.

2017-02-13 Thread John Colvin via Digitalmars-d-learn

On Monday, 13 February 2017 at 22:16:36 UTC, Bastiaan Veelo wrote:

On Monday, 13 February 2017 at 16:40:02 UTC, Daniel Kozak wrote:

https://dlang.org/phobos/std_typecons.html#.Typedef


Thanks for the pointers. Both Typedef and Proxy create types 
that don't mix with the base type, which I want to the 
contrary. So I guess I'll go with


Why not use a constructor instead of static opCall? Also, it's 
generally a bad idea to define `.init` for any type as code 
generally expects this to be the compiler-generated property 
(e.g. a value of type Initial!(int, 1) not of type int). So, 
perhaps like this:


struct Initial(T, T val)
{
private T _payload = val;
alias _payload this;
this(T v)
{
_payload = v;
}
enum initial = val;
}

unittest
{
alias Initial!(int, 1) int1;
static assert(int1.initial == 1); // typeof(int1.initial) == 
int
static assert(int1.init == 1); // typeof(int1.init) == 
typeof(int1)

int1 i;
assert(i == 1);
int1 ii = 2;
assert(ii == 2);
assert(ii.init == 1);
assert(int1.init == 1);

void f(int val)
{
assert(val == 1);
}
f(i);

int i0;
assert(i0 == 0);
i = i0;
assert(i == 0);
assert(i.init == 1);
i0 = ii;
assert(i0 == 2);
assert(i0.init == 0);
}


Creating an array of immutable objects

2017-02-13 Thread David Zhang via Digitalmars-d-learn

Hi,

I have a struct with two immutable members, and I want to make an 
array of them. How do I to this? I'm using allocators for this.


string[] paths;

struct FileDesc {
immutable string path;
immutable uint index;
}

_fileDesc = /*something*/;

You can't use alloc.makeArray because it requires a range with 
which to initialize the array, and while I can produce an array 
of paths, I don't know how to merge both a range of paths and 
indices. Lockstep doesn't work.


I also tried using emplace and an allocated byte array, but it 
gave me random values and was (I think) unnecessarily 
complicated. What am I missing?


Re: Creating an array of immutable objects

2017-02-13 Thread Ali Çehreli via Digitalmars-d-learn

On 02/13/2017 04:59 PM, David Zhang wrote:


I have a struct with two immutable members, and I want to make an array
of them. How do I to this? I'm using allocators for this.


I realize that I misunderstood you; see below for a mutable array.

The following code produces an immutable array through the use of the 
misplaced std.exception.assumeUnique. (Why is it in std.exception? :) )


import std.stdio;
import std.algorithm;
import std.range;

string[] paths = [ "hello", "world" ];

struct FileDesc {
immutable string path;
immutable uint index;
}

immutable(FileDesc[]) _fileDesc;

FileDesc[] makeFileDescs(string[] paths) pure {
return paths.enumerate!uint.map!(t => FileDesc(t[1], t[0])).array;
}

static this() {
import std.exception : assumeUnique;
auto fd = makeFileDescs(paths);
_fileDesc = assumeUnique(fd);
}

void main() {
_fileDesc.each!writeln;
}

A mutable array is simpler:

import std.stdio;
import std.algorithm;
import std.range;

string[] paths = [ "hello", "world" ];

struct FileDesc {
immutable string path;
immutable uint index;
}

FileDesc[] _fileDesc;

FileDesc[] makeFileDescs(string[] paths) pure {
return paths.enumerate!uint.map!(t => FileDesc(t[1], t[0])).array;
}

static this() {
_fileDesc = makeFileDescs(paths);
}

void main() {
_fileDesc.each!writeln;
}

Ali



Re: Alias type with different initialiser.

2017-02-13 Thread John Colvin via Digitalmars-d-learn

On Monday, 13 February 2017 at 22:59:11 UTC, John Colvin wrote:

[ snip ]


sorry, made a typo, that should have been


alias int1 = Initial!(int, 1);
static assert(int1.initial == 1); // typeof(int1.initial) 
== int

static assert(int1.init == 1); // typeof(int1.init) == int1




Policy-based design in D

2017-02-13 Thread TheGag96 via Digitalmars-d-learn
Tonight I stumbled upon Andrei's concept of policy-based design 
(https://en.wikipedia.org/wiki/Policy-based_design) and tried to 
implement their example in D with the lack of multiple 
inheritance in mind.


https://dpaste.dzfl.pl/adc05892344f (btw, any reason why 
certificate validation on dpaste fails right now?)


The implementation isn't perfect, as I'm not sure how to check 
members of mixin templates so that you  could verify whether 
print() and message() are actually where they should be. How 
would you do that? Is there any use for this kind of thing in D, 
and if so, what would it be? I've hardly dabbled in OOP patterns, 
but the abstraction seems kinda interesting.


Re: Policy-based design in D

2017-02-13 Thread Daniel Kozak via Digitalmars-d-learn



Dne 14.2.2017 v 07:48 TheGag96 via Digitalmars-d-learn napsal(a):
https://dpaste.dzfl.pl/adc05892344f (btw, any reason why certificate 
validation on dpaste fails right now?)
Because certificate is expired, dpaste use certs from Lets Encrypt which 
has short time of validity
I have same issue in the past with my websites, now I am using cron to 
keep it updated
1  0   *   *   *   certbot renew --nginx 
--keep-until-expiring