www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Which language constructs could be done as a library if we accept some

reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
If there was a majority in favour of D3, with breaking changes, 
and a strong focus on meta-programming, then it would make a lot 
of sense to streamline the language.

What would that consist of? I would say:

1. Figuring out what the missing bits for meta-programming are.

2. Taking out all language constructs that can be implemented as 
a library feature.

3. Add some syntactical sugar where necessary (mapping to library 
features).

Which features that are currently in the language could with some 
adjustments be done as a library feature?

Hashtable?

Dynamic array?

Slices?

Shared?

Class?

Others language features…?

(I think all these could be done if meta-programming facilities 
were strengthened.)

What do you think?
Nov 28 2021
next sibling parent reply Elronnd <elronnd elronnd.net> writes:
On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim Grøstad 
wrote:
 Which features that are currently in the language could with 
 some adjustments be done as a library feature?

 Class?
Classes should be a language feature in any case, for performance reasons
Nov 28 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 28 November 2021 at 21:01:53 UTC, Elronnd wrote:
 On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim 
 Grøstad wrote:
 Which features that are currently in the language could with 
 some adjustments be done as a library feature?

 Class?
Classes should be a language feature in any case, for performance reasons
A good compiler will detect standard library features and use a fast-path/optimized-path for those. So there should be no performance impact.
Nov 29 2021
parent reply user1234 <user1234 12.de> writes:
On Monday, 29 November 2021 at 11:12:16 UTC, Ola Fosheim Grøstad 
wrote:
 On Sunday, 28 November 2021 at 21:01:53 UTC, Elronnd wrote:
 On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim 
 Grøstad wrote:
 Which features that are currently in the language could with 
 some adjustments be done as a library feature?

 Class?
Classes should be a language feature in any case, for performance reasons
A good compiler will detect standard library features and use a fast-path/optimized-path for those. So there should be no performance impact.
static casts, devirtualization, are reasons for built-in classes. Things for classes that can be done in the library are already done there, e.g dynamic casts.
Nov 29 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 29 November 2021 at 12:30:42 UTC, user1234 wrote:
 static casts, devirtualization, are reasons for built-in 
 classes.
Casting is a weakness in D (in comparison to C++) so that is an area that needs improvement. I am not sure if devirtualization is a good argument, as you should be able to have immutable pointers and "devirtualize" those in general. Also, since it would be a standard library construct a good compiler could have a special path for those. So it should remain the same.
 Things for classes that can be done in the library are already 
 done there, e.g dynamic casts.
I am not so sure. If we give structs inheritance and some other minor adjustments then I think ```class``` could be done as a library construct just as well as the current builtin.
Nov 29 2021
parent reply user1234 <user1234 12.de> writes:
On Monday, 29 November 2021 at 12:51:47 UTC, Ola Fosheim Grøstad 
wrote:
 On Monday, 29 November 2021 at 12:30:42 UTC, user1234 wrote:
 static casts, devirtualization, are reasons for built-in
Also, since it would be a standard library construct a good compiler could have a special path for those. So it should remain the same.
If there must be a special path then it's already a failed library solution, not to say a lie. You make think to the user that classes is a library thing but it's not.
Nov 29 2021
next sibling parent user1234 <user1234 12.de> writes:
On Monday, 29 November 2021 at 13:11:12 UTC, user1234 wrote:
 On Monday, 29 November 2021 at 12:51:47 UTC, Ola Fosheim 
 Grøstad wrote:
 On Monday, 29 November 2021 at 12:30:42 UTC, user1234 wrote:
 static casts, devirtualization, are reasons for built-in
Also, since it would be a standard library construct a good compiler could have a special path for those. So it should remain the same.
If there must be a special path then it's already a failed library solution, not to say a lie. You make think to the user that classes is a library thing but it's not.
BTW, to be clear: yes I know that AliasSeq borrows such a special path in the compiler...but that rather tendd to show that the opposite is required: from library to builtin feature.
Nov 29 2021
prev sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 29 November 2021 at 13:11:12 UTC, user1234 wrote:
 If there must be a special path then it's already a failed 
 library solution, not to say a lie. You make think to the user 
 that classes is a library thing but it's not.
