D Language Foundation July 2024 Quarterly Meeting Summary
Mike Parker
aldacron at gmail.com
Sat Dec 7 15:16:10 UTC 2024
The D Language Foundation's quarterly meeting for July 2024 took
place on Friday the 5th at 15:00 UTC. It lasted for about an hour.
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)
* Luís Ferreira (Weka)
* Martin Kinkelin (DLF/Symmetry)
* Dennis Korpel (DLF/SARC)
* Mario Kröplin (Funkwerk)
* Mathias Lang (DLF/Symmetry)
* Mike Parker (DLF)
* Carsten Rasmussen (Decard)
* Robert Schadek (DLF/Symmetry)
* Bastiaan Veelo (SARC)
## The Summary
### Carsten
Carsten said Decard had been experimenting a lot with
WebAssembly. They'd stubbed out DRuntime until it worked. They
had some of their library functions running in a browser and had
tried different virtual machines. They wanted to do more work on
that. They had a lot of issues with mobile because different
chips worked in various ways. They wanted to get their entire SDK
working on WASM, but it would probably take a year to complete
because there was a lot of stuff moving around in WASM.
Robert asked if they'd gotten the GC working. Carsten said they
hadn't focused on that. They were just calling functions. They
didn't know how to write a GC, so they were hoping to use the
WASM GC eventually.
He said one thing that had been annoying was that the WASM
interface was basically POSIX, but the compiler didn't treat it
as such for versioning. He'd had to implement a lot of versioned
dummy code to get it to work. He would like to see the compiler
recognize WASM as POSIX.
Robert said he'd seen that the standardizing body had accepted a
proposal for GC. Carsten said they'd also accepted
multithreading. He thought WASM was moving into virtual machines
and such, so it would eventually be a VM for both in and out of
the browser. Robert said it was a really nice interface.
### Bastiaan
Bastiaan said he was still working on SARC's D translation. Now
and then he encountered a problem that was difficult to solve or
difficult to understand. That was his life, but there was nothing
major to bring up here.
### Mathis Beer
Mathis said that for the first time ever Funkwerk was using a
patched version of the compiler because the rebindable range
`destroy` bug was so horrible. He said that wasn't a new thing,
though, because it was mostly his fault. He thought the `destroy`
function should just be deprecated. It just did so much harm, but
he didn't feel it was debate-worthy.
Dennis asked if he meant the general core `destroy` function.
Mathis clarified that he meant the `Object` version. He said it
had this issue where when it was dealing with a value type it
would do something to the value, but when dealing with a class it
actually destroyed the class value, not the reference but the
actual object itself, in a way that was very hard to notice.
Sometime later you'd notice that your vtable pointer had become
zero, so you had to know what that meant and find out where it
happened.
He thought it was almost never the function you wanted to call in
the generic case. He couldn't think of a single case for it. He
found it bewildering.
Walter thought the purpose of `destroy` was so you didn't have to
wait for the GC to collect an object. You could just say you were
done with it. Mathis said no, it didn't even deallocate.
Walter asked why it mattered if it set the vtable to zero if you
weren't going to use it anymore. Mathis said the problem was that
he was using it in a generic context and wanted to call the
semantically appropriate destruction operation for a value. For a
struct, that meant calling the destructor because the value's
lifetime was ending. But when the lifetime of a class reference
ended, nothing should happen because there might be other
references to that class instance. But what actually happened was
that the class instance was destroyed no matter how many
references remained.
Walter said that was the point of `destroy`. Mathis said it
didn't do that for any other type. If he had a struct lying
around somewhere and passed a copy to `destroy`, the original
version wouldn't be affected. Dennis said that was true, but if
you had a pointer to that struct, then the pointer would be
dangling. Mathis said he didn't actually know what `destroy` did
with pointers. He thought it did nothing.
Walter said if you were to destroy something, then there should
be no more references to it. It was up to you as the programmer
to ensure there were no more references to it. Mathis said in
this case he was using it to compensate for lifetime management
of [a data object in
rebindable](https://code.dlang.org/packages/rebindable) where he
had to take charge of the lifetime. He thought he'd call
`destroy` to end its lifetime.
Walter said, no, you called `destroy` when you as the programmer
know that was the end of the targeted value, which was dependent
on the specific type. So if you were using it in a generic
function, if it was a struct, then it was going to be a copied
value so it made sense to say you wanted to end the lifetime of
that value. But if it was a class, the copy constructor was
literally just making a copy of the reference. If you called
`destroy` on that, you were saying that there were no more
references to it.
Mathis said that was his point. The behavior was different
semantically. He wasn't calling it on a class specifically. He
was calling it on a `T`, an arbitrary template parameter. Walter
said that by doing that he was saying there were no more
references to that `T` instance. But here in the meeting he was
saying he had more references and they were going to go bad, but
that was not the point of `destroy`. The point was that the
programmer was saying there were no more references.
Mathis said the behavior made sense for classes and made sense
for structs, but it didn't make sense for both classes and
structs. It was different. Walter said that was the way class
objects worked. Calling `destroy` was unsafe.
Mathis said that basically, it didn't make sense to be
overloaded. There should be a `destroy` and a `destroyClass`.
Walter again repeated that this was the point of the function:
calling it meant you were indicating there were no more
references.
Martin said the problem with classes was that you could never be
sure that the reference you were destroying was actually the
final reference. He suggested we should have a separate finalizer
for classes. It would mean breaking changes, but we could add a
finalizer for class objects and then in an edition, we could
change the semantics of `destroy`.
Walter thought it was a good idea, but said the trouble with
having a separate `finalize` and `destroy` was that people would
mix them up, wouldn't understand the difference, would use the
wrong one, and then be unhappy. It was inevitable.
He said one thing Mathis could do was to wrap the call to
`destroy` with "is this a class". Mathis said he'd been doing
that. He couldn't ever remember calling `destroy` without
wrapping it like that. Walter said okay, it was working the way
it was designed to work, and he didn't think we could change that
behavior.
Luís thought one of the problems here was special cases for
classes. Not only `destroy`, but a lot of stuff was special-cased
for classes because they were just pointers to hidden objects
plus a vtable. Another thing was that classes implied the
presence of the GC, but you could also allocate them without the
GC. The existence of the special cases was why Weka didn't use
classes. Most of the cases could be solved with structs.
Walter said Luís was right that classes and structs were
different from each other. Algorithms that ignored those
differences were going to lead to trouble. Luís understood that
but felt the design could have been more similar to structs
without the differences that always need special cases in generic
programming.
Walter said that in C++ you had to special-case for references.
When you had value types and reference types, they were going to
be different. He didn't think there was any magic way to fix
that. Luís said at this point he didn't think so either.
Mathis agreed. He said he really liked the class design in D. The
standard range algorithms worked fine with classes as well as
with structs when written in a straightforward way. The only
function he had a problem with was destroy. He felt that if he
had a generic function that required him to use a `static if` to
call a function, then in fact it was two functions that happened
to be named the same.
Walter said that was a good point, but if you were using value
types, you should be relying on RAII to do the destruction, not
an actual `destroy` function. And RAII didn't happen with classes.
Mathis noted that his case was a special case. He had this magic
rebindable thing going on where he had to take manual control of
lifetime. He supposed it was something that didn't come up often.
Walter said when you were manually doing lifetime as a special
case, then it was a special case and you had to put an `if` in
there.
I noted that `Object.finalize` in Java had been deprecated
because it was so easy to misuse. I remembered that Sun used to
always tell people not to do this or that in `finalize`, because
it wasn't a destructor, yet people would still do this and that.
We had kind of the opposite problem in D in that our destructors
were also finalizers.
Walter said you were never going to get fire and water to mix.
Reference types and value types were just intractably different
from each other.
Mathis said this had come up because he had to add that
rebindable alternative to support `immutable` in `std.algorithm`,
[which all went back to his DConf '22
talk](https://youtu.be/eGX_fxlig8I).
He then wrapped up by reporting that Funkwerk were on DMD 2.108
and LDC 1.38 everywhere and it was working pretty well. Their
code was internally managed with no major external dependencies.
They were happy to be off of vibe.d and no longer dealing with
its issues from compiler updates. And they were happy with 2.108.
### Luís
Luís said he had nothing new to bring, but he wanted to
understand the status of the AST refactoring project. Weka still
had linkage issues resulting from the incorrect inference of
templates and attributes. He thought it was mostly because the
way we queried the AST was kind of a mess. If we had a way to
make that better, then it would make other things better.
I said that Razvan was the one who knew all about that. I knew
that it was mostly Razvan working on it right now, though others,
including Bastiaan, had contributed. It was also an officially
sanctioned idea for a SAOC project. So it was in progress, and
Luís should ping Razvan if he wanted an accurate picture.
Luís closed by saying he'd seen some good features come into the
language lately that he'd been waiting a long time to have, like
string interpolation and named arguments. He thought that was
really cool to see.
(UPDATE: One of the SAOC 2024 participants is working on the AST
refactoring project right now, and Razvan intends to enlist some
of his students at the [Politechnica University of
Bucharest](https://upb.ro/en/) to contribute. He could always use
more help on this. It's not difficult work, there's just a lot of
it. But it can be done in small chunks which makes it really
amenable to contributions from multiple people. This is a
high-impact project. If you'd like to find out how to contribute,
please read [Razvan's call to arms on the D
blog](https://dlang.org/blog/2024/02/22/dmd-compiler-as-a-library-a-call-to-arms/).)
### Mario
Mario had no programming issues to report but said that three
Funkwerk staff would be attending DConf this year.
Mathis said that Luís mentioning named arguments had just
reminded him that Funkwerk wanted to use them, but currently
couldn't because they weren't supported in dfmt. They used to
allow one of their employees some time to spend on dfmt, but that
employee was no longer working for them and they were now in a
gap. He wasn't sure what to do about that. Maybe he could take a
few days to look at it, but they used dfmt in all their projects,
so that made named arguments a non-starter for them.
Dennis said he had started using dfmt recently for his own code
and noticed a few bugs. He'd opened some issues, but it seemed no
one was actively monitoring it. He said he might take some time
to figure out how it worked so he could fix these issues. It was
really annoying when the formatter squashed things in attributes,
got confused by the colon in named arguments, and completely
ruined the argument list.
Mario said that he hadn't assigned Mathis to fix dfmt because he
wasn't sure if it would be a waste of time and money. He knew
that there was also sdfmt from SDC, and he also knew that
something had been done with dfmt with regards to integrating
DMD-as-a-library, but he didn't know what the progress was. He
didn't want to task Mathis to fix dfmt if the fixes would become
irrelevant when it was replaced with something else.
Dennis said one of Razvan's students had worked on the project to
replace dfmt's use of libdparse with DMD-as-a-library, but he
didn't think it was enabled by default. The last he'd heard there
was just a switch to enable it and it was still kind of early. He
didn't think the change would affect the formatting logic, but
we'd have to see.
I noted that in the past we had discussed shipping a formatter
with the compiler. We had agreed it would be dfmt because it was
going to use DMD-as-a-library, which made sense if we were going
to ship it with DMD. As such, any fixes to the formatting logic
shouldn't be wasted time.
Luís said that Weka hadn't been able to test the dfmt changes yet
because they were a few compiler releases behind, but he hoped
they'd be able to soon. He'd report any issues they found with it.
### Johan
Johan said there were probably a few issues from Weka to talk
about, but he hadn't collected them before the meeting, so he'd
bring them up next time.
He did have some news for us. He said that Weka had been
interested in linking executables with musl libc. He'd fixed the
last parts that were required to make it happen. He'd upstreamed
almost all of it to DRuntime. He said that was a nice success
story. You could now create statically linked executables that
didn't depend on any libc implementation, and that had been the
goal.
Next, he requested that we include the language spec in the
compiler repository to prevent the kind of parallel pull requests
where you ended up having to revert one if you had to revert the
other. He was sure it had been debated before, but he would like
to see it.
Robert said it would be even more awesome if the spec were unit
tests, i.e., docs that were actually testable. That would
probably be more work, but it would be really cool. Even with the
spec in the compiler repository, you'd still have to remember to
update it. But if you had a spec that failed to compile and the
documentation was generated from that, it would be a bigger win.
Walter said that was a great idea.
Dennis noted that examples in the spec were currently run if they
had the proper macro. He said that Nick had been working on
transforming raw, untested code into runnable examples.
Robert said that was awesome and asked if it included other test
cases for the language. Sometimes when he read the spec and
something wasn't clear, he'd go to the tests and see what
actually came out at the end. If they were included, that would
tighten up the spec quite considerably.
Dennis asked if he meant linking the DMD test suite with the
specification, and Robert said yes.
Walter said the test suite was really not meant for public
consumption. It was not designed to be that way. It was designed
to make the compiler easy to debug.
Robert agreed but reiterated that sometimes when he read the
spec, there was some nuance missing, or the wording was such that
he misunderstood. Reading some obscure source code that might be
hitting his specific need helped him in that regard. He
understood where Walter was coming from, but it was just an idea
to float.
Walter said Robert was right, but he pointed out that every time
he read a computer software specification, including language
specifications, the specs on how the function call ABI worked
always confused him. So he would write little test cases, compile
them, and see what happened. Robert said he was a lot lazier than
Walter and was looking for somebody who had already written the
thing he was interested in.
Walter said that once he had written the code, compiled it, and
seen what happened, then he'd go back and read the spec again and
it would make sense. He wished he knew a way to make a better
correspondence between the specification and understanding it.
Luís said his experience in relation to Walter's had been the
opposite. For example, reading the D spec, assuming the ABI
worked as described, and then experimenting with DMD and finding
the ABI didn't work as specified. For example, arguments were
getting reversed. In the calling convention, the arguments were
supposed to be one way, but in the compiler, they were the other.
He said we had two different kinds of tests on the compiler. We
had all sorts of weird tests for specific compiler bugs. He
thought Robert was describing tests that served as examples but
that also confirmed the spec was conformant with what we wanted
to say.
Walter said if the compiler and the spec didn't match, that was a
bug and should be reported. They happened, but if they were
reported we could knock them down one by one. Luís said he had
tried to fix the calling convention bug, but it was a very hard
problem because it was everywhere in the DMD backend.
Walter agreed that the calling convention was a large source of
complexity, especially in the backend because it supported
multiple calling conventions. It was a large tangle of code.
Luís said one of the problems he saw was with DMD's math
intrinsics. They were implemented based on the calling
convention, but because the argument order was actually reversed,
we now needed to change all of those intrinsics. He'd submitted
some PRs to try to fix them, but the tests failed. From talking
to Iain, he thought GDC was the most ABI-compliant D compiler.
Johan brought us back to his original point: if we had the
compiler and the spec in the same repository, it would be easier
to know which language spec matched the version of the compiler
you had.
As for testing the spec, he said there were companies out there
that made test suites for C. This was tough work. He thought it
was a completely separate issue from having the spec and the
compiler in the same repository. It would be a huge amount of
work to write all the lines of test code that followed from a
single line of the spec. It would be great, but it was a huge
project for sure.
As for the ABI, he felt that was outside of the language spec. To
him, the spec was at a higher level. We implemented a C ABI
because we had to, but otherwise, the ABI was quite open. That
was on a lower level. The more interesting thing for programmers
was on the higher spec level, and that was linked with your
specific compiler version. When they were in separate
repositories, then you had to figure out which dates matched
which and it got quite tricky quite quickly.
Walter agreed that the language spec and the ABI spec were two
distinct things. He noted that after the C language was
standardized, a company made a test suite out of every piece of
code in the C spec and then released it. Every C compiler fell
flat on its face. It took years for all the C compilers to
successfully run the tests extracted from the spec. This was the
whole problem.
Mathis suggested that when you're looking at the language spec
and something doesn't make sense to you, but then looking at a
test causes it to make sense, then that was a test that should go
into the spec. You didn't have to put it in at that moment, but
you could file an issue for it. Walter agreed.
Luís gave an example of a situation Weka had encountered where
having the spec and the compiler in the same repository would
have been a help.
Walter said he had no objections to it. He didn't think it would
be a big problem to merge them.
Finally, Johan reported that Weka were still on LDC 1.30, but
they were close to upgrading to 1.38, which was D 2.108. He had
already seen some changes in 2.109 to which he thought it would
take them some time to adjust, so the plan was to upgrade first
to 2.108 and continue from there.
Luís said he was very excited to use some DIP 1000 features. The
DIP 1000 changes were what had been keeping them on an older
version because of breakage, but that had been fixed.
### Mathias Lang
Mathias wanted to reiterate the importance of tooling, and he
thanked Dennis in advance if he would take a look at dfmt.
Symmetry were using a formatter as well, though they were using
sdfmt since Amaury maintained it. But a lot more could be done
with the tooling and he thought it would integrate with their
projects quite well. DMD-as-a-library would enable a lot of good
things, and that would be enabled by the AST refactoring project.
If we had to choose between an ARM backend for DMD or an
immutable AST, his vote would go for the immutable AST.
### Dennis
Dennis had been working with COM lately. It had a special calling
convention with named arguments, and D had named arguments, so he
thought it would be nice to try to combine them. But `opDispatch`
and `opCall` didn't support named arguments, and the DIP didn't
provide any mechanism for it.
He had an idea to add something like `opNamedDispatch` that would
push the named arguments as a template argument as a string
array. That would make it work. Walter thought that sounded fun.
### Walter
Walter said that he'd been posting updates to X about his daily
progress on the AAarch64 code generator. He was currently working
on the function call return sequence. Having spent some time with
it, he had slowly begun to understand the ARM instruction set.
Some parts of it were still baffling. For a supposedly simple
instruction set, it was extremely complicated. He had to write
little snippets of code and try them out on godbolt to see what
they actually did.
He'd gotten to the point where he thought it was going to work,
but getting the details done would take a bit of time. He
expected to have the basics running fairly soon.
Johan asked if Walter had a machine to run it on. Walter said
he'd just been using godbolt. He'd write a function that was two
lines or so and wanted to see what instructions were emitted for
it. How were they doing pushes and pops? How were they doing
function calls? Godbolt was perfect for that.
He said he also had a Raspberry Pi. He expected that Raspberry Pi
users would be a potential user base for a simple AArch64 DMD
backend. That's what he planned to use as a target machine. The
code the compiler currently emitted didn't handle fixups in the
elf object files, so actually trying to run the generated code
wouldn't work.
Unfortunately, the elf generator code was a rat's nest. He'd been
refactoring it to make it more tractable. With the refactoring,
it should be easier to implement the AArch64 fixups, which were
completely different from the x86 fixups.
He'd already written an object file dumper and a disassembler for
it, so the pieces were slowly coming together. Once he had it
working on the Raspberry Pi, he'd get a recent Mac with an ARM
chip in it and make it work there.
Johan said he'd thought Walter was a Windows user. He'd learned
there were some good Windows ARM laptops these days. But at some
point, it would be good if Walter had a machine to run it on.
Walter said the Windows backend would probably be the last step,
primarily because he found the Windows ABI poorly documented and
much more high-effort to get things working. He also didn't like
working with the Microsoft SDK. It was excessively massive and
complicated, and it was hard to find anything in it. It had too
many directories and files, and he just didn't like messing
around with it. That was also the reason Windows support was the
last to get implemented for ImportC.
He said the Linux development tools were just so much better.
They were easier to understand and oriented toward a command
line, not a GUI. He found them much simpler to develop code on
and much easier to understand what was happening. So he was going
to defer the Microsoft problems to last.
Martin noted that DRuntime most likely needed work for Windows
AArch64. Johan said that, indeed, LDC probably would not run on a
Windows ARM laptop. It would be nice if we had some developers
that had one to work on it. It wouldn't necessarily have to be
Walter. Maybe one of the core contributors, or someone with skin
in the game and the motivation to fix the final bits and pieces.
Dennis asked what Walter planned to do with the PR. Was he going
to keep adding to it and merge the whole thing once the test
suite passed, or was he going to merge a minimal working version
and build on it?
Walter was aware that it was getting larger and larger, and there
was no end to that in sight. He was constantly rebasing it so it
didn't become hopelessly divergent. It was so large now that it
was frankly impossible to review. He asked if Dennis thought it
reasonable to simply mainline it even if it wasn't a fully
functional backend yet. That would make it easier to manage and
avoid it becoming impossible to merge while making future
additions easier to review.
Dennis thought in any case it would be nice to have the flag and
the skeleton that the actual code generation could build off of.
Walter said in that case, he'd be happy to merge it if it passed
the test suite. Dennis asked if there were any ARM tests in the
test suite that actually ran the generated code. Walter said
there were not.
Dennis asked if it was just testing against expected assembly,
and Walter said that's what he was doing. He was doing visual
checks of the assembly. The `-vasm` switch had turned out to be
really useful for that. He compiled with `-vasm`, looked at the
disassembled code, and compared it with what godbolt put out.
He'd even take what godbolt emitted and put it into the
disassembler as part of the test suite.
Dennis said he could take a look at it some time. He wanted to
look at the code, but it wasn't something he'd be able to do in a
single evening. Walter said that was exactly the problem, so he
was all for merging it and continuing on from there.
## The Next Meetings
Our October Monthly meeting took place the following Friday, July
12th. Our next quarterly was on Friday, October 5th.
More information about the Digitalmars-d-announce
mailing list