Re: Setting import paths - project (dub) and also rdmd or dmd
Thank you Steven and Christian. I had a look at both those methods, creating a local dmd.conf file almost worked but it wasn't a simple modification, I was hoping it would be as simple as just adding the extra path but it seems that I needed to add the whole path from the existing dmd.conf otherwise the build broke due to not being able to find stuff, I added extra stuff but it was a clumsy solution... Local dub packages I'm not not quite ready to do properly on this part of the learning curve and it is something I looked at and I think that I may end up using this. In the end I cheated. I simply added symlinks in my source directory to the *.d files I wanted to import and that solved the problem. It's probably(certainly ?) not the best way to do it but it works and as I become better with D I'm pretty sure I'll change it to something more sensible. Regards, D
Re: Poste some interesting vibe.d webpages
On Wednesday, 14 September 2022 at 19:34:01 UTC, Alain De Vos wrote: Although the framework is good. There is no community. Or general acceptance. Which is a pitty. Currently I ask myself how to do "sessions" with vibe.d. Hi Alain, I'm new to D and looking at vibe as well but I'm not as far down the path as settling on it as the final solution. Have you looked at alternatives to vibe such as the hunt framework ? https://code.dlang.org/packages/hunt-framework It does seem better documented and fuller featured than vibe but that could be due to me not having an in-depth knowledge of either of them :-) Regards, D
Setting import paths - project (dub) and also rdmd or dmd
Hi, New to D (and enjoying the learning..) I've probably missed something obvious but I'm slightly confused with the best way to achieve a simple build. I like to keep my reusable modules in a directory outside of the project directory so I can use them on another project for example. I do :- import externalmodulename; rdmd app.d and get a fail. No problems, I can run rdmd thus :- rdmd -I../EXTERNALMODULES app.d and it all compiles nicely. Same goes for dmd just use dmd -I and it compiles the code clean. I'd normally just have a CPPFLAGS=... line in a classic Makefile to do this for me but can't see a native D way of doing it. I looked at dub and that that :- dub add-path ../EXTERNALMODULES would do the trick but it doesn't make a difference (the path is added to the relevant json file in ~/.dub), I also tried add-local but no difference. I was expecting it to add something to dub.sdl but that hasn't changed since I created the project. TLDR: How do I automatically specify the -I to the compilers so I don't need to specify it manually each time ? Regards, D
Re: Dynamically allocated Array mutable but non resizeable
On Monday, 14 June 2021 at 17:34:00 UTC, Steven Schveighoffer wrote: D doesn't have head-const. So you must hide the mutable implementation to get this to work. You'd want to do this anyway, since you don't want to directly use the pointer for anything like indexing (it should first validate the index is valid, at least in an assert). -Steve Seems like I'll have to have a look at operator overloading, thanks for the clarification!
Dynamically allocated Array mutable but non resizeable
I'm searching for a way to do something like this in D: ```cpp struct MyStruct { const size_t length; int *const data; MyStruct(size_t n) : length(n) { data = new int[length]; } } ``` This way it is mutable, but non resizeable: ```cpp MyStruct s = MyStruct(10); s.data[0] = 42;// Valid s.data = new int[20]; // Error: assignment to const ``` Doing some extra reading about the theme I found the section on [Type Qualifiers](https://dlang.org/spec/const3.html), which makes me believe that the "tail constness" of D will disallow this kind of behavior. My solution would be overriding the `[]` to make MyStruct behave as an array and hiding the implementation details, but if you have a more elegant solution I'm all ears!
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Wednesday, 17 March 2021 at 15:16:36 UTC, Jacob Carlborg wrote: On Wednesday, 17 March 2021 at 13:52:48 UTC, Guillaume Piolat wrote: On Sunday, 14 March 2021 at 11:33:00 UTC, David wrote: Anyone else done this? Pointers welcome. Sorry for delay. Just add "dflags-osx-ldc": ["-static"], macOS doesn't support static linking. -- /Jacob Carlborg Ah that's really useful to know, thanks - this is my first bit of macOS dev (other than high level stuff like R, Python, kdb etc) and I'm having to learn more about internals than I really care to - ho hum.
Re: Can't call splitter with range struct
On Tuesday, 16 March 2021 at 07:43:18 UTC, drug wrote: That means that you GZippedRange should provide opSlice operator and should be a narrow string (string of char or wchar) Yes, I should have looked more carefully at the doc, I was assuming splitter would accept a simple input range, but it doesn't. I really didn't want to provide opSlice because then if it were called with an index higher than the length of the buffer I'd have to read more data and allocate memory to hold it. I'm not actually trying to do this any more though. Thanks.
Can't call splitter with range struct
I came across this problem as I was trying to see if could write a quick range-based solution with std.zlib to do what was asked about in a different Learn forum post - read a gzipped file. This seems like it should work: import std.stdio, std.algorithm, std.zlib; import std.range.primitives; void main(string[] args) { auto f = GZippedFile(File(args[1], "rb")); f.splitter("\n").each!writeln; } struct GZippedFile { File file; UnCompress uncompressor; ubyte[] readBuffer; const(char)[] buffer; this(File f) { file = f; uncompressor = new UnCompress(HeaderFormat.gzip); readBuffer = new ubyte[4096]; } dchar front() const { return buffer.front; } void popFront() { if (buffer.empty) { buffer = cast(const(char)[]) uncompressor.uncompress(file.rawRead(readBuffer)); } else { buffer.popFront(); } } bool empty() { return buffer.empty && file.eof(); } } But I get: Error: template std.algorithm.iteration.splitter cannot deduce function from argument types !()(GZippedFile, string), candidates are: /usr/include/dlang/dmd/std/algorithm/iteration.d(4678): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) with pred = "a == b", Range = GZippedFile, Separator = string must satisfy the following constraint: is(typeof(binaryFun!pred(r.front, s)) : bool) (...) If I change the newline separator to a character literal, I get: (...) /usr/include/dlang/dmd/std/algorithm/iteration.d(5055): splitter(alias pred = "a == b", Range, Separator)(Range r, Separator s) with pred = "a == b", Range = GZippedFile, Separator = char must satisfy the following constraint: is(typeof(binaryFun!pred(r.front, s.front)) : bool) It seems like "\n" should pass the second constraint and '\n' should pass the first. Using a dchar or dstring makes no difference. Adding @property to front makes no difference. Is this a bug?
Re: How do I load dylib (i.e. phobos and druntime for ldc) in Macos sandboxed app?
On Sunday, 14 March 2021 at 11:40:25 UTC, David wrote: This is more a macos thing than a D thing but still relevant. In another thread I was asking about cleaning up a D dylib for using in Excel. Ldc was suggested though first I have to figure out how to make the phobos and druntime loadable from within the sandbox. (I've posted in a new topic as it was drift from the original question - hope that helps anyone else searching for the same answers). I'm not expecting many relies - unless someone has happened to have solved it. Will post links once I've figured a solution. Solved using install_name_tool and https://medium.com/@donblas/fun-with-rpath-otool-and-install-name-tool-e3e41ae86172
How do I load dylib (i.e. phobos and druntime for ldc) in Macos sandboxed app?
This is more a macos thing than a D thing but still relevant. In another thread I was asking about cleaning up a D dylib for using in Excel. Ldc was suggested though first I have to figure out how to make the phobos and druntime loadable from within the sandbox. (I've posted in a new topic as it was drift from the original question - hope that helps anyone else searching for the same answers). I'm not expecting many relies - unless someone has happened to have solved it. Will post links once I've figured a solution.
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Sunday, 14 March 2021 at 01:38:23 UTC, David Skluzacek wrote: On Thursday, 11 March 2021 at 22:10:04 UTC, David wrote: I wasn't aware that object files could be manipulated like the strip manual page - thx for the heads up. With the caveats that the linked post is almost 14 years old, I can't try this command myself, and the ldc solution is probably preferable if you can get it to work - if you want to compile with dmd and use the strip command, this might help you (the OP answered his own question at the bottom): https://forum.juce.com/t/how-to-build-dylib-exporting-only-wanted-symbols/2180 He suggests doing: strip -u -r -s FILE_CONTAINING_EXPORTS_LIST MY_DYLIB.dylib It looks straight forward that way - thx
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Sunday, 14 March 2021 at 00:00:59 UTC, Adam D. Ruppe wrote: On Saturday, 13 March 2021 at 23:41:28 UTC, David wrote: So Excel complains that it can't load my library - presumably because libphobos2 and libdruntime are not in the sandbox.ly You *might* be able to compile with --link-defaultlib-shared=false to use the static phobos+druntime... but with shared libs it prefers shared and might not allow this. Probably worth a try. Otherwise I'd try to just add the phobos so to your sandbox somehow. or the rpath set to current directory and putting them in your correct directory may also work. I don't know how that works on Mac but on Linux it is passing... `-L-rpath -L.` or something like that when compiling... I can't find my notes on this but something like that. I think figuring out how to add phobos to the sandbox is probably the best option as I'm sure it won't be the last dylib I need to load. Anyone else done this? Pointers welcome.
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Thursday, 11 March 2021 at 22:10:04 UTC, David wrote: I wasn't aware that object files could be manipulated like the strip manual page - thx for the heads up. With the caveats that the linked post is almost 14 years old, I can't try this command myself, and the ldc solution is probably preferable if you can get it to work - if you want to compile with dmd and use the strip command, this might help you (the OP answered his own question at the bottom): https://forum.juce.com/t/how-to-build-dylib-exporting-only-wanted-symbols/2180 He suggests doing: strip -u -r -s FILE_CONTAINING_EXPORTS_LIST MY_DYLIB.dylib
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Friday, 12 March 2021 at 00:12:37 UTC, Guillaume Piolat wrote: Create a exports.lst file with: _addDD_D as the only line there. Build with: "lflags-osx-ldc": [ "-exported_symbols_list", "exports.lst", "-dead_strip" ], Thx that's really helpful. I've hit a snag with LDC. After serveral hours of searching and reading I think it's coming down to sandboxing and needing to deploy libraries in a place that excel can find them. The library DMD creates just references /usr/lib/libSystem.B.dylib and Excel can load my dylib. LDC on the other hand additionally references: @rpath/libphobos2-ldc-shared.95.dylib (compatibility version 95.0.0, current version 2.0.95) @rpath/libdruntime-ldc-shared.95.dylib (compatibility version 95.0.0, current version 2.0.95) So Excel complains that it can't load my library - presumably because libphobos2 and libdruntime are not in the sandbox.ly Can anyone (either tell me how to fix this) or give me pointers pls? (I'm current reading up on DYLD_LIBRARY_PATH (shouldn't use that), sandboxing on Mac, and rpaths) I suppose a solution that allows the additional libraries to be put in a subdirectory of my library would be idea as then I can deploy that within the sandbox. Thx for the help
Re: Storing interfaces as void[]
On Friday, 12 March 2021 at 22:18:59 UTC, tsbockman wrote: Why do you think you need a `void[]` slice? I think `void*` pointers are sufficient. This handles all normal data types, as long as they are allocated on the GC heap: I wanted to have the registry own the structs' memory, though using new makes more sense on second thought. Your example templated implementation makes so much sense, though it doesn't work in this case. Thanks for the idea though. Aye, I'm using hashes. The idea is to support either D interfaces or structs with arbitrary content. You can use TypeInfo references as the keys for the struct types, too. It's better than hashes because the TypeInfo is already being generated anyway, and is guaranteed to be unique, unlike your hashes which could theoretically collide. Makes sense. Using TypeInfo never occurred to me. I assume they are generated for COM classes as well? `I` is *not* the type of an interface instance, it is the type of a reference to an instance of the interface. So `I i` is a reference to the instance, which itself holds a reference to the implementation, like a reference to a delegate (pointer to (ctx, fn))? No. What you are calling "the implementation" is the same thing as "the instance". `I i` is a reference into the interior of the implementing class instance, offset such that it points at the virtual function table pointer for that interface. The lowering is something like this: interface I { ... } class C : I { ... } struct C_Instance { void* __vtblForC; // ... other junk void* __vtblForI; // ... explicit and inherited class fields, if any. } C c = new C; // Works like `C_Instance* c = new C_Instance;` I i = c; // Works like `void** i = (C_Instance.__vtblForI.offsetof + cast(void*) c);` Makes sense, I always thought of them as existing in separate places. So much head-bashing, and it's over. Thanks, tsbockman, Imperatorn.
Re: Storing interfaces as void[]
On Friday, 12 March 2021 at 18:14:12 UTC, Imperatorn wrote: On Friday, 12 March 2021 at 17:57:06 UTC, David Zhang wrote: On Friday, 12 March 2021 at 17:46:22 UTC, Imperatorn wrote: On Friday, 12 March 2021 at 17:37:43 UTC, David Zhang wrote: [...] Have you tried using Variant or jsvar (https://code.dlang.org/packages/arsd-official%3Ajsvar)? 樂 It doesn't appear to support interfaces, see opAssign at line 682. It occurs to me that I.sizeof == 8 which is just enough for the vtbl, but not enough for an implementation ptr. Maybe it's a pointer to a {self, vtbl} pair? SomeClass.sizeof == 16, which is enough storage for both... Did you try Variant? Seems to work for me It seems a bit overkill for this. I also want to be able to track memory usage here, and Variant doesn't appear able to store arbitrary-sized structs without untrackable allocations. The idea has merit, but doesn't give me the control I desire :)
Re: Storing interfaces as void[]
On Friday, 12 March 2021 at 18:50:26 UTC, tsbockman wrote: The idea is to implement a service locator s.t. code like this is possible: // struct (I didn't mention this in the top post, my mistake) auto log = Logger() api_registry.register!Logger(log); // class/interface auto input = new InputReplay(recorded_input); api_registry.register!InputStream(input); // // somewhere else // // interface auto input = api_registry.get!InputStream(); // do something with input. // struct* api_registry.get!Logger().info(...); // // and additionally // auto input = new KeyboardInput(...); api_registry.replace!InputStream(input); /* Fully qualified names can be *very* long because of templates, so it can be wasteful to store and compare them at runtime. Let's use `TypeInfo` instead: */ Aye, I'm using hashes. The idea is to support either D interfaces or structs with arbitrary content. `I` is *not* the type of an interface instance, it is the type of a reference to an instance of the interface. So `I i` is a reference to the instance, which itself holds a reference to the implementation, like a reference to a delegate (pointer to (ctx, fn))? Thus cast(void*) produces something like *(ctx, fn). I don't mind that. I just want to store that reference as void[], be able to replace with with some other reference to another implementation as void[], then retrieve that as a reference intact. I don't really need to copy or move the class instances here, just be able to read, assign, and replace references to them in the same place that I read, assign, and replace void[]'s of structs.
Re: Storing interfaces as void[]
On Friday, 12 March 2021 at 17:46:22 UTC, Imperatorn wrote: On Friday, 12 March 2021 at 17:37:43 UTC, David Zhang wrote: I want to store interfaces as untyped void[], then cast them back to the interface at a later time. However, it appears to produce garbage values on get(). Is this even possible, and if so, what is happening here? The alternative would be a struct { CheckedPtr self; api_fns } e.g. void register(I)(I i) { auto mem = new void[](I.sizeof); memcpy(mem.ptr, cast(void*) i, I.sizeof); // CheckedPtr includes a hash of fullyQualifiedName map[i.get_name()] = CheckedPtr!I(mem.ptr); } I get(I)() { // basically cast(I) p return map[I.get_name()].as!I(); } Have you tried using Variant or jsvar (https://code.dlang.org/packages/arsd-official%3Ajsvar)? 樂 It doesn't appear to support interfaces, see opAssign at line 682. It occurs to me that I.sizeof == 8 which is just enough for the vtbl, but not enough for an implementation ptr. Maybe it's a pointer to a {self, vtbl} pair? SomeClass.sizeof == 16, which is enough storage for both...
Storing interfaces as void[]
I want to store interfaces as untyped void[], then cast them back to the interface at a later time. However, it appears to produce garbage values on get(). Is this even possible, and if so, what is happening here? The alternative would be a struct { CheckedPtr self; api_fns } e.g. void register(I)(I i) { auto mem = new void[](I.sizeof); memcpy(mem.ptr, cast(void*) i, I.sizeof); // CheckedPtr includes a hash of fullyQualifiedName map[i.get_name()] = CheckedPtr!I(mem.ptr); } I get(I)() { // basically cast(I) p return map[I.get_name()].as!I(); }
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Thursday, 11 March 2021 at 18:35:37 UTC, Imperatorn wrote: On Thursday, 11 March 2021 at 17:00:06 UTC, David wrote: On Thursday, 11 March 2021 at 14:49:32 UTC, Imperatorn wrote: On Thursday, 11 March 2021 at 10:29:55 UTC, David wrote: On Thursday, 11 March 2021 at 08:40:58 UTC, Imperatorn wrote: [...] [...] Of course - but unless I've missed something I don't believe it works on macos. Hmm, I'm not sure. Have you tried? Nope the documentation implies it only works on windows so I've ruled it out. But the thing I'm trying to solve is suppression of symbols in the library. I see, there might be something similar to .def? https://docs.microsoft.com/en-us/cpp/build/reference/module-definition-dot-def-files?redirectedfrom=MSDN=msvc-160 Or I guess you could strip it? https://www.linux.org/docs/man1/strip.html But I guess you already thought of that and want to not even generate them in the first place? I was wondering if there was something similar to def - my next attempt will be a combination of ldc and export. I wasn't aware that object files could be manipulated like the strip manual page - thx for the heads up.
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Thursday, 11 March 2021 at 14:49:32 UTC, Imperatorn wrote: On Thursday, 11 March 2021 at 10:29:55 UTC, David wrote: On Thursday, 11 March 2021 at 08:40:58 UTC, Imperatorn wrote: On Thursday, 11 March 2021 at 08:34:48 UTC, David wrote: I thought it would be fun to convert some old C++/C quant utils to D. I'm starting with a simple library that I call from vba in Excel on macos: [...] *trigger warning* "vba in Excel on macos" ⚠️ Btw, have you looked at excel-d? https://code.dlang.org/packages/excel-d Btw, have you looked at excel-d? Of course - but unless I've missed something I don't believe it works on macos. Hmm, I'm not sure. Have you tried? Nope the documentation implies it only works on windows so I've ruled it out. But the thing I'm trying to solve is suppression of symbols in the library.
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Thursday, 11 March 2021 at 14:35:45 UTC, rikki cattermole wrote: Pipe it to grep should work | grep -v "__D2" Thanks - though I'm trying to suppress the symbols being generated in the library. A colleague says it can be done in ldc but not dmd. I'll think I'll try that out.
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Thursday, 11 March 2021 at 08:40:58 UTC, Imperatorn wrote: On Thursday, 11 March 2021 at 08:34:48 UTC, David wrote: I thought it would be fun to convert some old C++/C quant utils to D. I'm starting with a simple library that I call from vba in Excel on macos: [...] *trigger warning* "vba in Excel on macos" ⚠️ Btw, have you looked at excel-d? https://code.dlang.org/packages/excel-d Btw, have you looked at excel-d? Of course - but unless I've missed something I don't believe it works on macos.
Is it possible to suppress standard lib and dlang symbols in dylib (macos)
I thought it would be fun to convert some old C++/C quant utils to D. I'm starting with a simple library that I call from vba in Excel on macos: module xlutils; import core.stdc.string : strlen, strcpy; //import std.conv : to; //import std.string : toStringz; import core.stdc.stdlib : malloc, free; extern (C) double addDD_D(double a, double b) {return a + b;} ... which results in: nm -gU libxlutils.dylib 3f10 S __D7xlutils12__ModuleInfoZ 3e44 T _addDD_D 3ebc T _addrC 3e84 T _freeP 3e9c T _strcpyCC 3e6c T _strlenC_L If I import `to` and `toStringz` I get more symbols than will fit in my shell output. E.g. 000318bc T __D2rt5minfo11ModuleGroup9sortCtorsMFAyaZ8findDepsMFmPmZ9__lambda5MFNbNiQBjZv 00031534 T __D2rt5minfo11ModuleGroup9sortCtorsMFAyaZ8findDepsMFmPmZb 00030dcc T __D2rt5minfo11ModuleGroup9sortCtorsMFAyaZv 00031db4 T __D2rt5minfo11ModuleGroup9sortCtorsMFZv 00048ef0 S __D2rt5minfo12__ModuleInfoZ 000327e4 T __D2rt5minfo16rt_moduleTlsCtorUZ14__foreachbody1MFKSQBx19sections_osx_x86_6412SectionGroupZi ... 000183ac T _thread_resumeAll 00018660 T _thread_scanAll 00018480 T _thread_scanAllType 00019658 T _thread_suspendAll Is there a way of not exposing the symbols that aren't mine? - I only need a simple C interface. Thx David
Re: Memory allocation
On Wednesday, 24 February 2021 at 06:14:58 UTC, Imperatorn wrote: On Tuesday, 23 February 2021 at 19:44:39 UTC, David wrote: Not sure if `learn` is the right topic or not to post this.. I've been going through Bob Nystrom's "Crafting Interpreters" for a bit of fun and over the weekend put together a toy allocator in D - free and gc not yet done. It's single threaded and unsurprisingly faster than malloc for small objects up to 512 bytes, and about the same for larger objects (simulated with a linear distribution of size requests). [...] Have you looked at the "experimental" allocator(s) in D? std.experimental.allocator Hi, yes, good question, yes I did - my first cut using the mmap_allocator was slower - I presume because I should really allocate a good chunk of virtual memory and manage the pages myself. So some questions I'm asking myself - What people's heuristics for switching methods say from, some sort of pool to another approach - e.g. linked list of pages? At the page level does a bitmap allocator make more sense? Knuth (it seems) was under the impression that a third of memory is wasted by fragmentation, aka the 50% rule - that doesn't seem likely, does anyone measure these things? How does one go about choosing a set of pool sizes? Given that virtual pages are not necessarily physically contiguous are some of the considerations that inspired the buddy system no longer relevant. I should also say I'm aiming for a single thread longish running process (one + working days) that I anticipate could use a good chunk say 100GB or so on occasion but I'd like to be more efficient than java in terms of memory reuse - past experience was I had to reboot my workstation a few times a day as it did something really horrible (I don't know what). Any there any GC frameworks that someone has shared in D?
Memory allocation
Not sure if `learn` is the right topic or not to post this.. I've been going through Bob Nystrom's "Crafting Interpreters" for a bit of fun and over the weekend put together a toy allocator in D - free and gc not yet done. It's single threaded and unsurprisingly faster than malloc for small objects up to 512 bytes, and about the same for larger objects (simulated with a linear distribution of size requests). But I'd like to be able to benchmark it to see how I'm doing. A colleague suggested I ask here for resources and pointers - I was trying to find stats on malloc performance (internal and external fragmentation, long running reuse, distributions of size requests for testing and comparison, how to reason about trade-offs of cache missing, branch misprediction, meta data, etc). So academic papers, books, blogs, experiences are all welcome, especially with regard to optimising for immutability / COW - would be welcome or even just some good ol' conversation.
How to use import std.algorithm.iteration.permutations?
Hi When I try to build the following: import std.algorithm.iteration; void test(int[] array); void main() { int[] a = [1,1,2,2,3,3]; foreach (p; a.permutations) { test(p); } } I get the error: .\permutations_example.d(10): Error: function permutations_example.test(int[] array) is not callable using argument types (Indexed!(int[], ulong[])) .\permutations_example.d(10):cannot pass argument p of type Indexed!(int[], ulong[]) to parameter int[] array What's the proper way to obtain the array of permutations of a? Kind regards David
Re: Using std.net.curl
On Saturday, 29 February 2020 at 07:35:10 UTC, Boris Carvajal wrote: On Saturday, 29 February 2020 at 03:53:37 UTC, David Anderson wrote: I want to capture that text in a variable, but the upload function returns void. How can I get the text returned by the web server to be stored in a variable? import std; auto updata = read("inputfile"); auto dldata = put("https://postman-echo.com/put;, updata); writeln(dldata); Awesome, thank you! That's exactly what I needed.
Using std.net.curl
I'm working with std.net.curl. Using curl on the command line I can do this: curl -T file.txt http://localhost:9998/tika and it returns text as a result. When I attempt to do the same thing in D code as follows: import std.net.curl; upload("file.txt", "http://localhost:9998/tika;); the text is written to standard out. I want to capture that text in a variable, but the upload function returns void. How can I get the text returned by the web server to be stored in a variable?
Re: ld errors in osx Catalina
On Wednesday, 9 October 2019 at 15:42:42 UTC, David Briant wrote: On Wednesday, 9 October 2019 at 10:33:21 UTC, David Briant wrote: [...] If I uninstall clang using conda I now get: (base) Davids-MacBook:fred david$ dub Performing "debug" build using /Library/D/dmd/bin/dmd for x86_64. fred ~master: building configuration "application"... Linking... x86_64-apple-darwin13.4.0-clang: No such file or directory core.thread.ThreadError@src/core/thread.d(3093): Unable to load thread state Error: linker exited with status 255 /Library/D/dmd/bin/dmd failed with exit code 1. It seems like dub has somehow gotten entwined with the anaconda compiler - any ideas how to fix? FYI Solution was to use anaconda-clean to remove anaconda completely, then uninstall dmd using homebrew then reinstall the beta version.
Re: ld errors in osx Catalina
On Wednesday, 9 October 2019 at 10:33:21 UTC, David Briant wrote: I've accidentally upgraded to Catalina - a little earlier than planned as I had hoped not to be trail blazing! My problem is this, in a bash shell and a new directory when I run $ dub init ... answering the questions that dub asks $ dub dmd compiles the skeleton project but ld fails (full dump below). I've tried uninstalling dub, dmd (via homebrew) and reinstalling (had to use the latest beta) and upgrading xcode and also upgrading to Catalina. I'm a d newbie and this is my first escapade into compiling on the mac. Has anyone an idea how to fix this? If I uninstall clang using conda I now get: (base) Davids-MacBook:fred david$ dub Performing "debug" build using /Library/D/dmd/bin/dmd for x86_64. fred ~master: building configuration "application"... Linking... x86_64-apple-darwin13.4.0-clang: No such file or directory core.thread.ThreadError@src/core/thread.d(3093): Unable to load thread state Error: linker exited with status 255 /Library/D/dmd/bin/dmd failed with exit code 1. It seems like dub has somehow gotten entwined with the anaconda compiler - any ideas how to fix?
Re: formatting a float or double in a string with all significant digits kept
On Tuesday, 8 October 2019 at 20:37:03 UTC, dan wrote: I have a double precision number that i would like to print all significant digits of, but no more than what are actually present in the number. Or more exactly, i want to print the minimum number of digits necessary to recover the original number to within 2 or 3 least significant bits in the stored, in-core, version of its bit pattern. For example, import std.string; import std.stdio; import std.math; void main( ) { auto t = format("%3.30f", PI ); writeln("Value of PI is: ", PI, " or, : ", t); } The default way writeln prints is 5 digits to the right of the decimal point. I can format to print with any number of digits, such as 30 above, but that's too many. For pi, the correct number of digits to print looks to be about 18 (and the extra 12 digits presumably are from the decimal expansion of the least significant bit?). But i would like to be able to do this without knowing the expansion of pi, or writing too much code, especially if there's some d function like writeAllDigits or something similar. Thanks in advance for any pointers! dan Hi Dan, What's your usecase here, e.g. a csv/json reader / writer? You say it's for double precision numbers (64bit format) then provide an example for reals (80bit format). So I'm not certain your goal. If you google "what every developer should know about doubles" you'll hit a number of useful articles that explain the common issues of floating point representation in detail. -- David
ld errors in osx Catalina
I've accidentally upgraded to Catalina - a little earlier than planned as I had hoped not to be trail blazing! My problem is this, in a bash shell and a new directory when I run $ dub init ... answering the questions that dub asks $ dub dmd compiles the skeleton project but ld fails (full dump below). I've tried uninstalling dub, dmd (via homebrew) and reinstalling (had to use the latest beta) and upgrading xcode and also upgrading to Catalina. I'm a d newbie and this is my first escapade into compiling on the mac. Has anyone an idea how to fix this? (base) Davids-MacBook:fred david$ dub Performing "debug" build using /Library/D/dmd/bin/dmd for x86_64. fred ~master: building configuration "application"... Linking... ld: warning: ignoring file /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libpthread.tbd, file was built for unsupported file format ( 0x2D 0x2D 0x2D 0x20 0x21 0x74 0x61 0x70 0x69 0x2D 0x74 0x62 0x64 0x2D 0x76 0x33 ) which is not the architecture being linked (x86_64): /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libpthread.tbd ld: warning: ignoring file /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libm.tbd, file was built for unsupported file format ( 0x2D 0x2D 0x2D 0x20 0x21 0x74 0x61 0x70 0x69 0x2D 0x74 0x62 0x64 0x2D 0x76 0x33 ) which is not the architecture being linked (x86_64): /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libm.tbd ld: warning: ignoring file /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libSystem.tbd, file was built for unsupported file format ( 0x2D 0x2D 0x2D 0x20 0x21 0x74 0x61 0x70 0x69 0x2D 0x74 0x62 0x64 0x2D 0x76 0x33 ) which is not the architecture being linked (x86_64): /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib/libSystem.tbd Undefined symbols for architecture x86_64: "__NSGetMachExecuteHeader", referenced from: __D2rt9backtrace5dwarf23traceHandlerOpApplyImplFxAPvMDFKmKxAaZiZi in libphobos2.a(dwarf_9d0_924.o) "__Unwind_DeleteException", referenced from: ___dmd_personality_v0 in libphobos2.a(dwarfeh_892_811.o) ___dmd_begin_catch in libphobos2.a(dwarfeh_88f_6b9.o) "__Unwind_GetIP", referenced from: ___dmd_personality_v0 in libphobos2.a(dwarfeh_892_811.o) "__Unwind_GetLanguageSpecificData", referenced from: ___dmd_personality_v0 in libphobos2.a(dwarfeh_892_811.o) "__Unwind_GetRegionStart", referenced from: ___dmd_personality_v0 in libphobos2.a(dwarfeh_892_811.o) "__Unwind_RaiseException", referenced from: __d_throwdwarf in libphobos2.a(dwarfeh_891_56a.o) "__Unwind_Resume", referenced from: __D3std5stdio__T7writelnTAyaZQnFNfQjZv in fred.o __D3std5stdio4File8opAssignMFNcNjNfSQBhQBgQBdZQl in libphobos2.a(stdio_19dd_180.o) __D3std5stdio4File6reopenMFNeAyaMAxaZv in libphobos2.a(stdio_19dd_180.o) __D3std5stdio4File6fdopenMFNeiMAxaAyaZv in libphobos2.a(stdio_19dd_180.o) __D3std5stdio4File6detachMFNeZv in libphobos2.a(stdio_19dd_180.o) __D3std5stdio4File5closeMFNeZv in libphobos2.a(stdio_19dd_180.o) __D3std5stdio4File11ByChunkImpl6__ctorMFNcSQBoQBnQBkmZSQCaQBzQBwQBu in libphobos2.a(stdio_19dd_180.o) ... "__Unwind_SetGR", referenced from: ___dmd_personality_v0 in libphobos2.a(dwarfeh_892_811.o) "__Unwind_SetIP", referenced from: ___dmd_personality_v0 in libphobos2.a(dwarfeh_892_811.o) "___error", referenced from: __D3std5stdio4File7tryLockMFEQBaQz8LockTypemmZb in libphobos2.a(stdio_19dd_180.o) __D3std9exception14ErrnoException6__ctorMFNfAyaQdmZCQBxQBwQBp in libphobos2.a(exception_489_5b5.o) __d_run_main2 in libphobos2.a(dmain2_888_4ad.o) __D4core6thread6Thread5sleepFNbNiSQBf4time8DurationZv in libphobos2.a(thread_386_258.o) _fakePureReprintReal in libphobos2.a(demangle_2ff_79b.o) "___stderrp", referenced from: ___dmd_personality_v0 in libphobos2.a(dwarfeh_892_811.o) __d_throwdwarf in libphobos2.a(dwarfeh_891_56a.o) __D2rt7dwarfeh8scanLSDAFPxhmmbbPSQBe6unwind17_Unwind_ExceptionJmJiZEQCnQCn10LsdaResult in libphobos2.a(dwarfeh_896_2c9.o) __D2rt6dmain218_d_print_throwableUC6object9ThrowableZ4sinkMFNbNiNlMxAaZv in libphobos2.a(dmain2_88b_776.o) __d_run_main2 in libphobos2.a(dmain2_888_4ad.o) __D2rt6dmain212_d_run_main2UAAamPUQgZiZ6runAllMFZv in libphobos2.a(dmain2_888_4ad.o) __D2rt7dwarfeh17actionTableLookupFPSQBh6unwind17_Unwind_ExceptionkPxhQdhmQhZi in libphobos2.a(dwarfeh_897_6e0.o) ... "___stdoutp", referenced from: __D3std5stdio__T10makeGlobalVEQBbQBa13StdFileHandlea22_636f72652e737464632e737464696f2e7374646f7574ZQDgFNbNcNdNiZSQEhQEg4File in libphobos2.a(stdio_19e9_cfb.o) __d_run_main2 in libphobos2.a(dmain2_888_4ad.o) "__dyld_get_image_header", referenced fr
Re: do mir modules run in parallell
On Sunday, 6 October 2019 at 05:32:34 UTC, 9il wrote: mir-blas, mir-lapack, and lubeck parallelism depend on system BLAS/LAPACK library (OpenBLAS, Intel MKL, or Accelerate Framework for macos). mir-optim by default single thread but can use TaskPool from D standard library as well as user-defined thread pools. mir-random was created for multithread programs, check the documentation for a particular engine. The general idea is that each thread has its own engine. Other libraries are single thread but can be used in multithread programs with Phobos threads or other thread libraries. Best, Ilya thanks! I will try it out accordingly. Bests, David
Re: do mir modules run in parallell
On Saturday, 5 October 2019 at 04:38:34 UTC, 9il wrote: On Friday, 4 October 2019 at 20:32:59 UTC, David wrote: Hi I am wondering if MIR modules run in parallel by default or if I can enforce it by a compiler flag? Thanks David Hey David, Do you mean unittests run in parallel or mir algorithms themselves run in parallel? Ilya Hi Ilya Thanks for coming back on this and sorry for not being precise. I am wondering about the Mir algorithms. David
do mir modules run in parallell
Hi I am wondering if MIR modules run in parallel by default or if I can enforce it by a compiler flag? Thanks David
Re: How to create an overwriteable struct that is always const?
Ah, fair enough.
Re: How to create an overwriteable struct that is always const?
On Saturday, 1 June 2019 at 13:00:50 UTC, ag0aep6g wrote: How is setting/replacing different from modifying? e.g.: S s; this() { s = ...; } update(S s) { this.s = s; } mod(int i) { s.i = i; } // illegal Kinda like how strings can be copied and assigned to, but not modified.
Re: How to create an overwriteable struct that is always const?
On Saturday, 1 June 2019 at 16:30:12 UTC, Jonathan M Davis wrote: If any member variable of a struct is const, then you can't modify that member ever, and assignment isn't possible unless you override opAssign so that it overwrites only the mutable members. It's very rare that it makes sense to make any member variables of a struct const or immutable, because then you basically can't use assignment anymore. You could make all of the member variables private and provide no functions that set any of them, then the only way to change any of their values would be to construct a new value of that type and assign it to the variable. - Jonathan M Davis Ideally, I'd like for member functions to be checked against modifying s also, not just externally.
How to create an overwriteable struct that is always const?
Say I have a struct `S`: struct S { /*const*/ char* pointer; ... other members ... this(/*const*/ char* p, ... others ...) { pointer = p; ... } } What I want, is to be able to use `S` in other data structures with the following properties checked by the compiler: - The variable can be set - The variable can be read - The variable cannot be modified, only replaced Is there a type-safe way to do this? If this were a class, I'd try std.typecons.Rebindable. Thanks
Re: mir.ndslice: assign a vector to a matrix row
On Friday, 28 December 2018 at 08:11:37 UTC, 9il wrote: On Friday, 28 December 2018 at 08:09:09 UTC, 9il wrote: On Thursday, 27 December 2018 at 21:17:48 UTC, David wrote: On Wednesday, 26 December 2018 at 18:59:25 UTC, 9il wrote: [...] great many thanks!! Is there any logic why getting a row works by auto row = matrix[0]; but assigning to a row works (only) by the two variant you posted? This case gets a slice of a row, it does not copy the data. So row[i] is matrix[0, i], the same number in the RAM. auto row = matrix[0]; This case gets a slice of a row, it does not copy the data. If you wish to copy data you need to use a slice on the right side: EDIT: a slice on the LEFT side Many thanks for this background!!
Re: mir.ndslice: assign a vector to a matrix row
On Wednesday, 26 December 2018 at 18:59:25 UTC, 9il wrote: On Saturday, 15 December 2018 at 19:04:37 UTC, David wrote: Hi I am wondering if it is possible to assign a vector to a row of a matrix? main.d == import mir.ndslice; void main() { auto matrix = slice!double(3, 4); matrix[] = 0; matrix.diagonal[] = 1; auto row = matrix[0]; row[3] = 4; assert(matrix[0, 3] == 4); // assign it to rows of a matrix? auto vector = sliced!(double)([10, 11, 12, 13]); // ??? Here I would like to assign the vector to the last (but it is not working) // matrix[2] = vector; } So I am wondering what the correct way is to do such an assignment without looping? matrix[2][] = vector; Or matrix[2,0..$] = vector; great many thanks!! Is there any logic why getting a row works by auto row = matrix[0]; but assigning to a row works (only) by the two variant you posted?
Re: dscanner --ctags: local variables, functions, ... are now shown in vim/neovim Tagbar
On Monday, 17 December 2018 at 08:56:07 UTC, Laurent Tréguier wrote: I think that's not possible right now, D-Scanner skips over body functions and unittest blocks to not clutter the tags with potentially lots of local names. A pity; nevertheless many thanks for coming back on it!
dscanner --ctags: local variables, functions, ... are now shown in vim/neovim Tagbar
I am wondering how I could display (nested) local variables and functions in vim's tagbar (majutsushi/tagbar) using dscanner? So far I only see gloable variables, functions, ... === script.d == import std.stdio; enum globalEnum1 { A = 1, B = 2 } enum globalEnum2 { C, D } void globalFun(){ writeln("global"); } double globalDouble = 2.3; string globalString = "hi"; void main(){ enum localEnum { A = 1, B = 2 } void localFun(){ writeln("local"); } double localDouble = 2.3; } === === Tagbar shows: === ◢ functions globalFun() main() ◢ globalEnum1 : enum [enumerators] A B ◢ globalEnum2 : enum [enumerators] C D ◢ variables globalDouble globalString === " tagbar: let g:tagbar_type_d = { \ 'ctagstype' : 'd', \ 'kinds' : [ \ 'c:classes:1:1', \ 'f:functions:1:1', \ 'T:template:1:1', \ 'g:enums:1:1', \ 'e:enumerators:0:0', \ 'u:unions:1:1', \ 's:structs:1:1', \ 'v:variables:1:0', \ 'i:interfaces:1:1', \ 'm:members', \ 'a:alias' \ ], \'sro': '.', \ 'kind2scope' : { \ 'c' : 'class', \ 'g' : 'enum', \ 's' : 'struct', \ 'u' : 'union', \ 'T' : 'template', \}, \ 'scope2kind' : { \ 'enum' : 'g', \ 'class' : 'c', \ 'struct': 's', \ 'union' : 'u', \ 'template' : 'T', \ }, \ 'ctagsbin' : 'dscanner', \ 'ctagsargs' : ['--ctags'] \ }
mir.ndslice: assign a vector to a matrix row
Hi I am wondering if it is possible to assign a vector to a row of a matrix? main.d == import mir.ndslice; void main() { auto matrix = slice!double(3, 4); matrix[] = 0; matrix.diagonal[] = 1; auto row = matrix[0]; row[3] = 4; assert(matrix[0, 3] == 4); // assign it to rows of a matrix? auto vector = sliced!(double)([10, 11, 12, 13]); // ??? Here I would like to assign the vector to the last (but it is not working) // matrix[2] = vector; } So I am wondering what the correct way is to do such an assignment without looping?
Re: Class qualifier vs struct qualifier
On Wednesday, 13 June 2018 at 07:35:25 UTC, RazvanN wrote: Hello, I'm having a hard time understanding whether this inconsistency is a bug or intended behavior: immutable class Foo {} immutable struct Bar {} void main() { import std.stdio : writeln; Foo a; Bar b; writeln("typeof(a): ", typeof(a).stringof); writeln("typeof(b): ", typeof(b).stringof); } prints: typeof(Foo): Foo typeof(Bar): immutable(Bar) It seems like the class storage class is not taken into account which leads to some awkward situations like: immutable class Foo { this() {} } void main() { Foo a = new Foo(); // error: immutable method `this` is not callable using a // mutable object } To make it work I have to add immutable to both sides of the expression : immutable Foo a = new immutable Foo(); this is a wonder of redundancy. I already declared the class as immutable so it shouldn't be possible to have mutable instances of it (and it isn't), however I am forced to write the immutable twice even though it is pretty obvious that the class cannot be mutated. Just tested and I only seem to need to add the immutable to the left of the expression. https://run.dlang.io/is/EZ7es0 Also with the struct `Bar* b = new Bar();` works fine so i guess the discrepancy is because the class ref is mutatable.
Re: Confusion/trying to understand CTFE keywords
On Thursday, 7 June 2018 at 04:58:40 UTC, Jonathan M Davis wrote: It would be trivial enough to create a wrapper template so that you can do something like immutable n = ctfe!(foo()); e.g. template ctfe(alias value) { enum ctfe = value; } Would this be equivalent to using static immutable? static immutable n = foo(); In this case both the compiletime and runtime values were calculated using cfte. Also back to the OP the way I think of enum, static types is like this: alias and enum create compiletime stuff from compiletime stuff. static creates runtime stuff from compiletime stuff. Is that view valid in most cases?
Re: Manipulate slice or specific element of range and return range
On Thursday, 22 March 2018 at 04:49:39 UTC, Seb wrote: No need for regular expressions. D is powerful enough without them: ``` alias lowercased = (m, n) => m.take(n).asLowerCase.chain(m.drop(n)); ``` https://run.dlang.io/is/cSL0si And with the filter, so it passes the assert: ``` string input = "My Capital String"; auto lower1 = input.take(1).asLowerCase.chain(input.drop(1).filter!(c => c != ' ')).array; assert(lower1 == "myCapitalString"); ``` Also a few more options (including a slice version): https://run.dlang.io/is/dZHcSo As the input is never read until the array() is run, each element in the array should only be copied from RAM to the stack once. And if you compile with LDC a lot of it can be inlined and the stack copies of the range structs and elements should be minimised even further.
Re: How to build static linked executable
On Tuesday, 20 March 2018 at 10:37:55 UTC, zunkree wrote: On Sunday, 18 March 2018 at 14:36:04 UTC, Jacob Carlborg wrote: FYI, -static is not support on macOS. So, how to build static binary for macOS? Static binaries aren't really supported by Apple (anymore). What do you need it for? — David
Re: Slow start up time of runtime
On Tuesday, 20 March 2018 at 09:44:41 UTC, Dennis wrote: Are there ways to reduce this to below 0.1s, or should I just leave idiomatic D and make a betterC program? The best solution would be to profile the startup process and file a bug accordingly. ;) — David
Re: Does the compiler inline the predicate functions to std.algorithm.sort?
On Sunday, 18 March 2018 at 14:15:37 UTC, Stefan Koch wrote: On Sunday, 18 March 2018 at 12:59:06 UTC, tipdbmp wrote: I can't read assembly but it seems to me that it doesn't: https://godbolt.org/g/PCsnPT I think C++'s sort can take a "function object" that can get inlined. Correct it does not get in-lined. Even with -O3 it does not. The reason is that the code the sort instantiation produces is too big for the inliner cost function. If you have a look at the the cg file produced when you specify -vcg-ast you can see that it's a massive amount of code. I believe the original poster was asking about the *predicate* to sort, which is indeed inlined with optimizations on. (@tipdbmp: The string gets turned into the function _D3std10functional__T9binaryFunVAyaa5_61203c2062VQra1_61VQza1_62Z__TQBvTiTiZQCdFNaNbNiNfKiKiZb. No references to it remain with -O3; the LLVM IR obtained with -output-ll might be easier to read than assembly.) — David
Re: Convert output range to input range
On Friday, 16 March 2018 at 07:57:04 UTC, John Chapman wrote: I need to write to a range created with outputRangeObject, then read from it. Is there a way to convert it to an input range? Could you illustrate your problem a bit further? In the literal sense, converting from an output to an input range would require using coroutines (where .empty() blocks until the output range has supplied the next element). However, I suspect what you want to do is to write results from the output range to a buffer (e.g. an Appender) first, and after that – or possibly every so often in chunks – process the results further? — David
Re: Getting a reference to an immutable string
On Saturday, 10 February 2018 at 22:59:18 UTC, ag0aep6g wrote: But there is a recent regression on Windows that might be related. Do you also have a static constructor (`static this`) that uses `wndclassName`? If so, you might be hitting issue 18412. https://issues.dlang.org/show_bug.cgi?id=18412 If you don't have a static constructor, it might be a different bug. In that case, please provide complete code so that we can get to the bottom of it. I have a static constructor that uses wndclassName to register the window class... at the top of the file. I think that's the bug.
Re: Getting a reference to an immutable string
Building with Visual Studio seems to be fine. This isn't an OptLink issue, is it?
Re: Getting a reference to an immutable string
On Saturday, 10 February 2018 at 22:36:41 UTC, ag0aep6g wrote: On 02/10/2018 11:26 PM, David Zhang wrote: I've got an immutable string declared in module scope, and I attempted to get a pointer to its characters through both [0] and str.ptr. However, it appears to me that the string is behaving like a manifest constant, in that the pointer is null. The language reference indicates that it has a location in memory and thus has a pointer. So, my question is thus: Is this a bug in DMD, or is this just something I missed? The pointer should not be null, even when `str` is a manifest constant. But without code it's impossible to say if you're hitting a compiler bug or if you're doing something wrong. Ah, yeah. It appears to occur only when compiled in x86 mode. This is what I'm talking about: void createWindow( ... ) { assert( wndclassName.ptr ); //This fails HWND hwnd = CreateWindowW( wndclassName.ptr, //This too null, 0, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, null, null, null, null ); } wstring wndclassName = "wndclass_name"w;
Getting a reference to an immutable string
Hi, I've got an immutable string declared in module scope, and I attempted to get a pointer to its characters through both [0] and str.ptr. However, it appears to me that the string is behaving like a manifest constant, in that the pointer is null. The language reference indicates that it has a location in memory and thus has a pointer. So, my question is thus: Is this a bug in DMD, or is this just something I missed? Thanks David
Re: Terminating multiple processes
On Thursday, 1 February 2018 at 11:42:32 UTC, Russel Winder wrote: The problem is actually a thread blocked in an inotify blocking read. As both Steven and yourself have pointed out I am going to have to use a timeout to check the state of the application. There are better solutions (select/...), But couldn't you in theory just send a custom signal to the thread (which you ignore), and then check for the exit flag after the syscall returned EINTR? The DInotify wrapper might of course have the retry loop hardcoded; I didn't check. —David
Re: Get aliased type
On Tuesday, 2 January 2018 at 11:42:49 UTC, John Chapman wrote: Because an alias of a type is just another name for the same thing you can't test if they're different. I wondered if there was a way to get the aliased name, perhaps via traits? (.stringof returns the original type.) There is indeed no way to do this; as you say, aliases are just names for a particular reference to a symbol. Perhaps you don't actually need the names in your use case, though? — David
Re: partial application for templates
On Monday, 25 December 2017 at 20:39:52 UTC, Mengu wrote: is partially applying templates possible? Check out std.meta.Apply{Left, Right}. — David
Re: Does LDC support profiling at all?
On Saturday, 23 December 2017 at 12:23:33 UTC, Johan Engelen wrote: Fine grained PGO profiling: -fprofile-instr-generate http://johanengelen.github.io/ldc/2016/07/15/Profile-Guided-Optimization-with-LDC.html Function entry/exit profiling: -finstrument-functions https://github.com/ldc-developers/ldc/issues/1839 https://www.youtube.com/watch?v=LNav5qvyK7I I suspect it is not too much effort to add DMD's -profile and -profile=gc to LDC, but noone has done it yet. Another thing that is relatively easy to add to LDC: https://llvm.org/docs/XRay.html Apart from profiling based on compiler instrumentation, don't forget that LDC uses the standard object file formats/runtime libraries for the various platforms, so all the usual profiling tools like perf, VTune, Valgrind, etc. work just fine. I would usually start with one of the latter for general-purpose optimization work. — David
Re: Parsing string to octal(for umask) at runtime?
On Friday, 22 December 2017 at 21:36:20 UTC, Ryan David Sheasby wrote: Hi. Struggling to figure this out. At the bottom of this page: https://dlang.org/library/std/conv/octal.html is a vague reference to using parse. However, when I use what I would assume to be correct based on this: https://dlang.org/phobos/std_conv.html#.parse.3 and the fact that in the octal page it says octal is also a enum, I see no reason this syntax shouldn't work: import std.conv; umaskVal = parse!octal(data.umask); Yet I get an error saying the compiler cannot deduce which overload of parse to use... How do I do this parse? Am I going about this the wrong way? Is there a better way to parse a string as a normal base8 ushort? Nevermind. I've just figured it out from this forum post :-) http://forum.dlang.org/thread/nbvdebjxodabukfbe...@forum.dlang.org All I needed to do was: umaskVal = parse!ushort(data.umask, 8);
Parsing string to octal(for umask) at runtime?
Hi. Struggling to figure this out. At the bottom of this page: https://dlang.org/library/std/conv/octal.html is a vague reference to using parse. However, when I use what I would assume to be correct based on this: https://dlang.org/phobos/std_conv.html#.parse.3 and the fact that in the octal page it says octal is also a enum, I see no reason this syntax shouldn't work: import std.conv; umaskVal = parse!octal(data.umask); Yet I get an error saying the compiler cannot deduce which overload of parse to use... How do I do this parse? Am I going about this the wrong way? Is there a better way to parse a string as a normal base8 ushort?
Re: Where is sleep()?
On Sunday, 17 December 2017 at 08:40:53 UTC, rikki cattermole wrote: On 17/12/2017 8:32 AM, Ryan David Sheasby wrote: Hey guys. First time poster here. I've searched high and low but can't seem to find a simple sleep/delay/wait/pause function in the core or in phobos. The most recent information I can find about it is this forum post from 12 years ago: http://forum.dlang.org/thread/avr99b$b8j$2...@digitaldaemon.com In which they suggest using std.c.time which is now depreciated and seems to have been replaced by core.stdc.time which doesn't have any sleep functions... What am I missing? That link is not relevant to D. https://dlang.org/phobos/core_thread.html#.Thread.sleep Crap sorry you're right. I pasted the wrong link. This is the one I was talking about: http://forum.dlang.org/thread/diuepu$2ebg$1...@digitaldaemon.com
Where is sleep()?
Hey guys. First time poster here. I've searched high and low but can't seem to find a simple sleep/delay/wait/pause function in the core or in phobos. The most recent information I can find about it is this forum post from 12 years ago: http://forum.dlang.org/thread/avr99b$b8j$2...@digitaldaemon.com In which they suggest using std.c.time which is now depreciated and seems to have been replaced by core.stdc.time which doesn't have any sleep functions... What am I missing?
Re: Is there anyway to access LLVM's 128 bit int type for C from LDC?
On Thursday, 14 December 2017 at 19:47:53 UTC, Jack Stouffer wrote: Clang has __int128. Is there anyway to use this with D with LDC? There has been some work on this a while ago, by Kai, but it hasn't been merged yet: https://github.com/ldc-developers/ldc/pull/1355 — David
Re: Get pointer or reference of an element in Array(struct)
On Saturday, 9 December 2017 at 06:46:27 UTC, Arun Chandrasekaran wrote: Thanks. Just curious why reference can't be obtained here. Saves nasty null checks in most places. D simply doesn't have a (C++-style) concept of references as part of the type. Arguments can be passed by reference - hence the `ref` keyword -, but "free" references don't exist in the language. The ref in foreach loop variables can be conceptually thought of as a parameter to the loop body as well. (For opApply-based iteration, the loop body indeed gets turned into a function; for "plain" iteration the compiler AST internally has special ref variables, but they are not visible to the language.) -David
Re: Changing the class data underneath some reference
On Thursday, 30 November 2017 at 00:40:51 UTC, David Colson wrote: Hello all! I'm getting settled into D and I came into a problem. A code sample shows it best: class SomeType { string text; this(string input) {text = input;} } void main() { SomeType foo = new SomeType("Hello"); SomeType bar = foo; foo = new SomeType("World"); writeln(bar.text); // Prints hello // I'd like it to print World } In the C++ world I could do this using pointers and changing the data underneath a given pointer, but I can't use pointers in D, so I'm not sure how I can get this behaviour? I'd be open to other ways of achieving the same affect in D, using more D like methods. I made an example demonstrating what I'd do in C++: class SomeType { public: std::string text; SomeType(std::string input) {text = input;} }; int main() { SomeType foo = SomeType("Hello"); SomeType* bar = foo = SomeType("World"); std::cout << bar->text << "\n"; // Prints World }
Changing the class data underneath some reference
Hello all! I'm getting settled into D and I came into a problem. A code sample shows it best: class SomeType { string text; this(string input) {text = input;} } void main() { SomeType foo = new SomeType("Hello"); SomeType bar = foo; foo = new SomeType("World"); writeln(bar.text); // Prints hello // I'd like it to print World } In the C++ world I could do this using pointers and changing the data underneath a given pointer, but I can't use pointers in D, so I'm not sure how I can get this behaviour? I'd be open to other ways of achieving the same affect in D, using more D like methods.
Re: String copying fails when output from assert
On Tuesday, 21 November 2017 at 19:05:21 UTC, Jonathan M Davis wrote: Well, the assertion is going to throw an AssertError, which takes a string for its message. It doesn't copy the contents of the string. It's just taking a slice just like whenever you pass a string to any other function. So, it refers to the same memory as what's passed in. So, if what it's passed is a string that refers to memory on the stack, then when it goes to print the message, it's going to be garbage, because the stack was unwound, and the static array is gone. Honestly, I'd argue that it's a bug that it allows you provide a message as a char[] instead of immutable(char)[]. It seems that the compiler is implicitly converting char[] to immutable(char)[] in this case, which is very bad. It would matter less if you were giving the assertion a char[] that referred to memory on the heap, but it still shouldn't be allowed. You really should be giving assertions a value that is an actual string that lives on the heap when providing a message, not a char[], and definitely not a char[] that's a slice of a static array. - Jonathan M Davis Right. So a literal would work, because it's in the .data segment, or inlined. Basically, only strings from the heap, or that are compiled into the code are valid for assert messages. What kind of behavior would an assert from stdc have (id, betterC)?
Re: String copying fails when output from assert
On Tuesday, 21 November 2017 at 18:56:03 UTC, Adam D. Ruppe wrote: On Tuesday, 21 November 2017 at 18:49:40 UTC, David Zhang wrote: assert(false, chars[0..str.length]); } What am I missing here? You're escaping a reference to a local variable there. chars[] is a pointer to the stack, which is promptly smashed when the assert error starts working up the call chain, so by the time it actually prints, you have undefined behavior. So I'd have to allocate the buffer on the heap then... Is there any way to do this without allocating to the stack?
String copying fails when output from assert
Hi, I've been trying to copy a string, then output it from an `assert(false)` statement, but the copy seems to be corrupted somehow. void main() { string str = "some string"; //initializing `chars` with any value doesn't do anything char[64] chars; //char[64] chars = '!'; //memcpy doesn't work either, though the output's different //import core.stdc.string; //memcpy([0], [0], str.length); chars[0..str.length] = str; assert(false, chars[0..str.length]); } What am I missing here?
Re: @nogc deduction for templated functions
Huh, I think I did something weird. It compiles now, and I don't know why. Thanks for your answers.
@nogc deduction for templated functions
Hi, Is there a way for a templated function to deduce or apply the @safe/@nogc attributes automaticaly? I feel like I remember dmd doing so at one point, but it doesn't appear to work anymore. In particular, I need to call a function belonging to a templated type, but do not know what attributes are applied. eg. void func(T)(T t) { //Don't know if safe or nogc t.someFunc(); } Thanks.
Re: D on AArch64 CPU
On Thursday, 10 August 2017 at 07:00:55 UTC, David J Kordsmeier wrote: On Wednesday, 9 August 2017 at 08:37:53 UTC, Johannes Pfau wrote: Iain recently updated GDC & phobos up to 2.074 and we have a pull request for 2.075. So don't worry about fixing old GDC phobos/druntime versions, recent gdc git branches should already have AArch64 phobos changes. We have a test runner for AArch and GDC master here: https://buildbot.dgnu.org/#/builders/2/builds/29 There are still some failing test suite tests though and AFAICS we currently don't build phobos on that CI at all. (We can run ARM/AArch tests without special hardware, thanks to QEMU's user mode emulation) -- Johannes Thanks both for the reply. I'll be interested to try both gdc and the ldc cross compiler options. BTW - I randomly decided to check on the latest status of builds today, to see if by chance AARCH64 is passing the buildbot tests run for GDC. Pleased to find, that actually as of four days ago, it is passing: https://buildbot.dgnu.org/#/builders/2/builds/45/steps/3/logs/stdio Looking forward to jumping back into D.
Re: How to check if string is available at compile time
On Thursday, 21 September 2017 at 13:52:25 UTC, Meta wrote: On Thursday, 21 September 2017 at 12:30:15 UTC, David Bennett wrote: On Thursday, 21 September 2017 at 11:42:36 UTC, David Bennett wrote: enum isCTstring(alias arg) = (!isAssignable!(typeof(arg)) || __traits(compiles, mixin(` "foo" ~ `~__traits(identifier, arg; [snip] But this seems quite hackish... any better ideas? Try __traits(compiles, { enum _ = arg; }). Creating an enum necessarily requires that its value is available at compile time. Ahh, warping it in {} seems to change the timing of the execution, this is starting to make a lot of sense to me now. (also explains why int[arg] works). Thats much cleaner and I'll use that from now on. Thanks a lot! David
Re: Getting the size of a type tuple
On Thursday, 21 September 2017 at 19:49:14 UTC, ag0aep6g wrote: I don't have a one-liner, but here are some other solutions that might be interesting. None of them is particularly pretty, though. 1) Recursive template: 2) Using the std library: 3) Declaring a packed struct in a function literal that gets immediately called: I think the recursive one looks best, but I agree. None of them look particularly good.
Getting the size of a type tuple
Given the function F, where: F(Args...)(Args args) { ... } How can I statically determine the size of the argument list in bytes? Preferably, I would like a one-liner. However, std.algorithm doesn't seem to support tuples, or `Args.each!(T => T.sizeof).sum` would work. For the moment, I've settled on using a helper function: size_t size(Args...)() { size_t size; foreach(Arg; Args) size += Arg.sizeof; return size; } But it's a bit clunky. Is there a more idiomatic way to do this? Thanks
Re: How to check if string is available at compile time
On Thursday, 21 September 2017 at 11:42:36 UTC, David Bennett wrote: [snip] ``` string[] escapeCTFE(Args...)(){ static foreach (arg; Args){ static if(__traits(compiles, ###WHATDOIPUTHERE###)){ [snip] So far the best I've come up with is : ``` enum isCTstring(alias arg) = (!isAssignable!(typeof(arg)) || __traits(compiles, mixin(` "foo" ~ `~__traits(identifier, arg; string[] escapeCTFE(Args...)(){ static foreach (arg; Args){ static if(isCTstring!(arg)){ pragma(msg, "Do work on string: ", arg); }else{ pragma(msg, __traits(identifier, arg), " can only be read at runtime"); } } return new string[32]; } ``` But this seems quite hackish... any better ideas?
How to check if string is available at compile time
Hi Guys, Is there an easy way to check if the value of string passed to a template is available at compile time? Here is a cut down example of that I'm doing: ``` string[] escapeCTFE(Args...)(){ static foreach (arg; Args){ static if(__traits(compiles, ###WHATDOIPUTHERE###)){ pragma(msg, "Do work on string: ", arg); }else{ pragma(msg, __traits(identifier, arg), " can only be read at runtime"); } } } void main(){ string a = "a"; static string b = "b"; enum string c = "c"; immutable string d = "d"; const string e = "e"; enum escape_as_much_as_possible = escapeCTFE!(a,b,c,d,e,"f"); } ``` I know for ints I can use __traits(compiles, int[arg]) but I'm not sure about strings. I believe only a and b should be hidden from pragma right? Thanks, David.
Re: Propagating constness through function results
Nevermind! I rediscovered the `inout`attribute. Though if I may say so, I have no idea how `inout` is supposed to indicate "whatever the constness of a".
Re: Propagating constness through function results
On Sunday, 17 September 2017 at 21:18:08 UTC, David Zhang wrote: Hi, I have a class `Image`, and I have a function called `getSubImage(Rect bounds)`. What I can't figure out is how to get the result of `getSubImage()` to take on the constness of the backing image. ie. //The Image class is really just a view over a buffer that's managed elsewhere const(Image).getSubImage(...) -> const(Image) Image.getSubImage(...) -> Image I tried to do this with `inout`, but that requires that a parameter in the function be `inout`. I don't suppose I could somehow declare `this` to be inout? Thanks I am aware that you can duplicate the method, but it seems a bit unwieldy and excessive.
Propagating constness through function results
Hi, I have a class `Image`, and I have a function called `getSubImage(Rect bounds)`. What I can't figure out is how to get the result of `getSubImage()` to take on the constness of the backing image. ie. //The Image class is really just a view over a buffer that's managed elsewhere const(Image).getSubImage(...) -> const(Image) Image.getSubImage(...) -> Image I tried to do this with `inout`, but that requires that a parameter in the function be `inout`. I don't suppose I could somehow declare `this` to be inout? Thanks
Re: Internal error mixing templates and CTFE
On Friday, 15 September 2017 at 15:48:10 UTC, Stefan Koch wrote: are you using ucent ? Not that I know of, the code above is the full code (not sure what's used internally for string literals). I was using dmd 2.076 from the apt repo but the error also happens in LDC 1.3[1]. Is there an easy way for me to test newCTFE? The reduced version to get the same error is: ``` struct Content{string[] parts;} void main(){ enum Content content = {}; content.parts ~= ""; } ``` Strange (for a CTFE noob like me anyway) thing is the following code produces no error or warning. (obviously it doesn't do what it looks like it does) ``` struct Content{ string[] parts; void add(string s)(){ parts ~= "Part: "~s; } } void main(){ enum Content content = {}; content.add!("Header")(); } ``` I would have thought both the code in the OP and the above two codes should produce a warning pointing out that using a compile time value like that has no useful effect. As this would be useful information for noobs like me... Actually now that I think about it there could be a "valid" use.. ie if the add function set global state... does this even work... (checks) ... yes it does... so I guess a warning cant really happen then. [1] Here is the LDC backtrace: ldc2: /build/ldc-6CClyQ/ldc-1.3.0/gen/dvalue.cpp:43: llvm::Value* DtoLVal(DValue*): Assertion `lval' failed. #0 0x7f1d568658a8 llvm::sys::PrintStackTrace(llvm::raw_ostream&) (/usr/lib/x86_64-linux-gnu/libLLVM-4.0.so.1+0x76e8a8) #1 0x7f1d56863786 llvm::sys::RunSignalHandlers() (/usr/lib/x86_64-linux-gnu/libLLVM-4.0.so.1+0x76c786) #2 0x7f1d568638e5 (/usr/lib/x86_64-linux-gnu/libLLVM-4.0.so.1+0x76c8e5) #3 0x7f1d55ce2670 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x11670) #4 0x7f1d5509977f gsignal /build/glibc-mXZSwJ/glibc-2.24/signal/../sysdeps/unix/sysv/linux/raise.c:58:0 #5 0x7f1d5509b37a abort /build/glibc-mXZSwJ/glibc-2.24/stdlib/abort.c:91:0 #6 0x7f1d55091b47 __assert_fail_base /build/glibc-mXZSwJ/glibc-2.24/assert/assert.c:92:0 #7 0x7f1d55091bf2 (/lib/x86_64-linux-gnu/libc.so.6+0x2dbf2) #8 0x5644df8d2310 (ldc2+0x3cb310) ... #25 0x5644df909370 (ldc2+0x402370) #26 0x7f1d550843f1 __libc_start_main /build/glibc-mXZSwJ/glibc-2.24/csu/../csu/libc-start.c:325:0 #27 0x5644df6538ea (ldc2+0x14c8ea) Aborted (core dumped) ldc2 failed with exit code 134.
Re: Internal error mixing templates and CTFE
On Friday, 15 September 2017 at 07:12:36 UTC, Andrea Fontana wrote: Internal error is always a bug, so it should be reported! I have opened a issue: https://issues.dlang.org/show_bug.cgi?id=17828
Internal error mixing templates and CTFE
Hi Guys, I've been playing around with CTFE today to see how far I would push it but I'm having an issue appending to an array on a struct in CTFE from a template: ``` struct Content{ string[] parts; } void add_part_to_content(Content content, string s)(){ content.parts ~= "Part: "~s; } void main(){ enum Content content = {}; add_part_to_content!(content, "Header")(); } ``` This generates the following output: & el:0x24052a0 cnt=0 cs=0 & TY* 0x2403100 el:0x2403100 cnt=0 cs=0 const TYucent 0LL+0LL Internal error: ddmd/backend/cgcs.c 352 FYI: I also get the same error with the template add_part_to_content(alias Content content, alias s) syntax. So two questions: Should what I'm doing be possible? Is this an error in dmd, and should I open a bug report?
Re: DLL loading behaviors and pragma(lib)
On Friday, 11 August 2017 at 04:50:48 UTC, rikki cattermole wrote: On 11/08/2017 12:18 AM, David Zhang wrote: I've been working on getting OpenGL to load on windows without a library, and encountered something curious; Context creation fails when I try to use the function pointer retrieved through GetProcAddress, but works just fine with the statically linked version provided through core.sys.windows.wingdi.d. This may be a stupid question, but why is this? Thanks. Odd. Just to confirm your wglGetProcAddress, is extern(Windows/System)? And it is non-null after being loaded? Yes.
DLL loading behaviors and pragma(lib)
I've been working on getting OpenGL to load on windows without a library, and encountered something curious; Context creation fails when I try to use the function pointer retrieved through GetProcAddress, but works just fine with the statically linked version provided through core.sys.windows.wingdi.d. This may be a stupid question, but why is this? Thanks.
Re: D on AArch64 CPU
On Wednesday, 9 August 2017 at 08:37:53 UTC, Johannes Pfau wrote: Iain recently updated GDC & phobos up to 2.074 and we have a pull request for 2.075. So don't worry about fixing old GDC phobos/druntime versions, recent gdc git branches should already have AArch64 phobos changes. We have a test runner for AArch and GDC master here: https://buildbot.dgnu.org/#/builders/2/builds/29 There are still some failing test suite tests though and AFAICS we currently don't build phobos on that CI at all. (We can run ARM/AArch tests without special hardware, thanks to QEMU's user mode emulation) -- Johannes Thanks both for the reply. I'll be interested to try both gdc and the ldc cross compiler options.
Re: D on AArch64 CPU
On Sunday, 14 May 2017 at 15:05:08 UTC, Richard Delorme wrote: I recently bought the infamous Raspberry pi 3, which has got a cortex-a53 4 cores 1.2 Ghz CPU (Broadcom). After installing on it a 64 bit OS (a non official fedora 25), I was wondering if it was possible to install a D compiler on it. Richard, I would be interested in working through the GDC issues further with you if you haven't completely given up on this. I am surprised the response is that there is still no official support. I am struggling on nearly every project I have on aarch64 with really lagging support for a wide variety of software, mainly platform support in more complex builds that does not include aarch64, and clearly the compilers all need more core level work to bring up a language and programming toolchains in a new environment. I think Go, for example, isn't fully supported on aarch64, and Rust has the same issue. If you are still available, I would like to share notes on the GDC 6.3 work that you started, and see if we can work through the issues with the core team. I realize there is probably some lack of visibility into the interest that exists in the ARM-embedded area for D, but I've been using gdc on ARM since 2014. It has been reasonably good for me, however, with the migration of many device manufacturers to AARCH64, most notably the Raspi3 and all of the hordes of Android devices hitting the market, there is a substantial installed base. I can commit some hardware to builds also, and have some contacts in the industry around arm stuff, so it shouldn't be hard to find more dedicated gear if this helps teams like the GDC team who may not have access to gear to even run nightly builds. Honestly, I stopped using D when I ran into this issue, was hoping, as you, that "someone should fix this". However, that's not how good OSS works, and I'm willing to put some cycles on it if there is a way forward. At the time, I had to make some fast decisions and opted to rewrite my code base in C. I look forward to hearing from you and anyone else interested in working on/contributing to this topic. Also, why I don't look at LDC further, I think RAM on the embedded devices is still pretty skimpy, Raspi3 only has 1GB ram. It's not great for compiling with the LLVM-based things and probably run OOM. Other devices I have only have 512MB ram. So gcc is usually fine in these circumstances.
Re: GDC generate wrong .exe ("not a valid win32 application")
On Monday, 19 June 2017 at 14:08:56 UTC, Patric Dexheimer wrote: Fresh install of GDC. (tried with 32x ad 32_64x) Where did you get the GDC executable from? The GDC project doesn't currently offer any official builds that target Windows; the 6.3.0 builds from https://gdcproject.org/downloads in fact generate Linux binaries. — David
Re: libc dependency
On Wednesday, 21 June 2017 at 06:58:43 UTC, Jacob Carlborg wrote: Musl (or similar) should be available as an alternative. That will make it easier to cross-compile as well. This is not relevant for cross-compilation, as long as you have the libraries available. You can actually link a D Windows x64/MSVCRT executable from Linux today if you copy over the necessary libraries. The question is just how we can make this as easy as possible for users. — David
Re: libc dependency
On Tuesday, 20 June 2017 at 18:51:17 UTC, Moritz Maxeiner wrote: On Tuesday, 20 June 2017 at 12:09:06 UTC, Jacob Carlborg wrote: LLD, the LLVM linker [1]. As far as I understand it, it also support cross-platform linking. Using LDC, musl and LLD you have a fully working cross-compiler tool chain. You might need some extra libraries as well, depending on what you need. Hm, so then we could provide a self-contained installer for all major platforms that bundles all you need to get started with D. Neat. Yes, that's part of the idea behind the ongoing work to integrate LLD into LDC: https://github.com/ldc-developers/ldc/pull/2142 For Windows, we use the MS C runtime, though, and the legal situation around redistribution seems a bit unclear. — David
Re: Mutiple AliasSeq as input to template
On Thursday, 25 May 2017 at 17:56:12 UTC, jmh530 wrote: On Thursday, 25 May 2017 at 16:36:45 UTC, jmh530 wrote: [snip] I haven't played around with it fully, but it seems like the following resolves my issue in a sort of manual way: template Process1(A, B) { static if (!isIndex!B) alias Process1 = A; else alias Process1 = B; } template Process(size_t n, A...) if (n > 0) { import std.meta : AliasSeq; alias B = A[0..n]; alias C = A[n..$]; static if (n == 1) { alias Process = AliasSeq!(Process1!(B[0], C[0])); } else static if (n > 1) { alias Process = AliasSeq!(Process1!(B[0], C[0]), Process!(n - 1, B[1..$], C[1..$])); } } You can use nested templates to process multiple AliasSeqs like so: enum isIndex(I) = is(I : size_t); template Process(A...) { template With(B...) { import std.meta : AliasSeq; static if (A.length == 0 || B.length == 0) alias With = AliasSeq!(); else { static if(!isIndex!(B[0])) alias Process1 = A[0]; else alias Process1 = B[0]; alias With = AliasSeq!(Process1, Process!(A[1..$]).With!(B[1..$])); } } } void main() { import std.meta : AliasSeq; alias T = AliasSeq!(int[], int[]); alias U = AliasSeq!(int, string); static assert(is(Process!(T).With!(U) == AliasSeq!(int, int[]))); }
Re: std.path.buildPath
On Saturday, 3 June 2017 at 14:12:03 UTC, Russel Winder wrote: I have no idea what drugs the person who chose that last one to be correct semantics was on at the time, but it was some seriously bad stuff. Of all people, I certainly didn't expect you to stray so far from the tone appropriate here. Please keep it civil. I cannot find any excuse for this to be even remotely reasonable. I suspect the original author had applications in mind where you want to resolve user-specified file system paths that might be relative or absolute. One could just use buildPath to prepend the root path if necessary. (Whether this is useful or just unnecessarily error-prone is another question, of course.) — David
Re: C macros vs D can't do the right thing
On Saturday, 3 June 2017 at 14:19:00 UTC, Jacob Carlborg wrote: Perhaps using the variadic template with a constraint on one element trick will work. Ugly, but I think that will work. We could also finally fix the frontend to get around this. At DConf 2015, Walter officially agreed that this is a bug that needs fixing. ;) — David
Re: C macros vs D can't do the right thing
On Saturday, 3 June 2017 at 13:17:46 UTC, Russel Winder wrote: Is this a problem in D or a problem in DStep? It's a limitation of DStep – for that use case, it would need to transform one of the macro arguments into a template argument rather than a runtime function parameter. If you need to make the code work as-is, I suppose you could create some aliases like `enum u32 = __u32.init;` and pass these instead of the types – using runtime values just to convey their type. — David
Re: Implicit conversion from 'Ok' to 'Result' type when returning functions
On Sunday, 21 May 2017 at 10:03:58 UTC, Nicholas Wilson wrote: As in the function signature of the function you call `ok` or `error` in. Result!(int, SomeEnum) myfunc(bool foo) { if(!foo) return ok(42); else return error(SomeEnum.fooHappened); } should work. This is what I've got right now. --- [module 1] struct Result(OkType, ErrType) { this(OkType ok) pure nothrow { isOk = true; okPayload = ok; } this(ErrType error) pure nothrow { isOk = false; errorPayload = error; } bool isOk; union { OkType okPayload; ErrType errorPayload; } } auto ok(T, E)(T payload) { return Result!(T, E)(payload); } auto error(T, E)(T payload) { return Result!(T, E)(payload); } --- [module 2] Result!(string, int) fn(bool shouldErr) { if (!shouldErr) return ok("No problem"); return error(0); } --- But it can't infer the second parameter. "template result.ok cannot deduce function from argument types !()(string)"
Re: Implicit conversion from 'Ok' to 'Result' type when returning functions
On Sunday, 21 May 2017 at 09:37:46 UTC, Nicholas Wilson wrote: On Sunday, 21 May 2017 at 09:29:40 UTC, David Zhang wrote: Well then it becomes Result!(T, E) ok(T,E) (T t) { return Result(t); } Result!(T, E) error(T,E)(E e) { return Result(e); } and then provided it can be inferred (e.g. from the function signature) it will still work. But how would it be inferred? Like the `ok` function, `T` could be inferred, but E? I'm not sure I understand. If you have to specify the types every time, it kinda defeats the purpose. With the function signature as it is, you'd have to specify the type of the other type (e.g. you'd need to specify E for `ok()`).
Re: Implicit conversion from 'Ok' to 'Result' type when returning functions
On Sunday, 21 May 2017 at 09:15:56 UTC, Nicholas Wilson wrote: have free functions Result!(T, ErrorEnum) ok(T)(T t) { return Result(t); } Result!(T, ErrorEnum) error(T)(ErrorEnum e) { return Result(e); } then go if (!foo) return ok(42); else return error(Error.fooHappened); Ah, I think you misread. ErrorEnum is a template type, like `T`. There's no ErrorEnum enum specified.
Implicit conversion from 'Ok' to 'Result' type when returning functions
Hi, I was reading a bit about this in Rust, and their enum type. I was wondering if this is replicate-able in D. What I've got right now is rather clunky, and involves using `typeof(return).ok` and `typeof(return).error)`. While that's not too bad, it does involve a lot more typing, and thus more area for human error. If you're not familiar with the Result and Option types, it allows you to do something like this: --- Result!(string, ErrorEnum) someFunction(...) { return Ok("Hello!"); } Result!(string, ErrorEnum) someFunction2(...) { return Error(ErrorEnum.dummyError); } --- I'm not entirely sure it's possible... but I figured I might give it a try.