November 02, 2021
On Tuesday, 2 November 2021 at 01:18:02 UTC, deadalnix wrote:
> 9. Functional programming and attribute soup. Because it is not possible to define attribute in a way that depends to functions passed as argument, it is not possible to compose anything in a functional way without assuming that everything is impure, throw and uses the GC and more.

I agree with almost all of these, but this one especially.

A side effect of the lack of attribute polymorphism is that instead of making things take function parameters, you make them templates with alias parameters, making template bloat even worse.  For an idea of the impact this can have: I got a 10% improvement in compile time on a medium-sized codebase by using eager versions of std.algorithm in debug builds.
November 02, 2021
On 01.11.21 23:02, Andrei Alexandrescu wrote:
> 
>> 4. The way scope & return & ref apply to types is completely consistent. This enables me to advise that when people have problems understanding it, to rewrite their example code in terms of raw pointers, as it will behave the same.
> 
> I very much wish this is true and useful.

I think DIP 1000 etc. is actually a prime example of non-orthogonal language design, even if we ignore the issues with `ref` that have already been brought up. Lifetimes are not orthogonal to aggregates and function calls. To avoid such a situation, Rust allows explicit lifetime parameters.

In general, if for type checking, the compiler tracks information that can't be passed along when calling functions or when storing data in a struct/class, there will inevitably be trouble.

I have been guilty of implementing quick hacks like that myself in order to get code to type check before the paper deadline, but this kind of thing always comes back to bite users and ultimately the language designer. [1]

[1] https://github.com/eth-sri/silq/issues/28
November 02, 2021
On Monday, 1 November 2021 at 21:41:29 UTC, Walter Bright wrote:
> 1. basic types, structs, and arrays are interchangeable. But I couldn't add tuples to the list, because the function call ABI for structs is "special". Urgh.

Why? Shouldn't a tuple just be syntactical suger for a regular struct with special naming conventions (mangling)?

November 02, 2021
On Tuesday, 2 November 2021 at 01:00:27 UTC, Walter Bright wrote:
> On 11/1/2021 3:02 PM, Andrei Alexandrescu wrote:
>>> 1. basic types, structs, and arrays are interchangeable. But I couldn't add tuples to the list, because the function call ABI for structs is "special". Urgh.
>> 
>> 1a. Hash tables have a number of language magic hacks (particularly concerning keys that have statically-sized array types) that are thoroughly inconsistent with the language rules.
>
> True, but hash tables are not basic types, structs, arrays or tuples!

I hear the sound of bagpipes in the background (see no true scotsman).
While it is true that hash tables are not basic, they are treated and advertised as such by the language itself.



November 03, 2021
On Tuesday, 2 November 2021 at 03:38:02 UTC, Walter Bright wrote:
> Thank you. This is a great list. I would appreciate it if you could make a bugzilla entry for each one, along with a piece of example code.
>
> Some specific comments below:
>

As general answer, you request for bug report for these issues. Most of them do have bug report, several of them you dismissed as being issues to begin with.

> On 11/1/2021 6:18 PM, deadalnix wrote:
>> 1. enum binary ops and final switch. final switch assume an enum take a finite set of values as declared in the enum, but many more value can be obtained using binary ops.
>
> Not sure what to say here. enums have more than one use:
>
> 1. enumerate all values of a particular type
> 2. enumerate some specific values of a particular type
>
> Only use final for case (1).
>

And here we are getting at the root of the problem.

See, your use case 1 and 2 are all well and good. But an enum can't be both. It has to be one or the other. Pretending this is not a problem is exactly why these proliferate and this is by far the biggest tax on D's user time. Nothing comes close.

Think about it. Any code using an enum now must make a guess as to what the rest of the program as a whole does. It is already bad within a given application, but it is impossible for a library writer, or generic code to even consider doing that without defeating its whole purpose.

Types and other languages constructs are there to help the user by providing guarantee. invariant that the user knows won't be broken. When that is not the case, then these construct just become a tax on the user, which need to learn and know about them, but do not get any significant benefit from them.

1 and 2 are mutually exclusive. That's it, really. And for as long as you don't think this is a problem - while many people in this thread tell you it is - this will continue to proliferate.

>> 3. type qualifier transitivity and templates. template will consider types with different qualifier as disjoint, which seems like they should, until you try to write a container library or try to get range to interract with type qualifier.
>> 
>> This one is IMO the #1 problem with D, hands down. Nothing comes even remotely close. We don't have a decent set of collection to use because of it, and even worse, it's not even possible to write one.
>
> I beg of you and Andrei to produce a canonical example and place it in bugzilla. Perhaps I misunderstood Andrei when he said it would be resolved when we had copy constructors. Well, we have copy constructors now.
>

It's really simple.

Vector!T and Vector!(const T) are completely disjoint types. there is no way to get `const Vector!T` to be the same as `const Vector(const T)`. We aren't just talking about implicit conversion here, because this will break when things are passed by ref. There needs to be a way for both to be understood as having the same underlying reality by the compiler.

Basically, ranges and collection needs to behave just like the builtin slice do, but as far as i know, there is no way to do this at the moment.

```d
Vector!int v;

void foo(ref vector!(const int) x) {
    // ...
}

foo(v); // There needs to be a way to make this work.
```

I invested a fair amount of time last month into trying to make a collection library for phobos, but there is just no way to make this work that anyone could come up with.

> That's actually not a problem with the language. It's a problem with Phobos, one I've been trying to kill with fire for 10 years no.
>

No, no, no and no.

The standard library is part of the language. What does it change when I use D if the problem is in phobos or DMD? It doesn't. The impact is the same nevertheless: generic code needs to special case string or it is buggy.

> Yes, that's correct. I know of *no* way to construct a shared object without going into @system code. Just like there's no way to implement malloc() without dirty pointer manipulation. Note that in @safe code neither can be done. I propose that this is not a further issue.
>

There is not at the moment. You need one more type qualifier indicating a unique access to a subgraph of object. Then promoting that edge to shared makes the object shared. Same goes for immutable.

This also solve a ton of other problems, everything that is handled by the @live proposal to begin with, but also consumer/producer type object sharing, and a ton more.

> Phobos has a number of incomprehensible isxxxxx() functions. They are not the language's fault, though. Nor are they my fault, as I never reviewed them. But they are my responsibility.
>

Phobos is part of the language. And it disagrees with DMD. This is a problem. This very one has caused me to waste almost a full day of work a few weeks ago because DMD started to pick the wrong template overload in some test because it got smart enough to constant fold something to 1, then true.

1 2 3 4
Next ›   Last »