January 15, 2023

On Saturday, 14 January 2023 at 22:06:58 UTC, Timon Gehr wrote:

>

On 1/14/23 22:24, Walter Bright wrote:

>

On 1/14/2023 10:17 AM, Timon Gehr wrote:

>

On 1/12/23 03:32, Walter Bright wrote:

>

Me too. You all know my practice of putting links to more information in code I write. I've been doing that for a long time. I've found a lot of those older links to Microsoft documentation have become deadends, and google doesn't reveal any replacement.

It's just gone. Poof.

https://archive.org/web/

If they were there, wouldn't google have found them? They disappeared around 2001.

I don't know. I don't remember being pointed towards archived webpages by google, but you can just enter the links there directly and find out.

I never once received a Google query result that pointed to archive.org

It's always me having to explicitly visit the site and enter the url

January 15, 2023

On Saturday, 14 January 2023 at 12:15:46 UTC, Dukc wrote:

>

The distinction between recoverable and unrecoverable errors is still relevant. The library author is only picking the default. User still needs to make the decision.

Which they never make. I've never seen an 'assert' preceding a call to to!int in real code.

January 20, 2023

On Friday, 6 January 2023 at 13:43:33 UTC, Patrick Schluter wrote:

>

On Thursday, 5 January 2023 at 23:09:43 UTC, H. S. Teoh wrote:

>

On Thu, Jan 05, 2023 at 10:35:37PM +0000, areYouSureAboutThat via Digitalmars-d wrote: [...]

>

to be honest, I've never needed a static array in D.

:-D I haven't really used static arrays very much myself, but occasionally they're useful. E.g. in one project where I use a lot of 4-element int arrays, using static arrays for them reduces a lot of GC pressure, and also gives me nice by-value semantics (useful in certain contexts).

[...]

The annoying and shameful thing about this static array size auto-determination is that it is a feature that even K&R C was able to provide. We will probably see men on the Moon again before D is able to do it ;-)

It has been implemented:


scope int[] arr = [10, 20, 30];

In my opinion, it's a much better design than this:


int[$]    arr = [10, 20, 30];
int[..]   arr = [10, 20, 30];
int[auto] arr = [10, 20, 30];

Link: https://dlang.org/changelog/pending.html#dmd.scope-array-on-stack

January 20, 2023

On Friday, 20 January 2023 at 15:41:20 UTC, Ki Rill wrote:

>

[...]
It has been implemented:
[...]
Link: https://dlang.org/changelog/pending.html#dmd.scope-array-on-stack

"Change Log: 2.103.0" ???

https://dlang.org/changelog/2.102.0.html#log_float_double_implementations
https://dlang.org/changelog/pending.html#log_float_double_implementations

One change in two versions?

February 07, 2023

On Monday, 2 January 2023 at 22:53:30 UTC, Walter Bright wrote:

>

On 12/31/2022 2:28 AM, Max Samukha wrote:

>

For types that require runtime construction, initializing to T.init does not result in a constructed object.
The idea is to:

  1. have construction that cannot fail. This helps avoid things like double-fault exceptions

Here, it would help if you clarified what you mean by double-fault exceptions because I just tried to look it up and was lead to tennis and CPU interrupts.
I have a rough idea of what you man and could guess, but I could just ask.

Construction that cannot fail sounds nice, and if an aggregate type constructor can pull it off, it should go for it. But this sounds a lot like nothrow and not something the language should impose. I know people dislike complicated rules because exceptions (to rules, not Exceptions), but a possibility could be that nullary struct constructors must be nothrow or be annotated throw.

>
  1. have initializers that can be placed in read only memory

I’m not saying that init isn’t a great idea. It’s just that init shouldn’t be used explicitly, but only as “the thing a constructor must act on to produce a valid object”. A “naked” init may be an object that violates its invariants.
An example would be a string optimized for short values (SSO). It has (at least) a pointer to data, a fixed-size internal buffer, and a length with the invariant: pointer = &buffer[0] if and only if length <= buffer.length. A SSO’s init cannot possibly represent the empty string unless we allow pointer to be null to represent it. This means that a SSO has two representations for the empty string. Or we interpret the null data pointer as a null string. In any case, we get something we don’t want.

>
  1. have something to set a destroyed object to, in case of dangling references and other bugs

If a NaN state is available, use that. (I don’t think NaN states are bad; I actually think that every built-in type except bool should have one: Signed and unsigned integer types could use T.min and T.max. Setting those to 0 is bad because in a lot of contexts, 0 is a perfectly reasonable value, whereas int.min and size_t.max rarely are.

>
  1. present to a constructor an already initialized object. This prevents the common C++ problem of adding a field and forgetting to construct it in one of the overloaded constructors, a problem that has plagued me with erratic behavior

The problem is, C++ does not complain about you forgetting that field. (For other people:) In C++, if a struct field is of built-in type (e.g. int) and you forget to initialize it, it has an unspecified value. Aggregate types call a nullary constructor and fail to compile if no nullary constructor exists.
Now, even if there is a nullary constructor, it might not be what you want.

Requiring initialization of every field in every constructor is what C++ lacks.

>
  1. provide a NaN state. I know many people don't like NaN states, but if one does, the default construction is perfect for implementing one.

One question is penalty for the NaN state. Floating-point NaN values are supported by hardware. If we declared int.min and size_t.max as their respective types’ NaN, we’d probably specify existing behavior. The issue is, making them sticky incurs costs.

Floating-point NaN serves two purposes: Indicate an invalid result and error propagation through the program execution. Integer min/max values are used for the former already. People don’t like them do the latter probably.

Another issue of floating-point NaN values is their weird comparison behavior. I understand the argument that x == y should be false if x and y happen to be NaN, but if (x == double.nan) being silently always false feels broken.

>
  1. it fits in well with (future) sumtypes, where the default initializer can be the error state.

I’m curious what comes out of this.

>

An alternative to factory functions is to have a constructor with a dummy argument. Nothing says one has to actually use the parameters to a constructor.

Or we could just allow a nullary struct constructor. It should be backwards compatible (at least to a large degree) if D defines this() @… {} when this() is not defined explicitly (as @disabled or otherwise). An explicit this() should be nothrow if failure is a problem. With throw as an attribute, this() throw { … } is a kind of: “Sorry, Walter, I know you wanted the best for me, but for this type, it’s too wrong to be right.”

That way, a declaration like T x; will call a constructor that – in almost all cases – does nothing, in the remaining cases, in almost all cases does something that cannot fail.

Sorry for the late answer.

19 20 21 22 23 24 25 26 27 28 29
Next ›   Last »