No lies. Compiler optimizations that focus on standard library constructs are not uncommon and makes a lot of sense: these constructs occur frequently. It is still a library solution. Change the library implementation, it will still work, but the optimizer may not recognize it. Nothing unusual about this.
Nov 29 2021
prev sibling next sibling parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim Grøstad 
wrote:
 If there was a majority in favour of D3, with breaking changes, 
 and a strong focus on meta-programming, then it would make a 
 lot of sense to streamline the language.

 What would that consist of? I would say:

 1. Figuring out what the missing bits for meta-programming are.

 2. Taking out all language constructs that can be implemented 
 as a library feature.

 3. Add some syntactical sugar where necessary (mapping to 
 library features).

 Which features that are currently in the language could with 
 some adjustments be done as a library feature?

 Hashtable?

 Dynamic array?

 Slices?
I think these could've been implemented as structs, then the only change would be to rewrite any T[] to Array!T, given structs are able completely replicate their behavior. This in turn can lessen the coupling between compiler and the implementation, and allow other potential implementations. For example using custom gc, or making them rc counted (given rc problems are solved), or having a backing store location implementation hidden by interface allowing you to use different storing methods. There might be some compatibility problems though. I.e. you won't have any breakage here, though you might consider removing them as language constructs, and have the said breakage. Best regards, Alexandru.
Nov 28 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Sunday, 28 November 2021 at 21:56:37 UTC, Alexandru Ermicioi 
wrote:
 I think these could've been implemented as structs, then the 
 only change would be to rewrite any T[] to Array!T, given 
 structs are able completely replicate their behavior.
Yes, that should be the goal. Improve on meta-programming facilities and extending structs with more capabilities to make the language both smaller and more powerful. And exactly right, "T[…]" could be syntactical sugar that maps onto a standard library type, making the language more uniform and adaptable.
 I.e. you won't have any breakage here, though you might 
 consider removing them as language constructs, and have the 
 said breakage.
I think one has to accept breakage in order to streamline the language, so it would require D3, but the resulting language should be equally expressive! (I think that ought to be possible.)
Nov 29 2021
parent zjh <fqbqrr 163.com> writes:
On Monday, 29 November 2021 at 11:22:44 UTC, Ola Fosheim Grøstad 
wrote:

 I think one has to accept breakage in order to streamline the 
 language, so it would require D3, but the resulting language 
 should be equally expressive!

 (I think that ought to be possible.)
for `D` better,tolerence `breakage` is OK.
Nov 29 2021
prev sibling next sibling parent reply bauss <jj_1337 live.dk> writes:
On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim Grøstad 
wrote:
 If there was a majority in favour of D3, with breaking changes, 
 and a strong focus on meta-programming, then it would make a 
 lot of sense to streamline the language.

 What would that consist of? I would say:

 1. Figuring out what the missing bits for meta-programming are.

 2. Taking out all language constructs that can be implemented 
 as a library feature.

 3. Add some syntactical sugar where necessary (mapping to 
 library features).

 Which features that are currently in the language could with 
 some adjustments be done as a library feature?

 Hashtable?

 Dynamic array?

 Slices?

 Shared?

 Class?

 Others language features…?

 (I think all these could be done if meta-programming facilities 
 were strengthened.)

 What do you think?
Pretty much anything can be solved in a library, except for things that requires AST/macros.
Nov 29 2021
next sibling parent reply Nick Treleaven <nick geany.org> writes:
On Monday, 29 November 2021 at 11:34:41 UTC, bauss wrote:
 Pretty much anything can be solved in a library, except for 
 things that requires AST/macros.
There is no way to implicitly convert from other types (particularly built-in types) to a struct, and I think Walter is opposed to introducing that. This means no null -> Slice or null -> AA and other implicit conversions. So any library solution would be more awkward to use compared to the current language equivalents.
Nov 29 2021
next sibling parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Monday, 29 November 2021 at 12:47:35 UTC, Nick Treleaven wrote:
 On Monday, 29 November 2021 at 11:34:41 UTC, bauss wrote:
 Pretty much anything can be solved in a library, except for 
 things that requires AST/macros.
