May 11, 2022

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.
  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?

- `shared static this()` vs `static this()` is another trap.
  Honestly would have preferred `__threadlocal`. It's not like being thread-local is something completely normal or without consequence for platform support.

- Some features lack an escape hatch, notably `pure`. pure leaks into identifiers, like `pureMalloc`. Trying to add `pure` fails on a large codebase.

- `@safe`/`@trusted`/`@system` is good but the definition of what `@trusted` means has to be remembered from the programmer.
  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.

- 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.
  Phobos take short names for itself, this leads to pretty complicated operations having a small screen estate.

- `assert(false)` being different and not removed by `-release`. Keyword reuse seems entrenched but honestly a "crash here" keyword would be more readable.
  It is really 3 different things: assert, crash, and unreachable.

Otherwise D is glorious and get syntax and usability right, which puts it ahead of almost every other language.

May 11, 2022

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.

Also, if you intend to use the responses for planning purposes, keep in mind that people who read the forums regularly are more informed about pitfalls than other users. Forum-dwellers have a richer understanding of the landscape and probably view the feature set in a different light.

May 11, 2022
On 5/11/22 12:20, Ola Fosheim Grøstad 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.
>
> Also, if you intend to use the responses for planning purposes

No. :) I was hoping to get responses like "I come from Python and have no idea what templates are", "I come from C and have no idea what reference types are." Or exceptions, ranges, etc.

Ali

May 11, 2022
On 5/11/22 11:27, templatedperson wrote:

> I don't know if this counts as a feature, but reading the standard
> library documentation was especially difficult. There are a ton of
> `auto`s everywhere and function signatures are hard to read because of
> that. I got used to confusing function signatures in a week or two, but
> it made me consider not using D.

I agree with readability problems. And although you likely know why there are 'auto's everywhere in the standard library, I want to touch on that for others who may not know.

Although templates are great, they bring naming problems:

- Some names are overly complex and expose implementation details.

- Some names are unmentionable because the implementation chose to make the return type a nested struct.

import std.range;
import std.algorithm;

struct MyStruct {
}

void main() {
  auto arr = [ MyStruct() ];
  auto r = arr.map!(o => o).cycle;
  pragma(msg, typeof(r));
}

The type of the range object 'r' happens to be the scary

  Cycle!(MapResult!(__lambda2, MyStruct[])).

But make a change e.g. by adding .enumerate to the expression

  auto r = arr.map!(o => o).enumerate.cycle;

and now the type is very different (and deceptively simpler!):

  Cycle!(Result)

So, there is nothing else to do in current D but to have 'auto' return types.

Ali

May 12, 2022
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.
>
> To make it more meaningful, what is your experience with other languages?
>
> Ali

Every time I think I understand D, I don't.

Cool useful library functions like sumElement that magically don't work on static arrays.

'private' is per module, not per class, making it pretty much useless for preventing incorrect access and using .

completely different semantics for a class vs a struct. Is it a reference? Is it a value? Look up the entire declaration and have the entire Dlang manual open to find out.

As far as I remember, no automatic RAII support, even though it's insanely useful. You have to manually write scope(end) stuff which means any person forgetting one is now leaking memory.

Writing output in a deconstuctor (for learning) works. But then you accidentally combine two strings inside it and the garbage collecter crashes without a stack trace.

Documentation. Documentation. Documentation.

I just realized foreach copies by value by default. Maybe. Sometimes. When? I don't even know anymore. Because I "thought" I had to use foreach(ref) to be able to affect the original data structure (because by value means its a copy, right?). Except somehow everything has been working just fine, mutating the original structure/array from inside foreach and adding foreach(ref) makes no changes. Will it be faster? Maybe... who knows.

And I really like D! But there's lots of "WTF" moments. There's so much I have to Google for a single forum post with dead links from 2014 which is only 30% like my use-case that describes my error or problem.
May 12, 2022
On Thursday, 12 May 2022 at 01:06:02 UTC, Christopher Katko wrote:
> completely different semantics for a class vs a struct. Is it a reference? Is it a value? Look up the entire declaration and have the entire Dlang manual open to find out.
>
> As far as I remember, no automatic RAII support, even though it's insanely useful.

class = virtual functions

struct = RAII


May 11, 2022

On 5/11/22 9:06 PM, Christopher Katko wrote:

>

I just realized foreach copies by value by default. Maybe. Sometimes. When? I don't even know anymore. Because I "thought" I had to use foreach(ref) to be able to affect the original data structure (because by value means its a copy, right?). Except somehow everything has been working just fine, mutating the original structure/array from inside foreach and adding foreach(ref) makes no changes. Will it be faster? Maybe... who knows.

ref can be confusing depending on the type. foreach indeed does everything by value unless you specify ref. But some types "act like" a ref. Remember, the copy is a shallow copy. So a "copy" of an array slice, for example, still refers to the original elements.

-Steve

May 12, 2022

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.

I don't know the progress of interface to C++.
I want to use my C++ functions in d.

C++'s concept and ... is very convenient.

May 12, 2022

On Thursday, 12 May 2022 at 02:35:50 UTC, zjh wrote:

>

C++'s concept and ... is very convenient.

And C++'s stackless coroutine.

May 12, 2022

On Thursday, 12 May 2022 at 02:40:09 UTC, zjh wrote:

>

And C++'s stackless coroutine.

Another one,
I hope the error message can be adapted to different languages like chinese/german/russion/turkish etc.