Escape Analysis & Owner Escape Analysis

Dennis dkorpel at gmail.com
Tue Sep 3 16:37:32 UTC 2024


On Tuesday, 3 September 2024 at 03:00:20 UTC, Richard (Rikki) 
Andrew Cattermole wrote:
> I've done an almost complete rewrite, I expect this to be close 
> to the final version:

The description is getting clearer every revision, props for 
that. But it's also becoming increasingly hard for me to rhyme 
the proposal with the complaints of DIP1000.

Most of the DIP is spent on the 'multiple outputs' problem for 
separate compilation, inventing a meticulous function signature 
syntax to capture all kinds of possible assignments between 
parameters, globals, and the return value. And while this does 
solve the limitation that a `swap` function on `scope` values 
being impossible with DIP1000, it doesn't address other woes:

### Simple safe D

A common sentiment was "I don't care for @nogc @safe, keep the 
language simple by just using the GC or go @system". While it may 
be hard to believe for some, DIP1000 [is not a breaking change in 
theory](https://forum.dlang.org/post/gnuekdxflffjhwlnnwqr@forum.dlang.org) and leaves GC-based code alone. This proposal however breaks @safe code by design - both DIP1000-based code using `scope` pointers (because of new syntax) and 'regular' GC-based code (because added @live-like semantics).

I agree @live being opt-in per function is unsound, but forcing 
"effectively const" semantics everywhere in a new edition is not 
going to please people just happily using the GC.

### Attribute soup

`return` and `scope` annotations are noisy / confusing, but this 
proposal adds more and jumbles the existing ones in a way that's 
not necessarily easier to understand. For a simple `int* f(int* 
x)` function, the parameter attributes change in the following 
way**:

| DIP1000              | Escape Analysis                 |
|----------------------|---------------------------------|
| `return ref scope`   | `scope @escape(return)`         |
| `return ref`         | impossible***                   |
| `return scope`       | `@escape(return)`               |
| `scope`              | `@escape()` / `scope`           |

It solves the `return scope` and `scope return` problem, but 
might have problems of its own:
- `scope` now means two unrelated things: 'strong relationship' 
and 'default empty escape set'
- `@escape` is the opposite of `@escape()`, which could be 
confusing

** I might be wrong, but if so, that really doesn't bode well for 
the 'communicability' aspect of the lifetime attributes, which 
the DIP tries to address

*** That's what I take from "Error the parameter `ptr` cannot 
have an escape set that includes `__unknown` and be marked as 
having a strong relationship `scope`"

### Composability with respect to structs

Explicitly unaddressed

> Elements in an array, fields in a class/struct/union are 
> conflated with the variable that stores them in.

### Transitive scope

Not mentioned.

All in all, I feel the DIP is too focussed on addressing one 
issue (multiple outputs) while neglecting others. The most 
pressing issue is that many people simply don't want D to become 
like Rust. DIP1000 and @live at least leave 'regular' GC-based D 
mostly alone: just don't take the address of local variables in 
`@safe` functions and you're good. It would be really good if 
whatever 'escape analysis' D ends up boasting (if any), it would 
be for the benefit of specialized library types (e.g. 
`RefCounted(T)`) without complicating common pointer/array 
operations in `@safe` code.


More information about the dip.ideas mailing list