Re: question about keeeping reference to toStringz()

2018-05-30 Thread Mike Parker via Digitalmars-d-learn

On Thursday, 31 May 2018 at 01:12:34 UTC, Dr.No wrote:



is foo() is being called from a thread, how I am supposed to 
keep cstring "alive"?


As Jonathan explained, you don't have to worry about it if foo() 
itself doesn't assign the pointer to anything internally. That 
will be the case for most C functions. Well-behaved functions 
that need to keep the string around will copy it. That said, you 
need to be sure you understand fully what any C function you call 
is doing with the strings, or pointers to any memory allocated by 
the GC, that you pass to them.


In the rare cases where the C function does keep the pointer and 
you do need to keep a reference (if you don't have one already), 
the simplest approach is this one:


import core.memory;
GC.addRoot(cstring);

Then, when you no longer need it:
GC.removeRoot(cstring);

https://dlang.org/phobos/core_memory.html#.GC.addRoot





Re: question about keeeping reference to toStringz()

2018-05-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, May 31, 2018 01:12:34 Dr.No via Digitalmars-d-learn wrote:
> On Wednesday, 30 May 2018 at 20:43:48 UTC, Ali Çehreli wrote:
> > On 05/30/2018 01:09 PM, Dr.No wrote:
> > > consider a C function with this prototype:
> > >> void foo(const char *baa);
> > >
> > > Does it means I should do:
> > >> string s = ...;
> > >> auto cstring = s.toStringz;
> > >> foo(cstring);
> > >
> > > rather just:
> > >> foo(s.toStringz);
> > >
> > > ?
> >
> > It depends. cstring method above is not sufficient if cstring's
> > life is shorter than the C library's use:
> >
> > void bar() {
> >
> > string s = ...;
> > auto cstring = s.toStringz;
> > foo(cstring);
> >
> > } // <- cstring is gone
> >
> > What if the library saved that pointer while performing foo()?
> >
> > If cstring is in module-scope or in a container (e.g. an array)
> > that's in module-scope then it's fine. But then, you would have
> > to remove it from that container when the C library does not
> > need that pointer anymore.
> >
> > Ali
>
> is foo() is being called from a thread, how I am supposed to keep
> cstring "alive"?

If it's being passed to foo, then it should be on the stack until foo
returns, in which case, the GC should see it when it scans. It's when foo
could keep a reference to the pointer that you have a problem, since then as
soon as foo returns, the pointer you passed to foo won't be on the stack
anymore. So, in that case, you'd have to store the pointer somewhere in D
code so that the GC will see it when scanning.

Or are you concerned about something like spinning up a thread, calling foo,
and then exiting the thread while foo stores the pointer somewhere? If
that's the case, then you'll need to store the pointer in a shared or
__gshared variable in D code so that you can still refer to it after the
thread terminates.

- Jonathan M Davis




Re: What's the purpose of the 'in' keyword ?

2018-05-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, May 30, 2018 22:16:28 aberba via Digitalmars-d-learn wrote:
> On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote:
> > On Sunday, May 27, 2018 16:28:56 Russel Winder via
> >
> > Digitalmars-d-learn wrote:
> >> On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via
> >> Digitalmars-d-learn
> >
> > - Jonathan M Davis
>
> Jonathan, which font were you using in your DConf powerpoint
> presentation for source code? It made the code look really
> nice...

I'd point you to my reply to Ali, since what he figured out will probably
tell you better than I could.

> and also you have good naming skills.

Thanks. I'm glad that someone thinks so. Naming is pretty much the king of
bikeshedding in programming, and I've been in far too many arguments on that
topic before. Far too often, it seems like no matter what you name
something, someone is going to think that the name is terrible.

- Jonathan M Davis



Re: question about keeeping reference to toStringz()

2018-05-30 Thread Dr.No via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 20:43:48 UTC, Ali Çehreli wrote:

On 05/30/2018 01:09 PM, Dr.No wrote:

> consider a C function with this prototype:
>> void foo(const char *baa);
>
> Does it means I should do:
>
>> string s = ...;
>> auto cstring = s.toStringz;
>> foo(cstring);
>
> rather just:
>
>> foo(s.toStringz);
>
> ?

It depends. cstring method above is not sufficient if cstring's 
life is shorter than the C library's use:


void bar() {
string s = ...;
auto cstring = s.toStringz;
foo(cstring);

} // <- cstring is gone

What if the library saved that pointer while performing foo()?

If cstring is in module-scope or in a container (e.g. an array) 
that's in module-scope then it's fine. But then, you would have 
to remove it from that container when the C library does not 
need that pointer anymore.


Ali


is foo() is being called from a thread, how I am supposed to keep 
cstring "alive"?


Re: What's the purpose of the 'in' keyword ?

2018-05-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, May 30, 2018 15:28:53 Ali Çehreli via Digitalmars-d-learn 
wrote:
> On 05/30/2018 03:16 PM, aberba wrote:
> > On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote:
> >> On Sunday, May 27, 2018 16:28:56 Russel Winder via Digitalmars-d-learn
> >>
> >> wrote:
> >>> On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via
> >>> Digitalmars-d-learn
> >>
> >> - Jonathan M Davis
> >
> > Jonathan, which font were you using in your DConf powerpoint
> > presentation for source code? It made the code look really nice...and
> > also you have good naming skills.
>
> The pdf file has that information in it:
>
>http://www.identifont.com/similar?76H

Well, that's cool - especially since properly telling someone what the font
was is kind of hard anyway, since I used latex to generate the slides, and
you don't normally select a font directly with latex (rather, normally, you
select a font family). I used the beamer package to generate the slides and
the listings package for the code blocks. The code blocks were then
configured to use \ttfamily for the font, so it's whatever gets selected for
the ttfamily family of fonts.

