Re: LDC / BetterC / _d_run_main

2018-03-09 Thread Mike Franklin via Digitalmars-d-learn

On Saturday, 10 March 2018 at 02:25:38 UTC, Richard wrote:

Hi,
I've been trying to see if I can get an mbed project to work 
with Dlang

basically compiling D code for use on a Cortex-M Proccessor


You might be interested in the following, if you're not already 
aware:

 * https://github.com/JinShil/stm32f42_discovery_demo
 * https://bitbucket.org/timosi/minlibd

The STM32 demo only supports GDC right now, but I'll be updating 
it to support LDC when 2.079.0 lands there.  2.079.0 removes some 
coupling of the compiler to the runtime, so I should be able to 
avoid the following bugs:


https://github.com/ldc-developers/ldc/issues/created_by/JinShil


so I tried this instead
```
extern (C) int _d_run_main(int argc, char **argv, void* 
mainFunc) {

MainFuncType mFunc = cast(MainFuncType) mainFunc;
return mFunc(null);
}
```

but nope that didn't seem to work ether, compiles okay but the 
code in main() (D space) isn't called

I'd imagine this should be a simple thing, anyone got any ideas?


The following worked fine for me on my x64 Linux desktop with LDC 
version 1.8.0 (DMD v2.078.3, LLVM 5.0.1)


``` main.d
import core.stdc.stdio;

private alias extern(C) int function(char[][] args) MainFuncType;
extern (C) int _d_run_main(int argc, char **argv, void* mainFunc)
{
MainFuncType mFunc = cast(MainFuncType) mainFunc;
return mFunc(null);
}

void main()
{
printf("Hello, World!\n");
}
```

Compile with: ldc2 -defaultlib= -debuglib= -betterC main.d

Mike



Re: LDC / BetterC / _d_run_main

2018-03-09 Thread Adam D. Ruppe via Digitalmars-d-learn
Eh, you can simplify it a lot by just writing your own C main 
(legal with or without betterC btw)


---
import core.stdc.stdio;

extern(C)
int main(int argc, char** argv) {
printf("hello world, %s\n", argc > 1 ? argv[1] : "user");
return 0;
}
---

that should work with any compiler, with or without -betterC.


LDC / BetterC / _d_run_main

2018-03-09 Thread Richard via Digitalmars-d-learn

Hi,
I've been trying to see if I can get an mbed project to work with 
Dlang

basically compiling D code for use on a Cortex-M Proccessor
So far I've been using the latest release of LDC with the 
-BetterC Flag
From what I can gather, normally without -BetterC it works like 
this:


  * main() - C main generated by the compiler
  * _d_run_main - called by C main to setup the runtime
  * _Dmain - main function in D land, is called by _d_run_main

With -BetterC enabled, it instead works like this

  * main() - C main generated by the compiler
  * _d_run_main - needs to be written by the user since there's 
no runtime

  * _Dmain - main function in D land

so basically I need to write my own basic _d_run_main to call 
_Dmain.

Code in github does something like this typically
```
private alias extern(C) int function(char[][] args) MainFunc;
private extern (C) int _d_run_main(int argc, char** argv, 
MainFunc mainFunc)

{
return mainFunc(null);
}
```

However the LDC compiler doesn't like this as it expects the 
mainFunc parameter to be a void pointer

so I tried this instead
```
extern (C) int _d_run_main(int argc, char **argv, void* mainFunc) 
{

MainFuncType mFunc = cast(MainFuncType) mainFunc;
return mFunc(null);
}
```

but nope that didn't seem to work ether, compiles okay but the 
code in main() (D space) isn't called

I'd imagine this should be a simple thing, anyone got any ideas?



Re: Generic Property Implementation

2018-03-09 Thread Mike Franklin via Digitalmars-d-learn

On Friday, 9 March 2018 at 14:46:04 UTC, Simen Kjærås wrote:

This is the best I've come up with in the current language:

struct S {
int n;
mixin property!("field", "get => this.n", "set => this.n = 
set");

}


Not bad.  Not good, but not bad either.


Sadly, there are issues:

1) Wrong return type:
unittest {
S s;
auto a = s.field;
// Fails - typeof(a) is Property!((get) => this.n, (set) => 
this.n = set)

assert(is(typeof(a) == int));
}


This looks like a related issue:  
https://issues.dlang.org/show_bug.cgi?id=16657.  That's is a 
deal-breaker for me, but I think it could be fixed.



2) Noisy syntax:
If I had my druthers, mixin templates would be mixin'd 
automatically, and eponymous mixin templates would be a thing.


Yes, this would be nice, but I don't think it's a deal-breaker.


3) Stringy functions:
The string literal functions are an eyesore, but would require 
some compiler work to fix. This fails:


struct S {
int n;
mixin property!("field", get => this.n, set => this.n = 
set);

}

The reason is there's no 'this' at the point of instantiation, 
since we're in the context of the type, not a function where 
'this' makes sense. It seems to me this should be fixable, but 
I have no idea how much work would be required.


