D Language Foundation April 2024 Quarterly Meeting Summary

Mike Parker aldacron at gmail.com
Fri Jul 12 08:43:50 UTC 2024


The D Language Foundation's quarterly meeting for April 2024 took 
place on Friday the 5th at 15:00 UTC. It lasted for about 50 
minutes.

Our quarterly meetings are where representatives from businesses 
big and small can bring us their most pressing D issues, status 
reports on their use of D, and so on.

## The Attendees

The following people attended the meeting:

* Mathis Beer (Funkwerk)
* Walter Bright (DLF)
* Johan Engelen (Weka)
* Dennis Korpel (DLF/SARC)
* Mathias Lang (DLF/Symmetry)
* Razvan Nitu (DLF)
* Vladimir Panteleev (Symmetry)
* Mike Parker (DLF)
* Robert Schadek (DLF/Symmetry)
* Bastiaan Veelo (SARC)

## The Summary

### Vladimir

Vladimir brought three issues to us that he said were not a 
priority, but had been a pain in his side. He had now encountered 
them in the code base at work, so he wanted to ensure they were 
at least on someone's radar. He stressed they were not super 
urgent. Two of them were codegen bugs, and one of those two was a 
regression. The third one he said was just weird.

* [`this` not captured by lazy 
expression](https://issues.dlang.org/show_bug.cgi?id=24050)
* [[REG2.101.0] Wrong code with temporary and tuple range 
foreach](https://issues.dlang.org/show_bug.cgi?id=23923)
* [Type list (tuple) not expanded in delegate during 
IFTI](https://issues.dlang.org/show_bug.cgi?id=21804)

### Bastiaan

Bastiaan began by telling us he was very happy that Dennis had 
started working with SARC. He then gave us an update on the 
conversion from Pascal to D.

He reminded us that in our October 2023 meeting, [he'd reported 
on a thread contention 
problem](https://forum.dlang.org/post/jucppgelbdvxvoubxzkr@forum.dlang.org) he'd encountered with allocations (which [he subsequently reported had been solved](https://forum.dlang.org/post/gguwkjyiduyxjilyluvf@forum.dlang.org)). Since then, he'd had a problem with his implementation of Pascal sets. Those were bit arrays, and the implementation had been a bit sloppy regarding allocations, but that was solved now, too. He said the `@nogc` attribute had helped track down where the allocations were happening.

He said that overall, prospects were good. But one thing he'd 
noticed was that when doing function overloads, you could have 
`inout` to account for `const`, `immutable`, and mutable function 
parameters vs return types, there was nothing comparable for the 
presence or absence of `@nogc` on parameters which were 
delegates. Especially in `opApply`.

Dennis said this was a longstanding issue. He thought Mathias 
Lang had a DIP for attribute polymorphism on delegates, and there 
had been other proposals. But they were kind of complex and so 
far hadn't gained traction.

Mathias said that, yes, [he had a DIP for 
it](https://github.com/dlang/DIPs/pull/198), but he wasn't 100% 
confident about it due to some corner cases. He hadn't had a 
reason to make the time to pursue it further. If anyone was 
willing to pick it up, he'd be happy to discuss it with them, but 
he didn't see himself getting back to it anytime soon.

Bastiaan said it wasn't a big problem, but especially if you 
wanted to overload `opApply`, you had to do it twice to account 
for `@nogc` delegates and those that weren't.

Dennis said that sometimes with templates you could have a 
generic template type for your return type. He didn't know if 
`opApply` supported that, but he thought it did. Mathias said 
templates were nice until you needed to use classes or virtual 
functions, then things would just break.

Walter asked Bastiaan to file a Bugzilla issue on this, and he 
said he would.

### Mathis Beer

Mathis said he'd been trying to push incremental compilation at 
work as everyone was switching to 32GB laptops. A problem he'd 
encountered is that once you pass the compiler a D file along 
with some other files, you'd then not be able to rebuild that 
file in isolation. The compiler would insert some symbols into it 
which would then be missing in another module, or the other way 
around.

They'd been working around this by tracking which D files they 
were passing to which command line. Then when they needed to 
rebuild that file in isolation, they'd go ahead and rebuild the 
other files it had been built with. So they were kind of taking 
the files as a set, then breaking it into two different sets and 
building both of them. The first time around, there was no 
speedup, but they were seeing an improvement the second time 
around.

The main problem they'd had with that was memory usage. Even with 
their laptops as large as they were, it was getting critical. 
Especially if they broke it up too far and had something like 
eight instances of DMD running or passing the same modules in 
parallel. They'd been optimizing stuff to have the right amount 
of template usage for a single build and take good advantage of 
the object and module caches. If they were passing the same 
modules eight times, it may be faster, but it wasn't better for 
memory usage.

He pasted [a Bugzilla 
issue](https://issues.dlang.org/show_bug.cgi?id=24459) in the 
chat and said we should treat it as low priority. He said the 
reported issue was what happened when you tried to rebuild a 
single object that was part of a larger build set earlier. He 
anticipated that once this was fixed, there would be three more 
issues waiting in the wings behind it. What they had right now 
did seem to be working.

As an addendum, he noted that [the mold 
linker](https://github.com/rui314/mold) was absolutely amazing. 
He said that anyone on Linux needed to try it. He thought it 
should be part of the distribution, as it was very fast.

Dennis agreed that mold was fast. He added that ryuukk_ had 
[published a forum 
post](https://forum.dlang.org/post/zmknwhsidfigzsiqcibs@forum.dlang.org) saying how you could speed up build times by using mimalloc rather than the glibc malloc. Dennis said he hadn't looked into it yet.

Johan asked if Mathis could share the build system he'd 
described. Mathis said that if it worked out, he'd do a write-up 
on the forums about how it worked. Right now, it was just a heap 
of scripts that he was the only person actively maintaining. He 
wouldn't want to impose them on the world. He said that if you 
had an estimate of how much memory you were going to use, it was 
the sort of thing that could probably included in dub fairly 
straightforwardly.

Robert asked if they had tried the combination of reggae and 
ninja. He said ultimately, they'd run into the same problem, but 
instead of doing it all themselves there might be something there 
that was good enough for them. Mathis said that the big problem 
with the build systems he'd considered with this, or at least as 
far as he was aware, was that when you were using DMD in this 
way, then you'd have a build rule that reacted to change in one 
of five source files by rebuilding five object files, only some 
of which would be outdated. He said that was generally hard to 
express.

Robert said he was using reggae with ninja on a pretty big 
project and it was working well. Mathis provided more background 
and explained that they'd run into an issue when passing `-op` to 
DMD to maintain the source paths on generated object files so 
that they'd end up with a directory tree in the build folder that 
matched the source tree. This worked pretty well most of the 
time, and without it, you sometimes ran into name collisions with 
the object files. The problem came in when using it with dub when 
you passed files with absolute paths. You might see the object 
files ending up in a folder where you didn't want them. He 
intended to file an issue about it but hadn't done so yet. That 
was why they were doing a lot of stuff manually at the moment.

### Johan

This was Johan's first time joining the quarterly, so he'd 
intended to just come in and listen and hadn't brought anything 
specific to discuss. He reported that Weka was still at LDC 1.30, 
which was the equivalent of DMD 2.100. He said it was common that 
they skipped multiple versions because the updates were too 
frequent, but they'd recently started upgrading to LDC 1.37 or 
maybe 1.38. They'd run into the usual problems, but fewer than 
he'd expected, so that was positive.

As a result of the upgrade process, he said we may have recently 
noticed a few extra bug reports on Bugzilla. These were for 
issues for which there were no easy workarounds. Overall, he 
thought it was working out pretty well. There'd been nothing 
completely unsolvable or very crazy yet, but so far they were 
still at the stage of fixing compilation errors and hadn't gotten 
to the point of running anything. He said that in the past, 
compiler upgrades would break the binary, but that hadn't 
happened the past couple of times.

He said that Weka had so much templated introspective code that 
they seemed to hit every corner case of the language. With every 
compiler update, a corner case may have changed. They were very 
sensitive to that.

As an example, he said they had a struct with an `opAssign` 
override for `const`. Then somewhere in Phobos, it broke. There 
was a range iterator testing for `opAssign`, then afterward it 
didn't perform a move, but instead did a `memcpy` on the object, 
and then complained that it couldn't copy into constant memory. 
So it had this check for the assignment, and it passed because 
this `opAssign` override on a `const` object was allowed.

He said that Jonathan had already come up with a fix for it, so 
he was happy that it had been noticed and acted upon so quickly. 
But it showed how they had all these funny things in their code 
base. So he had the idea that he should make a test file that 
collected all these "structures from hell" where they did strange 
things. Then if we were looking for an annoying structure to test 
against, we could look at this file where they had a bunch of 
them. And the list would link to the bugs that caused each 
structure to be included in it.

Walter said that would be great, and that's what the test suite 
was for. Johan said the difficulty was often in figuring out 
whether it was valid code or not. Should the language support it, 
or was it just too crazy?

Mathis Beer asked what they were doing with that `opAssign` 
overload, and Johan explained it. It was just one place in the 
code base where they were essentially using a mixin to fix up the 
structure to basically have tail const. He said that very often 
in these cases, he didn't even know how the whole thing worked. 
He'd just update the compiler and then encounter compilation 
errors across this huge code base with so much template stuff 
going on that it was usually kind of difficult to figure out what 
the error actually was.

He said that understanding what the code was doing was usually 
his smallest concern. Sometimes he had to, but he usually tried 
to avoid getting into the meaning of the code, because then he 
might try and fix it and then run into problems with changing 
program behavior. So he usually tried to reproduce what the old 
compiler was doing to see if that was correct or if it was 
actually a bug.

He said one thing that was nice to mention was that the compiler 
now complained if you had a static assert on just a string, where 
instead of `static assert(false, "message")` you were just doing 
`static assert("message")`. This had uncovered a bug in their 
code base where someone had done exactly that, so he was really 
happy that the compiler complained about it. But even in that 
case, he had to stop and figure out what was going on, and if he 
could fix it by just adding `false` to the assert. Would that 
break the code? Had people started depending on the current 
behavior? And with all the introspection going on...

Razvan noted that he'd always found the ability to have `const` 
or `immutable` on `opAssign` really odd. He'd raised it in the 
past, but at the time some people had a use case for it. They 
weren't modifying any data, but just logging calls to it. He 
still found it odd and thought that we shouldn't allow 
`immutable` or `const` on there. But people did crazy things so 
now we had to support it.

Razvan then asked Johan if there was anything we could do to make 
things easier for him. Obviously, we couldn't put the Weka code 
base into our testing pipeline. But maybe there would be some way 
that when we had patches we could automatically send them over, 
then if Johan had any errors he could reduce a test case. Maybe 
that would take some of the load off of his shoulders.

Johan said that DMD couldn't compile the Weka code base anyway, 
though he hadn't tried it recently. He'd been trying to minimize 
the delta between Weka's LDC and vanilla LDC, and now it was very 
small. He thought it might no longer be relevant for just testing 
whether compilation worked. So the first step would be to get 
very close to the upstream compiler being able to compile it. But 
not to generate the binaries---there were some LDC-specific 
things in there that DMD couldn't compile, so just being able to 
do semantic analysis on it would be great.

He thought they were getting there. Then someone like him could 
just do a compilation check once a month or maybe once every 
week. We wouldn't want it on every DMD update, for sure. They 
didn't have that even on LDC. But it would be nice to have it 
done earlier. Deciding if it was valid code or not would still 
take time, but it would be better than the current situation. He 
didn't check LDC betas against Weka just yet. That might be a 
good first step.

He said recent template emission changes in both DMD and LDC were 
an improvement for Weka. They used to need to fix or change LDC 
to match whatever the Weka build system expected with template 
emission. That would never work with the upstream tests. It was 
only valid for Weka and was invalid in general. But now because 
of these upstream changes in template emissions, they had changed 
their build system significantly. So maybe now upstream LDC could 
compile Weka's code base. He was more skeptical about testing the 
binaries.

Razvan said that DMD didn't get many patches to the backend. Most 
changes were in the frontend. It would be great if we could test 
against Weka somehow when making changes to the semantic 
analysis. Johan said it was good to keep reminding them to do 
these kinds of tests and not delay them as much as they do now.

Johan added that a big incident they'd had with binaries on a new 
release was when the object layout had changed due to a change in 
class layout. The monitor field had been shifted toward the end, 
and that had an unexpectedly big impact. That kind of thing had 
been so bad in the past that they had tooling to check it. Every 
class and structure is hashed by introspecting the binary layout. 
If anything changes, the build system flags it. At a deeper 
level, it should flag even when the compiler does something like 
changing the padding. He said that kind of thing can happen even 
on an LLVM update, or when changing optimization flags, so it 
wasn't just the frontend they had to think about.

Bastiaan pointed out that the policy now was we didn't want to 
break things as frequently, and there had been some reversions. 
So in incrementally updating, Johan might end up making changes 
that turned out to be unnecessary. Johan agreed. He said that if 
they increased the amount of testing, then instead of fixing the 
code, he'd just report it and then fix it upon a real release in 
case a change of fix got reverted.

But he clarified that in upgrading from LDC 1.30 to 1.37, he 
wasn't testing every release in between. There were some places 
where they were still using 1.24, but in general, the code just 
had to compile with one compiler version, although compiling with 
two was very good. Ideally, he'd prefer to be able to make the 
code changes, test with the old compiler to make sure nothing had 
changed in terms of performance or whatever, and then update to 
the new compiler without fixing any code. Then they'd have a 
little separation between code change and compiler change.

He said that Weka had a script that automatically selected the 
compiler for you based on whatever git hash you were on. This 
allowed them to use several versions but always ensure that a 
given version of the code base was compiled with the version of 
the compiler it was known to work with.

### Addendum

Johan's point about compiler versions reminded Bastiaan of an 
issue with dub dependencies. Sometimes maintainers pulled 
packages off of the dub registry, or they'd go inactive and code 
would stop compiling. He wondered if there was an established way 
to deal with that for commercial apps. He thought it might be 
best to make sure you had forks of all those packages. It was 
nice that you could configure dub to find the dependencies 
elsewhere.

Mathis Beer said that at some point, dub was changed so that you 
could query the server using an API, and it then became 
incompatible with just dumping a copy of the registry in a 
folder. But you could still configure dub to use a registry that 
was just file and folder-based, and he thought that's what they 
were doing at Funkwerk. Then you could write a script that just 
downloaded all the packages and stashed them in a folder 
somewhere so you'd always have a backup. Anything that Funkwerk 
used or installed was backed up to a local server.

Mathias Lang said that they had a monorepo at Symmetry and wanted 
dub to support that better. So there were probably some changes 
coming that would make that possible. The last release had made 
`dub fetch` project aware so that it would fetch all a project's 
dependencies. And then using `--cache=local` with it, it would 
store them in your project. There were more improvements they 
wanted to make.

## The Next Meetings
Our April Monthly meeting took place the following Friday. Our 
next quarterly was on Friday, July 5th.


More information about the Digitalmars-d-announce mailing list