There is no way to implicitly convert from other types (particularly built-in types) to a struct, and I think Walter is opposed to introducing that. This means no null -> Slice or null -> AA and other implicit conversions.
But isn't a slice basically a struct with pointer and length? Therefore you can consider that a slice is never null, but rather internal ptr field is, while length is 0. The assoc array could follow same logic, i.e. point to null node. any ops could then be implemented in terms of operator overloading. I mean, the purpose of operator overloading was added to allow user types to simulate built in ones, but what if this is inverted? i.e. have the slices, arrays and aas, be implemented using structs with operator overloading for defining their behavior. This imho should make the compiler code and arch more decoupled and easy to manage compared to current situation. i.e. you won't need all tightly coupled magic hook for aas, arrays, etc. and could focus on improving operator overloading to support built in types behavior (not talking about classes here).
Nov 29 2021
next sibling parent reply Nick Treleaven <nick geany.org> writes:
On Monday, 29 November 2021 at 13:11:47 UTC, Alexandru Ermicioi 
wrote:
 But isn't a slice basically a struct with pointer and length?
 Therefore you can consider that a slice is never null, but 
 rather internal ptr field is, while length is 0.
 The assoc array could follow same logic, i.e. point to null 
 node.
For slices we could just stop supporting null and require `[]` instead, but I expect it would break quite a lot of code. For AAs, `null` is part of its design as a reference type. I'm not sure how you would get around that elegantly.
Nov 29 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 29 November 2021 at 13:22:34 UTC, Nick Treleaven wrote:
 On Monday, 29 November 2021 at 13:11:47 UTC, Alexandru Ermicioi 
 wrote:
 But isn't a slice basically a struct with pointer and length?
 Therefore you can consider that a slice is never null, but 
 rather internal ptr field is, while length is 0.
 The assoc array could follow same logic, i.e. point to null 
 node.
For slices we could just stop supporting null and require `[]` instead, but I expect it would break quite a lot of code. For AAs, `null` is part of its design as a reference type. I'm not sure how you would get around that elegantly.
Yes, that would make a lot of sense. Or you could make the current behaviour more general and add support for "dependent typing" of null-pointers. So, this would work like this: you can specify that an operator is "value dependent", meaning there are two or more implementations that will be selected based on the value of the argument. Is this sufficient to cover the current implementation?
Nov 29 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 29 November 2021 at 14:57:04 UTC, Ola Fosheim Grøstad 
wrote:
 Or you could make the current behaviour more general and add 
 support for "dependent typing" of null-pointers.
Maybe overkill? One step would be to make ```this``` optionally explicit in overloading functions such as ```opIndexAssign```. So you could specify ```opIndexAssign(ref … this, …)``` and modify ```this``` if it is a null pointer. Anyway, seems like such issues could be solved with minor adjustments.
Nov 29 2021
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Monday, 29 November 2021 at 13:11:47 UTC, Alexandru Ermicioi 
wrote:
 But isn't a slice basically a struct with pointer and length?
 Therefore you can consider that a slice is never null, but 
 rather internal ptr field is, while length is 0.
 The assoc array could follow same logic, i.e. point to null 
 node.

 any ops could then be implemented in terms of operator 
 overloading.
You can't overload operators for built-in types, like pointers. So if you do it this way, you would no longer be able to write `ptr[start .. end]`--instead, you'd have to write something like `ptr.slice(start, end)`.
Nov 29 2021
parent Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
On Monday, 29 November 2021 at 13:51:30 UTC, Paul Backus wrote:
 On Monday, 29 November 2021 at 13:11:47 UTC, Alexandru Ermicioi 
 wrote:
 But isn't a slice basically a struct with pointer and length?
 Therefore you can consider that a slice is never null, but 
 rather internal ptr field is, while length is 0.
 The assoc array could follow same logic, i.e. point to null 
 node.

 any ops could then be implemented in terms of operator 
 overloading.
You can't overload operators for built-in types, like pointers. So if you do it this way, you would no longer be able to write `ptr[start .. end]`--instead, you'd have to write something like `ptr.slice(start, end)`.
Sorry, kinda hard to remember that this is thread based conversation. I was talking in context where frontend does lower down built-in types to struct implementations of said builtin types.
Nov 29 2021
prev sibling parent reply bauss <jj_1337 live.dk> writes:
On Monday, 29 November 2021 at 12:47:35 UTC, Nick Treleaven wrote:
 On Monday, 29 November 2021 at 11:34:41 UTC, bauss wrote:
 Pretty much anything can be solved in a library, except for 
 things that requires AST/macros.
