Re: extern (C++) including bodies of member functions?
On Friday, 15 July 2016 at 19:20:52 UTC, Jacob Carlborg wrote: Yes. Just as it's possible to call C function from D, it's possible to implement functions in D that can be called from C. This compatibility applies C++ and Objective-C as well. So, it applies to member functions too (for C++)? Just as if you passed an extern(C++) directive to each one? And only their signature/mangling is changed, so that say in gdb for instance, they represent Type::member instead of zzTypezdxqdstuffmember? The front end was only fairly recently converted to D. Oh, I thought it happened a while ago, like when D2 came out. (Or was D2 recent as well?)
Re: Template args
On Friday, 15 July 2016 at 23:07:20 UTC, Andrey wrote: Hi guys! Can any one tell me - how to pass an array of int's in to the template struct at compile-time, and how to use int there? Like this: https://dpaste.dzfl.pl/844057da81e9 ?
Template args
Hi guys! Can any one tell me - how to pass an array of int's in to the template struct at compile-time, and how to use int there?
Iterate through getOverloads trait
I'm wondering how I can use the output of __traits(getOverloads, a, "name"). The example in the doc uses direct indexing (like __traits(getOverloads, a, "name")[0](param)) and it works. But I'm struggling with iterating through the result or storing the resulting tuple into a local var. Example: https://dpaste.dzfl.pl/28a0057dbffd
Re: Variadic Tuple of Structs with Mixed Types
On Friday, 15 July 2016 at 17:41:21 UTC, Michael Coulombe wrote: Your issue is this line: alias boxAR(A) = Box!(A, R); This means that A must be a type, but you are trying to instantiate it with lambdas. If you switch to: alias boxAR(alias A) = Box!(A, R); But now you are back to the "local '__lambda1' as parameter to non-global template" error. I had tried it a few different and ended up with errors like that. Have you considered recursive solutions? Will try that next. Thanks.
Re: extern (C++) including bodies of member functions?
On 2016-07-15 19:52, cy wrote: I would never (ever) do this myself, but trying to understand dmd, the code is absolutely packed with things like this: extern(C++) class Package : ScopeDSymbol { ... override const(char)* kind() const { return "package"; } ... override final inout(Package) isPackage() inout { return this; } ...etc... } How exactly does that... work? Is the body of such a member function written in the D Programming Language? Yes. Just as it's possible to call C function from D, it's possible to implement functions in D that can be called from C. This compatibility applies C++ and Objective-C as well. When the D compiler sees a "extern(C++)" declaration it will adopt the code and output the data structures to be compatible with C++. For example, the location of the vtable, name mangling and so on. The documents say nothing about this, only defining their examples as stubs, like extern(C++) class Foo { void bar(); } The documentation also avoids any memory allocation in D, instead assuming C++ routines like createInstance to use malloc to allocate the classes. But the code in dmd makes extensive use of things like this: extern(C++) ... { final extern(D) this(...) { ... } } IIRC, it's not possible to call a C++ constructor from D. That's why "extern(D) this" is used to be able to do the memory allocation from the D side. How would you create new objects of types that are declared extern(C++)? Just new, and mark the constructor as extern(D)? I realize DMD is a horrible program that was Frankensteined from C++ code ages ago and is practically still C++ itself The front end was only fairly recently converted to D. -- /Jacob Carlborg
extern (C++) including bodies of member functions?
I would never (ever) do this myself, but trying to understand dmd, the code is absolutely packed with things like this: extern(C++) class Package : ScopeDSymbol { ... override const(char)* kind() const { return "package"; } ... override final inout(Package) isPackage() inout { return this; } ...etc... } How exactly does that... work? Is the body of such a member function written in the D Programming Language? Or is it some weird hybrid of D and C++ that just has a human programmer brain taking into account all the times that differing name mangling might produce different code? I mean, Package.resolve for instance is a non-trivial function. Can you not use templates inside such a function? Can you only use other "extern(C++)" types? Can you import from other modules, inside such a function? The documents say nothing about this, only defining their examples as stubs, like extern(C++) class Foo { void bar(); } The documentation also avoids any memory allocation in D, instead assuming C++ routines like createInstance to use malloc to allocate the classes. But the code in dmd makes extensive use of things like this: extern(C++) ... { final extern(D) this(...) { ... } } How would you create new objects of types that are declared extern(C++)? Just new, and mark the constructor as extern(D)? I realize DMD is a horrible program that was Frankensteined from C++ code ages ago and is practically still C++ itself, and that DMD has to have /full/ control of symbol mangling, but it is also sort of important, not just as a D compiler, but as one of the only programs left in the world that produces optimized assembly, rather than passing it on to gcc or LLVM. So, understanding it is kind of an interest of mine.
Re: Variadic Tuple of Structs with Mixed Types
On Friday, 15 July 2016 at 17:00:09 UTC, jmh530 wrote: I was working with the lightweight wrapper and it seemed to work for simple stuff, but then I started getting a bunch of errors when I tried to integrate it in to my project. Below is the stripped down version of what I've been working with. I think the problem is that I can't get the fillAliasSeq template to work with aliases. If I change Foo to just take types and pass something like int or float, then it works fine. Note, I originally had fillAliasSeq as a nested template within bar, but this was causing errors similar to what is brought up in this thread http://forum.dlang.org/post/mailman.578.1343005779.31962.digitalmars-d-le...@puremagic.com Your issue is this line: alias boxAR(A) = Box!(A, R); This means that A must be a type, but you are trying to instantiate it with lambdas. If you switch to: alias boxAR(alias A) = Box!(A, R); But now you are back to the "local '__lambda1' as parameter to non-global template" error. Have you considered recursive solutions? template fillAliasSeq(R, f...) { import std.meta : AliasSeq; static if (f.length == 0) { alias fillAliasSeq = AliasSeq!(); } else { alias fillAliasSeq = AliasSeq!(Foo!(f[0], R), fillAliasSeq!(R, f[1..$])); } }
Re: How to group similar member functions from different classes?
On Monday, 20 June 2016 at 16:39:54 UTC, Marc Schütz wrote: Untested: Seems to only work if A and B are both defined in the same file as Foos (defeating the purpose). Putting A and B in a.d and b.d respectively gives me these errors: a.d(2): Error: undefined identifier 'Foos' a.d(2): Error: mixin a.A.Foos!() is not defined b.d(2): Error: undefined identifier 'Foos' b.d(2): Error: mixin b.B.Foos!() is not defined I also tried switching it around, like // b.d import foos Foos; class B { mixin Foos; } but that of course gives the error: foos.d(4): Error: undefined identifier 'A' b.d(3): Error: mixin b.B.Foos!() error instantiating since you can't do a static if(typeof(this) == A) without importing A from a somehow. (you can do else static if(typeof(this) == B) without importing B though, since it does the branch for A first) I think a mixin here is just required, because you can't use an identifier before it's defined, even at compile time. Honestly, I have yet to find a use for mixin templates.
Re: Variadic Tuple of Structs with Mixed Types
On Saturday, 9 July 2016 at 05:40:10 UTC, ag0aep6g wrote: On 07/09/2016 12:33 AM, jmh530 wrote: I'm trying to create a tuple of variadic length containing structs with mixed types. So for instance, given struct Foo(T, U) { T x; U y; } I want to create something like Tuple!(Foo!(type1, type2), Foo!(type1, type3), ..., Foo!(type1, typeN)) x; The bar function (below) is what I've tried to use to create it. template bar(T, U...) if (U.length > 1) { import std.meta : staticMap; template baz(A) { import std.meta : AliasSeq; alias baz = AliasSeq!(T, A); } alias V = staticMap!(baz, U); alias bar = staticMap!(Foo, V); } void main() { import std.typecons : Tuple; Tuple!(bar!(int, float, int)) x; } My strategy was getting something like AliasSeq!(AliasSeq!(type1, type2), AliasSeq!(type1, type3), ... ) and then I can staticMap over that with Foo in order to create the correct type. However, I can't seem to get it working. Any ideas? AliasSeq expands automatically. That means, AliasSeq!(AliasSeq!(type1, type2), AliasSeq!(type1, type3)) is the same as AliasSeq!(type1, type2, type1, type3) You can see this in action with `pragma(msg, V);` which prints "(int, float, int, int)". Obviously, the next staticMap fails then, because it gets handed a list of individual types, but it should operate on pairs of types. You need to wrap your pairs in something stronger than AliasSeq. You can use a std.typecons.Tuple or a little custom template. Then you need to unwrap it before applying Foo, because Foo works on a pair of types not a Tuple or custom wrapper. Putting it together: template bar(T, U...) if (U.length > 1) { import std.meta : staticMap; import std.typecons : Tuple; alias baz(A) = Tuple!(T, A); alias V = staticMap!(baz, U); alias TupleToFoo(T : Tuple!(Types), Types ...) = Foo!Types; // Alternative TupleToFoo with less complex syntax: // alias TupleToFoo(T) = Foo!(T.Types); alias bar = staticMap!(TupleToFoo, V); } Or with a more lightweight, custom wrapper: template bar(T, U...) if (U.length > 1) { import std.meta : staticMap; template Box(stuff ...) { alias contents = stuff; } alias baz(A) = Box!(T, A); alias V = staticMap!(baz, U); alias BoxToFoo(alias box) = Foo!(box.contents); alias bar = staticMap!(BoxToFoo, V); } I was working with the lightweight wrapper and it seemed to work for simple stuff, but then I started getting a bunch of errors when I tried to integrate it in to my project. Below is the stripped down version of what I've been working with. I think the problem is that I can't get the fillAliasSeq template to work with aliases. If I change Foo to just take types and pass something like int or float, then it works fine. Note, I originally had fillAliasSeq as a nested template within bar, but this was causing errors similar to what is brought up in this thread http://forum.dlang.org/post/mailman.578.1343005779.31962.digitalmars-d-le...@puremagic.com struct Foo(alias fun, R) { } template fillAliasSeq(R, f...) { import std.meta : staticMap; template Box(stuff...) { alias contents = stuff; } alias boxAR(A) = Box!(A, R); alias fillContents = staticMap!(boxAR, f); alias contents(alias box) = Foo!(box.contents); alias fillAliasSeq = staticMap!(contents, fillContents); } template bar(funs...) { auto bar(int[] x) { import std.meta : staticMap; import std.typecons : Tuple; alias resultType = fillAliasSeq!(int[], funs); Tuple!(resultType) result; return result; } } void main() { int[] x = [1, 2, 5, 9]; alias f = (a, b) => a + b; alias g = (a, b) => a * b; //auto y = bar!(f, g)(x); //this is what I want to do alias z = fillAliasSeq!(int[], f, g); //but I can't even do this }
Re: How define such scheleton classes
Use an intermediate class: abstract class OtherObject1(S) : AbstractObject!S { abstract void Foo(int a, int b); class OtherObject(S, bool R) : OtherObject1!S { int x; override void Foo(int a, int b)
Re: Are templates with variadic value parameters possible?
On Friday, 15 July 2016 at 15:04:22 UTC, Devin Hill wrote: to the condition. It works pretty well! Granted, it doesn't allow for calling it in two ways like a variadic version would have: foo(1, 2, 3) // works with this setup foo([1, 2, 3]) // doesn't, but would only be occasionally useful anyway but all in all it's a decent workaround for the problem. It isn't too much effort to add support for both: ``` import std.traits : isArray, ForeachType; import std.stdio : writeln; void func(Args...)(Args args) if(is(Args[0] : long) || (isArray!(Args[0]) && is(ForeachType!(Args[0]) : long))) { static if(isArray!(Args[0])) { foreach(i; args[0]) writeln(i); } else { foreach(arg; args) writeln(arg); } } void main() { func(10, 20, 30, 40); func([1, 2, 3, 4, 5]); } ``` Or, alternatively, to support multiple arrays: ``` void func(Args...)(Args args) if(is(Args[0] : long) || (isArray!(Args[0]) && is(ForeachType!(Args[0]) : long))) { foreach(arg; args) { static if(isArray!(Args[0])) { foreach(i; arg) writeln(i); } else writeln(arg); } } void main() { func(10, 20, 30, 40); func([1, 2, 3, 4, 5], [100, 200, 300, 400]); } ```
How define such scheleton classes
abstract class AbstractObject(S) if (IsSomeString!S) { } class OtherObject(S, bool R) : AbstractObject!S { int x; void Foo(int a, int b) { x = a + b; static if (R) // error { // more codes . } } } class OtherObjects(S) : AbstractObject!S { OtherObject!(S, bool) a, b; // error a = new OtherObject!(S, true)(); b = new OtherObject!(S, false)(); }
Re: LDC with ARM backend
Hi Claude! On Friday, 15 July 2016 at 14:09:40 UTC, Claude wrote: Hello, I would like to cross-compile a D program from a x86 machine to an ARM target. [...] So I'm a bit confused of what the current state of LDC+ARM is. For example, is the run-time fully ported on ARM/Linux? LDC is fully ported to Linux/ARM. The current release also includes LDC pre-compiled for ARMv7 with hard floats (e.g. matches recent Raspberry hardware). On such a platform you can simply unpack the binary packages and LDC should run out of the box. What would be the steps to have an LDC cross-compiling to ARM? That is a somewhat different story. First, you need to built LLVM with support for ARM and then compile LDC against this version of LLVM. You can run ldc2 -version to see if the ARM target is supported. As Radu already mentioned, most of the required steps are described in the wiki at https://wiki.dlang.org/Build_LDC_for_Android. From a different perspective there is an old news post about cross-compiling to AArch64, too: http://forum.dlang.org/post/fhwvxatxezkafnalw...@forum.dlang.org. There is a reason why we do not distribute a binary version of LDC with all LLVM targets enabled. LDC still uses the real format of the host. This is different on ARM (80bit on Linux/x86 vs. 64bit on Linux/ARM). Do not expect that applications using real type work correctly. (The Windows version of LDC uses 64bit reals. The binary build has the ARM target enabled.) Regards, Kai
Re: LDC with ARM backend
On Friday, 15 July 2016 at 15:02:15 UTC, Radu wrote: Hi, LDC on Linux ARM is fairly complete. I think it is a fully supported platform (all tests are passing). Check in https://wiki.dlang.org/Compilers the LDC column. This is the close for a tutorial for cross-compiling https://wiki.dlang.org/Build_LDC_for_Android builds. Great, I didn't see it. However I don't use Android on my ARM target, I have a arm-none-linux-gnueabi toolchain. I think I have to change the Android patch, keep the "80-bit float" stuff, and modify the build scripts somehow to use GNU version.
Re: Interior immutability and rvalues
On 07/15/2016 02:51 PM, maik klein wrote: Thanks I didn't know that you could have type qualifiers inside templates, D still surprises me sometimes. Qualifiers are part of the type. So wherever you can have a type, you can have a qualified type. I don't think it is practical to call move on "everything", for example maybe you just want to pass a `ref` or a `class`. Does move do something bad with class references? I would expect it to just copy the reference, maybe null the original. I'm not sure what you mean by passing a ref. ref is specified in the signature of the called function. So it depends on someOtherTest if the argument is passed by ref, and you have to check that if you don't know the signature beforehand. But it doesn't matter if the variable is copyable or not.
Re: Are templates with variadic value parameters possible?
On Friday, 15 July 2016 at 05:23:15 UTC, Basile B. wrote: even better: template sameType(T...) { import std.meta; static if (!T.length) enum sameType = false; else enum sameType = NoDuplicates!T.length == 1; } Yeah, that's basically what I ended up doing, but since I also needed to constrain the type of T, I added is(T[0] : long) to the condition. It works pretty well! Granted, it doesn't allow for calling it in two ways like a variadic version would have: foo(1, 2, 3) // works with this setup foo([1, 2, 3]) // doesn't, but would only be occasionally useful anyway but all in all it's a decent workaround for the problem.
Re: LDC with ARM backend
On Friday, 15 July 2016 at 14:09:40 UTC, Claude wrote: Hello, I would like to cross-compile a D program from a x86 machine to an ARM target. I work on GNU/Linux Ubuntu 64-bit. I have an ARM gcc toolchain, which I can use to make programs on an ARM Cortex-A9 architecture running a Linux kernel 3.4.11+. I managed to build and install LLVM 3.8.1 with LDC 1.1-alpha1, which works fine to build and run native programs. I read some documentation here: http://wiki.dlang.org/Minimal_semihosted_ARM_Cortex-M_%22Hello_World%22 ... but it seems to target bare-metal programming, whereas I already have a GNU/Linux running on my ARM target and want to use it. It does noty tell how to have an LDC with ARM backend. So I'm a bit confused of what the current state of LDC+ARM is. For example, is the run-time fully ported on ARM/Linux? What would be the steps to have an LDC cross-compiling to ARM? Thanks Hi, LDC on Linux ARM is fairly complete. I think it is a fully supported platform (all tests are passing). Check in https://wiki.dlang.org/Compilers the LDC column. This is the close for a tutorial for cross-compiling https://wiki.dlang.org/Build_LDC_for_Android builds.
LDC with ARM backend
Hello, I would like to cross-compile a D program from a x86 machine to an ARM target. I work on GNU/Linux Ubuntu 64-bit. I have an ARM gcc toolchain, which I can use to make programs on an ARM Cortex-A9 architecture running a Linux kernel 3.4.11+. I managed to build and install LLVM 3.8.1 with LDC 1.1-alpha1, which works fine to build and run native programs. I read some documentation here: http://wiki.dlang.org/Minimal_semihosted_ARM_Cortex-M_%22Hello_World%22 ... but it seems to target bare-metal programming, whereas I already have a GNU/Linux running on my ARM target and want to use it. It does noty tell how to have an LDC with ARM backend. So I'm a bit confused of what the current state of LDC+ARM is. For example, is the run-time fully ported on ARM/Linux? What would be the steps to have an LDC cross-compiling to ARM? Thanks
Re: Interior immutability and rvalues
On Friday, 15 July 2016 at 12:05:47 UTC, ag0aep6g wrote: On 07/15/2016 10:29 AM, maik klein wrote: [...] Sure. Just instantiate Rc with a const/immutable T. I.e., write `Rc!(const int)` instead of `const Rc!int`. Or with auto and makeRc: `auto rc = makeRc(immutable int(5));`. [...] When you pass an rvalue to a function, the parameter inside the function is still an lvalue. The argument being an rvalue just means that you can't pass it in a ref parameter. [...] Ok, not being copyable is the problem. [...] If args[0] can be moved, can args[1] and args[2] be moved, too? I mean, can you just move everything without testing for hasElaborateCopyConstructor? Just a thought. Thanks I didn't know that you could have type qualifiers inside templates, D still surprises me sometimes. I don't think it is practical to call move on "everything", for example maybe you just want to pass a `ref` or a `class`.
Re: Result Types and void usage
On Friday, 15 July 2016 at 11:36:27 UTC, ag0aep6g wrote: On 07/15/2016 10:11 AM, nik wrote: [...] [...] [...] void is somewhat special. It can't be used to declare variables or as a parameter type. So you'll have to approach this a bit differently. You also can't have a struct constructor with zero parameters. [...] Cool, that's neat and has the syntax I'm looking for. Thanks for your help Nik
Re: Interior immutability and rvalues
On 07/15/2016 10:29 AM, maik klein wrote: There are two things that bothered me for quite some time Interior immutability: Consider a something like this https://dpaste.dzfl.pl/fa5be84d26bc The implementation is totally wrong and it doesn't make sense, but it shows that Rc can not be const/immutable because at least "dup" needs to increment the counter. Is it possible to express that Rc should be mutable but the value that it wraps should be either mutable or const/immutable? Sure. Just instantiate Rc with a const/immutable T. I.e., write `Rc!(const int)` instead of `const Rc!int`. Or with auto and makeRc: `auto rc = makeRc(immutable int(5));`. Rvalues and forwarding: The problem is that when you pass an rvalue to a function you lose the information that is an rvalue. There is nothing like std::forward from c++ that I am aware of. When you pass an rvalue to a function, the parameter inside the function is still an lvalue. The argument being an rvalue just means that you can't pass it in a ref parameter. That becomes a problem when I use variadics with non copyable types. I need to call move on types that can not be copied. Ok, not being copyable is the problem. I guess what I could do is to use https://dlang.org/phobos/std_traits.html#hasElaborateCopyConstructor to detect which types in the variadic args are actually non copyable and then call .move on them. Is this how you would do it? The use case would be something like this void test(Args...)(Args args){ someOtherTest(args); // doesn't work because args contains some non copyable types } void test(Args...)(Args args){ someOtherTest(mixin forward!(args)); } //expands to void test(Args...)(Args args){ someOtherTest(args[0].move, args[1], args[2]); } If args[0] can be moved, can args[1] and args[2] be moved, too? I mean, can you just move everything without testing for hasElaborateCopyConstructor? Just a thought.
Re: unittests not being run
On 07/15/2016 04:16 PM, Jerry wrote: > Unittests have to be inside a module to be run on DMD atleast. > So putting module foo at top should fix it. Strange. Still not getting picked up. $ dmd --version DMD64 D Compiler v2.071.0 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright [app.d] module app; import std.stdio; private int incBy1(int i) { return i + 1; } unittest { assert(incBy1(1) == 200); } void main() { writeln(incBy1(1)); // which prints 2 } [/app.d] $ dub test Generating test runner configuration '__test__library__' for 'library' (library). Performing "unittest" build using dmd for x86_64. dplay ~master: building configuration "__test__library__"... Linking... Running ./__test__library__ All unit tests have been run successfully. -- Bahman
Re: persistence, serialization, history (run-to-run) in small self-contained program
On 2016-07-15 04:17, dan wrote: Thanks Jacob! I was unaware of Orange. Available on Dub now as well: https://code.dlang.org/packages/orange -- /Jacob Carlborg
Re: unittests not being run
Unittests have to be inside a module to be run on DMD atleast. So putting module foo at top should fix it.
Re: Bug? somearrayofclassinstances.filter(...).array fails because of .init() method in class
On 07/15/2016 12:54 PM, dom wrote: i just had a scenario like the one below. when calling .array on the filterresult dmd goes nuts because of the init() function in Players. Renaming to initialize() solved the problem. Solution: As .init is used for struct initialization and such (https://dlang.org/spec/property.html#init) i think it should be a restricted keyword for class members and methods Known issue. https://issues.dlang.org/show_bug.cgi?id=14237 https://issues.dlang.org/show_bug.cgi?id=7066 Of course, being known doesn't mean that anyone is actively working on a fix. Feel free to make (a little) noise on Bugzilla, or in the General group.
Re: Result Types and void usage
On 07/15/2016 10:11 AM, nik wrote: One thing I cant figure out/don't know if is possible is to have a type that takes "void" (see last unittest) [...] Result type: struct Result(T, E) { this(inout T result) inout { _result = result; _is_result = true; } this(inout E error) inout { _error = error; _is_result = false; } bool is_result() const pure nothrow @safe @property { return _is_result; } T result() const pure nothrow @safe @property { return _result; } bool is_error() const pure nothrow @safe @property { return !_is_result; } E error() const pure nothrow @safe @property { return _error; } private: T _result; bool _is_result; E _error; } void is somewhat special. It can't be used to declare variables or as a parameter type. So you'll have to approach this a bit differently. You also can't have a struct constructor with zero parameters. You can detect void and make it a special case where slightly different code is generated: struct Result(T, E) { static if (!is(T == void)) this(inout T result) inout { ... } ... T result() const pure nothrow @safe @property { static if (!is(T == void)) return _result; } ... static if (!is(T == void)) T _result; bool _is_result = true; /* important when T is void */ } [...] //unittest //{ //auto result_1 = Result!(void, string)(void); //auto result_2 = Result!(void, string)(void); `void` can't be an argument in D. Just leave the list empty: `Result!(void, string)()`. //assert(result_1.is_result); //assert(result_1 == result_2); //}
Re: Result Types and void usage
On Friday, 15 July 2016 at 08:11:13 UTC, nik wrote: //unittest //{ // auto result_1 = Result!(void, string)(void); // auto result_2 = Result!(void, string)(void); // assert(result_1.is_result); // assert(result_1 == result_2); //} You wanted to handle the void case? Because there are no void type you have to check the type at compile time. Enter static if... static if(!is(T == void)) { T result() const pure nothrow @safe @property { return _result; } } static if(!is(T == void)) T _result; static if(!is(T == void)) { this(inout T result) inout { _result = result; _is_result = true; } } else { this() { _is_result = true; //Or whatever semantics Rust use for void result } } And about conditional compilation (static if, version etc...): https://dlang.org/spec/version.html
unittests not being run
The test I have in 'app.d' don't get picked up by 'dub test' in a freshly created project by 'dub init'. $ dub test Generating test runner configuration '__test__library__' for 'library' (library). Performing "unittest" build using dmd for x86_64. dplay ~master: building configuration "__test__library__"... Linking... Running ./__test__library__ All unit tests have been run successfully. [app.d] import std.stdio; private int incBy1(int i) { return i + 1; } unittest { assert(foo(1) == 200); } void main() { writeln("hi"); } What am I missing? Thanks in advance, -- Bahman
Bug? somearrayofclassinstances.filter(...).array fails because of .init() method in class
i just had a scenario like the one below. when calling .array on the filterresult dmd goes nuts because of the init() function in Players. Renaming to initialize() solved the problem. Solution: As .init is used for struct initialization and such (https://dlang.org/spec/property.html#init) i think it should be a restricted keyword for class members and methods experienced programmers ofc know that .init is used in special ways and avoid it. newcomers like me have a hard time with such cases. class Players { void init() { ... } ... } auto candidates = players.filter!(x => { return x.active && x.getName().indexOf(searchstring) > -1; }).array;
Re: how to mark an extern function @nogc?
On Wednesday, 13 July 2016 at 02:20:58 UTC, anonymous wrote: On Tuesday, 12 July 2016 at 14:04:55 UTC, Seb wrote: D is entirely driven by highly motivated volunteers. (this will change soon with the new D foundation) With the fundation, volunteers wont be highly motivated anymore. Fundations are real motivation-killers. I disagree. Volunteers will be motivated more, because D will now be more reliable as a thing they put their effort into and rely upon. Right now D is moving at relatively slow pace, because everybody works on it in their spare time. That also means they don't have spare time anymore. Somebody has to work on it full-time.
Re: Problems with -fPIC, libraries and exceptions (in linux?)
Just as a follow-up, I think it's looking more and more like a compiler bug. It works properly both with gdc and ldmd2. Should I make a bug report about that?
Interior immutability and rvalues
There are two things that bothered me for quite some time Interior immutability: Consider a something like this https://dpaste.dzfl.pl/fa5be84d26bc The implementation is totally wrong and it doesn't make sense, but it shows that Rc can not be const/immutable because at least "dup" needs to increment the counter. Is it possible to express that Rc should be mutable but the value that it wraps should be either mutable or const/immutable? Rvalues and forwarding: The problem is that when you pass an rvalue to a function you lose the information that is an rvalue. There is nothing like std::forward from c++ that I am aware of. That becomes a problem when I use variadics with non copyable types. I need to call move on types that can not be copied. I guess what I could do is to use https://dlang.org/phobos/std_traits.html#hasElaborateCopyConstructor to detect which types in the variadic args are actually non copyable and then call .move on them. Is this how you would do it? The use case would be something like this void test(Args...)(Args args){ someOtherTest(args); // doesn't work because args contains some non copyable types } void test(Args...)(Args args){ someOtherTest(mixin forward!(args)); } //expands to void test(Args...)(Args args){ someOtherTest(args[0].move, args[1], args[2]); }
Result Types and void usage
Hi all, I've been using D for a week now to compare it to Rust as a replacement to C++. One thing I miss from Rust is https://doc.rust-lang.org/std/result/ and its companion https://doc.rust-lang.org/std/macro.try!.html They make for some nice syntax so I had a go at recreating them in D (below): One thing I cant figure out/don't know if is possible is to have a type that takes "void" (see last unittest) For example in Rust a can declare a Result of Result<(), ErrorType> however I'm struggling to find the same semantics in D. Of course I can just use a bool but I'd prefer not to. Thank you for your time Nik Result type: struct Result(T, E) { this(inout T result) inout { _result = result; _is_result = true; } this(inout E error) inout { _error = error; _is_result = false; } bool is_result() const pure nothrow @safe @property { return _is_result; } T result() const pure nothrow @safe @property { return _result; } bool is_error() const pure nothrow @safe @property { return !_is_result; } E error() const pure nothrow @safe @property { return _error; } private: T _result; bool _is_result; E _error; } unittest { auto result = Result!(int, string)(1); assert(result.is_result); assert(result.result == 1); } unittest { auto result = Result!(int, string)("error"); assert(result.is_error); assert(result.error == "error"); } unittest { auto result_1 = Result!(int, string)(1); auto result_2 = Result!(int, string)(1); assert(result_1 == result_2); } unittest { auto result_1 = Result!(int, string)(1); auto result_2 = Result!(int, string)(2); assert(result_1 != result_2); } unittest { auto result_1 = Result!(int, string)(1); auto result_2 = Result!(int, string)("error"); assert(result_1 != result_2); } unittest { auto result_1 = Result!(int, string)("error"); auto result_2 = Result!(int, string)("error"); assert(result_1 == result_2); } unittest { auto result_1 = Result!(int, string)("an error"); auto result_2 = Result!(int, string)("error"); assert(result_1 != result_2); } unittest { enum ErrorType{A_Error, B_Error} auto result = Result!(int, ErrorType)(ErrorType.A_Error); assert(result.error() == ErrorType.A_Error); auto result_2 = Result!(immutable(bool), ErrorType)(true); assert(result_2.result()); Result!(immutable(bool), ErrorType) a_method() { return Result!(immutable(bool), ErrorType)(true); } assert(a_method().result()); } unittest { auto result_1 = Result!(bool, string)(true); assert(result_1.result); } //unittest //{ // auto result_1 = Result!(void, string)(void); // auto result_2 = Result!(void, string)(void); // assert(result_1.is_result); // assert(result_1 == result_2); //}