Re: Best practices of using const

2019-06-21 Thread Yatheendra via Digitalmars-d-learn
It feels disingenous to want to call a caching object even 
"logically" const. There has to be a scaffolding-based but 
hopefully generic compromise. I haven't yet tested this belief, 
but I believe "physical" const is of good use wherever it can be 
applied.


On Friday, 21 June 2019 at 23:39:20 UTC, H. S. Teoh wrote:

The problem with this is that you cannot use const(Wrapper).

In particular, if you have a function that wants to document 
that it does not mutate its argument, you cannot write:


auto func(in Wrapper data) { ... }

because const(Wrapper) does not allow lazy initialization.
...


IMHO, in parameters are a more important scenario than const in 
ranges (of course, same constraints).


Just for the heck of it, I'll try to get a snippet "working" but 
I see out parameters snaking all through the call chain!


Re: There is a computer languages benchmark compare site, but no Dlang benchmark. I think they should support D.

2019-06-21 Thread lithium iodate via Digitalmars-d-learn

On Saturday, 22 June 2019 at 01:27:31 UTC, lili wrote:
A nick site, has a lot of languages, unfortunately no dlang in 
there. 
https://benchmarksgame-team.pages.debian.net/benchmarksgame/


This page frequently pops up in this forum, please refer to 
existing posts:

https://forum.dlang.org/search?q=benchmarksgame=forum
In particular the last thread: 
https://forum.dlang.org/post/rcrhjgnskiuzzhrnz...@forum.dlang.org


TL;DR: not happening.


There is a computer languages benchmark compare site, but no Dlang benchmark. I think they should support D.

2019-06-21 Thread lili via Digitalmars-d-learn
A nick site, has a lot of languages, unfortunately no dlang in 
there. 
https://benchmarksgame-team.pages.debian.net/benchmarksgame/


Re: Best practices of using const

2019-06-21 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jun 21, 2019 at 06:32:33PM +, Yatheendra via Digitalmars-d-learn 
wrote:
[...]
>struct CostlyComputeResult {
>   ... // data fields
>   // constructor takes compute results, no postblit
>}
> 
>struct Wrapper {
>   const (CostlyComputeResult) *cachee = 0;
>   ... // data fields storing compute inputs
>   // constructor takes compute inputs
>   // pointer to function(compute inputs)
>   const ref get() {
>  if (!cachee) {
> cachee = new(function(inputs));
>  }
>  return cachee;
>   }
>}
> 
> Hopefully jumping through these hoops is worth the while. Instead,
> maybe just wait until the compiler grows a 'cache pure' function
> qualifier (move constructor required?).

The problem with this is that you cannot use const(Wrapper).

In particular, if you have a function that wants to document that it
does not mutate its argument, you cannot write:

auto func(in Wrapper data) { ... }

because const(Wrapper) does not allow lazy initialization.  Basically
you have to resort to convention (e.g., name it ReadOnly or something
similar) rather than actually mark it const.  This generally isn't a big
problem if you're using func in isolation, but as soon as you need to
compose func with other const code, you quickly find yourself in a
gordian knot of const incompatibilities that percolate throughout the
entire call chain, because D's const is transitive.

I.e., you want func to interact with other functions that trade in const
data, but you cannot because of the constant(!) need to keep Wrapper
mutable.  The non-constness of Wrapper will then percolate up the call
chain, "tainting" all functions that call it so that they cannot be
marked const, even though *logically* they are const.  This mix is
already bad enough (try it on a non-trivial codebase sometime and see
for yourself), but once you add generic functions to the mix, the whole
thing simply becomes unusable -- because generic functions expect to
write const types as const(T), but that will break if T is Wrapper. OK,
so you can try to make it mutable as a workaround.  But then that breaks
const-ness attribute inference so the generic function becomes
non-const, which in turn recursively causes its callers to be non-const,
etc.  Somewhere at the top of the call chain you'll have a const method
that wants to call a const function, passing some higher-level data
structure that eventually contains Wrapper somewhere deep down -- and it
simply doesn't work without making the *entire* structure mutable, due
to the infectiousness of const.

So as soon as you use Wrapper in any data structure of arbitrary
complexity, the entire thing must be mutable -- otherwise const
percolates all the way down to Wrapper and the caching doesn't work
anymore.

tl;dr: using a wrapper works fine for relatively simple cases.  But as
soon as you add any meaningful complexity to it, the scheme quickly
becomes either impractically convoluted, or outright impossible to use
without a hard cast to cast away const (thereby invoking the lovely UB).


T

-- 
INTEL = Only half of "intelligence".


Re: Options for unit testing in D?

2019-06-21 Thread Mike Brockus via Digitalmars-d-learn

On Friday, 21 June 2019 at 17:52:43 UTC, Mike Wey wrote:

On 21-06-2019 06:08, Mike Brockus wrote:

[...]


If you are using the D unittests in your source you can 
recompile the same source with `d_unittest: true`, the 
appstream-generator project does this: 
https://github.com/ximion/appstream-generator/blob/master/src/asgen/meson.build#L108


Or you can keep the tests separate and compile these test 
separately like you are doing in your C project. I use this 
option in the GlibD project: 
https://github.com/gtkd-developers/GlibD/blob/master/tests/gobject/meson.build


So to use D 'unittest' I am required to include the main.d module 
file in the tester executable?


Re: What is iota function full name

2019-06-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, June 21, 2019 3:31:46 PM MDT KnightMare via Digitalmars-d-learn 
wrote:
> On Friday, 21 June 2019 at 19:18:02 UTC, KnightMare wrote:
> > On Friday, 21 June 2019 at 12:02:10 UTC, Jonathan M Davis wrote:
> >
> > auto goodName( ... ) {
> >
> > pragma( inline, true )
> > return terribleName( ... );
> >
> > }
>
> hmm.. I have a question: this pragma will inline terribleName
> (double code) or goodName (fine)?

pragma(inline, true) goes on function declarations, not on function calls.
So, you would need to put it on goodName's signature, in which case, it's
goodName which would be inlined. There is no way for a caller to force a
function to be inlined.

- Jonathan M Davis





Re: Transform a function's body into a string for mixing in

2019-06-21 Thread Emmanuelle via Digitalmars-d-learn

On Friday, 21 June 2019 at 15:54:35 UTC, Adam D. Ruppe wrote:

On Friday, 21 June 2019 at 15:42:56 UTC, Emmanuelle wrote:

[...]


This sounds very similar to something I hacked together a while 
ago and recently wrote about making cleaner code:


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

The idea here was to do a pass-by-value lambda. Usage:

---
auto bar(T)(T x) @nogc
{
return x(10);
}

auto foo(int x) @nogc
{
auto f = lambda!(x, q{ (int y) { return x + y; } });
return f;
}

void main()
{
import std.stdio;
writeln(foo(15)(10));
}
---

Magic implementation:

---
template lambda(Args...) {
static struct anon {
static foreach(i; 0 .. Args.length - 1)
			mixin("typeof(Args[i]) " ~ __traits(identifier, Args[i]) ~ 
";");

auto opCall(T...)(T t) {
return mixin(Args[$-1])(t);
}
this(T...)(T t) {
this.tupleof = t;
}
}

anon lambda() {
anon a;
// copy the values in
a.tupleof = Args[0 .. $-1];
return a;
}
}
---



You could convert that into a regular delegate too, so it works 
with non-template consumers, by generating a non-templated 
opCall and taking its address.


Oh wow, that's pretty awesome. Too bad it seems the token string 
around the lambda is unavoidable, but it's not a big deal I 
think. In any case thanks, you snippet helped me figure out the 
template I wanted without overuse of strings!


Re: What is iota function full name

2019-06-21 Thread KnightMare via Digitalmars-d-learn

On Friday, 21 June 2019 at 19:18:02 UTC, KnightMare wrote:

On Friday, 21 June 2019 at 12:02:10 UTC, Jonathan M Davis wrote:



auto goodName( ... ) {
pragma( inline, true )
return terribleName( ... );
}


hmm.. I have a question: this pragma will inline terribleName 
(double code) or goodName (fine)?


Re: Order of interfaces

2019-06-21 Thread Tomas via Digitalmars-d-learn

On Friday, 21 June 2019 at 20:50:02 UTC, user1234 wrote:

On Friday, 21 June 2019 at 20:42:00 UTC, Tomas wrote:

Does it matter in which order a class inherits from interfaces?

   class A : Interface1, Interface2{ ... }

   vs

   class A : Interface2, Interface1{ ... }

Conceptually it should not matter, but I'm getting really 
weird segfault errors with one version and no errors with the 
other version.


compiler segfault or segfault when the program runs ?

I still do not know what I'm doing wrong, but does anyone have 
an idea why the order might matter?


I'm getting segfault when running the program.


Re: Order of interfaces

2019-06-21 Thread user1234 via Digitalmars-d-learn

On Friday, 21 June 2019 at 20:42:00 UTC, Tomas wrote:

Does it matter in which order a class inherits from interfaces?

   class A : Interface1, Interface2{ ... }

   vs

   class A : Interface2, Interface1{ ... }

Conceptually it should not matter, but I'm getting really weird 
segfault errors with one version and no errors with the other 
version.


compiler segfault or segfault when the program runs ?

I still do not know what I'm doing wrong, but does anyone have 
an idea why the order might matter?


Re: What is iota function full name

2019-06-21 Thread Marco de Wild via Digitalmars-d-learn

On Friday, 21 June 2019 at 19:18:02 UTC, KnightMare wrote:

On Friday, 21 June 2019 at 12:02:10 UTC, Jonathan M Davis wrote:

On Friday, June 21, 2019 5:10:03 AM MDT JN via


Some folks argued a while back that iota was a terrible name 
and that it should be changed, but it was decided not to 
change it.


auto terribleName( ... ) { }

auto goodName( ... ) {
pragma( inline, true )
return terribleName( ... );
}

everyone is happy


Good tip. I usually make a file for these kind of aliases and 
simple functions that do not end up in the standard library, eg 
std.algorithm oneliners.


Order of interfaces

2019-06-21 Thread Tomas via Digitalmars-d-learn

Does it matter in which order a class inherits from interfaces?

   class A : Interface1, Interface2{ ... }

   vs

   class A : Interface2, Interface1{ ... }

Conceptually it should not matter, but I'm getting really weird 
segfault errors with one version and no errors with the other 
version.


I still do not know what I'm doing wrong, but does anyone have an 
idea why the order might matter?


Re: What is iota function full name

2019-06-21 Thread KnightMare via Digitalmars-d-learn

On Friday, 21 June 2019 at 12:02:10 UTC, Jonathan M Davis wrote:

On Friday, June 21, 2019 5:10:03 AM MDT JN via


Some folks argued a while back that iota was a terrible name 
and that it should be changed, but it was decided not to change 
it.


auto terribleName( ... ) { }

auto goodName( ... ) {
pragma( inline, true )
return terribleName( ... );
}

everyone is happy


Re: Best practices of using const

2019-06-21 Thread Yatheendra via Digitalmars-d-learn
That is a comprehensive reply. No pointers to other material 
required :-)


On Friday, 21 June 2019 at 16:35:50 UTC, H. S. Teoh wrote:
On Fri, Jun 21, 2019 at 06:07:59AM +, Yatheendra via 
Digitalmars-d-learn wrote:
Actually, optimizers work best when there is minimal mutation 
*in the original source*.  The emitted code, of course, is free 
to use mutation however it wants.  But the trouble with 
mutation at the source level is that it makes many code 
analyses very complex, which hinders the optimizer from doing 
what it might have been able to do in the absence of mutation 
(or a reduced usage of mutation).

[...]


(aside: I hope we don't end up advocating the Haskell/Erlang way 
or the Clojure way!)


Yes, the hindrances of non-const code are documented (are most 
programmers listening!). I was only pointing out that mutation 
being part of the design limits what can be logically const. Is 
the trade-off clear, between (mythical) guaranteed C++-like-const 
at all the points we remember to put it, versus guaranteed 
D-const at the fewer points we manage to put it? Does D-const 
distort the design (but you get all the optimizations possible in 
that scenario)?


The inability to have a const caching object seems correct. 
The way around would be to have a wrapper that caches (meh). 
If that is not possible, then maybe caching objects just 
aren't meant to be const by their nature? Isn't memoize a 
standard library feature? I should look at it, but I wouldn't 
expect it to be const.


It's not as simple as it might seem.  Here's the crux of the 
problem: you have an object that logically never changes 
(assuming no bugs, of course).  Meaning every time you read it, 
you get the same value, and so multiple reads can be elided, 
etc.. I.e., you want to tell the compiler that it's OK to 
assume this object is const (or immutable).


However, it is expensive to initialize, and you'd like it to be 
initialized only when it's actually needed, and once 
initialized you'd like it to be cached so that you don't have 
to incur the initialization cost again.  However, declaring a 
const object in D requires initialization, and after 
initialization it cannot be mutated anymore. This means you 
cannot declare it const in the first place if you want caching.


It gets worse, though.  Wrappers only work up to a certain 
point.  But when you're dealing with generic code, it becomes 
problematic.  Assume, for instance, that you have a type Costly 
that's logically const, but lazily initialized (and cached).  
Since you can't actually declare it const -- otherwise lazy 
initialization doesn't work -- you have to declare it mutable.  
Or, in this case, declare a wrapper that holds a const 
reference to it, say something like this:


struct Payload {
// lazily-initialized data
}

struct Wrapper {
const(Payload)* impl;
...
}

However, what if you're applying some generic algorithms to it?
 Generic code generally assume that given a type T, if you want 
to declare a const instance of it, you simply write const(T).  
But what do you pass to the generic function? If you pass 
Wrapper, const(Wrapper) means `impl` cannot be rebound, so 
lazily initialization fails.  OK, then let's pass 
const(Payload) directly.  But that means you no longer have a 
wrapper, so you can't have lazy initialization (Payload must be 
constructed before you can pass it to the function, thus it 
must be eagerly initialized at this point).




I should check on std memoize & maybe code something up for 
understanding before writing more than this - would you mind 
pointing to an example range algorithm that we would have trouble 
passing a caching wrapper to?


