Re: LDC / BetterC / _d_run_main
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
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
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
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)
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
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?
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)
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?
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?
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
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
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
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
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 ?
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
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
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
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
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 ?
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 ?
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
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 ?
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
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 ?
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
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?
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?
spawn doesn't infer `ref` storage class and copies eventBuffer by value.