Re: [Semi-OT] Cross-Platform GitHub Action 0.3.0 - NetBSD
On Tuesday, 16 November 2021 at 14:38:48 UTC, Sebastiaan Koppe wrote: I was reading https://github.com/marketplace/actions/cross-platform-action#under-the-hood and have to say I am impressed. Looks like a very well done library. Thanks. Yeah, it turned out to be quite complex to support everything. Multiple platforms, multiple hypervisors, multiple hosts platforms etc. -- /Jacob Carlborg
Re: [Semi-OT] Cross-Platform GitHub Action 0.3.0 - NetBSD
On Tuesday, 16 November 2021 at 14:04:12 UTC, Imperatorn wrote: Oh, nice to see support for FreeBSD. I just added a version for it in druntime 4 days ago. Now maybe we can test it lol I can add older versions of FreeBSD (currently 12.2 and 13 are supported) if there's a need for that. /Jacob Carlborg
[Semi-OT] Cross-Platform GitHub Action 0.3.0 - NetBSD
# Cross-Platform GitHub Action 0.3.0 I would like to announce a new release of [Cross-Platform GitHub Action](https://github.com/marketplace/actions/cross-platform-action), [0.3.0](https://github.com/cross-platform-actions/action/releases/tag/v0.3.0). For those not familiar with this project, it provides a GitHub action for running GitHub Action workflows on multiple platforms. This includes platforms that GitHub Actions don't natively support (for more information see the original announcement of the project [1]). The major new feature in this release is the support for a new platform: NetBSD. The only supported version so far is 9.2. Other minor features since the last announcement are support for FreeBSD 13 and OpenBSD 6.9. ## Under the Hood For those interested in what's going on under the hood. This release contains some major refactoring to add support for the QEMU hypervisor. Up until now the xhyve hypervisor has been used for the FreeBSD and OpenBSD platforms. Unfortunately NetBSD doesn't run on the xhyve hypervisor, therefore support for QEMU was added. In this release it's only possible to run NetBSD on Linux hosts. The GitHub Linux runners doesn't support hardware accelerated nested virtualization. This unfortunately means that the QEMU hypervisor will be a bit slower than the xhyve hypervisor. [1] https://forum.dlang.org/post/jhasyhuvcxoqhldlb...@forum.dlang.org
Re: OpenBSD DMD package
On Thursday, 14 October 2021 at 16:14:17 UTC, Brian wrote: Awesome! I will spend some time soon figuring it out. Here are two real world examples: https://github.com/jacob-carlborg/lime/blob/master/.github/workflows/ci.yml https://github.com/jacob-carlborg/dlp/blob/master/.github/workflows/ci.yml -- /Jacob Carlborg
Re: OpenBSD DMD package
On Tuesday, 12 October 2021 at 12:42:09 UTC, Brian wrote: I don't think any of the free ones support OpenBSD yet :) There is SourceHut, which does support OpenBSD CI, but I don't think it is free to use. You can use my GitHub action: https://github.com/marketplace/actions/cross-platform-action. -- /Jacob Carlborg
Re: Diva - D Language Interface for Versioned Applications
On Saturday, 10 July 2021 at 12:30:43 UTC, Bastiaan Veelo wrote: Thanks for clarifying the differences. Some other differences: * DVM is cross-platform. Diva seems to only run on Ubuntu. * DVM is implemented in D (with a tiny shell script wrapper). Diva depends on Python * DVM does not use symlinks. When invoking the compiler it's the actual executable that's invoked directly * DVM provides a built-in command to install itself and do any setup -- /Jacob Carlborg
Re: [Semi-OT] Cross-Platform GitHub Action
On Tuesday, 8 June 2021 at 20:39:45 UTC, Steven Schveighoffer wrote: I might have a need for it. When I moved mysql-native to github actions, I could no longer run mysql integration tests on MacOS or Windows, since there is no docker support for a mysql instance on those platforms. I can probably install mysql manually at some point, but I haven't looked into it. At least for MacOS, this sounds like a way I can run a mysql instance that the MacOS host can talk to. I don't think that would work. The VM is only running during one step. When the step is done, the VM is terminated. Also, Docker doesn't support FreeBSD or OpenBSD. I don't plan to add platforms which GitHub Actions natively support. On the other hand, it seems pretty straightforward to install MySQL natively on macOS: ``` brew install mysql brew services start mysql ``` There are also several GitHub Actions that will setup MySQL: https://github.com/marketplace?type=actions=mysql -- /Jacob Carlborg
Re: [Semi-OT] Cross-Platform GitHub Action
On Tuesday, 8 June 2021 at 19:40:01 UTC, kinke wrote: Thx for sharing! Interesting; I've recently worked on something similar, but on Linux hosts and using a kvm/qemu/libvirt stack for running CI jobs in Windows VMs. Yeah, this is running on macOS instead because the Linux and the Windows runners on GitHub actions don't support nested virtualization. The Hypervisor framework is something similar to KVM. The VM images are actually created using QEMU (on Linux hosts), because Packer doesn't have any support for Xhyve. Packer will create a qcow2 VM image. At run time, the qcow2 image will be converted to the "raw" format, which is the only format that Xhyve supports. qcow2 is used up until runtime because it natively supports compression. I do want to support other operating systems going forward, but unfortunately, it's only FreeBSD and OpenBSD that work in Xhyve. For other operating systems I will have to use QEMU. QEMU does support the Hypervisor framework as an accelerator, but I don't think it will be as fast as Xhyve. When QEMU is supported, it will hopefully be trivial to add support for non-native architectures. I've already built the OpenBSD image for ARM64. -- /Jacob Carlborg
[Semi-OT] Cross-Platform GitHub Action
# Cross-Platform GitHub Action I would like to announce the first version of a project I've been working on for a while. It's not anything D specific or implemented in D, but it can be used with D projects. This project provides a GitHub action for running GitHub Action workflows on multiple platforms. This includes platforms that GitHub Actions don't natively support. It currently supports FreeBSD and OpenBSD. https://github.com/cross-platform-actions/action ## Features Some of the features that are supported include: * Multiple operating system with one single action * Multiple versions of each operating system * Allows to use default shell or Bash shell * Low boot overhead * Fast execution Compared to [vmactions/freebsd-vm](https://github.com/vmactions/freebsd-vm), the boot time is around a fifth and the full execution time for the same job is around half of freebsd-vm. ## Usage Here's a sample workflow file which will setup a matrix resulting in two jobs. One which will run on FreeBSD 12.2 and one which runs on OpenBSD 6.8. ```yaml name: CI on: [push] jobs: test: runs-on: macos-10.15 strategy: matrix: os: - name: freebsd version: 12.2 - name: openbsd version: 6.8 steps: - uses: actions/checkout@v2 - name: Test on ${{ matrix.os.name }} uses: cross-platform-actions/action@v0.0.1 env: MY_ENV1: MY_VALUE1 MY_ENV2: MY_VALUE2 with: environment_variables: MY_ENV1 MY_ENV2 operating_system: ${{ matrix.os.name }} version: ${{ matrix.os.version }} shell: bash run: | uname -a echo $SHELL pwd ls -lah whoami env | sort ``` I've been using this action for one of my own projects ([DLP](https://github.com/jacob-carlborg/dlp/runs/2759807903)) for now close to a week and it works fine. It's mostly FreeBSD that has been tested. If you're interested in how the sausage is made, read on. Also see the readmes of the builder repositories: https://github.com/cross-platform-actions/freebsd-builder https://github.com/cross-platform-actions/openbsd-builder ## Under the Hood GitHub Actions currently only support the following platforms: macOS, Linux and Windows. To be able to run other platforms, this GitHub action runs the commands inside a virtual machine (VM). macOS is used as the host platform because it supports nested virtualization. The VMs run on the [xhyve][xhyve] hypervisor, which is built on top of Apple's [Hypervisor][hypervisor_framework] framework. The Hypervisor framework allows to implement hypervisors with support for hardware acceleration without the need for kernel extensions. xhyve is a lightweight hypervisor that boots the guest operating systems quickly and requires no dependencies outside of what's provided by the system. The VM images running inside the hypervisor are built using [Packer][packer]. It's a tool for automatically creating VM images, installing the guest operating system and doing any final provisioning. The GitHub action uses SSH to communicate and execute commands inside the VM. It uses [rsync][rsync] to share files between the guest VM and the host. xhyve does not have any native support for sharing files. To authenticate the SSH connection a unique key pair is used. This pair is generated each time the action is run. The public key is added to the VM image and the private key is stored on the host. Since xhyve does not support file sharing, a secondar hard drive, which is backed by a file, is created. The public key is stored on this hard drive, which is then mounted by the VM. At boot time, the secondary hard drive will be identified and the public key will be copied to the appropriate location. To reduce the time it takes for the GitHub action to start executing the commands specified by the user, it aims to boot the guest operating systems as fast as possible. This is achieved in a couple of ways: * By downloading [resources][resources], like xhyve and a few other tools, instead of installing them through a package manager * No compression is used for the resources that are downloaded. The size is small enough anyway and it's faster to download the uncompressed data than it is to download compressed data and then uncompress it. * It leverages `async`/`await` to perform tasks asynchronously. Like downloading the VM image and other resources at the same time * It performs as much as possible of the setup ahead of time when the VM image is provisioned [xhyve]: https://github.com/machyve/xhyve [hypervisor_framework]: https://developer.apple.com/library/mac/documentation/DriversKernelHardware/Reference/Hypervisor/index.html [rsync]: https://en.wikipedia.org/wiki/Rsync [resources]: https://github.com/cross-platform-actions/resources [packer]:
Re: (Oh My) Gentool 0.3.0 released
On 2021-05-05 13:54, user1234 wrote: Thanks for the explanations. BTW I had the same question for LDC backend being c++, I guess the answer would be similar. If I understand correctly, the Zig compiler is implemented partially in Zig. It use the LLVM C API and some wrappers C around the C++ API where the C API is not sufficient. -- /Jacob Carlborg
Re: (Oh My) Gentool 0.3.0 released
On 2021-05-05 12:01, user1234 wrote: Is it possible to use libclang and more generally LLVM c++ api [directly in D](https://dlang.org/spec/cpp_interface.html) or the Cpp interface is too limited ? Was this an option, have you tried ? Yes, it's possible to use libclang. DStep [1] is using that and it fully written in D. Although DStep cannot create bindings for C++ yet so I cannot guarantee that using only libclang will work for C++ code. [1] https://github.com/jacob-carlborg/dstep -- /Jacob Carlborg
Re: Cross-compiler targeting macOS
On 2021-04-10 15:50, kinke wrote: Thanks Jacob, I'm sure this was quite a bit of work, and opening up proprietary SDKs for non-native systems is always welcome. Thumbs up! Thanks. -- /Jacob Carlborg
Re: KQueue and Fibers
On 2021-04-09 11:00, rashir wrote: Goodmorning everyone, I'm trying to understand both Kqueue and Fiber's operation on Mac. Why don't I get the correct data as long as I read from the socket? It seems to be reading too early, but Kquue tells me that the socket is readable. ```D const bytesRead = recv(fd, b.ptr, readableAmount < b.length ? readableAmount : b.length, 0); writeln("read bytesRead: ", bytesRead, "readableAmount:", readableAmount, " errno:", errno); assert(bytesRead != EAGAIN && bytesRead != EWOULDBLOCK); ``` `recv` returns the number of bytes received or `-1` if an error occurred. `EAGAIN` and `EWOULDBLOCK` are error codes. You should not compare the value returned by `recv` with error codes. The error code will be placed in `errno`. ```D assert(eventList[0].filter & EVFILT_READ); ``` The `filter` field of an event is not a flag/bit field. It's just a plain value, you should use `==` to check if it's a read event. I'm not sure if fixing these things will solve your issue. But at least some problems I noticed. -- /Jacob Carlborg
Re: Cross-compiler targeting macOS
On 2021-04-08 18:36, H. S. Teoh wrote: Thanks for this, it is very helpful. You're welcome. I'm glad that it's useful to someone. I just created a tag [1] (no changes yet), if I would like to make some changes in the future. [1] https://github.com/d-cross-compiler/docker-ldc-darwin/tree/v0.0.1 -- /Jacob Carlborg
Cross-compiler targeting macOS
# Docker LDC Darwin I would like to announce a new project I'm working on: docker-ldc-darwin [1]. The project consists of a Dockerfile for building a Docker image which has all the necessary tools to cross-compile D applications targeting macOS x86-64. ## Features * Uses Apple's ld64 linker so all features that are being used when linking on macOS should work. No reliance on custom linkers that need to be kept up to date with the system linker * Ships with the full macOS SDK (for macOS version 10.15.4) * No reliance on hacks like allowing undefined symbols when linking like Zig and Rust does * Minimal Docker image. Only the exact files that are required to run the compiler and linker are included. Not even a shell is included * The Docker image, all tools and resources are fully reproducible and automated. No manual steps involved of uploading to random cloud storage accounts The following tools are included: * dub * ldc2 * ldmd2 * rdmd * ld64 (linker) * clang (C compiler, used for linking) ## Building ### Prerequisites * [git](https://git-scm.com) * [Docker](https://www.docker.com) ### Building the Docker Image Follow the steps below to build the Docker images by running the commands in the terminal: 1. Clone the git repository: ``` git clone https://github.com/d-cross-compiler/docker-ldc-darwin && cd docker-ldc-darwin ``` 1. Build the Docker image: ``` docker build -t ldc-x86_64-apple-macos . ``` ## Usage By default, the `ldc2` compiler will be invoked. ### Compiling Hello World Compile Hello World: ``` $ uname Darwin $ cat < main.d import std; void main() { writeln("Hello World"); } EOF $ docker run --rm -v "$(pwd):/work" ldc-x86_64-apple-macos main.d $ ./main Hello World ``` For more information and examples, see the readme [1]. [1] https://github.com/d-cross-compiler/docker-ldc-darwin -- /Jacob Carlborg
Re: Gui toolkits alive and gui toolkits dead
On 2021-04-06 21:57, Alain De Vos wrote: Can we say tk ang gtk toolkits are alive. But wxwidgets , fox an fltk are dead ? Do you mean these libraries in general or D bindings to these libraries? -- /Jacob Carlborg
Re: Contributing CDF bindings to Deimos
On 2021-03-25 05:00, Chris Piker wrote: 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. There's a general convention to name the top level module or package the same as the project. To avoid causing conflict with other projects. I see that you have used DStep to create the bindings. I also see that you had to make some changes to the output. Please report any issues or enhancement requests to [1]. I you need any DStep specific help or have any questions, please ask here in the learn forum or on the DStep specific discussions section (which I just enabled) on GitHub [2]. I'll do my best to help you. [1] https://github.com/jacob-carlborg/dstep [2] https://github.com/jacob-carlborg/dstep/discussions -- /Jacob Carlborg
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Wednesday, 17 March 2021 at 15:16:36 UTC, Jacob Carlborg wrote: macOS doesn't support static linking. The proper way to solve this is to bundle the dynamic libraries with the application. If it's a GUI application it can be located in the application bundle. It seems like David already figured this out [1]. [1] https://forum.dlang.org/post/wsvlwdgzswxprtfjz...@forum.dlang.org -- /Jacob Carlborg
Re: Is it possible to suppress standard lib and dlang symbols in dylib (macos)
On Wednesday, 17 March 2021 at 13:52:48 UTC, Guillaume Piolat wrote: On Sunday, 14 March 2021 at 11:33:00 UTC, David wrote: Anyone else done this? Pointers welcome. Sorry for delay. Just add "dflags-osx-ldc": ["-static"], macOS doesn't support static linking. -- /Jacob Carlborg
Re: lockstep works with .each, but fails with .map
On 2021-03-05 19:49, realhet wrote: Why it works with each (or foreach), but not with map? o.O `lockstep` is specifically designed to work with `foreach`. I think `each` has a special case to work with `lockstep`. If you want to use other range functions, you should use `zip` instead of `lockstep`. -- /Jacob Carlborg
Re: ldc on a raspberry pi 3 running freebsd
On 2021-02-23 16:34, Decabytes wrote: ldc2 is the winner thank you! I'd like to get gdc and dmd up and running to at some point Unfortunately, DMD doesn't support ARM. -- /Jacob Carlborg
Re: utiliD: A library with absolutely no dependencies for bare-metal programming and bootstrapping other D libraries
On 2021-02-24 17:32, Imperatorn wrote: What happened to utiliD? Broken link to gh I think Mike gave up on D. -- /Jacob Carlborg
Re: How can I get this UDA at compile time?
On 2021-02-21 07:12, Jack wrote: I've had a struct like this: struct Attr { string value; } struct Foo { @(Attr("a attr")) enum a = Foo(10); @(Attr("b attr")) enum b = Foo(11); int x; int y; bool doY = true; int value() { return x; } } I'd like to get that atrribute's value at compile time, something like this: enum s = Foo.a.baa; enum s2 = Foo.b.baa; writeln(s); // a attr writeln(s2); // b attr I did this: string baa() { import std.traits : getUDAs, hasUDA; static foreach(field; __traits(allMembers, Foo)) {{ alias m = __traits(getMember, Foo, field); static if(is(typeof(m) == Foo)) { if(m.value == this.value) return getUDAs!(m, Attr)[0].value; } }} return null; } that was working fine, but I needed to switch value property from Foo struct, so that I can't read this value at CTFE anymore, so this fails now: if(m.value == this.value) return getUDAs!(m, Attr)[0].value; How can I solve this? You can't look at the value when trying to find the correct member. You need to look at the name. I don't think it's possible to solve that with the exact same API as you have used above. The simplest solution would be to just use `__traits(getAttributes)` and wrap that in a help function: string getAttribute(T, string name)() { return __traits(getAttributes, mixin(T.stringof, ".", name))[0].value; } void main() { writeln(getAttribute!(Foo, "a")); } Or you can create a proxy struct and use opDispatch like this, to get something a bit closer to your original example: // add this to the Foo struct static Proxy attributes() { return Proxy(); } struct Proxy { string opDispatch(string name)() { return __traits(getAttributes, mixin("Foo.", name))[0].value; } } void main() { writeln(Foo.attributes.a); } -- /Jacob Carlborg
Re: Windows Bindings v1.1
On 2021-02-20 15:03, Rumbu wrote: - new attributes (currently ignored): RetVal, NullNullTerminated, NotNullTerminated Regarding the ignored attributes. You could always output these as UDAs. It would not add any semantic meaning, but could serve as documentation. In theory, it would be possible to create a separate tool that will perform some semantic checks on these UDAs. -- /Jacob Carlborg
Re: Type of string literal concatenated with non-immutable char array
On Sunday, 31 January 2021 at 21:48:09 UTC, Per Nordlöw wrote: Given char x[]; why is typeof("a" ~ x) `char[]` when typeof("a" ~ x.idup) is `string`? My case is class NameLookupException : Exception { this(string name) { super("Name " ~ name ~ " could not be found"); } this(scope const(char)[] name) { super("Name " ~ name.idup ~ " could not be found"); } } where I instead would like to only need class NameLookupException : Exception { this(scope const(char)[] name) { super("Name " ~ name ~ " could not be found"); } } Why isn't "Name " ~ name ~ " could not be found" implicitly convertible to `string`? Because if you have arrays of reference types, it's possible to change an element of the mutable array, which will affect the immutable array, those breaking the immutability. Example: class Foo { int a; } void main() { Foo[] a = [new Foo]; immutable(Foo)[] b = [new Foo]; // `string` is an alias for `immutable(char)[]` auto c = b ~ a; a[0].a = 3; assert(c[1].a == 3); } Due to language consistency it should behave the same for all types. In the above example, `c` is typed as `const(Foo)[]`. Although, I wonder why in your example the concatenation is typed as `char[]` instead of `const(char)[]`. Perhaps that's a bug. -- /Jacob Carlborg
Re: Why are multiple instances of the single enum created?
On Monday, 1 February 2021 at 09:40:20 UTC, Per Nordlöw wrote: An enum only exists at compile-time, and does not occupy any space. Each time it's referenced, a new instance of the value is created. Why is that? Seems like a waste of resources to the compiler. It makes perfect sense for numeric values, strings, characters and similar values. Why waste extra space on a variable if it's not needed? If you don't want a new instance, then don't use `enum`. Use `immutable` instead. -- /Jacob Carlborg
Re: Article: Why I use the D programming language for scripting
On Sunday, 31 January 2021 at 20:36:43 UTC, aberba wrote: It's finally out! https://opensource.com/article/21/1/d-scripting FYI, the code will compile faster if you use `dmd -run` instead of `rdmd`. If you have multiple files that need to be compiled you can use `dmd -i -run`. -- /Jacob Carlborg
Re: std.expreimantal.allocator deallocate
On Sunday, 24 January 2021 at 11:00:17 UTC, vitamin wrote: void destruct(Base base){ void[] x = (cast(void*)base)[0 .. __traits(classInstanceSize, Base)]; writeln("deallocate: ", x.length); theAllocator.deallocate(x); } You can get the dynamic size of an object using `typeid(base).initializer.length`. Base base = new Derived; assert(__traits(classInstanceSize, Derived) == typeid(base).initializer.length); -- /Jacob Carlborg
Re: Current state of DWT
On 2021-01-24 04:50, mori wrote: I feel as if I came across rather... pessimistic. I do want to help. Awesome :) Yesterday I spent some time trying to port the (cocoa) Program class to D using `extern (Objective-C)`. What I've got works, but the main difference (as you'd probably know) is that Java the Objective-C lib itself (i.e. ) which allows them to create instances with `new`. This (seemingly) isn't possible with `extern (Objective-C)` classes. Yes, that's correct. The way Eclipse has created the Objective-C bindings is to wrap all Objective-C classes in Java classes. That means that for each Objective-C object there will also be a Java object. This is to create friendlier API. But in D, since there's direct language support for using Objective-C classes, that's not necessary. There will only be an Objective-C object. Instead of Java code looking like this: NSAlert alert = (NSAlert) new NSAlert().alloc().init(); The D code will look just like this: NSAlert alert = NSAlert.alloc().init(); I'll use that code as a base, but did you want to stick to using the `objc_msgSend` style code or `extern (Objective-C)`? It's better to use the `extern (Objective-C)` style. This will result in the code looking slightly less like the Java code, but it will be more correct. Also (this applies to Gtk as well), did you want me to send pull requests against the main DWT repository, or the individual repositories? I guess you have already figured this out, but the org.eclipse.swt.win32.win32.x86, org.eclipse.swt.snippets and org.eclipse.swt.gtk.linux.x86 repositories have been merged into the dwt repository. As for the Cocoa port. It depends on what approach you want to take. Finish the existing port in D1 or start fresh and incrementally porting 4.7.3. For the one doing the code reviews, it's much easier if the diffs are smaller. Haven't run into this issue myself yet, but will keep it mind. As soon as some methods return NSRect you'll run into this. A workaround is to manually call the Objective-C runtime function `objc_msgSend_stret`. Also, keep in mind that `float` and `double` are initialized to 0.0 by default in Java, while in D they're initialized to NaN. I mentioned why I chose 4.7.3 in the pull request, but there is also the benefit that doesn't depend on `gnomeui` and `gnomevfs` which aren't available in some package repositories now. (Mainly Debian based it seems.) Since you're the one doing the work and if 4.7.3 is fine with you, then that's great. I don't imagine there are any broken APIs in the win32 version (Microsoft is good with backwards compatibility after all), just not sure on the Cocoa side. Apple has a tendency to, not necessarily break APIs but change things that might cause problems. Especially if applications are not implemented the way that Apple thinks they should be implemented. Like dark mode. They do deprecate APIs as well. -- /Jacob Carlborg
Re: Current state of DWT
On 2021-01-19 05:51, mori wrote: Sorry for the late reply. I keep forgetting to check this forum. There's usually not much activity here. Initially I'll try converting the manually so I can understand the internals a little (also don't know any Scala...). I didn't know any Scala before I started with JPort either. That didn't stop me. I picked Scala because JDT (Java the compiler library) I'm using is written in Java and I didn't want to write the tool in Java. In hindsight it might have been better to pick Java. Because, when the tool is ready you can automatically port SWT to D. But also, hopefully, port JDT and the tool itself to D :). Then we would both a have a tool that translates Java to D code and a Java compiler written in D. But now we would need to port the tool manually from Scala to D. The benefit of completing JPort is apparent though, so perhaps in the future. That would be nice. All contributions are welcome. IIRC correctly, translating of the syntax is done. Now it's the big part left, the semantic translations. Understandable. However, this begs the question, is it worth it? I don't know. It's up to you if you want to help. I'm just happy to get any help I can. As mentioned, I'm happy to work on the Gtk side, but there isn't much merit in a "cross-platform" Toolkit which only supports one platform. Hehe, yeah. I do have an old Macbook Air (currently on 10.15 can be updated though), however, I'm a little uncertain on the current status of `extern (Objective-C)` (e.g. could a full binding for Cocoa be done?). If it is possible, then I may be able to tinker away at that once the Gtk version is a bit more updated. Yeah, that's the embarrassing thing. macOS is my main platform, I've implemented the support for `extern (Objective-C)` and native TLS on macOS, but there's no macOS port of DWT. I've started on a port many years ago [1]. It's still written in D1. The plan was to complete the port in D1 before translating it to D2 (there's some info in the readme). This is way before the support for `extern (Objective-C)`, which is only in D2. When it comes to the status of the Objective-C integration. The last release of DMD (2.095.0) added support for interfacing with Objective-C protocols. This is, more or less, the final piece to be able to properly use the Objective-C APIs. There are a few problems though, which there are some workarounds for: * There's a bug in the code that DMD geberates, where compiled executable code segfaults for any method that returns a struct that is too large to fit in registers. On x86-64, this is 16 bytes, IIRC. This is the most severe problem. * LDC has not kept up to date with the Objective-C integration, it only supports the first iteration that DMD implemented. That is, support for instance methods. Of course, LDC doesn't have the above bug :) * There's no language support for blocks. I'm not sure if SWT uses any APIs which require blocks. It's possible to implement block support in library code [2] * In Objective-C there's both a class and a protocol (interface) which is named NSObject. This is not possible in D. We need language support to change the name which is output in the binary (something like `pragma(mangle)`. A workaround is to add the methods which are declared in the protocol to the class instead. Or/and any protocols that inherits form the NSObject protocol and not include the NSObject protocol at all. Anyway, I might still send some pull requests for Gtk, but what version of SWT should be aimed for? That's a good question. It's probably easier to do incremental updates, i.e. pick some old version which is newer then DWT. [1] https://github.com/d-widget-toolkit/dwt-mac [2] https://github.com/dlang/druntime/pull/1582/files#diff-0b75a0e079a2a997c1c32e5da529db020232a8d4e7686591d0c710085c4e26d3 -- /Jacob Carlborg
Re: Current state of DWT
On 2021-01-18 07:22, Imperatorn wrote: Ok, thanks for your efforts. I'm just wondering what the "official" ui framework is considered to be, looking around At one point DWT was named to be the official GUI framework for D :). Of course, that didn't mean anything. No additonal contributors, fundings or similar. -- /Jacob Carlborg
Re: Current state of DWT
On 2021-01-18 01:11, mori wrote: Given this, would it be correct to assume that you're not accepting pull requests that would update DWT? Only asking because I'd be willing to help update the GNU/Linux side. No, I will definitely accept pull requests. It's mostly that I don't have much time available and I think it's too tiresome to manually update. I've started a project to automatically translate Java code to D code [1] to be able to automatically update DWT. But again, due to time constraints I've not been able to work on that project for a while. Although, I'm not sure how to best handle this if only Linux is going to be updated. [1] https://github.com/d-widget-toolkit/jport -- /Jacob Carlborg
Re: Current state of DWT
On 2021-01-13 11:50, Imperatorn wrote: What's the current state of dwt and where can I find some toturials and/or example applications? The current state is that is in maintenance mode. I'm only make sure it works on the latest version of DMD. It does not receive any other form of updates. When it comes to tutorials, you can use the same tutorials for SWT [1]. DWT is a port of SWT to D. There's also a bunch of snippets available here [2]. [1] https://www.eclipse.org/swt/ [2] https://github.com/d-widget-toolkit/dwt/tree/master/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets -- /Jacob Carlborg
Re: Printing shortest decimal form of floating point number with Mir
On 2021-01-06 03:30, Walter Bright wrote: The baseline Linux target does not have SSE. What about this changelog entry: https://dlang.org/changelog/2.087.0.html#xmm-linux-changelog ? -- /Jacob Carlborg
Re: [Understanding] Classes and delegate inheritance vs function pointers
On 2021-01-09 19:16, Q. Schroll wrote: Say I have a class hierarchy like this: class Base { } class Derived : Base { } A Derived object cannot be referenced as a Base object, but as a const(Base) object. That makes sense to me. It can: Base b = new Derived(); One can replace Base by a @system delegate type (SysDG) and Derived by a @safe delegate type (SafeDG) and it works the same way: a SafeDG object cannot be referenced as a SysDG object, but as a const(SysDG) object. However, if I try that with function pointers instead of delegates (SysFP, SafeFP), for some reason, a SafeFP cannot be referenced as a const(SysFP). This makes no sense in my head. Is there some reason I'm unable to see? Example code is here: https://run.dlang.io/is/zSNArx Is there a reason all you're examples are using pointers? Classes are already reference types, delegates are kind of like reference types. They consist of a context pointer and a function pointer. Function pointer are, as the name suggest, already pointers. -- /Jacob Carlborg
Re: DConf talk : Exceptions will disappear in the future?
On 2021-01-07 01:01, sighoya wrote: Thanks, reminds on swift error types which are enum cases. Swift can throw anything that implements the Error protocol. Classes, structs and enums can implement protocols. Oh, no please not. Interestingly we don't use longjmp in default exception handling, but that would be a good alternative to Herb Sutter’s proposal Some platforms implement C++ exception using longjmp, for example, iOS. because exceptions are likewise faster, but have likewise an impact on normal running code in case a new landing pad have to be registered. But interestingly, the occurrence of this is much more seldom than checking the return value after each function. It's claimed that exceptions are not zero cost, even when an exception is not thrown. Because the compiler cannot optimize functions that may throw as well as those that cannot throw. -- /Jacob Carlborg
Re: DConf talk : Exceptions will disappear in the future?
On 2021-01-06 22:27, H. S. Teoh wrote: That's the whole point of Sutter's proposal: they are all unified with the universal Error struct. There is only one "backend": normal function return values, augmented as a tagged union to distinguish between normal return and error return. We are throwing out nonlocal jumps in favor of normal function return mechanisms. We are throwing out libunwind and all the heavy machinery it entails. This is not what Sutter is proposing. He's proposing to add a new "backend", so you end up with three different types of functions (when it comes to error handling): * Functions annotated with `throws`. This is the new "backend": void foo() throws; * Functions annotated with `noexcept`. This indicates a function will not throw an exception (of the existing style): void foo() noexcept; * Functions without annotation. This indicates a function that may or may not throw an exception (of the existing style): void foo(); From the proposal, paragraph 4.1.7: "Compatibility: Dynamic exceptions and conditional noexcept still work. You can call a function that throws a dynamic exception from one that throws a static exception (and vice versa); each is translated to the other automatically by default or you can do it explicitly if you prefer." But perhaps you're proposing something different for D? -- /Jacob Carlborg
Re: Discussion Thread: DIP 1039--Static Arrays with Inferred Length--Community Review Round 1
On 2021-01-06 10:21, Mike Parker wrote: This is the discussion thread for the first round of Community Review of DIP 1039, "Static Arrays with Inferred Length": https://github.com/dlang/DIPs/blob/c06ce7f144b3dabf363d1896ddcd31a2a6b7c969/DIPs/DIP1039.md There's `staticArray` to solve this issue [1]. [1] https://dlang.org/phobos/std_array.html#.staticArray -- /Jacob Carlborg
Re: dmd 2.093.1: duplicate method definitions ignored altogether
On 2021-01-05 03:02, kdevel wrote: expected output: none. The compiler should have rejected the code after the duplicate definition def #2. dmd 2.093.1 ignores both definitions instead. Is this a bug or a bug? DMD 2.095.0 now reports an error for this. -- /Jacob Carlborg
Re: Printing shortest decimal form of floating point number with Mir
On 2021-01-06 03:30, Walter Bright wrote: The baseline Linux target does not have SSE. Other compilers solve this by having a flag to specify the minimum target CPU. -- /Jacob Carlborg
Re: I'm creating a game purely written in D with the arsd library
On 2021-01-02 22:21, H. S. Teoh wrote: Nope. Reverse-engineering is a thing. There's even tools out there to automate this stuff. Or you can try to prevent reverse engineering. This is both an interesting and fun talk [1]. [1] https://www.youtube.com/watch?v=HlUe0TUHOIc -- /Jacob Carlborg
Re: How to store a pointer to class contructor
On Thursday, 24 December 2020 at 10:23:09 UTC, Dmitriy Asondo wrote: I expect code like this: -- class OloloService {} class BlablaService {} auto servicesList = [OloloService, BlablaService]; auto serviceInstance = new servicesList[1](args); -- Here's a slightly different version that I think is closer to your original example: import std; interface Service {} mixin template Constructor() { this(int a) { } } class OloloService : Service { mixin Constructor; } class BlablaService : Service { mixin Constructor; } Service function(int) create(T)() { return a => new T(a); } void main() { auto servicesList = [create!OloloService, create!BlablaService]; auto serviceInstance = servicesList[1](3); writeln(serviceInstance); } Since D is a statically typed language you need a form of base type if you want to store a list of values of different types. In this case, the base type is `Service`. If you want to have a constructor, as you do in your original example, the constructor needs to have the same signature for all types, the mixin template helps with that. You can use a tuple as well to store different values of different types. But then everything need to be known at compile time. That is, the index, in your case. -- /Jacob Carlborg
Re: DLP - D Language Processing 0.3.0 - infer attributes
On 2020-12-19 00:26, Dave P. wrote: Looks very useful. Something strange I noticed though, it seems to be doing the analysis in 32 bits? I had some static assertions go off due to this which halted the program. Wow, I haven't noticed that. That's not indented. I've created an issue [1] and I'll take a look at it. [1] https://github.com/jacob-carlborg/dlp/issues/7 -- /Jacob Carlborg
DLP - D Language Processing 0.3.0 - infer attributes
I would like to announce a new release of DLP, 0.3.0. For those not familiar with DLP, it's a tool collecting commands/tasks related to processing the D programming language. It uses the DMD frontend as a library to process D code. The major new feature in this release a new command that has been added: `infer-attributes`. This command will print the inferred attributes of all functions that are normally not inferred by the compiler. These are regular functions and methods. Templates, nested functions and lambdas are inferred by the compiler and will not be included by this command. By default, virtual methods are not inferred. Use the flag `--include-virtual-methods` to enable inferring of virtual methods. The attribute inference is enabled only on the file that is currently being processed. This is to avoid the tool outputting attributes that would not be valid unless other files are modified. For example, your code is calling a third-party function. The third-party function is inferred to be `pure`. Now your function is inferred to be `pure` as well. But if you only change your function to be `pure`, it will fail to compile because the third-party function has not been updated. The intention of this command is to help you in adding attributes to your code. You don't have to figure out exactly which attributes you can add to a function, just have the compiler tell you instead. It's recommend to run DLP in an iterative process. Run it on a file, update the file with the new attributes, run it again and repeat the process until the tool doesn't output any more inferred attributes. The release is available here [1]. Pre-compiled binaries are available for macOS, FreeBSD and Linux 64bit and Windows 32bit and 64bit. For the full change log, see [1]. [1] https://github.com/jacob-carlborg/dlp/releases/tag/v0.3.0 -- /Jacob Carlborg
Re: extern(C) and name mangling
On 2020-12-16 16:18, Dave P. wrote: Is this a bug in the spec or in the implementation? Yeah, that's a good question. That's always problematic with D. The spec is incomplete. How do we get this fixed? The simplest would be to change the spec. -- /Jacob Carlborg
Re: extern(C) and name mangling
On Wednesday, 16 December 2020 at 04:17:13 UTC, Mike Parker wrote: So what you're asking for is a way to retain the D name mangling on an extern C function. The way to do that is with `pragma(mangle, "new_name")`. To match the original D function mangling, declare the function first without extern(C) and print `func.mangleof`. Use that as the parameter to pragma(mangle). I can't imagine any benefit you'd get from doing that, though. I actually had a use case for this. An initialization function that is called by the C runtime, i.e. `pragma(crt_constructor)`. That function needs to have C calling convention. But to avoid any conflicts with other `extern(C)` functions I wanted to keep the D mangling. https://github.com/dlang/druntime/blob/master/src/core/memory.d#L212-L232 -- /Jacob Carlborg
Re: extern(C) and name mangling
On Wednesday, 16 December 2020 at 04:17:13 UTC, Mike Parker wrote: However, the D calling convention is defined to be identical to the C calling convention on the host system for everything except Windows x86. Also keep in mind that D supports other types than C does, like D arrays and delegates. In those cases the D calling convention needs to be extended since there's no way to just relay on the C calling convention. One could think it would be possible to passes D arrays and delegates as structs, but that's not how DMD passes them. On some platforms it matches how a struct is passed, on some it doesn't. -- /Jacob Carlborg
Re: extern(C) and name mangling
On Wednesday, 16 December 2020 at 04:17:13 UTC, Mike Parker wrote: However, the D calling convention is defined to be identical to the C calling convention on the host system for everything except Windows x86. That's what's specified, but that's not how DMD actually behaves. DMD passes the arguments in reverse order. That's easily observable by calling a C function with D linkage: $ cat foo.c #include void foo(int a, int b) { printf("a=%d b=%d\n", a, b); } $ cat main.d module main; import std; pragma(mangle, "foo") // override D mangling to get the same name as the C function void foo(int a, int b); // D calling convention void main() { foo(1, 2); } $ clang -o foo.o foo.c -c $ dmd main.d foo.o $ ./main a=2 b=1 LDC behaves the same way as DMD and, IIRC, GDC follows how GCC passes the arguments. -- /Jacob Carlborg
Re: Httparsed - fast native dlang HTTP 1.x message header parser
On 2020-12-14 22:59, tchaloupka wrote: Hi, I was missing some commonly usable HTTP parser on code.dlang.org and after some research and work I've published httparsed[1]. This is awesome. I wanted to use picohttpparser myself and used the C version. But if you already have created a HTTP parser with the same properties in D, that's even better. -- /Jacob Carlborg
Re: Hex constant method starts from ".a": 0xCCCCCC.argb
On Monday, 14 December 2020 at 05:51:28 UTC, Виталий Фадеев wrote: It's parsing the `.a` in `.argb` as part of the number: auto color = 0x00AABBCC.a rgb; // what the compiler sees You can fix it with parentheses: auto color = (0x00AABBCC).argb; Thanks! It is not perfect, but also beauty! Or you can call it `rgba`. It seems to be what Wikipedia prefers [1]. [1] https://en.wikipedia.org/wiki/RGBA_color_model -- /Jacob Carlborg
Re: Request assistance initializing struct instance at global scope
On Tuesday, 8 December 2020 at 01:47:51 UTC, Andrew Edwards wrote: Thanks Jacob. The extern(C) is temporary. I'm doing a direct port of the code to D using -betterC. Wanted to keep it as close to the original as possible until everything compiles. Yes, that's always a good idea. Do the initial port as close as possible to the original code. Then refactor and start adding D specific features. I noticed that static this() does not work if either it or main() (or both) is marked extern(C). Yes, that's expected. If you have a regular D main function, the compiler will recognize that and output an undefined symbol to the C main function. The C main function is implemented in the D runtime. The C runtime will call the C main function in the D runtime. The C main function is responsible for initializing the D runtime. This includes (not a complete list): * Converting the arguments passed to the C main function to `string[]` * Initializing the garbage collector * Calling `shared static this()` in all modules * Calling `static this()` in all modules * Running the any unit tests * Finally calling the D main function When you define a C main function the compiler will recognize that and not output an undefined symbol. That means the C main function in the D runtime will never be called. That means the D runtime is never initialized. This is to allow you to use D without its runtime or get more control of the startup phase. So either either you define a D main function and everything works as expected or you define a C main function and then you need to manually initialize and deinitialize the D runtime, if you want to use it. This can be done with [1] and [2]. [1] https://dlang.org/phobos/core_runtime.html#.rt_init [2] https://dlang.org/phobos/core_runtime.html#.rt_term -- /Jacob Carlborg
Re: Request assistance initializing struct instance at global scope
On Monday, 7 December 2020 at 04:13:16 UTC, Andrew Edwards wrote: Given: === extern(C): char*[] hldr; enum I = (1<<0); struct S { char* ft; char** fm; int f; } void main(){} === // Error Deprecation: static constructor can only be of D linkage S[] s; static this() { s = [ S(cast(char*)"c", [0], I) ]; } This is the correct way to do it. The problem is that you have added `extern(C):` at the top. This means that ever symbol below will have C linkage. As the error message says, `static this` can only have D linkage. `static this` is transformed into a function which is automatically called by the runtime. When you add `extern(C):` at the top, this function will also get the C linkage. A simple way to make sure that there are not multiple C functions with the same name (caused by multiple `static this`, in the same file or another file) is to mangle the function name the same way as a D function. You can either use `extern(C) char*[] hldr` to make only `hldr` have C linkage. Use `extern(C) {}` to group several symbols which should have C linkage or rearrange the code so that `static this` is above `extern(C):`. -- /Jacob Carlborg
Re: Ways to parse D code.
On 2020-11-25 17:27, Jan Hönig wrote: dmd has to do it somewhere as well. Although I don't know exactly where. I do know ldc uses dmd's frontend for parsing. https://dlang.org/phobos/dmd_parse.html Using DMD as a library will be most accurate and up to date. Because it's the same code as the compiler is using. Here's an example on how to use DMD to parse some code [1]. Here's some more advance usages [2]. [1] https://github.com/dlang/dmd/blob/b35572b07a6994385b6459a430674d32e9a97279/test/dub_package/frontend.d#L10-L24 [2] https://github.com/jacob-carlborg/dlp/blob/master/source/dlp/commands/infer_attributes.d#L61 -- /Jacob Carlborg
Re: How can I convert Hexadecimal to RGB Color and vice-versa?
On Friday, 16 October 2020 at 20:10:58 UTC, Marcone wrote: How can I convert Hexadecimal to RGB Color and vice-versa? Not sure if this is what you're looking for: struct Color { private uint hex; int red() out(result; result >= 0 && result <= 255) // assert that the result is within bounds { return (hex & 0xFF) >> 16; } void red(int value) in(value >= 0 && value <= 255) // assert that the value is within bounds { hex = (hex & 0x00) | (value << 16); } int green() out(result; result >= 0 && result <= 255) // assert that the result is within bounds { return (hex & 0x00FF00) >> 8; } void green(int value) in(value >= 0 && value <= 255) // assert that the value is within bounds { hex = (hex & 0xFF00FF) | (value << 8); } int blue() out(result; result >= 0 && result <= 255) // assert that the result is within bounds { return hex & 0xFF; } void blue(int value) in(value >= 0 && value <= 255) // assert that the value is within bounds { hex = (hex & 0x00) | value; } string toString() { return format!"Color(red: %s, green: %s, blue: %s)"(red, green, blue); } } void main() { Color color; color.red = 255; color.green = 143; color.blue = 89; writeln(color); } -- /Jacob Carlborg
Re: Preparing for Google Summer of Code 2021
On Monday, 23 November 2020 at 13:34:14 UTC, Petar Kirov [ZombineDev] wrote: Thanks, I've just added the gsoc2020 label for these issues. I will ping someone to give you permissions for the repo ;) Shouldn't it be gsoc2021? We're already past GSoC 2020 ;) -- /Jacob Carlborg
Re: betterC question
On Thursday, 19 November 2020 at 00:20:50 UTC, Dibyendu Majumdar wrote: On Thursday, 19 November 2020 at 00:18:54 UTC, rikki cattermole You don't need the brackets to call a function (and with a little help from UFCS): void main() { import std.stdio; "Hello!".writeln; writeln; } Okay thanks. Bad idea IMO. Yes, calling `writeln` like that is a bad idea. That was a bad example. But the actual reason is, this is how D implements properties [1]. Any function that doesn't take an argument can be called without parentheses. Any function which takes a single argument can be called like setting a field. Here's an example: struct Color { private uint hex; int red() out(result; result >= 0 && result <= 255) // assert that the result is within bounds { return (hex & 0xFF) >> 16; } void red(int value) in(value >= 0 && value <= 255) // assert that the value is within bounds { hex = (hex & 0x00) | (value << 16); } // similar functions for green and blue } void main() { Color color; color.red = 255; assert(color.red == 255); } [1] https://en.wikipedia.org/wiki/Property_(programming) -- /Jacob Carlborg
Re: question as to when a new command gets executed
On 2020-11-11 06:29, WhatMeWorry wrote: Which begs the question, how would the statement, m_State = new BreakState() ever get executed? class DebuggerSession { private BreakState m_State = new BreakState(); private UnrealCallback m_UnrealCallback; this( ) { } // rest of class } It gets executed at compile time. All instances of `DebuggerSession` will share the same single instance of `BreakState`. -- /Jacob Carlborg
Re: How add class or struct member after construction?
On 2020-11-05 23:48, Marcone wrote: How add class or struct member after construction? Is it possible in D? How? It depends on what needs you have. You can declare a free function that takes the class/struct as the first parameter and call it like a method [1]: class Foo { int a; } void printA(Foo foo) { writeln(foo.a); } foo.printA(); printA(foo); The two above lines are exactly the same. [1] https://dlang.org/spec/function.html#pseudo-member -- /Jacob Carlborg
Re: DMD: invalid UTF character `\U0000d800`
On 2020-11-08 13:39, Kagamin wrote: Surrogate pairs are used in rules because java strings are utf-16 encoded, it doesn't make much sense for other encodings. D supports the UTF-16 encoding as well. The compiler doesn't accept the surrogate pairs even for UTF-16 strings. -- /Jacob Carlborg
Re: DMD: invalid UTF character `\U0000d800`
On Saturday, 7 November 2020 at 16:12:06 UTC, Per Nordlöw wrote: CtoLexer_parser.d 665 57 error invalid UTF character \Ud800 CtoLexer_parser.d 665 67 error invalid UTF character \Udbff CtoLexer_parser.d 666 28 error invalid UTF character \Ud800 CtoLexer_parser.d 666 38 error invalid UTF character \Udbff CtoLexer_parser.d 666 53 error invalid UTF character \Udc00 CtoLexer_parser.d 666 63 error invalid UTF character \Udfff Doesn't DMD support these Unicodes yet? They're not valid: "The Unicode standard permanently reserves these code point values for UTF-16 encoding of the high and low surrogates, and they will never be assigned a character, so there should be no reason to encode them. The official Unicode standard says that no UTF forms, including UTF-16, can encode these code points" [1]. "... the standard states that such arrangements should be treated as encoding errors" [1]. Perhaps they need to be combined with other code points to form a valid character. [1] https://en.wikipedia.org/wiki/UTF-16#U+D800_to_U+DFFF -- /Jacob Carlborg
Re: why `top` report is not consistent with the memory freed by core.stdc.stdlib : free?
On Friday, 6 November 2020 at 06:17:42 UTC, mw wrote: https://wiki.dlang.org/Memory_Management#Explicit_Class_Instance_Allocation using core.stdc.stdlib : malloc and free to manually manage memory, I tested two scenarios: -- malloc & free -- malloc only and I use Linux command `top` to check the memory used by the program, there is no difference in this two scenarios. I also tried to use `new` to allocate the objects, and GC.free(). The memory number reported by `top` is much less than those reported by using core.stdc.stdlib : malloc and free. I'm wondering why? shouldn't core.stdc.stdlib : malloc and free be more raw (low-level) than new & GC.free()? why `top` shows stdlib free() is not quite working? In general, any GC (not just the one in D) are not likely to give back memory to the OS. Because it's less overhead for the GC to keep the memory and reuse it. But I'm guessing `GC.free()` is supposed to give back memory to the OS, which leads into the other scenario. When it comes to maclloc/free. I would guess it's doing something similar. It probably splitting up the memory in blocks and/or pools. It might keep the memory just as the GC does for efficiency, even if `free` is called. Otherwise it would be not much point in using over the syscalls like `mmap` or `sbrk` (and whatever the corresponding calls are on Windows). -- /Jacob Carlborg
Re: Does dmd's -i "include imported modules in the compilation" switch generate object files?
On 2020-11-03 20:02, H. S. Teoh wrote: I believe -i behaves as though you manually typed the names of the source files on the command line. So it would do what the compiler would usually do in the latter case. Yes, this is correct. AFAIK, that means it loads everything into memory and produces only a single object file for the final executable. Separate compilation only happens if you invoke the compiler separately for each source file or group of source files. If the `-c` flag is passed, the compiler will produce one object file for each source file. If the `-c` flag is **not** passed, it will produce one executable and one single object file. -- /Jacob Carlborg
Re: requests 2.0.0 release
On 2020-11-01 11:13, Sönke Ludwig wrote: ddb marks the vibe-d dependency as optional, so it *should* not trigger a download by itself. It does not trigger a download. The downside is that user of the library needs to manually add vibe.d as a dependency. -- /Jacob Carlborg
Re: requests 2.0.0 release
On Thursday, 29 October 2020 at 06:42:54 UTC, ikod wrote: Hi, requests 2.0.0 released with single change - support for vibe-d moved to separate subpackage. The goal of this update is to prevent dub from downloading vibe-d packages for optional subConfiguration. Another approach is to check if vibe.d is available using version conditions [1]. This is how the DDB [2] package supports both vibe.d sockets and Phobos sockets. [1] https://github.com/pszturmaj/ddb/blob/97bc3652b05492e7917888c92e59f4576a69dfa8/source/ddb/postgres.d#L189-L216 [2] https://code.dlang.org/packages/ddb -- /Jacob Carlborg
Re: synthesising instantiated template parameters and arguments
On Wednesday, 28 October 2020 at 05:51:14 UTC, Nicholas Wilson wrote: 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? Are you looking for `TemplateArgsOf` [1] ? [1] https://dlang.org/phobos/std_traits.html#TemplateArgsOf -- /Jacob Carlborg
Re: Dynamic Template-Expansion of (Token) Strings
On Tuesday, 27 October 2020 at 08:33:08 UTC, Per Nordlöw wrote: I'm looking for elegant ways of expressing expansion of parameterized strings written to a file at run-time. My primary use case is run-time generation of D code. In the lazy case, something like import std.file : write; import std.algorithm : substitute; const s = q{int $X = $Y;}; // templated source foreach (part; s.substitute("$X", "x", "$Y", "42")) write(somePath, part); is my current best bet. You might want to have a look at Mustache [1]. Here's a Dub package [2]. [1] http://mustache.github.io/mustache.5.html [2] https://code.dlang.org/packages/mustache-d -- /Jacob Carlborg
Re: this T / variadic template and interfaces
On Tuesday, 27 October 2020 at 09:40:33 UTC, frame wrote: Hmm, a question of design. Is there also a convenient way to pass the arguments to a template or get a Variant[] from it? Convenient, no not that I know of. You can use a type safe variadic function that takes Variant, if you want to end up with Variant[] anyway. It depends on how you want the API to look like. Here are some examples: void foo(...); void bar(Variant[] args ...); foo(3, "foo", 'a'); // pass in the arguments as is bar(Variant(3), Variant("foo"), Variant('a')); // need to wrap each argument in Variant The advantage of using the type safe variadic function is that all the arguments are bundle into one array, make it easier to work with. -- /Jacob Carlborg
Re: this T / variadic template and interfaces
On Monday, 26 October 2020 at 11:14:47 UTC, frame wrote: Is there any way to get this working? I know, I could use a known object to feed the arguments and use that instead - but I want to keep things simple as possible. As Simen mentioned, templates cannot be virtual. But you don't need to use a template, you can use a regular variadic method [1]. It's a bit more clunky to work with than template variadic functions. Or if all the arguments will be of the same type, you can use type safe variadic functions [2], which are easier to work with. [1] https://dlang.org/spec/function.html#d_style_variadic_functions [2] https://dlang.org/spec/function.html#typesafe_variadic_functions -- /Jacob Carlborg
Re: Template pattern delegate?
On Monday, 26 October 2020 at 00:56:26 UTC, frame wrote: I see that your approach can handle functions and delegates but isn't that not equivalent like this template for a function? auto myStuff(T)(T function() fn) { try { return fn(); } catch (Exception e) { // } } You cannot pass a delegate to something that expects a function pointer. I wonder if I could use such a template as static variant and the compiler just expands the code? Just thinking that using a function or delegate is an overhead. Maybe not a function but a delegate will allocate GC memory I think. If you pass the delegate as a template parameter/alias parameter, it's more likely to be inlined: auto myStuff(alias fn)() { try return fn(); catch (Exception e) { } } myStuff!( { /* some code */ } ); -- /Jacob Carlborg
Re: Can we do compile time reading part of a file using import?
On Sunday, 25 October 2020 at 16:50:09 UTC, Jack wrote: Which build tool are you refering to? an existing one or build one oneself to do this job? It should work with any build tool that has hooks to execute arbitrary commands. -- /Jacob Carlborg
Re: Two ways of receiving arrays on the C ABI
On 2020-10-20 02:16, Ali Çehreli wrote: Everything works at least on Linux. Is this kosher, or am I using some internal knowledge? Yes, you're using some internal knowledge. You cannot assume it works on any other platform or architecture. In theory, the D compiler could choose to change the ABI for passing D arrays and this would break. If fact, the ABI documentation [1] doesn't mention how a D array is passed. A different compiler could choose to pass it differently. [1] https://dlang.org/spec/abi.html#arrays -- /Jacob Carlborg
Re: Can we do compile time reading part of a file using import?
On 2020-10-23 18:42, data pulverizer wrote: For me it's not make-or-break, it just something very useful and I think has clear use case. Please let me know if there are aspects or alternatives I am missing. You could always have the build tool split up the file in multiple smaller files and read one of the smaller files with the import expression. -- /Jacob Carlborg
Re: Druntime without pthreads?
On Tuesday, 20 October 2020 at 16:58:12 UTC, Severin Teona wrote: Hi guys. I have a curiosity, regarding [1] - I had encountered some "undefined reference" errors when trying to link the druntime (compiled for an embedded architecture) without some implementation of the POSIX thread calls (and other stuff too). First, keep in mind that druntime and Phobos depends heavily on the C standard library, the Posix APIs, Windows APIs and other platform specific APIs. There's no list of what features or APIs need to be supported by a platform. There's no general concept of optional platform features, i.e. druntime will not automatically adopt if your platform doesn't support a specific feature (like threads). For example, on iOS (and related platforms) `std.process` is not supported (because you're not allowed to call `fork`). This is just hardcoded: if the platform is iOS, don't provide `std.process`. What I'm saying, if you modify druntime to remove threads and locks, and resolve your undefined references, you might end up with new undefined references for other symbols. My curiosity is what would change if I removed from the druntime everything that has to do with mutexes or threads. Would it be possible for the druntime to run and work properly on a microcontroller - where those concepts are not necessary? Could I just remove everything about synchronisation from the druntime, and classes or Garbage Collector to still work properly? The garbage collector will probably work (if you remove the interaction with threads from it). Classes are a bit more complicated, they have a hidden monitor field [1]. There's also the concept of synchronized classes [2]. There's also the `synchronized` statement [3]. All these depend on mutex/monitors/locks in some form (I don't know exactly how the implementation works). Hopefully it should be fine as long as your code doesn't use the `synchronized` statement or synchronized classes. But all classes do come with a hidden monitor field. [1] https://dlang.org/spec/abi.html#classes [2] https://dlang.org/spec/class.html#synchronized-classes [3] https://dlang.org/spec/statement.html#synchronized-statement -- /Jacob Carlborg
Re: Escape this in pure members
On 2020-09-19 21:50, Per Nordlöw wrote: On Saturday, 19 September 2020 at 18:48:31 UTC, Jacob Carlborg wrote: A nested class seems to be able to escape the `this` reference: Ahh, thanks. I just realized that it can escape into other parameters without the `scope` qualifier? This class Bar { void bar(scope Bar b) @safe pure { b = this; } } compiles but this class Bar { scope void bar(scope Bar b) @safe pure { b = this; // Error: scope variable `this` assigned to `b` with longer lifetime } } Hmm, why would `b` have longer lifetime? Isn't the lifetime of `b` throughout `bar`? -- /Jacob Carlborg
Re: Escape this in pure members
On 2020-09-19 18:07, Per Nordlöw wrote: If an aggregate member is pure but not scope when can it escape the `this` pointer?. Only via return? I'm not sure if returning the `this` pointer is considered escaping it. The caller already had access to it. Under the hood, the `this` pointer is just another argument passed to the function. In the struct and class case? A nested class seems to be able to escape the `this` reference: class Foo { Bar b; class Bar { void bar() pure { b = this; } } } -- /Jacob Carlborg
Re: Good repos to learn D
On Saturday, 19 September 2020 at 08:26:36 UTC, Imperatorn wrote: What are some good examples of pretty large/medium size, good structured repos in D? I'm looking for examples to learn from Thanks! Here are some examples of large projects: * DWT [1]. This is one of the largest D projects I'm aware of. It's a port from Java so it's structured like a Java project. I think it works pretty well for D projects as well. But it's not common to have the reverse domain name package structure like in Java. It's more common to have the top level package be named after the project. * Mecca [2]. This one is not as large as DWT, but I think it nicely shows how to separate the platform specific code from the platform independent code. Instead of having `version` statements sprinkled all over the code most platform specific code is located in the `platform` packages. Then it provides a common interface that is used by the rest of the project. * Ocean [3]. This one is quite large as well. [1] https://github.com/d-widget-toolkit/dwt [2] https://github.com/weka-io/mecca [3] https://github.com/sociomantic-tsunami/ocean -- /Jacob Carlborg
Re: DDoc generation
On Saturday, 19 September 2020 at 07:43:24 UTC, Russel Winder wrote: Doesn't that then make the whole DDoc system fairly useless, despite it's use in Phobos? If you use Dub, you can run `dub build -b ddox` and it will use Ddox to build the documentation. This will include an index page listing all modules. This will actually start a local web server to show the documentation. It's possible to generate documentation offline as well [1]. Or it should be pretty straightforward to write a simple script that iterates all D files and generates documentation. Then iterate all HTML files and output a simple index.html file. [1] https://github.com/rejectedsoftware/ddox#generating-offline-documentation -- /Jacob Carlborg
Re: DDoc generation
On Saturday, 19 September 2020 at 07:43:24 UTC, Russel Winder wrote: Doesn't that then make the whole DDoc system fairly useless, despite it's use in Phobos? Yes. The problem is that most things in D are compared with C or C++. People are praising that the built-in support for unit tests and Ddoc are the best things that have happened since sliced bread. But if you compare with C or C++ the bar isn't very high. -- /Jacob Carlborg
Re: Question about linker errors when using slices
On 2020-09-19 04:45, tspike wrote: I’ve been using D for personal projects for almost a year now and I really love it. I recently ran across a linker error that I’m a little confused by. Consider the following files: platform.d: module platform; import app; struct PlatformData { AppData a; } void main() { } app.d: module app; struct AppData { //int* items; int[] items; } If you only compile platform.d, the linker will complain about “undefined references.” This is true when using dmd and gdc, though platform.d compiles just fine when using ldc. But the file only fails to compile when the “items” member of AppData is a slice; if “items” is an int* platform.d will compile. The linker spits the following: platform.o:(.data._D22TypeInfo_S3app7AppData6__initZ+0x30): undefined reference to `_D3app7AppData9__xtoHashFNbNeKxSQBeQBdZm' platform.o:(.data._D22TypeInfo_S3app7AppData6__initZ+0x38): undefined reference to `_D3app7AppData11__xopEqualsFKxSQBdQBcKxQjZb' I was just wondering if anyone knows if this behavior is expected or if this is a compiler bug. Thank you in advance for your time! You should compile both files. I'm guessing LDC might be doing some form of optimization to figure out that it doesn't need those symbols. PS: I hope this is the right sub-forum for asking this sort of question! Yes. -- /Jacob Carlborg
Re: Proper way to exit with specific exit code?
On 2020-09-17 16:58, drathier wrote: What's the proper way to exit with a specific exit code? I found a bunch of old threads discussing this, making sure destructors run and the runtime terminates properly, all of which seemingly concluding that it's sad that there isn't a way to do this easily, but hopefully things have changed in the last 5-10 years and I'm just missing the obvious solution. The proper way is: int main() { return 42; } I highly recommend against trying to terminate the application using `exit` or any other way. Just let the control flow return back to the `main` function. -- /Jacob Carlborg
Re: DDoc generation
On 2020-09-18 13:41, Russel Winder wrote: Hi, I am trying to get to grips with DDoc for documenting an application. Getting the individual module HTML files seems to be the easy bit. The question is how to get an index.html (or equivalent) so as to have an application level entry point to the generated documentation. There's no built-in support for that. You might want to look at some other doc generating tool if those support that. -- /Jacob Carlborg
Re: Beta 2.094.0
On 2020-09-18 23:14, John Colvin wrote: I know. But it should be. dub.selections.json wasn't available in the initial version. I don't remember if branches were deprecated before or after dub.selections.json was added. -- /Jacob Carlborg
Re: get element index when using each!(x)
On 2020-09-17 05:16, Paul Backus wrote: Worth knowing that the tuples you get from enumerate actually have named members, so you can write: s.enumerate.each!(x => writeln(x.index, ":", x.value)); It actually works out of the box for `each`: s.each!((index, value) => writeln(index, ":", value)); https://dlang.org/phobos/std_algorithm_iteration.html#.each -- /Jacob Carlborg
Re: Neater "not version (...)" ?
On 2020-09-16 21:04, Vladimirs Nordholm wrote: Ah, I guess it boils down to this then. Doesn't really make it "neater", but thank you for the tip! You only need to declare the enums ones. -- /Jacob Carlborg
Re: Beta 2.094.0
On 2020-09-17 12:10, John Colvin wrote: I personally think it's not so bad as long as the commit gets written to the dub.selections.json It doesn't. -- /Jacob Carlborg
Re: Neater "not version (...)" ?
On 2020-09-16 19:53, Vladimirs Nordholm wrote: Hello. I wonder if there is a better way to compile something if the current operating system is _not_ a specific platform. For example, I only want some code to compile if the operating system is not Windows. Currently I do this: version (Windows) { } else { // ... my code } Is there a neater version of this, like `!version (Windows) { /+ ... my code +/ }` ? The workaround for that is to define booleans for all versions and then use `static if`: version (Windows) enum windows = true; else enum windows = false; static if (!windows) { // ... my code } -- /Jacob Carlborg
Re: Beta 2.094.0
On 2020-09-16 19:20, mw wrote: Why it's deprecated? can we revive it? It was deprecated because it's a bad idea to not lock versions. Using `~master` would fetch the latest code from the "master" branch when compiling. You never know which version you get. You don't get reproducible builds. -- /Jacob Carlborg
Re: tupleof seems to break encapsulation
On 2020-09-05 07:14, 60rntogo wrote: I wouldn't dispute that it is useful, but that's besides the point. If I declare something private, it's usually because I want to preserve certain invariants and I want the compiler to provide a guarantee that I don't accidentally violate them. As it stands, the compiler cannot guarantee that if I use tupleof. I don't really have an issue with read-only access to private fields (but arguments could be made against it) and then serialization would still be possible. However, if my struct is supposed to maintain invariants, then any attempt at deserialization that naively reads from a tuple without establishing these invariants should fail to compile. I wouldn't mind if `tupleof` was not allowed in @safe code, which Walter mentions in one of the linked issues. Although it would be a breaking change. Secondly, my serialization library, Orange [1], uses `tupleof` to read and write fields. It also supports before and after hooks for both serialization and deserialization. This allows to implement any invariants that are not covered by just restoring the fields. It also supports implementing a method that allows to take full control of the (de)serialization of a specific type. Thirdly, you can do the same thing with pointer arithmetic. Although this is not allowed if @safe code. [1] https://github.com/jacob-carlborg/orange -- /Jacob Carlborg
Re: tupleof seems to break encapsulation
On 2020-09-04 12:16, 60rntogo wrote: Consider the following code. foo.d --- module foo; struct Foo { private int i; } --- main.d --- void main() { import std.stdio; import foo; auto x = Foo(); writeln(x); // ++x.i; ++x.tupleof[0]; writeln(x); } --- As expected, the commented line does not compile. If I uncomment it, I get the error "no property i for type foo.Foo". However, the rest of the code compiles just fine and outputs: --- Foo(0) Foo(1) --- This appears to defeat the purpose of declaring i private. What am I missing? It's useful for serialization and, as you can see in your example, for debugging as well. `writeln` will print the values of the fields in a struct, even for private fields. -- /Jacob Carlborg
Re: Install multiple executables with DUB
On 2020-09-03 14:41, glis-glis wrote: Yes I already tried that, but I get the error Error: only one main allowed. Previously found main at src/scripts/copy.d Looks like DUB doesn't like multiple binaries? Oh, multiple binaries, I missed that. You can try to add multiple configurations [1]. Or if you have executables depending on only one source file, you can use single-file packages [2]. Here are some real-world examples [3][4]. [1] https://dub.pm/package-format-sdl.html#configurations [2] https://dub.pm/advanced_usage.html [3] https://github.com/jacob-carlborg/dstep/blob/master/dub.json#L26 [4] https://github.com/d-widget-toolkit/dwt/blob/master/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet10.d -- /Jacob Carlborg
Re: Install multiple executables with DUB
On Thursday, 3 September 2020 at 08:22:25 UTC, glis-glis wrote: I usually would just write a makefile for that, but I thought I'd give DUB a go. Unfortunately, the DUB-documentation is a little thin and I cannot find a way to tell DUB "compile all the files in the scripts folder and put the binary to the bin folder". How do I do that? By default Dub will compile all files in the `source` or `src` directory and place the binary in the root directory of the project. If you want to override that you can use the following build settings `sourcePaths` or `sourceFiles` to override the source directory. To override the output directory you can use `targetPath` build setting. They are documented here [1][2]. [1] For the SDL format: https://dub.pm/package-format-sdl.html#build-settings [2] For the JSON format: https://dub.pm/package-format-json.html#build-settings -- /Jacob Carlborg
Re: D mentionned in the ARTIBA webzine for an article on Silq
On Thursday, 3 September 2020 at 08:40:32 UTC, aberba wrote: The slack I have no ideas how people get in. I know there's a number of members in there too. Unfortunately you need to be invited. Anyone can do it, if you're interested. We just need an email address. -- /Jacob Carlborg
Re: Symmetry Investments and the D Language Foundation are Hiring
On Sunday, 30 August 2020 at 14:13:36 UTC, Mike Parker wrote: Looking for a full-time or part-time gig? Not only is Symmetry Investments hiring D programmers, they are also generously funding two positions for ecosystem work under the D Language Foundation. And they've put up a bounty for a new DUB feature. Read all about it here: https://dlang.org/blog/2020/08/30/symmetry-investments-and-the-d-language-foundation-are-hiring/ As an alternative to use SHA-1 hashing. There's the option to have a daemon running the background listing on filesystem events. BTW, is timestamps vs SHA-1 hashing really the most pressing issue with Dub? -- /Jacob Carlborg
Re: Installing D on Fresh Windows 10 machine is a pain
On Friday, 28 August 2020 at 05:38:59 UTC, novice3 wrote: DMD x86 on Windows have no dependencies, just unpack .zip and use. It's a pitty, that DMD x64 depend on VS :( It does not. If VS is not installed the MinGW provided libraries, which are bundled, will be used. -- /Jacob Carlborg
Re: Visual D 1.0.1 released
On Tuesday, 25 August 2020 at 20:37:38 UTC, Per Nordlöw wrote: I'm dying to get a semantic engine that supports code navigation to (and completion of) overloaded functions at their call site including UFCS-calls. DCD doesn't support these two features. I have interest in a LSP server based on the DMD frontend as well. There's also a SAoC 2020 project related to DMD as a library [1]. Was there another master thesis (or similar) that would work on a LSP server as well? Either sponsored by Symmetry or related to the University of Bucharest. We should try to work together instead of duplicating the work. Although I've given up on the DMD upstream project and instead, I've forked it [2] to be able to do the necessary changes. [1] https://dlang.org/blog/2020/08/23/symmetry-autumn-of-code-2020-projects-and-participants [2] https://github.com/jacob-carlborg/ddc -- /Jacob Carlborg
Re: How does D's templated functions implementation differ from generics in C#/Java?
On 2020-08-07 23:03, aberba wrote: Syntactically they look the same (although D's can do more things) so I'm trying to understand how why in D it's called template but in languages like C#/Java they're generics. I guess I have fair understanding of D's code generation but isn't it same as what what is available in those languages too? How are the implementation different? Objective-C recently added support for generics. It uses the same approach as Java, type erasure. Basically the only reason why this was added is to make the Swift APIs better and more type safe. Swift also has quite an interesting implementation of generics. IIRC correctly it supports both a more Java like implementation where you only get one instantiation and a more D/C++ like implementation where the compiler generates one instantiation per type. This is supposed to give the best of both worlds. Little binary bloat and high performance. -- /Jacob Carlborg
Re: How does D's templated functions implementation differ from generics in C#/Java?
On 2020-08-07 23:39, H. S. Teoh wrote: They are *very* different. Java generics are based on "type erasure", i.e., at the syntactic level, containers are parametrized with the element types, but at the implementation level, the element types are merely "erased" and replaced with Object (a top type of sorts). There is only one container instantiation, which is shared across all parametrizations. I don't know exactly why this approach was chosen I'm guessing a strong reason was to be backwards compatible with earlier versions of Java. The type erasure is also most likely the reason why Java generic types don't accept primitive types. They need to be boxed, i.e. `int` need to be wrapped in an object of type `Integer`. -- /Jacob Carlborg
Re: Invoking the compiler during runtime
On 2020-08-05 09:57, cy wrote: Well, I did find this: https://dlang.org/blog/2017/08/01/a-dub-case-study-compiling-dmd-as-a-library/ That is more for using the frontend, not the backend for generating code. But it's pretty advanced... probably just invoking dmd would be good... You can start with that at least. -- /Jacob Carlborg
Re: Using D within a rust codebase
On 2020-07-27 13:43, Ali Çehreli wrote: They should be taken care of when the program is linked with a D compiler. Just linking with a D compiler is not sufficient. There needs to be a D main function for the runtime to automatically be initialized. If you make the D code a bit more complicated, for example: static this() { import std.stdio: writeln; writeln("static this"); } Then that won't be printed without a D main function or manually initializing the runtime. The initial question was about linking D code into an already existing Rust code base. I don't think the first thing to try is to replace the Rust main function with a D main function. -- /Jacob Carlborg
Re: Using D within a rust codebase
On 2020-07-27 03:03, Paul Backus wrote: extern(C) void hello() { import std.stdio: writeln; writeln("Hello from D!"); } The D runtime needs to be initialized first [1]. Then it should be terminated as well [2]. [1] https://dlang.org/phobos/core_runtime.html#.rt_init [2] https://dlang.org/phobos/core_runtime.html#.rt_term -- /Jacob Carlborg