- Jonathan M Davis




Re: Constructing text with astericks

2018-05-30 Thread Adam D. Ruppe via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 22:57:06 UTC, aberba wrote:

How will you approach this problem in D idiomatically?


Well, I never bother with "idiomatically", so I can't speak to 
that, but a simple solution that would work is to realize that 
what you're basically asking for here is a bitmap.


Each letter in your "font" would be a little bitmap that you copy 
into a destination buffer - itself a larger bitmap.


Then, when it is complete, you can draw the destination buffer 
line by line to the screen.


The data for your font may just be a bunch of string arrays in 
source, or an actual bitmap file you create outside the program 
and load at runtime or something like that. Just remember that 
you can't just `buffer ~= letter` - you need to do line by line 
since the two bitmaps will have different sizes.


Re: Constructing text with astericks

2018-05-30 Thread Basile B. via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 22:57:06 UTC, aberba wrote:
I've been given a challenge to write texts using asterisks to 
form the letters. D happen to have an unlimited amount of 
idioms yet i'm out out ideas as to the simplest approach. Task 
is to basically take a piece of text and write them as 
asterisks to the console.


*  *
*  *
*  *
*  *
*  *

First solution I found was to create a class for each 
letter...like new A(), new B() and implement the logic withing 
each class. This doesn't scale and i'll have to write about 24 
or more classes.


Another complex but "makes sense" solution will be to use a 
GRID system like old digital watches but i'll need a more 
complex grid to draw complex letters using a dictionary of 
REPOPULATED indexes of asterisk for each word. First use the 
length of the string to compute the grid size and iterate over 
each character to indentify the dictionary of a letter's 
indexes to use:


*
***
**   **
***
**  ***
**   ***  (an R using a more complex Grid)


How will you approach this problem in D idiomatically?


I'd use an ascii art approach:

- Programatically make bitmaps with each letter rendered using a 
monospaced font.

- use higher order functions to make 2d arrays of ' ' and '*'


Re: Move and CTFE

2018-05-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, May 30, 2018 22:42:13 Q. Schroll via Digitalmars-d-learn 
wrote:
> On Wednesday, 30 May 2018 at 21:02:07 UTC, Jonathan M Davis wrote:
> > On Wednesday, May 30, 2018 20:42:38 Q. Schroll via
> >
> > Digitalmars-d-learn wrote:
> >> It seems one cannot std.algorithm.mutation.move objects
> >> explicitly. Say I have a non-copyable type
> >> [...]
> >> It fails because move() cannot be executed at compile time. The
> >> reason
> >>
> >>  "memcpy cannot be interpreted at compile time, because it
> >>
> >> has
> >> no available source code"
> >> sounds very suspicious.
> >
> > Why is it suspicious? memcpy is a C function, and you can't
> > call C functions during CTFE precisely because the compiler
> > doesn't have their source code. You can't call D functions
> > either if the compiler doesn't have their source (e.g. if
> > you're using a .di file to hide the implementation).
>
> I definitely do understand the error message and it makes sense
> that it fails the way it's implemented. However, it makes no
> sense that moving as a concept can fail at CTFE. That's what I
> find suspicious. [Maybe 'suspicious' isn't the right term; I
> couldn't express it better.] You can move rvalues at CTFE which
> proves that the compiler can do it.
>
> >> Shouldn't it be possible to move at CTFE,
> >> too, or does it mean, non-copyable types are practically
> >> unusable
> >> for CTFE?
> >
> > You can't do much in the way of pointer or memory manipulation
> > during CTFE (e.g. no pointer arithmetic or reinterpret casts).
> > So, I don't see how a move could be done during CTFE. Even if
> > the source for memcpy were available during CTFE, I suspect
> > that it wouldn't be allowed due to the lower level stuff that
> > it does.
>
> That's the explanation why probably all currently possible
> library alternatives to memcpy would fail. I suspected that when
> encountering the error, but still wonder why memcpy or other
> low-level stuff is even necessary to accomplish something the
> compiler is perfectly able to do.
>
>  From what I see, the reason for the hack is lack of
> expressiveness: We don't have rvalue-refs in D (which I find
> good) so, currently, there is no cast-solution as in C++. So for
> a proper move() that works at CTFE, we'd need some specific tool.
>
> I have no idea of the details on how the compiler handles
> lvalues. Would it make sense to add a compiler trait,
> specifically to solve moving? Like __traits(move,
> lvalue_expression) [name up for discussion] that is identical to
> lvalue_expression with the exception that the (lvalue/rvalue)
> flag (or whatever it is) is set to "rvalue". Basically, it's the
> C++ solution: After the "cast", the compiler will proceed and
> pretend it is an rvalue and therefore initiate moving.
>
> Do you think adding a trait to make move() and swap() work at
> CTFE is worth it?
>
> A quick search showed me the class "Expression" has "virtual bool
> isLvalue();" so it might be easy as wrapping and hooking that
> virtual method. To me, [1] highly suggests that it works.
>
> [1]
> https://github.com/dlang/dmd/blob/master/src/dmd/expression.d#L1219