I hadn't considered pointers as an option. Why wouldn't the 
following work, if expressible in D?

   struct CostlyComputeResult {
  ... // data fields
  // constructor takes compute results, no postblit
   }

   struct Wrapper {
  const (CostlyComputeResult) *cachee = 0;
  ... // data fields storing compute inputs
  // constructor takes compute inputs
  // pointer to function(compute inputs)
  const ref get() {
 if (!cachee) {
cachee = new(function(inputs));
 }
 return cachee;
  }
   }

Hopefully jumping through these hoops is worth the while. 
Instead, maybe just wait until the compiler grows a 'cache pure' 
function qualifier (move constructor required?).


Re: Options for unit testing in D?

2019-06-21 Thread Mike Wey via Digitalmars-d-learn

On 21-06-2019 06:08, Mike Brockus wrote:

If you never herd about Meson before:
樂. https://mesonbuild.com/

I am wondering as to what options are available for a Meson build user 
when unit testing?


What I am trying todo is simply rewrite my C17 project reference 
templates to D versions so I may show other developers the basic 
structure of my project if I have a question about something or to 
influence the idea of Meson with D projects.  Excuse the Conan file.


As reference:
C17
https://github.com/squidfarts/c-example.git
https://github.com/squidfarts/c-project.git

Dlang
https://github.com/squidfarts/d-example.git




If you are using the D unittests in your source you can recompile the 
same source with `d_unittest: true`, the appstream-generator project 
does this: 
https://github.com/ximion/appstream-generator/blob/master/src/asgen/meson.build#L108


Or you can keep the tests separate and compile these test separately 
like you are doing in your C project. I use this option in the GlibD 
project: 
https://github.com/gtkd-developers/GlibD/blob/master/tests/gobject/meson.build


--
Mike Wey


Re: Best practices of using const

2019-06-21 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jun 21, 2019 at 06:07:59AM +, Yatheendra via Digitalmars-d-learn 
wrote:
> Am I mistaken in saying that we are conflating:
>"anything that is logically const should be declared const"

No, not in D.  D does not have logical const; it has "physical" const,
which is a strict subset of logical const, and therefore there are some
uses of logical const for which D's const is unsuitable.


>// makes perfect sense
>// e.g. the lowest 2, and some branches of the 3rd and 4th, levels
>// of members (and a subset of the overall methods) in a 5-deep type 
> hierarchy are const
> with:
>"most code/data should be declared const"
>// no! isn't efficient code all about mutation?
>// no grounds for, e.g.: "ideally, no more than 40% of code should be
> doing mutation"

Actually, optimizers work best when there is minimal mutation *in the
original source*.  The emitted code, of course, is free to use mutation
however it wants.  But the trouble with mutation at the source level is
that it makes many code analyses very complex, which hinders the
optimizer from doing what it might have been able to do in the absence
of mutation (or a reduced usage of mutation).  Aliasing is one example
that hampers optimizers from emitting optimal code. Aliasing plus
mutation makes the analysis so complex that the optimizer has a hard
time deciding whether a particular construct can be optimized away or
not.

Having minimal mutation in the original source code allows the optimizer
to make more assumptions, which in turn leads to better optimizations.
It also makes the source code easier to understand.  Paradoxically,
having less mutation in the source code means it's easier for the
compiler to optimize it into mutation-heavy optimal code -- because it
doesn't have to worry about arbitrary mutations in the source code, and
therefore can be free(r) to, e.g., eliminate redundant copies, redundant
movement of data, etc., which ultimately results in in-place
modification of values, i.e., mutation-heavy emitted code.

Conversely, if the source code is heavy on mutations, then the compiler
cannot confidently predict the overall effect of the mutations, and
therefore is forced to err on the safe side of assuming the worst, i.e.,
don't apply aggressive optimizations in case the programmer's mutations
invalidate said optimizations. The result is less optimal code.


[...]
> The inability to have a const caching object seems correct. The way
> around would be to have a wrapper that caches (meh). If that is not
> possible, then maybe caching objects just aren't meant to be const by
> their nature? Isn't memoize a standard library feature? I should look
> at it, but I wouldn't expect it to be const.

It's not as simple as it might seem.  Here's the crux of the problem:
you have an object that logically never changes (assuming no bugs, of
course).  Meaning every time you read it, you get the same value, and so
multiple reads can be elided, etc.. I.e., you want to tell the compiler
that it's OK to assume this object is const (or immutable).

However, it is expensive to initialize, and you'd like it to be
initialized only when it's actually needed, and once initialized you'd
like it to be cached so that you don't have to incur the initialization
cost again.  However, declaring a const object in D requires
initialization, and after initialization it cannot be mutated anymore.
This means you cannot declare it const in the first place if you want
caching.

