Re: How to implement Canceleable spawn() from parent

2020-06-28 Thread Ali Çehreli via Digitalmars-d-learn

On 6/28/20 4:08 PM, aberba wrote:

So I checked receiveTimeout() when I was looking for what I could use. I 
wish there was an example in the docs.


https://dlang.org/library/std/concurrency/receive_timeout.html


I have an example of it:

  http://ddili.org/ders/d.en/concurrency.html#ix_concurrency.receiveTimeout

Ali


Re: reference variables don't exist, but can simulate them

2020-06-28 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 29 June 2020 at 02:11:15 UTC, NonNull wrote:

Deprecation: Cannot use alias this to partially initialize 
variable j of type refer. Use j._()


This is for the line j=3

What is this about? Where does this hidden rule come from?


That one comes from [1]. But there are quite a few more "hidden" 
rules that you're violating here. Try putting @safe on your main 
and compiling with -preview=dip1000 (for dmd, refer to your 
compiler's help if you're using others). The bulk of escape 
analysis is only done for @safe, and only with that DIP enabled 
(IIRC only some trivial checks are done otherwise).


[1] https://issues.dlang.org/show_bug.cgi?id=19441


Re: reference variables don't exist, but can simulate them

2020-06-28 Thread NonNull via Digitalmars-d-learn

On Sunday, 28 June 2020 at 21:01:36 UTC, NonNull wrote:

On Sunday, 28 June 2020 at 20:59:59 UTC, NonNull wrote:

Using gdc (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0
Please criticize:

struct refer(T) {
  T* ptr;
  this(ref T x) { ptr =  }
  ref T _() { return *ptr; }
  alias _ this;
  string toString() { import std.conv; return to!string(*ptr);
 }
}

This will make a reference variable (simulation). [ toString() 
is just for writeln. ]


void main() {
int i = 100;
refer!int j = i;
j = 3;
writeln(i);
i = 100;
writeln(j);
j += 3;
writeln(i);
refer!int k = j;
writeln(k);
}

And a refer!int can be returned as it is just a value. 
Returning one that contains a pointer to a local variable 
leads to a compilation error.


* does not lead to a compilation error


Now with a different compiler I this:

Deprecation: Cannot use alias this to partially initialize 
variable j of type refer. Use j._()


This is for the line j=3

What is this about? Where does this hidden rule come from?



[DIP1000] Something I don't quite understand regarding 'scope'

2020-06-28 Thread Stanislav Blinov via Digitalmars-d-learn

void local(Args...)(Args args)
{
}

void main() @safe
{
import std.stdio;
scope int* p;
local(p);   // Ok
writeln(p); // Error: scope variable p assigned to non-scope 
parameter _param_0 calling std.stdio.writeln!(int*).writeln

}

The signatures of `std.stdio.writeln` and `local` are the same 
(see `writeln` [1]). Yet, with '$ dmd -preview=dip1000' the call 
to `local` compiles, while the call to `writeln` doesn't.


Is that an instance of [2]?

[1] 
https://github.com/dlang/phobos/blob/v2.092.1/std/stdio.d#L3865

[2] https://issues.dlang.org/show_bug.cgi?id=20023


Re: How to implement Canceleable spawn() from parent

2020-06-28 Thread aberba via Digitalmars-d-learn

On Sunday, 28 June 2020 at 23:39:07 UTC, Stanislav Blinov wrote:

On Sunday, 28 June 2020 at 23:02:26 UTC, aberba wrote:


I believe this:

StopWatch sw;
sw.start;

works becuse D structs are initialized by default, right?
I've never actually done it this way. Little details.


Yup. You can also do a

auto sw = StopWatch(AutoStart.yes);

and not have to call `start` explicitly.


Interesting. I should look into Phobos more.


Re: How to implement Canceleable spawn() from parent

2020-06-28 Thread Stanislav Blinov via Digitalmars-d-learn

On Sunday, 28 June 2020 at 23:02:26 UTC, aberba wrote:


I believe this:

StopWatch sw;
sw.start;

works becuse D structs are initialized by default, right?
I've never actually done it this way. Little details.


Yup. You can also do a

auto sw = StopWatch(AutoStart.yes);

and not have to call `start` explicitly.


Re: How to implement Canceleable spawn() from parent

2020-06-28 Thread aberba via Digitalmars-d-learn

On Sunday, 28 June 2020 at 23:02:26 UTC, aberba wrote:

On Sunday, 28 June 2020 at 14:23:01 UTC, Stanislav Blinov wrote:

On Sunday, 28 June 2020 at 13:29:08 UTC, aberba wrote:

 Thanks.

I believe this:

StopWatch sw;
sw.start;


works becuse D structs are initialized by default, right?
I've never actually done it this way. Little details.


So I checked receiveTimeout() when I was looking for what I could 
use. I wish there was an example in the docs.


https://dlang.org/library/std/concurrency/receive_timeout.html


Re: How to implement Canceleable spawn() from parent

2020-06-28 Thread aberba via Digitalmars-d-learn

On Sunday, 28 June 2020 at 14:23:01 UTC, Stanislav Blinov wrote:

On Sunday, 28 June 2020 at 13:29:08 UTC, aberba wrote:

 Thanks.

I believe this:

StopWatch sw;
sw.start;


works becuse D structs are initialized by default, right?
I've never actually done it this way. Little details.


Re: foreach iterator with closure

2020-06-28 Thread Denis via Digitalmars-d-learn

To keep this reply brief, I'll just summarize:

Lots of great takeaways from both of your posts, and a handful of 
topics you mentioned that I need to dig into further now. This is 
great (I too like D :)


I very much appreciate the extra insight into how things work and 
why certain design decisions were made: for me, this is essential 
for gaining fluency in a language.


Thanks again for all your help!
Denis


Re: reference variables don't exist, but can simulate them

2020-06-28 Thread NonNull via Digitalmars-d-learn

On Sunday, 28 June 2020 at 20:59:59 UTC, NonNull wrote:

Using gdc (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0
Please criticize:

struct refer(T) {
  T* ptr;
  this(ref T x) { ptr =  }
  ref T _() { return *ptr; }
  alias _ this;
  string toString() { import std.conv; return to!string(*ptr);  
}

}

This will make a reference variable (simulation). [ toString() 
is just for writeln. ]


void main() {
int i = 100;
refer!int j = i;
j = 3;
writeln(i);
i = 100;
writeln(j);
j += 3;
writeln(i);
refer!int k = j;
writeln(k);
}

And a refer!int can be returned as it is just a value. 
Returning one that contains a pointer to a local variable leads 
to a compilation error.


* does not lead to a compilation error



reference variables don't exist, but can simulate them

2020-06-28 Thread NonNull via Digitalmars-d-learn

Using gdc (Ubuntu 8.4.0-1ubuntu1~18.04) 8.4.0
Please criticize:

struct refer(T) {
  T* ptr;
  this(ref T x) { ptr =  }
  ref T _() { return *ptr; }
  alias _ this;
  string toString() { import std.conv; return to!string(*ptr);  }
}

This will make a reference variable (simulation). [ toString() is 
just for writeln. ]


void main() {
int i = 100;
refer!int j = i;
j = 3;
writeln(i);
i = 100;
writeln(j);
j += 3;
writeln(i);
refer!int k = j;
writeln(k);
}

And a refer!int can be returned as it is just a value. Returning 
one that contains a pointer to a local variable leads to a 
compilation error.







Re: foreach iterator with closure

2020-06-28 Thread Ali Çehreli via Digitalmars-d-learn

On 6/28/20 9:07 AM, Denis wrote:

> * foreach is the actual iterator,

Yes. foreach is "lowered" to the following equivalent:

  for ( ; !range.empty; range.popFront()) {
// Use range.front here
  }

A struct can support foreach iteration through its opCall() member 
function as well. opCall() takes the body of the foreach as a delegate. 
Because it's a function call, it can take full advantage of the function 
call stack. This may help with e.g. writing recursive iteration algorithms.



http://ddili.org/ders/d.en/foreach_opapply.html#ix_foreach_opapply.opApply

> the instantiation of a struct is the
> range.

Yes.

> * When a constructor is not used, the arguments in the call to
> instantiate the range (in this case, `hello` in letters(`hello`)) are
> mapped sequentially to the member variables in the struct definition
> (i.e. to letters.str).

Yes, that is a very practical struct feature. I write my structs with as 
little as needed and provide a constructor only when it is necessary as 
in your case.


> * When a constructor is used, the member variables in the struct
> definition are in essence private.

Not entirely true. You can still make them public if you want.

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

> The arguments in the call to
> instantiate the range are now mapped directly to the parameters in the
> definition of the "this" function.

Yes.

> * The syntax and conventions for constructors is difficult and
> non-intuitive for anyone who hasn't learned Java (or a derivative).

C++ uses the name of the class as the constructor:

// C++ code
struct S {
  S(); // <-- Constructor
  S(int);  // <-- Another one
};

The problem with that syntax is having to rename more than one thing 
when the name of struct changes e.g. to Q:


struct Q {
  Q();
  Q(int);
};

And usually in the implementation:

Q::Q() {}
Q::Q(int) {}

D's choice of 'this' is productive.

> The
> linked document provides a simplified explanation for the "this"
> keyword, which is helpful for the first read:
> https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html.

I like searching for keywords in my index. The "this, constructor" here 
links to the constructor syntax:


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

> * In some respects, the Java syntax is not very D-like. (For example, it
> breaks the well-established convention of "Do not use the same name to
> mean two different things".)

Yes but it competes with another goal: Change as little code as possible 
when one thing needs to be changed. This is not only practical but helps 
with correctness.


> However, it does need to be learned,
> because it is common in D source code.

I like D. :p

> Here is the complete revised code for the example (in condensed form):
>
>import std.stdio;
>
>struct letters {
>
>  string str;
>  int pos = 1;// Assign here or in this())
>
>  this(string param1) {// cf. shadow str
>str = param1;// cf. this.str = param1 / this.str = str
>writeln(`BEGIN`); }
>
>  char front() { return str[pos]; }
>  void popFront() { pos ++; }
>  bool empty() { return pos == str.length; }
>
>  ~this() { writeln("\nEND"); }}
>
>void main() {
>  foreach (letter; letters(`hello`)) {
>write(letter, ' '); }}
>
> At this point, I do have one followup question:
>
> Why is the shadow str + "this.str = str" the more widely used syntax in
> D, when the syntax in the code above is unambiguous?

Because one needs to come up with names like "param7", "str_", "_str", 
"s", etc. I like and follow D's standard here.


> One possible reason that occurred to me is that "str = param1" might
> require additional GC, because they are different names.

Not at all because there is not memory allocation at all. strings are 
implemented as the equivalent of the following struct:


struct __D_native_string {
  size_t length_;
  char * ptr;
  // ...
}

So, the "str = param1" assignment is nothing but two 64 bit data 
transfer, which can easily by optimized away by the compiler in many cases.


> But I wouldn't
> think it'd make any difference to the compiler.

Yes. :)

>
> Denis

Ali



Re: std.concurrency.receive and shared const(char)[]?

2020-06-28 Thread BakedPineapple via Digitalmars-d-learn

On Sunday, 28 June 2020 at 16:39:12 UTC, Anonymouse wrote:

On Sunday, 28 June 2020 at 16:11:50 UTC, BakedPineapple wrote:

import std.stdio;
import std.concurrency;

void main()
{
auto t = spawn((){
receive((shared const(char)[] char_arr) {
ownerTid.send(true);
});
});
shared const(char)[] char_arr = "cut my code into pieces";
t.send(char_arr);
assert(receiveOnly!(bool) == true);
}

When I run this program, it blocks on the receive() inside the 
spawned thread. What am I doing wrong?


Make the parameter shared(const(char))[] and it will work. I'll 
leave it to someone who knows more to explain why it behaves 
that way.


ty.


Re: std.concurrency.receive and shared const(char)[]?

2020-06-28 Thread Anonymouse via Digitalmars-d-learn

On Sunday, 28 June 2020 at 16:11:50 UTC, BakedPineapple wrote:

import std.stdio;
import std.concurrency;

void main()
{
auto t = spawn((){
receive((shared const(char)[] char_arr) {
ownerTid.send(true);
});
});
shared const(char)[] char_arr = "cut my code into pieces";
t.send(char_arr);
assert(receiveOnly!(bool) == true);
}

When I run this program, it blocks on the receive() inside the 
spawned thread. What am I doing wrong?


Make the parameter shared(const(char))[] and it will work. I'll 
leave it to someone who knows more to explain why it behaves that 
way.


std.concurrency.receive and shared const(char)[]?

2020-06-28 Thread BakedPineapple via Digitalmars-d-learn

import std.stdio;
import std.concurrency;

void main()
{
auto t = spawn((){
receive((shared const(char)[] char_arr) {
ownerTid.send(true);
});
});
shared const(char)[] char_arr = "cut my code into pieces";
t.send(char_arr);
assert(receiveOnly!(bool) == true);
}

When I run this program, it blocks on the receive() inside the 
spawned thread. What am I doing wrong?


Re: foreach iterator with closure

2020-06-28 Thread Denis via Digitalmars-d-learn
Many thanks: your post has helped me get past the initial 
stumbling blocks I was struggling with. I do have a followup 
question.


First, here are my conclusions up to this point, based on your 
post above, some additional experimentation, and further research 
(for future reference, and for any other readers).


* foreach is the actual iterator, the instantiation of a struct 
is the range.
* When a constructor is not used, the arguments in the call to 
instantiate the range (in this case, `hello` in letters(`hello`)) 
are mapped sequentially to the member variables in the struct 
definition (i.e. to letters.str).
* When a constructor is used, the member variables in the struct 
definition are in essence private. The arguments in the call to 
instantiate the range are now mapped directly to the parameters 
in the definition of the "this" function.
* The syntax and conventions for constructors is difficult and 
non-intuitive for anyone who hasn't learned Java (or a 
derivative). The linked document provides a simplified 
explanation for the "this" keyword, which is helpful for the 
first read: 
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html.
* In some respects, the Java syntax is not very D-like. (For 
example, it breaks the well-established convention of "Do not use 
the same name to mean two different things".) However, it does 
need to be learned, because it is common in D source code.


Here is the complete revised code for the example (in condensed 
form):


  import std.stdio;

  struct letters {

string str;
int pos = 1;// Assign here or in this())

this(string param1) {   // cf. shadow str
  str = param1; // cf. this.str = param1 / this.str = str
  writeln(`BEGIN`); }

char front() { return str[pos]; }
void popFront() { pos ++; }
bool empty() { return pos == str.length; }

~this() { writeln("\nEND"); }}

  void main() {
foreach (letter; letters(`hello`)) {
  write(letter, ' '); }}

At this point, I do have one followup question:

Why is the shadow str + "this.str = str" the more widely used 
syntax in D, when the syntax in the code above is unambiguous?


One possible reason that occurred to me is that "str = param1" 
might require additional GC, because they are different names. 
But I wouldn't think it'd make any difference to the compiler.


Denis


Re: Temporary File Creation

2020-06-28 Thread Per Nordlöw via Digitalmars-d-learn

On Monday, 22 June 2020 at 23:53:41 UTC, Stanislav Blinov wrote:
tempDir just returns a path (i.e. "/tmp" or whatever it is on 
Windows, etc.), it doesn't create anything.


Given the synopsis of std.file, a procedure for *creating* a 
file doesn't belong there, as it would only be half of an 
operation.


There is a https://dlang.org/library/std/stdio/file.tmpfile.html


Thanks.


Re: How to implement Canceleable spawn() from parent

2020-06-28 Thread Stanislav Blinov via Digitalmars-d-learn

On Sunday, 28 June 2020 at 13:29:08 UTC, aberba wrote:


Getting error:

Error: template std.concurrency.spawn cannot deduce function 
from argument types !()(void delegate(Tid id) @system, Tid), 
candidates are:
/usr/include/dmd/phobos/std/concurrency.d(460,5):
spawn(F, T...)(F fn, T args)

  with F = void delegate(Tid) @system,
   T = (Tid)
  must satisfy the following constraint:
   isSpawnable!(F, T)



The error you're getting is because you're passing a pointer to a 
delegate instead of a delegate.



Tid id = spawn(, milliseconds, );

^ here

But fixing that still won't compile, because when you want to 
pass a delegate to `spawn`, it needs to be a shared delegate.


If I understood your intent correctly, here's how you can do it:

import std.stdio : writeln;
import std.concurrency;
import core.thread.osthread : Thread;
import std.datetime.stopwatch;

auto setInterval(long milliseconds, void function() callback)
{
static void worker(Duration d, void function() cb)
{
writeln("Starting ", thisTid, "...");

bool done = false;

StopWatch sw;
sw.start;
while (true)
{
// wait for messages for a timespan of at least `d`
receiveTimeout(
d,
(string text) {
   writeln("Received string: ", text);
   if (text == "cancel")
   done = true;
   });

if (done)
break;

// a non-cancelling message might've been received 
before timeout,

// so test if it's really time for the callback
if (sw.peek >= d)
{
cb();
sw.reset;
}
}
}

Tid id = spawn(, milliseconds.msecs, callback);

return id;
}

void stopInterval(Tid tid) {
send(tid, "cancel");
}

void main()
{
auto tid = setInterval(1000, { writeln("tick"); });
Thread.sleep(2.seconds);
send(tid, "not cancel");
Thread.sleep(5.seconds);
stopInterval(tid);
}


How to implement Canceleable spawn() from parent

2020-06-28 Thread aberba via Digitalmars-d-learn

Trying to implement a setInterval() that I can cancel using:

Tid tid = setInterval(2000, (){ writeln("hello");})

And then I can do:

stopInterval(tid);


With something like this:

stopInterval(Tid tid) {
send(tid, "cancel");
}

import std.stdio : writeln;
import std.concurrency : receive, spawn, thisTid, Tid;

auto setInterval(long milliseconds, void delegate() callback)
{
auto worker(long mls, void delegate() cb)
{
import core.thread.osthread : Thread;
import std.datetime : seconds, msecs;

writeln("Starting ", thisTid, "...");

bool done = false;

receive((string text) {
   writeln("Received string: ", text);
   done = true;
});

do
{
// or receive() comes here?

Thread.sleep(mls.msecs);
cb();
}
while (!done);
}

// I guess issue is with the callback
Tid id = spawn(, milliseconds, );

return id;
}



Getting error:

Error: template std.concurrency.spawn cannot deduce function from 
argument types !()(void delegate(Tid id) @system, Tid), 
candidates are:
/usr/include/dmd/phobos/std/concurrency.d(460,5):spawn(F, 
T...)(F fn, T args)

  with F = void delegate(Tid) @system,
   T = (Tid)
  must satisfy the following constraint:
   isSpawnable!(F, T)


Am I even using the right tool here?


Re: Translating C headers to D: How do I compile it?

2020-06-28 Thread Kirill via Digitalmars-d-learn

On Sunday, 28 June 2020 at 05:13:32 UTC, Mike Parker wrote:

On Sunday, 28 June 2020 at 04:59:12 UTC, Kirill wrote:


something.d:
module something;
int add(int a, int b);


This should be extern(C) int add(int a, int b). The extern(C) 
tells the D compiler to use the standard C calling convention 
when calling that function.




Thanks! It all works now! 'extern(C)' is what was missing.


Re: Light-weight runtime

2020-06-28 Thread aberba via Digitalmars-d-learn

On Sunday, 28 June 2020 at 07:09:53 UTC, Виталий Фадеев wrote:

I want light-weight runtime !

How to ?


If you have access to Google translate or any equivalent tool, 
you may use it to write in Russian language and copy+paste the 
English here. I think that'll really help.


I always give deep respect to people with different native 
languages who're trying really well to write English here. 
Considering someone of us learnt and wrote English in school but 
still suck at it. My biggest problem is typos.



--;;::
Now I think your question was discussed recently here 
https://forum.dlang.org/thread/gxtgbthyytukmqmzp...@forum.dlang.org


dmd release schedule?

2020-06-28 Thread drathier via Digitalmars-d-learn
Is there a release schedule anywhere for DMD? Any list of tasks 
to be the next release? I'm only finding 5+ year old things when 
searching.


Light-weight runtime

2020-06-28 Thread Виталий Фадеев via Digitalmars-d-learn

I want light-weight runtime !

How to ?