I'm not sure that it really makes sense to worry about fixing stuff like
this in CTFE before newCTFE is actually merged.

For instance, as I understand it, current CTFE can't even really handle
mutation. Rather, it creates a new value every time you mutate a variable.
Don explained to me at one point about how even incrementing a variable
allocates memory so that you then have a new value to use. Stuff like that
is why CTFE is so slow and eats up so much memory. Much as it acts like it's
running your code in a normal fashion, it's really not implemented that way
(the reason that it works the way does having to do with how it grew into
existence out of other features rather than being designed up front). The
current CTFE implementation is incredibly hacky, and it's arguably a miracle
that it can do as much as it can.

newCTFE is taking a very different approach to CTFE, and in theory, it will
fix many of the problems that CTFE currently has, but it's taking Stefan
quite a while to get it to where it needs to be to actually merge it.

- Jonathan M Davis



Constructing text with astericks

2018-05-30 Thread aberba via Digitalmars-d-learn
I've been given a challenge to write texts using asterisks to 
form the letters. D happen to have an unlimited amount of idioms 
yet i'm out out ideas as to the simplest approach. Task is to 
basically take a piece of text and write them as asterisks to the 
console.


*  *
*  *
*  *
*  *
*  *

First solution I found was to create a class for each 
letter...like new A(), new B() and implement the logic withing 
each class. This doesn't scale and i'll have to write about 24 or 
more classes.


Another complex but "makes sense" solution will be to use a GRID 
system like old digital watches but i'll need a more complex grid 
to draw complex letters using a dictionary of REPOPULATED indexes 
of asterisk for each word. First use the length of the string to 
compute the grid size and iterate over each character to 
indentify the dictionary of a letter's indexes to use:


*
***
**   **
***
**  ***
**   ***  (an R using a more complex Grid)


How will you approach this problem in D idiomatically?


Re: Move and CTFE

2018-05-30 Thread Q. Schroll via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 21:02:07 UTC, Jonathan M Davis wrote:
On Wednesday, May 30, 2018 20:42:38 Q. Schroll via 
Digitalmars-d-learn wrote:
It seems one cannot std.algorithm.mutation.move objects 
explicitly. Say I have a non-copyable type

[...]
It fails because move() cannot be executed at compile time. The
reason
 "memcpy cannot be interpreted at compile time, because it 
has

no available source code"
sounds very suspicious.


Why is it suspicious? memcpy is a C function, and you can't 
call C functions during CTFE precisely because the compiler 
doesn't have their source code. You can't call D functions 
either if the compiler doesn't have their source (e.g. if 
you're using a .di file to hide the implementation).


I definitely do understand the error message and it makes sense 
that it fails the way it's implemented. However, it makes no 
sense that moving as a concept can fail at CTFE. That's what I 
find suspicious. [Maybe 'suspicious' isn't the right term; I 
couldn't express it better.] You can move rvalues at CTFE which 
proves that the compiler can do it.



Shouldn't it be possible to move at CTFE,
too, or does it mean, non-copyable types are practically 
unusable

for CTFE?


You can't do much in the way of pointer or memory manipulation 
during CTFE (e.g. no pointer arithmetic or reinterpret casts). 
So, I don't see how a move could be done during CTFE. Even if 
the source for memcpy were available during CTFE, I suspect 
that it wouldn't be allowed due to the lower level stuff that 
it does.


That's the explanation why probably all currently possible 
library alternatives to memcpy would fail. I suspected that when 
encountering the error, but still wonder why memcpy or other 
low-level stuff is even necessary to accomplish something the 
compiler is perfectly able to do.


From what I see, the reason for the hack is lack of 
expressiveness: We don't have rvalue-refs in D (which I find 
good) so, currently, there is no cast-solution as in C++. So for 
a proper move() that works at CTFE, we'd need some specific tool.