There is no way to implicitly convert from other types (particularly built-in types) to a struct, and I think Walter is opposed to introducing that. This means no null -> Slice or null -> AA and other implicit conversions. So any library solution would be more awkward to use compared to the current language equivalents.
Yeah, I'm not really supportive of everything having to be a library. There are far more advantages of having some things built-in, rather than added as a library solution.
Nov 29 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 29 November 2021 at 14:16:56 UTC, bauss wrote:
 There are far more advantages of having some things built-in, 
 rather than added as a library  solution.
What advantages? Keep the language small and make it possible to implement a bug-free compiler.
Nov 29 2021
prev sibling parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 29 November 2021 at 11:34:41 UTC, bauss wrote:
 Pretty much anything can be solved in a library, except for 
 things that requires AST/macros.
I think we can assume that the AST closely matches the core language since we assume «D3». So I think we also can assume the ability to at least construct AST trees programatically (maybe also inspect, but I don't fully understand the implications in relation to ```static if``` etc). This would allow for more elegant and less error-prone creation of facades and interfacing-types (e.g. automatic construction of intelligent smart pointers, APIs for transport over network etc.)
Nov 29 2021
prev sibling next sibling parent reply rumbu <rumbu rumbu.ro> writes:
On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim Grøstad 
wrote:
 If there was a majority in favour of D3, with breaking changes, 
 and a strong focus on meta-programming, then it would make a 
 lot of sense to streamline the language.

 What would that consist of? I would say:

 1. Figuring out what the missing bits for meta-programming are.

 2. Taking out all language constructs that can be implemented 
 as a library feature.

 3. Add some syntactical sugar where necessary (mapping to 
 library features).

 Which features that are currently in the language could with 
 some adjustments be done as a library feature?

 Hashtable?

 Dynamic array?

 Slices?

 Shared?

 Class?

 Others language features…?

 (I think all these could be done if meta-programming facilities 
 were strengthened.)

 What do you think?
And consequentely we can rename it "!" instead of "D".
Nov 29 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 29 November 2021 at 11:38:17 UTC, rumbu wrote:
 And consequentely we can rename it "!" instead of "D".
I understand your concern, but the crux is to provide syntactical sugar. D already does this for user-defined operators, so it is a matter of coming up with something equally useful for other constructs than operators. The advantage is that in meta-programming you can ignore all the syntactical sugar and deal only with the minimal core language. (Syntactical sugar disappears after the AST has been built.)
Nov 29 2021
prev sibling next sibling parent reply Petar Kirov [ZombineDev] <petar.p.kirov gmail.com> writes:
On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim Grøstad 
wrote:
 If there was a majority in favour of D3, with breaking changes, 
 and a strong focus on meta-programming, then it would make a 
 lot of sense to streamline the language.

 [..]

 What do you think?
From the top of my head, my list looks like this: 1. (Perhaps not D3 worthy - can be done in D2 as well, without removing existing funcitonality) replace all of the current reflection functionality (`__traits(..)`, `is(..)`, `std.traits`, etc.) with a cleaner CTFE-based API, along the lines of Stefan's `core.reflect`: https://github.com/UplinkCoder/druntime/tree/core_reflect/src/core/reflect Than add syntax sugar on top, after we develop experience with using it. 2. Type qualifiers. I really like D's type qualifiers, including `shared`, but after using TypeScript at work for the past 2-3 years, I feel their approach is more flexible - simply offer head-only type qualifiers and build transitive ones on top: ```ts // Generic mapped type: // https://www.typescriptlang.org/docs/handbook/2/mapped-types.html type IdentityObject<T> = { [K in keyof T]: T[K]; }; // Non-transitive read-only (const) type constructor type ReadOnly<T> = { readonly [K in keyof T]: T[K]; }; // Deep (transitive) read-only type constructor type DeepReadOnly<T> = { readonly [K in keyof T]: DeepReadOnly<T[K]>; }; ``` [Full example in TS playground](https://www.typescriptlang.org/play?ssl=68&ssc=3&pln=66&pc=1#code/C4TwDgpgBACg9gSwHbALIFdhQLxQN4CwAUFFAB4BcUS6AtgEYQBOA3MaSFTQ820QL59ioSLEQoASgHkyOfOyhMIAQwAmcJABsQ5LnUasFnavt7FBxYpohYwARirxkaTHLy6odgDRRjAJigLInsAOllcABY-ISJrWz9HcWBpcPwPb18qAKCwPzC5KJYoAHpiqABhZSQkOCxlAGd6hABzJChgOCgAcjIuqEYAY2V0eugELAR6qGVFFVUAWg1tKDAmOEgmUBDLIlKoAHEIJGYEAahaZTBIVXbwCCoAC2BgMHqKUoB3L5CRCHqBpgIMDATRVZohOBMZrFdQDerFB5VVT0OBwADWxT8xQuVwgC1+9RCT1ommEdygAElVEdgOMQFJ6AArCADYAAHgAKgA+NwKADaAGkoMgoGiICA4AAzKAcgC6VA5gtlfCCVhsKwAzFQqTS6Qzmay2U4UBhgDzcO5KJ4fP5AnwwBr8pFojs4isItrqSg9UyWezjckZOa0laMrachEnVBCiUypVqrVpo0Wm0Ot1ev0WcNRsKJlMZko1IstDpVutmFsdr8oBI5lIS5zg4QSLM1EsdILhW0xRLpXKFUqVTE3WAAKxUWtqevaI1JU1N9I2rJ24hjqMxvbxmp1ZOtdqdHp9QbZsZ56athbtlZrDaV4KjkI6Z1FTdVbdJpp7tNdEBHrMjU9hXzC9i2WMtbxAbZ7zcDwNSXaM7VjWZ5gaJokGaWgaSAqB0WUEAfDQgZoDgX1WXzJRZklZgjiI25IHqHYBg0epbAANgnOsGwDecYNDeDsntVj12iJCt0TVCU33dM-yGADc2wgs5lA0sbwrSDVyEp9oxE18Ex3T9UwPX9M1knNxgUkCr3AtSoLAVjeKoODMgQwRRLfcTd0M7o7Jkk95Mmc8mKQFiqmAKCyVEfZlEw3kWxIg1gDeKAAGVEUgPllXMGJq1Sy5oAtBQADcK1OP5EmcU0MqHV11WaaKIAcA56ti0h4r9JK+QUUhm1IXqoGKzZSo6rq+pDKgw2XfgvBGvrLUc+CIkCaaW1GsaoFHeD7KmmaoFlZa+u2ls9qyxjmKwOrMISGtOJnKLMODC6Gr4R68jasi5Cqty9I-STvzexLfLk8yAsUosrNUzZ1KIF6IVIxK+QABllGCBtpIiOuR1y9ikAUfEnVRpx0AL32pCAwBKdomCqJpaWKqtyQAEQgMn8cJxsWovK9OxFHspRleUoCZlmbpATklS5aqiGIIKWKgR6tUF5mwFZhs7ogB76rsZ76sdf6plwT7dPfCSvwPPXAbMs9QcvEtr3LSGoPl2GEvqRHkYtfqSvRqgMsQvYKSQalZAM5RgHQCiRWrLpC3UW2heVkW2VyyAuQyvorOYWhximGPkHBYgnb1t2QlRobi9SDUXzjdz9N+g8M2PIGrcs23rIdnYgA). In D3 perhaps this would like this: ```d // aggregateOf(T) yields `struct`, `class`, `union` or `module` alias Const(T) = aggregateOf(T) { static foreach (fieldName, fieldType; T.fieldsOf) const fieldType $fieldName; }; alias TransitiveConst(T) = aggregateOf(T) { static foreach (fieldName, fieldType; T.fieldsOf) const TransitiveConst!fieldType $fieldName; }; ``` 3. Replace `interface` types and ad hoc Design-by-Introspection patterns like `isInputRange`, `hasMember!(S1, "member")` with TypeScript's object types: https://www.typescriptlang.org/docs/handbook/2/objects.html which offer a very powerful, yet elegant and concise way of describing object shapes. 4. Replace ad hoc DIP1000 parameter storage class design with affine types. I haven't given it much thought, but ideally we should be able to write an Affine type constructor in library code and simply use it like as any other type constructor (e.g. tuple, sum type, etc.) 5. Introduce some concept of compile-time dependency resolution / context abstraction (see https://docs.scala-lang.org/scala3/reference/contextual.html) so that things like the current allocator, scheduler, request/response context, etc., can be implicitly provided to improve the ergonomics of such APIs. For example, one could specify that in one scope the current implementation of associative arrays is a GC-managed hashmap, while in other a unique_ptr to red-black tree value container, like `std::map`, all while using the same `K[V] x = [key1: value1]` syntax.
Nov 29 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 29 November 2021 at 13:56:08 UTC, Petar Kirov 
[ZombineDev] wrote:
 2. Type qualifiers. I really like D's type qualifiers, 
 including `shared`, but after using TypeScript at work for the 
 past 2-3 years, I feel their approach is more flexible - simply 
 offer head-only type qualifiers and build transitive ones on
Yes, it is a powerful concept, but TypeScript is "reinterpreting" the underlying types. If done in D it might be the same as refining types with constraints. A long time ago I suggested using reqular expressions for expressing constness, which perhaps is what TypeScript is doing. Just with a verbose syntax. It could be done in a more concise fashion by borrowing ideas from query languages for tree-datastructures, such as XQuery or CSS selectors. Using the more verbose syntax of TypeScript only makes sense if you also do your point 3:
 3. Replace `interface` types and ad hoc Design-by-Introspection 
 patterns like `isInputRange`, `hasMember!(S1, "member")` with 
 TypeScript's object types: 
 https://www.typescriptlang.org/docs/handbook/2/objects.html 
 which offer a very powerful, yet elegant and concise way of 
 describing object shapes.
Concepts/traits in C++ and Rust are making the lack of this feature more apparent, I guess.
 4. Replace ad hoc DIP1000 parameter storage class design with 
 affine types. I haven't given it much thought, but ideally we 
 should be able to write an Affine type constructor in library 
 code and simply use it like as any other type constructor (e.g. 
 tuple, sum type, etc.)
By "affine types" in this context, do you mean "use once or never" types?
 5. Introduce some concept of compile-time dependency resolution 
 / context abstraction (see 
 https://docs.scala-lang.org/scala3/reference/contextual.html) 
 so that things like the current allocator, scheduler, 
 request/response context, etc., can be  implicitly provided to 
 improve the ergonomics of such APIs. For example, one could 
 specify that in one scope the current implementation of 
 associative arrays is a GC-managed hashmap, while in other a 
 unique_ptr to red-black tree value container, like `std::map`, 
 all while using the same `K[V] x = [key1: value1]` syntax.
So you would make all functions "templated"? Or, how else would this work?
Nov 29 2021
parent reply jmh530 <john.michael.hall gmail.com> writes:
On Monday, 29 November 2021 at 16:05:46 UTC, Ola Fosheim Grøstad 
wrote:
 [snip]

 3. Replace `interface` types and ad hoc 
 Design-by-Introspection patterns like `isInputRange`, 
 `hasMember!(S1, "member")` with TypeScript's object types: 
 https://www.typescriptlang.org/docs/handbook/2/objects.html 
 which offer a very powerful, yet elegant and concise way of 
 describing object shapes.
Concepts/traits in C++ and Rust are making the lack of this feature more apparent, I guess. [snip]
Typescript's object types look to me like Go's interfaces (which are like Rust's traits), but with a bit more flexibility. They look more runtime-oriented than C++'s concepts.
Nov 29 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Monday, 29 November 2021 at 16:14:29 UTC, jmh530 wrote:
 Typescript's object types look to me like Go's interfaces 
 (which are like Rust's traits), but with a bit more 
 flexibility. They look more runtime-oriented than C++'s 
 concepts.
Hm. I think I understand what you mean, but TypeScripts type system does not exist at runtime at all, so it is static and for compile time only (or mostly). Runtime type checks are limited to JavaScript. Go is more dynamic in nature and therefore not fully static, so some typing errors will be discovered at runtime in Go. TypeScripts types are however weak, in the sense that they are just painted over JavaScript objects that may have content that contradicts the types TypeScript paints over them. Kinda like how D can paint incompatible types over data-structures received from C code. In that context maybe it would be interesting to have something similar, and allow programmers to «paint constraints» over both D and C data-structures to catch more bugs at compile time.
Nov 29 2021
prev sibling next sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim Grøstad 
wrote:
 If there was a majority in favour of D3, with breaking changes, 
 and a strong focus on meta-programming, then it would make a 
 lot of sense to streamline the language.
I just don't understand the premise of a "D3". We don't need "D3" to have breaking changes, we now have a **better** system with -preview/-revert. Considering D2 approximately halved the userbase, talks about "D3" should really be talks about new -preview flags. The idea that a magical breaking change fixes the langage without a nice upgrade path is magical thinking, because it would be strictly **worse** than what we have today.
Nov 30 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 30 November 2021 at 13:49:12 UTC, Guillaume Piolat 
wrote:
 On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim 
 Grøstad wrote:
 If there was a majority in favour of D3, with breaking 
 changes, and a strong focus on meta-programming, then it would 
 make a lot of sense to streamline the language.
I just don't understand the premise of a "D3". We don't need "D3" to have breaking changes, we now have a **better** system with -preview/-revert. Considering D2 approximately halved the userbase, talks about "D3" should really be talks about new -preview flags. The idea that a magical breaking change fixes the langage without a nice upgrade path is magical thinking, because it would be strictly **worse** than what we have today.
There should absolutely be an upgrade path, which is why "equally expressive" would be very much a requirement. I believe to a large extent that one could do it this way: For files ending in ".d" emulate most of the current behaviour. For files ending in ".d3" provide the full cleanup. Then you can combine ".d" and ".d3" files. Much like how you combine ".c", ".cpp", ".mm" files in X-Code for C, C++, Objective-C. One possible way to arrive at this path would be to create a high level IR (HIR) for the current DMD compiler, then a new D3 compiler would emit the same high level IR and you would combine the HIR output using a high level linker (basically a compiler). You could do the same for C too. The problem right now is that there is neither LTS or a compiler code base that is suitable for further evolution, so with no change on the technological level you effectively "halve the population" anyway by slow evolution. There are other languages quite close to D in semantics, so without "D3" there are other languages that take that role regardless. It also makes absolutely no sense to write a new compiler codebase that emulate the quirks of dmd? The better strategy is to have: 1. DMD -> HIR 2. D3 -> HIR 3. HIR -> LLVM That allows you to give DMD D2 long term support and also improve on compilation speed and backend support (ARC and borrowing) for both.
Nov 30 2021
next sibling parent reply zjh <fqbqrr 163.com> writes:
On Tuesday, 30 November 2021 at 14:46:59 UTC, Ola Fosheim Grøstad 
wrote:


What about the shortage of manpower?
How to arrange manpower?
Nov 30 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 30 November 2021 at 14:58:02 UTC, zjh wrote:
 On Tuesday, 30 November 2021 at 14:46:59 UTC, Ola Fosheim 
 Grøstad wrote:

 What about the shortage of manpower?
 How to arrange manpower?
There are several people writing compilers for either D or D-like languages already… With a clean code base, that is more contemporary, with a more modular architecture, more people would be interested in working on the compiler.
Nov 30 2021
prev sibling parent reply Guillaume Piolat <first.last gmail.com> writes:
On Tuesday, 30 November 2021 at 14:46:59 UTC, Ola Fosheim Grøstad 
wrote:
 There should absolutely be an upgrade path
Such as with -preview/-revert then?
 For files ending in ".d" emulate most of the current behaviour. 
 For files ending in ".d3" provide the full cleanup.
Can you give an example of breaking changes that this .d3 trick allows, that cannot be covered by -preview/-revert?
Nov 30 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Tuesday, 30 November 2021 at 19:56:01 UTC, Guillaume Piolat 
wrote:
 On Tuesday, 30 November 2021 at 14:46:59 UTC, Ola Fosheim 
 Grøstad wrote:
 There should absolutely be an upgrade path
Such as with -preview/-revert then?
This is possible: 1. -preview-d3-feature-X on the D2 side 2. -emulate-d2-feature-Y on the D3 side for common "deprecated" features. 3. Allow subsystems compiled with both D2 and D3 to be combined using high level intermediate representation (HIR) so that you can transition one subsystem at a time from D2 to D3. Although, you might have to replicate some templates on both sides because I doubt that "static if" is suitable for HIR. You have to decide case-by-case what is worthwhile. It has to be based on what existing code-authors find difficult.
 For files ending in ".d" emulate most of the current 
 behaviour. For files ending in ".d3" provide the full cleanup.
Can you give an example of breaking changes that this .d3 trick allows, that cannot be covered by -preview/-revert?
If you create a new modular frontend and follow a clean spec, then you will get many differences all at once. Anything that depends on "does-this-compile-traits" could break even if you try to emulate DMD. The alternative is to reimplement all quirks of the current frontend and that could have a negative complexity impact and a development time impact, basically not making it worthwhile. All changes that are cleaning up language semantics, can potentially break things such as traits. When you move something to a library or change things you will affect those that do "shoehorn tricks" with the language. You should probably only aim for ease of transition for people who write good code. People who rely on trickery are very costly to support. Anyway, «D3» is inevitable if the current compiler is difficult to evolve, maybe it already «exists» in the shape of another language with no affiliation to D.
Dec 01 2021
prev sibling parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim Grøstad 
wrote:
 If there was a majority in favour of D3, with breaking changes, 
 and a strong focus on meta-programming, then it would make a 
 lot of sense to streamline the language.

 What would that consist of? I would say:

 1. Figuring out what the missing bits for meta-programming are.

 2. Taking out all language constructs that can be implemented 
 as a library feature.

 3. Add some syntactical sugar where necessary (mapping to 
 library features).

 Which features that are currently in the language could with 
 some adjustments be done as a library feature?

 Hashtable?

 Dynamic array?

 Slices?

 Shared?

 Class?

 Others language features…?

 (I think all these could be done if meta-programming facilities 
 were strengthened.)

 What do you think?
What you basically are asking for is C with ast macros. -Alex
Dec 01 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Wednesday, 1 December 2021 at 15:01:10 UTC, 12345swordy wrote:
 What you basically are asking for is C with ast macros.
Can you emulate D as C with AST macros?
Dec 01 2021
parent reply 12345swordy <alexanderheistermann gmail.com> writes:
On Wednesday, 1 December 2021 at 15:09:28 UTC, Ola Fosheim 
Grøstad wrote:
 On Wednesday, 1 December 2021 at 15:01:10 UTC, 12345swordy 
 wrote:
 What you basically are asking for is C with ast macros.
Can you emulate D as C with AST macros?
https://github.com/eudoxia0/cmacro Why not try it out yourself.
Dec 01 2021
parent reply Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 2 December 2021 at 00:58:38 UTC, 12345swordy wrote:
 On Wednesday, 1 December 2021 at 15:09:28 UTC, Ola Fosheim 
 Grøstad wrote:
 On Wednesday, 1 December 2021 at 15:01:10 UTC, 12345swordy 
 wrote:
 What you basically are asking for is C with ast macros.
Can you emulate D as C with AST macros?
https://github.com/eudoxia0/cmacro
That would be a different language. Templates are related to AST macros, but they are limited to expanding on"!".
Dec 02 2021
next sibling parent 12345swordy <alexanderheistermann gmail.com> writes:
On Thursday, 2 December 2021 at 09:20:26 UTC, Ola Fosheim Grøstad 
wrote:
 On Thursday, 2 December 2021 at 00:58:38 UTC, 12345swordy wrote:
 On Wednesday, 1 December 2021 at 15:09:28 UTC, Ola Fosheim 
 Grøstad wrote:
 On Wednesday, 1 December 2021 at 15:01:10 UTC, 12345swordy 
 wrote:
 What you basically are asking for is C with ast macros.
Can you emulate D as C with AST macros?
https://github.com/eudoxia0/cmacro
That would be a different language.
Exactly
Dec 02 2021
prev sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Thursday, 2 December 2021 at 09:20:26 UTC, Ola Fosheim Grøstad 
wrote:
 On Thursday, 2 December 2021 at 00:58:38 UTC, 12345swordy wrote:
 On Wednesday, 1 December 2021 at 15:09:28 UTC, Ola Fosheim 
 Grøstad wrote:
 On Wednesday, 1 December 2021 at 15:01:10 UTC, 12345swordy 
 wrote:
 What you basically are asking for is C with ast macros.
Can you emulate D as C with AST macros?
https://github.com/eudoxia0/cmacro
That would be a different language. Templates are related to AST macros, but they are limited to expanding on"!".
The syntax used for macro expansion is a trivial detail. Rust has "real" AST macros, and they also use `!` for expansion (`vec!`, `println!`, etc.). The biggest difference between AST macros and templates is that expanding a template both *generates* code and *binds* that code to a symbol in a particular scope.
Dec 02 2021
parent Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= <ola.fosheim.grostad gmail.com> writes:
On Thursday, 2 December 2021 at 14:38:21 UTC, Paul Backus wrote:
 The syntax used for macro expansion is a trivial detail. Rust 
 has "real" AST macros, and they also use `!` for expansion 
 (`vec!`, `println!`, etc.).
It isn't trivial if you can match on anything you want. If you can match on "if (x==123)" etc then you are opening Pandora's box. Of course, that was also never suggested in the thread. Only adjustments to current semantics were suggested, not a new language-family like 12345swordy implied…
Dec 02 2021