| |
| Posted by H. S. Teoh in reply to Guillaume Piolat | PermalinkReply |
|
H. S. Teoh
Posted in reply to Guillaume Piolat
| On Wed, May 11, 2022 at 06:43:39PM +0000, Guillaume Piolat via Digitalmars-d-learn wrote:
> On Wednesday, 11 May 2022 at 05:41:35 UTC, Ali Çehreli wrote:
> > What are you stuck at? What was the most difficult features to understand? etc.
>
> - How to do deterministic destruction with programs that use
> everything (struct / class / dynamic dispatch / GC / manual /
> etc). This requires to understand what the runtime does, what the
> gc does.
I'm not sure I fully understand what you're trying to say here. How does GC mix with deterministic destruction? I thought by the very nature of GC, destruction is non-deterministic. If you want deterministic destruction, don't use the GC...?
> Interesting nonetheless.
>
> - Some traps. Accidental TLS is a thing, top-level should probably
> not be silently TLS.
> People will loose hours on this completely preventable thing.
> What was the idea, optimize code without people knowing?
Why is TLS by default a problem?
It's not really for optimization, AIUI, it's more for thread safety: module-global state is TLS by default, so you don't accidentally introduce race conditions.
> - `shared static this()` vs `static this()` is another trap.
One is per-process, one is per-thread. Why is this a trap?
[...]
> - Some features lack an escape hatch, notably `pure`. pure leaks
> into identifiers, like `pureMalloc`. Trying to add `pure` fails on
> a large codebase.
IMNSHO, pureMalloc is a code smell. It should not have been added in the first place.
But more to the point: pure is of limited utility. Perhaps the most useful application is the initialization of immutable data structures constructed by a mutable factory method. But other than that, I don't find very much use for it in practice. I wouldn't sweat it if I couldn't easily add `pure` to an entire codebase -- it hardly makes any difference anyway.
> - `@safe`/`@trusted`/`@system` is good but the definition of what
> `@trusted` means has to be remembered from the programmer.
But isn't that the nature of all escape hatches? An escape hatch by definition means you're operating outside of the abstractions provided by the compiler; IOW you're on your own and you take responsibility for any problems that you may inadvertently introduce by using the escape hatch.
> For example `Mutex.lock()` is `@trusted`, it could have been
> `@system` to let user review their usage of locks. You have to
> wonder "can a lock()/unlock() corrupt memory?". People can use
> that to mean "@reviewed" instead. Because it is up to us, the
> exact meaning will float in the D subcultures. A function which
> has been marked `@trusted` does not receive any review whan
> changed later. It will not mean the same as `@trusted` in
> another codebase.
IMNSHO, @trusted should never be used in public-facing APIs. It's really an implementation detail -- "this code does something using potentially dangerous operations, but we reviewed it carefully to make sure it's safe to call from @safe code". The caller does NOT need to know this; as far as the caller is concerned, it's calling a @safe function. That's all it knows and all that it should care about. How this @safe function is implemented -- using completely @safe operations or potentially dangerous operations (@trusted) isn't something the user should care about. That's something the author of the module needs to care about, but it's none of the users' business.
IOW, public APIs should always be @safe or @system. @trusted should only appear on internal APIs.
> - Generic code typically has bad names (domain-less) and worse
> usability. It's often not pretty to look at. Mostly cultural,
> since D has powerful templates so they had to be everywhere. UFCS
> chains are not that convincing when you are worried about
> maintenance.
I'm puzzled by this. I use (and write!) generic code all the time and they have been great. UFCS chains are awesome; they allow me to express a series of data transformations in a very concise way, so that I can keep the high-level logic of the function readable, without having to break it into separate functions. This, plus `auto` type inference, makes the code *more* maintainable, IME, because I can shuffle components of the UFCS chain around without needing to rewrite the types of a bunch of helper functions.
So I'm curious, what exactly is it about UFCS chains that make it less maintainable?
> Phobos take short names for itself, this leads to pretty
> complicated operations having a small screen estate.
I'm also puzzled by this. Why is this a problem?
> - `assert(false)` being different and not removed by `-release`.
> Keyword reuse seems entrenched but honestly a "crash here" keyword
> would be more readable.
noreturn crashHere() { assert(false); }
void main() {
...
crashHere; // ;-)
}
[...]
> Otherwise D is glorious and get syntax and usability right, which puts it ahead of almost every other language.
Can't argue with that.
T
--
MACINTOSH: Most Applications Crash, If Not, The Operating System Hangs
|