I have no idea of the details on how the compiler handles 
lvalues. Would it make sense to add a compiler trait, 
specifically to solve moving? Like __traits(move, 
lvalue_expression) [name up for discussion] that is identical to 
lvalue_expression with the exception that the (lvalue/rvalue) 
flag (or whatever it is) is set to "rvalue". Basically, it's the 
C++ solution: After the "cast", the compiler will proceed and 
pretend it is an rvalue and therefore initiate moving.


Do you think adding a trait to make move() and swap() work at 
CTFE is worth it?


A quick search showed me the class "Expression" has "virtual bool 
isLvalue();" so it might be easy as wrapping and hooking that 
virtual method. To me, [1] highly suggests that it works.


[1] 
https://github.com/dlang/dmd/blob/master/src/dmd/expression.d#L1219




Re: What's the purpose of the 'in' keyword ?

2018-05-30 Thread Ali Çehreli via Digitalmars-d-learn

On 05/30/2018 03:16 PM, aberba wrote:

On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote:
On Sunday, May 27, 2018 16:28:56 Russel Winder via Digitalmars-d-learn 
wrote:

On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via Digitalmars-d-learn


- Jonathan M Davis


Jonathan, which font were you using in your DConf powerpoint 
presentation for source code? It made the code look really nice...and 
also you have good naming skills.





The pdf file has that information in it:

  http://www.identifont.com/similar?76H

Ali


Re: What's the purpose of the 'in' keyword ?

2018-05-30 Thread aberba via Digitalmars-d-learn

On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote:
On Sunday, May 27, 2018 16:28:56 Russel Winder via 
Digitalmars-d-learn wrote:
On Sun, 2018-05-27 at 13:10 +, Adam D. Ruppe via 
Digitalmars-d-learn



- Jonathan M Davis


Jonathan, which font were you using in your DConf powerpoint 
presentation for source code? It made the code look really 
nice...and also you have good naming skills.





Re: Setter chaining

2018-05-30 Thread DigitalDesigns via Digitalmars-d-learn

The above idea can be emulated in code, abiet ugly and useless:

https://dpaste.dzfl.pl/bd118bc1910c




import std.stdio;

struct CT(A,B)
{
A v;
B t;
alias v this;

B opUnary(string s)() if (s == "~")
{
return t;
}

A opUnary(string s)() if (s == "*")
{
return v;
}

}


class C
{
int q;
	CT!(int, typeof(this)) foo() { q = 3; CT!(int, typeof(this)) v; 
v.t = this; v.v = q; return v; }
	CT!(int, typeof(this)) bar(int y) { q = q + y; CT!(int, 
typeof(this)) v; v.t = this; v.v = q; return v; }

}


void main()
{
C c = new C();

auto x = *((~c.foo()).bar(6));



writeln(x);
}

With a language implementation, all one would need is a symbol, 
using #,


everything would simplify to


class C
{
int q;
int foo() { q = 3; return q; }
int bar(int y) { q = q + y; return q;}
}

auto x = c.#foo().bar(6);






Re: no [] operator overload for type Chunks!(char[])

2018-05-30 Thread Malte via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 21:27:44 UTC, Ali Çehreli wrote:

On 05/30/2018 02:19 PM, Malte wrote:
Why does this code complain at the last line about a missing 
[] operator overload?


auto buffer = new char[6];
auto chunked = buffer.chunks(3);
chunked[1][2] = '!';

Same happens with wchar.
Dchar and byte work as expected.


UTF-8 auto decoding strikes again. :)

Even though the original container is char[], passing it 
through Phobos algorithms generated range of dchar. The thing 
is, those dchar elements are generated (decoded from chars) "on 
the fly" as one iterates over the range. Which means, there is 
no array of dchar to speak of, so there is no random access.


Ali


I see. Not what I would have expected, but makes sense for people 
working with UTF-8 strings.


Thanks for the fast answer.


Re: no [] operator overload for type Chunks!(char[])

2018-05-30 Thread Ali Çehreli via Digitalmars-d-learn

On 05/30/2018 02:19 PM, Malte wrote:
Why does this code complain at the last line about a missing [] operator 
overload?


