Re: Find homography in D?
On Sunday, 21 April 2024 at 14:57:33 UTC, Paolo Invernizzi wrote: Hi, Someone can point me to a D implementation of the classical OpenCV find homography matrix? Thank you, Paolo Something I wrote awhile ago... ``` import kaleidic.lubeck : svd; import gfm.math; import mir.ndslice : sliced; auto generateTransformationArray(int[] p) { return generateTransformationArray(p[0],p[1],p[2],p[3]); } auto generateTransformationArray(int x, int y, int x_, int y_) { return [-x, -y, -1, 0, 0, 0, x*x_, y*x_, x_, 0, 0, 0, -x, -y, -1, x*y_, y*y_, y_]; } auto transformCoor (mat3d mat, vec3d vec) { auto res = mat * vec; return res / res[2]; } auto findHomography (int[][] correspondances) { auto a = correspondances .map!(a => a.generateTransformationArray) .joiner .array .sliced(8,9); auto r = a.svd; auto homog = r.vt.back; return mat3d(homog.map!(a => a/homog.back).array); } ```
profiling vibe
I can't seem to be able to use `--profile` with vibe: ```shell dub init -t vibe.d dub build --build=profile ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(142,3): Warning: statement is not reachable ../../.dub/packages/vibe-core/2.7.3/vibe-core/source/vibe/internal/async.d-mixin-119(143,3): Warning: statement is not reachable Error: warnings are treated as errors Use -wi if you wish to treat warnings only as informational. ``` I've tried using `buildRequirements "allowWarnings"`, but still the same. Jordan
Re: Help optimize D solution to phone encoding problem: extremely slow performace.
On Friday, 19 January 2024 at 08:57:40 UTC, Renato wrote: Do you know why the whole thread seems to have disappeared?? There's a lot of good stuff in the thread, it would be a huge shame to lose all that! I agree! Thanks for posting your benchmarks, I thought your whole benching setup was pretty good, and learnt alot from your code and the resulting contributions in the thread and others. Jordan
Re: Help optimize D solution to phone encoding problem: extremely slow performace.
On Saturday, 13 January 2024 at 11:03:42 UTC, Renato wrote: I like to use a phone encoding problem to determine the strenghtness and weaknesses of programming languages because this problem is easy enough I can write solutions in any language in a few hours, but complex enough to exercise lots of interesting parts of the language. [...] Hello Renato, This seems to be quite a lot of calls: ``` Timer frequency unknown, Times are in Megaticks Num TreeFuncPer CallsTimeTimeCall 1920496437613756 0 pure nothrow ref @trusted immutable(char)[][] core.internal.array.appending._d_arrayappendcTX!(immutable(char)[][], immutable(char)[])._d_arrayappendcTX(scope return ref immutable(char)[][], ulong) 1920492489573474 0 @safe void dencoder.printTranslations(immutable(char)[][][dencoder.Key], dencoder.ISolutionHandler, immutable(char)[], immutable(char)[], immutable(char)[][]) ``` This is when using the `words-quarter.txt` input (the `dictionary.txt` input seems to finish much faster, although still slower than `java`/`rust`). I also used only 100 phone numbers as input. My final observation is that `words-quarter.txt` contains some 1-letter inputs, (for example, `i` or `m`)...this may result in a large number of encoding permutations, which may explain the high number of recursion calls? Jordan
Desiring bool any_key_pressed()
Here is a very simple version of the program I'm working on. Is there a way to write is_any_key_pressed() that doesn't block, doesn't require the Enter key, and doesn't require dragging in any complex libraries or dealing with low-level stuff like ioctl()? Is there nothing in Phobos that provides the needed functionality? I won't go into the details, but I tried threading, putting the getchar() in a separate thread that sets a global bool g_keypressed variable. It was a disaster. Maybe there's a right way to use threading? I am not talented at threads. ``` import core.thread; import core.time; import std.stdio; import std.conv; void light_on() { write("on "); stdout.flush; } void light_off() { write("off "); stdout.flush; } void wait() { Duration dur = dur!("seconds")( to!int(1) ); Thread.sleep(dur); } bool is_any_key_pressed() { getchar(); // nope, requires Enter key to be pressed, and is blocking return true; } void main(string[] args) { while (true) { light_on(); wait(); light_off(); wait(); if (is_any_key_pressed()) { break; } } } ```
Re: stdin.readln line editing and recall with up arrow
On Saturday, 25 February 2023 at 08:47:42 UTC, Richard (Rikki) Andrew Cattermole wrote: On 25/02/2023 9:45 PM, Daren Scot Wilson wrote: I went with readline. Left/right arrows work, but up arrow still does not recall earlier commands. Maybe I need also a separate input history thing? https://tiswww.case.edu/php/chet/readline/readline.html#Basic-Behavior Hmm... the add_history(), or maybe it's rl_add_history(), function seems to have been in ancient readline versions but at some point all line history code was taken out to be its own library. https://tiswww.case.edu/php/chet/readline/rltop.html https://tiswww.case.edu/php/chet/readline/history.html Arch Linux drags in both readline.so and history.so in its readline package. No one notices! Trying import gnu.history; fails since there's no distinct 'history' package (yet) and Dub doesn't drag it in along with readline. D can call C and link to anything in /usr/lib easily. Done. It works! How does D know to link to the libhistory.so library? I didn't say "history" anywhere. But it works. extern (C) { void add_history(const char*); } I'm tempted to make a history package and submit it to DUB. Maybe. After dinner...
Re: stdin.readln line editing and recall with up arrow
On Saturday, 25 February 2023 at 05:41:48 UTC, Richard (Rikki) Andrew Cattermole wrote: On 25/02/2023 6:36 PM, Daren Scot Wilson wrote: stdin.readln() works fine until I, out of habit, use the up arrow to recall an earlier input and the left/right to move around and change a character. How do I get that to work? Not with that module. You can either use GNU readline itself, or Adam's version within arsd. I went with readline. Left/right arrows work, but up arrow still does not recall earlier commands. Maybe I need also a separate input history thing?
stdin.readln line editing and recall with up arrow
stdin.readln() works fine until I, out of habit, use the up arrow to recall an earlier input and the left/right to move around and change a character. How do I get that to work?
Re: Which TOML package, or SDLang?
On Monday, 30 January 2023 at 17:54:15 UTC, H. S. Teoh wrote: XML is evil. Agreed! I'm going with TOML, community package. It's working, so far.
Which TOML package, or SDLang?
So, which package do I use for TOML? I find these three: * toml-foolery (Andrej Petrović) * toml-d, or toml.d (oglu on github) at ver 0.3.0 * toml, (dlang community on github) at ver 2.0.1 I'm guessing from version numbers that the third one, toml, is officially good for real world use. But I wonder if there are good reasons to use the others. Also, a low-effort search for TOML in the D world turned up SDLang, where the substring "DLang" has nothing to do with dlang, the common short name for D Language. SDLang looks nice. Should I ditch TOML for it? I just realized - it's been ages since I've dealt with config files, beyond editing them as an end user. I work on existing software where someone else made the choiced and wrote the code, or it's a small specialized project not needing config. I'm a config caveman! This is for a small fun personal project with potential show-off value, available on github but too primitive for now to mention. Controlling hardware, needing to store device info to recall for later runs. There are zero compatibility or standards issues to consider. Whatever is simplest to implement and tinker with is the winner.
Re: Handling CheckBox state changes in DLangUI
On Saturday, 31 December 2022 at 03:05:45 UTC, brianush1 wrote: On Saturday, 31 December 2022 at 02:40:49 UTC, Daren Scot Wilson wrote: The compiler errors I get are, for no '&' and with '&': Error: function `app.checkbox_b_clicked(Widget source, bool checked)` is not callable using argument types `()` Error: none of the overloads of `opAssign` are callable using argument types `(bool function(Widget source, bool checked))` Try: import std.functional : toDelegate; check_c.checkChange = toDelegate(_b_clicked); That works :)
Handling CheckBox state changes in DLangUI
I'm writing a GUI program using dlangui. It has some checkboxes. I'm trying to figure out how to invoke a callback function when the user clicks the box. What are the valid ways of doing that? I can copy from dlangide's source, where a delegate is defined in-line and assigned. That seems to work. But is that the only way? bool g_x = true; bool checkbox_b_clicked(Widget source, bool checked) { g_x = checked; if (checked) { writeln(checked); } return true; } auto check_a = new CheckBox("wantalt", "Alternating"d); auto check_b = new CheckBox("wantblinkb", "Blink(delg)"d); auto check_c = new CheckBox("wantblinkc", "Blink(direct)"d); check_a.checkChange = delegate(Widget w, bool checked) { g_x=checked; return true; }; check_b.checkChange = delegate(Widget w, bool checked) { return checkbox_b_clicked(w,checked); }; check_c.checkChange = checkbox_b_clicked; check_c.checkChange = _b_clicked; The assignment to check_a is fine with the compiler. For check_b, I try calling a function defined earlier. (Maybe in real life it's too complex to try having inline.) It was giving a compiler error until I realized I'm dumb, wasn't passing 'w' and 'checked' to it. Fixed, works fine now. Okay! But what I think I should be able to do: assign checkbox_b_clicked directly to the .checkChange property of the checkbox, as shown for check_c. It doesn't work. Oh, I see an example where '&' is used - okay let's try that... nope! The compiler errors I get are, for no '&' and with '&': Error: function `app.checkbox_b_clicked(Widget source, bool checked)` is not callable using argument types `()` Error: none of the overloads of `opAssign` are callable using argument types `(bool function(Widget source, bool checked))`
Re: Passing D reimplementation of C++ template as argument to a C++ function
On Saturday, 24 September 2022 at 07:04:34 UTC, Gregor Mückl wrote: Hi! I have a D template struct that reimplements a C++ class template with identical memory layout for a set of types that matter to me. Now, I want to use some C++ functions and classes that use these template instances, from D. For that, I want to purposefully alias the D and C++ types. However, with the C++ type being templated, I don't know how to name that type in a extern declaration in D. [...] ``` extern(C++) extern(C++, class) struct Foo(T) { T a, b; } alias FooFloat = Foo!float; extern(C++) void bar(FooFloat f); ```
Re: how to install the new dmd on Mac M1?
On Friday, 26 August 2022 at 00:34:30 UTC, MichaelBi wrote: when using ldc2, has this error "ld: library not found for -lssl" after dub build --compiler=ldc2 So where is your ssl library located and how (if at all) are you telling the compiler/linker where to find it?
Re: Using LDC2 with --march=amdgcn
On Sunday, 24 July 2022 at 18:44:42 UTC, realhet wrote: Hello, I noticed that the LDC2 compiler has an architecture target called "AMD GCN". Is there an example code which is in D and generates a working binary of a hello world kernel. I tried it, and just failed at the very beginning: How can I specify __kernel and __global in D? As mentioned by Johan, LDC in conjunction with dcompute is the closest thing. You can use LDC to generate SPIR-V binaries with which I believe you should be able to use with the OpenCL implementation for that platform using dcompute to drive OpenCL.
Re: Python <==> d call both ways example (with PyD and autowrap)?
On Wednesday, 22 June 2022 at 16:02:00 UTC, mw wrote: Hi, I know with PyD, D can call Python, and with autowrap, Python can call a D .dll, I'm just wondering if someone can show an example that Python <==> d can call both ways? esp. show passing D objects to Python and then call its member function there, and vice versa. Thanks. When I did something like this, I used this as my inspiration: https://github.com/ariovistus/pyd/tree/master/examples/testdll So, I used PyD to supply D objects and read Python data also. Thanks, Jordan
Re: How to do same as 'nmap' command from within a D program?
On Sunday, 23 January 2022 at 06:30:11 UTC, frame wrote: On Saturday, 22 January 2022 at 20:55:38 UTC, Daren Scot Wilson wrote: I don't see any D std.* libraries that do this. Are there a Dub packages I should look at? If you really want to this in D without any external app or OS API you could just ping all possible hosts, see which respond and then use `getHostByAddr()` to find the hostname. Another more professional way is to query the ARP protocol, where you send a packet as broadcast to all interfaces in the network to find a MAC for a given IP - if any host responses with a MAC, the host is up. You have to build the packet data for yourself, there are examples on the web. The socket to use is family:INET, type:RAW and protocol:ICMP for ping or RAW for ARP or anything that isn't listed in D. As you can see, it's required to test every possible IP out (except for any other discovery protocols supported by your network/router). For this reason, any OS does this scan periodically and caches the result. On UNIX you can just directly read the file `/proc/net/arp`, no need to use nmap. I'll try this. Looks more educational. This is a personal project, a show-off project. Once I'm done with another portion of it, I'll get onto this. My program will need to scan only once, not even once per run, since I can stash the results in a config file, but once whenever the user knows the hardware devices have changed.
How to do same as 'nmap' command from within a D program?
I'm writing a command line program to control certain hardware devices. I can hardcode or have in a config file the IP addresses for the devices, if I know that info. If I don't? Then I run an 'nmap' command and look for the devices. But why should I, a human, have to do any work like that? Bah! I want my program to obtain this information at runtime, automatically, and "don't make me think". One thing that might make it tough is nmap must run sudo to report the desired information. (To my knowledge; I'm no networking expert.) The exact command is: sudo nmap -sn 192.168.11.0/24 |ack -B2 "Philips" The IP address is printed two lines before the name match (ack is "better than grep"). Typical nmap output is a series of chunks of text like this: Nmap scan report for 192.168.11.10 Host is up (0.00033s latency). MAC Address: 00:17:88:4D:97:4D (Philips Lighting BV) I don't see any D std.* libraries that do this. Are there a Dub packages I should look at?
Re: writeln the struct from the alis this Example from the home page
On Thursday, 18 November 2021 at 16:08:22 UTC, Paul Backus wrote: On Thursday, 18 November 2021 at 13:51:42 UTC, Martin Tschierschke wrote: [...] You can define a `toString` method, like this: ```d string toString() { import std.conv; return p.to!string; } ``` You can find more information about `toString` in the documentation here: https://dlang.org/phobos/std_format_write.html By the way, the reason your original version does not work is that `p` is `private`, so `writeln` cannot access it. If you change `p` to be `public`, it will work without a `toString` method. I thought private was to the module/file, not class/struct? Jordan
Re: Obtain pointer from static array literal
On Friday, 8 October 2021 at 05:31:21 UTC, codic wrote: On Friday, 8 October 2021 at 05:01:00 UTC, Nicholas Wilson wrote: note that if the pointer is not escaped from the function (i.e. thing is void thing(scope int* abc)note the addition of scope) LDC will perform promotion of GC allocation to stack of the array literal even if you don't use .staticArray. Interesting, I think you meant "even if you do use .staticArray"; No, I meant what I said. The array literal will cause a GC allocation, unless it is assigned to a static array of the same length or is inferred to be a static array. The latter happens when you pass it to `staticArray` because staticArray takes a static array as a parameter and the literal is inferred to be static array instead of a dynamic array, which is the default. not sure why it would do that, When you _don't_ use staticArray, what happens is LDC looks at the allocation and the fact that the allocated memory does not escape the passed to function (because the argument is annotated with `scope`) and turns the GC allocated dynamic array literal into a stack allocation (assuming that the array is of sufficiently small size as to not blow the stack). but it doesn't matter because my code is betterC I guess the point is moot and therefore nogc so it *should* allocate it on the stack, I think No, you can still try to use the GC in betterC but you will get a compile time error if you do so. Passing `-betterC` does not cause GC to stack promotion, it issues errors if you try to use GC (or any other feature that requires druntime like associative arrays or typeinfo).
Re: Obtain pointer from static array literal
On Friday, 8 October 2021 at 02:49:17 UTC, codic wrote: I am working with a C API (XCB) which uses `void*` a lot to obtain parameter packs; these are very small and throwaway so I want them to be allocated to the stack. CUDA has something similar that I have to deal with for dcompute[1]. The trick is that the parameter packs always have some sort of underlying structure to them and in D it is possible to exploit that structure at compile time to ensure that you don't break type safety. I can't give a more specific answer without some more concrete examples from XCB, but for CUDA the function signature of the kernel you are trying to launch dictates what goes into the parameter pack. The best way is to generate (or write) wrapper functions that do this for you such that you can call `wrappedFunc(x,y,w,h)` and statically verify through its type signature that uint[4] params=[x,y,width,height]; func(params.ptr); is a valid call to func. Of course, this is valid, but a bit painful: ```d uint[4] params=[x,y,width,height]; func(params.ptr); ``` especially when you have lots of calls. now, this compiles: ```d // (import std.array) func([x,y,width,height].staticArray.ptr); ``` but is it well-formed? or is it UB because it is a rvalue and scope ends? For simple types (i.e. ones with no destructor), like int, IIRC this is fine. When you have a static array of objects that need to be destructed, then end of scope becomes important. i.e. here is an example program, is it well formed? ```d import core.stdc.stdio, std.array; void thing(int* abc) { printf("%d\n", *abc); } extern(C) void main() { thing([1].staticArray.ptr); } ``` At any rate, it runs fine consistently with ldc: ``` $ ldc2 test.d -fsanitize=address $ ./test 1 ``` I don't know if it is spec-compliant though, or if it is actually causing UB here and I don't notice it. note that if the pointer is not escaped from the function (i.e. `thing` is `void thing(scope int* abc)`note the addition of `scope`) LDC will perform promotion of GC allocation to stack of the array literal even if you don't use `.staticArray`. https://github.com/libmir/dcompute/blob/master/source/dcompute/driver/cuda/queue.d#L80-L92
Re: How can we view source code that has been generated (say via "static foreach") ?
On Thursday, 16 September 2021 at 04:54:21 UTC, james.p.leblanc wrote: Thank you for your kind response. Wow, at first the large output file from a small test program was a bit surprising .., but actually it is manageable to dig through to find the interesting bits. So, this is quite useful! Thanks again, now I am off to do some digging... Best Regards, James Note that that will only give the expansions from string mixins, not from template mixins, templates and other things.
Re: yet another segfault - array out of bound is not caught by try catch
On Friday, 17 September 2021 at 11:10:33 UTC, seany wrote: I have now this function, as a private member in a Class : } catch (RangeError er) { I can't remember if you can catch an index OOB error but try `catch (Throwable er)` will work if it is catchable at all and you can figure out what kind of Error you have by printing its name. "Attempt to take address of value not located in memory" ? I am not even calling / accessing a pointer. I am trying to extract a value outside an array bound. `Type[]` arrays in D are effectively struct {size_t length; Type* ptr; } under the hood. Your problem is the array has no elements which is why trying to extract a value outside an array bound is an irrecoverable error. with the bound checking operation in place, would the bound error be triggered before the attempt to take unavailable address error has a chance to trigger? with a null array of zero length `arr`, `arr[0]` with bounds check enabled will fail the bounds check before it tries to dereference the pointer. if you try `arr.ptr[0]` to bypass the bounds checking (which is a very bad idea!) you will then try to load from an invalid memory address and crash.
Re: is it possible to sort a float range ?
On Wednesday, 23 June 2021 at 22:46:28 UTC, Steven Schveighoffer wrote: On 6/23/21 6:30 PM, Jordan Wilson wrote: On Wednesday, 23 June 2021 at 19:53:24 UTC, someone wrote: [...] ```sort``` returns a ```SortedRange```, and I believe you wish to return a float. So you can do either ```return lnumRange.sort!(...).array;```, or you can do ```lnumRange.sort!(...); return lnumRange```. Use the `release` method: ```d return lnumRange.sort!(...).release; ``` -Steve Wow...learn something new every day, cheers! Jordan
Re: is it possible to sort a float range ?
On Wednesday, 23 June 2021 at 19:53:24 UTC, someone wrote: Please, look for the line marked +++ This is a structure with a public property returning a (still unsorted) range built on-the-fly from already-set properties, a basic range from a to z with n step where some specific values can be added in-between. The range is a float which I am currently using for currency (horrible) and later plan to move it to decimal 10 or the like. [...] ```sort``` returns a ```SortedRange```, and I believe you wish to return a float. So you can do either ```return lnumRange.sort!(...).array;```, or you can do ```lnumRange.sort!(...); return lnumRange```.
Re: Now can build and run d on RISC-V arch?
On Sunday, 6 June 2021 at 04:14:20 UTC, lili wrote: I want learn RISC-V and write a simple kernel on it using d. but can not find any support about RISC-V. LDC can compile for riscv 32 and 64 bit. https://github.com/ldc-developers/ldc/releases/tag/v1.26.0 use `-mtriple=riscv32` or `-mtriple=riscv32` as the arch for the triple. I'm not sure what you should put for the `os` and `env` fields of the triple. The vendor field can be left as `unknown`. Do a search for triples people use to target riscv and use that if the above doesn't work.
Re: DUB doesn't seem to respect my config, am I doing something wrong?
On Saturday, 22 May 2021 at 20:28:56 UTC, rempas wrote: I've read the documentation about DUB's config (I'm using the SDL format) and it seems that DUB completely ignores my config. My config file is: ``` name "test" description "Testing dub" authors "rempas" copyright "Copyright © 2021, rempas" license "AGPL-3.0" compiler "ldc2" configuration "development" { platforms "linux" build "dubug" compiler "ldc2" targetType "executable" } configuration "release" { platforms "linux" dflags "-Oz" platform="/bin/ldc2" build "release" compiler "ldc2" targetType "executable" } ``` I'm compiling using `dub --config=development` and I'm getting the following line: `Performing "debug" build using /usr/bin/dmd for x86_64`. The same exactly happens when I'm trying to do the release config. If I disable the `targetType` option, it seems that it's creating a library and I can also manually change the compiler and the build-type so I don't know what's going on Ignoring the "dubug" typo...normally, I think you pass compiler values directly to dub via the ```--compiler``` flag. For example: ```shell dub --config=development --compiler=ldc2 ``` Note: you can also pass "debug" and "release" builds (among others), like so: ```shell dub -b "debug" --compiler=ldc2 ``` Passing in the compiler allows any end user building your code to use whatever compiler they want. Otherwise, something like ```toolchainRequirements dmd="no" ldc=">=1.21.0"``` may achieve what you want. Thanks, Jordan
Re: Recommendations on avoiding range pipeline type hell
On Sunday, 16 May 2021 at 09:55:31 UTC, Chris Piker wrote: On Sunday, 16 May 2021 at 09:17:47 UTC, Jordan Wilson wrote: Another example: ```d auto r = [iota(1,10).map!(a => a.to!int),iota(1,10).map!(a => a.to!int)]; # compile error ``` Hi Jordan Nice succinct example. Thanks for looking at the code :) So, honest question. Does it strike you as odd that the exact same range definition is considered to be two different types? Maybe that's eminently reasonable to those with deep knowledge, but it seems crazy to a new D programmer. It breaks a general assumption about programming when copying and pasting a definition yields two things that aren't the same type. (except in rare cases like SQL where null != null.) On a side note, I appreciate that `.array` solves the problem, but I'm writing pipelines that are supposed to work on arbitrarily long data sets (> 1.4 TB is not uncommon). There are those far more learned than me that could help explain. But in short, yes, it did take a little getting used to it - I would recommend looking at Voldemort types for D. Ironically, use of Voldemort types and range-based programming is what helps me perform large data processing. Jordan
Re: Recommendations on avoiding range pipeline type hell
On Sunday, 16 May 2021 at 07:20:52 UTC, Chris Piker wrote: On Saturday, 15 May 2021 at 14:05:34 UTC, Paul Backus wrote: If you post your code (or at least a self-contained subset of it) someone can probably help you figure out where you're running into trouble. The error messages by themselves do not provide enough information--all I can say from them is, "you must be doing something wrong." I just tacked on `.array` in the the unittest and moved on for now, but for those who may be interested in the "equivalent but not equivalent" dmd error message mentioned above, the code is up on github. To trigger the error message: ```bash git clone g...@github.com:das-developers/das2D.git cd das2D rdmd -unittest --main das2/range.d # This works ``` In file `das2/range.d`, comment out lines 550 & 553 and uncomment lines 557 & 558 to get alternate definitions of `coarse_recs` and `fine_recs` then run rdmd again: ```bash rdmd -unittest --main das2/range.d # No longer works ``` In addition to the issue mentioned above, comments on any style issues, best practices or design choices are invited. By the way the writeln calls in the unittests just temporary. Essentially, `dr_fine` and `dr_coarse` are different types. For example: ```bash echo 'import std; void main() { auto a = [a,"test"]; }' | dmd -run - # your error ``` Another example: ```d auto r = [iota(1,10).map!(a => a.to!int),iota(1,10).map!(a => a.to!int)]; # compile error ``` Using ```.array``` on both of the elements of r will compile. Thanks, Jordan
Re: Local library with dub
On Wednesday, 21 April 2021 at 15:07:25 UTC, JG wrote: On Wednesday, 21 April 2021 at 00:39:41 UTC, Mike Parker wrote: On Tuesday, 20 April 2021 at 18:43:28 UTC, JG wrote: This still leaves open the question of how to include a version of such a library in another project via dub. Execute `dub add-local` followed by the path to the project's root directory (the directory containing the `dub.json/sdl`) and a version number in semver format. ``` dub add-local path 0.1.0 ``` Then you can use the package just as you would any other dub dependency. Thanks. I suppose this means that if you want to able to use multiple versions you have to keep each version in a separate directory and add them individually, and there is no way of being able to get the appropriate version from say a git repository? You can specify git repos as dependencies, if this helps. https://dlang.org/changelog/2.094.0.html#git-paths Jordan
Re: Contributing CDF bindings to Deimos
On Thursday, 25 March 2021 at 04:00:33 UTC, Chris Piker wrote: On Tuesday, 23 March 2021 at 05:54:13 UTC, mw wrote: [...] Okay, that's done. The repo https://github.com/das-developers/deimos.cdf and package https://code.dlang.org/packages/cdf have been drafted and tested on Linux, I'm about to test on Windows and MacOS. As an aside, software developers at NASA Goddard have now heard of D which is nice. They were pleased to see that it was supported by gcc. (Hat tip to the GDC team) I've attempted to follow all guidelines as best I understood them, but this is my first package. It likely has some style and functionality issues. Is there a peer review stage to this process that is triggered automatically or could be requested? Nice one. I've used HDF5/NetCDF, will have to check out and see what CDF offers. Jordan
Re: Strange error
On Monday, 22 March 2021 at 07:52:14 UTC, MichaelJames wrote: Tell me, did you manage to solve this problem? https://github.com/dlang/dmd/pull/12300
Re: Simple BeamUI project won't link
On Wednesday, 16 December 2020 at 07:45:50 UTC, Ferhat Kurtulmuş wrote: On Wednesday, 16 December 2020 at 07:40:45 UTC, Ferhat Kurtulmuş wrote: This may be not your issue, but I could manage it to work by adding this line: subPackage "examples/myproject" to the dub.sdl of the beamui. I simply put my project in examples/ folder. And compile and run using: dub run :myproject The thought crossed my mind to try putting my source under examples/ but that's not a good way to organize a real project. I'd like it be under ~/projects/, naturally. What I want to make will involve a lot more than just a GUI.
Re: Simple BeamUI project won't link
On Wednesday, 16 December 2020 at 07:40:45 UTC, Ferhat Kurtulmuş wrote: On Wednesday, 16 December 2020 at 07:02:11 UTC, Daren Scot Wilson wrote: Trying out the beamui GUI package, obtained by git clone from github. The "basic" example builds and runs. I'm working on an Arch Linux machine with lots of RAM, but a user with not enough practice at D yet. I have a little experience with beamui but only on windows. It is under WIP. You'd better open an issue with an error report on GitHub as I did before https://github.com/dayllenger/beamui/issues/16. You may get some help from the maintainer. So maybe beamui isn't ready for the real world. It's a one-off personal tool for image processing, maybe will go up on Github, so I don't need anything super-solid or well established. OTOH, if it's too much on the WIP side with lots of loose ends, it might be more work than my free time allows. At least, beamui appears to be more workable than dlangui which seems to have fallen away.
Simple BeamUI project won't link
Trying out the beamui GUI package, obtained by git clone from github. The "basic" example builds and runs. So I create a new project from scratch, with "dub init beamy beamui" (ircc) in a directory outside beamui's, sibling to it in fact. This builds and runs, but does not make use of beamui at all. So I copy a tiny bit from the basic example. It only initializes a GuiApp: import std.stdio; import beamui; int main() { GuiApp app; if (!app.initialize()) { writeln("App no init :("); return 1; } return 0; } Here's the dub file: name "beamy" description "trying BeamUI" license "none" authors "darenw" targetName "beamy" targetType "executable" dependency "beamui" path="../../beamui/" dependency "beamui:platforms" path="../../beamui/platforms/" Running "dub build" leads to compiling but no linking. undefined reference to `initPlatformProxy'. Note that this build takes place in a directory such that ../../beamui/ goes to the top-level directory for beamui. Changing the path or replacing 'beamui' with 'beamuixxx' prevents the build from getting anywhere at all, so the path is right. I compared everything with the basic example, but am either missing some obvious detail or have something screwed up, or failed to add something, or need to say some secret magic incantation. I'm working on an Arch Linux machine with lots of RAM, but a user with not enough practice at D yet.
synthesising instantiated template parameters and arguments
Given template ScopeClass(C) { //... } where C is a, possibly templated, class I want the eponymous member of ScopeClass!(C) to have the same templatedness (both parameters and arguments)as C. For a non-template C this is a simple as: template ScopeClass(C) { class ScopeClass { // implement members with compile time reflection } } but for a templated C this is tricker as I can't use a template sequence parameter (...) unless C uses it in the same position (I'm trying to generate a mangle from it so it needs to be exact). Given class A(T,int,args...) {} alias C = A!(int, 0, float); I need `ScopeClass!C` to be template ScopeClass(C) { class Anon(T,int,args...) // name doesn't matter { // implement members with compile time reflection } alias ScopeClass = Anon!(int, 0, float); } How do I do this?
Re: Two ways of receiving arrays on the C ABI
On Tuesday, 20 October 2020 at 00:16:48 UTC, Ali Çehreli wrote: On the D side, both of the following extern(C) functions take the same arguments. https://github.com/dlang/dmd/pull/8120 there are issues with structs. Not sure about length/ptr.
Re: Asserting that a base constructor is always called
On Sunday, 24 May 2020 at 06:38:46 UTC, Tim wrote: Oh right. I mean it makes sense but I got confused when super() is valid syntax. Why would you need to call the super constructor when it's called automatically? A base class with a constructor that has no args will automatically get called at the start of a child class if it is not explicitly called. You can call it yourself anywhere in an always executed branch of the constructor. As for why, if you wanted to do some logging before the base constructor was called. You need to call the base class's constructor explicitly when it has arguments and there is no default constructor in the base class. This must be done in an always executed branch. This must be called or the compiler will issue an error.
Re: Thread to watch keyboard during main's infinite loop
On Thursday, 7 May 2020 at 01:02:57 UTC, ag0aep6g wrote: Thank you, this is 110% helpful. Actually, I'd like to return the excess 10%. My dmd compiler does not like: import core.thread: sleep; so I put the code back the way I had, just to get on with work. Use `shared` so that all threads use the same variables: shared bool running=true; shared char command = '?'; "shared" did the job. I had read about "thread local" and "shared" in D before, but did not comprehend. Now I do :) This sequence of events is entirely possible: 1) main: cmd = command 2) cmdwatcher: command = c 3) main: command = ' ' It won't happen often, but if it does, your input has no effect. For this tool, lost key hits are not a problem. At least, that's what I say for now. I may be back next week for help with that. For now, the trousered ape running the software will just have to tap the key again. (Or the key + Enter.)
Thread to watch keyboard during main's infinite loop
I'm writing a simple command line tool to send data by UDP once per second forever, to test some software on another machine. Not actually forever, of course, but until ^C or I hit 'Q'. I want to tap keys to make other things happen, like change the data or rate of sending. Not sure of the best way to do this. Thought I'd try a thread whose job is just to loop, calling readln() or getch() or something similar, and setting a global variables according to what key was tapped. The loop in the main thread can then break, or do some other action, according to the value of that variable. Code I have written is below, stripped to just the stuff relevant to key watching. It doesn't work. When it runs, it prints "Repetitive work" over and over, but never see anything appear in "cmd [ ]". When I tap 'A' I expect to see "cmd [A]" and a line of several 'A'. This does not happen. But the writeln in cmdwatcher() does show whatever I typed just fine. How to fix this, or redesign the whole thing to work? Note that I'm coming from science and fine art. My know-how in computer science is uneven, and I probably have gaps in my knowledge about threads. import std.stdio; import core.stdc.stdio; // for getchar(). There's nothing similar in D std libs? import std.concurrency; import core.thread; // just for sleep() bool running=true; char command = '?'; void cmdwatcher() { writeln("Key Watcher"); while (running) { char c = cast(char)getchar(); if (c>=' ') { command = c; writefln(" key %c %04X", c, c); } } } void main() { writeln("Start main"); spawn(); while (running) { writeln("Repetitive work"); Thread.sleep( dur!("msecs")( 900 ) ); char cmd = command; // local copy can't change during rest of this loop command = ' '; writefln("cmd [%c] running %d", cmd, running); switch (cmd) { case 'A': writeln("A A A A A"); break; case 'Q': writeln("Quitting"); running=false; break; default: break; } } }
Re: determine ldc version in static if or version?
On Wednesday, 1 April 2020 at 21:19:54 UTC, Adam D. Ruppe wrote: I want to do like static if(__LDC_VERSION == 1.19) { // declaration } All the tricks I know that I have tried so far give the dmd numbers. Perhaps I could use that to identify a particular version as a hack, but I specifically am curious about the ldc version because of a change they made there independently of D. Is there something I don't know about? https://github.com/ldc-developers/druntime/blob/ldc/src/ldc/intrinsics.di#L22-L34 version (LDC_LLVM_309) enum LLVM_version = 309; else version (LDC_LLVM_400) enum LLVM_version = 400; else version (LDC_LLVM_500) enum LLVM_version = 500; else version (LDC_LLVM_600) enum LLVM_version = 600; else version (LDC_LLVM_700) enum LLVM_version = 700; else version (LDC_LLVM_701) enum LLVM_version = 701; else version (LDC_LLVM_800) enum LLVM_version = 800; else version (LDC_LLVM_900) enum LLVM_version = 900; else version (LDC_LLVM_1000) enum LLVM_version = 1000; else version (LDC_LLVM_1100) enum LLVM_version = 1100; else static assert(false, "LDC LLVM version not supported"); enum LLVM_atleast(int major) = (LLVM_version >= major * 100);
Re: Best way to learn 2d games with D?
On Sunday, 15 March 2020 at 17:58:58 UTC, Steven Schveighoffer wrote: I want to try and learn how to write 2d games. I'd prefer to do it with D. I've found a ton of tutorials on learning 2d gaming with other languages. Is there a place to look that uses D for learning? Should I just start with another language and then migrate to D later? Anyone recommend any specific tutorial/book? -Steve I'm on a similar journey myself, I'll list my findings, maybe it could be useful for you. I decided on a game programming library. I mostly looked at SFML and Allegro, and found both to have good bindings available in D, and good documentation, and got minimal examples working with both. I went with SFML, simply because there was a book written specifically about writing a game in SFML. I didn't see any such books for Allegro (although there are plenty of tutorials/articles). I learnt about the "game loop". Bauss touched on it in his post, and I'm sure there are a lot of tutorials on it. I specifically learnt about it from the first few chapters of the SFML Game Development book. I learnt about game design. In doing so, I came across Entity-Component-System design pattern. I decided to use this pattern, for no other reason than to try something other than OOP. I found these links useful: https://medium.com/ingeniouslysimple/entities-components-and-systems-89c31464240d https://gameprogrammingpatterns.com/component.html https://www.richardlord.net/blog/ecs/what-is-an-entity-framework.html I started writing a game, using the derelict-sfml2 as my game library (again, I found the allegro library to be good too), and entitysysd to provide the ECS framework (there are a few ECS written in D available). Are they the best choices? Is SFML technically limited? Will I cope with ECS beyound the toy game example? No idea. But I'm having a lot of fun, which I think for a hobby project, is a fairly good measure of success ;-) Jordan
Re: SQLite 3 support?
On Wednesday, 26 February 2020 at 20:06:20 UTC, mark wrote: There seems to be some support for SQLite 3 in std. lib. etc when looking at the stable docs: https://dlang.org/phobos/etc_c_sqlite3.html But this isn't visible when looking at stable (ddox). Is this the best SQLite 3 library to use or is a third-party library best? For example https://github.com/biozic/d2sqlite3 I use d2sqlite3 regularly, no problems at all with it. I have no experience with the std. lib one. Jordan
Re: Finding position of a value in an array
On Tuesday, 31 December 2019 at 06:01:36 UTC, Paul Backus wrote: countUntil operates on ranges, and static arrays aren't ranges. To get a range from a static array, you have to slice it with the `[]` operator: int i = info.doos[].countUntil(important_d); (Why can't static arrays be ranges? Because ranges can shrink, via popFront, but a static array can never change its length.) Aha, adding [] made the compiler happy.
Re: Finding position of a value in an array
On Monday, 30 December 2019 at 23:15:48 UTC, JN wrote: On Sunday, 29 December 2019 at 08:31:13 UTC, mipri wrote: int i = a.countUntil!(v => v == 55); assert(i == 2); I also had to ask because I couldn't find it. In other languages it's named "index()", "indexOf()" or "find()". D is the only language I know which uses the "countUntil" scheme. And even so it's not obvious from the name if it's the index of the element or number of preceding elements. I had first tried myarray.index(myvalue) because I coulda sworn I wrote exactly that syntax a only a few days ago. But I've been hopping between languages, some D, some Crystal, some C++, some Javascript, and with only two cerebral hemispheres, maybe I got confused. So, D doesn't have index()? Is it called find()? Something else? It was hard to find the right stuff in the documentation. So now I know about countUntil, and I'm glad the question has gotten some traction for others to make progress with their code. I'm needing to see more examples. It might have something to do with the array I'm working with being inside a foreach loop. My code looks like this, with the problematic line duplicated to show some of the variations I tried: import std.algorithm; alias doo = ubyte; struct Info { int x; doo[NDOOS] doos; // NDOOS = 10 } immutable int INFO = 10; Info[NINFOS] infos;// global array, used heavily. float foo_function(doo important_d){ ... foreach (info; infos){ int i = info.doos.index(important_d); // #1 int i = info.doos.countUntil(d => d == important_d); // #2 int i = info.doos.countUntil!(d => d == important_d); // #3 int i = countUntil(d => d == important_d, info.doos); // #4 int i = countUntil!(d => d == important_d)(info.doos); // #5 if (i>=0) { // assuming -1 represents value not found ... do stuff with i ... } } ... } All the lines shown give me "template ... cannot deduce function from argument types..." but one time I got, but cannot reproduce now, the error "Error: template instance countUntil!((d) => d == important_d, doos) has no value"
Finding position of a value in an array
Reading documentation... Array, Algorithms, ... maybe I've been up too late... how does one obtain the index of, say, 55 in an array like this int[] a = [77,66,55,44]; I want to do something like: int i = a.find_value_returning_its_index(55); assert(i==2) I'm sure it's obvious but I'm not seeing it right now.
Re: No UFCS with nested functions?
On Monday, 4 November 2019 at 19:51:26 UTC, Tobias Pankrath wrote: Why does the following not work? It works, if I move the 'prop' out of 'foo'. --- struct S { ubyte[12] bar; } bool foo (ref S s) { static bool prop(const(ubyte)[] f) { return f.length > 1; } return s.bar[].prop; } --- Thanks! https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/ struct S { ubyte[12] bar; } alias I(alias f) = f; bool foo (ref S s) { static bool prop(const(ubyte)[] f) { return f.length > 1; } return s.bar[].I!prop; }
Re: exceptions and optimization
On Monday, 21 October 2019 at 21:09:32 UTC, Peter Jacobs wrote: On Monday, 21 October 2019 at 20:37:32 UTC, Nicholas Wilson wrote: What kind of conditions are you wanting to throw exception on? infinities, NaNs, ill conditioning, something else? As always the best way to check is to mark the function of interest, nothrow take a look at the disassembly and compare to without nothrow. You may also want to look to the optimisation summary that I _think_ you can get LDC to generate. Our methods take a few short cuts and occasionally step over a stability boundary, so I guess that it may look like ill-conditioning. The reason I asked that is to see what sort of action you take because there may be better architectures that you can use to handle that kind of change. For example, you are integrating with some scheme and hit a region of high curvature and need to rollback and change scheme (to either a less coarse time step or better integrator). In which case it may be best to take a page out of databases and use a change-commit kind of approach to short circuit through your calculations and if at the end of your update loop a flag is set that says this update is invalid then retry with another scheme. Thank you for the explanation and suggestions.
Re: contains method on immutable sorted array
On Monday, 21 October 2019 at 10:14:54 UTC, Andrey wrote: Hello, I have got a global constant immutable array: immutable globalvalues = sort(cast(wstring[])["й", "ц", "ук", "н"]); Somewhere in program I want to check an existance: globalvalues.contains("ук"w).writeln; But get an error: Error: template std.range.SortedRange!(wstring[], "a < b").SortedRange.contains cannot deduce function from argument types !()(wstring) immutable, candidates are: /dlang/ldc-1.17.0/bin/../import/std/range/package.d(10993): std.range.SortedRange!(wstring[], "a < b").SortedRange.contains(V)(V value) if (isRandomAccessRange!Range) Why I can't check? pragma(msg,typeof(globalvalues)); gives immutable(SortedRange!(wstring[], "a < b")) and (cast(SortedRange!(wstring[], "a < b"))globalvalues).contains("ук"w).writeln; works, so I guess contains doesn't work with immutable? If you can do some more research into this and confirm it then, please file a bug report.
Re: exceptions and optimization
On Monday, 21 October 2019 at 20:12:19 UTC, Peter Jacobs wrote: Toward the end of Walter's recent talk, D at 20, he says something to the effect that optimizations are disabled when exceptions can be thrown. We have a compressible flow solver in which it is very convenient to be able to throw an exception from deep within the code and catch it at a relatively high level where we can partially recover and continue the calculation. Because our calculations can run for days across hundreds of processors, we also care about letting the optimizer do its best. In what parts of our program would the optimizer be disabled because of the presence of the exception and its handling code? How do we tell? It really comes into effect if you use: a) structs with destructors b) scope(exit) and scope(failure) as these need to be run, regardless of the return mode of the function i.e. normally or via an exception. Also if the function is nothrow (possibly inferred because its a template, n.b. also that nothrow function can throw Errors as these are considered terminal) then you should also be fine. The effect of exceptions on optimisation effect logic heavy code a lot more that math heavy code. What kind of conditions are you wanting to throw exception on? infinities, NaNs, ill conditioning, something else? As always the best way to check is to mark the function of interest, nothrow take a look at the disassembly and compare to without nothrow. You may also want to look to the optimisation summary that I _think_ you can get LDC to generate.
Re: Is there a way to do the same thing in entry and return of a bunch of functions?
On Tuesday, 17 September 2019 at 17:11:09 UTC, Stefanos Baziotis wrote: I think it's better to give a concrete example rather than explaining this vaguely. -- The question -- Can we do better ? For one, I believe that because D does not have a preprocessor, we have to do an actual declaration which would be somewhat more verbose. Or do a mixin that does it. mixin can help as it can be more complicated and also we can access local scope (although I don't think this is a good idea). But in both cases, they're not totally invisible. Can we do something like: func1, func2 and func3, when they enter do the X and when they return, they do the Y. Thanks, Stefanos I think a mixin that does string LOG_SCOPE = q{ callDepth++; scope(exit) callDepth--; } is probably the easiest. for bonus points string LOG_SCOPE = q{ callDepth++; debug_log(__FUNCTION__);// or __PRETTY_FUNTION__ scope(exit) callDepth--; } and the mixin(LOG_SCOPE); I mean you _could_ do some UDA reflection to generate wrapping function that do the indentation, bit that is overkill.
Re: LDC asm for int128
On Tuesday, 10 September 2019 at 06:18:05 UTC, Newbie2019 wrote: I want to translate this c code into d (build with ldc), so I can use -flto and inline with other code. uint64_t _wymum(uint64_t A, uint64_t B){ __uint128_t r = A ; r *= B; return (r>>64)^r; } Do i need ASM or is there a easy way to implement it ? Easiest way is to use GFM's[1] 128bit integers. [1]:http://code.dlang.org/packages/gfm
Re: Undefined reference - built from source DMD
On Tuesday, 10 September 2019 at 11:12:30 UTC, Stefanos Baziotis wrote: I don't if this the right group to post this. DMD built from source fails to link / find `main`. The error is: /usr/lib/gcc/x86_64-linux-gnu/7/../../../x86_64-linux-gnu/Scrt1.o: In function `_start': (.text+0x20): undefined reference to `main' collect2: error: ld returned 1 exit status Error: linker exited with status 1 Does anyone know how this could have happened? Is this you have built your own DMD and using it to compile a test program and you get that error, or you get that error trying to build DMD?
Re: Why is sformat and formattedWrite (appender) allocating GC mem here?
On Saturday, 31 August 2019 at 21:12:32 UTC, ag0aep6g wrote: I've made a pull request to get rid of those allocations: https://github.com/dlang/phobos/pull/7163 Merged.
Re: Is removing elements of AA in foreach loop safe?
On Thursday, 29 August 2019 at 10:11:58 UTC, berni wrote: Iterating of some structure and removing elements thereby is always errorprone and should be avoided. But: In case of AA, I've got the feeling, that it might be safe: foreach (k,v;ways) if (v.empty) ways.remove(k); Do you agree? Or is there a better way to achieve this? This should work, due to the keys property returning a dynamic array: foreach (k; ways.keys) { if (ways[k].empty) ways.remove(k); } Jordan
Re: Shadertoy in Dcompute?
On Thursday, 22 August 2019 at 00:57:26 UTC, Bert wrote: How hard would it be to do something like Shadertoy in Dcompute and would it be any faster? I don't like the basics of Shadertoy, lots of nonsense to do basic stuff. E.g., to work with complex numbers one must essentially do everything manually. Would there be any benefit using Dcompute(last time I tried it I couldn't get it to work). DCompute is primarily for compute at the moment, and not graphics. It targets OpenCL and CUDA, not OpenGL/WebGL/Vulkan/DirectX. Thats not to say that you can't use it for computational graphics but you wouldn't be utilising the specialised hardware for the rendering pipeline, so it would probably be slower. If you want to have a crack at it, I'd take a look at how to do graphics with OpenCL or CUDA and adapt what you can. I haven't tested OpenCL/OpenGL interop at all (with or without DCompute) but it is a thing.
Re: Function called twice
On Friday, 2 August 2019 at 22:35:53 UTC, Adam D. Ruppe wrote: On Friday, 2 August 2019 at 21:44:28 UTC, Jordan Wilson wrote: // outputs 1 2 2 3 z.map!(a => tuple!("number","iseven")(a, a.isEven)) .filter!(a => a.iseven) .array; I *think* what's happening here is first it calls map() first going into the filter... then it gets called again when it is being evaluated for the array. So like basically consider if you had: if(filter(a()) array ~= a(); that kind of thing. I think anyway, I'm not entirely sure but it fits what I can see happening here. but idk why it is actually doing this in the phobos implementation In my real-world case "isEven" is a long running function. I'll put an .array after the map and see if it makes a difference. Thanks, Jordan
Function called twice
Hello, I don't quite understand why isEven is called twice in the 2nd example? auto isEven(int n) { n.writeln; return (n % 2) == 0; } void main() { auto z = [1,2,3]; // outputs 1 2 3 z.map!(a => tuple!("number")(a)) .filter!(a => a.number.isEven) .array; // outputs 1 2 2 3 z.map!(a => tuple!("number","iseven")(a, a.isEven)) .filter!(a => a.iseven) .array; return; } Thanks, Jordan
Re: Wrong vtable for COM interfaces that don't inherit IUnknown
On Monday, 15 July 2019 at 22:01:25 UTC, KytoDragon wrote: I am currently trying to write a XAudio2 backend and have come across the problem, that some of the interfaces for XAudio2's COM objects seem to be missing the first entry in their vtable. After reading the iterface article in the spec (https://dlang.org/spec/interface.html#com-interfaces) it seems that only interfaces inheriting from core.stdc.windows.com.IUnknown (or any interface named "IUnknown") get the COM interface layout instead of the D layout. What can I do to get the COM layout on interfaces that don't inherit IUnknown? Examples: IXAudio2Voice or any of the IXAudio2*Callback interfaces. I have already declared everything extern(Windows), but that does not fix it. From memory COM interfaces are really just `extern(C++) interface`s, so extern(C++) interface IXAudio2Voice { //methods... } should do the trick
Re: Finding Max Value of Column in Multi-Dimesional Array
On Friday, 5 July 2019 at 00:54:15 UTC, Samir wrote: Is there a cleaner way of finding the maximum value of say the third column in a multi-dimensional array than this? int[][] p = [[1,2,3,4], [9,0,5,4], [0,6,2,1]]; writeln([p[0][2], p[1][2], p[2][2]].max); I've tried the following writeln([0, 1, 2].map!(p[a][2]).max); but get an "Error: undefined identifier a" error. I know there doesn't seem to be much of a difference between two examples but my real-world array is more complex which is why I'm looking for a more scalable option. Thanks Samir p.map!(a => a[2]).maxElement.writeln; // 5 p.map!"a[2]".maxElement.writeln; // 5 Or, modifying your example: writeln([0,1,2].map!(a => p[a][2]).maxElement; Thanks, Jordan
Re: D on ARM laptops?
On Wednesday, 3 July 2019 at 20:49:20 UTC, JN wrote: Does anyone know if and how well D works on ARM laptops (such as Chromebooks and similar)? For example this one https://www.pine64.org/pinebook/ . Can it compile D? Obviously DMD is out because it doesn't have ARM builds. Not sure about GDC. How about LDC? Haven't tried on laptops, but I can't imagine it would be too different to RasPi which LDC worked fine on.
Re: Illegal Filename after basic install and trying Hello World
On Wednesday, 26 June 2019 at 13:57:22 UTC, Gilbert Fernandes wrote: I am using VS 2019 into which I have C# and C++ active. Installed the following : DMD 2.086.1 then Visual D 0.50.0 DMD has been installed at the base of C:\ at C:\D Created a D project, which contains a default Hello world program. Build fails. Running the program fails. VS displays the following error : -- Build started: Project: Test2, Configuration: Debug x64 -- Building x64\Debug\Test2.exe... OPTLINK (R) for Win32 Release 8.00.17 Copyright (C) Digital Mars 1989-2013 All rights reserved. http://www.digitalmars.com/ctg/optlink.html OPTLINK : Error 8: Illegal Filename == Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped == Besides installing Visual D and creating a new project, done nothing. I have searched the forum for people with the same problem and found two threads. https://forum.dlang.org/post/poq048$28mm$1...@digitalmars.com https://forum.dlang.org/post/xmhkgkqujxmzruque...@forum.dlang.org None do help. The option "override linker settings from sc.ini" it may be called dmd.conf (it is on my Mac, but the windows may be different) is nowhere it seems. I have checked both inside the current project properties, and VS settings themselves. I have the following cmd to build the program in the folder : set PATH=C:\Program Files (x86)\Visual Studio\VC\bin;C:\Program Files (x86)\Visual Studio\Common7\IDE;C:\Program Files (x86)\Windows Kits\10\bin;C:\D\dmd2\windows\bin;%PATH% set DMD_LIB=C:\Program Files (x86)\Visual Studio\VC\lib\amd64 set VCINSTALLDIR=C:\Program Files (x86)\Visual Studio\VC\ set VCTOOLSINSTALLDIR=C:\Program Files (x86)\Visual Studio\VC\Tools\MSVC\14.21.27702\ set VSINSTALLDIR=C:\Program Files (x86)\Visual Studio\ set WindowsSdkDir=C:\Program Files (x86)\Windows Kits\10\ set WindowsSdkVersion=10.0.17763.0 set UniversalCRTSdkDir=C:\Program Files (x86)\Windows Kits\10\ set UCRTVersion=10.0.17763.0 "C:\Program Files (x86)\VisualD\pipedmd.exe" -deps x64\Debug\Test2.dep dmd -m64 -g -gf -debug -X -Xf"x64\Debug\Test2.json" -c -of"x64\Debug\Test2.obj" Test2.d if %errorlevel% neq 0 goto reportError set LIB=C:\D\dmd2\windows\bin\..\lib64 echo. > D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp echo "x64\Debug\Test2.obj" /OUT:"x64\Debug\Test2.exe" user32.lib >> D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp echo kernel32.lib >> D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp echo legacy_stdio_definitions.lib /LIBPATH:"C:\Program Files (x86)\Visual Studio\VC\lib\amd64" /DEBUG /PDB:"x64\Debug\Test2.pdb" /INCREMENTAL:NO /NOLOGO /noopttls /NODEFAULTLIB:libcmt libcmtd.lib /SUBSYSTEM:CONSOLE >> D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp "C:\Program Files (x86)\VisualD\mb2utf16.exe" D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp "C:\Program Files (x86)\VisualD\pipedmd.exe" -msmode -deps x64\Debug\Test2.lnkdep C:\D\dmd2\windows\bin\link.exe @D:\sources_D\Test2\Test2\x64\Debug\Test2.link.rsp if %errorlevel% neq 0 goto reportError if not exist "x64\Debug\Test2.exe" (echo "x64\Debug\Test2.exe" not created! && goto reportError) goto noError :reportError echo Building x64\Debug\Test2.exe failed! :noError Typing "link" seems to launch the D Optilink Linker by default on my CMD. If I understand properly, I should be using the VS C++ supplied linker ? Correct. You have VS, so it is of no use to you. Use the VS one instead of C:\D\dmd2\windows\bin\link.exe in your build file. You can just delete the wrong link.exe any hopefully it will pick up the correct one in the $PATH. Also any reason why you (or is that visualD doing that? )are manually invoking the linker? Omit -c and dmd will invoke the linker for you (hopefully the correct one).
Re: DIP 1016 and const ref parameters
On Wednesday, 19 June 2019 at 19:25:59 UTC, Jonathan M Davis wrote: Aside from looking through the newsgroup/forum for discussions on DIPs, that's pretty much all you're going to find on that. Andrei's talk is the most up-to-date information that we have about this particular DIP. The preliminary implementation is the most practicable up to date info there: https://github.com/dlang/dmd/pull/9817
Re: is there a way to embed python 3.7 code in D program?
On Sunday, 12 May 2019 at 20:06:34 UTC, torea wrote: Hi, I'd like to use D for the "brain" of a small robot (Anki vector) whose API is coded in Python 3.6+. I had a look at Pyd but it's limited to python 2.7... It isn't. You may needs to set a dub version, or it may pick up the 2.7 as the default but it definitely works (I'm travelling ATM, can't check).
Re: Compiler/Phobos/Types problem — panic level due to timing.
On Sunday, 5 May 2019 at 19:18:47 UTC, lithium iodate wrote: On Sunday, 5 May 2019 at 18:53:08 UTC, Russel Winder wrote: Hi, I had merrily asumed I could implement nth Fibonacci number with: takeOne(drop(recurrence!((a, n) => a[n-1] + a[n-2])(zero, one), n)).front where zero and one are of type BigInt, and n is of type size_t. However both dmd and ldc2 complain saying: […] I am now at the WTF stage – how can I show this example on Thursday in my DevoxxUK presentation? I am close to giving up and imbibing of too much Pernod. `recurrence` takes the `CommonType` of the initial values and declares its internal state as an array of this type, however when at least one of the values is const or immutable, the `CommonType` is const too, or even immutable in the case when all values are immutable. The state being const/immutable means that the following step, initializing it, can't work, since, well, the array cannot be modified (hence the errors). I'd say this can be considered to be a bug with `recurrence`. You can solve this issue by constructing and passing mutable versions of `one` and `zero` to `recurrence`. Yep https://run.dlang.io/is/XsLrRz works for me, https://run.dlang.io/is/KxY0e9 doesn't.
Re: I had a bad time with slice-in-struct array operation forwarding/mimicing. What's the best way to do it?
On Saturday, 4 May 2019 at 15:18:58 UTC, Random D user wrote: I wanted to make a 2D array like structure and support D slice like operations, but I had surprisingly bad experience. I quickly copy pasted the example from the docs: https://dlang.org/spec/operatoroverloading.html#array-ops It's something like this: struct Array2D(E) { E[] impl; int stride; int width, height; this(int width, int height, E[] initialData = []) ref E opIndex(int i, int j) Array2D opIndex(int[2] r1, int[2] r2) auto opIndex(int[2] r1, int j) auto opIndex(int i, int[2] r2) int[2] opSlice(size_t dim)(int start, int end) @property int opDollar(size_t dim : 0)() @property int opDollar(size_t dim : 1)() } So basic indexing works fine: Array2D!int foo(4, 4); foo[0, 1] = foo[2, 3]; But array copy and setting/clearing doesn't: int[] bar = [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ]; foo[] = bar[]; And I get this very cryptic message: (6): Error: template `example.Array2D!int.Array2D.opSlice` cannot deduce function from argument types `!()()`, candidates are: (51):`example.Array2D!int.Array2D.opSlice(ulong dim)(int start, int end) if (dim >= 0 && (dim < 2))` 1. WTF `!()()` and I haven't even called anything with opSlice i.e. `a .. b`? Anyway, it doesn't overload [] with opIndex(), so fine, I add that. T[] opIndex() { return impl; } Now I get: foo[] = bar[]; // or foo[] = bar; Error: `foo[]` is not an lvalue and cannot be modified Array copying docs say: When the slice operator appears as the left-hand side of an assignment expression, it means that the contents of the array are the target of the assignment rather than a reference to the array. Array copying happens when the left-hand side is a slice, and the right-hand side is an array of or pointer to the same type. 2.WTF I do have slice operator left of assignment. So I guess [] is just wonky named getter (and not an operator) for a slice object and that receives the = so it's trying to overwrite/set the slice object itself. Next I added a ref to the E[] opIndex(): ref E[] opIndex() { return impl; } Now foo[] = bar[] works as expected, but then I tried foo[] = 0; and that fails: Error: cannot implicitly convert expression `0` of type `int` to `int[]` 3. WTF. Didn't I just get reference directly to the slice and array copy works, why doesn't array setting? The ugly foo[][] = 0 does work, but it's so ugly/confusing that I'd rather just use a normal function. So I added: ref E[] opIndexAssign(E value) { impl[] = value; return impl; } And now foo[] = 0; works, but foo[0, 1] = foo[2, 3] doesn't. I get: Error: function `example.Array2D!int.Array2D.opIndexAssign(int f)` is not callable using argument types `(int, int, int)` expected 1 argument(s), not 3 4. WTF. So basically adding opIndexAssign(E value) disabled ref E opIndex(int i, int j). Shouldn't it consider both? I'm surprised how convoluted this is. Is this really the way it's supposed to work or is there a bug or something? So what is the best/clear/concise/D way to do these for a custom type? I was planning for: foo[] = bar; // Full copy foo[] = 0; // Full clear foo[0 .. 5, 1] = bar[ 0 .. 5]; // Row/Col copy foo[1, 0 .. 5] = 0; // Row/Col clear foo[0 .. 5, 2 .. 4] = bar[ 1 .. 6, 0 .. 2 ]; // Box copy foo[0 .. 5, 2 .. 4] = 0; // Box clear Anyway, this is not a huge deal breaker for me, I was just surprised and felt like I'm missing something. I suppose I can manually define every case one by one and not return/use any references etc. or use alias this to forward to impl[] (which I don't want to do since I don't want to change .length for example) or just use normal functions and be done with it. And it's not actually just a regular array I'm making, so that's why it will be mostly custom code, except the very basics. The de facto multi dimensional array type in D is mir's ndslice https://github.com/libmir/mir-algorithm/blob/master/source/mir/ndslice/slice.d#L479
Call delegate from C++
How do you pass a delegate to a c++ function to be called by it? The function to pass the delegate to is: extern (C++) int fakeEntrypoint( extern(C++) void function(void* /*delegate's context*/) func, void* /*delegate's context*/ arg); What I want is: int entrypoint(scope void delegate() func) { return fakeEntrypoint( // for some reason func.funcptr is void function() cast(void function(void*))func.funcptr, func.ptr); } but that fails with cannot pass argument cast(void function(void*))func.funcptr of type void function(void*) to parameter extern (C++) void function(void*) func
Re: Error: template instance `Reflect!(type)` cannot use local `type` as parameter to non-global template `Reflect(Ts...)()`
On Sunday, 7 April 2019 at 05:24:38 UTC, Alex wrote: Error: template instance `Reflect!(type)` cannot use local `type` as parameter to non-global template `Reflect(Ts...)()` mixin(`import `~moduleName!(T)~`;`); mixin(`alias X = T.`~name~`;`); super.Reflect!(X); I realize X is local but I'm trying to figure out why it can't be passed to a "non-global" template. See https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/ TL;DR At global scope alias Identity(alias X) = X; then where the error is issued from use `Identity!(type)` instead of type.
Re: Problems instantiating template class
On Saturday, 6 April 2019 at 17:30:45 UTC, Mek101 wrote: I'm rewriting from C# a small library of mine to practice with D. I have a class: class WeightedRandom(T, W = float) if(isNumeric!W) { // Fields private W[T] _pairs; // The total sum of all the weights; private W _probabilities; /// Code... } And when I try to instantiate an object in a unittest unittest { auto wrnd = new WeightedRandom!char(); wrnd.normalizeAt(120.55); } Compilation fails with the following error: source/utils/weightedRandom.d(25,18): Error: cannot pass type char as a function argument source/utils/weightedRandom.d(90,18): Error: template instance `utils.weightedrandom.WeightedRandom!(char, float)` error instantiating /usr/bin/dmd failed with exit code 1. Same exact error with: WeightedRandom!(char)(); WeightedRandom!(string, float)(); It seems like dmd thinks I'm calling a function while I'm trying to instantiate the object. Hmm, import std.traits; class WeightedRandom(T, W = float) if(isNumeric!W) { // Fields private W[T] _pairs; // The total sum of all the weights; private W _probabilities; /// Code... } void main() { auto wrnd = new WeightedRandom!char(); } works for me: https://run.dlang.io/is/CjSubj
Re: template with enum parameter doesn't compile
On Friday, 5 April 2019 at 14:47:42 UTC, Sjoerd Nijboer wrote: So the following code doesn't compile for some reason, and I can't figure out why. enum MyEnum { A, B, C } class MyClass(MyEnum myEnum) { /*...*/ } int main() { MyClass!MyEnum.A a; } The error: Error: template instance `MyClass!(MyEnum)` does not match template declaration `MyClass(MyEnum myEnum)` pops up, no matter what I do. You wrote: MyClass!MyEnum.A a; Which is equivalent to MyClass!(MyEnum).A a; What you want is MyClass!(MyEnum.A) a;
Re: Request some GtkD Assistance
On Wednesday, 27 March 2019 at 06:55:53 UTC, Andrew Edwards wrote: Good day all, I've installed Gtk+ and GtkD on my MacBookPro which is running macOS Mojave but am having some issues linking to and using it. Any assistance to resolve this is appreciated. Steps taken: 1. Install Gtk+ brew install gtk+ 2. Build and install GtkD-3.8.5 unzip GtkD-3.8.5.zip copy gtkd folder to dmd/osx/src/ make copy libgtkd-3.a to dmd/osx/lib/ 3. Update dmd.conf add -I%@P%/../../src/gtkd to DFLAGS Problems encountered: 1. Unable to find the lib (dmd-2.085.0)BMP:model edwarac$ dmd -de -w -Llibgtkd-3.a nufsaid ld: file not found: libgtkd-3.a clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: linker exited with status 1 Not sure why I'm receiving this first error since the file is stored alongside the libphobos2.a which the linker doesn't have any issues locating. If copy the file to the local directory, linking completes without any further errors. 2. Unable to find libgtkd-3.dylib (dmd-2.085.0)Andrews-MBP:model edwarac$ ./nufsaid object.Exception@generated/gtkd/gtkd/Loader.d(125): Library load failed (libgdk-3.0.dylib): dlopen(libgdk-3.0.dylib, 258): image not found Not sure what's going on here at all. This file was not created when I built GtkD. Where do I find it, or how do I create it? --Andrew dmd -de -w -Llibgtkd-3.a nufsaid try dmd -de -w -lgtkd-3 nufsaid or dmd -de -w -L/path/to/lib nufsaid dlopen(libgdk-3.0.dylib, 258): image not found it that a typo? gdk not gtk? Regardless gtkD is bindings to gtk which are separate, make sure you have gtk installed and in your path.
Re: Why a template with Nullable does not compile?
On Tuesday, 12 March 2019 at 05:14:21 UTC, Victor Porton wrote: Why does this not compile? import std.typecons; template FieldInfo(T, Nullable!T default_) { } /usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(2570,17): Error: `alias T = T;` cannot alias itself, use a qualified name to create an overload set /usr/lib/ldc/x86_64-linux-gnu/include/d/std/typecons.d(3291,17): Error: `alias T = T;` cannot alias itself, use a qualified name to create an overload set It seems to be getting confused between the two types of Nullable, namely: Nullable(T), and Nullable(T, T defaultVal) template FieldInfo(T) { template FieldInfo(Nullable!(T) default_) { enum FieldInfo = 0; } } seems to work, but I can't seem to instantiate one of it.
Re: Phobos in BetterC
On Saturday, 9 March 2019 at 12:42:34 UTC, Sebastiaan Koppe wrote: There might also be the option to use @nogc exceptions (dip 1008), but I am not sure. That won't work as the implementation on DIP1008 cheats the type system but doesn't actually work, i.e. the exceptions are still CG allocated.
Re: Phobos in BetterC
On Friday, 8 March 2019 at 09:24:25 UTC, Vasyl Teliman wrote: I've tried to use Mallocator in BetterC but it seems it's not available there: https://run.dlang.io/is/pp3HDq This produces a linker error. I'm wondering why Mallocator is not available in this mode (it would be intuitive to assume that it's working). Also I would like to know what parts of Phobos are available there (e.g. std.traits, std.typecons...). Thanks in advance. This is really a linker problem, because -betterC doesn't link druntime, and pbobos links druntime. to get around this pass -i=std.experimental.allocator to dmd along with the rest of you usual arguments.
Re: dcompute - Error: unrecognized `pragma(LDC_intrinsic)
On Thursday, 28 February 2019 at 09:58:35 UTC, Michelle Long wrote: I've included it in Visual D as di and it seems not to add it to the include line... Is it in any way possible that it being an di file would allow that? Seems that it is an LDC issue though but LDC has some usage of it I believe and it works fine. Could it be a LDC version? Or do I need to include something to make it work? Seems like it would be part of the compiler itself. (I'm on cold and flu meds so apologies if this doesn't make sense) It should be on the atuoimport path of LDC as that file had others (https://github.com/ldc-developers/druntime/tree/ldc/src/ldc) are part of LDC's druntime which should be imported by ldc's .conf file, it won't show up on the command line unless you do something (... brain not working properly...). Irrespective of all that, the error comes from https://github.com/ldc-developers/ldc/blob/f5a5324773484447953746725ea455d2827e6004/dmd/dsymbolsem.d#L1862 which should never happen because this branch should be taken https://github.com/ldc-developers/ldc/blob/f5a5324773484447953746725ea455d2827e6004/dmd/dsymbolsem.d#L1807 because that pragma is explicitly checked for here https://github.com/ldc-developers/ldc/blob/187d8198e63564c633f22f2ef4db2a31a8a600ce/gen/pragma.cpp#L110
Re: how to pass a malloc'd C string over to be managed by the GC
On Thursday, 28 February 2019 at 03:33:25 UTC, Sam Johnson wrote: ``` string snappyCompress(const string plaintext) { import deimos.snappy.snappy : snappy_compress, snappy_max_compressed_length, SNAPPY_OK; import core.stdc.stdlib : malloc, free; import std.string : fromStringz, toStringz; char *input = cast(char *) toStringz(plaintext); size_t output_length = snappy_max_compressed_length(plaintext.length); char *output = cast(char *) malloc(output_length); if(snappy_compress(input, plaintext.length, output, _length) == SNAPPY_OK) { string ret = (cast(string) fromStringz(output)).clone(); // < do something magical here return ret; } assert(0); } ``` How can I get the GC to automatically garbage collect the `output` malloc call by tracking the returned `ret` reference? I'm surprised that GC.addRoot(output) actually helped you here, GC.addRoot is for when the thing you are adding may hold pointers to GC allocated stuff and you don't want non-GC allocated references to dangle when the GC does a collection pass. If you want the GC to handle it just use new: char[] output = new char[output_length]; ... return assumeUnique(output); Or is this already managed by the gc because I cast to a `string`? No, string is just an alias for immutable(char)[], which is just struct { size_t length; immutable(char)* ptr; } it can refer to any span of memory, it has no concept of ownership.
Re: dcompute - Error: unrecognized `pragma(LDC_intrinsic)
On Wednesday, 27 February 2019 at 22:56:14 UTC, Michelle Long wrote: Trying to get dcompute to work... after a bunch of issues dealing with all the crap this is what I can't get past: Error: unrecognized `pragma(LDC_intrinsic) This is actually from the ldc.intrinsics file, which I had to rename from .di to d so it would be included in by VisualD. I upgraded to latest LDC just before LDC - the LLVM D compiler (1.14.0git-1bbda74): based on DMD v2.084.1 and LLVM 7.0.1 pragma(LDC_intrinsic, "llvm.returnaddress") void* llvm_returnaddress(uint level); ..\..\..\..\D\LDC\import\ldc\intrinsics.d(85): Error: unrecognized `pragma(LDC_intrinsic)` I've got no idea why that is the case, although I note that you shouldn't need to change intrinsics.di to intrinsics.d, as a .di it only needs to be on the include path which should already be the case for LDC.
Re: Template recursion exceeded
On Wednesday, 27 February 2019 at 05:45:19 UTC, Michelle Long wrote: Basically void foo(int k = 20)() { static if (k <= 0 || k >= 100) return; foo!(k-1)(); } Error Error: template instance `foo!-280` recursive expansion Yep, that return is a dynamic return, not a static one. static if (k <= 0 || k >= 100) {} else: foo!(k-1)(); will work.
Re: How to break from parallel foreach?
On Tuesday, 26 February 2019 at 19:58:24 UTC, Andrey wrote: Hello, How to break from parallel foreach? More general question - how to control such loop? A basic way would be to use a flag: shared stopWork=false; foreach (wordBag; wordBags.parallel) { if (!stopWork) { // do work if (wordBag.canFind("myword")) stopWork=true } } I'd say it's probably not an elegant solution to "break" from parallel forloops, but that's up to you to decide. Jordan
Re: DMD2 vs LDC2 inliner
On Monday, 25 February 2019 at 04:08:38 UTC, Jonathan M Davis wrote: One issue that's commonly brought up about dmd's inliner is that it's in the front-end, which apparently is a poor way to do inlining. One side effect of that though would be that unless the ldc folks go to extra effort to disable the front-end's inliner We do. , ldc has that inliner - and then it's inlining using llvm. So, given that, it's practically guaranteed to do a better job. It does anyway ;)
Re: DMD2 vs LDC2 inliner
On Monday, 25 February 2019 at 02:49:36 UTC, James Blachly wrote: Any ideas why DMD2 cannot inline this, but LDC2 has no problem doing so -- or suggestions for what I can do to make DMD2 inline it? Alternatively, I could version(DigitalMars) and version(LDC), but AFAICT this requires me to duplicate the entire template, because I cannot figure out how to make the version() directive apply only to the pragma. Template instantiation is with a simple struct having integer members start and end. Thanks in advance for tips. --- pragma(inline, true) bool overlaps(IntervalType1, IntervalType2)(IntervalType1 int1, IntervalType2 int2) Leaving aside the issue of why DMD can't handle this, the entire reason pragma(inline, bool) takes a bool is for it to be (potentially) predicated. In this case you want: version(DigitalMars) private enum inline_overlaps = false; else // assuming GDC is good private enum inline_overlaps = true; pragma(inline, inline_overlaps) bool overlaps(IntervalType1, IntervalType2)(IntervalType1 int1, IntervalType2 int2) { return ...; }
Re: Compile Time Fun Time
On Monday, 25 February 2019 at 06:51:20 UTC, Yevano wrote: I am writing a domain specific language of sorts in D for the lambda calculus. One of my requirements is that I should be able to generate expressions like this: new Abstraction(v1, M) like this: L!(x => M) It is common to want to write things like L!(x => L!(y => M)) but it is much nicer to write that like L!((x, y) => M) So, I have created a templated function for this. Abstraction L(alias f)() { static if(__traits(compiles, f(null))) { auto v1 = new Variable; return new Abstraction(v1, f(v1)); } else static if(__traits(compiles, f(null, null))) { auto v1 = new Variable; auto v2 = new Variable; return new Abstraction(v1, new Abstraction(v2, f(v1, v2))); } else static if(__traits(compiles, f(null, null, null))) { auto v1 = new Variable; auto v2 = new Variable; auto v3 = new Variable; return new Abstraction(v1, new Abstraction(v2, new Abstraction(v3, f(v1, v2, v3; } } This only works for at most 3 parameter delegates. If I want to add more, I have to linearly add more static ifs in the obvious way. However, I believe I can make this function scalable using string mixins and other magic. Any insight into this is much appreciated. import std.traits; Abstraction L(alias f)() { alias Args = Parameters!f; Args v; foreach(i; 0 .. v.length) v[i] = new Variable; auto _f = f(v); auto abstraction = new Abstraction(v[$-1],_f); foreach_reverse(e; v[ 0 .. $-2]) abstraction = new Abstraction( e, abstraction); return abstraction; }
Re: How can I walk the list in a RegexMatch backwards?
On Sunday, 3 February 2019 at 18:07:13 UTC, Chris Bare wrote: auto matches = matchAll(str, searchRegex); foreach (m; matches) // this walks the list forward I tried: foreach_reverse (m; matches) foreach (m; reverse (matches)) foreach (m; retro (matches)) and they all failed to compile. I also tried to index matches (matches[i]) but that does not work either. matchAll is a forward range, whereas retro requires a bi-directional range. So using the array function should work: foreach (m; matches.array.retro) Jordan
Re: Can LDC compile to supported legacy LLVM versions?
On Monday, 28 January 2019 at 11:37:56 UTC, Dukc wrote: I have recenty updated my LDC to the most recent version (1.14). The problem is that it compiles to LLVM code version 7.0.1, but I need it to compile to LLVM 6.x.x or LLVM 5.x.x. The last release note said that LLVM versions from 3.something.something are supported, but does this mean only linking to them, or also compiling to them? If it can be done, how? Thanks. Do you mean bitcode, LLVM IR or something different? The LDC built against a given version of LLVM can link to bitcode/compile LLMV IR, of that version. Lowest LLVM it can be compiled against is 3.9. LDC's releases are compiled against 7.0.1, but that doesn't stop you downloading a release of the desired LLVM version and compiling LDC against that. All you need is a semi-recent CMake. Just git clone from our github and run cmake, you'll need to provide the location of the llvm-config binary as LLVM_CONFIG but thats it.
Re: How to use core.atomic.cas with (function) pointers?
On Tuesday, 22 January 2019 at 14:13:23 UTC, Johan Engelen wrote: The following code compiles: ``` alias T = shared(int)*; shared T a; shared T b; shared T c; void foo() { import core.atomic: cas; cas(, b, c); } ``` The type of T has to be a pointer to a shared int (you get a template match error for `cas` if `T = int*`), which is annoying but I kind-of understand. However, change b to null (`cas(, null, c);`) and things no longer work: "Error: template `core.atomic.cas` cannot deduce function from argument types" I have not succeeded to make things work with function pointers (neither with nor without `null` as second argument). What am I doing wrong if `alias T = void function();` ? Thanks, Johan You need to cast stuff (as seems to be the case with everything to do with shared, at least until/if Manu's proposal goes through): alias T = void function(); alias S = shared(size_t*); shared T a; shared T b; shared T c; void foo() { import core.atomic: cas; cas(cast(S*), cast(S)b, cast(S)c); }
Re: Deprecation: foreach: loop index implicitly converted from size_t to int
On Friday, 18 January 2019 at 12:27:17 UTC, Michael wrote: Hello all, I am getting this deprecation warning when compiling using DMD64 D Compiler v2.084.0 on Linux. I'm a little unsure what the problem is, however, because the code producing these warnings tends to be of the form: foreach (int i, ref prop; props) This, to be, looks like quite the explicit conversion, no? Does it mean I now have to use to!int(i) to convert the type of i in a foreach now? Thanks, Michael. foreach (int i, ref prop; props) All you need to do is foreach (i, ref prop; props) The reason for the deprecation is that if your array props is > 2GB int can't span the range of indices necessary because it will overflow.
Re: Understanding SIGSEGV issues
On Wednesday, 9 January 2019 at 16:48:47 UTC, Russel Winder wrote: It really is totally weird. My new Rust binding to libdvbv5 and associated version of the same application works fine. So libdvbv5 itself is not the cuprit. This has to mean it is something about the D compilers that has changed the way the D binding to libdvbv5 behaves. Hmm, if you think the binding could be the problem you could try using app as an alternative, see if it makes any difference.
Re: Understanding SIGSEGV issues
On Tuesday, 8 January 2019 at 10:23:30 UTC, Russel Winder wrote: Actually that is not a worry since the TransmitterData instance is only needed to call the scan function which creates a ChannelsData instance that holds no references to the TransmitterData instance. It turns out that whilst the code used to run, and now doesn't, all the things we have been talking of are nothing to do with the core problem. It turns out that the function call to initialise the File_Ptr object is returning a valid object with invalid data. Thus the unknown change is likely in the libdvbv5 library either due to the C API doing different things or the adapter created using DStep doing the wrong thing. Ahh. Good that you've found that, I can't help you much more with that then. The compiler generated default opEquals will do basically the same thing. Ditto for the other types. You usually want to take a const ref for opEquals since there is no point copying it. I deleted them, added a test or three (should have done this ages ago) and the tests pass. So teh generated methods do the needful. Thanks for that "heads up". No problems, less code is good code. Very true. For now I have forbidden copying, which is wrong for this sort of thing. If D had the equivalent of C++ std::shared_ptr or Rust std::rc::Rc or std::rc::Arc, that would be the way forward But I guess having explicit reference counting is not too hard. I believe Andrei and Razvan are working on that, part of that being the Copy Constructor DIP. Hopefully it will arrive soon. You seem to like const, good! You don't need to take `const int`s as parameters, you're getting a copy anyway. You have a bunch of redundant casts as well. I am a person who always makes Java variables final, and loves that Rust variables are immutable by default! Indeed, less to think about is always nice. Good luck figuring out why your data is dud. Nic
Re: Co-developing application and library
On Saturday, 5 January 2019 at 13:01:24 UTC, Russel Winder wrote: Dub seems to have the inbuilt assumption that libraries are dependencies that do not change except via a formal release when you developing an application. Clearly there is the workflow where you want to amend the library but not release as a part of developing an application. Does Dub have a way of doing this, I haven't been able to infer one to date. But I am a beginner at Dub. you can depend on ~master as a version, I'm not sure if you have to tell it to refresh what is has.
Re: Understanding SIGSEGV issues
On Saturday, 5 January 2019 at 12:14:15 UTC, Russel Winder wrote: Indeed. I should do that to see if I can reproduce the problem to submit a proper bug report. File_Ptr is wrapping a dvb_file * from libdvbv5 to try and make things a bit for D and to ensure RAII. libdvbv5 is a C API with classic C approach to handling objects and data structures. My DStep/with manual binding is at https://github.com/russel/libdvbv5_d and the application using it (which is causing the problems) is at https://github.com/russel/DVBTune Your problem possibly (probably?) stems from auto channelsData = TransmitterData(args[1]).scan(frontendId); The temporary TransmitterData(args[1]) is, well, temporary and its destructor runs after that expression is done. As the returned object from scan references data from the temporary, you have a stale pointer. I have a feeling that I am really not doing things in a D idiomatic way. Some driveby style comments then: bool opEquals()(const FrontendId other) const { if (this is other) return true; if (other is null) return false; return this.adapter_number == other.adapter_number && this.frontend_number == other.frontend_number; } The compiler generated default opEquals will do basically the same thing. Ditto for the other types. You usually want to take a const ref for opEquals since there is no point copying it. if (other is null) I'm surprised the compiler doesn't warn or error on that as the only way that could make sense would be if it had an alias this to a pointer type. You should consider reference counting your pointer wrapper types, FrontendParameters_Ptr/File_Ptr/ScanHandler_Ptr You seem to like const, good! You don't need to take `const int`s as parameters, you're getting a copy anyway. You have a bunch of redundant casts as well. I'll have another looks tomorrow when I'm a bit more awake.
Re: Understanding SIGSEGV issues
On Saturday, 5 January 2019 at 10:52:48 UTC, Russel Winder wrote: I found the problem and then two minutes later read your email and bingo we have found the problem. Well done. Previously I had used File_Ptr* and on this occasion I was using File_Ptr and there was no copy constructor because I have @disable this(this). Except that clearly copying a value is not copying a value in this case. Clearly this situation is what is causing the destructor to be called on an unconstructed value. But I have no idea why. Could you post a minimised example? Its a bit hard to guess without one. The question now, of course, is should I have been using File_Ptr instead of File_Ptr* in the first place. I am beginning to think I should have been. More thinking needed. From the name, File_Ptr sounds like it is wrapping a reference to a resource. So compare with C's FILE/ D's File which is a reference counted wrapper of a FILE*. Would you ever use a File* (or a FILE**)? Probably not, I never have.
Re: Understanding SIGSEGV issues
On Saturday, 5 January 2019 at 07:34:17 UTC, Russel Winder wrote: TransmitterData has a destructor defined but with no code in it. This used to work fine – but I cannot be certain which version of LDC that was. The problem does seem to be in the construction of the TransmitterData object because a destructor is being called on the File_Ptr field as part of the transmitterData constructor. As you can see from the stack trace #3, the File_Ptr is null. The solution to this is to either ensure it is initialised in the constructor of TransmitterData, or account for it possibly being null by defining a destructor for TransmitterData. For some reason it seems File_Ptr.~this() is being called before File_Ptr.this() in the TransmitterData.this(). This is totally weird. Having added some writeln statements: (gdb) bt #0 0x555932e0 in dvb_file_free (dvb_file=0x0) at dvb_file.d:276 #1 0x55592fbc in types.File_Ptr.~this() (this=...) at types.d:83 #2 0x5558cdf6 in _D3std6format__T14formattedWriteTSQBg5stdio4File17LockingTextWriterTaTS5types8File_PtrZQCtFKQChxAaQBcZk (w=..., fmt=..., _param_2=...) at /usr/lib/ldc/x86_64-linux-gnu/include/d/std/format.d:472 Maybe it is a problem with copying a File_Ptr (e.g. missing a increase of the reference count)? Like, `auto a = File_Ptr(); { auto b = a; }` and b calls the destructor on scope exit. That would be consistent with having problems copying to object to pass to writeln.
Re: Understanding SIGSEGV issues
On Thursday, 3 January 2019 at 08:35:17 UTC, Russel Winder wrote: Sorry about that, fairly obvious that the backtrace is needed in hindsight. :- ) #0 __GI___libc_free (mem=0xa) at malloc.c:3093 #1 0x5558f174 in dvb_file_free (dvb_file=0x555a1320) at dvb_file.d:282 #2 0x5558edcc in types.File_Ptr.~this() (this=...) at types.d:83 #3 0x55574809 in channels.TransmitterData.__fieldDtor() (this=variable: Cannot access memory at address 0xa>) at channels.d:144 #4 0x5556aeda in channels.TransmitterData.__aggrDtor() (this=...) at channels.d:144 #5 0x5556ab53 in D main (args=...) at main.d:33 Which indicates that the destructor is being called before the instance has been constructed. Which is a real WTF. Not quite, this occurs as a TransmitterData object goes out of scope at the end of main(stick a fflush'ed printf there to see): TransmitterData is a struct that has no destructor defined but has a field of type File_Ptr that does. The compiler generates a destructor, __aggrDtor, which calls the fields that have destructors, __fieldDtor (e.g. the File_Ptr) which in turn calls its destructor, File_Ptr.~this(). As you can see from the stack trace #3, the File_Ptr is null. The solution to this is to either ensure it is initialised in the constructor of TransmitterData, or account for it possibly being null by defining a destructor for TransmitterData.
Re: Understanding SIGSEGV issues
On Thursday, 3 January 2019 at 06:25:46 UTC, Russel Winder wrote: So I have a D program that used to work. I come back to it, recompile it, and: [...] __GI___libc_free (mem=0xa) at malloc.c:3093 You've tried to free a pointer that, while not null, was derived from a pointer that was, i.e. an offset to a field of a struct. A backtrace would help a lot, otherwise it really is just guessing.
Re: Mixin operator 'if' directly
On Saturday, 22 December 2018 at 03:44:09 UTC, Timoses wrote: On Wednesday, 19 December 2018 at 15:40:50 UTC, Neia Neutuladh wrote: On Wed, 19 Dec 2018 15:12:14 +, bauss wrote: Or while instantiating it: mixin template foo() { int _ignoreme() { if (readln.strip == "abort") throw new AbortException; return 1; } int _alsoIgnoreMe = _ignoreme(); } void main() { mixin foo; } Awesome hack! Being a hack, it would be even nicer if it worked ouf of the box: mixin template foo(bool b) { int _impl() { writeln(b); return int.init; } int _ipml2 = _impl(); } vs mixin template foo(bool b) { writeln(b); } https://issues.dlang.org/show_bug.cgi?id=19506
Re: 2D-all?
On Friday, 14 December 2018 at 12:43:40 UTC, berni wrote: I've got a lot of code with two-dimensional arrays, where I use stuff like: assert(matrix.all!(a=>a.all!(b=>b>=0))); Does anyone know if there is a 2D-version of all so I can write something like: assert(matrix.all2D!(a=>a>=0)); auto all2d(alias f)(ref Matrix m) { return m.all!(a => a.all!(b => f(b))); }
Re: File .. byLine
On Monday, 3 December 2018 at 06:09:21 UTC, Joel wrote: I can't seem to get this to work! ``` foreach(line; File("help.txt").byLine) { writeln(line.stripLeft); ``` With the code above, I get this compile error: source/app.d(360,36): Error: template std.algorithm.mutation.stripLeft cannot deduce function from argument types !()(char[]), candidates are: /usr/local/opt/dmd/include/dlang/dmd/std/algorithm/mutation.d(2602,7): std.algorithm.mutation.stripLeft(Range, E)(Range range, E element) if (isInputRange!Range && is(typeof(range.front == element) : bool)) /usr/local/opt/dmd/include/dlang/dmd/std/algorithm/mutation.d(2610,7): std.algorithm.mutation.stripLeft(alias pred, Range)(Range range) if (isInputRange!Range && is(typeof(pred(range.front)) : bool)) I just want to use each 'line' variable as a string?! I've tried 'byLineCopy', and 'line.to!string'. I've looked at documentation. https://run.dlang.io/is/h0ArAB works for me. If you want it as a string not char[] then byLineCopy should work, if not just `.idup` `line`.
Re: D & C++ class question
On Wednesday, 28 November 2018 at 13:13:40 UTC, bauss wrote: Well unfortunately I cannot control the C++ side of things, but I assume that it'll work properly with extern(C++) so I guess I will just go ahead and try and see if everything works out. I have access to the C++ source so at the very least I can see how it's used there and if it's possible in the way I want it to. I don't hope I have to have a separate C++ "bridge" to make it work. Its mostly a magling problem, if the C++ API uses class& that you have to interface with then you have a problem that would require a shim.
Re: D & C++ class question
On Wednesday, 28 November 2018 at 07:22:46 UTC, bauss wrote: If I have a class from D. How would you use that class in C++? Like what's the correct approach to this. Would it work just by doing "extern(C++)" or will that only work for D to use C++ classes? If you have foo.d class Foo { int aMember; void aMethod() { ... }; final aFinalMethod() { ... }; } to expose that to C++ you need to add extern(C++) too Foo and use it in C++ as a Foo* foo.h class Foo { int aMember; virtual void aMethod(); void aFinalMethod(); }; If you can't/don't want to do that you can always pass it around in C++ as an opaque pointer with functions that call the member functions and get/set the variables (i.e. the pimpl strategy).
Re: memoize & __traits(compiles...)
On Friday, 23 November 2018 at 10:34:11 UTC, John Chapman wrote: I'm doing a fair amount of repeatedly checking if a function compiles with __traits(compiles...), executing the function if so, erroring out if not, like this: static if (__traits(compiles, generateFunc1())) { return generateFunc1(); } static if (__traits(compiles, generateFunc2())) { return generateFunc2(); } else static assert(false); But it seems inefficient to have to evaluate those functions twice, so I'd like to optimise this so if __traits(compiles...) succeeds, the result is cached and then used when the function is actually called. I wondered if using std.functional.memoize would help? No, std.functional.memoize uses a hashtable to cache the runtime results of calls to expensive functions. assuming that the example is not oversimplified and generateFunc1 and generateFunc2 are functions, the compiler doesn't do extra semantic analysis so the validity of the functions is effectively cached. If they are templates (with parameters) then the compiler will automatically memoize them (it too keeps a hashtable of template instances). When in doubt, profile! https://blog.thecybershadow.net/2018/02/07/dmdprof/