digitalmars.D - Which language constructs could be done as a library if we accept some
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (20/20) Nov 28 2021 If there was a majority in favour of D3, with breaking changes,
- Elronnd (4/7) Nov 28 2021 Classes should be a language feature in any case, for performance
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/12) Nov 29 2021 A good compiler will detect standard library features and use a
- user1234 (5/18) Nov 29 2021 static casts, devirtualization, are reasons for built-in classes.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (12/16) Nov 29 2021 Casting is a weakness in D (in comparison to C++) so that is an
- user1234 (5/10) Nov 29 2021 If there must be a special path then it's already a failed
- user1234 (4/14) Nov 29 2021 BTW, to be clear: yes I know that AliasSeq borrows such a special
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/11) Nov 29 2021 No lies. Compiler optimizations that focus on standard library
- Alexandru Ermicioi (16/30) Nov 28 2021 I think these could've been implemented as structs, then the only
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (12/18) Nov 29 2021 Yes, that should be the goal. Improve on meta-programming
- zjh (3/7) Nov 29 2021 for `D` better,tolerence `breakage` is OK.
- bauss (4/24) Nov 29 2021 Pretty much anything can be solved in a library, except for
- Nick Treleaven (7/9) Nov 29 2021 There is no way to implicitly convert from other types
- Alexandru Ermicioi (17/24) Nov 29 2021 But isn't a slice basically a struct with pointer and length?
- Nick Treleaven (6/11) Nov 29 2021 For slices we could just stop supporting null and require `[]`
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (9/20) Nov 29 2021 Yes, that would make a lot of sense.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (9/11) Nov 29 2021 Maybe overkill?
- Paul Backus (6/13) Nov 29 2021 You can't overload operators for built-in types, like pointers.
- Alexandru Ermicioi (5/19) Nov 29 2021 Sorry, kinda hard to remember that this is thread based
- bauss (5/14) Nov 29 2021 Yeah, I'm not really supportive of everything having to be a
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/6) Nov 29 2021 What advantages?
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (9/11) Nov 29 2021 I think we can assume that the AST closely matches the core
- rumbu (3/23) Nov 29 2021 And consequentely we can rename it "!" instead of "D".
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/9) Nov 29 2021 I understand your concern, but the crux is to provide syntactical
- Petar Kirov [ZombineDev] (69/74) Nov 29 2021 From the top of my head, my list looks like this:
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (19/44) Nov 29 2021 Yes, it is a powerful concept, but TypeScript is "reinterpreting"
- jmh530 (5/15) Nov 29 2021 Typescript's object types look to me like Go's interfaces (which
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (14/18) Nov 29 2021 Hm. I think I understand what you mean, but TypeScripts type
- Guillaume Piolat (10/13) Nov 30 2021 I just don't understand the premise of a "D3".
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (29/42) Nov 30 2021 There should absolutely be an upgrade path, which is why "equally
- zjh (4/4) Nov 30 2021 On Tuesday, 30 November 2021 at 14:46:59 UTC, Ola Fosheim Grøstad
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/10) Nov 30 2021 There are several people writing compilers for either D or D-like
- Guillaume Piolat (5/8) Nov 30 2021 Such as with -preview/-revert then?
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (30/39) Dec 01 2021 This is possible:
- 12345swordy (4/24) Dec 01 2021 What you basically are asking for is C with ast macros.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (2/3) Dec 01 2021 Can you emulate D as C with AST macros?
- 12345swordy (4/8) Dec 01 2021 https://github.com/eudoxia0/cmacro
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/11) Dec 02 2021 That would be a different language. Templates are related to AST
- 12345swordy (3/14) Dec 02 2021 Exactly
- Paul Backus (8/20) Dec 02 2021 The syntax used for macro expansion is a trivial detail. Rust has
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (6/9) Dec 02 2021 It isn't trivial if you can match on anything you want. If you
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
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
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:A good compiler will detect standard library features and use a fast-path/optimized-path for those. So there should be no performance impact.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 29 2021
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: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.On Sunday, 28 November 2021 at 20:47:28 UTC, Ola Fosheim Grøstad wrote:A good compiler will detect standard library features and use a fast-path/optimized-path for those. So there should be no performance impact.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 29 2021
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
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: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.static casts, devirtualization, are reasons for built-inAlso, since it would be a standard library construct a good compiler could have a special path for those. So it should remain the same.
Nov 29 2021
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: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.On Monday, 29 November 2021 at 12:30:42 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.static casts, devirtualization, are reasons for built-inAlso, since it would be a standard library construct a good compiler could have a special path for those. So it should remain the same.
Nov 29 2021
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
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
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
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
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
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
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: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).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.
Nov 29 2021
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
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: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?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
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
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
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: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.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
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: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.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
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
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
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
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
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
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 onYes, 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
On Monday, 29 November 2021 at 16:05:46 UTC, Ola Fosheim Grøstad wrote:[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.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]
Nov 29 2021
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
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
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: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.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
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
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
On Tuesday, 30 November 2021 at 14:46:59 UTC, Ola Fosheim Grøstad wrote:There should absolutely be an upgrade pathSuch 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
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: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.There should absolutely be an upgrade pathSuch as with -preview/-revert then?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.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?
Dec 01 2021
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
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
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:https://github.com/eudoxia0/cmacro Why not try it out yourself.What you basically are asking for is C with ast macros.Can you emulate D as C with AST macros?
Dec 01 2021
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:That would be a different language. Templates are related to AST macros, but they are limited to expanding on"!".On Wednesday, 1 December 2021 at 15:01:10 UTC, 12345swordy wrote:https://github.com/eudoxia0/cmacroWhat you basically are asking for is C with ast macros.Can you emulate D as C with AST macros?
Dec 02 2021
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:ExactlyOn Wednesday, 1 December 2021 at 15:09:28 UTC, Ola Fosheim Grøstad wrote:That would be a different language.On Wednesday, 1 December 2021 at 15:01:10 UTC, 12345swordy wrote:https://github.com/eudoxia0/cmacroWhat you basically are asking for is C with ast macros.Can you emulate D as C with AST macros?
Dec 02 2021
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: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.On Wednesday, 1 December 2021 at 15:09:28 UTC, Ola Fosheim Grøstad wrote:That would be a different language. Templates are related to AST macros, but they are limited to expanding on"!".On Wednesday, 1 December 2021 at 15:01:10 UTC, 12345swordy wrote:https://github.com/eudoxia0/cmacroWhat you basically are asking for is C with ast macros.Can you emulate D as C with AST macros?
Dec 02 2021
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