Re: Best practices of using const
On Wednesday, 13 February 2019 at 16:40:18 UTC, H. S. Teoh wrote: On Wed, Feb 13, 2019 at 11:32:46AM +, envoid via Digitalmars-d-learn wrote: [...] Const in D is very restrictive because it's supposed to provide real compiler guarantees, i.e., it's statically verifiable that the data cannot be changed. [...] I keep hearing how const is nigh unusable in D, and except for ranges I litter my code with const everywhere, pretty much just as often as I used in C++. I normally only use `auto` for return types and input ranges, and nearly all of my function parameters are `in`. It's true that a lot of people don't use `const` because I keep finding and filing bugs in dub libraries as soon as I try using them, but other than that: const is fine.
Re: How do I use libraries manually?
On Tuesday, 5 February 2019 at 20:39:50 UTC, Murilo wrote: On Tuesday, 5 February 2019 at 19:46:32 UTC, H. S. Teoh wrote: Thank you very much, I will try what you just explained. And yes I would really appreciate it if people would make single file libraries that I can just import as if it were any other .d file. That doesn't work in the aggregate. Any non-trivial library will need to be split up into packages and modules. There might be tasks to be performed before or after the build. There might be different build configurations. There might be external C library dependencies. The library might have dependencies of its own, so the possible complications are recursive. Just use dub, it's easier. I don't think there's any good reason to not use it.
Re: How can I express the type of a function in D?
On Wednesday, 30 January 2019 at 05:14:20 UTC, Sobaya wrote: I want to get a mangled name of a D function by `core.demangle.mangle`, but I'm in trouble because there are no ways to express a type of a function, which is used for a template argument of `mangle`. There's a way: int add(int i, int j); static assert(is(typeof(add) == typeof(*(int function(int, int)).init))); Unfortunately there's no dedicated syntax for it, unlike C++. Weirdly enough, if you pragma(msg) a function type it prints it out in C++ syntax (e.g. `int(int, int)`), but if you type it yourself it won't compile. Then there's this oddity: https://issues.dlang.org/show_bug.cgi?id=19270
Re: using dub to compile plugins
On Wednesday, 19 December 2018 at 12:57:14 UTC, Codifies wrote: I am currently using this dub.sdl name"runz80" targetType "executable" lflags "libz80/libz80.a" however I will be creating a number of plugins, each plugin will consist of a single source file, I'd like the plugin source directory to be separate from main source directory and compile the plugins (.so) to a (binary) plugins directory (the plugins will be dynamically loaded at runtime - I've previously done this in C so I don't anticipate any particular issues - famous last words!) I could do this with a few simple rules in a Makefile, but I have no clue how to achieve this using dub. can someone show me a concrete example of doing this ? Ideally just dropping a new source file into the plugins source folder should produce a new .so the next time dub is run, without having to explicitly add each plugin to the dub file... Unless the plugins have dub dependencies, don't use dub for it. Plugins that do can have their own dub.sdl/json with targetType "dynamicLibrary". Ideally just dropping a new source file into the plugins source folder should produce a new .so the next time dub is run, without having to explicitly add each plugin to the dub file... I don't see how you can do this with dub, and I wouldn't attempt it either. Just use make, and have make call dub for the main project (and potentially any plugins that need it). Remember to make the dub targets `.PHONY` since you don't want to be managing the D dependencies by hand.
Re: Why does nobody seem to think that `null` is a serious problem in D?
On Thursday, 29 November 2018 at 18:31:41 UTC, SimonN wrote: On Monday, 19 November 2018 at 21:23:31 UTC, Jordi Gutiérrez Hermoso wrote: When I was first playing with D, I managed to create a segfault What's the reasoning for allowing this? 100 % agree that there should be non-nullable class references, they're my main missing feature in D. Likewise, I'm astonished that only few D users wish for them. https://github.com/aliak00/optional/blob/master/source/optional/notnull.d "But I don't like the verbosity!" alias MyClass = NotNullable!MyClassImpl;
Re: Why does nobody seem to think that `null` is a serious problem in D?
On Friday, 30 November 2018 at 06:15:29 UTC, O-N-S (ozan) wrote: On Monday, 19 November 2018 at 21:23:31 On Monday, 19 November 2018 at 21:23:31 UTC, Jordi Gutiérrez Hermoso wrote: I'm not the only one who has done this. I can't find it right now, but I've seen at least one person open a bug report because they misunderstood this as a bug in dmd. I have been told a couple of times that this isn't something that needs to be patched in the language, but I don't understand. It seems like a very easy way to generate a segfault (and not a NullPointerException or whatever). I love Null in an empty class variable and I use it very often in my code. It simplifies a lot. What would be a better way? (practical not theoretical) Regards Ozan A better way is to always initialise. Invalid states should be unrepresentable.
Re: Can I create static c callable library?
On Thursday, 27 September 2018 at 23:53:50 UTC, Steven Schveighoffer wrote: On 9/27/18 8:16 AM, Atila Neves wrote: On Tuesday, 25 September 2018 at 14:13:50 UTC, Jacob Carlborg wrote: On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M Davis wrote: If you use -betterC, then it's trivial, because your D program is restricted to extern(C) functions and features which don't require druntime. It can also be done without -betterC (and thus with druntime), but it gets to be _way_ more of a pain, because it requires that you manually initialize druntime - either by forcing whatever is using your "C" library to call a specific function to initialize druntime before using any of its normal functions or by having every function in the library check whether druntime has been initialized yet and initialize it if it hasn't been before it does whatever it's supposed to do. Shouldn't it be possible to use a C initialization function, i.e. pragma(crt_constructor) to initialize druntime? Then it only needs to be initialized once and it's not required to check if it's initialized all the time. -- /Jacob Carlborg Even easier, compile this C file and add the resulting object file to your (now mostly) D static library: --- extern int rt_init(void); extern int rt_term(void); __attribute__((__constructor__)) void dinit(void) { rt_init(); } __attribute__((__destructor__)) void dterm(void) { rt_term(); } --- The C runtime will initialise the D runtime for you. I will point out that this is EXACTLY what pragma(crt_constructor) does. Really? Huh. You live, you learn. I didn't even know that pragma existed - it's not listed here at all: https://dlang.org/spec/pragma.html And my comments still aren't answered -- I'm not sure whether this works correctly or not, as we don't test initializing druntime before C main runs. It's worked for me in practice. Since C initialization functions have no order to them, it's possible that some initialization functions in the D runtime are using uninitialized pieces of the C runtime No, that can't happen. The C runtime is initialised no matter what you do (unless you write `_start` yourself), _then_ the global constructors are run. The code I wrote isn't standard C - it's just that gcc/clang/cl are all also C++ compilers so they chose to extend the already existing functionality to C.
Re: Can I create static c callable library?
On Tuesday, 25 September 2018 at 14:13:50 UTC, Jacob Carlborg wrote: On Tuesday, 25 September 2018 at 12:05:21 UTC, Jonathan M Davis wrote: If you use -betterC, then it's trivial, because your D program is restricted to extern(C) functions and features which don't require druntime. It can also be done without -betterC (and thus with druntime), but it gets to be _way_ more of a pain, because it requires that you manually initialize druntime - either by forcing whatever is using your "C" library to call a specific function to initialize druntime before using any of its normal functions or by having every function in the library check whether druntime has been initialized yet and initialize it if it hasn't been before it does whatever it's supposed to do. Shouldn't it be possible to use a C initialization function, i.e. pragma(crt_constructor) to initialize druntime? Then it only needs to be initialized once and it's not required to check if it's initialized all the time. -- /Jacob Carlborg Even easier, compile this C file and add the resulting object file to your (now mostly) D static library: --- extern int rt_init(void); extern int rt_term(void); __attribute__((__constructor__)) void dinit(void) { rt_init(); } __attribute__((__destructor__)) void dterm(void) { rt_term(); } --- The C runtime will initialise the D runtime for you.
Re: Access to structures defined in C
On Wednesday, 19 September 2018 at 00:46:54 UTC, Joe wrote: On Tuesday, 18 September 2018 at 13:47:50 UTC, Atila Neves wrote: Sorry, Atila, I got confused looking at my two cases. I should have said "an array of ints", e.g., int yp[] = {2, 4, 0}; int yq[] = {10, 12, 0}; That makes more sense. int *ys[] = {yp, yq, 0}; This isn't even valid C code. It is, because C treats 'yp' as a pointer. It wasn't with the definition of `yp` and `yq` you posted. In D, I first declared these as int[] yp = [2, 4]; int[] yq = [10, 12]; __gshared int*[] ys = [ &yp, &yq ]; D dynamic arrays are not equivalent to C arrays. It's hard to see what you're trying to do with the code you posted. Have you tried instead to use a tool to translate the C headers? At this point, I've translated everything, even the code above. I had to use 'immutable(int [])' in the second and higher level arrays like 'ys' so that they could refer to 'yp' and 'yq' (without the address operators). This would be the literal translation: int[3] yp = [2, 4, 0]; int[3] yq = [10, 12, 0]; int*[3] ys; shared static this() { ys = [yp.ptr, yq.ptr, null]; } However, I still would like to have a deeper understanding of the "static variable yp cannot be read at compile time" error messages which went away when I declared yp immutable. I guess immutable makes everything known at compile-time? I didn't even know that was a thing. In any case, the reason why you got those error messages is because initialisation of global variables in D happens at compile-time. If you want runtime initialisation like in C++, you have to use static constructors like in my code above.
Re: Access to structures defined in C
On Tuesday, 18 September 2018 at 02:39:39 UTC, Joe wrote: On Sunday, 10 June 2018 at 17:59:12 UTC, Joe wrote: That worked but now I have a more convoluted case: a C array of pointers to int pointers, e.g., int **xs[] = {x1, x2, 0}; int *x1[] = {x1a, 0}; int *x2[] = {x2a, x2b, 0}; ... int x2a[] = { 1, 3, 5, 0}; Only the first line is exposed (and without the initialization). So I tried: extern(C) __gshared extern int**[1] xs; After a long hiatus, I'm back to working on something related to the above, but now that various other C pieces have been converted to D I'm down to converting these static arrays to D. There are two arrays that are giving me trouble. The second type is like that shown above. The first is a simpler array of pointers to int, e.g., int *yp = {2, 4, 0}; int *yq = {10, 12, 0}; This is valid C in the sense that it compiles, but I doubt it does what you think it does. This is equivalent code: int *yp = 2; int *yq = 10; int *ys[] = {yp, yq, 0}; This isn't even valid C code. In D, I first declared these as int[] yp = [2, 4]; int[] yq = [10, 12]; __gshared int*[] ys = [ &yp, &yq ]; D dynamic arrays are not equivalent to C arrays. It's hard to see what you're trying to do with the code you posted. Have you tried instead to use a tool to translate the C headers?
Re: Is it possible to translate this API's C headers?
On Monday, 17 September 2018 at 19:13:06 UTC, Jonathan M Davis wrote: On Monday, September 17, 2018 7:43:21 AM MDT Kagamin via Digitalmars-d-learn wrote: try dpp https://github.com/atilaneves/dpp Since according to Mike's post, it's C++ code, dpp wouldn't help, because it currently only supports C and not C++. - Jonathan M Davis It does C++ as well, just not all (or even close at this point) of it. I doubt it'd work on any real C++ codebase right now, but who knows. It definitely won't if any of the headers use the standard library, which is likely to happen. It turns out that parsing C++ is a lot of work. Who knew? :P
Re: Temporary file creation for unittests
On Monday, 21 May 2018 at 15:20:14 UTC, Dr.No wrote: On Monday, 21 May 2018 at 15:16:11 UTC, Atila Neves wrote: On Friday, 18 May 2018 at 15:16:52 UTC, Russel Winder wrote: Hi, What's the current official position on how to create temporary files for use during a unittest. I found Not official, but... import unit_threaded; with(const Sandbox()) { writeFile("myfile.txt", "contents"); shouldExist("myfile.txt"); shouldEqualContent("myfile.txt", "contents"); fileShouldContain("myfile.txt", "cont"); } Atila I've never seen "should" being in used in function names before... There's a whole lot of them here: https://github.com/atilaneves/unit-threaded/blob/master/source/unit_threaded/should.d
Re: Temporary file creation for unittests
On Monday, 21 May 2018 at 17:03:40 UTC, Russel Winder wrote: On Mon, 2018-05-21 at 15:16 +, Atila Neves via Digitalmars-d-learn wrote: On Friday, 18 May 2018 at 15:16:52 UTC, Russel Winder wrote: > Hi, > > What's the current official position on how to create > temporary files for use during a unittest. I found Not official, but... import unit_threaded; with(const Sandbox()) { writeFile("myfile.txt", "contents"); shouldExist("myfile.txt"); shouldEqualContent("myfile.txt", "contents"); fileShouldContain("myfile.txt", "cont"); } Atila OK, we like this. A lot. :) Given I use Unit-Threaded, why did I not know this. Ah, OK, RTFM. :-) It's got so many features that I don't know how to document everything and make it accessible at the same time. Did I mention how much I like this RAII approach? Me too - RAII is definitely C++'s gift to the world. I've been abusing `with` lately quite a bit. I think it's underused.
Re: Temporary file creation for unittests
On Friday, 18 May 2018 at 15:16:52 UTC, Russel Winder wrote: Hi, What's the current official position on how to create temporary files for use during a unittest. I found Not official, but... import unit_threaded; with(const Sandbox()) { writeFile("myfile.txt", "contents"); shouldExist("myfile.txt"); shouldEqualContent("myfile.txt", "contents"); fileShouldContain("myfile.txt", "cont"); } Atila
Re: howto run unittest of a single module in dub driven project?
On Sunday, 4 March 2018 at 10:43:06 UTC, Arjan wrote: Is it somehow possible to only run the unittests of a single d file within a dub project? Of course without resorting to typing the complete commandline with all versions includes switches etc. You could use unit-threaded: http://code.dlang.org/packages/unit-threaded You'd still need to build everything, but `dub test` would take care of that. I started working on, and need to get back to, a way of only building one module and needed dependencies. Atila
Re: What is "stringImportPaths"
On Wednesday, 6 December 2017 at 20:17:55 UTC, Ali Çehreli wrote: On 12/06/2017 11:05 AM, mrphobby wrote: > importing is a construct used for importing symbols, right? That's the import statement. -J compiler switch is about the import expression: https://dlang.org/spec/expression.html#import_expressions Ali I went looking for that and didn't find it! I searched for "string imports" but apparently that doesn't quite work.
Re: What is "stringImportPaths"
On Wednesday, 6 December 2017 at 19:05:24 UTC, mrphobby wrote: Can anyone explain what "stringImportPaths" is? I have seen this being used in dub.json files and I think I kind of know what it does, but I haven't been able to find a clear explanation in any documentation of what it does. It does not look like anything I'm familiar with from other languages. I understand it can be used for resources but I have seen it being used with both text files and binary files so I'm a bit confused. The documentation says I can import "whatever", but that feels a bit weird since importing is a construct used for importing symbols, right? stringImportPaths are to -J what importPaths are to -I. In D you can import a string directly into your program, similarly to #include in C and C++. Imagine it as kind of a mixin(read("filename")) (which you can't do). For security concerns, dmd only looks for "filename" in directories passed in with -J. A silly example: foo.d: import std.stdio; void main() { mixin(`auto values = [` ~ import("foo.txt") ~ `];`); writeln(values); } foo.txt: 1, 2, 3, 4, 5 $ dmd -J. foo.d $ ./foo [1, 2, 3, 4, 5] Atila
Re: Does dmd not always compile all of the source code?
On Wednesday, 6 December 2017 at 19:40:49 UTC, A Guy With a Question wrote: On Wednesday, 6 December 2017 at 19:19:09 UTC, A Guy With a Question wrote: It seems D's fast compile times are achieved by skipping semantic checking and even parsing when it doesn't feel it's needed. I strongly disagree with this decision. This could leave complex dormant time bombs that break builds unexpectedly and even accidentally. It's understandable in certain situations where there is enough information, but the first step to testing code, is first making sure it compiles...I don't want the compiler making decisions on what is worthy to compile. If I pass a d source file into it, I want to know if it's valid. This is unfortunate. This might be a deal breaker for me. I'm very concerned of working with a language that, at minimum, doesn't let me know if a file I passed in even contains valid code. It does let you know if it contains valid code - if you're actually building it. If you write unit tests but never compile them in, whether or not they make any sense is IMHO irrelevant. If you write a template and never instantiate it, does it make a sound?* Imagine this: version(Windows) int i = 0; else foobarbaz; Should it fail to compile on Linux? How is this any different from: #ifdef _WIN32 int i = 0; #else ohnoes #endif As noted by others, C++ templates work similarly. And for good reason! Atila * https://en.wikipedia.org/wiki/If_a_tree_falls_in_a_forest
Re: Does dmd not always compile all of the source code?
On Wednesday, 6 December 2017 at 16:07:41 UTC, A Guy With a Question wrote: Noticed several typos that dmd seems to have not picked up initially. Does dmd not compile all source code? I obviously wouldn't expect it to recompile something unnecessarily, but in a few cases I've just seen it not throw errors where it should have. It depends on how you're invoking it. In all likelihood, you had typos in uninstantiated templates. Atila
Re: How to specify 64 bit architecture in dub configuration file?
On Friday, 10 November 2017 at 09:18:34 UTC, Nicholas Wilson wrote: On Friday, 10 November 2017 at 08:30:39 UTC, OlaOst wrote: Using 'dub --arch=x86_64' will get you a 64 bit build, but is it possible to specify 64 bit architecture in the configuration file, so one can just type 'dub' and get a 64 bit build? "dflags" : "-m64" will work. You can probably use a less quick and dirty solution with a proper configuration. Or edit your dmd.conf to include -m64 as a default. It'll work but dub will complain. I really wish it didn't. Atila
Re: For fun: Expressive C++ 17 Coding Challenge in D
On Tuesday, 3 October 2017 at 19:25:56 UTC, Ali Çehreli wrote: Found on Reddit: https://www.reddit.com/r/programming/comments/740617/the_expressive_c17_coding_challenge/ How would you do it in D? Ali P.S. You can ignore the following note from the challenge text; I don't think it applies to D. Honestly, I don't think it matters for C++17 either. :) "You can assume input files won't be super large and can fit fully into memory." I can't bring myself to code a solution in C++17 or D. In C++17 it'd be too painful, and in D so trivial it'd probably make me sleep out of boredom. Maybe that should be our new catchphrase: "D: Making programming boring" :P Atila
Re: C++ Interfacing:'static' array function parameter contradiction
On Saturday, 29 April 2017 at 06:22:03 UTC, ParticlePeter wrote: On Saturday, 29 April 2017 at 01:49:56 UTC, Atila Neves wrote: On Friday, 28 April 2017 at 18:41:22 UTC, kinke wrote: [...] The worst part about that is mangling aside, the two declarations are identical to the compiler. Atila In this context, can anybody explain [1], in particular, in this case, one should extern( C++ ) void cppSArray( ref float[3] color ); instead of: extern( C++ ) void cppSArray( float* color ); Others and me in this discussion seem to agree that parameter (float color[3]) is equivalent to (float* color) in C++ world. [1] http://dlang.org/spec/interfaceToC.html#passing_d_array It's "just" the mangling. If it were `extern(C)` there'd be nothing to talk about. Atila
Re: C++ Interfacing:'static' array function parameter contradiction
On Friday, 28 April 2017 at 18:41:22 UTC, kinke wrote: On Friday, 28 April 2017 at 18:07:49 UTC, ParticlePeter wrote: Interesting, your example corresponds to my third case, the linker error. I am on Window, building an x64 App, afaik in that case the MS Visual Studio linker is used instead of optilink. Will add your findings to the bug report. Apparently Microsoft's C++ compiler doesn't mangle `float arg[3]` parameters identically to `float* arg`: void cppSArray(float color[3]) => ?cppSArray@@YAXQEAM@Z void cppPtr(float* color) => ?cppPtr@@YAXPEAM@Z The worst part about that is mangling aside, the two declarations are identical to the compiler. Atila
Re: COM Expertise needed: COM Callbacks
On Monday, 24 April 2017 at 00:55:45 UTC, Nierjerson wrote: Still trying to get the com automation code working. This is a general issue with COM programming as I do not have the experience to solve the problem. [...] I tried looking at this because I just did some COM work even if most of it in C++. There's a _lot_ of code and I was instantly lost, even with your explanations. I'd forget about Photoshop for now, just write a simple COM client. That'd also ease in getting other people to help because having Photoshop is a high barrier for entry. Can you get this to work in C++?
Re: Stuck with DMD, and Unit-Threaded
On Tuesday, 18 April 2017 at 07:07:16 UTC, Russel Winder wrote: On Mon, 2017-04-17 at 22:56 +, Atila Neves via Digitalmars-d-learn wrote: […] https://github.com/russel/ApproxGC/pull/2 Unfortunately the auto generated integration test main file doesn't quite work (feel free to file a bug on unit-threaded) so in that PR I disabled auto-generating it and force added my edited version. What I did there in dub.sdl is my current go-to solution for also running integration tests with unit-threaded. Thanks for that, much appreciated. I am hesitant to commit the pull request for now in case get_ut_main gets fixed fairly quickly. For the moment I am progressing with the SCons build since I got it working. I wouldn't hold my breath - the fix is annoying and non-trivial. Basically I special cased "source" since it's the default for dub packages but "test-source" gums up the works and I'd have to look at it properly. The real joy is that I have Unit-Threaded working. It's extensions of the unittest D language feature make testing D codes far more fun than the basic feature. Thanks for putting in the effort. I'm happy the work is appreciated :) Atila
Re: Stuck with DMD, and Unit-Threaded
On Sunday, 16 April 2017 at 08:20:21 UTC, Russel Winder wrote: There are points when you need to ask someone for help… I am trying to get Dub to build integration tests from test-source as a separate thing from building unit tests from source. The latter is easy and works, as does building the application. I cannot however get the integration tests to build, I always get something along the lines of: ../../../../../../../tmp/dub_test_root-677ee80a-1e29-44c8-b08c-2fe37eb83633.d(10,12): Error: function D main conflicts with static import dub_test_root.main at ../../../../../../../tmp/dub_test_root-677ee80a-1e29-44c8-b08c-2fe37eb83633.d(3,15) and I haven't a clue. This is almost certainly just a bad dub.sdl file, but, if anyone can take a look at tell me what I am failing to get right, I'd appreciate it. https://github.com/russel/ApproxGC https://github.com/russel/ApproxGC/pull/2 Unfortunately the auto generated integration test main file doesn't quite work (feel free to file a bug on unit-threaded) so in that PR I disabled auto-generating it and force added my edited version. What I did there in dub.sdl is my current go-to solution for also running integration tests with unit-threaded. Atila
Re: C++ namespace mangling: bug or me being stupid?
On Tuesday, 28 March 2017 at 16:30:19 UTC, kinke wrote: That's a mangling compression scheme (possibly tunable via gcc options), from https://github.com/gchatelet/gcc_cpp_mangling_documentation: To save space a compression scheme is used where symbols that appears multiple times are then substituted by an item from the sequence : S_, S0_, S1_, S2_, etc ... As to nested C++ namespaces - `extern(C++, ns1) { ... extern(C++, ns2) { ... } }` should work in a single D file. Not only good to know, this... fixed it. So I was being stupid. Thanks! Atila
Re: C++ namespace mangling: bug or me being stupid?
On Tuesday, 28 March 2017 at 16:30:19 UTC, kinke wrote: That's a mangling compression scheme (possibly tunable via gcc options), from https://github.com/gchatelet/gcc_cpp_mangling_documentation: To save space a compression scheme is used where symbols that appears multiple times are then substituted by an item from the sequence : S_, S0_, S1_, S2_, etc ... As to nested C++ namespaces - `extern(C++, ns1) { ... extern(C++, ns2) { ... } }` should work in a single D file. Good to know, thanks! Atila
C++ namespace mangling: bug or me being stupid?
I'm trying to wrap a C++ library and have reduced my problem case to the code below. I get a linker error due to different name mangling (this is on Linux): main.d:(.text._Dmain+0x13): undefined reference to `_ZN3ns13ns212createStructERN3ns17OptionsE' The C++ object file has instead a symbol called _ZN3ns13ns212createStructERNS_7OptionsE. To make matters worse and me more confused, according to https://demangler.com, they both demangle to the same thing: `ns1::ns2::createStruct(ns1::Options&)`. If you're wondering why there's two D files it's because trying to do: extern(C++, ns1) {... } extern(C++, ns1.ns2) {...} doesn't compile since there would be two D versions of ns1, which is... mildly annoying. I even took `const` off of the parameter in case that was the problem but clearly not. Atila impl.cpp: namespace ns1 { struct Options { }; struct Struct { }; namespace ns2 { ns1::Struct* createStruct(Options&) { return nullptr; } } } header.d: extern(C++, ns1) { struct Options { } struct Struct { } } main.d: extern(C++, ns1.ns2) { import header; Struct* createStruct(ref Options); } void main() { import header; Options options; auto s = createStruct(options); }
Re: Weird template error in Phobos (after editing) that I can't quite get. Compiler bug?
On Wednesday, 22 March 2017 at 14:06:56 UTC, Atila Neves wrote: isInputRange looks like this: template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke popFront() auto h = r.front; // can get the front of the range })); } [...] Got the same error when I changed it to: enum isInputRange(R) = is(typeof({...})); Which might explain why it's still inside an explicit template declaration. Or not, this whole thing is weird to me. Atila
Weird template error in Phobos (after editing) that I can't quite get. Compiler bug?
isInputRange looks like this: template isInputRange(R) { enum bool isInputRange = is(typeof( (inout int = 0) { R r = R.init; // can define a range object if (r.empty) {} // can test for empty r.popFront; // can invoke popFront() auto h = r.front; // can get the front of the range })); } If I change the `enum bool` line to `enum bool isInputRange = true && is(typeof(`, all is fine. If instead I: enum foo = true; enum bool isInputRange = foo && is(typeof( Then: std/range/primitives.d(352): Error: static assert "Cannot put a char[] into a Appender!string." std/format.d(1877):instantiated from here: put!(Appender!string, char[]) std/format.d(1784):instantiated from here: formatUnsigned!(Appender!string, ulong, char) std/format.d(1755):instantiated from here: formatIntegral!(Appender!string, ulong, char) std/format.d(3778):... (3 instantiations, -v to show) ... std/typecons.d(421):instantiated from here: format!(char, ulong, ulong) std/encoding.d(3468):instantiated from here: Tuple!(BOM, "schema", ubyte[], "sequence") Surely they should be identical? Obviously I was trying to do something else with an enum, but this is the reduced sample. Atila
Re: Can't send messages to tid spawned in a Windows DLL. Bug?
On Thursday, 16 February 2017 at 15:14:25 UTC, kinke wrote: On Thursday, 16 February 2017 at 12:07:40 UTC, Atila Neves wrote: This fails for me in a DLL: auto tid = spawn(&func); assert(tid != Tid.init); If I print out the tid, I find that its message box is null. This is odd, since according the code in std.concurrency there's nothing weird about how it gets a message box, it's just `auto spawnTid = Tid(new MessageBox);`. So... `new` is returning null??? The really weird thing is that a thread is spawned and func starts executing. I just can't send it any messages without crashing. Atila If you suspect `new` of returning null, a GC issue seems likely. Is your DLL linked statically against druntime, thus having its own GC? Or are you using a shared druntime (and thus GC) across multiple binaries? Whatever's default on Windows 32-bit. The thing is, all other uses of GC allocations in the same DLL work as expected. Atila
Can't send messages to tid spawned in a Windows DLL. Bug?
This fails for me in a DLL: auto tid = spawn(&func); assert(tid != Tid.init); If I print out the tid, I find that its message box is null. This is odd, since according the code in std.concurrency there's nothing weird about how it gets a message box, it's just `auto spawnTid = Tid(new MessageBox);`. So... `new` is returning null??? The really weird thing is that a thread is spawned and func starts executing. I just can't send it any messages without crashing. Atila
Re: How do I call a C++ struct default constructor from D?
On Tuesday, 7 February 2017 at 10:46:24 UTC, kinke wrote: On Tuesday, 7 February 2017 at 10:15:09 UTC, Atila Neves wrote: I can declare a C++ struct like so: extern(C++, mynamespace) struct Foo { //... } But... I don't want to repeat the initialisation code for that struct's default constructor. I can't declare one in D because D doesn't allow default constructors for structs. What's my way out? Thanks, Atila I'm afraid there's no way out. I summarized some of my C++ interop findings incl. default constructor here: http://forum.dlang.org/thread/nqxsdehlydizatopr...@forum.dlang.org Ugh, I was afraid of that. I ended up having to write (!) a C++ function that returned the default-initialised struct and called that from D. It got uglier soon after... I've only every done trivial C++ integration before. As soon as I tried something "real" it all broke down incredibly fast. Probably going to have to file some bugs on name mangling. Atila
How do I call a C++ struct default constructor from D?
I can declare a C++ struct like so: extern(C++, mynamespace) struct Foo { //... } But... I don't want to repeat the initialisation code for that struct's default constructor. I can't declare one in D because D doesn't allow default constructors for structs. What's my way out? Thanks, Atila
Re: Why is &array[0] @safer than array.ptr?
On Tuesday, 24 January 2017 at 11:32:47 UTC, TheFlyingFiddle wrote: On Tuesday, 24 January 2017 at 11:28:17 UTC, Atila Neves wrote: void main() { foo; } void foo() @safe { int[] array; auto ptr = array.ptr; } foo.d(7): Deprecation: array.ptr cannot be used in @safe code, use &array[0] instead &array[0] is incredibly ugly and feels like an unnecessary hack, and I'm wondering why it's @safe. Atila Just a speculative guess. unittest @safe { int[] array; auto ptr = array.ptr; //could be null auto ptr2 = &array[0]; //Does a bounds check? auto ptr3 = &array[5]; //Should do a bounds check. } &array[5] makes sense to bounds check, and I guess then the issue is I could instead do `array.ptr + 5` which would be bad. But it's still annoying to have to do &array[0] just to pass it to a C function, since `my_c_func(array.ptr)` isn't going to screw up anything. BTW, in that example above array.ptr is null even though array is null. It doesn't crash. Atila
Why is &array[0] @safer than array.ptr?
void main() { foo; } void foo() @safe { int[] array; auto ptr = array.ptr; } foo.d(7): Deprecation: array.ptr cannot be used in @safe code, use &array[0] instead &array[0] is incredibly ugly and feels like an unnecessary hack, and I'm wondering why it's @safe. Atila
Re: Does anyone know of an sdl-mode for Emacs?
On Wednesday, 4 January 2017 at 18:50:21 UTC, Russel Winder wrote: On Wed, 2017-01-04 at 17:24 +, Atila Neves via Digitalmars-d-learn wrote: It's getting tedious editing dub.sdl files with no editor support. If nobody's written one, I will. Emacs has an sdlang-mode. It's on MELPA so installable via packages. Huh. I guess I search for sdl-mode when I didn't find it. Thanks! Atila
Does anyone know of an sdl-mode for Emacs?
It's getting tedious editing dub.sdl files with no editor support. If nobody's written one, I will. Atila
Re: import("dir/file") does not work
On Wednesday, 18 May 2016 at 05:11:51 UTC, Vadim Lopatin wrote: Hello, Is it intended that import of file as array does not work if path is specified for import file name? import("dir/file.ext"); // does not work import("file.ext"); // works if dir is added to -J list I believe it would be convenient if I could just specify one -J path (e.g. -Jviews) and import any file from nested directories just by providing relative path from one of -J dirs. (checked on latest DMD under Windows; replacing / with \\ does not help) Best regards, Vadim That was a bug that was recently fixed. Atila
Re: Why does Reggae use mixins?
On Saturday, 16 April 2016 at 13:04:24 UTC, Nordlöw wrote: On Friday, 15 April 2016 at 13:18:46 UTC, Nordlöw wrote: Why does the build system Reggae use mixins everywhere in the D examples? https://github.com/atilaneves/reggae Correction, it can do stuff either at CT or run-time as show here: https://github.com/atilaneves/reggae/blob/master/doc/basics.md Could somebody highlight when either is adviced? Mixins are used so a D build description can be written at module-scope, thereby looking like a scripting language. The only reason this is important is to enable builds that have run-time logic, which is pretty much all of the high-level rules (since they have to read the file system). the build template mixin doesn't have to be used, the only thing reggae wants from a build description written in D is that there be one and exactly one function with the signature: Build func(); That's the function that gets called to generate the build. Since I'm lazy I created a template mixin to write the function for me, which again means that all definitions can be at module-scope. Basically it's so that the file looks like: alias exe = executable!(...); mixin build!(exe); Instead of: Build myBuild() { auto exe = executable(...); return Build(exe); } Atila
Initializing global delegate variable - bug or on purpose?
int delegate(int) dg = (i) => i * 2; Error: non-constant nested delegate literal expression __lambda3 int delegate(int) dg; static this() { dg = i => i * 2; // ok } Am I doing anything wrong? Atila
Re: Whitch can replace std::bind/boost::bind ?
On Friday, 18 March 2016 at 10:50:34 UTC, Dsby wrote: foreach (i ; 0..4) { auto th = new Thread(delegate(){listRun(i);});//this is erro _thread[i]= th; th.start(); } void listRun(int i) { writeln("i = ", i); // the value is not(0,1,2,3), it all is 2. } I want to know how to use it like std::bind. I would suggest not using Thread directly: foreach(i; 0..4) { auto tid = spawn(&listRun, i); //from std.concurrency _tid[i] = tid; } Atila
Re: If stdout is __gshared, why does this throw / crash?
On Sunday, 6 March 2016 at 01:28:52 UTC, Marco Leise wrote: Got it now: https://issues.dlang.org/show_bug.cgi?id=15768 writeln() creates a copy of the stdout struct in a non thread-safe way. If stdout has been assigned a File struct created from a file name this copy includes a "racy" increment/decrement of a reference count to the underlying C-library FILE*. In the case that the reference count is erroneously reaching 0, the file is closed prematurely and when Glibc tries to access internal data it results in the observable SIGSEGV. Nice, good work! Atila
Re: If stdout is __gshared, why does this throw / crash?
On Sunday, 6 March 2016 at 01:10:58 UTC, Anon wrote: On Saturday, 5 March 2016 at 14:18:31 UTC, Atila Neves wrote: [...] Note that `1000.iota.parallel` does *not* run 1000 threads. `parallel` just splits the work of the range up between the worker threads (likely 2, 4, or 8, depending on your CPU). I see the effect you describe with any parallel workload. Smaller numbers in place of 1000 aren't necessarily splitting things off to additional threads, which is why smaller numbers avoid the multi-threaded problems you are encountering. Err, right. [...] `File` uses ref-counting internally to allow it to auto-close. `stdout` and friends are initialized in a special way such that they have a high initial ref-count. When you assign a new file to stdout, the ref count becomes one. As soon as one of your threads exits, this will cause stdout to close, producing the odd errors you are encountering on all the other threads. I would avoid reassigning `stdout` and friends in favor of using a logger or manually specifying the file to write to if I were you. I see. Here's my problem: I want to make it so code not under my control doesn't get to write to stdout and stderr. I don't see any other way but to reassign stdout. Maybe I can manually bump up the ref count? Atila
Re: Dub and unit-threaded import problem
On Saturday, 5 March 2016 at 15:05:50 UTC, Casey wrote: Hello, I'm just starting a small project with dub and unit-threaded, but I'm getting an issue where the file "unit_threaded.d" cannot be found. [...] You mispelled "dependencies". Atila
If stdout is __gshared, why does this throw / crash?
With a small number of threads, things work as intended in the code below. But with 1000, on my machine it either crashes or throws an exception: import std.stdio; import std.parallelism; import std.range; void main() { stdout = File("/dev/null", "w"); foreach(t; 1000.iota.parallel) { writeln("Oops"); } } I get, depending on the run, "Bad file descriptor", "Attempting to write to a closed file", or segfaults. What am I doing wrong? Atila
Re: How would you implement this in D? (signals & slots)
On Tuesday, 2 February 2016 at 17:35:25 UTC, Chris Wright wrote: On Tue, 02 Feb 2016 15:59:06 +, Atila Neves wrote: [...] I've seen this sort of thing before. A blogger I used to follow, Jeremy Miller, implemented an event broker using this pattern. I don't like it. It requires a new type for each event, and you have to defensively use that pattern even if you only have one event at the moment. Every time I implemented an event system, I've gone with named events and no special type for their parameters. [...] Nice. I liked your example and Kagamin's better than mine. Atila
Re: How would you implement this in D? (signals & slots)
On Tuesday, 2 February 2016 at 14:49:21 UTC, Gerald wrote: On Monday, 1 February 2016 at 21:44:28 UTC, Enjoys Math wrote: On Monday, 1 February 2016 at 21:40:45 UTC, Enjoys Math wrote: module signals_and_slots; import std.algorithm: remove; [...] D's signals & slots: https://dlang.org/phobos/std_signals.html I looked at that and perhaps I'm not reading the exampes correctly but I'm not sure how useful std.signals is in the real world. If you have a bunch of slots which take the same parameter types, not unusual in the GUI world, how would that work? Switch on the value inside the slot. Or use different types by wrapping, say, an int or a string with a struct: import std.stdio; import std.signals; struct String1 { string s; } struct String2 { string s; } class Observer { void watch1(String1) { writeln("watch1"); } void watch2(String2) { writeln("watch2"); } } class Signals { mixin Signal!String1; mixin Signal!String2; } void main() { auto o = new Observer; auto s = new Signals; s.connect(&o.watch1); s.connect(&o.watch2); s.emit(String1("foo")); s.emit(String2("bar")); } The other thing that bugs me is lack of naming for slots and signals, again in the GUI world where you typically have dozens of these on an an individual widget differentiation is quite important. Slots are named: the methods are slots. Signals can be named if you use only one struct as the parameter, as above. The signals would be String1 and String2, the slots watch1 and watch2. Atila
Re: virtual destructor in C++ integration: bug or me being stupid?
On Tuesday, 29 December 2015 at 18:41:41 UTC, Adam D. Ruppe wrote: On Tuesday, 29 December 2015 at 18:32:23 UTC, Atila Neves wrote: The problem here is that I don't know what the workaround is. The one I used (well, last time I tried this) was to just put a dummy function in the D interface that is a placeholder for it. interface C++Class { // at the same place as void _dontCallMeIamjustadestructor(); void other_function_you_actually_want(); } Ugh. As long as it works... thanks! Atila
virtual destructor in C++ integration: bug or me being stupid?
cpp.cpp: class Oops { public: virtual ~Oops() {} virtual int number() const { return 42; } }; Oops* newOops() { return new Oops; } d.d: import std.stdio; extern(C++) { interface Oops { int number() const; } Oops newOops(); } void main() { auto oops = newOops(); writeln(oops.number()); } I get garbage in the output (I found this due to a crash in much more complicated code). If I comment out the virtual destructor, it works. It seems that the presence of the virtual destructor changes the layout and D doesn't know about it. Thinking about it now, it makes sense, how would D know? The problem here is that I don't know what the workaround is. Abstract classes in C++ usually have virtual destructors... Atila
Re: struct constructor co nfusion
On Friday, 6 November 2015 at 17:34:29 UTC, Spacen Jasset wrote: Hello, I have read various things about struct constructors, specifically 0 argument constructors, and using opCall and @disable this(); which no longer seems to work. What I am after I think is the behavior of C++'s structs on the stack, namely for some or all of these uses at a given time: 1. Allocation on the stack 2. Value type semantics 3. RAII (combined with (1) often) This is common in D as well. The difference to C++ is 0-argument struct constructors to do extra work to satisfy invariants. Is it the case that a struct should now be used with a factory method? Does this also mean that the struct destructor must be It's the easiest way to emulate C++'s 0-argument struct constructors. made to work when .init is called instead of the factory method? If the factory method isn't called, then yes, the destructor shouldn't blow up just because all the struct members are T.init. This idiom is inconsistent with struct constructors that do have one or more arguments, and I think that this question is likely to arise time immemorial from others who are not expecting this particular inconstancy. How is it inconsistent? Nobody stops me from doing this: struct Struct { void* ptr = cast(void*)5; this(int size) { ptr = malloc(size); } ~this() { free(ptr); } } void main() { auto ok = Struct(10); //auto oops = Struct.init; } Atila
Re: Access violation when calling C DLL from D
On Monday, 2 November 2015 at 02:30:09 UTC, AnoHito wrote: On Monday, 2 November 2015 at 02:13:29 UTC, BBasile wrote: On Monday, 2 November 2015 at 01:02:45 UTC, AnoHito wrote: [...] the headers are very long and complicated, and porting them entirely to D would be a huge project in and of itself. [...] You can give a try at h2d, the C header to D interface converter: http://dlang.org/htod.html I did, but it just produced a ton of errors... Try this instead: https://github.com/jacob-carlborg/dstep It's been used to convert C Ruby declarations to D: https://github.com/jacob-carlborg/orbit/tree/master/ruby Atila
Re: D serialization temporary fixup?
On Friday, 23 October 2015 at 16:27:11 UTC, Shriramana Sharma wrote: Shriramana Sharma wrote: I'd just like to have a quick but reliable way to store real and int data types into a binary data file and read therefrom. Is there such a solution? Wow thank you people! Nice to know I can do rawWrite and also have other options. BTW is there a reason that either msgpack or cerealed are not made part of Phobos but developed separately? Developing a library and getting it on the dub registry is easy. Getting a whole library into Phobos is incredibly hard. Atila
Re: D serialization temporary fixup?
On Thursday, 22 October 2015 at 16:15:23 UTC, Shriramana Sharma wrote: I wanted a D equivalent to: http://doc.qt.io/qt-5/qdatastream.html https://docs.python.org/3/library/pickle.html and saw that one is under construction: http://wiki.dlang.org/Review/std.serialization But till it's finalized, I'd just like to have a quick but reliable way to store real and int data types into a binary data file and read therefrom. Is there such a solution? The size of the data is fixed, but especially since I have real values, I'd like to not write to limited fixed decimal text format. https://github.com/atilaneves/cerealed Atila
Re: How to do unittests
On Friday, 2 October 2015 at 10:22:40 UTC, Namal wrote: On Wednesday, 30 September 2015 at 14:44:20 UTC, qsdf wrote: On Wednesday, 30 September 2015 at 14:20:28 UTC, Namal wrote: [...] D unit tests are like a stack of free functions. You put them separatly. when there's a main: dmd -unittest a.d -- module a; void main(){} unittest{} -- when there is no main: (like std.uri): dmd -main -unittest a.d -- module a; unittest{} -- the -main switch adds a dummy main function so that the output can be executed. But most of the time you'll think that nothing happens because the tests succeed... So do I understand it right that it stops after the first failed test? Is it possible to continue and get a list of all failed tests? http://code.dlang.org/packages/unit-threaded https://github.com/D-Programming-Language/phobos/pull/3207 Atila
Re: Range of variables
On Wednesday, 30 September 2015 at 20:11:56 UTC, Freddy wrote: Is there a way to make a range of a variables lazily? --- int var1; int var2; void func() { int var3; auto range = /*range of var1,var2,var3*/ ; } --- std.range.iota Atila
Re: Why getting private member fails using getMember trait in a template?
On Tuesday, 29 September 2015 at 09:40:41 UTC, Alexandru Ermicioi wrote: On Saturday, 26 September 2015 at 10:10:39 UTC, Alexandru Ermicioi wrote: Suppose we have, two modules: module testOne; [...] So, is this behavior correct? If yes, then why? Yes, because private members aren't accessible from another module. If they need to be accessed, then they need to be public. Atila
Re: Dub package with C code
On Thursday, 24 September 2015 at 11:38:08 UTC, Sebastiaan Koppe wrote: On Thursday, 24 September 2015 at 08:35:40 UTC, Edwin van Leeuwen wrote: Alternatively you could use reggea to build both. I want to use dub. Simply because of code.dlang.org. Or can reggae also pull packages from there? Yes. Atila
Re: No -v or -deps for gdc?
On Tuesday, 15 September 2015 at 18:12:56 UTC, Johannes Pfau wrote: Am Tue, 15 Sep 2015 12:19:34 + schrieb Atila Neves : gdmd supports those options but gdc doesn't. Is that likely to always be the case? Atila gdmd is just a wrapper around gdc. If something is supported by gdmd it must also be supported by gdc (the exact switch names might differ). See: https://github.com/D-Programming-GDC/GDMD/blob/master/dmd-script Seems like -v maps to -fd-verbose and -deps to -fdeps. Ah cool, thanks! Atila
No -v or -deps for gdc?
gdmd supports those options but gdc doesn't. Is that likely to always be the case? Atila
Re: Is D suitable for my latest project?
On Sunday, 6 September 2015 at 14:36:53 UTC, chris stevens wrote: Hi All, I am considering using D for my latest project and there are a few features I would like and am not entirely sure at this point whether D has them. They are: - dynamic creation of classes/structs at runtime (think I can emulate this with variants/dynamic) At runtime, no. However... if it doesn't actually need to be runtime and is in the code itself you can have code be generated at compile time. - dynamic compilation of code files at runtime Only by running a compiler. But as above, if it doesn't strictly have to be at runtime and everything is specified in the source files, you can compute strings at compile-time and mix them in to generate code. - some basic code creation tools mixin, template mixin, CTFE. Are the above possible? It really depends on what you want to do. A lot of the dynamic code generation that goes on is done at runtime because that's what other languages support. In my experience a lot of those use-cases can be done at compile-time in D. A famous example is compile-time regular expressions. Unless you're writing a tool similar to grep, all regexes in your program are known at compile-time. They don't _need_ to be parsed/interpreted/compiled at run-time, that's just what every other language that isn't D does. So, if your use-case depends on information from the file-system, user interaction, networking, etc. then your only choice is to generate text files with D code and compile it. If, on the other hand, it's all defined by the code you write, then D has excellent compile-time code generation tools at your disposal. Atila
Re: What is "FilterResult" type?
On Wednesday, 9 September 2015 at 07:19:06 UTC, Bahman Movaqar wrote: On Tuesday, 8 September 2015 at 18:45:33 UTC, Jonathan M Davis wrote: If you're returning a range, you should be returning auto. @Jonathan, @cym13 and @Meta It's reasonable to use `auto`. However there are times when you need to pass the `auto` value to another function and the receiving function needs to know the type of its input arguments. No, it doesn't. It needs to know what the compile-time interface is, i.e. what it can do with that type. If the type in question happens to be an InputRange, then the consumer function would be: void func(R)(R range) if(isInputRange!R) { ... } instead of using a concrete type like this: void func(MyType range) { ... } That way you can change range types and `func` doesn't care. Atila
Re: What is the D way to map a binary file to a structure?
On Saturday, 29 August 2015 at 12:56:08 UTC, cym13 wrote: Hi, Let's say I have a simple binary file whose structure is well-known. Here is an example which stores points: struct Point { long x; long y; long z; } struct BinFile { uintmagicNumber; // Some identifier ulong pointsNumber; Point[] points; // Array of pointsNumber points. } What is the best way to read some file and fill a structure with it? Would reading the file into a void[] and then casting it to the struct work with things like internal struct padding? https://github.com/atilaneves/cerealed Just pass the bytes obtained from reading the file to `Decerealiser`. Atila
Re: post on using go 1.5 and GC latency
On Saturday, 22 August 2015 at 06:54:43 UTC, Ola Fosheim Grøstad wrote: On Saturday, 22 August 2015 at 06:48:48 UTC, Russel Winder wrote: But one that Google are entirely happy to fully fund. Yes, they have made Go fully supported on Google Cloud now, so I think it is safe to say that Google management is backing Go fully. I'm kinda hoping for Go++... The other day I thought it'd be hilarious if I did a Bjarne and wrote a preprocessor to generate Go code that would accept a superset of Go syntax but added generics, function overloading, etc. And, of course, called it Go++. Alas, 'tis too much work for just the lulz. I'd rather spend the time making D better. Atila
Re: Compiletime Vs Runtime bencmarks
On Monday, 17 August 2015 at 14:43:35 UTC, D_Learner wrote: Hello everyone . I need advice on my first D-project . I have uploaded it at :- [...] I wouldn't compare benchmarks without optimisations turned on. Atila
Re: dmd.conf... again
On Wednesday, 12 August 2015 at 15:49:37 UTC, Joakim Brännström wrote: On Wednesday, 12 August 2015 at 15:30:09 UTC, Atila Neves wrote: [...] From man ld :) -l namespec Add the archive or object file specified by namespec to the list of files to link. This option may be used any number of times. If namespec is of the form :filename, ld will search the library path for a file called filename, otherwise it will search the library path for a file called libnamespec.a. On systems which support shared libraries, ld may also search for files other than libnamespec.a. Specifically, on ELF and SunOS systems, ld will search a directory for a library called libnamespec.so before searching for one called libnamespec.a. (By convention, a ".so" extension indicates a shared library.) Note that this behavior does not apply to :filename, which always specifies a file called filename. So in this case it could probably work with -lphobos2. Maybe -L-l:libphobos2.a was chosen to force the linking with the static lib (as can be seen in the second paragraph for systems that supports both). Yeah, pretty sure that was it: when I called gcc myself it linked to the shared version. Maybe I should file a bug report for at least a proper error message when using it on ancient systems. Atila
Re: dmd.conf... again
On Wednesday, 12 August 2015 at 15:22:39 UTC, wobbles wrote: On Wednesday, 12 August 2015 at 14:05:57 UTC, Atila Neves wrote: On Wednesday, 12 August 2015 at 13:46:24 UTC, wobbles wrote: On Wednesday, 12 August 2015 at 13:00:45 UTC, Atila Neves wrote: On Wednesday, 12 August 2015 at 12:40:49 UTC, Adam D. Ruppe wrote: [...] I downloaded the zip, added linux/bin64 to PATH, tried compiling a hello world and got: usr/bin/ld: cannot find -l:libphobos2.a That's when I started trying to set the configuration but nothing seems to work. Atila Have you run dmd from the directory you unzipped it to? libphobos2.a is in there I think, so ld wouldn't be able to find it. Just did, didn't work. Tried it from lib64 and lib32 as well, nothing. Atila Hmm, I'll setup a VM later this evening to test, see if I can figure it out. This really should be easier. It really should. I straced it and it's trying to link to phobos with `-l:libphobos2.a`. I've never seen a colon in library options before and the (ancient) gcc on the system doesn't seem to like it one bit. I added a hand-compiled gcc 4.9 to my PATH and... it worked. Atila
Re: dmd.conf... again
On Wednesday, 12 August 2015 at 12:21:14 UTC, Rikki Cattermole wrote: On 13/08/2015 12:16 a.m., Atila Neves wrote: [...] Perhaps this small snippet from my Windows install might shred some light. Specifically the LIB property. [Environment32] LIB="%@P%\..\lib" LINKCMD=%@P%\link.exe [Environment64] LIB="%@P%\..\lib64" Tried setting LIB, still doesn't work. Sigh. Atila
Re: dmd.conf... again
On Wednesday, 12 August 2015 at 13:46:24 UTC, wobbles wrote: On Wednesday, 12 August 2015 at 13:00:45 UTC, Atila Neves wrote: On Wednesday, 12 August 2015 at 12:40:49 UTC, Adam D. Ruppe wrote: On Wednesday, 12 August 2015 at 12:16:50 UTC, Atila Neves wrote: [...] If you use the dmd zip, everything just works when you just unzip it and use it all in-place. No need to move or copy files anywhere, no need for root. I downloaded the zip, added linux/bin64 to PATH, tried compiling a hello world and got: usr/bin/ld: cannot find -l:libphobos2.a That's when I started trying to set the configuration but nothing seems to work. Atila Have you run dmd from the directory you unzipped it to? libphobos2.a is in there I think, so ld wouldn't be able to find it. Just did, didn't work. Tried it from lib64 and lib32 as well, nothing. Atila
Re: dmd.conf... again
On Wednesday, 12 August 2015 at 12:40:49 UTC, Adam D. Ruppe wrote: On Wednesday, 12 August 2015 at 12:16:50 UTC, Atila Neves wrote: I'm trying to use dmd on a VM where I don't have root privileges (don't ask). I can't copy dmd.conf to /etc. If you use the dmd zip, everything just works when you just unzip it and use it all in-place. No need to move or copy files anywhere, no need for root. I downloaded the zip, added linux/bin64 to PATH, tried compiling a hello world and got: usr/bin/ld: cannot find -l:libphobos2.a That's when I started trying to set the configuration but nothing seems to work. Atila
Re: dmd.conf... again
On Wednesday, 12 August 2015 at 12:29:46 UTC, Dicebot wrote: More info about what gets placed where please. I have special dev layout on my system that co-exists with system-wide installation of dmd. It is as simple as having ~/dlang/{dmd|druntime|phobos}, linking ~/dlang/dmd/src/dmd to ~/bin/dmd-dev and placing dmd.conf in ~/bin which adds all those paths as -I and -L flags. Works just fine. There's no system-wide installation (since I don't have root), I just downloaded the zip for 2.068 and added dmd2/linux/bin64 to my PATH. Atila
dmd.conf... again
I'm trying to use dmd on a VM where I don't have root privileges (don't ask). I can't copy dmd.conf to /etc. According to the docs, I should be able to use a dmd.conf that's in the same dir as dmd itself, or in my home directory, or even specifying -conf=. None of these seems to tell dmd where to find phobos. I've also tried setting DFLAGS myself, but under no circumstances is dmd passing the -L where phobos is to ld, so I can compile but not link (well, I can if I use gcc!). Also tried dmd -L-L/path/to/phobos. Does anyone have a clue why this doesn't work? My dmd.conf looks like this: [Environment] DFLAGS=-I/nobackup/dlang/phobos/ -I/nobackup/dlang/druntime/import -L-L/nobackup/dlang/download/dmd2/linux/lib64 Atila
Re: Typed Message Passing between D Processes
On Thursday, 30 July 2015 at 05:53:48 UTC, yawniek wrote: On Wednesday, 29 July 2015 at 16:36:41 UTC, Atila Neves wrote: LDC: Cerealed: 970 ms, 482 μs, and 6 hnsecs MsgPack: 896 ms, 591 μs, and 2 hnsecs Not too shabby! Atila cool. what are the advantages of cereald over msgpack? AFAIK, features. The kind of features I need/use to write networking code and reduce the boilerplate to an absolute minimum. can you stream in packets with cereald too? I don't know exactly what you mean. I've only used it to go from network packets structs to bytes and vice-versa. cool thing about msgpack is that there exist libraries for many language. so we use it do actually store logs and then process them with other tools too. I wrote cerealed for networking. You _can_ use it to convert whatever else to binary, but its focus is easy networking. Atila
Re: Typed Message Passing between D Processes
On Monday, 29 June 2015 at 13:59:37 UTC, Nordlöw wrote: On Monday, 29 June 2015 at 10:22:10 UTC, Atila Neves wrote: I guess I'm going to have benchmark this now... :) What about doing a memory profiling using DMD fresh builtin profiler of http://dpaste.dzfl.pl/17b0ed9c0204 ? I'm guessing the GC might give misguiding results as your testStruct returns a relatively small data structure. I would rather like to see a larger (randomized) structure being tested on. You could make use of my https://github.com/nordlow/justd/blob/master/random_ex.d for random instance generation :) I tried your code and added it to the benchmark. It didn't make much of a difference. Atila
Re: Typed Message Passing between D Processes
On Monday, 29 June 2015 at 10:22:10 UTC, Atila Neves wrote: On Monday, 29 June 2015 at 08:45:15 UTC, Atila Neves wrote: On Sunday, 28 June 2015 at 17:02:42 UTC, Nordlöw wrote: On Friday, 26 June 2015 at 21:40:49 UTC, Atila Neves wrote: I'd have to benchmark it against something, but I'm pretty sure cerealed is fast. Faster than msgpack? I guess I'm going to have benchmark this now... :) Atila In release builds, _nearly_. Here's the benchmark program: http://dpaste.dzfl.pl/17b0ed9c0204. Results below. msgpack is... fast. From the docs, cerealed seems to have more features that I actually use and need though. Results: DMD debug: Cerealed: 4 secs, 987 ms, 700 μs, and 5 hnsecs MsgPack: 1 sec, 771 ms, 713 μs, and 7 hnsecs DMD release: Cerealed: 2 secs, 556 ms, 714 μs, and 6 hnsecs MsgPack: 1 sec, 89 ms, 561 μs, and 3 hnsecs GDC debug: Cerealed: 4 secs, 863 ms, 501 μs, and 1 hnsec MsgPack: 2 secs, 32 ms, 53 μs, and 1 hnsec GDC release: Cerealed: 1 sec, 740 ms, 726 μs, and 4 hnsecs MsgPack: 1 sec, 20 ms, 287 μs, and 3 hnsecs LDC debug: Cerealed: 7 secs, 711 ms, 154 μs, and 4 hnsecs MsgPack: 3 secs, 694 ms, 566 μs, and 2 hnsecs LDC release: Cerealed: 1 sec, 795 ms, 380 μs, and 7 hnsecs MsgPack: 931 ms, 355 μs, and 5 hnsecs Before I had time to look into it, somebody graciously optimised cerealed for me in this PR: https://github.com/atilaneves/cerealed/pull/6 And now then benchmarks are (dub build --build=release, fastest of 10 runs for each compiler): DMD: Cerealed: 1 sec, 199 ms, 118 μs, and 1 hnsec MsgPack: 1 sec, 85 ms, and 516 μs GDC: Cerealed: 927 ms, 677 μs, and 4 hnsecs MsgPack: 1 sec, 32 ms, 736 μs, and 5 hnsecs LDC: Cerealed: 970 ms, 482 μs, and 6 hnsecs MsgPack: 896 ms, 591 μs, and 2 hnsecs Not too shabby! Atila
Re: goroutines vs vibe.d tasks
On Tuesday, 30 June 2015 at 16:43:58 UTC, anonymous wrote: On Tuesday, 30 June 2015 at 15:18:36 UTC, Jack Applegame wrote: Just creating a bunch (10k) of sleeping (for 100 msecs) goroutines/tasks. Compilers go: go version go1.4.2 linux/amd64 vibe.d: DMD64 D Compiler v2.067.1 linux/amd64, vibe.d 0.7.23 Code go: http://pastebin.com/2zBnGBpt vibe.d: http://pastebin.com/JkpwSe47 go version build with "go build test.go" vibe.d version built with "dub build --build=release test.d" Results on my machine: go: 168.736462ms (overhead ~ 68ms) vibe.d: 1944ms (overhead ~ 1844ms) Why creating of vibe.d tasks is so slow (more then 10 times)??? I think this might be a problem with vibe.d's `sleep`. Putting a `writeln("...");` there is a lot faster than `sleep`ing even the tiniest amount of time. Sleep will almost certainly pause and block the fiber. Vibe.d only switches between them when there's IO to be done or something else from the event loop. A better way of comparing would be to actually do something: use channels to ping-pong back between the goroutines and use vibe.d's concurrency to send messages betweeen fibers. Whatever you do, don't sleep. Atila
Re: Typed Message Passing between D Processes
On Monday, 29 June 2015 at 08:45:15 UTC, Atila Neves wrote: On Sunday, 28 June 2015 at 17:02:42 UTC, Nordlöw wrote: On Friday, 26 June 2015 at 21:40:49 UTC, Atila Neves wrote: I'd have to benchmark it against something, but I'm pretty sure cerealed is fast. Faster than msgpack? I guess I'm going to have benchmark this now... :) Atila In release builds, _nearly_. Here's the benchmark program: http://dpaste.dzfl.pl/17b0ed9c0204. Results below. msgpack is... fast. From the docs, cerealed seems to have more features that I actually use and need though. Results: DMD debug: Cerealed: 4 secs, 987 ms, 700 μs, and 5 hnsecs MsgPack: 1 sec, 771 ms, 713 μs, and 7 hnsecs DMD release: Cerealed: 2 secs, 556 ms, 714 μs, and 6 hnsecs MsgPack: 1 sec, 89 ms, 561 μs, and 3 hnsecs GDC debug: Cerealed: 4 secs, 863 ms, 501 μs, and 1 hnsec MsgPack: 2 secs, 32 ms, 53 μs, and 1 hnsec GDC release: Cerealed: 1 sec, 740 ms, 726 μs, and 4 hnsecs MsgPack: 1 sec, 20 ms, 287 μs, and 3 hnsecs LDC debug: Cerealed: 7 secs, 711 ms, 154 μs, and 4 hnsecs MsgPack: 3 secs, 694 ms, 566 μs, and 2 hnsecs LDC release: Cerealed: 1 sec, 795 ms, 380 μs, and 7 hnsecs MsgPack: 931 ms, 355 μs, and 5 hnsecs
Re: Typed Message Passing between D Processes
On Sunday, 28 June 2015 at 17:02:42 UTC, Nordlöw wrote: On Friday, 26 June 2015 at 21:40:49 UTC, Atila Neves wrote: I'd have to benchmark it against something, but I'm pretty sure cerealed is fast. Faster than msgpack? I guess I'm going to have benchmark this now... :) Atila
Re: Typed Message Passing between D Processes
On Friday, 26 June 2015 at 12:31:04 UTC, Dicebot wrote: std.concurrency was supposed to be able to handle that by design but it is impossible to do without any sort of standard serialization utility in Phobos (and, ideally, very fast binary serialization utility) I'd have to benchmark it against something, but I'm pretty sure cerealed is fast.
Re: Typed Message Passing between D Processes
On Thursday, 25 June 2015 at 14:04:23 UTC, Per Nordlöw wrote: Is there an alternative to http://dlang.org/phobos/std_process.html#.pipe that can be used to do _typed_ _message_ _passing_ between two D processes with the same convenience as `send` and `receive` in std.concurrency ? Either in Phobos or in a third party library? You'd have to implement your own IPC for that to work. You can always use TCP and serialise everything. Atila
Does anyone get line numbers in stack traces on Linux?
I thought it was because I was weird and I use gold as my linker, but ld.bfd produced the same results. The most I could find in bug reports was someone complaining it used to work but the consensus was that it never did? Atila
Re: dmd/druntime/phobos HEAD: can't link binaries on Arch Linux
On Tuesday, 16 June 2015 at 01:18:29 UTC, Vladimir Panteleev wrote: Not using Arch Linux, but just from your post it looks like it's not finding the libphobos.a from HEAD and using the system one instead. You may want to check the dmd.conf file for your HEAD D install: make sure DMD is using it (dmd | head -4), and that it adds the library search path correctly (-L-L switch in DFLAGS). Thanks! Typo in dmd.conf... sigh. Atila
dmd/druntime/phobos HEAD: can't link binaries on Arch Linux
Anyone else getting this problem on Arch Linux? dmd hello.d hello.o:hello.d:TypeInfo_S3std3uni38__T13InversionListTS3std3uni8GcPolicyZ13InversionList67__T9IntervalsTS3std3uni32__T8CowArrayTS3std3uni8GcPolicyZ8CowArrayZ9Intervals.init$: error: undefined reference to 'std.uni.InversionList!(std.uni.GcPolicy).InversionList.Intervals!(std.uni.CowArray!(std.uni.GcPolicy).CowArray).Intervals.__fieldPostblit()' collect2: error: ld returned 1 exit status --- errorlevel 1 With -v I see that it's compiling phobos in by calling gcc like this: -l:libphobos2.a When I replace that with just the path to phobos instead, it works. Atila
dmd and string imports on Windows
On Linux: foo.d: import std.stdio; void main() { writeln(import("dir/bar.txt")); } dmd -J. foo.d # ok On Windows: Error: file "dir/bar.txt" cannot be found or not in a path specified with -J I tried the obvious buildPath("dir", "bar.txt") instead and now: Error: file "dir\\bar.d" cannot be found or not in a path specified with -J I tried r"dir\bar.txt" and "dir\\bar.txt" and still nothing. What am I supposed to do? Thanks, Atila
Re: Is there a way to get the types of all template parameters?
On Thursday, 4 June 2015 at 14:12:08 UTC, ketmar wrote: On Thu, 04 Jun 2015 13:38:18 +, Atila Neves wrote: For regular runtime parameters, there's ParameterTypeTuple. How would I write an equivalent template for template parameters? i.e. void fun(Foo foo, Bar bar)() {} alias types = CtParameterTypeTuple!fun; //TypeTuple!(Foo, Bar) I've tried but my is expression kung fu was weak. actually, you can't. uninstantiated template cannot be processed by anything, as it's not semanticed yet. and to semantic it, you have to instantiate it. The way I wrote it, no. But if they all have default values, then yes: TemplateArgsOf!(fun!()) Atila
Re: Is there a way to get the types of all template parameters?
On Thursday, 4 June 2015 at 13:50:02 UTC, Meta wrote: On Thursday, 4 June 2015 at 13:38:20 UTC, Atila Neves wrote: For regular runtime parameters, there's ParameterTypeTuple. How would I write an equivalent template for template parameters? i.e. void fun(Foo foo, Bar bar)() {} alias types = CtParameterTypeTuple!fun; //TypeTuple!(Foo, Bar) I've tried but my is expression kung fu was weak. Atila There is http://dlang.org/phobos/std_traits.html#TemplateArgsOf, but it only works with an instantiated template. Don't know how I missed that, thanks! Atila
Is there a way to get the types of all template parameters?
For regular runtime parameters, there's ParameterTypeTuple. How would I write an equivalent template for template parameters? i.e. void fun(Foo foo, Bar bar)() {} alias types = CtParameterTypeTuple!fun; //TypeTuple!(Foo, Bar) I've tried but my is expression kung fu was weak. Atila
Re: TypeTuple!(T...) vs Tuple!(T...)
On Tuesday, 2 June 2015 at 18:48:16 UTC, rsw0x wrote: On Tuesday, 2 June 2015 at 11:49:18 UTC, anonymous wrote: On Tuesday, 2 June 2015 at 08:10:27 UTC, rsw0x wrote: The tuple page is even confusing me http://dlang.org/tuple.html A variable declared with a TypeTuple becomes an ExpressionTuple: alias TL = Tuple!(int, long); is it using Tuple!(T...) and TypeTuple!(T...) interchangeably? Almost. `Tuple` is defined at the top of the article as `template Tuple(E...) {alias Tuple = E;}`. "TypeTuple" is later defined as a `Tuple` whose elements "elements are solely types". So, in the context of the article, `Tuple!(int, long)` is a "TypeTuple", because it's a `Tuple` of types. The article does not refer to `std.typecons.Tuple` or `std.typetuple.TypeTuple` at all. Specifically, the article's `Tuple` is not `std.typecons.Tuple`. And the article's "TypeTuple" is not `std.typetuple.TypeTuple`. However, going for bonus confusion points, the article's `Tuple` is defined the same as `std.typetuple.TypeTuple`. That's... really confusing and probably needs a rewrite honestly. Yep. Atila
Re: How to append range to array?
std.range.chain? Atila On Saturday, 23 May 2015 at 07:03:35 UTC, Vladimir Panteleev wrote: int[] arr = [1, 2, 3]; auto r = iota(4, 10); // ??? assert(equal(arr, iota(1, 10))); Hopefully in one GC allocation (assuming we know the range's length). I tried std.range.primitives.put but its behavior seems a little mysterious: This compiles but asserts at runtime: int[] arr = [1, 2, 3]; arr.put(iota(4, 10)); And this is even weirder, can you guess what it will print? int[] arr = [1, 2, 3]; arr.put(4); writeln(arr);
Re: Possible to write a classic fizzbuzz example using a UFCS chain?
On Tuesday, 28 April 2015 at 10:46:54 UTC, Gary Willoughby wrote: After reading the following thread: http://forum.dlang.org/thread/nczgumcdfystcjqyb...@forum.dlang.org I wondered if it was possible to write a classic fizzbuzz[1] example using a UFCS chain? I've tried and failed. [1]: http://en.wikipedia.org/wiki/Fizz_buzz import std.stdio, std.algorithm, std.range, std.conv; void main() { immutable words = [3: "fizz", 5: "buzz"]; iota(1, 100). map!((int i) { immutable res = reduce!((a, b) => a ~ ((i % b == 0) ? words[b] : ""))("", words.keys); return res.empty ? i.to!string : res; }). writeln; } Atila
Re: Looking for MQTT client library
Those are basically your options. You could wrap Mosquitto (a C implementation), but I'd just use the existing MQTT broker code. Then again, I would say that. :) Atila On Thursday, 12 March 2015 at 07:59:55 UTC, o3o wrote: I'm looking a MQTT [0] client library written in D, if it exists. Anyone know of any? I found the great Atila Neves MQTT broker (server) [1], and some C/C++ libraries [2], so, possible solutions are: a. Write a native D library from scratch b. Adapt/copy some parts of [1] to convert from server to client c. Create a binding from [2] Anyone has other idea that I could use to create this myself? Thanks [0]http://mqtt.org/ [1]https://github.com/atilaneves/mqtt [2]http://www.eclipse.org/paho/clients/c/
Re: I want to introduce boost_asio to dlang
On Thursday, 5 March 2015 at 09:38:27 UTC, zhmt wrote: On Thursday, 5 March 2015 at 08:22:33 UTC, Jack Applegame wrote: On Thursday, 5 March 2015 at 06:05:56 UTC, zhmt wrote: I am a gameserver developer, my programming lang is java now. I want to change java to dlang, and I like boost_asio and it's coroutine, so, I want to create a binding of boost_asio. But I am not familiar with dlang, so I want to find someone help me, or develope this binding with me. I will put the asio binding on github, and opensource, and free. Anybody help or join? There is no need to do it. Just use http://vibed.org/ instead of boost::asio. It sounds like a good choice, is it as good as boost::asio? Having used both, it's better. Atila
Re: Import paths do not work
I would suggest instead of using make, use dub[0] build manager instead. It'll handle grabbing all the files and compiling them correctly. [0] http://code.dlang.org/package-format Or for simple projects such as this one seems to be, just use rdmd. Atila
Re: Any dub tips and tricks
Are you sure your package/dub.json is valid JSON? You can check it here: http://jsonlint.com/ Atila On Thursday, 16 October 2014 at 22:22:14 UTC, Joel wrote: Any way of using dub (on Windows or OSX). I've been trying it lately, but not much success. 1. (In the command prompt or Terminal), I create a new folder. 2. Run 'dub init' in the new folder 3. I copy the dependency from a lib/app into the dub.json file. 4. Then I just enter 'dub' In Windows I get this error (and others, but seems to go through): Failed to parse package description for dil in C:\Users\Joel\AppData\Roaming\dub\packages\dil-master\. I'm more interested in using OSX, for D.
Re: Using return type of a predicate function as a template
This works: import std.range; auto groupBy(alias func, R)(R values) if (isInputRange!R) { alias K = typeof(func(values.front)); alias V = ElementType!R[]; V[K] grouped; foreach(value; values) grouped[func(value)] ~= value; return grouped; } unittest { struct Test { string a; double b; } auto values = [Test( "a", 1 ), Test( "a", 2 ), Test( "b", 3 )]; auto grouped = values.groupBy!(a => a.a); assert( grouped["a"].length == 2 ); assert( grouped["a"][1].b == 2 ); assert( grouped["b"].length == 1 ); assert( grouped["b"][0].b == 3 ); } Atila On Thursday, 16 October 2014 at 08:04:08 UTC, Edwin van Leeuwen wrote: I am trying to implement a groupBy function that groups by the return type of a predicate. Currently I have to define the returntype of the predicate for it to compile. Is there a way to get the return type at compile time and use it. The code: V[K] groupBy( alias func, K, V )( V values ) { V[K] grouped; foreach ( value ; values ) { grouped[func( value )] ~= value; } return grouped; } unittest { struct Test { string a; double b; } auto values = [Test( "a", 1 ), Test( "a", 2 ), Test( "b", 3 )]; auto grouped = values.groupBy!( (a) => a.a, string ); assert( grouped["a"].length == 2 ); assert( grouped["a"][1].b == 2 ); assert( grouped["b"].length == 1 ); assert( grouped["b"][0].b == 3 ); } So the above works, but I need to call it with: values.groupBy!( (a) => a.a, string ); Ideally I would call it instead with: values.groupBy!( (a) => a.a ) and it would infer that the template K needs to be a string, since that is the return type of (a) => a.a. Cheers, Edwin
Re: Building a dmd that works on old systems: TLS problems with libc
On Friday, 3 October 2014 at 10:47:11 UTC, David Nadlinger wrote: On Friday, 3 October 2014 at 08:47:07 UTC, Atila Neves wrote: ld: <...>/libphobos2.a(sections_linux_570_420.o): undefined reference to symbol '__tls_get_addr@@GLIBC_2.3' /lib64/ld-linux-x86-64.so.2: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status So to be clear, this is with a libphobos2.a built on the target system? The error message looks like you might have a Phobos library built for a newer libc. David Yes, built on the target system. It gets worse in that I "installed" gcc 4.8 by compiling it and changing my PATH and LD_LIBRARY_PATH to use it. At first I thought that was the problem and it sort of is but isn't. I removed my custom installations from PATH and LD_LIBRARY_PATH and used the system compiler but got the same problem. Then I tried only using dmd to compile and linking it myself. That worked, but the resulting binary crashed. After loading it up in gdb, it crashed in __tls_get_addr Atila
Building a dmd that works on old systems: TLS problems with libc
Both the pre-compiled dmd and building it from source from git HEAD give me the same result. I'm trying to compile D programs on an ancient Linux distro I have no root access to and hence no control over (don't ask). Its libc is so old I can't compile gcc 4.9 on it (gcc 4.8 is the most recent one that'll compile). I also can't copy compiled D programs over since its dynamic linker is too old as well. And using dmd works until it tries linking, at which point I get this: ld: <...>/libphobos2.a(sections_linux_570_420.o): undefined reference to symbol '__tls_get_addr@@GLIBC_2.3' /lib64/ld-linux-x86-64.so.2: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status Any ideas on what else I could do except for compiling a new libc? Cos I tried that a few weeks back and it was a descent into madness that didn't work at all. Atila
Re: Why is amap implemented as a member function of TaskPool?
On Saturday, 20 September 2014 at 06:46:43 UTC, Nordlöw wrote: On Thursday, 18 September 2014 at 19:49:00 UTC, Atila Neves wrote: I had to roll my own parallel map today, but at least I did get a nice 3x speedup. Is your own parallel map public somewhere? It would be interesting to see it. I just did the simplest, stupidest thing that would work, so it's probably buggy. It works where I used it (and was faster) so that's all I needed to know. To even think of releasing this I'd use atomics instead of the mutex and try to break it in all sorts of ways. But here it is anyway: private auto pmap(alias fun, R)(R range) if(isInputRange!R) { import std.parallelism; import core.sync.mutex; static __gshared Mutex mutex; if(mutex is null) mutex = new Mutex; typeof(fun(range.front))[] values; foreach(i, value; range.parallel) { auto newValue = fun(value); synchronized(mutex) { if(values.length < i + 1) values.length = i + 1; values[i] = newValue; } } return values; } Oh, and the reason I don't just append to `values` is that I need to preserve the original order. Atila
Re: Why is amap implemented as a member function of TaskPool?
On Saturday, 20 September 2014 at 07:25:45 UTC, Russel Winder via Digitalmars-d-learn wrote: On Sat, 2014-09-20 at 06:46 +, "Nordlöw" via Digitalmars-d-learn wrote: On Thursday, 18 September 2014 at 19:49:00 UTC, Atila Neves wrote: > I had to roll my own parallel map today, but at least I did > get a nice 3x speedup. How many cores? Is the problem a data parallel one and hence should show linear speedup? It depends on the data. I was running analysis on a build dependency graph. It'd depend on the dependency tree topology. I have 4 cores with hyperthreading. 3x speedup seems good to me, especially since the implementation is recursive. Is your own parallel map public somewhere? It would be interesting to see it. Particularly if it can be used to improved the code in std.parallelism. Now that I looked at the bug id referenced above, I don't think it'd help. I can see all sorts of problems with guaranteeing no mutable references are captured by the delegate. Atila