Yeah, that's quite unfortunate; writing code in strings stinks.  
I actually prefer the DIP for this issue alone.



4) 'this' in function bodies
It should be possible to write "get => this.n" as "get => n". 
There's no ambiguity as to which 'n' I'm referring to. Filed a 
bug:

https://issues.dlang.org/show_bug.cgi?id=18584


Thanks for filing the issue.  I just might be able to fix it; 
I'll try.



Implementation:
https://gist.github.com/Biotronic/5849af011cbe9c7ea05515011d5995bf


You've done some great work here.  I spent about an hour on this 
yesterday, and my implementation started to require more and more 
mixing strings to get it to work.


If all of the issues you've identified were addressed, you'd end 
up with something like this (formatted in a C# way).


struct S {
int n;
property!
(
get =>
{
n
},
set =>
{
n = set
}
) field;
}

That's actually pretty darn good.  It makes me wonder if I should 
work on fixing those issues or continue with the DIP.


If you don't have any objections I'd like to incorporate this 
implementation and your analysis into the DIP.


Thank you again for doing this; you've saved me a awful lot of 
time, and have done more than I probably could have.


Mike





Re: Returning constant / literal struct value (pod)

2018-03-09 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Mar 09, 2018 at 09:30:53PM +, Cecil Ward via Digitalmars-d-learn 
wrote:
> Can we return a literal struct value straight from a return statement?
> 
> ie something like
> mystruct_t myfunc()
> { // ... blah
> return { field1: val1, field2: val2; };
> }
> assuming that the return type is defined suitably, and the struct is
> just a C struct, plain-old-data (ie not a C++-like class).

The usual D idiom is to write:

mystruct_t myfunc() {
return mystruct_t(val1, val2);
}

Unfortunately, AFAIK at this time there's no way to write field names as
well, so you'll have to rely on the struct's field order or the ctor's
parameter order.  (But I could be wrong.)


T

-- 
Never step over a puddle, always step around it. Chances are that whatever made 
it is still dripping.


Re: Compile-time variadic equality

2018-03-09 Thread Simen Kjærås via Digitalmars-d-learn

On Friday, 9 March 2018 at 19:24:03 UTC, Nordlöw wrote:
I'm looking for a function (that probably should be placed in 
std.meta) named something like `areEqual` that checks whether 
all it's arguments are equal or not.


Is there such as function already in Phobos?

My usage is

static if (allEqual!(staticMap!(ElementEncodingType, Rs)))
{
// compare Rs byCodeUnit
}


NoDuplicates!V.length == 1

--
  Simen


Re: What's the proper way to add a local file dependence to dub?

2018-03-09 Thread crimaniak via Digitalmars-d-learn

On Sunday, 4 March 2018 at 16:46:56 UTC, Marc wrote:

then copy it to sources folder?

...
Also, symlinks are power tool for organizing your files without 
copying.


Returning constant / literal struct value (pod)

2018-03-09 Thread Cecil Ward via Digitalmars-d-learn
Can we return a literal struct value straight from a return 
statement ?


ie something like
mystruct_t myfunc()
{ // ... blah
return { field1: val1, field2: val2; };
}
assuming that the return type is defined suitably, and the struct 
is just a C struct, plain-old-data (ie not a C++-like class).


I've had to set up a throwaway const item, initialised, and then 
had to return that.


Re: does the shared keyword work with mutable structs?

2018-03-09 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, March 09, 2018 19:33:26 WhatMeWorry via Digitalmars-d-learn 
wrote:
> On Friday, 9 March 2018 at 10:42:47 UTC, Kagamin wrote:
> > To make a struct noncopyable, add @disable this(this); to it,
> > then compiler will give an error on an attempt to copy it.
>
> I tried the @disable this(this); but now it doesn't even compile?
>
> Error: template std.concurrency.spawn cannot deduce function from
> argument types !()(void function(shared(EventBuffer) eB,
> shared(Lock) lock), shared(EventBuffer), shared(Lock)),
> candidates are:
> C:\ldc2\bin\..\import\std\concurrency.d(464):
> std.concurrency.spawn(F, T...)(F fn, T args) if (isSpawnable!(F,
> T))
>
>
> Is std.concurrency a work in progress or I'm I just obtuse here?
>
> I've been reading Ali's book on the concurrency chapters as
> inspiration, but the examples there use simple data types like
> ints or bools.

Well, as Kagamin said, the compiler gives you an error if you
@disable this(this); and then the code attempts to copy the type. The point
was to catch when the type was copied, not make spawn work with your type.
spawn requires that the types that its given be copyable. Either your type
needs to be able to work if it's copied, or it needs to be a reference type
(either by using a class, a pointer to a struct, or by making the struct's
guts live on the heap with a member variable that's a pointer pointing to
them).

- Jonathan M Davis



Re: does the shared keyword work with mutable structs?

2018-03-09 Thread WhatMeWorry via Digitalmars-d-learn