It gets worse, though.  Wrappers only work up to a certain point.  But
when you're dealing with generic code, it becomes problematic.  Assume,
for instance, that you have a type Costly that's logically const, but
lazily initialized (and cached).  Since you can't actually declare it
const -- otherwise lazy initialization doesn't work -- you have to
declare it mutable.  Or, in this case, declare a wrapper that holds a
const reference to it, say something like this:

struct Payload {
// lazily-initialized data
}

struct Wrapper {
const(Payload)* impl;
...
}

However, what if you're applying some generic algorithms to it?  Generic
code generally assume that given a type T, if you want to declare a
const instance of it, you simply write const(T).  But what do you pass
to the generic function? If you pass Wrapper, const(Wrapper) means
`impl` cannot be rebound, so lazily initialization fails.  OK, then
let's pass const(Payload) directly.  But that means you no longer have a
wrapper, so you can't have lazy initialization (Payload must be
constructed before you can pass it to the function, thus it must be
eagerly initialized at this point).

It's an impasse.  Cached / lazily-initialized objects and D's const
simply don't mix.  Well, you can try to mix them, but it's like trying
to mix water and oil.  They just don't work well together.


T

-- 
Notwithstanding the eloquent discontent that you have 

Re: Transform a function's body into a string for mixing in

2019-06-21 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 21 June 2019 at 15:42:56 UTC, Emmanuelle wrote:
Yeah, I want to be able to basically use mixin templates but 
with expressions instead, with the code being executed on the 
scope of the caller, not the callee; but it seems that's 
impossible without passing strings


This sounds very similar to something I hacked together a while 
ago and recently wrote about making cleaner code:


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

The idea here was to do a pass-by-value lambda. Usage:

---
auto bar(T)(T x) @nogc
{
return x(10);
}

auto foo(int x) @nogc
{
auto f = lambda!(x, q{ (int y) { return x + y; } });
return f;
}

void main()
{
import std.stdio;
writeln(foo(15)(10));
}
---

Magic implementation:

---
template lambda(Args...) {
static struct anon {
static foreach(i; 0 .. Args.length - 1)
			mixin("typeof(Args[i]) " ~ __traits(identifier, Args[i]) ~ 
";");

auto opCall(T...)(T t) {
return mixin(Args[$-1])(t);
}
this(T...)(T t) {
this.tupleof = t;
}
}

anon lambda() {
anon a;
// copy the values in
a.tupleof = Args[0 .. $-1];
return a;
}
}
---



You could convert that into a regular delegate too, so it works 
with non-template consumers, by generating a non-templated opCall 
and taking its address.


Re: Transform a function's body into a string for mixing in

2019-06-21 Thread Emmanuelle via Digitalmars-d-learn

On Thursday, 20 June 2019 at 20:38:48 UTC, Dennis wrote:

On Thursday, 20 June 2019 at 19:09:11 UTC, Emmanuelle wrote:
Is there any trait or Phobos function for transforming a 
function/delegate/lambda/whatever's body into a string 
suitable for `mixin(...)`? For example:


See:
https://forum.dlang.org/post/kozwskltzidfnatbp...@forum.dlang.org


If not, is there any way to do this _without_ using strings?


Depends on what you are trying to achieve with mixing in 
function body code. If you just want to execute the function 
code, you can just call it (obviously), so I assume you want 
dynamic scoping (that global variables are overridden by local 
variables from the caller) or something?


