Re: dub creates unrunnable binary in "build" dir
On Thursday, 23 February 2023 at 12:28:35 UTC, Richard (Rikki) Andrew Cattermole wrote: On 24/02/2023 1:10 AM, tastyminer...@gmail.com wrote: The symbol exists if I understood correctly. -imports shows you the imports of the binary, not the exports. So no it does not exist (probably came from libc). https://keith.github.io/xcode-man-pages/dyld_info.1.html My guess is something changed some place else. Such as XCode or tcl. Yes, you're correct. I managed to resolve it. So "_memcmp" was missing and it is part of the libc library. I remember that MacPorts asked me to reclaim some space by removing the deps of inactive ports. When agreed, it removed almost complete port library including many libs used for compilation of other ports. I managed to restore most of them but looks like glibc2 was still missing. After installing it and libgcc with deps, the project compiled without issues.
dub creates unrunnable binary in "build" dir
I have been using dub to build one project of mine and its been 2021 the last time I tried to rebuild it... I made some code changes today and wanted to run unittests. Here is what I got after running `dub build -b tests`: ``` Starting Performing "tests" build using /Users/pavels/.local/share/ldc2-1.31.0-osx-arm64/bin/ldc2 for aarch64, arm_hardfloat. Building dxml 0.4.3: building configuration [library] Building x11 1.0.21: building configuration [tcltk-import] Building tcltk 8.6.5: building configuration [library] Building tkd 1.1.14: building configuration [library] Building toml 1.0.0-rc.3: building configuration [library] Building doc_sender_app ~master: building configuration [application] Linking doc_sender_app Copying files for doc_sender_app... ``` Build is completed, now let's run it. `cd build && ./doc_sender_app` ``` dyld[4032]: Symbol not found: _memcmp Referenced from: <2E0B0A60-5997-399C-8361-B70D44650A19> /Users/pavels/dev/build/doc_sender_app Expected in: /opt/local/lib/libtcl8.6.dylib fish: Job 1, './doc_sender_app' terminated by signal SIGABRT (Abort) ``` Huh? Checking `dyld_info -imports /opt/local/lib/libtcl8.6.dylib | rg "_memcmp"` ``` 0x008F 0x002 _memcmp ``` The symbol exists if I understood correctly. Searching the internet didn't provide me with any answers :( Building with older 1.27.1 ldc/dub provided the same results. So, it means that something changed on my system after the latest mac ports update but I have no clue how to proceed tbo. Can anyone provide some more information about the error? What else should I try out? DUB version: version 1.30.0, built on Feb 11 2023 The compiler is the latest "ldc2-1.31.0-osx-arm64". The machine is Mac M1 with Ventura installed and all relevant tk and tcl libs in place.
Re: How to update Associative Array?
On Thursday, 10 February 2022 at 12:04:04 UTC, bauss wrote: On Thursday, 10 February 2022 at 10:59:17 UTC, tastyminerals wrote: [...] You can just do: aa[key] = value. If the key exist then it's updated, if it doesn't then it's added. The reason for the update function is simply in cases where you want to use the oldvalue etc. perhaps it has a timestamp that you need to keep etc. But in general you shouldn't need it. I meant a different thing though. I am looking for `mydic.update(another_dic)` analogue where `{"a": 1, "b": 2}` update `{"c": 3, "a": -1}` becomes `{"a":-1, "b": 2, "c": 3}`.
How to update Associative Array?
Not sure if the `update` method got changed but I am having trouble with understanding it now. I assumed it would work as easy as in Python:) Just do `mydic.update(dic)` or `mydic["key"].update(anotherDic)`. The docs have the following example. ``` class C{} C[string] aa; C older; C newer; aa.update("a", { newer = new C; return newer; }, (ref C c) { older = c; newer = new C; return newer; }); ``` This looks pretty scary and confusing to me tbo. Also, why is there an example with class and not simple `int[string]`? I just need to know how can I update let's say `int[string]` or nested `int[string][string]` AA. Should I also initialise and additional C classes before calling this method as in the example? Considering this is the only example in the docs I could find on how to update AA, imagine someone from Python world comes and sees this. Next thing he does, is close the page and never come back to D again :(
Re: How to use sets in D?
On Tuesday, 8 February 2022 at 21:42:06 UTC, H. S. Teoh wrote: On Tue, Feb 08, 2022 at 09:08:47PM +, tastyminerals via Digitalmars-d-learn wrote: [...] > [...] [...] [...] E is whatever key type you want to use. String, or integer ID, or whatever you want to put in your set. [...] Thank you! That's neat.
How to use sets in D?
https://forum.dlang.org/post/mailman.1072.1581112984.31109.digitalmars-d-le...@puremagic.com On Friday, 7 February 2020 at 22:03:00 UTC, H. S. Teoh wrote: On Fri, Feb 07, 2020 at 07:37:08PM +, mark via Digitalmars-d-learn wrote: [...] bool[E] works just fine. The bool does take up 1 byte, though, so if you're *really* want to optimize that away, you could do this: alias Unit = void[0]; enum unit = Unit.init; // Look, ma! A bona fide set! Unit[E] mySet; mySet[...] = unit; mySet.remove(...); ... // etc. Or you can wrap void[0][E] in a nice user-defined type that gives nice set-like syntax. But IMO, this is all overkill, and adds needless complexity. Just use bool[E] or std.container.rbtree. :-D T Can you please explain what does `bool[E]` mean? And how does the code with aliasing void[0] and then using enum even work?
Dub fails to run inside a docker container on MacBook
I am trying to create a Docker image where I can build my dub project. Here is a simple Dockerfile. ``` FROM ubuntu as build RUN apt-get update \ && apt-get install --no-install-recommends -y -q locales build-essential apt-transport-https ca-certificates dub\ && apt-get clean \ && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* WORKDIR /compiling COPY source source COPY dub.json . RUN dub build -b release ``` When I try to run `docker build .`, I get the following output: ``` [+] Building 1.0s (10/10) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 424B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/ubuntu:latest 0.6s => [internal] load build context 0.0s => => transferring context: 2.41kB 0.0s => [1/6] FROM docker.io/library/ubuntu@sha256:626ffe58f6e7566e00254b638eb7e0f3b11d4da9675088f4781a50ae288f3322 0.0s => CACHED [2/6] RUN apt-get update && apt-get install --no-install-recommends -y -q locales build-essential apt-transport-https ca-certificates dub&& apt-get clean && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 0.0s => CACHED [3/6] WORKDIR /compiling 0.0s => CACHED [4/6] COPY source source 0.0s => CACHED [5/6] COPY dub.json . 0.0s => ERROR [6/6] RUN dub build -b release 0.2s -- > [6/6] RUN dub build -b release: #10 0.208 dub: symbol lookup error: dub: undefined symbol: _D3std3net4curl4HTTP9__mixin376onSendMFNdDFAvZmZv ``` I am running this from M1 MacBook but was successfully using similar Dockerfile with dub on a Linux machine. Could it be the issue?
Re: tkd does not build anymore after 2.096
On Wednesday, 13 October 2021 at 01:55:38 UTC, russhy wrote: On Tuesday, 12 October 2021 at 18:18:45 UTC, tastyminerals wrote: On Tuesday, 12 October 2021 at 17:35:53 UTC, russhy wrote: [...] Yes, I can locally "fix" that but I would also like whoever wants to compile the app in the company also compile it for his machine :( I tried to find the email of the maintainer but so far didn't have time for search. I found this twitter: https://twitter.com/nomaddeveloper And his linkdin: https://uk.linkedin.com/in/gary-willoughby-33b48963 (Publicly available on his website: http://nomad.uk.net/pages/about.html) What you should probably do anyways is: 1- fork the project on github 2- apply the workaround for nullable Update your dub file so it picks your dependency (people forgot, but you can use git repo as dependencies, just like in go) ```json "repository":"https://github.com/your_github/tkd.git;, "dependencies": { "tkd": "~master" // or what ever version you want } ``` Thank you. I have contacted him via LinkedIn and he unarchived the repo so I could push a PR. The PR is now merged and a new tkd version `1.1.14` is available via dub. This version is compatible with the recent dmd. All good.
Re: How to check if value is null, today?
On Thursday, 14 October 2021 at 12:43:36 UTC, jfondren wrote: On Thursday, 14 October 2021 at 11:58:29 UTC, tastyminerals wrote: Here is an example code that doesn't work with the new compiler anymore: ``` if (someValue.isNull) ``` Attempting to run the above throws: ``` Error: incompatible types for `(0) : (someValue)`: `int` and `Nullable!int` ``` Do you have a complete example? Because this runs without error: ```d import std.typecons : nullable, Nullable; import std.stdio : writeln; void main() { auto a = nullable(1); auto b = Nullable!int.init; if (!a.isNull) writeln(a.get); if (b.isNull) writeln("b is null"); } ``` Steven Schveighoffer was correct, the error was caused by non explicit `someVar;` which had to be changed to `someVar.get;`.
How to check if value is null, today?
The new `DMD v2.097.2` deprecated implicit null conversions `std.typecons.Nullable!double.Nullable.get_`. The deprecation warning tell you to `Please use .get explicitly.`. Here is an example code that doesn't work with the new compiler anymore: ``` if (someValue.isNull) ``` Attempting to run the above throws: ``` Error: incompatible types for `(0) : (someValue)`: `int` and `Nullable!int` ``` I am not sure I understand what kind of `.get` overload are we supposed to use here. I tried to read the documentation but looks like it is yet to be updated. Can somebody please help me out?
Re: tkd does not build anymore after 2.096
On Tuesday, 12 October 2021 at 17:35:53 UTC, russhy wrote: Recent version for nullable removed implicit conversion, you must call .get now.. wich is a pain to update i suggest using a previous version of ``struct Nullable`` https://github.com/dlang/phobos/blob/v2.096.1/std/typecons.d create a nullable.d file in tkd project, and replace the imports to that module that'll solve this issue but that wouldn't solve the fact that the https://code.dlang.org/packages/tkd package won't build we need to contact the maintainers and suggest to update the library another solution would be to revert the nullable change that sounds like an unnecessary change that breaks lot of code/packages.. Yes, I can locally "fix" that but I would also like whoever wants to compile the app in the company also compile it for his machine :( I tried to find the email of the maintainer but so far didn't have time for search.
tkd does not build anymore after 2.096
There have been numerous deprecation warnings for nice **tkd** library: https://github.com/nomad-software/tkd and with the current ldc 1.27.1 it fails to build. ``` x11 1.0.21: building configuration "tcltk-import"... tcltk 8.6.5: building configuration "library"... tkd 1.1.13: building configuration "library"... ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/arcspecific.d(134,10): Error: incompatible types for `(0.0) : (this._startAngle)`: `double` and `Nullable!double` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(45,10): Error: incompatible types for `(0) : (this._outlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(92,10): Error: incompatible types for `(0) : (this._activeOutlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(139,10): Error: incompatible types for `(0) : (this._disabledOutlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/textspecific.d(56,10): Error: incompatible types for `(0.0) : (this._angle)`: `double` and `Nullable!double` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/textspecific.d(234,10): Error: incompatible types for `(0) : (this._maxLineLength)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/widgetspecific.d(79,10): Error: incompatible types for `(0) : (this._width)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/widgetspecific.d(127,10): Error: incompatible types for `(0) : (this._height)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/arcspecific.d(134,10): Error: incompatible types for `(0.0) : (this._startAngle)`: `double` and `Nullable!double` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(45,10): Error: incompatible types for `(0) : (this._outlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(92,10): Error: incompatible types for `(0) : (this._activeOutlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(139,10): Error: incompatible types for `(0) : (this._disabledOutlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(45,10): Error: incompatible types for `(0) : (this._outlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(92,10): Error: incompatible types for `(0) : (this._activeOutlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(139,10): Error: incompatible types for `(0) : (this._disabledOutlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(45,10): Error: incompatible types for `(0) : (this._outlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(92,10): Error: incompatible types for `(0) : (this._activeOutlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(139,10): Error: incompatible types for `(0) : (this._disabledOutlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(45,10): Error: incompatible types for `(0) : (this._outlineWidth)`: `int` and `Nullable!int` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/widget/common/canvas/outlinewidth.d(92,10): Error: incompatible types for `(0) : (this._activeOutlineWidth)`: `int` and `Nullable!int` /Users/pavels/.local/share/ldc2/bin/ldc2 failed with exit code 1. ``` Since the repo is **archived** now how can we keep the library alive? Is it up to the person whoever forks it and then keeps a working copy of it? What about the corresponding dub package page? Is there a defined process or anything about the potential handover? For example, I could keep a working fork for myself but updating it for the dub would be even better. What do you think?
Re: How to convert PDF to PNG using DMagick?
On Saturday, 25 September 2021 at 16:27:35 UTC, Tejas wrote: On Saturday, 25 September 2021 at 15:14:50 UTC, Mike Wey wrote: On 25-09-2021 15:21, tastyminerals wrote: [...] It's been awhile since i used it myself, but if imagemagick supports reading PDF's this might work: ``` Image pdf = new Image("./test.pdf") pdf.write("./test.png") ``` DMagick hasn't been updated in a while so it will probably not work with newer versions of ImageMagick. For his personal use you think there's any problem just using `std.process`? I mean: ```d rdmd --eval='import std.process; auto dmd = execute(["convert", `Screenshot from 2021-09-12 18-14-22.png` , `hello.pdf`]);' ``` I don't see why go beyond that if it's guaranteed that the user has `convert` on their machine Yes, this is an option although I want to use it as a dub dependency as part of the project.
How to convert PDF to PNG using DMagick?
When I need to convert a PDF image in console, I use ImageMagick: `convert doc.pdf doc.png` command. Today I found ImageMagick D bindings -- DMagick https://github.com/MikeWey/DMagick. I would like to script this operation using DMagick. However, I couldn't find any code samples and was not able to find anything about image conversion in official ImageMagick C API docs either (maybe I need to spend more time though). But maybe someone has code samples of how to convert PDF?
Re: How to make clang use a different tk framework version on MacOS?
On Monday, 20 September 2021 at 21:58:27 UTC, tastyminerals wrote: My tkd GUI app started getting compiled with an outdated 8.5 Tk framework version which gets shipped with command line tools: `xcode-select --install`. As a result, the UI doesn't display icons and is laggy. When you run the compiled tk app, you get a notorious warning: ``` DEPRECATION WARNING: The system version of Tk is deprecated and may be removed in a future release. Please don't rely on it. Set TK_SILENCE_DEPRECATION=1 to suppress this warning. ``` This didn't happen before but here is why it probably started to occur. I've recently been playing with uninstalling the MacPorts in favour of homebrew and in the process I had to remove tk8.6 library which was installed once by MacPorts. I wasn't aware that command line tools come with their own version of tk which is 8.5. Somehow, after moving to homebrew, I rebuilt the app and saw new warnings that never appeared before: ``` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/image/png.d(83,7): Deprecation: Function `tkd.image.image.Image.embedBase64Data!("lock.png", EmbeddedPng!"lock.png").embedBase64Data` of type `@system EmbeddedPng!"lock.png"()` is not accessible from module `png` ``` I tried coming back to MacPorts, reinstalling the command line tools reinstalling the tkd and dub dependencies but nothing worked so far. Maybe someone here has experience how to make clang go and link against the tk 8.6 version installed by MacPorts instead of 8.5. That would be of great help. If anyone bumps into this issue. The reason why it happened was because I uninstalled Mac Ports and lost `pkgconfig` package. When this package is installed on the system, dub uses it to resolve the necessary flags and links with `-L-ltk8.6 -L-ltkstub8.6 -L-ltcl8.6 -L-ltclstub8.6` instead of `8.5`. Keep in mind that in order for your tkd app to work on Mac OS, you need to install quartz type of tk: `sudo port install tk +quartz`. After that your should be able to run the app.
Re: zsh: command not found: rdmd
On Monday, 20 September 2021 at 11:04:42 UTC, leikang wrote: Enter dmd lk01.d in vscode, the terminal displays zsh: command not found: dmd, an error is reported, I don't know what the problem is, can it only be run in /Users/mac1094/dmd2/osx/bin? Keep in mind that if you have M1 machine, you cannot use dmd. Download and use `ldc2` compiler for arm64 here. https://github.com/ldc-developers/ldc/releases/download/v1.27.1/ldc2-1.27.1-osx-arm64.tar.xz
How to make clang use a different tk framework version on MacOS?
My tkd GUI app started getting compiled with an outdated 8.5 Tk framework version which gets shipped with command line tools: `xcode-select --install`. As a result, the UI doesn't display icons and is laggy. When you run the compiled tk app, you get a notorious warning: ``` DEPRECATION WARNING: The system version of Tk is deprecated and may be removed in a future release. Please don't rely on it. Set TK_SILENCE_DEPRECATION=1 to suppress this warning. ``` This didn't happen before but here is why it probably started to occur. I've recently been playing with uninstalling the MacPorts in favour of homebrew and in the process I had to remove tk8.6 library which was installed once by MacPorts. I wasn't aware that command line tools come with their own version of tk which is 8.5. Somehow, after moving to homebrew, I rebuilt the app and saw new warnings that never appeared before: ``` ../../../../.dub/packages/tkd-1.1.13/tkd/source/tkd/image/png.d(83,7): Deprecation: Function `tkd.image.image.Image.embedBase64Data!("lock.png", EmbeddedPng!"lock.png").embedBase64Data` of type `@system EmbeddedPng!"lock.png"()` is not accessible from module `png` ``` I tried coming back to MacPorts, reinstalling the command line tools reinstalling the tkd and dub dependencies but nothing worked so far. Maybe someone here has experience how to make clang go and link against the tk 8.6 version installed by MacPorts instead of 8.5. That would be of great help.
Re: How to simply parse and print the XML with dxml?
On Thursday, 9 September 2021 at 18:40:53 UTC, jfondren wrote: On Thursday, 9 September 2021 at 17:17:23 UTC, tastyminerals wrote: [...] dxml.parser is a streaming XML parser. The documentation at http://jmdavisprog.com/docs/dxml/0.4.0/dxml_parser.html has a link to more information about this at the top, behind 'StAX'. Thus, when you're mapping over `xml`, you're not getting `some text` at a time, but ``, `some text`, and `` separately, as they're parsed. The `` there is an `elementStart` which lacks a `text`, hence the error. Here's a script: ```d #! /usr/bin/env dub /++ dub.sdl: dependency "dxml" version="0.4.0" stringImportPaths "." +/ import dxml.parser; import std; enum text = import(__FILE__) .splitLines .find("__EOF__") .drop(1) .join("\n"); void main() { foreach (entity; parseXML!simpleXML(text)) { if (entity.type == EntityType.text) writeln(entity.text.strip); } } __EOF__ some text more text ``` that runs with this output: ``` some text more text ``` Ok, that makes sense now. Thank you. As for the dxml, I believe adding a small quick start example would be very beneficial for the newcomers. Especially, ppl like me who are not aware of the XML parser types and just need to extract text from an XML file.
How to simply parse and print the XML with dxml?
Maybe I missed something obvious in the docs but how can I just parse the XML and print its content? ``` import dxml.parser; auto xml = parseXML!simpleXML(layout); xml.map!(e => e.text).join.writeln; ``` throws `core.exception.AssertError@../../../.dub/packages/dxml-0.4.3/dxml/source/dxml/parser.d(1457): text cannot be called with elementStart`.
Re: DUB "Error: only one `main` allowed."
On Wednesday, 11 August 2021 at 11:44:42 UTC, Steven Schveighoffer wrote: On 8/11/21 5:31 AM, tastyminerals wrote: [...] `dub -b unittest` should work (you don't need the extra build type stuff) dub test does something funky -- it removes the *whole module* where your main function is (if you identify it, or if it's `app.d`) and then builds its own main module. Why does it do this? Legacy reasons, the runtime used to run main after running unittests, which dub didn't want to do. It also is useful on a library where there is no main function. However, dub with a build type of `unittest` just enables the unittest switch, and builds all your stuff as normal. -Steve I see. Thank you for a detailed answer! I just with this was somehow reflected in the DUB docs...
Re: DUB "Error: only one `main` allowed."
On Wednesday, 11 August 2021 at 09:31:46 UTC, tastyminerals wrote: I would like to trigger tests in a simple dub project. ``` source/my_script.d dub.json ``` Here is a dub config: ```json { "targetPath": "build", "targetType": "executable", "sourcePaths": ["source"], "name": "my_script", "buildTypes": { "release": { "buildOptions": [ "releaseMode", "inline", "optimize" ] }, "tests": { "buildOptions": [ "unittests" ] } } } ``` The project builds but when I attempt to run `dub test`, I get ``` .dub/code/my_script-test-application-unittest-posix.osx.darwin-aarch64.arm_hardfloat-ldc_v1.26.0-8A5B544D5AC6B47B68DE875ACB4BA60E_dub_test_root.d(9,12): Error: only one `main` allowed. Previously found `main` at source/my_script.d(131,6) ``` How can one run tests with dub? Hahaha, I fixed it by renaming the `my_script.d` to `app.d`. Oh boy.
DUB "Error: only one `main` allowed."
I would like to trigger tests in a simple dub project. ``` source/my_script.d dub.json ``` Here is a dub config: ```json { "targetPath": "build", "targetType": "executable", "sourcePaths": ["source"], "name": "my_script", "buildTypes": { "release": { "buildOptions": [ "releaseMode", "inline", "optimize" ] }, "tests": { "buildOptions": [ "unittests" ] } } } ``` The project builds but when I attempt to run `dub test`, I get ``` .dub/code/my_script-test-application-unittest-posix.osx.darwin-aarch64.arm_hardfloat-ldc_v1.26.0-8A5B544D5AC6B47B68DE875ACB4BA60E_dub_test_root.d(9,12): Error: only one `main` allowed. Previously found `main` at source/my_script.d(131,6) ``` How can one run tests with dub?
Re: DUB "Error: only one `main` allowed."
On Wednesday, 11 August 2021 at 09:31:46 UTC, tastyminerals wrote: I would like to trigger tests in a simple dub project. ``` source/my_script.d dub.json ``` Here is a dub config: ```json { "targetPath": "build", "targetType": "executable", "sourcePaths": ["source"], "name": "my_script", "buildTypes": { "release": { "buildOptions": [ "releaseMode", "inline", "optimize" ] }, "tests": { "buildOptions": [ "unittests" ] } } } ``` The project builds but when I attempt to run `dub test`, I get ``` .dub/code/my_script-test-application-unittest-posix.osx.darwin-aarch64.arm_hardfloat-ldc_v1.26.0-8A5B544D5AC6B47B68DE875ACB4BA60E_dub_test_root.d(9,12): Error: only one `main` allowed. Previously found `main` at source/my_script.d(131,6) ``` How can one run tests with dub? On a side note, can somebody advise a less buggy build tool for D? Does meson work any better?
Re: How to put an arbitrary string to clipboard in D?
On Friday, 30 July 2021 at 20:01:09 UTC, rikki cattermole wrote: On 31/07/2021 7:33 AM, tastyminerals wrote: I made a GUI app using tkd library. I am reading the string from one of the app widgets and would like to put it into the clipboard. Does anyone have an idea how to copy a string to the clipboard in D? copyText on a Text widget appears to do what you want. https://github.com/nomad-software/tkd/blob/9ca40d117649bb9a9db108d8f92e92870b9dc77e/source/tkd/widget/text.d#L477 https://wiki.tcl-lang.org/page/tk_textCopy The problem is that I don't use Text widget but retrieve the string from TreeView widget which only has getSelectedRows method. So I thought there may be a way in D to communicate with the system clipboard...
How to put an arbitrary string to clipboard in D?
I made a GUI app using tkd library. I am reading the string from one of the app widgets and would like to put it into the clipboard. Does anyone have an idea how to copy a string to the clipboard in D?
Re: Receiving "pthread_mutexattr_init" during compilation when using FileLogger.
On Monday, 7 June 2021 at 11:29:44 UTC, tastyminerals wrote: On Monday, 7 June 2021 at 10:36:23 UTC, Mike Parker wrote: On Monday, 7 June 2021 at 09:29:08 UTC, tastyminerals wrote: I getting ``` import/core/sync/mutex.d(87,36): Error: `pthread_mutexattr_init` cannot be interpreted at compile time, because it has no available source code ``` compile time error. One of those D exceptions which doesn't say where it happened in your code so you need to comment out the lines that might cause it one by one :D I found that this was caused by the "FileLogger" which I create at the top of the file. But why? You can't initialize classes at module scope. You can declare them, but then they must be initialized in a function or a module constructor. Normally for a type `MyClass` in module `foo`, you'd see an error like this: ```D Error: variable `foo.MyClass` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead. ``` I guess CTFE runs before the check that catches this, though, and the `FileLogger` constructor ultimately triggers the error your seeing. I see, I only remember that one cannot create associative arrays in global scope. This is explicitly written in the language reference. It's interesting how there is no information about class instantiation at module level anywhere in the docs. Even the Ali's book does not explicitly say that you cannot instantiate a class this way. Maybe I totally missed it but just doing the key search on "scope", "global", "module" in class related chapters didn't give me any results.
Re: Receiving "pthread_mutexattr_init" during compilation when using FileLogger.
On Monday, 7 June 2021 at 10:36:23 UTC, Mike Parker wrote: On Monday, 7 June 2021 at 09:29:08 UTC, tastyminerals wrote: I getting ``` import/core/sync/mutex.d(87,36): Error: `pthread_mutexattr_init` cannot be interpreted at compile time, because it has no available source code ``` compile time error. One of those D exceptions which doesn't say where it happened in your code so you need to comment out the lines that might cause it one by one :D I found that this was caused by the "FileLogger" which I create at the top of the file. But why? You can't initialize classes at module scope. You can declare them, but then they must be initialized in a function or a module constructor. Normally for a type `MyClass` in module `foo`, you'd see an error like this: ```D Error: variable `foo.MyClass` is a thread-local class and cannot have a static initializer. Use `static this()` to initialize instead. ``` I guess CTFE runs before the check that catches this, though, and the `FileLogger` constructor ultimately triggers the error your seeing. I see, I only remember that one cannot create associative arrays in global scope. This is explicitly written in the language reference. It's interesting how there is no information about class instantiation at module level anywhere in the docs. Even the Ali's book does not explicitly say that you cannot instantiate a class this way. Maybe I missed it but just doing the key search on "scope", "global", "module" in class related chapters didn't give me any results.
Receiving "pthread_mutexattr_init" during compilation when using FileLogger.
I getting ``` import/core/sync/mutex.d(87,36): Error: `pthread_mutexattr_init` cannot be interpreted at compile time, because it has no available source code ``` compile time error. One of those D exceptions which doesn't say where it happened in your code so you need to comment out the lines that might cause it one by one :D I found that this was caused by the "FileLogger" which I create at the top of the file. But why? ```d import std.experimental.logger: FileLogger; auto fileLogger = new FileLogger("last.log"); ``` Moving the FileLogger instantiation to a function fixes the issue though.
How to parse JSON in D?
We need to parse a bunch of JSON files. What does D have? It has std.json which is strangely slower than Python json :( Ok, we go to dub repository and search for something that is faster. There are basically two implementations fast.json and stdx.data.json. The first one refuses to work on Mac M1 chip so we take the stdx.data.json, go to the documentation page and see two three snippets on how to use the library. The code examples are so scarce that I feel like a person who did it was forced to do it out of his own will. Now, to the problem. I have the following JSON structure. "items": { "elements": [ { "name" : "", "type" : "" }, { "name": "", "type": "" } ] } auto elements = parseJSONValue("file.json")["items]["elements"]; I want to access each "name" member of "elements". How do I do it in stdx.data.json?
Re: What happened to std.net.curl HTTP execute?
On Wednesday, 17 March 2021 at 16:02:58 UTC, tastyminerals wrote: I am using std.net.curl and the following chunk of code in many places: """ http.setPostData(userData, "application/json"); http.addRequestHeader("Accept", "application/json"); http.addRequestHeader("Authorization", "BEARER " ~ clientAccessToken); auto jsonData = http.execute.parseJSON; if (jsonData.isNull) { """ Today I tried to compile one of the scripts and it failed with Error: no property execute for type std.net.curl.HTTP When was it removed? I checked GitHub history briefly but the latest change dates back to April 2020 when these scripts were not even written. How did they work couple of months ago? I am confused. Ohh, I created a custom function "execute" which calls "HTTP.perform" :facepalm: I need to take a rest.
What happened to std.net.curl HTTP execute?
I am using std.net.curl and the following chunk of code in many places: """ http.setPostData(userData, "application/json"); http.addRequestHeader("Accept", "application/json"); http.addRequestHeader("Authorization", "BEARER " ~ clientAccessToken); auto jsonData = http.execute.parseJSON; if (jsonData.isNull) { """ Today I tried to compile one of the scripts and it failed with Error: no property execute for type std.net.curl.HTTP When was it removed? I checked GitHub history briefly but the latest change dates back to April 2020 when these scripts were not even written. How did they work couple of months ago? I am confused.
Re: dub support for Mac M1?
On Thursday, 4 March 2021 at 23:57:25 UTC, kinke wrote: On Thursday, 4 March 2021 at 22:30:17 UTC, tastyminerals wrote: I got a company MacBook with M1 chip and gradually migrate all the stuff from Linux machine. I got precompiled ldc binary installed without any problem now is the time for dub since I have couple of D projects I use at work and all of them use dub. I can only see the dub-v1.23.0-osx-x86_64.tar.gz package so it should at least run via Rosetta. The official prebuilt LDC package comes with prebuilt dub, dustmite, ddemangle and rdmd, just like any other package. Oh, you are right! I was not aware of that. Thank you.
dub support for Mac M1?
I got a company MacBook with M1 chip and gradually migrate all the stuff from Linux machine. I got precompiled ldc binary installed without any problem now is the time for dub since I have couple of D projects I use at work and all of them use dub. I can only see the dub-v1.23.0-osx-x86_64.tar.gz package so it should at least run via Rosetta. I also tried compiling it via MacPorts but looks like dub pulls dmd as a dependency and dmd fails to build currently. For example: """ $ sudo port install dub Warning: The macOS 11.2 SDK does not appear to be installed. Ports may not build correctly. Warning: You can install it as part of the Xcode Command Line Tools package by running `xcode-select --install'. ---> Computing dependencies for dub The following dependencies will be installed: dmd dmd-tools druntime phobos Continue? [Y/n]: y Warning: The macOS 11.2 SDK does not appear to be installed. Ports may not build correctly. Warning: You can install it as part of the Xcode Command Line Tools package by running `xcode-select --install'. ---> Fetching archive for dmd ---> Attempting to fetch dmd-2.088.0_0.darwin_20.arm64.tbz2 from https://lil.fr.packages.macports.org/dmd ---> Attempting to fetch dmd-2.088.0_0.darwin_20.arm64.tbz2 from https://mse.uk.packages.macports.org/dmd ---> Attempting to fetch dmd-2.088.0_0.darwin_20.arm64.tbz2 from https://packages.macports.org/dmd ---> Building dmd Error: Failed to build dmd: command execution failed Error: See /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_macports_release_tarballs_ports_lang_dmd/dmd/main.log for details. Error: Follow https://guide.macports.org/#project.tickets to report a bug. Error: Processing of port dub failed """ We look into the logs and see """ :info:build (maybe you meant: dt_writeToObj(Obj*, dt_t*, int, unsigned long long&), file_write(char*, void*, unsigned int) , Obj_write_pointerRef(Symbol*, unsigned int) , Obj_write_bytes(seg_data*, unsigned int, void*) , __D3dmd4glue18obj_write_deferredRCQBf3lib7LibraryZ5counti , Obj_write_zeros(seg_data*, unsigned long long) , obj_write_deferred(Library*) , Obj_write_byte(seg_data*, unsigned int) ) :info:build ld: symbol(s) not found for architecture i386 :info:build clang: error: linker command failed with exit code 1 (use -v to see invocation) :info:build Error: linker exited with status 1 :info:build make: *** [../generated/osx/release/32/dmd] Error 1 """ Are there any plans to support M1 for dub?
Re: DMD support for Apples new silicon
On Sunday, 10 January 2021 at 14:50:44 UTC, Guillaume Piolat wrote: On Sunday, 10 January 2021 at 14:22:25 UTC, Christian Köstlin wrote: [...] Hello Christian, [...] I see that there is a ldc2-1.25.1-osx-arm64.tar.xz already among https://github.com/ldc-developers/ldc/releases So, one could use this straight away, right?
Re: How to rebind the default tkd GUI keybinds?
On Saturday, 17 October 2020 at 18:39:54 UTC, starcanopy wrote: On Saturday, 17 October 2020 at 09:33:04 UTC, tastyminerals wrote: On Sunday, 11 October 2020 at 18:51:17 UTC, tastyminerals wrote: [...] So, this is even tricky in Python TkInter but possible. In tkd this is not possible unfortunately. You could try directly calling [bindtags](https://www.tcl.tk/man/tcl8.4/TkCmd/bindtags.htm) with _tk.eval. Modifying and extending tkd is easy from my experience where I had added support for additional image formats. (After blundering about on how to get tcl/tk to work, lol.) So, there is a way. It just needs substantial time investment :) Thanks for point it out.
Re: How to rebind the default tkd GUI keybinds?
On Sunday, 11 October 2020 at 18:51:17 UTC, tastyminerals wrote: Tk default keys are somewhat different from what we used to use for selecting, copying and pasting the text. So, any Tk based GUI app starts with writing the rebinding function for "ctrl+a", "ctrl+c", "ctrl+x" and "ctrl+v" keys, at least. I did it when writing TkInter based apps in Python. Today I am trying out tkd and want to do the same. However, it doesn't work :( For example: private void selectText(CommandArgs args) { this._clientId.selectText; } this._loginFrame = new Frame(2, ReliefStyle.groove); this._clientId = new Entry(loginFrame).grid(1, 0); this._clientId.bind("", ); It works if I change "" to "" for example. But how do I overwrite the actual "" key in tkd? So, this is even tricky in Python TkInter but possible. In tkd this is not possible unfortunately.
Re: How to add an additional config dir in DUB under source?
On Tuesday, 13 October 2020 at 05:13:18 UTC, Mike Parker wrote: On Monday, 12 October 2020 at 22:31:53 UTC, tastyminerals wrote: [...] This: readText("conf.toml"); [...] Thanks. I remembered that I read about them in Ali's book but never actually used them.
How to add an additional config dir in DUB under source?
I have the following project structure: source/ media/ icon.png config/ conf.toml In order to access "icon.png" without explicitly providing the path I added in dub.json "stringImportPaths": [ "source/media", "source/config" ] It works for "icon.png" but doesn't work for "conf.toml". The "icon.png" can be accessed and the code below works: addEntry(new EmbeddedPng!("quit.png") but std.file: readText refuses to see "conf.toml": readText("conf.toml"); file.d(371): conf.toml: No such file or directory I wonder why and what am I doing wrong?
Re: vibe.d / experience / feedback
On Sunday, 11 October 2020 at 11:56:29 UTC, Robert M. Münch wrote: On 6 Oct 2020 at 10:07:56 CEST, "ddcovery" wrote: I found myself in a similar situation recently, and I can't help but ask you: What technology do you use regularly? Hi, well we use a couple of different things. Scripting languages, C, Lua, .. What drives/draws you to try dlang/vibe.d? A prototype we wanted to build while evaluating D as our next tech stack foundation. Do you have other alternatives to dlang/vibe.d for your project? Yes. We are currently looking into Go as well. In my case we usually work in Node+js/ts (previously Scala+Play) and I wanted to jump to something really performant for a new project without losing code expressiveness and development speed. Dlang seemed a good alternative (I like it much more than Go or Rust). Well, for us it's getting more and more clear, that a decision what to use in the future will be based on less and less technical aspects. The interesting thing about Go is, that their main focus is thinking from an enterprise perspective, not only from a technical one. So, their focus is getting stuff done, keeping maintainability in big, constantly changing teams and stripping everything away, that reduces productivity in such an environment... I don't know about any other language which puts all these non-technical aspects on the top of the agenda. Viele Grüsse. And I feel like you guys will just pick Go because it will get stuff done. I am in a philosophical mood today so here it goes... When I just started learning about D ecosystem, vibe frequently popped up as one of the popular frameworks available for the language AND also a reason for ppl to jump in and try out D. However, as time goes, I also pick up many complaints about vibe, its performance and ease of use compared to competitors. This post just solidifies the impression. Bad documentation is the worst thing that can happen to a project which gets promoted as a one of the jems of the language ecosystem and actually hurts the language image much more than does good. Sigh... I will never advice vibe to anyone because I know that better alternatives exist. People will use Go, Python, Ruby, Rust whatever has better docs to get it running fast and not risk wasting time. Sadly, this is how some languages grow and some don't. And it's not all about the corporate support, hype, GC or random luck, it's about cases like the above.
How to rebind the default tkd GUI keybinds?
Tk default keys are somewhat different from what we used to use for selecting, copying and pasting the text. So, any Tk based GUI app starts with writing the rebinding function for "ctrl+a", "ctrl+c", "ctrl+x" and "ctrl+v" keys, at least. I did it when writing TkInter based apps in Python. Today I am trying out tkd and want to do the same. However, it doesn't work :( For example: private void selectText(CommandArgs args) { this._clientId.selectText; } this._loginFrame = new Frame(2, ReliefStyle.groove); this._clientId = new Entry(loginFrame).grid(1, 0); this._clientId.bind("", ); It works if I change "" to "" for example. But how do I overwrite the actual "" key in tkd?
Re: How to hide a function return type in order to wrap several functions into an associated array?
On Sunday, 27 September 2020 at 20:03:21 UTC, Paul Backus wrote: On Sunday, 27 September 2020 at 18:54:11 UTC, tastyminerals wrote: [...] You can use an Algebraic [1] or SumType [2] for this: alias Feature = SumType!(ulong, double, bool); Feature numberOfPunctChars(string text) { // ... return Feature(cnt); } Feature ratioOfDigitsToChars(string text) { // ... return Feature(ratio); } Feature hasUnbalancedParens(string text) { // ... return Feature(!isBalanced); } [1] http://dpldocs.info/experimental-docs/std.variant.Algebraic.html [2] https://code.dlang.org/packages/sumtype Nice, thanks. Never used it, shall take a look.
Re: How to hide a function return type in order to wrap several functions into an associated array?
On Sunday, 27 September 2020 at 22:55:14 UTC, Ali Çehreli wrote: On 9/27/20 11:54 AM, tastyminerals wrote: > [...] input, a string. > [...] function does > [...] [...] Thank you. Quite an inspirational example with delegates.
How to hide a function return type in order to wrap several functions into an associated array?
This is rather a generic implementation question not necessarily related to D but I'd like to get some opinions. I have a collection of functions that all have the same input, a string. The output however is different and depending on what the function does it can be ulong, double or bool. The problem is that for each line of text I'd like to apply all these functions, collect the results and write them into some file. For example, auto numberOfPunctChars(string text) { const ulong cnt = text.filter!(c => c.isPunctuation).count; return Feature!ulong("numberOfPunctChars", cnt); } auto ratioOfDigitsToChars(string text) { const double digits = numberOfDigitChars(text).val.to!double; const double alphas = numberOfAlphaChars(text).val.to!double; const double ratio = digits / (alphas > 0 ? alphas : digits); return Feature!double("ratioOfDigitsToChars", ratio); } auto hasUnbalancedParens(string text) { const bool isBalanced = balancedParens(text, '(', ')') && balancedParens(text, '[', ']'); return Feature!bool("hasUnbalancedParens", !isBalanced); } As you can see, I created a templated Feature struct. This does not help much because I also want to create an associative array of ["functionName": ]. How can I define such an array when "Feature!T function(string)[string] allFuns" requires defining T beforehand and using auto is not possible? I was thinking of having a Feature struct with 3 fiels of ulong, double and bool members but then each Feature init would look ugly imho "Feature("name", null, 1.5, null)". There should be a another way.
Re: How to use std.net.curl with specific curl query?
On Thursday, 3 September 2020 at 11:14:14 UTC, tastyminerals wrote: I have a specific curl query that I want to use in a D script via std.net.curl. Here is the query: curl -v -X POST --data-urlencode "username=u...@gmail.net" --data-urlencode "password=12345" -H "Content-Type: application/x-www-form-urlencoded" -H "Accept: application/json" -u "client_name:CLIENT_PASS" "https://some.i.net/oauth/token?grant_type=password; The std.net.curl post documentation says that it needs a URL and a key:value map as arguments. However, what should be the key and what should be the value given the above query? There are two "--data-urlencode" parameters so the map cannot have two identical keys. Unfortunately the documentation is lacking both information and examples. Can somebody help me out here please? In addition, the current "post" ddoc example fails to run throwing "std.net.curl.CurlException@std/net/curl.d(4402): Couldn't resolve host name on handle 55DF372ABBC0" Figured it out, just needed to read further docs. auto http = HTTP("https://some.i.net/oauth/token?grant_type=password;); auto data = "username=u...@gmail.net=12345"; http.setPostData(data, "application/x-www-form-urlencoded"); http.addRequestHeader("Content-Type", "application/x-www-form-urlencoded"); http.addRequestHeader("Accept", "application/json"); http.setAuthentication("client_name", "CLIENT_PASS"); http.perform
How to use std.net.curl with specific curl query?
I have a specific curl query that I want to use in a D script via std.net.curl. Here is the query: curl -v -X POST --data-urlencode "username=u...@gmail.net" --data-urlencode "password=12345" -H "Content-Type: application/x-www-form-urlencoded" -H "Accept: application/json" -u "client_name:CLIENT_PASS" "https://some.i.net/oauth/token?grant_type=password; The std.net.curl post documentation says that it needs a URL and a key:value map as arguments. However, what should be the key and what should be the value given the above query? There are two "--data-urlencode" parameters so the map cannot have two identical keys. Unfortunately the documentation is lacking both information and examples. Can somebody help me out here please? In addition, the current "post" ddoc example fails to run throwing "std.net.curl.CurlException@std/net/curl.d(4402): Couldn't resolve host name on handle 55DF372ABBC0"
Re: 2-D array initialization
On Sunday, 2 August 2020 at 19:19:51 UTC, Andy Balba wrote: On Sunday, 2 August 2020 at 06:37:06 UTC, tastyminerals wrote: You haven't said anything about efficiency because if you care and your arrays are rather big, you better go with https://github.com/libmir/mir-algorithm as mentioned above. It might be a little finicky at the start but this post: https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html should get you up to speed. Keep in mind that std.array.staticArray is not efficient for large arrays. If you want to stick to standard D, I would not initialize a 2D array because it is just cumbersome but rather use a 1D array and transform it into 2D view on demand via ".chunks" method. Here is an example. import std.range; import std.array; void main() { int[] arr = 20.iota.array; auto arr2dView = arr.chunks(5); } Should give you ┌ ┐ │ 0 1 2 3 4│ │ 5 6 7 8 9│ │10 11 12 13 14│ │15 16 17 18 19│ └ ┘ whenever you need to access its elements as arr.chunks(5)[1][1 .. 3] --> [6, 7]. @ tastyminerals Thanks for your help on this. These comments, combined with the others, are making my climb of the D learning curve much quicker. I'm not a gitHub fan, but I like the mir functions; and it looks like I have to download mir before using it. mir has quite a few .d files..Is there a quick way to download it ? mir is a D package (akin to Python pip package). You can easily include it into your program by adding at the top of your file the following code: /+ dub.sdl: name "my_script" dependency "mir-algorithm" version="~>3.9.12" +/ And then just run your script with "dub my_script.d", dub will fetch the necessary dependencies, compile and run the file. However, it will not generate compiled versions of your my_script.d for that, you better set a dub project. Here, see to do it: https://tastyminerals.github.io/tasty-blog/dlang/2020/03/01/how_to_use_external_libraries_in_d_project.html
Re: 2-D array initialization
On Sunday, 2 August 2020 at 02:00:46 UTC, Andy Balba wrote: On Saturday, 1 August 2020 at 22:00:43 UTC, Ali Çehreli wrote: On 8/1/20 12:57 PM, Andy Balba wrote: > On Saturday, 1 August 2020 at 00:08:33 UTC, MoonlightSentinel wrote: >> On Friday, 31 July 2020 at 23:42:45 UTC, Andy Balba wrote: >>> How does one initialize c in D ? >> >> ubyte[3][4] c = [ [5, 5, 5], [15, 15,15], [25, 25,25], [35, 35,35] ]; > I'm a D newbie. moving over from C/C++, and I'm really finding it hard > to adjusting to D syntax, which I find somewhat cryptic compared to C/C++. That's surprising to me. I came from C++03 year ago but everything in D was much better for me. :) I wanted to respond to your question yesterday and started typing some code but then I decided to ask first: Do you really need a static array? Otherwise, the following is a quite usable 2D array: ubyte[][] c = [ [5, 5, 5], [15, 15,15], [25, 25,25], [35, 35,35] ]; However, that's quite different from a ubyte[3][4] static array because 'c' above can be represented like the following graph in memory. (Sorry if this is already known to you.) c.ptr --> | .ptr | .ptr | .ptr | .ptr | | | | | . . | --> | 35 | 35 | 35 | 35 | etc. etc. --> | 25 | 25 | 25 | 25 | In other words, each element is reached through 2 dereferences in memory. On the other hand, a static array consists of nothing but the elements in memory. So, a ubyte[3][4] would be the following elements in memory: | 5 | 5 | ... | 35 | 35 | One big difference is that static arrays are value types, meaning that all elements are copied e.g. as arguments during function calls. On the other hand, slices are copied just as fat pointers (ptr+length pair), hence have reference semantics. Here are some ways of initializing a static array. This one is the most natural one: ubyte[3][4] c = [ [5, 5, 5], [15, 15,15], [25, 25,25], [35, 35,35] ]; Yes, that works! :) Why did you need to cast to begin with? One reason may be you had a value that could not fit in a ubyte so the compiler did not agree. (?) This one casts a 1D array as the desired type: ubyte[3][4] c = *cast(ubyte[3][4]*)(cast(ubyte[])[ 5, 5, 5, 15, 15, 15, 25, 25, 25, 35, 35, 35 ]).ptr; The inner cast is required because 5 etc. are ints by-default. There is std.array.staticArray as well but I haven't used it. Ali Although not detailed in my original question, in my actual app I have array ubyte [1000][3] Big which consists of research data I obtained, and from which I want to randomly select 4 observations to construct ubyte c[ ][ ]. i.e. construct c= [ Big[r1][3], Big[r2][3], Big[r3][3], Big[r4][3] ] where r1, r2, r3 and r4 are 4 random integers in 0..1001 Being a D newbie, my naive way of doing this was to declare c using: ubyte[3][4] c= [ Big[r1][3], Big[r2][3], Big[r3][3], Big[r4][3] ] Obviously, I want to learn how to this the smart D way, but I not smart enough at this point. You haven't said anything about efficiency because if you care and your arrays are rather big, you better go with https://github.com/libmir/mir-algorithm as mentioned above. It might be a little finicky at the start but this post: https://tastyminerals.github.io/tasty-blog/dlang/2020/03/22/multidimensional_arrays_in_d.html should get you up to speed. Keep in mind that std.array.staticArray is not efficient for large arrays. If you want to stick to standard D, I would not initialize a 2D array because it is just cumbersome but rather use a 1D array and transform it into 2D view on demand via ".chunks" method. Here is an example. import std.range; import std.array; void main() { int[] arr = 20.iota.array; auto arr2dView = arr.chunks(5); } Should give you ┌ ┐ │ 0 1 2 3 4│ │ 5 6 7 8 9│ │10 11 12 13 14│ │15 16 17 18 19│ └ ┘ whenever you need to access its elements as arr.chunks(5)[1][1 .. 3] --> [6, 7].
Re: D Mir: standard deviation speed
On Wednesday, 15 July 2020 at 07:51:31 UTC, 9il wrote: On Wednesday, 15 July 2020 at 07:34:59 UTC, tastyminerals wrote: On Wednesday, 15 July 2020 at 06:57:21 UTC, 9il wrote: On Wednesday, 15 July 2020 at 06:55:51 UTC, 9il wrote: On Wednesday, 15 July 2020 at 06:00:46 UTC, tastyminerals wrote: On Wednesday, 15 July 2020 at 02:08:48 UTC, 9il wrote: [...] Good to know. So, it's fine to use it with sum!"fast" but better avoid it for general purposes. They both are more precise by default. This was a reply to the other your post in the thread, sorry. Mir algorithms are more precise by default then the algorithms you have provided. Right. Is this why standardDeviation is significantly slower? Yes. It allows you to pick a summation option, you can try others then default in benchmarks. Indeed, I played around with VarianceAlgo and Summation options, and they impact the end result a lot. ans = matrix.flattened.standardDeviation!(VarianceAlgo.naive, Summation.appropriate); std of [300, 300] matrix 0.375903 std of [60, 60] matrix 0.0156448 std of [600, 600] matrix 1.54429 std of [800, 800] matrix 3.03954 ans = matrix.flattened.standardDeviation!(VarianceAlgo.online, Summation.appropriate); std of [300, 300] matrix 1.12404 std of [60, 60] matrix 0.041968 std of [600, 600] matrix 5.01617 std of [800, 800] matrix 8.64363 The Summation.fast behaves strange though. I wonder what happened here? ans = matrix.flattened.standardDeviation!(VarianceAlgo.naive, Summation.fast); std of [300, 300] matrix 1e-06 std of [60, 60] matrix 9e-07 std of [600, 600] matrix 1.2e-06 std of [800, 800] matrix 9e-07 ans = matrix.flattened.standardDeviation!(VarianceAlgo.online, Summation.fast); std of [300, 300] matrix 9e-07 std of [60, 60] matrix 9e-07 std of [600, 600] matrix 1.1e-06 std of [800, 800] matrix 1e-06
Re: Contributing to D wiki
On Wednesday, 15 July 2020 at 16:04:56 UTC, aberba wrote: So I'm looking to make changes to the D wiki but I'm not sure who to talk to about such changes. Currently: Move all other IDEs low-quality down (maybe to Others) and focus on just the few that really works (IntelliJ, Visual Studio Code and Visual Studio). Instead of many options that don't work, why not focus on they few that works? D wiki is badly outdated. This is not a fact but a gut feeling after reading through some of its pages. I was wondering who's owning it myself but never actually dared to just go and update. I just had a feeling it's abandoned. On the other hand why would it be?
Re: D Mir: standard deviation speed
On Wednesday, 15 July 2020 at 06:57:21 UTC, 9il wrote: On Wednesday, 15 July 2020 at 06:55:51 UTC, 9il wrote: On Wednesday, 15 July 2020 at 06:00:46 UTC, tastyminerals wrote: On Wednesday, 15 July 2020 at 02:08:48 UTC, 9il wrote: On Tuesday, 14 July 2020 at 19:04:45 UTC, tastyminerals wrote: @fastmath private double sd0(T)(Slice!(T*, 1) flatMatrix) @fastmath shouldn't be really used with summation algorithms except the `"fast"` version of them. Otherwise, they may or may not behave like "fast". Good to know. So, it's fine to use it with sum!"fast" but better avoid it for general purposes. They both are more precise by default. This was a reply to the other your post in the thread, sorry. Mir algorithms are more precise by default then the algorithms you have provided. Right. Is this why standardDeviation is significantly slower?
Re: D Mir: standard deviation speed
On Wednesday, 15 July 2020 at 02:08:48 UTC, 9il wrote: On Tuesday, 14 July 2020 at 19:04:45 UTC, tastyminerals wrote: @fastmath private double sd0(T)(Slice!(T*, 1) flatMatrix) @fastmath shouldn't be really used with summation algorithms except the `"fast"` version of them. Otherwise, they may or may not behave like "fast". Good to know. So, it's fine to use it with sum!"fast" but better avoid it for general purposes.
Re: D Mir: standard deviation speed
On Tuesday, 14 July 2020 at 19:36:21 UTC, jmh530 wrote: On Tuesday, 14 July 2020 at 19:04:45 UTC, tastyminerals wrote: [...] It would be helpful to provide a link. You should only need one accumulator for mean and centered sum of squares. See the python example under the Welford example https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance This may have broken optimization somehow. variance and standardDeviation were recently added to mir.math.stat. They have the option to switch between Welford's algorithm and the others. What you call as the naive algorithm, is VarianceAlgo.twoPass and the Welford algorithm can be toggled with VarianceAlgo.online, which is the default option. It also would be interesting if you re-did the analysis with the built-in mir functions. There are some other small differences between your implementation and the one in mir, beyond the issue discussed above. You take the absolute value before the square root and force the use of sum!"fast". Another difference is VarianceAlgo.online in mir is using a precise calculation of the mean rather than the fast update that Welford uses. This may have a modest impact on performance, but should provide more accurate results. Ok, the wiki page looks more informative, I shall look into my Welford implementation. I've just used standardDeviation from Mir and it showed even worse results than both of the examples above. Here is a (WIP) project as of now. Line 160 in https://github.com/tastyminerals/mir_benchmarks_2/blob/master/source/basic_ops.d std of [60, 60] matrix 0.0389492 (> 0.001727) std of [300, 300] matrix 1.03592 (> 0.043452) std of [600, 600] matrix 4.2875 (> 0.182177) std of [800, 800] matrix 7.9415 (> 0.345367)
D Mir: standard deviation speed
I am trying to implement standard deviation calculation in Mir for benchmark purposes. I have two implementations. One is the straightforward std = sqrt(mean(abs(x - x.mean())**2)) and the other follows Welford's algorithm for computing variance (as described here: https://www.johndcook.com/blog/standard_deviation/). However, although the first implementation should be less efficient / slower, the benchmarking results show a startling difference in its favour. I'd like to understand if I am doing something wrong and would appreciate some explanation. # Naive std import std.math : abs; import mir.ndslice; import mir.math.common : pow, sqrt, fastmath; import mir.math.sum : sum; import mir.math.stat : mean; @fastmath private double sd0(T)(Slice!(T*, 1) flatMatrix) { pragma(inline, false); if (flatMatrix.empty) return 0.0; double n = cast(double) flatMatrix.length; double mu = flatMatrix.mean; return (flatMatrix.map!(a => (a - mu).abs ^^ 2).sum!"fast" / n).sqrt; } # std with Welford's variance @fastmath double sdWelford(T)(Slice!(T*, 1) flatMatrix) { pragma(inline, false); if (flatMatrix.empty) return 0.0; double m0 = 0.0; double m1 = 0.0; double s0 = 0.0; double s1 = 0.0; double n = 0.0; foreach (x; flatMatrix.field) { ++n; m1 = m0 + (x - m0) / n; s1 = s0 + (x - m0) * (x - m1); m0 = m1; s0 = s1; } // switch to n - 1 for sample variance return (s1 / n).sqrt; } Benchmarking: Naive std (1k loops): std of [60, 60] matrix 0.001727 std of [300, 300] matrix 0.043452 std of [600, 600] matrix 0.182177 std of [800, 800] matrix 0.345367 std with Welford's variance (1k loops): std of [60, 60] matrix 0.0225476 std of [300, 300] matrix 0.534528 std of [600, 600] matrix 2.0714 std of [800, 800] matrix 3.60142
Re: Why is this allowed
On Tuesday, 30 June 2020 at 16:22:57 UTC, JN wrote: Spent some time debugging because I didn't notice it at first, essentially something like this: int[3] foo = [1, 2, 3]; foo = 5; writeln(foo); // 5, 5, 5 Why does such code compile? I don't think this should be permitted, because it's easy to make a mistake (when you wanted foo[index] but forgot the []). If someone wants to assign a value to every element they could do foo[] = 5; instead which is explicit. auch, that is very nasty. Thanks for posting. This is a good example for D gotchas.
Why infinite loops are faster than finite loops?
I am not sure that this is a question about D or a more general one. I have watched this nice presentation "Speed Is Found In The Minds of People" by Andrei: https://www.youtube.com/watch?v=FJJTYQYB1JQ=youtu.be?t=2596 and on 43:20 he says that "push_heap" is slow because of structured loops and finite for (throughout the presentation Andrei shows algorithm examples with infinite loops). I wonder why is that? Is it because the finite loop needs to keep track of the number of iterations it performs? Wouldn't the compiler optimize it better than the infinite one because it knows the number of iterations the for loop needs?
Using autowrap to build a D library for Python
I am trying out autowrap to build a D library for Python. After I ran "dub build" which builds mylib.so and try to import it in Python interpreter, I get: "ImportError: dynamic module does not define module export function (PyInit_libautowrap_mylib)" Which means the library was build for some other Python version which is strange because in dub.sdl I specifically set subConfiguration "autowrap:python" "python36" And attempt to import the libautowrap_mylib from Python 3.6.9 interpreter. The dub.sdl contains the following deps: dependency "autowrap:python" version="~>0.5.2" dependency "mylib" version="~>1.0.0" subConfiguration "autowrap:python" "python36" targetType "dynamicLibrary"
Re: Looking for a Code Review of a Bioinformatics POC
On Thursday, 11 June 2020 at 21:54:31 UTC, duck_tape wrote: On Thursday, 11 June 2020 at 20:24:37 UTC, tastyminerals wrote: Mir Slices instead of standard D arrays are faster. Athough looking at your code I don't see where you can plug them in. Just keep in mind. Thanks for taking a look! What is it about Mir Slices that makes them faster? I hadn't seen the Mir package before but it looks very useful and intriguing. Mir is fine-tuned for LLVM, pointer magic and SIMD optimizations.
Re: Looking for a Code Review of a Bioinformatics POC
On Thursday, 11 June 2020 at 16:13:34 UTC, duck_tape wrote: Hi! I'm new to dlang but loving it so far! One of my favorite first things to implement in a new language is an interval library. In this case I want to submit to a benchmark repo: https://github.com/lh3/biofast If anyone is willing to take a look and give some feedback I'd be very appreciative! Specifically if you have an performance improvement ideas: https://github.com/sstadick/dgranges/pull/1 Currently my D version is a few seconds slower than the Crystal version. putting it very solid in third place overall. I'm not really sure where it's falling behind crystal since `-release` removes bounds checking. I have not looked at the assembly between the two, but I suspect that Crystal inlines the callback and D does not. I also think there is room for improvement in the IO, as I'm just using the defaults. Add to your dub.json the following: """ "buildTypes": { "release": { "buildOptions": [ "releaseMode", "inline", "optimize" ], "dflags": [ "-boundscheck=off" ] }, } """ dub build --compiler=ldc2 --build=release Mir Slices instead of standard D arrays are faster. Athough looking at your code I don't see where you can plug them in. Just keep in mind.
Re: Looking for a Code Review of a Bioinformatics POC
On Thursday, 11 June 2020 at 16:13:34 UTC, duck_tape wrote: Hi! I'm new to dlang but loving it so far! One of my favorite first things to implement in a new language is an interval library. In this case I want to submit to a benchmark repo: https://github.com/lh3/biofast If anyone is willing to take a look and give some feedback I'd be very appreciative! Specifically if you have an performance improvement ideas: https://github.com/sstadick/dgranges/pull/1 Currently my D version is a few seconds slower than the Crystal version. putting it very solid in third place overall. I'm not really sure where it's falling behind crystal since `-release` removes bounds checking. I have not looked at the assembly between the two, but I suspect that Crystal inlines the callback and D does not. I also think there is room for improvement in the IO, as I'm just using the defaults. Move as much as possible code to compile time. Do not allocate inside the loops. Keep GC collection away from performance critical parts with GC.disable switch; Also dflags-ldc "-mcpu=native" in dub.json might give you some edge.
Re: Metaprogramming with D
On Monday, 8 June 2020 at 14:41:55 UTC, Jan Hönig wrote: On Sunday, 7 June 2020 at 00:45:37 UTC, Ali Çehreli wrote: dmd -mixin= ... thanks for the tip! writeln(q{ void foo() { } }); What is the name of this `q` thing? How do i find it? Are there any recent tutorials on it? Ali's online book consolidates a lot of D language knowledge like this. I forgot about token string literals myself but then remembered it was in his book.