On Friday, 9 March 2018 at 10:42:47 UTC, Kagamin wrote:
To make a struct noncopyable, add @disable this(this); to it, 
then compiler will give an error on an attempt to copy it.


I tried the @disable this(this); but now it doesn't even compile?

Error: template std.concurrency.spawn cannot deduce function from 
argument types !()(void function(shared(EventBuffer) eB, 
shared(Lock) lock), shared(EventBuffer), shared(Lock)), 
candidates are:
C:\ldc2\bin\..\import\std\concurrency.d(464): 
std.concurrency.spawn(F, T...)(F fn, T args) if (isSpawnable!(F, 
T))



Is std.concurrency a work in progress or I'm I just obtuse here?

I've been reading Ali's book on the concurrency chapters as 
inspiration, but the examples there use simple data types like 
ints or bools.





Re: Compile-time variadic equality

2018-03-09 Thread Nordlöw via Digitalmars-d-learn

On Friday, 9 March 2018 at 19:24:03 UTC, Nordlöw wrote:
I'm looking for a function (that probably should be placed in 
std.meta) named something like `areEqual` that checks whether 
all it's arguments are equal or not.


Is there such as function already in Phobos?

My usage is

static if (allEqual!(staticMap!(ElementEncodingType, Rs)))
{
// compare Rs byCodeUnit
}


My current own implementation is

/** Returns: true iff all values $(D V) are the same.
See also: 
http://forum.dlang.org/post/iflpslqgrixdjwrlq...@forum.dlang.org
See also: 
http://forum.dlang.org/post/mheumktihihfsxxxa...@forum.dlang.org

*/
template allSame(V ...)
if (isExpressions!V)
{
static if (V.length <= 1)
{
enum allSame = true;
}
else static if (V.length & 1)
{
enum allSame = (V[$ - 1] == V[0] &&
V[0 .. $/2] == V[$/2 .. $-1] &&
allSame!(V[0 .. $/2]));
}
else
{
enum allSame = (V[0 .. $/2] == V[$/2 .. $] &&
allSame!(V[0 .. $/2]));
}
}

Should this go into std.meta?


Compile-time variadic equality

2018-03-09 Thread Nordlöw via Digitalmars-d-learn
I'm looking for a function (that probably should be placed in 
std.meta) named something like `areEqual` that checks whether all 
it's arguments are equal or not.


Is there such as function already in Phobos?

My usage is

static if (allEqual!(staticMap!(ElementEncodingType, Rs)))
{
// compare Rs byCodeUnit
}


Re: Build an AliasSeq from memberFunction return types

2018-03-09 Thread Simen Kjærås via Digitalmars-d-learn

On Friday, 9 March 2018 at 17:47:46 UTC, Timoses wrote:
To retrieve the member names the following (and filtering for 
only the functions) does the job:


   alias members = aliasSeqOf!([__traits(allMembers, S)]);


This can be simplified to
alias members = Alias!(__traits(allMembers, S));


However, I now would want to build an AliasSeq of the types. My 
idea would be (absolute pseudocode!!!):


   alias memberTypes;
   static foreach (member; members)
   {
  memberTypes ~= ReturnType!S.member;
   }


Generally, we use recursive templates in these cases:

template GetMemberTypes(funcs...) {
static if (funcs.length == 0) {
alias GetMemberTypes = AliasSeq!();
} else {
alias GetMemberTypes = AliasSeq!(
  ReturnType!(funcs[0]),
  GetMemberTypes!(funcs[1..$])
  );
}
}


However, std.meta has staticMap, which will do this recursion for 
us:


alias memberTypes = staticMap!(ReturnType, members);

Of course, this assumes 'members' contains only the functions you 
care about. All in all, what you want can be boiled down to this 
code:



import std.meta : staticMap, Alias, Filter;
import std.traits : isFunction, ReturnType;
import std.bitmanip : bitfields;

struct A
{
int a;
mixin(bitfields!(
uint, "x",2,
int,  "y",3,
uint, "z",2,
bool, "flag", 1));
}