auto buffer = new char[6];
auto chunked = buffer.chunks(3);
chunked[1][2] = '!';

Same happens with wchar.
Dchar and byte work as expected.


UTF-8 auto decoding strikes again. :)

Even though the original container is char[], passing it through Phobos 
algorithms generated range of dchar. The thing is, those dchar elements 
are generated (decoded from chars) "on the fly" as one iterates over the 
range. Which means, there is no array of dchar to speak of, so there is 
no random access.


Ali


no [] operator overload for type Chunks!(char[])

2018-05-30 Thread Malte via Digitalmars-d-learn
Why does this code complain at the last line about a missing [] 
operator overload?


auto buffer = new char[6];
auto chunked = buffer.chunks(3);
chunked[1][2] = '!';

Same happens with wchar.
Dchar and byte work as expected.


Re: Move and CTFE

2018-05-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Wednesday, May 30, 2018 20:42:38 Q. Schroll via Digitalmars-d-learn 
wrote:
> It seems one cannot std.algorithm.mutation.move objects
> explicitly. Say I have a non-copyable type
>
>  struct NoCopy
>  {
>  int payload; // some payload
>  pure nothrow @nogc @safe @disable:
>  this(this); // make it non copyable
>  }
>
> that is being used in a compile-time function evaluation where
> values are being moved.
>
>  int f() pure nothrow @nogc @safe
>  {
>  import std.algorithm.mutation : move;
>  NoCopy nc = NoCopy(1), nc2 = NoCopy(3);
>  nc = move(nc2);
>  return 0;
>  }
>
>  static assert(f() == 0); // trigger CTFE
>
> It fails because move() cannot be executed at compile time. The
> reason
>  "memcpy cannot be interpreted at compile time, because it has
> no available source code"
> sounds very suspicious.

