digitalmars.D - C++ pattern matching is coming
- ryuukk_ (11/11) Oct 22 2022 https://twitter.com/seanbax/status/1583654796791140352/photo/1
- ryuukk_ (3/3) Oct 22 2022 Forgot to add but it looks like they'll also add the .Enum
- Paul Backus (15/19) Oct 22 2022 My prediction: if Walter gets bored of ImportC and decides to
- Mike Parker (2/5) Oct 22 2022 Walter's primary focus right now is shoring up DIP 1000.
- Imperatorn (3/9) Oct 23 2022 That's good to know. Would be great news if Dip1000 would be
- Timon Gehr (4/15) Oct 23 2022 I don't expect it to be "finalized" very soon. It lacks expressiveness,
- Walter Bright (2/4) Oct 23 2022 The changes have been bug fixes. The concept has held up well.
- Timon Gehr (15/21) Oct 23 2022 As soon as people try to use it in production they will run into some
- Timon Gehr (2/3) Oct 23 2022 Missed a 0 there.
- Walter Bright (2/3) Oct 23 2022 We forgive you :-) since missing a 0 only matters on one's paycheck.
- Walter Bright (10/23) Oct 23 2022 That's right. DIP1000 does not track lifetimes at all. It only does scop...
- Steven Schveighoffer (30/42) Oct 23 2022 Is this a bug? Because I can't do this from @trusted code:
- Steven Schveighoffer (16/59) Oct 23 2022 Comically almost, I realized *return values* can be unscoped, so adding
- Walter Bright (2/4) Oct 23 2022 Yes, it looks like a bug. Please file it and tag it with the 'safe' keyw...
- Dukc (27/47) Oct 24 2022 Hmm, this looks like it probably should work because of having
- Timon Gehr (31/67) Oct 23 2022 It kind of does a bit with return annotations:
- Walter Bright (13/30) Oct 23 2022 It isn't actually tracking lifetimes, it just copies the attributes from...
- Timon Gehr (43/83) Oct 24 2022 Well, yes, this is essentially how to track lifetimes.
- Walter Bright (20/20) Oct 24 2022 There's a misunderstanding here. @live *does* work in @safe code, and co...
- Paul Backus (18/24) Oct 24 2022 The problem with using @live and @safe together is that (a) you
- rikki cattermole (6/12) Oct 24 2022 Right now I'm building up my library infrastructure using @safe and DIP1...
- Walter Bright (11/25) Oct 24 2022 @live doesn't actually add any *new* semantic behavior to a function. Al...
- IGotD- (8/11) Oct 24 2022 I think what he means are movable types. Movable types are moved
- rikki cattermole (27/32) Oct 24 2022 That's not what I'm suggesting, and I'm familiar with that issue (sadly
- Walter Bright (5/7) Oct 24 2022 I deliberately avoided making scope a type qualifier.
- rikki cattermole (9/18) Oct 24 2022 My concern is that memory owners simply cannot expose their owned memory...
- zjh (5/6) Oct 25 2022 `scope as a type qualifier`.
- zjh (5/6) Oct 25 2022 I think `@live` is good. `@live` just adds `restrictions` to
- Araq (12/21) Oct 24 2022 1. Nobody should care about strcpy in 2022. It was a poor design
- Imperatorn (4/17) Oct 25 2022 You have some points, but do you have some constructive
- Walter Bright (4/14) Oct 24 2022 @live does indeed allow for incremental, function by function use of @li...
- Paul Backus (17/35) Oct 24 2022 It is impossible for both of the following statements to be true
- Walter Bright (4/16) Oct 24 2022 (1) is false. @live functions come with the assumption that:
- Dukc (29/47) Oct 24 2022 I demonstrate what I think Paul means. Suppose we have a manually
- Walter Bright (2/21) Oct 24 2022
- ryuukk_ (3/26) Oct 24 2022 It's never too late, dmd could have a mechanism to fix/convert
- Timon Gehr (13/51) Oct 24 2022 Yes.
- Walter Bright (16/20) Oct 24 2022 This has been proposed before (I think by deadalnix), and much much earl...
- Timon Gehr (14/45) Oct 24 2022 Pretty sure this has already been proposed in some academic paper in the...
- Walter Bright (11/15) Oct 24 2022 I'd appreciate if you would write this all up, and in the simplest possi...
- =?UTF-8?Q?Ali_=c3=87ehreli?= (4/5) Oct 24 2022 I think this has already past the point where interested parties should
- Tejas (2/8) Oct 24 2022 Maybe Dconf online can be the place where this can happen 😃
- jmh530 (2/9) Oct 27 2022 +1
- German Diago (26/29) Oct 25 2022 I am glad to see a language that is C-like, understandable,
- zjh (4/8) Oct 25 2022 I am very satisfied with the `current D`!
- zjh (7/8) Oct 25 2022 I think `'D'` can be the companion language of `'C++'`.
- zjh (4/7) Oct 25 2022 Maybe one day, someone will come out with a book called `'D for
- Alexandru Ermicioi (9/15) Oct 25 2022 Nope, its not cool. There are people that know D and not C++,
- German Diago (15/26) Oct 25 2022 FWIW, D is a language. I would not advocate for or against
- Alexandru Ermicioi (4/17) Oct 25 2022 It is fine, if you have high compatibility with other languages,
- zjh (18/26) Oct 25 2022 compatibility with other
- =?UTF-8?Q?Ali_=c3=87ehreli?= (11/12) Oct 25 2022 What you mean is languages can have different features that a programmer...
- zjh (3/8) Oct 25 2022 Well, this is just a `personal opinion`.
- Arun (4/9) Oct 25 2022 For short running tools and low volume stuff, yes, GC is good.
- German Diago (10/20) Oct 26 2022 I would like to hear your experience with Vibe.d. I would care
- Imperatorn (3/14) Oct 26 2022 Have you read this?
- German Diago (4/8) Oct 26 2022 No I did not, but it is 242 pages. I am not sure I can go through
- German Diago (16/34) Oct 26 2022 After a quick look I do not see what I am looking for to start,
- Imperatorn (5/22) Oct 26 2022 I see, then you should look into arsd imo, very simple and
- Tejas (5/28) Oct 26 2022 Is django really that much of a resource hog though? If stuff
- Tejas (7/27) Oct 26 2022 Also, a benchmark site :
- Steven Schveighoffer (4/16) Oct 26 2022 My experience with vibe.d with GC is just fine. In fact, I think it's a
- German Diago (23/34) Oct 26 2022 Besides concepts, what are those exactly? D metaprogramming is
- zjh (8/9) Oct 26 2022 You are more `radical` than me. Yes, `C++` means that there are
- German Diago (6/25) Oct 26 2022 I do not propose that at all either. I propose the best path
- Imperatorn (2/11) Oct 26 2022 +1
- Imperatorn (3/19) Oct 24 2022 But, he's working on it ;)
- Per =?UTF-8?B?Tm9yZGzDtnc=?= (4/8) Oct 23 2022 Can you elaborate on why this is case?
- Walter Bright (2/4) Oct 23 2022 I haven't thought much about them yet.
- =?UTF-8?Q?Ali_=c3=87ehreli?= (7/8) Oct 22 2022 Is that really C++? I ask because there is no mention of C++ there.
- ryuukk_ (4/13) Oct 22 2022 Thanks for pointing that out, i didn't know, i thought it was
- Mike Parker (4/6) Oct 22 2022 It is not and has never been "planned". It's something Walter
- IGotD- (7/10) Oct 23 2022 Can they reuse switch? In Swift they have pattern matching but
- Paulo Pinto (3/15) Oct 23 2022 Java and C# have reused switch, by exchanging the order from
- Walter Bright (8/14) Oct 23 2022 Fallthrough by default was removed from D many years ago.
- IGotD- (4/5) Oct 23 2022 Yeah, but the break statement must still be there. I was think
- Timon Gehr (32/54) Oct 23 2022 Actually, each case does introduce a new scope:
- Walter Bright (10/18) Oct 23 2022 Yup.
- Quirin Schroll (10/18) Oct 24 2022 No. Java re-used the `swtich` keyword and IMO is correct in doing
- ryuukk_ (4/4) Oct 27 2022 PHP also got builtin sumtype and pattern matching
- German Diago (3/7) Oct 27 2022 I do not think pattern matching is a must-have. It can be quite
- Timon Gehr (4/16) Oct 27 2022 I believe it's quickly becoming a feature where people will be pretty
- Sergey (2/6) Oct 28 2022 D also has them: https://dlang.org/phobos/std_sumtype.html#match
- ryuukk_ (4/14) Oct 28 2022 std.sumtype is buggy, it's slow and it is a template
- ryuukk_ (5/21) Oct 28 2022 Only with D the solution is a template, then your program takes
- Nick Treleaven (8/30) Oct 28 2022 Has C or C++ actually added sum types to their standards?
- ryuukk_ (3/4) Oct 28 2022 It was proposed and feedback was favorable, it's only just a
- Nick Treleaven (4/9) Oct 28 2022 Do you have a link? I saw the circle compiler extension and
- ryuukk_ (8/21) Oct 28 2022 Here is the latest revision i could find
- Nick Treleaven (4/21) Oct 28 2022 That's pattern matching (I probably confused things mentioning
- ryuukk_ (7/36) Oct 28 2022 The design of this proposal also accounts for a potential
- German Diago (5/28) Oct 28 2022 This is just the pattern matching part I am guessing. I do not
- Paulo Pinto (5/15) Oct 28 2022 The feature on ISO C++ is only planned post-C++26, as you say, is
- German Diago (5/10) Oct 28 2022 Really? Who is championing the effort? Because if you do not keep
- Paul Backus (3/6) Oct 28 2022 If you've found any bugs in `std.sumtype`, please report them on
- ryuukk_ (6/14) Oct 28 2022 The only fix is to make it a builtin language feature, the burden
- Dukc (3/6) Oct 28 2022 We do have a builtin nullable. Given a type `T`, the builtin
- ryuukk_ (5/12) Oct 28 2022 We should have learnt from Kotlin, C#, Zig, Rust and countless
- IGotD- (7/11) Oct 28 2022 Rust do not have a "type?" in order to make it an optional what I
- ryuukk_ (2/15) Oct 28 2022 I should have developed further, but you did it for me so thanks
- Tejas (4/11) Oct 28 2022 I really wonder whether we'd have problems with nullables if
- Imperatorn (2/18) Oct 28 2022 How is sumtype buggy?
https://twitter.com/seanbax/status/1583654796791140352/photo/1 It looks like C++ is catching up pretty fast with other modern languages (pattern matching, builtin sumtype, modules) Pattern matching is mentioned in the D vision document (other section) [1], but is missing in the project board [2] Is it still planned or it was mentioned as "what's possible next"? One issue with C++'s take is they will reserve 2 more keywords (choice, match), i think it is a huge mistake, enum and switch should have been reused imo [1] - https://github.com/dlang/vision-document#other [2] - https://github.com/orgs/dlang/projects?query=is%3Aopen
Oct 22 2022
Forgot to add but it looks like they'll also add the .Enum support! We got a DIP for that one! https://github.com/dlang/DIPs/pull/230
Oct 22 2022
On Sunday, 23 October 2022 at 00:12:32 UTC, ryuukk_ wrote:Pattern matching is mentioned in the D vision document (other section) [1], but is missing in the project board [2] Is it still planned or it was mentioned as "what's possible next"?My prediction: if Walter gets bored of ImportC and decides to make pattern matching his next project, we'll get it. If he doesn't, we won't. I am less optimistic about built-in sum types. The DMD frontend is not really designed to accomodate adding an entire new category of types to D's type system. I would not be surprised if someone *tries* to add them, but it will probably take multiple years for them to go from "initial implementation" to "usable in production code". (Case in point: `noreturn` is basically the simplest possible extension to the type system you could make. Over 1.5 years since [its initial implementation][1], it is still riddled with bugs and unusable in practice.) [1]: https://github.com/dlang/dmd/pull/12214
Oct 22 2022
On Sunday, 23 October 2022 at 01:02:16 UTC, Paul Backus wrote:My prediction: if Walter gets bored of ImportC and decides to make pattern matching his next project, we'll get it. If he doesn't, we won't.Walter's primary focus right now is shoring up DIP 1000.
Oct 22 2022
On Sunday, 23 October 2022 at 02:42:53 UTC, Mike Parker wrote:On Sunday, 23 October 2022 at 01:02:16 UTC, Paul Backus wrote:That's good to know. Would be great news if Dip1000 would be finalized ☀️My prediction: if Walter gets bored of ImportC and decides to make pattern matching his next project, we'll get it. If he doesn't, we won't.Walter's primary focus right now is shoring up DIP 1000.
Oct 23 2022
On 10/23/22 09:08, Imperatorn wrote:On Sunday, 23 October 2022 at 02:42:53 UTC, Mike Parker wrote:I don't expect it to be "finalized" very soon. It lacks expressiveness, which will be improved by small, incremental changes. Which also means it won't be stable all that soon.On Sunday, 23 October 2022 at 01:02:16 UTC, Paul Backus wrote:That's good to know. Would be great news if Dip1000 would be finalized ☀️My prediction: if Walter gets bored of ImportC and decides to make pattern matching his next project, we'll get it. If he doesn't, we won't.Walter's primary focus right now is shoring up DIP 1000.
Oct 23 2022
On 10/23/2022 4:02 PM, Timon Gehr wrote:I don't expect it to be "finalized" very soon. It lacks expressiveness, which will be improved by small, incremental changes.The changes have been bug fixes. The concept has held up well.
Oct 23 2022
On 10/24/22 01:42, Walter Bright wrote:On 10/23/2022 4:02 PM, Timon Gehr wrote:As soon as people try to use it in production they will run into some issues with expressiveness. For example, DIP1000 does not even support storing objects with different lifetimes in different fields of the same struct. (Real case that came up on Discord today.) The underlying issue is that DIP1000 lacks a modular way to track different lifetimes. E.g., DIP100 does not allow having an array allocated on a region allocator, containing references pointing to objects allocated on a distinct region allocator with correct lifetime tracking. As soon as you store things in the array and want to get them back out, if it works at all, their lifetimes will be limited by the lifetime of the region allocator that backs the array storage, even if their own allocator actually is longer-lived. DIP1000 is very keen to conflate different lifetimes and to cut the longer one off based on the shorter one.I don't expect it to be "finalized" very soon. It lacks expressiveness, which will be improved by small, incremental changes.The changes have been bug fixes. The concept has held up well.
Oct 23 2022
On 10/24/22 01:54, Timon Gehr wrote:E.g., DIP100Missed a 0 there.
Oct 23 2022
On 10/23/2022 4:55 PM, Timon Gehr wrote:Missed a 0 there.We forgive you :-) since missing a 0 only matters on one's paycheck.
Oct 23 2022
On 10/23/2022 4:54 PM, Timon Gehr wrote:As soon as people try to use it in production they will run into some issues with expressiveness. For example, DIP1000 does not even support storing objects with different lifetimes in different fields of the same struct. (Real case that came up on Discord today.)That's right. DIP1000 does not track lifetimes at all. It only does scoped lifetimes. Tracking requires data flow analysis, which is in the purview of live.The underlying issue is that DIP1000 lacks a modular way to track different lifetimes. E.g., DIP100 does not allow having an array allocated on a region allocator, containing references pointing to objects allocated on a distinct region allocator with correct lifetime tracking. As soon as you store things in the array and want to get them back out, if it works at all, their lifetimes will be limited by the lifetime of the region allocator that backs the array storage, even if their own allocator actually is longer-lived.That's right.DIP1000 is very keen to conflate different lifetimes and to cut the longer one off based on the shorter one.Yup. DIP1000 does not handle what you describe, and isn't designed to. However, it is still very useful for the vast bulk of cases. It's also carefully set up to be conservative, i.e. it will always err on the side of safety. To loosen up the safety is the job of trusted containers, similar to Rust's unsafe code blocks, because Rust's expressiveness is limited, too.
Oct 23 2022
On 10/23/22 8:29 PM, Walter Bright wrote:Is this a bug? Because I can't do this from trusted code: ```d void foo() trusted { static struct T { Exception ex; ubyte[] buf; } scope buffer = new ubyte[100]; T t; t.ex = new Exception("hello"); t.buf = buffer; throw t.ex; } void main() safe { foo(); } ``` Fails with: ``` onlineapp.d(14): Error: scope variable `t` may not be thrown ``` when compiled with -dip1000. Note that the exception is not intended to be scope. (this is a reduction of the aforementioned discord case, and it's from vibe-core originally) -SteveDIP1000 is very keen to conflate different lifetimes and to cut the longer one off based on the shorter one.Yup. DIP1000 does not handle what you describe, and isn't designed to. However, it is still very useful for the vast bulk of cases. It's also carefully set up to be conservative, i.e. it will always err on the side of safety. To loosen up the safety is the job of trusted containers, similar to Rust's unsafe code blocks, because Rust's expressiveness is limited, too.
Oct 23 2022
On 10/23/22 9:01 PM, Steven Schveighoffer wrote:On 10/23/22 8:29 PM, Walter Bright wrote:Comically almost, I realized *return values* can be unscoped, so adding the following accessor works: ```d static struct T { Exception ex; ubyte[] buf; Exception getEx() { return ex; } } ... throw t.getEx; // ok, because now we unscoped it ``` This seems like a goofy workaround, still makes me feel like the rejection in trusted code is a bug. -SteveIs this a bug? Because I can't do this from trusted code: ```d void foo() trusted { static struct T { Exception ex; ubyte[] buf; } scope buffer = new ubyte[100]; T t; t.ex = new Exception("hello"); t.buf = buffer; throw t.ex; } void main() safe { foo(); } ``` Fails with: ``` onlineapp.d(14): Error: scope variable `t` may not be thrown ```DIP1000 is very keen to conflate different lifetimes and to cut the longer one off based on the shorter one.Yup. DIP1000 does not handle what you describe, and isn't designed to. However, it is still very useful for the vast bulk of cases. It's also carefully set up to be conservative, i.e. it will always err on the side of safety. To loosen up the safety is the job of trusted containers, similar to Rust's unsafe code blocks, because Rust's expressiveness is limited, too.
Oct 23 2022
On 10/23/2022 6:11 PM, Steven Schveighoffer wrote:This seems like a goofy workaround, still makes me feel like the rejection in trusted code is a bug.Yes, it looks like a bug. Please file it and tag it with the 'safe' keyword.
Oct 23 2022
On Monday, 24 October 2022 at 01:01:03 UTC, Steven Schveighoffer wrote:Is this a bug? Because I can't do this from trusted code: ```d void foo() trusted { static struct T { Exception ex; ubyte[] buf; } scope buffer = new ubyte[100]; T t; t.ex = new Exception("hello"); t.buf = buffer; throw t.ex; } void main() safe { foo(); } ```Hmm, this looks like it probably should work because of having the ` trusted` attribute. In a ` safe` function it'd be right to fail because `T t` is inferred as `scope` due to the statement `t.buf = buffer;`. However, using ` trusted` just to accomplish this is asking for trouble. Instead, you should make the function checkably safe: ```D void foo() safe { static struct T { Exception ex; ubyte[] buf; } scope buffer = new ubyte[100]; T t; auto helloEx = new Exception("hello"); t.ex = helloEx; t.buf = buffer; throw helloEx; } ``` Well, in this example anyway. I understand this is just a simplified example, and ` trusted` may be necessary with your real problem.
Oct 24 2022
On 24.10.22 02:29, Walter Bright wrote:On 10/23/2022 4:54 PM, Timon Gehr wrote:It kind of does a bit with return annotations: ```d int* foo(return scope int* x) safe{ auto y=x; int t; auto z=&t; return y; // ok, but can't return z } ```As soon as people try to use it in production they will run into some issues with expressiveness. For example, DIP1000 does not even support storing objects with different lifetimes in different fields of the same struct. (Real case that came up on Discord today.)That's right. DIP1000 does not track lifetimes at all.It only does scoped lifetimes.My use cases with storing references in structs and region allocators can be dealt with with scoped lifetimes only, but they still do not work with DIP1000. In any case, I'd also consider that lifetime tracking, it's just not very precise. The main problem though is lack of modularity. In the example above, `y` and `z` are different, and the compiler understands that they are different within that one function, but there is no way to preserve that difference when passing both of them though a function further down the stack at the same time.Tracking requires data flow analysis, which is in the purview of live. ...I guess my issue here is that live, while it may use some methods that may be helpful in another context, does not enable any of the use cases I described either. It does not make safe any safer and it also does not make DIP1000 any more modular.I agree that it is quite useful for some cases. It just does not seem to offer all that much yet in terms of actually enabling safe manual memory management for the entire application.The underlying issue is that DIP1000 lacks a modular way to track different lifetimes. E.g., DIP100 does not allow having an array allocated on a region allocator, containing references pointing to objects allocated on a distinct region allocator with correct lifetime tracking. As soon as you store things in the array and want to get them back out, if it works at all, their lifetimes will be limited by the lifetime of the region allocator that backs the array storage, even if their own allocator actually is longer-lived.That's right.DIP1000 is very keen to conflate different lifetimes and to cut the longer one off based on the shorter one.Yup. DIP1000 does not handle what you describe, and isn't designed to. However, it is still very useful for the vast bulk of cases.It's also carefully set up to be conservative, i.e. it will always err on the side of safety. To loosen up the safety is the job of trusted containers, similar to Rust's unsafe code blocks, because Rust's expressiveness is limited, too.Yes, it is also limited (additional safety guarantees always come with some limitations), but it can do everything I brought up above. Furthermore, the unsafe blocks can usually be hidden away in libraries with expressive interfaces that are able to distinguish distinct lifetimes pretty well.
Oct 23 2022
On 10/23/2022 6:50 PM, Timon Gehr wrote:It kind of does a bit with return annotations: ```d int* foo(return scope int* x) safe{ auto y=x; int t; auto z=&t; return y; // ok, but can't return z } ```It isn't actually tracking lifetimes, it just copies the attributes from x to y. z gets the scope attribute because it is initialized with the address of a stack variable.I guess my issue here is that live, while it may use some methods that may be helpful in another context, does not enable any of the use cases I described either. It does not make safe any safer and it also does not make DIP1000 any more modular.live's purpose is to prevent: 1. use after free 2. multiple free's 3. no free To go further than that will require the user to construct a container that encapsulates whatever it does, and is likely going to include some trusted functionality. Which is more or less what Rust does.I agree that it is quite useful for some cases. It just does not seem to offer all that much yet in terms of actually enabling safe manual memory management for the entire application.Without the 1,2,3 above, you're right that DIP1000 is not a complete solution. But it is a necessary precondition for doing 1,2,3.
Oct 23 2022
On 10/24/22 06:26, Walter Bright wrote:On 10/23/2022 6:50 PM, Timon Gehr wrote:Well, yes, this is essentially how to track lifetimes. Right now, there are two kinds of lifetimes (attached to declaration using annotations). Some lifetimes outlive the current function and others are strictly lexical. To get more expressiveness, you could: - have more than one lifetime that exceeds the current function's lifetime. I.e., multiple distinct return annotations, ideally an arbitrary number, by allowing the return annotation to be parameterized by a lifetime variable. - have such parameterized scope return annotations on fields of aggregates. None of this requires a fundamentally different approach than what DIP1000 does. What's missing is: - a way to parameterize functions and aggregates that is completely erased at runtime (generally useful, not only for lifetimes; e.g., this is how to fix `inout`.) - return storage class parameterized by a lifetime variable By default, people write their code in the current DIP1000 subset, but library authors get more expressiveness to build containers that actually work well with DIP1000.It kind of does a bit with return annotations: ```d int* foo(return scope int* x) safe{ auto y=x; int t; auto z=&t; return y; // ok, but can't return z } ```It isn't actually tracking lifetimes, it just copies the attributes from x to y. z gets the scope attribute because it is initialized with the address of a stack variable. ...Yes, as some sort of linter within system/ trusted code. DIP1000 is for safe code. (I don't really see why system and trusted code should have access to more static analysis muscle that safe code, but it's not even strictly needed in order to make DIP1000 vastly more expressive.) I think there is currently more demand for a type system that does not get in your way in safe code than for a linter that helps you get malloc/free in system/ trusted code right.I guess my issue here is that live, while it may use some methods that may be helpful in another context, does not enable any of the use cases I described either. It does not make safe any safer and it also does not make DIP1000 any more modular.live's purpose is to prevent: 1. use after free 2. multiple free's 3. no free ...To go further than that will require the user to construct a container that encapsulates whatever it does, and is likely going to include some trusted functionality. Which is more or less what Rust does. ...Yes, but the magic is in expressive interfaces that actually allow the implementation to be trusted because the type checker can correctly restrict safe code in a way that allows the trusted code to make assumptions about the behavior of said safe code. Note that live loses all guarantees at interface boundaries, but those are what actually matters for modular safety in the style of Rust. DIP1000 does not lose guarantees at interface boundaries, which means this is the more promising approach that people will want to extend.DIP1000+ live is also not a "complete solution". One (less important) reason is because live does not address 1,2,3 in safe code. Another (more important) reason is that DIP1000 is not really expressive enough to create some common containers encapsulating trusted functionality. (E.g., region allocators.) I agree with the abstract motivation for DIP1000, it's just that I predict that the actual implementation will in practice be too restrictive to achieve the stated goals.I agree that it is quite useful for some cases. It just does not seem to offer all that much yet in terms of actually enabling safe manual memory management for the entire application.Without the 1,2,3 above, you're right that DIP1000 is not a complete solution. But it is a necessary precondition for doing 1,2,3.
Oct 24 2022
There's a misunderstanding here. live *does* work in safe code, and confers benefits. I oversimplified things by talking about `free`. Of course, `free()` is system and is not callable from safe code. But what I am *really* talking about is when a pointer is passed as an argument to a function, is it being "moved" or "copied"? If it is "copied", that means the caller retains ownership of the pointer. If it is "moved", the caller transfers ownership to the callee. What the callee does with the pointer that was transferred to it is not relevant to the caller. So, 1. void foo(int* p) => argument is moved to foo(), caller can no longer use it 2. void foo(scope int* p) => argument is copied to foo(), caller retains ownership If we change the annotations to: 1. void foo(owner int* p) => argument is moved to foo() 2. void foo(borrow int* p) => argument is copied to foo() it means the same thing. This is why dip1000 is foundational to implementing an ownership/borrowing system. move == owner == notscope copy == borrow == scope If I was smarter, scope would have been spelled "borrow" :-/
Oct 24 2022
On Monday, 24 October 2022 at 18:18:52 UTC, Walter Bright wrote:There's a misunderstanding here. live *does* work in safe code, and confers benefits.[...]1. void foo(int* p) => argument is moved to foo(), caller can no longer use it 2. void foo(scope int* p) => argument is copied to foo(), caller retains ownershipThe problem with using live and safe together is that (a) you cannot *safely* call a live function from a non- live function, or vice-versa (because non- live functions will not honor the above rules), and (b) as a consequence, changing a function from safe to safe live is a breaking API change. This means that existing safe D projects will not be able to adopt live, and the community will have to build an entirely new safe live ecosystem from the ground up in order to see any benefit in practice. The more likely outcome is that D users will stick with their existing safe codebases (which they've invested time and money in) and ignore live altogether. It's a Python 2/Python 3 situation--exactly the kind of thing D wants to avoid. (Of course, projects written in system D will be free to adopt live--but why would they? If they wanted automatic safety checking, they'd already be using safe.)
Oct 24 2022
On 25/10/2022 8:12 AM, Paul Backus wrote:This means that existing safe D projects will not be able to adopt live, and the community will have to build an entirely new safe live ecosystem from the ground up in order to see any benefit in practice. The more likely outcome is that D users will stick with their existing safe codebases (which they've invested time and money in) and ignore live altogether.Right now I'm building up my library infrastructure using safe and DIP1000. live on a memory object sounds very attractive to ensuring memory owned in a data structure/nullable ext. stays alive and won't be deallocated. But not on a function, that asks far too much of people, so I'm 100% in agreement with Paul over this.
Oct 24 2022
On 10/24/2022 12:26 PM, rikki cattermole wrote:On 25/10/2022 8:12 AM, Paul Backus wrote:live doesn't actually add any *new* semantic behavior to a function. All it does is add checking. This means it can be mixed and matched with non- live functions as the user sees fit. This is on purpose. It seems you're suggesting attaching this behavior to the pointer, rather than the function. That means multiple pointer types. Multiple pointer types have been tried many times. They are attractive in theory, but work out poorly in practice. For example, take: char* strcpy(char* dst, char* src); With two pointer types, now you have 4 implementations of strcpy rather than one. It does not scale.This means that existing safe D projects will not be able to adopt live, and the community will have to build an entirely new safe live ecosystem from the ground up in order to see any benefit in practice. The more likely outcome is that D users will stick with their existing safe codebases (which they've invested time and money in) and ignore live altogether.Right now I'm building up my library infrastructure using safe and DIP1000. live on a memory object sounds very attractive to ensuring memory owned in a data structure/nullable ext. stays alive and won't be deallocated. But not on a function, that asks far too much of people, so I'm 100% in agreement with Paul over this.
Oct 24 2022
On Monday, 24 October 2022 at 20:38:59 UTC, Walter Bright wrote:It seems you're suggesting attaching this behavior to the pointer, rather than the function. That means multiple pointer types.I think what he means are movable types. Movable types are moved by default and if a copy is needed there is an explicit method to do so. In the case of D that could be newPointer = oldPointer.dup. dup implementation is dependent on type. In the case of raw pointers like D has today, dup wouldn't do much other than assigning the pointer and perhaps some compiler intrinsic for the life time system.
Oct 24 2022
On 25/10/2022 9:38 AM, Walter Bright wrote:It seems you're suggesting attaching this behavior to the pointer, rather than the function. That means multiple pointer types. Multiple pointer types have been tried many times. They are attractive in theory, but work out poorly in practice. For example, take:That's not what I'm suggesting, and I'm familiar with that issue (sadly far too well). I have something like 700LOC just for replace in my Unicode string builder. For all the different string types. Can't use templates at that level due to shared libraries and wanting to guarantee everything is initialized + tested in it. I have suggested this before, but scope as a type qualifier. A type qualifier (especially if its scope!) adds the extra checks for a specific object, without invading the entire function call graph. Consider: ```d struct Nullable(T) { T value; ref borrow(T) get() { return value; } alias get this; } void func1() { Nullable!U n; func2(n); } void func2(scope U input) { } ``` We have this sort of behavior in the language already i.e. shared. Why is lifetime tracking any different?
Oct 24 2022
On 10/24/2022 2:13 PM, rikki cattermole wrote:We have this sort of behavior in the language already i.e. shared. Why is lifetime tracking any different?I deliberately avoided making scope a type qualifier. My concern with a complex type structure is (besides the combinatorial explosion) people will just find it too complicated to use. What a relief it was to be rid of near and far pointers.
Oct 24 2022
On 25/10/2022 11:04 AM, Walter Bright wrote:On 10/24/2022 2:13 PM, rikki cattermole wrote:My concern is that memory owners simply cannot expose their owned memory without the possibility of logic errors & segfaults. A good recent example: https://dlang.org/changelog/2.101.0.html#borrow_for_refcounted Ultimately the owner must come first, regardless of what the caller wants if we want this to be safe.We have this sort of behavior in the language already i.e. shared. Why is lifetime tracking any different?I deliberately avoided making scope a type qualifier. My concern with a complex type structure is (besides the combinatorial explosion) people will just find it too complicated to use.What a relief it was to be rid of near and far pointers.Oh I bet. I'm glad I have never needed to use them.
Oct 24 2022
On Monday, 24 October 2022 at 21:13:33 UTC, rikki cattermole wrote:I have suggested this before, but scope as a type qualifier.`scope as a type qualifier`. Maybe this is the good idea to overcome the shortcomings of `'live'`.
Oct 25 2022
On Tuesday, 25 October 2022 at 08:44:17 UTC, zjh wrote:..I think ` live` is good. ` live` just adds `restrictions` to `functions`. Maybe `D` can also add ` live` for `types`. In this way, you can also enjoy the benefits of ` live` for `custom pointer types`.
Oct 25 2022
On Monday, 24 October 2022 at 20:38:59 UTC, Walter Bright wrote:It seems you're suggesting attaching this behavior to the pointer, rather than the function. That means multiple pointer types. Multiple pointer types have been tried many times. They are attractive in theory, but work out poorly in practice. For example, take: char* strcpy(char* dst, char* src); With two pointer types, now you have 4 implementations of strcpy rather than one. It does not scale.1. Nobody should care about strcpy in 2022. It was a poor design back then and now it's ridiculously foolish. 2. You already have multiple pointer types in D, there is const*, immutable*, scope*... It's just that these multiple pointer types still don't get the job done because these don't deal with ownership nor memory regions effectively. 3. What does not scale is reason by analogy. "In DOS there were NEAR and FAR pointers so having multiple pointer types does not work so let's conflate traced and untraced pointers." No mainstream language that came after D copied this brilliant design of yours, maybe it's time to wonder *why*.
Oct 24 2022
On Tuesday, 25 October 2022 at 06:40:01 UTC, Araq wrote:On Monday, 24 October 2022 at 20:38:59 UTC, Walter Bright wrote:You have some points, but do you have some constructive criticism? What *should* be done, instead of what should *not* be done?[...]1. Nobody should care about strcpy in 2022. It was a poor design back then and now it's ridiculously foolish. 2. You already have multiple pointer types in D, there is const*, immutable*, scope*... It's just that these multiple pointer types still don't get the job done because these don't deal with ownership nor memory regions effectively. 3. What does not scale is reason by analogy. "In DOS there were NEAR and FAR pointers so having multiple pointer types does not work so let's conflate traced and untraced pointers." No mainstream language that came after D copied this brilliant design of yours, maybe it's time to wonder *why*.
Oct 25 2022
On 10/24/2022 12:12 PM, Paul Backus wrote:The problem with using live and safe together is that (a) you cannot *safely* call a live function from a non- live function, or vice-versa (because non- live functions will not honor the above rules), and (b) as a consequence, changing a function from safe to safe live is a breaking API change. This means that existing safe D projects will not be able to adopt live, and the community will have to build an entirely new safe live ecosystem from the ground up in order to see any benefit in practice. The more likely outcome is that D users will stick with their existing safe codebases (which they've invested time and money in) and ignore live altogether.live does indeed allow for incremental, function by function use of live. This is inevitable as using an ownership/borrowing system requires restructuring the algorithms and data structures.
Oct 24 2022
On Monday, 24 October 2022 at 20:29:55 UTC, Walter Bright wrote:On 10/24/2022 12:12 PM, Paul Backus wrote:It is impossible for both of the following statements to be true simultaneously: 1. Existing safe code can incrementally adopt live without breaking API changes. 2. live allows code to be made safe or trusted that could previously only be system. If (1) is true, then allowing live functions to do anything a safe function could not already do would make it possible for memory corruption to occur in safe code. Therefore, (2) must be false. If (2) is true, then the argument in my previous message applies, which means that (1) must be false. Note that DIP 1000 satisfies both (1) and (2)--it can be (and has been!) incrementally adopted without breaking existing APIs, and it allows some previously- system code to be made safe or trusted.The problem with using live and safe together is that (a) you cannot *safely* call a live function from a non- live function, or vice-versa (because non- live functions will not honor the above rules), and (b) as a consequence, changing a function from safe to safe live is a breaking API change. This means that existing safe D projects will not be able to adopt live, and the community will have to build an entirely new safe live ecosystem from the ground up in order to see any benefit in practice. The more likely outcome is that D users will stick with their existing safe codebases (which they've invested time and money in) and ignore live altogether.live does indeed allow for incremental, function by function use of live. This is inevitable as using an ownership/borrowing system requires restructuring the algorithms and data structures.
Oct 24 2022
On 10/24/2022 1:50 PM, Paul Backus wrote:It is impossible for both of the following statements to be true simultaneously: 1. Existing safe code can incrementally adopt live without breaking API changes. 2. live allows code to be made safe or trusted that could previously only be system. If (1) is true, then allowing live functions to do anything a safe function could not already do would make it possible for memory corruption to occur in safe code. Therefore, (2) must be false. If (2) is true, then the argument in my previous message applies, which means that (1) must be false.(1) is false. live functions come with the assumption that: live void foo(int* p, int* q) { ... } will not be passed pointers to the same object.
Oct 24 2022
On Monday, 24 October 2022 at 20:29:55 UTC, Walter Bright wrote:On 10/24/2022 12:12 PM, Paul Backus wrote:I demonstrate what I think Paul means. Suppose we have a manually managed custom pointer type, designed for safe usage in ` live` functions: ```D struct MMptr (Pointee) { system Pointee* data; // Assuming system variables DIP is implemented // implementation... } // The only way to create MMptrs except for nulls MMptr!T mallocate(T)() { import core.lifetime; import core.stdc : malloc; auto mem = cast(T*)malloc(sizeof(T)); return MMptr(mem.emplace); } // The only way to get rid of owned MMptrs void free(T)(MMptr!T expired) { import core.stdc : free; destroy!false(*expired.data); free(expired.data); } ``` This is great when all client code is ` live`. Perfectly ` safe` as far as I see. Yet you cannot mark `free` ` trusted`. This is because then there would be nothing to prevent a ` safe` but non-` live` function using it and corrupting the heap with dangling pointers.The problem with using live and safe together is that (a) you cannot *safely* call a live function from a non- live function, or vice-versa (because non- live functions will not honor the above rules), and (b) as a consequence, changing a function from safe to safe live is a breaking API change. This means that existing safe D projects will not be able to adopt live, and the community will have to build an entirely new safe live ecosystem from the ground up in order to see any benefit in practice. The more likely outcome is that D users will stick with their existing safe codebases (which they've invested time and money in) and ignore live altogether.live does indeed allow for incremental, function by function use of live. This is inevitable as using an ownership/borrowing system requires restructuring the algorithms and data structures.
Oct 24 2022
On 10/24/2022 1:58 PM, Dukc wrote:struct MMptr (Pointee) { system Pointee* data; // Assuming system variables DIP is implemented // implementation... } // The only way to create MMptrs except for nulls MMptr!T mallocate(T)() { import core.lifetime; import core.stdc : malloc; auto mem = cast(T*)malloc(sizeof(T)); return MMptr(mem.emplace); } // The only way to get rid of owned MMptrs void free(T)(MMptr!T expired) { import core.stdc : free; destroy!false(*expired.data);.data wouldn't be accessible from safe code.free(expired.data); }
Oct 24 2022
On Monday, 24 October 2022 at 22:15:21 UTC, Walter Bright wrote:On 10/24/2022 1:58 PM, Dukc wrote:Oh sorry, I wasn't clear. I meant `MMpointer` would enable borrowing `.data` from ` safe` code with a member function(s), such as ```D trusted Pointee* asPtr() return scope {return data;} trusted ref Pointee opUnary(string op)() return if(op == "*") { return *data; } ```struct MMptr (Pointee) { system Pointee* data; // Assuming system variables DIP is implemented // implementation... } // The only way to create MMptrs except for nulls MMptr!T mallocate(T)() { import core.lifetime; import core.stdc : malloc; auto mem = cast(T*)malloc(sizeof(T)); return MMptr(mem.emplace); } // The only way to get rid of owned MMptrs void free(T)(MMptr!T expired) { import core.stdc : free; destroy!false(*expired.data);.data wouldn't be accessible from safe code.
Oct 25 2022
On Tuesday, 25 October 2022 at 09:33:36 UTC, Dukc wrote:```D trusted Pointee* asPtr() return scope {return data;} trusted ref Pointee opUnary(string op)() return if(op == "*") { return *data; } ```Lower function should be `return scope`, not `return`.
Oct 25 2022
On Monday, 24 October 2022 at 18:18:52 UTC, Walter Bright wrote:There's a misunderstanding here. live *does* work in safe code, and confers benefits. I oversimplified things by talking about `free`. Of course, `free()` is system and is not callable from safe code. But what I am *really* talking about is when a pointer is passed as an argument to a function, is it being "moved" or "copied"? If it is "copied", that means the caller retains ownership of the pointer. If it is "moved", the caller transfers ownership to the callee. What the callee does with the pointer that was transferred to it is not relevant to the caller. So, 1. void foo(int* p) => argument is moved to foo(), caller can no longer use it 2. void foo(scope int* p) => argument is copied to foo(), caller retains ownership If we change the annotations to: 1. void foo(owner int* p) => argument is moved to foo() 2. void foo(borrow int* p) => argument is copied to foo() it means the same thing. This is why dip1000 is foundational to implementing an ownership/borrowing system. move == owner == notscope copy == borrow == scope If I was smarter, scope would have been spelled "borrow" :-/It's never too late, dmd could have a mechanism to fix/convert code automatically
Oct 24 2022
On 10/24/22 20:18, Walter Bright wrote:There's a misunderstanding here.Not really.live *does* work in safe code,Yes.and confers benefits.Barely.I oversimplified things by talking about `free`. Of course, `free()` is system and is not callable from safe code. But what I am *really* talking about is when a pointer is passed as an argument to a function, is it being "moved" or "copied"? If it is "copied", that means the caller retains ownership of the pointer. If it is "moved", the caller transfers ownership to the callee. What the callee does with the pointer that was transferred to it is not relevant to the caller. So, 1. void foo(int* p) => argument is moved to foo(), caller can no longer use it 2. void foo(scope int* p) => argument is copied to foo(), caller retains ownership If we change the annotations to: 1. void foo(owner int* p) => argument is moved to foo() 2. void foo(borrow int* p) => argument is copied to foo() it means the same thing.The difference is that now you have annotated an adequate thing.This is why dip1000 is foundational to implementing an ownership/borrowing system. move == owner == notscope copy == borrow == scope If I was smarter, scope would have been spelled "borrow" :-/I am aware. I also know a thing or two about move semantics and borrowing. live falls short of my expectations in at least two fundamental ways: - it is a function annotation (this makes no sense) - it works on built-in pointers instead of library-defined types It does not guarantee any of the invariants one usually tries to establish with an ownership/borrowing system. Hence it is pretty much useless in safe code.
Oct 24 2022
On 10/24/2022 6:14 AM, Timon Gehr wrote:- have more than one lifetime that exceeds the current function's lifetime. I.e., multiple distinct return annotations, ideally an arbitrary number, by allowing the return annotation to be parameterized by a lifetime variable.This has been proposed before (I think by deadalnix), and much much earlier (before Rust) by Bartosz Milewski. My objection to it was based on its complexity. People have a hard enough time with `scope`. I am frankly amazed that Rust has been able to sell the idea of such complicated annotations, though Rust does seem to attract programmers who revel in such :-) I often hear stories about Rust developers just trying random annotations to get it to pass the compiler, having little concept of how it actually works. The design of dip1000 does not preclude this, however, and it's good to see how far we can push things and avoid needing such complexity.- have such parameterized scope return annotations on fields of aggregates.Same problem. Let's see how far we can get without them. P.S. another annotation that nobody is able to use effectively (or correctly) is C's `restrict` keyword. C++ never bothered to adopt it. Though it was a bad design anyway, as the compiler cannot check if it is used correctly, it just generates bad code. ImportC just ignores `restrict`.
Oct 24 2022
On 10/25/22 00:26, Walter Bright wrote:On 10/24/2022 6:14 AM, Timon Gehr wrote:Pretty sure this has already been proposed in some academic paper in the 1990's or earlier.- have more than one lifetime that exceeds the current function's lifetime. I.e., multiple distinct return annotations, ideally an arbitrary number, by allowing the return annotation to be parameterized by a lifetime variable.This has been proposed before (I think by deadalnix), and much much earlier (before Rust) by Bartosz Milewski. ...My objection to it was based on its complexity.It's barely more complicated than return annotations. `inout` grew into a complex type unsound mess exactly because D was avoiding such parameters.People have a hard enough time with `scope`. I am frankly amazed that Rust has been able to sell the idea of such complicated annotations, though Rust does seem to attract programmers who revel in such :-) I often hear stories about Rust developers just trying random annotations to get it to pass the compiler, having little concept of how it actually works. ...Well, one goal of safe is to reduce the amount of damage that can be done by incompetent developers. Let them randomly try stuff. If that allows them to write memory safe code, more power to them I guess. Anyway, for the cases where DIP1000 is adequate, no other annotations are needed. Library developers do need them though.The design of dip1000 does not preclude this, however, and it's good to see how far we can push things and avoid needing such complexity.It does not allow me to do most of the things I'd like to do with lifetime tracking. At least `scope` is checked by the compiler more reliably now, which is good.- have such parameterized scope return annotations on fields of aggregates.Same problem. Let's see how far we can get without them. ...P.S. another annotation that nobody is able to use effectively (or correctly) is C's `restrict` keyword. C++ never bothered to adopt it. Though it was a bad design anyway, as the compiler cannot check if it is used correctly, it just generates bad code. ImportC just ignores `restrict`.(That's a completely different case.)
Oct 24 2022
On 10/24/2022 4:18 PM, Timon Gehr wrote:It does not allow me to do most of the things I'd like to do with lifetime tracking.I'd appreciate if you would write this all up, and in the simplest possible terms. Most examples I see are hopelessly overcomplicated, I have to do a lot of reduction to figure out the essence of it :-/ For example, there's no need for templates to demonstrate a lifetime issue. Or arrays, or non-static member functions, or copy constructors, or other abstractions. Almost always simple pointers and refs will do.At least `scope` is checked by the compiler more reliably now, which is good.I try to distinguish between fundamental design faults and implementation bugs. I recently went through the entire list of dip1000 issues in bugzilla, including those that asserted that scope was unfixable, and they all turned out to be tractable.
Oct 24 2022
On 10/24/22 21:38, Walter Bright wrote:I'd appreciate if you would write this all upI think this has already past the point where interested parties should get together in a virtual meeting to understand each other. Ali
Oct 24 2022
On Tuesday, 25 October 2022 at 05:08:47 UTC, Ali Çehreli wrote:On 10/24/22 21:38, Walter Bright wrote:Maybe Dconf online can be the place where this can happen 😃I'd appreciate if you would write this all upI think this has already past the point where interested parties should get together in a virtual meeting to understand each other. Ali
Oct 24 2022
On Tuesday, 25 October 2022 at 04:38:48 UTC, Walter Bright wrote:On 10/24/2022 4:18 PM, Timon Gehr wrote:+1It does not allow me to do most of the things I'd like to do with lifetime tracking.I'd appreciate if you would write this all up, and in the simplest possible terms. Most examples I see are hopelessly overcomplicated, I have to do a lot of reduction to figure out the essence of it :-/
Oct 27 2022
On Monday, 24 October 2022 at 22:26:41 UTC, Walter Bright wrote:The design of dip1000 does not preclude this, however, and it's good to see how far we can push things and avoid needing such complexity.I am glad to see a language that is C-like, understandable, trying to not put all the heavy-weight on the programmer but allowing it where it is necessary. This is what kept me with C++ and not Rust so far. Rust is just too rigid and restrictive for a lot of legal coding patterns. As a long-time C++ user (20 years using it non-stop) D, combined with its powerful import('file.ext'), powerful metaprogramming, C/C++ linkage compatibility and interaction and now DIP1000, and a more than reasonable standard library with Ranges, sumtypes and powerful type meta-programming and concurrency it is getting very attractive, at the top of the list: more than Zig, Rust or Nim. Of course, I am more familiar with C++ than anything else. But this is a selling point for me: if you jump to Nim/Zig/Rust you are, in some way, in more foreign territory. I wonder how the status is implementation-wise, that is the part that scares me a bit to jump in. I think the tooling needed some love though I did not try recently. Congrats for the hard work, it has been a ton of years but you show a lot of practical, real-life use in your decisions. My advice would to sell D as an industrial language that can be incrementally adopted from C++ with safety and compatibility guarantees, besides the metaprogramming, beyond what the competition can achieve.
Oct 25 2022
On Tuesday, 25 October 2022 at 10:18:53 UTC, German Diago wrote:My advice would to sell D as an industrial language that can be incrementally adopted from C++ with safety and compatibility guarantees, besides the metaprogramming, beyond what the competition can achieve.I am very satisfied with the `current D`! D just needs `some time` to prove itself. `BetterC` or better interfacing `'C++'` is a good idea!
Oct 25 2022
On Tuesday, 25 October 2022 at 10:51:48 UTC, zjh wrote:`BetterC` or better interfacing `'C++'` is a good idea!I think `'D'` can be the companion language of `'C++'`. For example, as `'C++'` implements coroutines, `'D'` does not need to implement it again. As long as `D` can interface `C++` very well, then, for users, When it's time to use 'D', use 'D'. When it's time to use 'C++', use 'C++'. Isn't it very cool?
Oct 25 2022
On Tuesday, 25 October 2022 at 11:09:38 UTC, zjh wrote:On Tuesday, 25 October 2022 at 10:51:48 UTC, zjh wrote:`BetterC` or better interfacing `'C++'` is a good idea!I think `'D'` can be the companion language of `'C++'`.Maybe one day, someone will come out with a book called `'D for C++ Programmers'` to talk specifically about interfacing `'C++'`. Yes, you don't have to `give up` your `'C++'` skills.
Oct 25 2022
On Tuesday, 25 October 2022 at 11:09:38 UTC, zjh wrote:I think `'D'` can be the companion language of `'C++'`. For example, as `'C++'` implements coroutines, `'D'` does not need to implement it again. As long as `D` can interface `C++` very well, then, for users, When it's time to use 'D', use 'D'. When it's time to use 'C++', use 'C++'. Isn't it very cool?Nope, its not cool. There are people that know D and not C++, since everyone's background is different. Having to learn two new languages is just waste of time, I'd rather just learn C++ and do everything in there if it is the case. Now, it is indeed good to have C++ interop, but being a companion of C++, is a no go imho. Best regards, Alexandru.
Oct 25 2022
On Tuesday, 25 October 2022 at 15:29:27 UTC, Alexandru Ermicioi wrote:On Tuesday, 25 October 2022 at 11:09:38 UTC, zjh wrote:FWIW, D is a language. I would not advocate for or against anything. But the highest chance of success for languages is compatibility to consume the old code bases, that for sure, at least in the big picture. - Kotlin -> compatible with Java - Swift -> interoperable with Objective-C - C -> C++ I did not see a clean-cut language that got popular yet for real use in a considerable amount of places. Namely, compatibility is a feature. How deep is the big question and the devil is in the details: source-compatible? API/ABI? Etc. but throwing away and rewriting is not even realistic.I think `'D'` can be the companion language of `'C++'`. For example, as `'C++'` implements coroutines, `'D'` does not need to implement it again. As long as `D` can interface `C++` very well, then, for users, When it's time to use 'D', use 'D'. When it's time to use 'C++', use 'C++'. Isn't it very cool?Nope, its not cool. There are people that know D and not C++, since everyone's background is different. Having to learn two new languages is just waste of time, I'd rather just learn C++ and do everything in there if it is the case.
Oct 25 2022
On Tuesday, 25 October 2022 at 17:07:34 UTC, German Diago wrote:FWIW, D is a language. I would not advocate for or against anything. But the highest chance of success for languages is compatibility to consume the old code bases, that for sure, at least in the big picture. - Kotlin -> compatible with Java - Swift -> interoperable with Objective-C - C -> C++ I did not see a clean-cut language that got popular yet for real use in a considerable amount of places. Namely, compatibility is a feature. How deep is the big question and the devil is in the details: source-compatible? API/ABI? Etc. but throwing away and rewriting is not even realistic.It is fine, if you have high compatibility with other languages, but I'm against it being a companion of another language, which implies that one without another cannot work.
Oct 25 2022
On Tuesday, 25 October 2022 at 17:34:10 UTC, Alexandru Ermicioi wrote:compatibility with otherI did not see a clean-cut language that got popular yet for real use in a considerable amount of places. Namely, compatibility is a feature. How deep is the big question and the devil is in the details: source-compatible? API/ABI? Etc. but throwing away and rewriting is not even realistic.It is fine, if you have highlanguages, but I'm against it being a companion of another language, which implies that one without another cannot work.Many people have studied `C++` for 10 years or 20 years.`C++` comes out very early. There are many `C++` related libraries. The latest`C++` is also good. It also has some functions and convenience that `D` does not provide. The same is true of `D`. `D` also has shortcomings, such as` default` GC. For me, I can take the advantage of both. If `C++`and `D` interact well, it is very convenient to pick the two languages's advantage! `C++` has a large user base. Many people start learning languages from `C++`. It is not difficult to switch from `C++` to `D`. The basic concepts are similar. Because many of the latest things in `C++` are already in `D`. `D`,Being a `partner` language. It is best to use `'C++' and 'D'` at the same time.
Oct 25 2022
On 10/25/22 17:53, zjh wrote:`D` also has shortcomings, such as` default` GC.What you mean is languages can have different features that a programmer can see advantages to use at different parts of a program. I agree. However, please note that "shortcoming" is purely a negative term, which does not match reality: D's default GC happens to be a strength. I take advantage of it in all of my programs. I am saying the above with full understanding that there are programmers out there who were educated in C++ circles and are sure that garbage collectors are for inferior languages. That is a shortcoming of their education. Ali
Oct 25 2022
On Wednesday, 26 October 2022 at 01:06:27 UTC, Ali Çehreli wrote:I am saying the above with full understanding that there are programmers out there who were educated in C++ circles and are sure that garbage collectors are for inferior languages. That is a shortcoming of their education. AliWell, this is just a `personal opinion`. Of course, maybe due to I can't make good use of it now.
Oct 25 2022
On Wednesday, 26 October 2022 at 01:06:27 UTC, Ali Çehreli wrote:On 10/25/22 17:53, zjh wrote:I am saying the above with full understanding that there are programmers out there who were educated in C++ circles and are sure that garbage collectors are for inferior languages. That is a shortcoming of their education.For short running tools and low volume stuff, yes, GC is good. My practical experience running vibe.d service with GC in production: default GC is a bane. Default should've been nogc.
Oct 25 2022
On Wednesday, 26 October 2022 at 06:28:37 UTC, Arun wrote:On Wednesday, 26 October 2022 at 01:06:27 UTC, Ali Çehreli wrote:I would like to hear your experience with Vibe.d. I would care about performance scaling. I have been genuinely interested in using it for years but I did not dare to jump into it. As opposed to Django. But my intuition tells me that sooner or later Django backends for small things like what I do will be a resource hog compared to D? True that I can partition, do microservices, etc. but that complicates things. On the positive Python side, there is no compilation step and that helps a lot in many situations.On 10/25/22 17:53, zjh wrote:I am saying the above with full understanding that there are programmers out there who were educated in C++ circles and are sure that garbage collectors are for inferior languages. That is a shortcoming of their education.For short running tools and low volume stuff, yes, GC is good. My practical experience running vibe.d service with GC in production: default GC is a bane. Default should've been nogc.
Oct 26 2022
On Wednesday, 26 October 2022 at 10:53:50 UTC, German Diago wrote:On Wednesday, 26 October 2022 at 06:28:37 UTC, Arun wrote:Have you read this? https://raw.githubusercontent.com/reyvaleza/vibed/main/BuildWebAppsinVibe.pdf[...]I would like to hear your experience with Vibe.d. I would care about performance scaling. I have been genuinely interested in using it for years but I did not dare to jump into it. As opposed to Django. But my intuition tells me that sooner or later Django backends for small things like what I do will be a resource hog compared to D? True that I can partition, do microservices, etc. but that complicates things. On the positive Python side, there is no compilation step and that helps a lot in many situations.
Oct 26 2022
On Wednesday, 26 October 2022 at 11:09:30 UTC, Imperatorn wrote:On Wednesday, 26 October 2022 at 10:53:50 UTC, German Diago wrote:Have you read this? https://raw.githubusercontent.com/reyvaleza/vibed/main/BuildWebAppsinVibe.pdfNo I did not, but it is 242 pages. I am not sure I can go through all it at once. But thanks dor the pointer.
Oct 26 2022
On Wednesday, 26 October 2022 at 11:09:30 UTC, Imperatorn wrote:On Wednesday, 26 October 2022 at 10:53:50 UTC, German Diago wrote:After a quick look I do not see what I am looking for to start, though. I am looking for the performance compared to using Django, so requests/s, memory usage, etc. is a good place to start. What I care about is that once I deploy something it is faster than Django. Of course this is going to depend on the use case and my software... so I guess this is something I will have to try myself. - Did the GC get a lot in the way? - It is very memory-intensive? - Are there good alternatives to side-step GC when using Vibe to reasonable ways if that could be a resource hog? Those are the things I would care about. If I use D it would be to lower hosting cost basically.On Wednesday, 26 October 2022 at 06:28:37 UTC, Arun wrote:Have you read this? https://raw.githubusercontent.com/reyvaleza/vibed/main/BuildWebAppsinVibe.pdf[...]I would like to hear your experience with Vibe.d. I would care about performance scaling. I have been genuinely interested in using it for years but I did not dare to jump into it. As opposed to Django. But my intuition tells me that sooner or later Django backends for small things like what I do will be a resource hog compared to D? True that I can partition, do microservices, etc. but that complicates things. On the positive Python side, there is no compilation step and that helps a lot in many situations.
Oct 26 2022
On Wednesday, 26 October 2022 at 11:31:50 UTC, German Diago wrote:On Wednesday, 26 October 2022 at 11:09:30 UTC, Imperatorn wrote:I see, then you should look into arsd imo, very simple and minimal. It doesn't get much more simple than this https://arsd-official.dpldocs.info/arsd.cgi.html[...]After a quick look I do not see what I am looking for to start, though. I am looking for the performance compared to using Django, so requests/s, memory usage, etc. is a good place to start. What I care about is that once I deploy something it is faster than Django. Of course this is going to depend on the use case and my software... so I guess this is something I will have to try myself. - Did the GC get a lot in the way? - It is very memory-intensive? - Are there good alternatives to side-step GC when using Vibe to reasonable ways if that could be a resource hog? Those are the things I would care about. If I use D it would be to lower hosting cost basically.
Oct 26 2022
On Wednesday, 26 October 2022 at 10:53:50 UTC, German Diago wrote:On Wednesday, 26 October 2022 at 06:28:37 UTC, Arun wrote:Is django really that much of a resource hog though? If stuff like Instagram can use it just fine, maybe we're just being overly pessimistic? https://instagram-engineering.com/web-service-efficiency-at-instagram-with-python-4976d078e366On Wednesday, 26 October 2022 at 01:06:27 UTC, Ali Çehreli wrote:I would like to hear your experience with Vibe.d. I would care about performance scaling. I have been genuinely interested in using it for years but I did not dare to jump into it. As opposed to Django. But my intuition tells me that sooner or later Django backends for small things like what I do will be a resource hog compared to D? True that I can partition, do microservices, etc. but that complicates things. On the positive Python side, there is no compilation step and that helps a lot in many situations.On 10/25/22 17:53, zjh wrote:I am saying the above with full understanding that there are programmers out there who were educated in C++ circles and are sure that garbage collectors are for inferior languages. That is a shortcoming of their education.For short running tools and low volume stuff, yes, GC is good. My practical experience running vibe.d service with GC in production: default GC is a bane. Default should've been nogc.
Oct 26 2022
On Wednesday, 26 October 2022 at 10:53:50 UTC, German Diago wrote:On Wednesday, 26 October 2022 at 06:28:37 UTC, Arun wrote:Also, a benchmark site : https://www.techempower.com/benchmarks//#section=data-r21&test=composite Just do ctrl-f and look for vibed and django For those who want a 1 number summary: vibe is at 92 django at 137On Wednesday, 26 October 2022 at 01:06:27 UTC, Ali Çehreli wrote:I would like to hear your experience with Vibe.d. I would care about performance scaling. I have been genuinely interested in using it for years but I did not dare to jump into it. As opposed to Django. But my intuition tells me that sooner or later Django backends for small things like what I do will be a resource hog compared to D? True that I can partition, do microservices, etc. but that complicates things. On the positive Python side, there is no compilation step and that helps a lot in many situations.[...][...]For short running tools and low volume stuff, yes, GC is good. My practical experience running vibe.d service with GC in production: default GC is a bane. Default should've been nogc.
Oct 26 2022
On 10/26/22 2:28 AM, Arun wrote:On Wednesday, 26 October 2022 at 01:06:27 UTC, Ali Çehreli wrote:My experience with vibe.d with GC is just fine. In fact, I think it's a great use case (vibe uses lots of little allocations for each request). -SteveOn 10/25/22 17:53, zjh wrote:I am saying the above with full understanding that there are programmers out there who were educated in C++ circles and are sure that garbage collectors are for inferior languages. That is a shortcoming of their education.For short running tools and low volume stuff, yes, GC is good. My practical experience running vibe.d service with GC in production: default GC is a bane. Default should've been nogc.
Oct 26 2022
On Wednesday, 26 October 2022 at 00:53:26 UTC, zjh wrote:On Tuesday, 25 October 2022 at 17:34:10 UTC, Alexandru Ermicioi wrote:It also has some functions and convenience that `D` does not provide.Besides concepts, what are those exactly? D metaprogramming is ahead of C++'s and #embed, which goes into C23 and probably C++26 is import("file") in D for years, modules are not there yet, D has had them for years. Overload resolution is easier to understand also in D. I do not see (from a language-level, not ecosystem, which is clearly behind) what is clearly worse from D compared to C++. CTFE is also there for years. C++ is just catching up on this.The same is true of `D`. `D` also has shortcomings, such as` default` GC.You have nogc, not sure how well it works in practice. You lose slices to begin with as far as I understand, or most uses of them. That said, nothing would prevent you from having your own struct similar to `std::span` I think?`C++` has a large user base. Many people start learning languages from `C++`.True. I based most of my career around it.Because many of the latest things in `C++` are already in `D`. `D`,Being a `partner` language. It is best to use `'C++' and 'D'` at the same time.Nothing prevents you from using it today in a "companion" mode. It is just that it is more than powerful enough to be an independent language as well IMHO. In my list, after years and years taking a look at Nim, Rust, Zig (C replacement more than C++) and others, I think the winner, with a little more ecosystem love, is D. The reason is because it is powerful, productive and has few surprises compared to C++ and there is a serious effort in code reuse coming from C/C++, which are, whether we like it or not, the kings of native.
Oct 26 2022
On Wednesday, 26 October 2022 at 10:51:03 UTC, German Diago wrote:whether we like it or not, the kings of native.You are more `radical` than me. Yes, `C++` means that there are many `libs`. Therefore, I suggest that vigorously developing the interfacing with `C++`, as well as `tutorials`. There are too few learning materials. Personally, I like the concept of `RAII` very much. I will not discuss `GC`. every one has his own hobby. `Interfacing C++` and `BetterC` are all good directions!
Oct 26 2022
On Tuesday, 25 October 2022 at 17:34:10 UTC, Alexandru Ermicioi wrote:On Tuesday, 25 October 2022 at 17:07:34 UTC, German Diago wrote:I do not propose that at all either. I propose the best path forward compared to alternatives if you are using C++ as a big user-base case. Of course, fullfilling other cases is nice also. But I think this one is crucial.FWIW, D is a language. I would not advocate for or against anything. But the highest chance of success for languages is compatibility to consume the old code bases, that for sure, at least in the big picture. - Kotlin -> compatible with Java - Swift -> interoperable with Objective-C - C -> C++ I did not see a clean-cut language that got popular yet for real use in a considerable amount of places. Namely, compatibility is a feature. How deep is the big question and the devil is in the details: source-compatible? API/ABI? Etc. but throwing away and rewriting is not even realistic.It is fine, if you have high compatibility with other languages, but I'm against it being a companion of another language, which implies that one without another cannot work.
Oct 26 2022
On Tuesday, 25 October 2022 at 10:18:53 UTC, German Diago wrote:On Monday, 24 October 2022 at 22:26:41 UTC, Walter Bright wrote:+1[...]I am glad to see a language that is C-like, understandable, trying to not put all the heavy-weight on the programmer but allowing it where it is necessary. This is what kept me with C++ and not Rust so far. Rust is just too rigid and restrictive for a lot of legal coding patterns. [...]
Oct 26 2022
On Sunday, 23 October 2022 at 23:02:41 UTC, Timon Gehr wrote:On 10/23/22 09:08, Imperatorn wrote:But, he's working on it ;) "hope is the last thing tha..."On Sunday, 23 October 2022 at 02:42:53 UTC, Mike Parker wrote:I don't expect it to be "finalized" very soon. It lacks expressiveness, which will be improved by small, incremental changes. Which also means it won't be stable all that soon.On Sunday, 23 October 2022 at 01:02:16 UTC, Paul Backus wrote:That's good to know. Would be great news if Dip1000 would be finalized ☀️My prediction: if Walter gets bored of ImportC and decides to make pattern matching his next project, we'll get it. If he doesn't, we won't.Walter's primary focus right now is shoring up DIP 1000.
Oct 24 2022
On Sunday, 23 October 2022 at 01:02:16 UTC, Paul Backus wrote:On Sunday, 23 October 2022 at 00:12:32 UTC, ryuukk_ wrote: I am less optimistic about built-in sum types. The DMD frontend is not really designed to accomodate adding an entire new category of types to D's type system.Can you elaborate on why this is case? Would be interesting to hear Walter's opinion on built-in sum-types and obstacles in implementing them in dmd.
Oct 23 2022
On 10/23/2022 2:27 PM, Per Nordlöw wrote:Would be interesting to hear Walter's opinion on built-in sum-types and obstacles in implementing them in dmd.I haven't thought much about them yet.
Oct 23 2022
On 10/22/22 17:12, ryuukk_ wrote:https://twitter.com/seanbax/status/1583654796791140352/photo/1Is that really C++? I ask because there is no mention of C++ there. Sean Baxter has been adding amazing features (very similar to D in many cases) to his Circle compiler. Not all influential C++ people agree with Circle's approach. I do agree with Circle's approach but I am not influential. :o) Ali
Oct 22 2022
On Sunday, 23 October 2022 at 01:01:20 UTC, Ali Çehreli wrote:On 10/22/22 17:12, ryuukk_ wrote:Thanks for pointing that out, i didn't know, i thought it was related to the pattern matching proposal: https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1371r1.pdfhttps://twitter.com/seanbax/status/1583654796791140352/photo/1Is that really C++? I ask because there is no mention of C++ there. Sean Baxter has been adding amazing features (very similar to D in many cases) to his Circle compiler. Not all influential C++ people agree with Circle's approach. I do agree with Circle's approach but I am not influential. :o) Ali
Oct 22 2022
On Sunday, 23 October 2022 at 00:12:32 UTC, ryuukk_ wrote:Is it still planned or it was mentioned as "what's possible next"?It is not and has never been "planned". It's something Walter would like in the future, but he has other priorities at the moment. That makes it a good candidate for a DIP.
Oct 22 2022
On Sunday, 23 October 2022 at 00:12:32 UTC, ryuukk_ wrote:One issue with C++'s take is they will reserve 2 more keywords (choice, match), i think it is a huge mistake, enum and switch should have been reused imoCan they reuse switch? In Swift they have pattern matching but they use the switch keyword for their jack-of-all-trades switch statement. Problem with C++ (and D) is that the switch statement is fallthrough by default. In order to fix this historical mistake they need a complete new keyword. This is something to fix in D3, remove fallthrogh by default.
Oct 23 2022
On Sunday, 23 October 2022 at 10:43:40 UTC, IGotD- wrote:On Sunday, 23 October 2022 at 00:12:32 UTC, ryuukk_ wrote:"switch (var)" into "var switch".One issue with C++'s take is they will reserve 2 more keywords (choice, match), i think it is a huge mistake, enum and switch should have been reused imoCan they reuse switch? In Swift they have pattern matching but they use the switch keyword for their jack-of-all-trades switch statement. Problem with C++ (and D) is that the switch statement is fallthrough by default. In order to fix this historical mistake they need a complete new keyword. This is something to fix in D3, remove fallthrogh by default.
Oct 23 2022
On 10/23/2022 3:43 AM, IGotD- wrote:Can they reuse switch? In Swift they have pattern matching but they use the switch keyword for their jack-of-all-trades switch statement. Problem with C++ (and D) is that the switch statement is fallthrough by default. In order to fix this historical mistake they need a complete new keyword. This is something to fix in D3, remove fallthrogh by default.Fallthrough by default was removed from D many years ago. The awkward problem with re-using switch is that each case does not introduce a new scope. This raises all kinds of problems when using pattern matching to declare new variables. A second awkward problem is that case statements can be placed inside nested scopes. It's better to just leave switch as it is, and develop a new construct for pattern matching that hews to modern sensibilities.
Oct 23 2022
On Sunday, 23 October 2022 at 19:28:37 UTC, Walter Bright wrote:Fallthrough by default was removed from D many years ago.Yeah, but the break statement must still be there. I was think more like the break isn't needed at all. It should be the other way around that you have a "fallthrough" keyword instead.
Oct 23 2022
On 10/23/22 21:28, Walter Bright wrote:On 10/23/2022 3:43 AM, IGotD- wrote:Actually, each case does introduce a new scope: ```d int main(){ int x; switch(x){ case 0: int y; break; case 1: int y; break; default: int y; break; } return 0; } ``` (You get compiler errors trying to compile that as C code, but not when you try to compile it as D code.) https://dlang.org/spec/statement.html#switch-statementCan they reuse switch? In Swift they have pattern matching but they use the switch keyword for their jack-of-all-trades switch statement. Problem with C++ (and D) is that the switch statement is fallthrough by default. In order to fix this historical mistake they need a complete new keyword. This is something to fix in D3, remove fallthrogh by default.Fallthrough by default was removed from D many years ago. The awkward problem with re-using switch is that each case does not introduce a new scope.The ScopeStatementList introduces a new scope.Not sure if it has always been this way (it seems my frontend that I mostly developed ~10 years ago does fail to introduce a new scope).This raises all kinds of problems when using pattern matching to declare new variables. A second awkward problem is that case statements can be placed inside nested scopes. It's better to just leave switch as it is, and develop a new construct for pattern matching that hews to modern sensibilities.I agree with this though. Another problem is that switch cases are not ordered and are supposed to be disjoint. But for pattern matching, the semantics is usually to try each pattern in order, where patterns can overlap and you are supposed to put more specific patterns earlier. Of course, one could think about additionally adding some pattern support to switch, where the compiler checks that all patterns are disjoint, but does not seem very nice to use. Also seems like somewhat of a hassle to implement.
Oct 23 2022
On 10/23/2022 4:21 PM, Timon Gehr wrote:Actually, each case does introduce a new scope:Ack, you're right. Going back and forth between C and D confuses me.Another problem is that switch cases are not ordered and are supposed to be disjoint. But for pattern matching, the semantics is usually to try each pattern in order, where patterns can overlap and you are supposed to put more specific patterns earlier.Yup.Of course, one could think about additionally adding some pattern support to switch, where the compiler checks that all patterns are disjoint, but does not seem very nice to use. Also seems like somewhat of a hassle to implement.The syntax of switch is old-fashioned, too. A more modern one would be: match (x) { 0 => foo(); 3 => bar(); } Note the lack of need for `break`.
Oct 23 2022
On Sunday, 23 October 2022 at 23:40:21 UTC, Walter Bright wrote:The syntax of `switch` is old-fashioned, too.Yes.A more modern one would be: match (x) { 0 => foo(); 3 => bar(); } Note the lack of need for `break`.No. Java re-used the `swtich` keyword and IMO is correct in doing so. The rest is great as in Java. the `expression switch { case pattern => …; }` *expression* and the `switch (expression) { case value => statement; }` version. Like with `mixin`, there can be a statement and an expression form, and while the mixin stuff is confusing, here the syntax is visually different.
Oct 24 2022
On Monday, 24 October 2022 at 14:05:47 UTC, Quirin Schroll wrote:IMO `match` is a much better name than `switch`, which I didn't find intuitive when I first encountered it, and it only made sense because it was followed by a series of `case` statements. I would like the above syntax plus ``` match (x) { 0 => &foo; 3 => &bar; } ``` where `foo` and `bar` are functions taking one argument, and ``` match (x) { case(0): lines of code break; 3 => &foo; 4 => bar(); } ``` No idea if this would be possible/sensible, but it's one of the few things that would be a big improvement when I'm writing D programs.A more modern one would be: match (x) { 0 => foo(); 3 => bar(); } Note the lack of need for `break`.No. Java re-used the `swtich` keyword and IMO is correct in doing so. The rest is great as in Java.
Oct 24 2022
On Monday, 24 October 2022 at 14:39:26 UTC, bachmeier wrote:On Monday, 24 October 2022 at 14:05:47 UTC, Quirin Schroll wrote:What about: ```D auto result = switch (x) { 0,1,2 => aaa(); 3 => bbb(); 4 => ccc(); 5 => { int a = 1+1; return a; }; else => 0; } ``` If the symbol after switch is not "``case``" or "``default``", then the compiler can process it as "enhanced" switchIMO `match` is a much better name than `switch`, which I didn't find intuitive when I first encountered it, and it only made sense because it was followed by a series of `case` statements. I would like the above syntax plus ``` match (x) { 0 => &foo; 3 => &bar; } ``` where `foo` and `bar` are functions taking one argument, and ``` match (x) { case(0): lines of code break; 3 => &foo; 4 => bar(); } ``` No idea if this would be possible/sensible, but it's one of the few things that would be a big improvement when I'm writing D programs.A more modern one would be: match (x) { 0 => foo(); 3 => bar(); } Note the lack of need for `break`.No. Java re-used the `swtich` keyword and IMO is correct in doing so. The rest is great as in Java.
Oct 24 2022
PHP also got builtin sumtype and pattern matching https://laravel-news.com/modern-php-features-explained https://news.ycombinator.com/item?id=33357318 D lagging behind most languages now :/
Oct 27 2022
On Thursday, 27 October 2022 at 15:14:30 UTC, ryuukk_ wrote:PHP also got builtin sumtype and pattern matching https://laravel-news.com/modern-php-features-explained https://news.ycombinator.com/item?id=33357318 D lagging behind most languages now :/I do not think pattern matching is a must-have. It can be quite nice, but you can do lots with all the other things.
Oct 27 2022
On 10/27/22 18:08, German Diago wrote:On Thursday, 27 October 2022 at 15:14:30 UTC, ryuukk_ wrote:I believe it's quickly becoming a feature where people will be pretty upset that a language lacks it. Lack of algebraic data types is definitely a reason why some people are avoiding D in my experience.PHP also got builtin sumtype and pattern matching https://laravel-news.com/modern-php-features-explained https://news.ycombinator.com/item?id=33357318 D lagging behind most languages now :/I do not think pattern matching is a must-have. It can be quite nice, but you can do lots with all the other things.
Oct 27 2022
On Thursday, 27 October 2022 at 15:14:30 UTC, ryuukk_ wrote:PHP also got builtin sumtype and pattern matching https://laravel-news.com/modern-php-features-explained https://news.ycombinator.com/item?id=33357318 D lagging behind most languages now :/D also has them: https://dlang.org/phobos/std_sumtype.html#match
Oct 28 2022
On Friday, 28 October 2022 at 09:35:06 UTC, Sergey wrote:On Thursday, 27 October 2022 at 15:14:30 UTC, ryuukk_ wrote:std.sumtype is buggy, it's slow and it is a template C/C++ also had them with MACROs, why do you think they decided to now have them has built in feature?PHP also got builtin sumtype and pattern matching https://laravel-news.com/modern-php-features-explained https://news.ycombinator.com/item?id=33357318 D lagging behind most languages now :/D also has them: https://dlang.org/phobos/std_sumtype.html#match
Oct 28 2022
On Friday, 28 October 2022 at 12:34:42 UTC, ryuukk_ wrote:On Friday, 28 October 2022 at 09:35:06 UTC, Sergey wrote:Only with D the solution is a template, then your program takes 30 seconds to compile and people wonder why it is slow, don't put the burden on the users for something this essential, it doesn't look goodOn Thursday, 27 October 2022 at 15:14:30 UTC, ryuukk_ wrote:std.sumtype is buggy, it's slow and it is a template C/C++ also had them with MACROs, why do you think they decided to now have them has built in feature?PHP also got builtin sumtype and pattern matching https://laravel-news.com/modern-php-features-explained https://news.ycombinator.com/item?id=33357318 D lagging behind most languages now :/D also has them: https://dlang.org/phobos/std_sumtype.html#match
Oct 28 2022
On Friday, 28 October 2022 at 12:36:48 UTC, ryuukk_ wrote:On Friday, 28 October 2022 at 12:34:42 UTC, ryuukk_ wrote:PHP is hardly a competitor to D.On Friday, 28 October 2022 at 09:35:06 UTC, Sergey wrote:On Thursday, 27 October 2022 at 15:14:30 UTC, ryuukk_ wrote:PHP also got builtin sumtype and pattern matching https://laravel-news.com/modern-php-features-explained https://news.ycombinator.com/item?id=33357318 D lagging behind most languages now :/Has C or C++ actually added sum types to their standards?D also has them: https://dlang.org/phobos/std_sumtype.html#matchstd.sumtype is buggy, it's slow and it is a template C/C++ also had them with MACROs, why do you think they decided to now have them has built in feature?Only with D the solution is a template, then your program takes 30 seconds to compile and people wonder why it is slow, don't put the burden on the users for something this essential, it doesn't look goodD templates are fast, unlike in C++. Maybe you're using other features like CTFE slowing things down. Or maybe the front end isn't using GC and you're short on memory. Either way doesn't seem like a fundamental criticism of std.sumtype, though they may exist.
Oct 28 2022
On Friday, 28 October 2022 at 14:43:54 UTC, Nick Treleaven wrote:Has C or C++ actually added sum types to their standards?It was proposed and feedback was favorable, it's only just a matter of when now
Oct 28 2022
On Friday, 28 October 2022 at 14:47:27 UTC, ryuukk_ wrote:On Friday, 28 October 2022 at 14:43:54 UTC, Nick Treleaven wrote:Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.Has C or C++ actually added sum types to their standards?It was proposed and feedback was favorable, it's only just a matter of when now
Oct 28 2022
On Friday, 28 October 2022 at 14:49:28 UTC, Nick Treleaven wrote:On Friday, 28 October 2022 at 14:47:27 UTC, ryuukk_ wrote:Here is the latest revision i could find https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1371r3.pdf And Bjarne Stroustrup thoughts https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2021/p2411r0.pdfOn Friday, 28 October 2022 at 14:43:54 UTC, Nick Treleaven wrote:Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.Has C or C++ actually added sum types to their standards?It was proposed and feedback was favorable, it's only just a matter of when nowFinal wordsI am still of the opinion that after a general model of concurrency, a module version of the standardlibrary, and library support for coroutines, pattern matching is the most promising addition to the language for the (relatively) near future [P2000].
Oct 28 2022
On Friday, 28 October 2022 at 15:29:15 UTC, ryuukk_ wrote:On Friday, 28 October 2022 at 14:49:28 UTC, Nick Treleaven wrote:That's pattern matching (I probably confused things mentioning circle). Presumably sum types would still be a library feature in C++.On Friday, 28 October 2022 at 14:47:27 UTC, ryuukk_ wrote:Here is the latest revision i could find https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1371r3.pdf And Bjarne Stroustrup thoughts https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2021/p2411r0.pdfOn Friday, 28 October 2022 at 14:43:54 UTC, Nick Treleaven wrote:Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.Has C or C++ actually added sum types to their standards?It was proposed and feedback was favorable, it's only just a matter of when now
Oct 28 2022
On Friday, 28 October 2022 at 15:45:51 UTC, Nick Treleaven wrote:On Friday, 28 October 2022 at 15:29:15 UTC, ryuukk_ wrote:On Friday, 28 October 2022 at 14:49:28 UTC, Nick Treleaven wrote:That's pattern matching (I probably confused things mentioning circle). Presumably sum types would still be a library feature in C++.On Friday, 28 October 2022 at 14:47:27 UTC, ryuukk_ wrote:Here is the latest revision i could find https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1371r3.pdf And Bjarne Stroustrup thoughts https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2021/p2411r0.pdfOn Friday, 28 October 2022 at 14:43:54 UTC, Nick Treleaven wrote:Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.Has C or C++ actually added sum types to their standards?It was proposed and feedback was favorable, it's only just a matter of when now10.1 Language Support for VariantThe design of this proposal also accounts for a potential language support for variant. It achieves this by keeping the alternative pattern flexible for new extensions via < new_entity > pattern.Consider an extension to union that allows it to be tagged by an integral, and has proper lifetime managementsuch that the active alternative need not be destroyed manually.
Oct 28 2022
On Friday, 28 October 2022 at 15:29:15 UTC, ryuukk_ wrote:On Friday, 28 October 2022 at 14:49:28 UTC, Nick Treleaven wrote:This is just the pattern matching part I am guessing. I do not see any built-in sum type there such as Rust's enum or Haskell/Ocalm style stuff for sum types. There is the std::variant library type so far.On Friday, 28 October 2022 at 14:47:27 UTC, ryuukk_ wrote:Here is the latest revision i could find https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2020/p1371r3.pdf And Bjarne Stroustrup thoughts https://www.open-std.org/JTC1/SC22/WG21/docs/papers/2021/p2411r0.pdfOn Friday, 28 October 2022 at 14:43:54 UTC, Nick Treleaven wrote:Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.Has C or C++ actually added sum types to their standards?It was proposed and feedback was favorable, it's only just a matter of when nowFinal wordsI am still of the opinion that after a general model of concurrency, a module version of the standardlibrary, and library support for coroutines, pattern matching is the most promising addition to the language for the (relatively) near future [P2000].
Oct 28 2022
On Friday, 28 October 2022 at 14:49:28 UTC, Nick Treleaven wrote:On Friday, 28 October 2022 at 14:47:27 UTC, ryuukk_ wrote:The feature on ISO C++ is only planned post-C++26, as you say, is long and arduous. Many hardliners don't like Circle regardless of the feature anyway.On Friday, 28 October 2022 at 14:43:54 UTC, Nick Treleaven wrote:Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.Has C or C++ actually added sum types to their standards?It was proposed and feedback was favorable, it's only just a matter of when now
Oct 28 2022
On Friday, 28 October 2022 at 14:47:27 UTC, ryuukk_ wrote:On Friday, 28 October 2022 at 14:43:54 UTC, Nick Treleaven wrote:Really? Who is championing the effort? Because if you do not keep working on it I can tell you out of experience (following WG21 lists since 2008 or so, from the top of my head) that it will vanish if noone keeps going forward.Has C or C++ actually added sum types to their standards?It was proposed and feedback was favorable, it's only just a matter of when now
Oct 28 2022
On Friday, 28 October 2022 at 12:34:42 UTC, ryuukk_ wrote:std.sumtype is buggy, it's slow and it is a template C/C++ also had them with MACROs, why do you think they decided to now have them has built in feature?If you've found any bugs in `std.sumtype`, please report them on issues.dlang.org or https://github.com/pbackus/sumtype/issues!
Oct 28 2022
On Friday, 28 October 2022 at 12:37:22 UTC, Paul Backus wrote:On Friday, 28 October 2022 at 12:34:42 UTC, ryuukk_ wrote:The only fix is to make it a builtin language feature, the burden should not be on the users It is similar with Nullable Try to compile this: https://github.com/d-language-server/dls And try to decipher the error messages full of template messstd.sumtype is buggy, it's slow and it is a template C/C++ also had them with MACROs, why do you think they decided to now have them has built in feature?If you've found any bugs in `std.sumtype`, please report them on issues.dlang.org or https://github.com/pbackus/sumtype/issues!
Oct 28 2022
On Friday, 28 October 2022 at 14:02:37 UTC, ryuukk_ wrote:The only fix is to make it a builtin language feature, the burden should not be on the users It is similar with NullableWe do have a builtin nullable. Given a type `T`, the builtin nullable variant of it is `T*`.
Oct 28 2022
On Friday, 28 October 2022 at 14:15:28 UTC, Dukc wrote:On Friday, 28 October 2022 at 14:02:37 UTC, ryuukk_ wrote:more languages, and make it `?` and call it optional, but nope, it had to be a template, and the syntax changed at will by its author without consertation and consideration for its users!The only fix is to make it a builtin language feature, the burden should not be on the users It is similar with NullableWe do have a builtin nullable. Given a type `T`, the builtin nullable variant of it is `T*`.
Oct 28 2022
On Friday, 28 October 2022 at 14:19:20 UTC, ryuukk_ wrote:more languages, and make it `?` and call it optional, but nope, it had to be a template, and the syntax changed at will by its author without consertation and consideration for its users!Rust do not have a "type?" in order to make it an optional what I know about. You have to use Optional<T>. The Rust syntax is very explicit and often not that nice to read. Also Rust does not have Swift which is really nice. In Rust you must use "and_then" or nested if let statements which is super ugly.
Oct 28 2022
On Friday, 28 October 2022 at 14:42:14 UTC, IGotD- wrote:On Friday, 28 October 2022 at 14:19:20 UTC, ryuukk_ wrote:I should have developed further, but you did it for me so thanksmore languages, and make it `?` and call it optional, but nope, it had to be a template, and the syntax changed at will by its author without consertation and consideration for its users!Rust do not have a "type?" in order to make it an optional what I know about. You have to use Optional<T>. The Rust syntax is very explicit and often not that nice to read. Also Rust does not have optional chaining (ex. let i = var1?.var2?.var3) like "and_then" or nested if let statements which is super ugly.
Oct 28 2022
On Friday, 28 October 2022 at 14:15:28 UTC, Dukc wrote:On Friday, 28 October 2022 at 14:02:37 UTC, ryuukk_ wrote:I really wonder whether we'd have problems with nullables if `scope T* a = new T()` always allocated on the stack, with some way to denote to allocate on the heap if one wants to do thatThe only fix is to make it a builtin language feature, the burden should not be on the users It is similar with NullableWe do have a builtin nullable. Given a type `T`, the builtin nullable variant of it is `T*`.
Oct 28 2022
On Friday, 28 October 2022 at 12:34:42 UTC, ryuukk_ wrote:On Friday, 28 October 2022 at 09:35:06 UTC, Sergey wrote:How is sumtype buggy?On Thursday, 27 October 2022 at 15:14:30 UTC, ryuukk_ wrote:std.sumtype is buggy, it's slow and it is a template C/C++ also had them with MACROs, why do you think they decided to now have them has built in feature?PHP also got builtin sumtype and pattern matching https://laravel-news.com/modern-php-features-explained https://news.ycombinator.com/item?id=33357318 D lagging behind most languages now :/D also has them: https://dlang.org/phobos/std_sumtype.html#match
Oct 28 2022