Yeah, I want to be able to basically use mixin templates but with 
expressions instead, with the code being executed on the scope of 
the caller, not the callee; but it seems that's impossible 
without passing strings. For example, I recently hit an issue 
with closure scoping 
(https://forum.dlang.org/post/rnxebjcfpmyzptpwz...@forum.dlang.org) that can be worked around by using IIFEs; I thought, hey, maybe I could make a mixin that turns, say, this (taking the example from the post I just linked):


---
((x) => (int i) { nums[x] ~= i; })(x);
---

into this:

---
mixin(capture!(x, (int i) { nums[x] ~= i; });
---

where the variables I need captured go first there (in this case, 
only `x`). Of course, that doesn't work unless I use strings 
everywhere:


---
mixin(capture!("x", q{(int i) { nums[x] ~= i; }});
---

which I find rather ugly and inconvenient.

The technique you linked seems interesting but also loads of work 
so I'll just give up on this idea for now lol. Thanks though!


Trick for passing void* arrays around with typing

2019-06-21 Thread Bart via Digitalmars-d-learn




foo(cast(void*)[Object1, Object2]);

foo(cast(bool delegate(void*))(Tuple!(X,Y) objects)) { });

One can pass arbitrary data as an array(the cast is ugly though)

Then the tuple is cast back to void* but one can access objects 
correctly with typing.


This works well when interacting with C/C++ void* data passing 
but can also work with passing heterogeneous objects in general.





import std.stdio, std.typecons;

class X { int x = 1; }
class Y { int y = 2; }

// a ** is required for the cast.
void foo(void** data)
{
auto dd = cast(Tuple!(X,Y)*)(data);
auto d = *dd;
   writeln(d[0].x);
   writeln(d[1].y);
}


// This would be a C callback that is hidden from us but the 
callback isn't.

alias Q = void delegate(void*);
void bar(Q d, void* x)
{
d(x);
}



void main()
{
X x = new X;
Y y = new Y;
foo(cast(void**)[x, y]);
bar(cast(Q)(Tuple!(X,Y)* dd)
{
auto d = *dd;
writeln("> ", d[0].x);
writeln("> ", d[1].y);
}, cast(void*)[x, y]);
}


What would be nice is if one didn't actually have to jump through 
all the hoops:



void foo(void* as Tuple!(X,Y) d) // Redundant here but only 
because we have access to foo

{
   writeln(d[0].x);
   writeln(d[1].y);
}

// This would be a C callback that is hidden from us but the 
callback isn't.

alias Q = void delegate(void*);
void bar(Q d, void* x)
{
d(x);
}



void main()
{
X x = new X;
Y y = new Y;
foo([x, y]);
bar((as Tuple!(X,Y) d)
{
writeln("> ", d[0].x);
writeln("> ", d[1].y);
}, as [x, y]);
}


here I'm using as to signify a sort of implicit cast.

The main thing to note is that for the callback, D gets the type 
as it is defined  even though the cast changes the overall 
delegate to what it should be:



bar(cast(Q)(Tuple!(X,Y)* dd)
   {
auto d = *dd;
writeln("> ", d[0].x);
writeln("> ", d[1].y);
}, cast(void*)[x, y]);
}


I don't actually use * in my code I think it is necessary to get 
the right values due to how they are passed. I think it has to do 
with register vs stack passing. So it might be fragile


What I have is

bar(cast(Q)(Tuple!(X,Y) d)
   {
writeln("> ", d[0].x);
writeln("> ", d[1].y);
}, cast(void*)[x, y]);
}

which works, at least for x64.

The cool thing is the "casting" all happens internally and so 
there is no direct need for casting. Obviously though there is no 
real casting going on(one could swap x and y in the argument) and 
so it is dangerous... but D could make it 100% type safe with the 
appropriate syntax. (only for delegates and callbacks) although 
maybe one could use it for normal functions too:


foo([x,y] as Tuple!(X,Y))

e.g., normally we would have to do

bar((dd)
   {
auto d = cast(Tuple!(X,Y))dd; // Doesn't work though 
because tuple is not a reference, so must use the double pointer 
hacks.

writeln("> ", d[0].x);
writeln("> ", d[1].y);
}, cast(void*)[x, y]);
}


When working with quite a number of C callbacks and passing data, 
this is a nice pattern to use to avoid the ugly temp variables 
and casting.







Why can't 'scope' be inferred here?

2019-06-21 Thread Paul Backus via Digitalmars-d-learn

The following code fails to compile with -dip1000:

struct Inner(T) {
T value;
this(ref T value) { this.value = value; }
}

struct Outer(T) {
Inner!T inner;
void opAssign(ref T rhs) { inner = Inner!T(rhs); }
}

@safe void main() {
int x;
int* p = 
Outer!(int*) o;
o = p;
}