Why is it suspicious? memcpy is a C function, and you can't call C functions
during CTFE precisely because the compiler doesn't have their source code.
You can't call D functions either if the compiler doesn't have their source
(e.g. if you're using a .di file to hide the implementation).

> Shouldn't it be possible to move at CTFE,
> too, or does it mean, non-copyable types are practically unusable
> for CTFE?

You can't do much in the way of pointer or memory manipulation during CTFE
(e.g. no pointer arithmetic or reinterpret casts). So, I don't see how a
move could be done during CTFE. Even if the source for memcpy were available
during CTFE, I suspect that it wouldn't be allowed due to the lower level
stuff that it does.

Maybe the newCTFE stuff that Stefan is working on can do more in this area
(I don't know), but in general, anything that's at all low-level is
forbidden in CTFE.

- Jonathan M Davis



Re: Setter chaining

2018-05-30 Thread DigitalDesigns via Digitalmars-d-learn
On Wednesday, 30 May 2018 at 15:46:36 UTC, Steven Schveighoffer 
wrote:

On 5/30/18 10:49 AM, DigitalDesigns wrote:

Does it sound good?

class X
{
    double x;
    @property X foo(double y) { x = y; return this; }

    @property X bar(double y) { x = y + 5; return this; }
}

void main()
{
 X x = new X();
 x.foo(3).bar(4);
}


It sort of emulates UFCS but I'm not sure if it's more trouble 
than it's worth.



I figure it would be better than just returning void as it 
provides the option to chain but not sure if it will come back 
to bite me.


Yes, I do this kind of stuff, but you need to word your 
functions correctly.


I would avoid @property there, as this implies you should use 
it like:


x.foo = 5;

and if you return a reference to the type itself, it will read 
weird if you do it that way:


auto five = (x.foo = 5);

Here the name of the function is really really important.

In my use case, I am kind of using it in an SQL builder type, 
where each time you call a method it adds some piece of the 
query. Like:


auto query = table.select("id, name").where("foo = 
5").orderBy("name");


-Steve


Well, what I mean is to be able to have the ability to assign 
like a field or a function.



sometimes I might want to use it as a property like

x.foo = 5;

and sometimes like a method

x.foo(5).foo(8);

for chaining.

Rather than having to to create setfoo and such.

Since D allows both syntaxes to be used, rather than returning 
void, turning parenting object allows the chaining to take place.


Since the trick here is to be consistent, all setters must follow 
this principle, it shouldn't be a problem with consistency.




auto five = (x.foo = 5);


I wouldn't do that,just doesn't look right but I see your point.

What would be cool is if D had some special way to return the 
object of the class the setter was in.


auto x = (@x.foo = 5);

Here @ returns x but first computes x.foo = 5;.

In a way, it is like "this". @ gets the "this" of the function. 
Could work on any function:


class Y
{
   void foo();
   @property int baz();
   @property double bar(int x);
}

y.@foo() returns y;
y.@baz() returns y;
y.@bar(3) returns y;

Essentially one could few all functions as returning this and the 
value in a tuple and be default the value is returned and using a 
"selector" character will return this.


class Y
{
   Tuple!(void, typeof(this)) foo();
   Tuple!(int, typeof(this)) baz();
   Tuple!(double, typeof(this)) bar(int x);
}

y.foo()[1] returns y;
...

The compiler could simplify all this and by putting this in a 
register it could be be quite fast. In fact, since these are 
member functions and this is passed it will just fall through so 
very little overhead. The compiler can also optimize the code. 
Might take a bit to verify all the corner cases but would 
probably be useful once people could use it and get used to it.


@, $, |, ?, ! or many symbols could be used without ambiguity 
because a dot will always preceded them.











Move and CTFE

2018-05-30 Thread Q. Schroll via Digitalmars-d-learn
It seems one cannot std.algorithm.mutation.move objects 
explicitly. Say I have a non-copyable type


struct NoCopy
{
int payload; // some payload
pure nothrow @nogc @safe @disable:
this(this); // make it non copyable
}

that is being used in a compile-time function evaluation where 
values are being moved.


int f() pure nothrow @nogc @safe
{
import std.algorithm.mutation : move;
NoCopy nc = NoCopy(1), nc2 = NoCopy(3);
nc = move(nc2);
return 0;
}

static assert(f() == 0); // trigger CTFE

It fails because move() cannot be executed at compile time. The 
reason
"memcpy cannot be interpreted at compile time, because it has 
no available source code"
sounds very suspicious. Shouldn't it be possible to move at CTFE, 
too, or does it mean, non-copyable types are practically unusable 
for CTFE?


Re: question about keeeping reference to toStringz()

2018-05-30 Thread Ali Çehreli via Digitalmars-d-learn

On 05/30/2018 01:09 PM, Dr.No wrote:

> consider a C function with this prototype:
>> void foo(const char *baa);
>
> Does it means I should do:
>
>> string s = ...;
>> auto cstring = s.toStringz;
>> foo(cstring);
>
> rather just:
>
>> foo(s.toStringz);
>
> ?

It depends. cstring method above is not sufficient if cstring's life is 
shorter than the C library's use:


void bar() {
string s = ...;
auto cstring = s.toStringz;
foo(cstring);

} // <- cstring is gone

What if the library saved that pointer while performing foo()?

If cstring is in module-scope or in a container (e.g. an array) that's 
in module-scope then it's fine. But then, you would have to remove it 
from that container when the C library does not need that pointer anymore.


Ali



question about keeeping reference to toStringz()

2018-05-30 Thread Dr.No via Digitalmars-d-learn

The documentation says:

Important Note: When passing a char* to a C function, and the C 
function keeps it around for any reason, make sure that you keep 
a reference to it in your D code. Otherwise, it may become 
invalid during a garbage collection cycle and cause a nasty bug 
when the C code tries to use it.


(from https://dlang.org/library/std/string/to_stringz.html)

consider a C function with this prototype:

void foo(const char *baa);


Does it means I should do:


string s = ...;
auto cstring = s.toStringz;
foo(cstring);


rather just:


foo(s.toStringz);


?


Re: Setter chaining

2018-05-30 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/30/18 10:49 AM, DigitalDesigns wrote:

Does it sound good?

class X
{
    double x;
    @property X foo(double y) { x = y; return this; }

    @property X bar(double y) { x = y + 5; return this; }
}

void main()
{
 X x = new X();
 x.foo(3).bar(4);
}


It sort of emulates UFCS but I'm not sure if it's more trouble than it's 
worth.



I figure it would be better than just returning void as it provides the 
option to chain but not sure if it will come back to bite me.


Yes, I do this kind of stuff, but you need to word your functions correctly.

I would avoid @property there, as this implies you should use it like:

x.foo = 5;

and if you return a reference to the type itself, it will read weird if 
you do it that way:


auto five = (x.foo = 5);

Here the name of the function is really really important.

In my use case, I am kind of using it in an SQL builder type, where each 
time you call a method it adds some piece of the query. Like:


auto query = table.select("id, name").where("foo = 5").orderBy("name");

-Steve


Re: What's the purpose of the 'in' keyword ?

2018-05-30 Thread Q. Schroll via Digitalmars-d-learn

On Sunday, 27 May 2018 at 16:00:15 UTC, Jonathan M Davis wrote:

[...]
Honestly, I'd suggest that folks never use in at this point.
There's zero benefit to it.
[...]


Exactly. If you intend const, just write const. If you intend 
const scope, write const scope.




Setter chaining

2018-05-30 Thread DigitalDesigns via Digitalmars-d-learn

Does it sound good?

class X
{
   double x;
   @property X foo(double y) { x = y; return this; }

   @property X bar(double y) { x = y + 5; return this; }
}

void main()
{
X x = new X();
x.foo(3).bar(4);
}


It sort of emulates UFCS but I'm not sure if it's more trouble 
than it's worth.



I figure it would be better than just returning void as it 
provides the option to chain but not sure if it will come back to 
bite me.






Re: Build interface from abstract class

2018-05-30 Thread DigitalDesigns via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 10:31:27 UTC, Simen Kjærås wrote:

On Monday, 28 May 2018 at 20:13:49 UTC, DigitalDesigns wrote:
I do not think this is a problem in D. Infinite recursion can 
always be terminated with appropriate means.


1. Use attributes. methods in class A should be marked as 
being for the interface. When added to the interface they will 
not have the attribute so will not be picked up again.


2. Your method of function creation does not pick up 
attributes and other factors so it is weak.


Here is my solution that does not solve problem 2:

[Neat stuff]


Neat, but as you say it doesn't handle attributes or UDAs. The 
use of stringof is also a red flag - the same name can apply to 
different types in different scopes, and aliases may confuse 
it. Here's a version that solves both of those issues:



import std.array : join;
import std.meta : ApplyLeft, staticMap, Filter, Alias;
import std.traits;

enum isPublic(alias overload) = Alias!(__traits(getProtection, 
overload) == "public");


interface InterfaceFromClass(T, alias filter = isPublic)
{
static foreach (overload; Filter!(filter, 
staticMap!(ApplyLeft!(MemberFunctionsTuple, T), 
__traits(derivedMembers, T
mixin("@(__traits(getAttributes, overload)) 
"~attributes!overload~" ReturnType!overload 
"~__traits(identifier, overload)~"(Parameters!overload);");

}

string attributes(alias overload)()
{
enum attrs = Filter!(ApplyLeft!(hasFunctionAttributes, 
overload),
"pure", "nothrow", "ref", "@property", "@trusted", 
"@safe", "@nogc", "@system", "const", "immutable", "inout", 
"shared", "return", "scope");

return [attrs].join(" ");
}

alias A = InterfaceFromClass!C;

abstract class C : A
{
int n;
@("InterfaceMembers")
{
@(3) ref int foo(ref int a) { return n; }
@(19) @safe void bar() { }
}
}

// https://issues.dlang.org/show_bug.cgi?id=18915
// class D : C {}

static assert([__traits(allMembers, A)] == ["foo", "bar"]);
static assert(functionAttributes!(A.foo) == 
functionAttributes!(C.foo));
static assert(functionAttributes!(A.bar) == 
functionAttributes!(C.bar));

static assert(is(Parameters!(A.foo) == Parameters!(C.foo)));
static assert(is(Parameters!(A.bar) == Parameters!(C.bar)));

Note the link to issue 18915 (that's your 'string mixin output 
works...' post). I believe if we can fix that, the above should 
work.


--
  Simen


Yeah! with a little work you can include fields in the 
interfacemembers because they will be ignored.


I see no reason to have to declare an interface in D except in 
rare occasions! One should be able to abstract out an interface 
from a class or abstract class and use it as the base only for 
others to use. If a program was "sealed" there would be no real 
point in using interfaces(assuming it was designed to perfection) 
except to get around the diamond problem, which is what 
interfaces solve but in the process have forced us to duplicate 
code.


The above technique alleviates that problem greatly. It's still 
bring the members inside the interface because it allows one to 
add final, static, and normal members if desired, although, this 
can be done by using another interface and inheriting from that.




Re: Build interface from abstract class

2018-05-30 Thread Simen Kjærås via Digitalmars-d-learn

On Monday, 28 May 2018 at 20:13:49 UTC, DigitalDesigns wrote:
I do not think this is a problem in D. Infinite recursion can 
always be terminated with appropriate means.


1. Use attributes. methods in class A should be marked as being 
for the interface. When added to the interface they will not 
have the attribute so will not be picked up again.


2. Your method of function creation does not pick up attributes 
and other factors so it is weak.


Here is my solution that does not solve problem 2:

[Neat stuff]


Neat, but as you say it doesn't handle attributes or UDAs. The 
use of stringof is also a red flag - the same name can apply to 
different types in different scopes, and aliases may confuse it. 
Here's a version that solves both of those issues:



import std.array : join;
import std.meta : ApplyLeft, staticMap, Filter, Alias;
import std.traits;

enum isPublic(alias overload) = Alias!(__traits(getProtection, 
overload) == "public");


interface InterfaceFromClass(T, alias filter = isPublic)
{
static foreach (overload; Filter!(filter, 
staticMap!(ApplyLeft!(MemberFunctionsTuple, T), 
__traits(derivedMembers, T
mixin("@(__traits(getAttributes, overload)) 
"~attributes!overload~" ReturnType!overload 
"~__traits(identifier, overload)~"(Parameters!overload);");

}

string attributes(alias overload)()
{
enum attrs = Filter!(ApplyLeft!(hasFunctionAttributes, 
overload),
"pure", "nothrow", "ref", "@property", "@trusted", 
"@safe", "@nogc", "@system", "const", "immutable", "inout", 
"shared", "return", "scope");

return [attrs].join(" ");
}

alias A = InterfaceFromClass!C;

abstract class C : A
{
int n;
@("InterfaceMembers")
{
@(3) ref int foo(ref int a) { return n; }
@(19) @safe void bar() { }
}
}

// https://issues.dlang.org/show_bug.cgi?id=18915
// class D : C {}

static assert([__traits(allMembers, A)] == ["foo", "bar"]);
static assert(functionAttributes!(A.foo) == 
functionAttributes!(C.foo));
static assert(functionAttributes!(A.bar) == 
functionAttributes!(C.bar));

static assert(is(Parameters!(A.foo) == Parameters!(C.foo)));
static assert(is(Parameters!(A.bar) == Parameters!(C.bar)));

Note the link to issue 18915 (that's your 'string mixin output 
works...' post). I believe if we can fix that, the above should 
work.


--
  Simen


Re: Logging inside struct?

2018-05-30 Thread biocyberman via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 10:07:35 UTC, Simen Kjærås wrote:

On Wednesday, 30 May 2018 at 09:58:16 UTC, biocyberman wrote:

[...]


This line:

writeln("got num: %s, of type: %s", num, typeof(num));

[...]


Problem solved. Thanks Simen!


Re: Logging inside struct?

2018-05-30 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 30 May 2018 at 09:58:16 UTC, biocyberman wrote:

How do I add logging for this struct?

https://run.dlang.io/is/9N6N4o

If not possible, what's the alternative?


This line:

writeln("got num: %s, of type: %s", num, typeof(num));

Gives this error message:

onlineapp.d(7): Error: cannot pass type int as a function 
argument


The error message says exactly what's wrong - you can't pass a 
type as a runtime argument. You can get a string representation 
using .stringof:


writeln("got num: %s, of type: %s", num, 
typeof(num).stringof);


Next up: if prints this:

got num: %s, of type: %s1int
1

You probably want something more like this:

got num: 1, of type: int
1

The problem is you're using writeln, which only dumps its 
arguments to stdout in the order they're passed. writefln does 
formatting using %s:


writefln("got num: %s, of type: %s", num, 
typeof(num).stringof);


--
  Simen


Logging inside struct?

2018-05-30 Thread biocyberman via Digitalmars-d-learn

How do I add logging for this struct?

https://run.dlang.io/is/9N6N4o

If not possible, what's the alternative?



Re: CMake support for D

2018-05-30 Thread Stefan via Digitalmars-d-learn

On Tuesday, 27 February 2018 at 14:32:54 UTC, King_DuckZ wrote:

... My problem is mixing D with C and C++ ...


you found already Dragos cmake-d, but not sure if you also know 
Dragos talk about mixing D with C/C++.


If not, have a look:
https://gitlab.com/dcarp/MUCplusplus/tree/master/2016.01.28



Re: string mixin output works when directly used but when generator is used D fails

2018-05-30 Thread Simen Kjærås via Digitalmars-d-learn

On Tuesday, 29 May 2018 at 21:19:01 UTC, DigitalDesigns wrote:

https://dpaste.dzfl.pl/67691db19ce8


Simplified:

interface A
{
import std.meta : AliasSeq;
alias a = AliasSeq!(__traits(getMember, B, "foo"));
void foo();
}

class B : A
{
void foo() { }
}

It seems the compiler is looking at the class before the 
interface is ready, and that the method thus isn't marked as 
implementing an interface method. Filed as 
https://issues.dlang.org/show_bug.cgi?id=18915


--
  Simen


Re: CMake support for D

2018-05-30 Thread King_Duckz via Digitalmars-d-learn

On Tuesday, 27 February 2018 at 14:32:54 UTC, King_DuckZ wrote:
On Tuesday, 27 February 2018 at 09:20:21 UTC, Russel Winder 
wrote:

[...]


Right, I stand corrected about Rust, though as you say there 
are those who use it with CMake.
About cmake-d, there's this 
https://github.com/dcarp/cmake-d/issues/19, which I could work 
around. More seriously though, it doesn't track dependencies 
between .d files. So if for example you have:


[...]


Are there any news at all about CMake support? Should I just give 
up?