template GetMember(T) {
alias GetMember(string name) = Alias!(__traits(getMember, T, 
name));

}
alias memberTypes = staticMap!(ReturnType, Filter!(isFunction, 
staticMap!(GetMember!A, __traits(allMembers, A;



So, how does it work?

GetMember is a template that takes an aggregate type as a 
parameter and returns a new template that takes a string. This 
inner template then returns the member of the aggregate type that 
has that name:


// Define a template that will find a member in A.
alias GetMemberOfA = GetMember!A;

// Get the 'flag' member of A.
alias someMemberOfA = GetMemberOfA!"flag";



Next: This line is a bit of a mouthful, so let's break it down:
alias memberTypes = staticMap!(ReturnType, Filter!(isFunction, 
staticMap!(GetMember!A, __traits(allMembers, A;


becomes:

// Grab the name of every single member of A.
alias allMemberNames = Alias!(__traits(allMembers, A));

// Define a template that will find a member in A.
alias GetMemberOfA = GetMember!A;

// Now get the members of A that correspond to the names 
__traits(allMembers) returned.

alias allMembers = staticMap!(GetMemberOfA, allMemberNames);

// Get rid of everything that's not a function.
alias onlyFunctions = Filter!(isFunction, allMembers);

// And finally grab the return type of each function.
alias memberTypes = staticMap!(ReturnType, onlyFunctions);

--
  Simen


Build an AliasSeq from memberFunction return types

2018-03-09 Thread Timoses via Digitalmars-d-learn

Hi,

I feel like starting to dig deeper into D. And I got lost : D.

I would like to reflect on defined bitfields:

   struct S
   {
  mixin!(bitfields!(
 , , ,
 ...
  ));
   }

which produces something like this in the back scenes:

   struct S
   {
  uint storage;

  @property  () {
 ... return field from storage;
  }
   }

There is an approach here:
https://forum.dlang.org/post/o5u21b$15f3$1...@digitalmars.com
However, it feels a bit overcomplicating the issue perhaps.

To retrieve the member names the following (and filtering for 
only the functions) does the job:


   alias members = aliasSeqOf!([__traits(allMembers, S)]);

However, I now would want to build an AliasSeq of the types. My 
idea would be (absolute pseudocode!!!):


   alias memberTypes;
   static foreach (member; members)
   {
  memberTypes ~= ReturnType!S.member;
   }

   pragma(msg, memberTypes); // prints sth like: (int, bool, 
uint, ...)


I have taken a look at https://dlang.org/phobos/std_meta.html but 
am unsure whether I can actually build an AliasSeq iteratively.


The mentioned example might help:
   alias TL = AliasSeq!(int, double);
   alias Types = AliasSeq!(TL, char);
   static assert(is(Types == AliasSeq!(int, double, char)));

However, I can't simply do

   static foreach (i, member; members)
   {
  alias memberTypes_i = AliasSeq!
 (memberTypes_i, ReturnType!S.) // <--- no idea 
even how to get
// the ReturnType 
here...
// S.member does 
not work

   }
   alias memberTypes = AliasSeq!(memberTypes_i_max);

But what the heck! I can't find a solution!
This might be related to:
https://forum.dlang.org/post/pxtqeahzxrsrljnrw...@forum.dlang.org

Do you have any ideas? Or does your head start spinning like mine 
does, too?


Re: How to fake a const method ?

2018-03-09 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, March 09, 2018 14:12:10 Basile B. via Digitalmars-d-learn wrote:
> On Friday, 9 March 2018 at 13:47:34 UTC, Basile B. wrote:
> > I would need this to work:
> >
> > ```
> > struct Foo
> > {
> >
> > TypeInfo typeCache;
> >
> > TypeInfo getTypeCache()
> > {
> >
> > alias NotThePoint = ubyte;
> > if (typeCache is null)
> >
> > typeCache = typeid(NotThePoint);
> >
> > return typeCache;
> >
> > }
> >
> > TypeInfo type() const
> > {
> >
> > alias NothrowType = TypeInfo delegate() const;
> > return (cast(NothrowType) )();
> >
> > }
> >
> > }
> >
> > void main(){}
> > ```
> >
> > But get:
> >> Error: mutable method `Foo.getTypeCache` is not callable using
> >> a `const` `this`
> >
> > - `type()` really has to be const because it's used in an
> > opEquals that's used by an AA (key is const so opEquals has to
> > as well)
> > - `typeCache` is not used to compare 2 Foos so it really
> > doesn't matter if it get assigned.
>
> Solved...The error message helped much actually... problem is
> `this` is `const`
>
> https://run.dlang.io/is/UOR2i2

Yes. That's what happens when you mark the function as const. Making the
this pointer/reference const is exactly what marking a member function const
does. However, if your solution involves casting away const, you had better
be 100% sure that the result is never mutated, because if it is mutated,
you're violating the type system and could get weird and subtle bugs. It
would be better if you could just remove const from the equation entirely,
but if you're dealing with AA keys, that's a bit difficult, since they're
immutable (forcing you to deal with either immutable or const).

- Jonathan M Davis



Re: complex arithmetic in D: multiple questions

2018-03-09 Thread bachmeier via Digitalmars-d-learn

On Friday, 9 March 2018 at 14:41:47 UTC, J-S Caux wrote:

Going further, I'm really wondering what the plan is as far as 
Complex is concerned. Right now it just feels neglected 
(half-done/aborted transition from creal etc to Complex, lots 
of missing basic functions etc), and is one major blocking 
point as far as adoption (among scientists) is concerned. Julia 
is really taking off with many of my colleagues, mostly because 
due respect was given to maths. I'd certainly choose Julia if 
it wasn't for the fact that I can't get my exploratory/testing 
codes to run faster than about 1/10th of my C++ stuff. It seems 
D could have such an appeal in the realm of science, but these 
little things are really blocking adoption (including for 
myself).


I don't do the things you're doing (I do econometrics) but I 
don't think that at this point D is ready to be used as a 
complete solution for everything you need. It can be done, but 
someone has to do the work, and that hasn't happened. D is 
designed to be fully interoperable with C and mostly 
interoperable with C++. You'll get the same performance as C, but 
that doesn't help if the libraries you need haven't been written 
yet.


From a practical perspective (i.e., you want to just work without 
writing a bunch of low-level stuff yourself) it's best to prepare 
to call from D into C/C++ or from C/C++ into D. This hybrid 
approach has worked well for me, and to be honest, I'd rather 
rely on well-tested, well-maintained C libraries than worry about 
pure D libraries that haven't been tested extensively and may or 
may not be maintained in the future. It really doesn't matter to 
your own code if the function you're calling was written in C or 
written in D.


As for Julia, that was created as a Matlab replacement, and they 
have full-time devs to work on it. If I were starting over, I 
would consider Julia for my own work. I'd probably still choose D 
but Julia does offer advantages.


Re: complex arithmetic in D: multiple questions

2018-03-09 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 9 March 2018 at 14:41:47 UTC, J-S Caux wrote:
Is this a case for a bug report? Seems pretty bizarre to do 
that, like an oversight/neglect.


Yes if there's not one there for it already.

OK thanks. I looked at libmir, and saw many good things there. 
I was wondering: is it still actively developed/maintained? How 
will it fit with the "core" D in the future? [I don't want to 
build dependencies to libraries which aren't there to stay in 
the long run, I want code which can survive for decades]. It 
would seem to me that some of the things included in there 
should be part of D core/std anyway.


Yes, it is sponsored by https://github.com/kaleidicassociates it 
will be around for a long time.
It is developed separately because the dev/release cycles don't 
easily align with the core/ stdlib developers.


https://github.com/libmir/mir-algorithm/blob/master/source/mir/ndslice/slice.d#L594
is the de facto matrix structure for D.

Going further, I'm really wondering what the plan is as far as 
Complex is concerned. Right now it just feels neglected 
(half-done/aborted transition from creal etc to Complex, lots 
of missing basic functions etc), and is one major blocking 
point as far as adoption (among scientists) is concerned. Julia 
is really taking off with many of my colleagues, mostly because 
due respect was given to maths. I'd certainly choose Julia if 
it wasn't for the fact that I can't get my exploratory/testing 
codes to run faster than about 1/10th of my C++ stuff. It seems 
D could have such an appeal in the realm of science, but these 
little things are really blocking adoption (including for 
myself).


Indeed, I'll see what I can do about it.


[related questions:


Did you press send too soon?


No, the related questions were linked in my previous post (just 
copied & pasted it further above, but didn't delete these last 
couple of words properly).


Thanks a lot Nicholas!




Re: Generic Property Implementation

2018-03-09 Thread Simen Kjærås via Digitalmars-d-learn

On Friday, 9 March 2018 at 01:22:15 UTC, Mike Franklin wrote:

* binary assignment operators (e.g. +=)
* unary assignment operators (e.g. ++)
* @safe, @nogc, and -betterC compatible
* at least as good code generation as that proposed in the DIP 
when optimizations are enabled.
* And should be scalable to data that isn't addressable (e.g. 
bitfields).  See

https://issues.dlang.org/show_bug.cgi?id=16187


This is the best I've come up with in the current language:

struct S {
int n;
mixin property!("field", "get => this.n", "set => this.n = 
set");

}

unittest {
import std.conv : to;
S s;
s.field = 3;
assert(s.field == 3);
s.field += 2;
assert(s.field == 5);
s.field++;
assert(s.field == 6);
assert(s.field.to!string == "6");
}

Sadly, there are issues:

1) Wrong return type:
unittest {
S s;
auto a = s.field;
// Fails - typeof(a) is Property!((get) => this.n, (set) => 
this.n = set)

assert(is(typeof(a) == int));
}
Not a whole lot to do about this. I've pondered writing a DIP on 
auto-decaying/rvalue types, which would decay to a different type 
the moment they're passed to a function or assigned to a 
variable. The feature would probably not be worth the trouble, 
though.



2) Noisy syntax:
If I had my druthers, mixin templates would be mixin'd 
automatically, and eponymous mixin templates would be a thing. 
That would give us this syntax:


struct S {
int n;
property!("get => this.n", "set => this.n = set") field;
}


3) Stringy functions:
The string literal functions are an eyesore, but would require 
some compiler work to fix. This fails:


struct S {
int n;
mixin property!("field", get => this.n, set => this.n = set);
}

The reason is there's no 'this' at the point of instantiation, 
since we're in the context of the type, not a function where 
'this' makes sense. It seems to me this should be fixable, but I 
have no idea how much work would be required.



4) 'this' in function bodies
It should be possible to write "get => this.n" as "get => n". 
There's no ambiguity as to which 'n' I'm referring to. Filed a 
bug:

https://issues.dlang.org/show_bug.cgi?id=18584

Implementation:
https://gist.github.com/Biotronic/5849af011cbe9c7ea05515011d5995bf

--
  Simen


Re: complex arithmetic in D: multiple questions

2018-03-09 Thread J-S Caux via Digitalmars-d-learn

On Friday, 9 March 2018 at 13:56:33 UTC, Nicholas Wilson wrote:
- I would expect the D `Complex!double` case to work faster 
than the `real` one. Why is it the other way around? [I can 
accept (and use) D with Complex!real running 1/3 the speed of 
C++ (but with increased accuracy), but I'd also love to be 
able to run D with `Complex!double` at C++ speeds, since the 
tradeoff might be worth it for some calculations]


because the double version is doing the exact same work as the 
real
except that it is also converting between real and double for 
atan2 (from arg). 
https://github.com/dlang/phobos/blob/master/std/math.d#L1352


I'm really not sure why phobos does that, it should't.


Is this a case for a bug report? Seems pretty bizarre to do that, 
like an oversight/neglect.


- what is the best way to correct the unfortunate (to be 
polite) omission of many standard mathematical functions from 
std.complex? [if I may be frank, this is a real pain for us 
scientists] There exists 
https://gist.github.com/Biotronic/17af645c2c9b7913de1f04980cd22b37 but can this be integrated (after improvements) in the language, or should I (re)build my own?


It will be much faster to build your own that just forward to 
the C functions (or LLVM intrinsics) see 
https://github.com/libmir/mir-algorithm/blob/master/source/mir/math/common.d#L126 for a starting point (we'd greatly appreciate pull requests for anything missing).
Even if the decision to make std.math behave at the appropriate 
precision is accepted, it will still take an entire release 
cycle (unless you use dmd master), and I'm not so sure it will.




OK thanks. I looked at libmir, and saw many good things there. I 
was wondering: is it still actively developed/maintained? How 
will it fit with the "core" D in the future? [I don't want to 
build dependencies to libraries which aren't there to stay in the 
long run, I want code which can survive for decades]. It would 
seem to me that some of the things included in there should be 
part of D core/std anyway.


Going further, I'm really wondering what the plan is as far as 
Complex is concerned. Right now it just feels neglected 
(half-done/aborted transition from creal etc to Complex, lots of 
missing basic functions etc), and is one major blocking point as 
far as adoption (among scientists) is concerned. Julia is really 
taking off with many of my colleagues, mostly because due respect 
was given to maths. I'd certainly choose Julia if it wasn't for 
the fact that I can't get my exploratory/testing codes to run 
faster than about 1/10th of my C++ stuff. It seems D could have 
such an appeal in the realm of science, but these little things 
are really blocking adoption (including for myself).



[related questions:


Did you press send too soon?


No, the related questions were linked in my previous post (just 
copied & pasted it further above, but didn't delete these last 
couple of words properly).


Thanks a lot Nicholas!



Re: How to fake a const method ?

2018-03-09 Thread Basile B. via Digitalmars-d-learn

On Friday, 9 March 2018 at 13:47:34 UTC, Basile B. wrote:

I would need this to work:

```
struct Foo
{
TypeInfo typeCache;

TypeInfo getTypeCache()
{
alias NotThePoint = ubyte;
if (typeCache is null)
typeCache = typeid(NotThePoint);
return typeCache;
}

TypeInfo type() const
{
alias NothrowType = TypeInfo delegate() const;
return (cast(NothrowType) )();
}
}

void main(){}
```

But get:

Error: mutable method `Foo.getTypeCache` is not callable using 
a `const` `this`



- `type()` really has to be const because it's used in an 
opEquals that's used by an AA (key is const so opEquals has to 
as well)
- `typeCache` is not used to compare 2 Foos so it really 
doesn't matter if it get assigned.


Solved...The error message helped much actually... problem is 
`this` is `const`


https://run.dlang.io/is/UOR2i2


Re: How to fake a const method ?

2018-03-09 Thread Basile B. via Digitalmars-d-learn

On Friday, 9 March 2018 at 13:54:07 UTC, Basile B. wrote:

On Friday, 9 March 2018 at 13:47:34 UTC, Basile B. wrote:
- `type()` really has to be const because it's used in an 
opEquals that's used by an AA (key is const so opEquals has to 
as well)


And the most annoying is that the non reduced Foo has a custom 
toHash that hashes a payload so the cast to const would really 
be perfectly valid.


Other annoying fact:

https://run.dlang.io/is/pmPSGr

It used to be accepted from 2.061 to 2.071.2


Re: complex arithmetic in D: multiple questions

2018-03-09 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 9 March 2018 at 12:34:40 UTC, J-S Caux wrote:

Please bear with me, this is a long question!
To explain, I'm a scientist considering switching from C++ to 
D, but before I do, I need to ensure that I can:
- achieve execution speeds comparable to C++ (for the same 
accuracy; I can accept a slight slowdown, call it 30%, to get a 
few more digits (which I typically don't need))
- easily perform all standard mathematical operations on 
complex numbers
- (many other things not relevant here: memory use, 
parallelization, etc).


In the two files linked below, I compare execution 
speed/accuracy between D and C++ when using log on complex 
variables:


https://www.dropbox.com/s/hfw7nkwg25mk37u/test_cx.d?dl=0
https://www.dropbox.com/s/hfw7nkwg25mk37u/test_cx.d?dl=0

The idea is simple: let a complex variable be uniformly 
distributed around the unit circle. Summing the logs should 
give zero.


In the D code, I've defined an "own" version of the log, 
log_cx, since std.complex (tragically!) does not provide this 
function (and many others, see recent threads 
https://forum.dlang.org/post/dewzhtnpqkaqkzxwp...@forum.dlang.org and https://forum.dlang.org/thread/lsnuevdefktulxlto...@forum.dlang.org, and issue https://issues.dlang.org/show_bug.cgi?id=18571).


[snip]

So simple C++ is thrice as fast as the best-achieved D I 
managed.


Now for my questions:
- I would expect the D `Complex!double` case to work faster 
than the `real` one. Why is it the other way around? [I can 
accept (and use) D with Complex!real running 1/3 the speed of 
C++ (but with increased accuracy), but I'd also love to be able 
to run D with `Complex!double` at C++ speeds, since the 
tradeoff might be worth it for some calculations]


because the double version is doing the exact same work as the 
real
except that it is also converting between real and double for 
atan2 (from arg). 
https://github.com/dlang/phobos/blob/master/std/math.d#L1352


I'm really not sure why phobos does that, it should't.

- what is the best way to correct the unfortunate (to be 
polite) omission of many standard mathematical functions from 
std.complex? [if I may be frank, this is a real pain for us 
scientists] There exists 
https://gist.github.com/Biotronic/17af645c2c9b7913de1f04980cd22b37 but can this be integrated (after improvements) in the language, or should I (re)build my own?


It will be much faster to build your own that just forward to the 
C functions (or LLVM intrinsics) see 
https://github.com/libmir/mir-algorithm/blob/master/source/mir/math/common.d#L126 for a starting point (we'd greatly appreciate pull requests for anything missing).
Even if the decision to make std.math behave at the appropriate 
precision is accepted, it will still take an entire release cycle 
(unless you use dmd master), and I'm not so sure it will.


- for my education, why was the decision made to go from the 
built-in types `creal` etc to the `Complex` type?


I think because they can be done in the library.
I personally don't think they should have been, they don't 
complicate things that much.



[related questions:


Did you press send too soon?


Re: How to fake a const method ?

2018-03-09 Thread Basile B. via Digitalmars-d-learn

On Friday, 9 March 2018 at 13:47:34 UTC, Basile B. wrote:
- `type()` really has to be const because it's used in an 
opEquals that's used by an AA (key is const so opEquals has to 
as well)


And the most annoying is that the non reduced Foo has a custom 
toHash that hashes a payload so the cast to const would really be 
perfectly valid.




[vibe.d/dub] Linker error

2018-03-09 Thread Chris via Digitalmars-d-learn

I got this error msg today (see below):

DUB version 1.8.0, built on Mar  3 2018
vibe.d version 0.8.3
dmd 2.078.3 (the same with 2.079.0 and 2.077.0)

.dub/build/server64_72_debug-debug-linux.posix-x86_64-dmd_2079-CAC4A12AC8FE4B4625A9511E4EFEB8F6/anscealai.o:
 In function 
`_D3std5range10primitives__T5doPutTSQBh6format__T11hasToStringTSQCj8typecons__T5TupleTAysTmZQnTaZ9__lambda1MFZ1STaZQDjFNaNbNiNfKQDpaZv':
/usr/include/dlang/dmd/std/range/primitives.d:269: undefined 
reference to 
`_D3std6format__T11hasToStringTSQBd8typecons__T5TupleTAysTmZQnTaZ9__lambda1MFZ1S3putMFNaNbNiNfaZv' [...and loads of other similar messages...]

collect2: error: ld returned 1 exit status
Error: linker exited with status 1
/usr/bin/dmd failed with exit code 1.

It is so massive that it must be something ridiculous.


How to fake a const method ?

2018-03-09 Thread Basile B. via Digitalmars-d-learn

I would need this to work:

```
struct Foo
{
TypeInfo typeCache;

TypeInfo getTypeCache()
{
alias NotThePoint = ubyte;
if (typeCache is null)
typeCache = typeid(NotThePoint);
return typeCache;
}

TypeInfo type() const
{
alias NothrowType = TypeInfo delegate() const;
return (cast(NothrowType) )();
}
}

void main(){}
```

But get:

Error: mutable method `Foo.getTypeCache` is not callable using 
a `const` `this`



- `type()` really has to be const because it's used in an 
opEquals that's used by an AA (key is const so opEquals has to as 
well)
- `typeCache` is not used to compare 2 Foos so it really doesn't 
matter if it get assigned.


complex arithmetic in D: multiple questions

2018-03-09 Thread J-S Caux via Digitalmars-d-learn

Please bear with me, this is a long question!
To explain, I'm a scientist considering switching from C++ to D, 
but before I do, I need to ensure that I can:
- achieve execution speeds comparable to C++ (for the same 
accuracy; I can accept a slight slowdown, call it 30%, to get a 
few more digits (which I typically don't need))
- easily perform all standard mathematical operations on complex 
numbers
- (many other things not relevant here: memory use, 
parallelization, etc).


In the two files linked below, I compare execution speed/accuracy 
between D and C++ when using log on complex variables:


https://www.dropbox.com/s/hfw7nkwg25mk37u/test_cx.d?dl=0
https://www.dropbox.com/s/hfw7nkwg25mk37u/test_cx.d?dl=0

The idea is simple: let a complex variable be uniformly 
distributed around the unit circle. Summing the logs should give 
zero.


In the D code, I've defined an "own" version of the log, log_cx, 
since std.complex (tragically!) does not provide this function 
(and many others, see recent threads 
https://forum.dlang.org/post/dewzhtnpqkaqkzxwp...@forum.dlang.org 
and 
https://forum.dlang.org/thread/lsnuevdefktulxlto...@forum.dlang.org, and issue https://issues.dlang.org/show_bug.cgi?id=18571).


First, speed/accuracy (times for 1M points in all cases):
D:
dmd, no flags:
Complex!real: re, im (should be 0): 
-9.24759400999786151942e-15	6.26324079407839123978e-14

time for 100 pts: 190 ms, 508 μs, and 9 hnsecs
Complex!double: re, im (should be 0): 
-1.96986871259241524967e-12	5.46260919029144254022e-09

time for 100 pts: 455 ms, 888 μs, and 7 hnsecs

dmd -release -inline -O:
Complex!real: re, im (should be 0): 
-9.24759400999786151942e-15	6.26324079407839123978e-14

time for 100 pts: 175 ms, 352 μs, and 3 hnsecs
Complex!double: re, im (should be 0): 
-4.23880765557105362133e-14	5.46260919029144254022e-09

time for 100 pts: 402 ms, 965 μs, and 7 hnsecs

ldc2, no flags:
Complex!real: re, im (should be 0): 
-9.24759400999786151942e-15	6.26324079407839123978e-14

time for 100 pts: 184 ms, 353 μs, and 9 hnsecs
Complex!double: re, im (should be 0): 
-1.96986871259241524967e-12	5.46260919029144254022e-09

time for 100 pts: 436 ms, 526 μs, and 8 hnsecs

ldc2 -release -O:
Complex!real: re, im (should be 0): 
-9.24759400999786151942e-15	6.26324079407839123978e-14

time for 100 pts: 108 ms and 966 μs
Complex!double: re, im (should be 0): 
-1.96986871259241524967e-12	5.46260919029144254022e-09

time for 100 pts: 330 ms, 421 μs, and 8 hnsecs

As expected accuracy with Complex!real is about 4 digits better, 
and the best combo is ldc2 with flags.


Now C++:
GCC 7.1.0, -O3:
complex: re, im (should be 0): 
(8.788326118779445e-13,1.433519814600731e-11)

time for 100 pts: 0.042751 seconds.

Apple LLVM version 9.0.0 (clang-900.0.39.2), -O3:
complex: re, im (should be 0): 
(-3.0160318686967e-12,1.433519814600731e-11)

time for 100 pts: 0.038715 seconds.

So simple C++ is thrice as fast as the best-achieved D I managed.

Now for my questions:
- I would expect the D `Complex!double` case to work faster than 
the `real` one. Why is it the other way around? [I can accept 
(and use) D with Complex!real running 1/3 the speed of C++ (but 
with increased accuracy), but I'd also love to be able to run D 
with `Complex!double` at C++ speeds, since the tradeoff might be 
worth it for some calculations]
- what is the best way to correct the unfortunate (to be polite) 
omission of many standard mathematical functions from 
std.complex? [if I may be frank, this is a real pain for us 
scientists] There exists 
https://gist.github.com/Biotronic/17af645c2c9b7913de1f04980cd22b37 but can this be integrated (after improvements) in the language, or should I (re)build my own?
- for my education, why was the decision made to go from the 
built-in types `creal` etc to the `Complex` type?


[related questions:


Re: does the shared keyword work with mutable structs?

2018-03-09 Thread Kagamin via Digitalmars-d-learn
To make a struct noncopyable, add @disable this(this); to it, 
then compiler will give an error on an attempt to copy it.


Re: does the shared keyword work with mutable structs?

2018-03-09 Thread Kagamin via Digitalmars-d-learn
spawn doesn't infer `ref` storage class and copies eventBuffer by 
value.