May 19, 2022
On 5/19/2022 12:30 AM, Dukc wrote:
> One hole that remains: https://forum.dlang.org/thread/kazglmjwsihfewhscioe@forum.dlang.org
> 
> According to a reply, the current langauge implementation does not cause anything special to happen, but it is still undefined behaviour in `@safe` code if we go by the spec.

I'm aware of that, but if the user selects "ignore the asserts" then he assumes the risk of what happens if the assert would have otherwise tripped.

Just like if the user turns off array bounds checking.

You want an option for it to continue and be defined behavior. Others have argued for this, too, but that makes it kinda pointless to have.
May 19, 2022
On 5/19/2022 3:15 AM, Siarhei Siamashka wrote:
> Regarding safety and avoiding various sources of undefined behavior. Do you agree that "Implementation Defined: The built-in associative arrays do not preserve the order of the keys inserted into the array. In particular, in a foreach loop the order in which the elements are iterated is typically unspecified." from https://dlang.org/spec/hash-map.html can be a source of bugs in the user code?

Yes.

But still, languages draw a distinction between implementation defined and undefined.

There are many implementation defined behaviors in D, like the precise layout of struct fields.
May 19, 2022

On Thursday, 19 May 2022 at 18:39:51 UTC, Walter Bright wrote:

>

On 5/19/2022 12:30 AM, Dukc wrote:

>

One hole that remains: https://forum.dlang.org/thread/kazglmjwsihfewhscioe@forum.dlang.org

According to a reply, the current langauge implementation does not cause anything special to happen, but it is still undefined behaviour in @safe code if we go by the spec.

I'm aware of that, but if the user selects "ignore the asserts" then he assumes the risk of what happens if the assert would have otherwise tripped.

Agreed. But asserts are often used without regard for performance, because it's assumed they are removed from release code. Which puts pressure to disable them from a release build

>

Just like if the user turns off array bounds checking.

We can do a bit better. If an assert trips, the program will go to unknown state, and there's no telling what it will do. But that's still not quite the same as undefined behaviour. If the program trips an assert in @safe code, it probably won't cause a buffer overflow vulnerability, because @safe would almost certainly have detected a vulnerability if one existed. But if the spec says "undefined behaviour", the compiler is allowed to optimise so that it creates such a vulnerability - see the linked thread for an example. I know the current compilers do not do that, but the spec allows doing so in the future.

May 20, 2022

On Thursday, 19 May 2022 at 20:17:36 UTC, Dukc wrote:

>

On Thursday, 19 May 2022 at 18:39:51 UTC, Walter Bright wrote:

>

On 5/19/2022 12:30 AM, Dukc wrote:

>

[...]

I'm aware of that, but if the user selects "ignore the asserts" then he assumes the risk of what happens if the assert would have otherwise tripped.

Agreed. But asserts are often used without regard for performance, because it's assumed they are removed from release code. Which puts pressure to disable them from a release build

>

Just like if the user turns off array bounds checking.

We can do a bit better. If an assert trips, the program will go to unknown state, and there's no telling what it will do. But that's still not quite the same as undefined behaviour. If the program trips an assert in @safe code, it probably won't cause a buffer overflow vulnerability, because @safe would almost certainly have detected a vulnerability if one existed. But if the spec says "undefined behaviour", the compiler is allowed to optimise so that it creates such a vulnerability - see the linked thread for an example. I know the current compilers do not do that, but the spec allows doing so in the future.

Isn't the advice to use enforce for handling/verifying input in release builds and assert for development builds though?
Yeah, it's violating DRY if a particular check needs to be done in both development and release, but then one can skip the assert and just do enforce, no?

May 20, 2022

On Thursday, 19 May 2022 at 18:42:11 UTC, Walter Bright wrote:

>

On 5/19/2022 3:15 AM, Siarhei Siamashka wrote:

>

Regarding safety and avoiding various sources of undefined behavior. Do you agree that "Implementation Defined: The built-in associative arrays do not preserve the order of the keys inserted into the array. In particular, in a foreach loop the order in which the elements are iterated is typically unspecified." from https://dlang.org/spec/hash-map.html can be a source of bugs in the user code?

But still, languages draw a distinction between implementation defined and undefined.

Some programming languages just maintain the order of insertion (Ruby, Crystal, Python, ...) for their associative arrays and this makes their behavior much more predictable and friendly to the developers.