(Interactive: https://run.dlang.io/is/yYTReh)

Changing Inner's constructor to take a `scope ref T value` fixes 
the error. But since Inner is a template, and the body of the 
constructor is available to the compiler, shouldn't it be able to 
infer the `scope` attribute?


Re: Options for unit testing in D?

2019-06-21 Thread XavierAP via Digitalmars-d-learn

On Friday, 21 June 2019 at 04:08:42 UTC, Mike Brockus wrote:


I am wondering as to what options are available for a Meson 
build user when unit testing?


Unit tests are part of the language in D:

https://dlang.org/spec/unittest.html

These are compiled when you (or whatever build system you use) 
pass the argument -unittest to the compiler.



If you never herd about Meson before:
樂. https://mesonbuild.com/


D has an "official" build manager, called dub. Of course you're 
free to use another one you prefer.


https://dub.pm/getting_started

PS also embedded documentation is part of the language (no need 
for e.g. doxygen):


https://dlang.org/spec/ddoc.html



Blog Post #0046 - SpinButton

2019-06-21 Thread Ron Tarrant via Digitalmars-d-learn
Friday's post covers the SpinButton and its all-important 
Adjustment object companion. You can find it here: 
https://gtkdcoding.com/2019/06/21/0046-the-spinbutton.html


Facelift Update

Things are moving along nicely and I expect the fully-realized 
site to be unveiled within the next week.




Re: What is iota function full name

2019-06-21 Thread Andrea Fontana via Digitalmars-d-learn

On Friday, 21 June 2019 at 09:24:54 UTC, lili wrote:

in dictionary iota means:
a tiny or scarcely detectable amount
the 9th letter of the Greek alphabet
 but this function is not that mean.


Full answer:
https://stackoverflow.com/questions/9244879/what-does-iota-of-stdiota-stand-for


Re: What is iota function full name

2019-06-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, June 21, 2019 5:10:03 AM MDT JN via Digitalmars-d-learn wrote:
> On Friday, 21 June 2019 at 09:18:49 UTC, Jonathan M Davis wrote:
> So, iota is
>
> > the name of the function, and it doesn't stand for anything.
> > It's just the name of the Greek letter that was used for a
> > similar function in another language that most programmers
> > these days have probably never heard of.
> >
> > - Jonathan M Davis
>
> I don't even understand why get so much inspiration from C++. Why
> not just name it seq or sequence?

Quite a lot of the functions in std.algorithm (especially the functions that
it got early on) are modeled after similar functions in C++, standard
library, and when Andrei wrote those functions, he purposefully made them
use the same names as they have in C++. For anyone already familiar with
those functions in C++ (including iota), having the same names makes sense.
Other people are more likely to look at the names on their own merits, and
as such, the names don't necessarily make as much sense (particularly iota).
Regardless, given that Andrei was heavily involved in C++ long before he got
involved with D, it's not exactly surprising that he'd use the C++ names
rather than coming up with new ones - especially when std.algorithm was
originally heavily modeled after C++'s algorithm header.

Some folks argued a while back that iota was a terrible name and that it
should be changed, but it was decided not to change it. However, truth be
told, if you know what iota is, the name is more descriptive than a more
generic name like sequence or generateRange would be. It's just a terrible
name from the perspective that it's not at all decriptive of what it is.
It's just a name that has historically been used for this particular
operation.

In practice, what tends to happen is that when someone first encounters
iota, they think that it's a terrible name, but in the long run, they just
know what it is, and it isn't actually a problem. Either way, at this point,
names in Phobos don't get changed just because some folks think that a name
isn't as good as it could be or should be, because changing would break
code, and Walter and Andrei do not believe that simply giving something a
better name is worth breaking anyone's code.

- Jonathan M Davis





Re: What is iota function full name

2019-06-21 Thread JN via Digitalmars-d-learn

On Friday, 21 June 2019 at 09:18:49 UTC, Jonathan M Davis wrote:
So, iota is
the name of the function, and it doesn't stand for anything. 
It's just the name of the Greek letter that was used for a 
similar function in another language that most programmers 
these days have probably never heard of.


- Jonathan M Davis


I don't even understand why get so much inspiration from C++. Why 
not just name it seq or sequence?


Re: What is iota function full name

2019-06-21 Thread KlausO via Digitalmars-d-learn

So basically iota spills Increments Over The Array.

Am 21.06.2019 um 11:18 schrieb Jonathan M Davis:

On Friday, June 21, 2019 3:01:17 AM MDT lili via Digitalmars-d-learn wrote:

Hi Guys:
  What is range.iota function full name


iota _is_ its full name. It's named after an STL function which does
basically the same with iterators in C++:

https://en.cppreference.com/w/cpp/algorithm/iota

Apparently, C++ got it from the APL programming language, which uses Greek
characters and other symbols that you can't find on most keyboards, which
makes APL code more like what you see in equations in a math textbook, and
APL uses the Greek letter iota for a function with similar behavior to the
C++ and D functions. And since unlike APL, C++ couldn't use the Greek
letter, when they named their version of the function, they used the name of
the letter rather than the letter. And then D's function name was named
after the C++ function. So, iota is the name of the function, and it doesn't
stand for anything. It's just the name of the Greek letter that was used for
a similar function in another language that most programmers these days have
probably never heard of.

- Jonathan M Davis





Re: make C is scriptable like D

2019-06-21 Thread dangbinghoo via Digitalmars-d-learn

On Thursday, 20 June 2019 at 16:55:01 UTC, Jonathan Marler wrote:

On Thursday, 20 June 2019 at 06:20:17 UTC, dangbinghoo wrote:

[...]


rdmd adds a few different features as well, but the bigger 
thing it does is cache the results in a global temporary 
directory.  So If you run rdmd on the same file with the same 
options twice, the second time it won't compile anything, it 
will detect that it was already compiled and just run it.


great! thanks.


Re: What is iota function full name

2019-06-21 Thread lili via Digitalmars-d-learn

On Friday, 21 June 2019 at 09:09:33 UTC, aliak wrote:

On Friday, 21 June 2019 at 09:01:17 UTC, lili wrote:

Hi Guys:
What is range.iota function full name


That is the full name. Or what do you mean?

Found on the internet somewhere:

"The function is named after the integer function ⍳ from the 
programming language APL."


 I mean is that the what is iota stands for.

in dictionary iota means:
a tiny or scarcely detectable amount
the 9th letter of the Greek alphabet
 but this function is not that mean.


Re: What is iota function full name

2019-06-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, June 21, 2019 3:01:17 AM MDT lili via Digitalmars-d-learn wrote:
> Hi Guys:
>  What is range.iota function full name

iota _is_ its full name. It's named after an STL function which does
basically the same with iterators in C++:

https://en.cppreference.com/w/cpp/algorithm/iota

Apparently, C++ got it from the APL programming language, which uses Greek
characters and other symbols that you can't find on most keyboards, which
makes APL code more like what you see in equations in a math textbook, and
APL uses the Greek letter iota for a function with similar behavior to the
C++ and D functions. And since unlike APL, C++ couldn't use the Greek
letter, when they named their version of the function, they used the name of
the letter rather than the letter. And then D's function name was named
after the C++ function. So, iota is the name of the function, and it doesn't
stand for anything. It's just the name of the Greek letter that was used for
a similar function in another language that most programmers these days have
probably never heard of.

- Jonathan M Davis






Re: What is iota function full name

2019-06-21 Thread aliak via Digitalmars-d-learn

On Friday, 21 June 2019 at 09:01:17 UTC, lili wrote:

Hi Guys:
What is range.iota function full name


That is the full name. Or what do you mean?

Found on the internet somewhere:

"The function is named after the integer function ⍳ from the 
programming language APL."





What is iota function full name

2019-06-21 Thread lili via Digitalmars-d-learn

Hi Guys:
What is range.iota function full name


Re: Best practices of using const

2019-06-21 Thread Yatheendra via Digitalmars-d-learn

Am I mistaken in saying that we are conflating:
   "anything that is logically const should be declared const"
   // makes perfect sense
   // e.g. the lowest 2, and some branches of the 3rd and 4th, 
levels
   // of members (and a subset of the overall methods) in a 
5-deep type hierarchy are const

with:
   "most code/data should be declared const"
   // no! isn't efficient code all about mutation?
   // no grounds for, e.g.: "ideally, no more than 40% of code 
should be doing mutation"


On Wednesday, 13 February 2019 at 16:40:18 UTC, H. S. Teoh 
wrote:
On Wed, Feb 13, 2019 at 11:32:46AM +, envoid via 
Digitalmars-d-learn wrote:
Unfortunately, that guarantee also excludes a lot of otherwise 
useful idioms, like objects that cache data -- a const object 
cannot cache data because that means it's being mutated, or 
lazily-initialized objects -- because once the ctor has run, 
the object can no longer be mutated. Most notably, D's 
powerful range idiom is pretty much unusable with const 
because iteration over a range requires mutating the range 
(though having const *elements* in a range is fine).  This 
doesn't seem as bad at first glance, but it wreaks havoc on 
generic code, another thing that D is purportedly good at. 
It's very hard (and often impossible) to write generic code 
that works with both const and mutable objects.


So ironically, the iron-clad semantics of D's const system 
turns out to be also its own downfall.



T


The point about generic code (reiterated by many) is intriguing 
on its own; until now, I hadn't explicitly thought about const 
even for my C++ template library code (whatever little I have of 
those). Any pointers to other posts or articles elaborating this 
a little bit?


I believe the other points probably matter when interacting with 
every other feature (I would have to write some of my "real" code 
in D to see if I hit it on my own), but there doesn't seem to be 
anything unusable about them on their own.


The inability to have a const caching object seems correct. The 
way around would be to have a wrapper that caches (meh). If that 
is not possible, then maybe caching objects just aren't meant to 
be const by their nature? Isn't memoize a standard library 
feature? I should look at it, but I wouldn't expect it to be 
const.


On Monday, 18 February 2019 at 06:50:32 UTC, Marco de Wild wrote:


I agree that const by nature unfortunately kills lazy 
initialization.


Lazy initialization - is this the same as post-blit? At the cost 
of copying (justifiable? maybe), doesn't D have a way to 
copy-construct a const/immutable struct object from a mutable 
one? If there is a way (or will be - there is a recent posting 
and a Dconf talk about copy constructors), does the copying 
negate the benefits of lazy initialization?


However, I don't really understand why const is a problem with 
ranges. Const elements are not a problem. Iterating over a 
range consumes it (if I understand correctly). It does not make 
sense to be able to consume a const object, so from my point of 
view it's perfectly logical to disallow iterating const ranges. 
If I'm missing something, please correct me.

...


+1.

Or I haven't understood why ranges would ever ever need to be 
const.

After all, in C++, what use is:
   std::vector::const_iterator const iter = sequence.begin();
About the only kind of use would be:
   std::vector::const_iterator iter = sequence.begin();
   std::vector::const_iterator const iterEnd = sequence.end();
What are ranges if not an encapsulation of the above 
functionality?