Go intentionally randomizes the order of iteration over elements from its associative arrays, so that the unpredictable nature of it is much more visible to the developers and can be caught by unit tests.

Every little bit helps to improve safety. You skipped my comment about default unstable sort in Phobos, but such decision also erodes safety to some extent.

May 20, 2022

On Tuesday, 2 November 2021 at 17:27:25 UTC, Dr Machine Code wrote:

>

It got asked on reddit sub but for those that aren't active too, I'd like you opinions. Please don't get me wrong, I also love D, I've used it everywhere I can and I'd say it's my favourite language (yes I have one...) but I'm as as the reddit's OP, trying to understand why it's unpopular. Rust and Go seeming to be getting more and more users. I think it's due to large ecosystem and the big corporations with deep pockets that pushes them. But I'd like to know you all opinions

I decided not to question the whys... D simply follows it's "winding" path (like Paul McCartney's Beatles song).

I use it as an scripting language and I simply wait for some productive "things" to be incorporated one day: named parameters, strings interpolation, unlimited UFCS, null safety (or Optional/Some/None native support, or union types or whatever D decide to do), better optional typing inference (at least, as powerful as dart or typescript or ...), nice D debugger inspector (at least, as powerful as java or javascript or c# or ...).

I'm not the one to be involved in D experts brainy discussions.

Languages are tools... just use the one that fits your needs. It can be D or not.

May 20, 2022

On Friday, 20 May 2022 at 07:01:09 UTC, Siarhei Siamashka wrote:

>

Go intentionally randomizes the order of iteration over elements from its associative arrays, so that the unpredictable nature of it is much more visible to the developers and can be caught by unit tests.

I'm not sure how a unittest can catch it, because even if the order is randomized then it can in theory end up being ordered.

May 20, 2022

On Friday, 20 May 2022 at 09:26:58 UTC, bauss wrote:

>

On Friday, 20 May 2022 at 07:01:09 UTC, Siarhei Siamashka wrote:

>

Go intentionally randomizes the order of iteration over elements from its associative arrays, so that the unpredictable nature of it is much more visible to the developers and can be caught by unit tests.

I'm not sure how a unittest can catch it, because even if the order is randomized then it can in theory end up being ordered.

D unittest (save as "main_test.d" and run as "rdmd -unittest main_test.d"):

unittest {
	// Create an associative array
	auto a = ["Alice": true, "Bob": true, "Charlie": true];

	// Iterate over the associative array and save keys
	string[] s;
	foreach (k, _ ; a)
		s ~= k;

	// If the order is preserved, then the first retrieved name will be "Alice"
	assert(s[0] == "Alice");
}

void main() {
}

Go unittest (save as "main_test.go" and run as "go test main_test.go"):

package main

import "testing"

func TestAssocArrayOrder(t *testing.T) {
	// Create an associative array
	a := map[string]bool{"Alice": true, "Bob": true, "Charlie": true}

	// Iterate over the associative array and save keys
	var s []string
	for k, _ := range a {
		s = append(s, k)
	}

	// If the order is preserved, then the first retrieved name will be "Alice"
	if s[0] != "Alice" {
		t.Fatalf("The first returned key was not 'Alice'! The actual order: %v", s)
	}
}

In Go this unittest will sporadically fail and the problem will be detected reasonably fast. Of course, assuming that the unit tests are run regularly.

May 20, 2022

On Friday, 20 May 2022 at 12:45:07 UTC, Siarhei Siamashka wrote:

>

D unittest (save as "main_test.d" and run as "rdmd -unittest main_test.d"):

unittest {
	// Create an associative array
	auto a = ["Alice": true, "Bob": true, "Charlie": true];

	// Iterate over the associative array and save keys
	string[] s;
	foreach (k, _ ; a)
		s ~= k;

	// If the order is preserved, then the first retrieved name will be "Alice"
	assert(s[0] == "Alice");
}

void main() {
}

The problem quickly shows when you dig slightly deeper. Import another module. It fails. Add -i, it work, but now run the unittests of the module you import. Bonus point: dependencies are not tracked properly so you might be running stale code.

May 20, 2022
On 5/20/2022 12:01 AM, Siarhei Siamashka wrote:
> You skipped my comment about default unstable sort in Phobos, but such decision also erodes safety to some extent.

The language and Phobos are two different things.