www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - C++ pattern matching is coming

reply ryuukk_ <ryuukk.dev gmail.com> writes:
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
next sibling parent ryuukk_ <ryuukk.dev gmail.com> writes:
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
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
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
next sibling parent reply Mike Parker <aldacron gmail.com> writes:
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
parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
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:

 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.
That's good to know. Would be great news if Dip1000 would be finalized ☀️
Oct 23 2022
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10/23/22 09:08, Imperatorn wrote:
 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:

 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.
That's good to know. Would be great news if Dip1000 would be finalized ☀️
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.
Oct 23 2022
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10/24/22 01:42, Walter Bright wrote:
 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.
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.
Oct 23 2022
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10/24/22 01:54, Timon Gehr wrote:
 E.g., DIP100
Missed a 0 there.
Oct 23 2022
parent Walter Bright <newshound2 digitalmars.com> writes:
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
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/23/22 8:29 PM, Walter Bright wrote:
 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.
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) -Steve
Oct 23 2022
next sibling parent reply Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/23/22 9:01 PM, Steven Schveighoffer wrote:
 On 10/23/22 8:29 PM, Walter Bright wrote:
 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.
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 ```
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. -Steve
Oct 23 2022
parent Walter Bright <newshound2 digitalmars.com> writes:
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
prev sibling parent Dukc <ajieskola gmail.com> writes:
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
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 24.10.22 02:29, Walter Bright wrote:
 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 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 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.
 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.
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.
 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
parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10/24/22 06:26, Walter Bright wrote:
 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. ...
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.
 
 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 ...
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.
 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.
 
 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.
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.
Oct 24 2022
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
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 ownership
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. 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
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
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
parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 10/24/2022 12:26 PM, rikki cattermole wrote:
 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.
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.
Oct 24 2022
next sibling parent IGotD- <nise nise.com> writes:
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
prev sibling next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
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
next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
parent rikki cattermole <rikki cattermole.co.nz> writes:
On 25/10/2022 11:04 AM, Walter Bright wrote:
 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.
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.
 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
prev sibling parent reply zjh <fqbqrr 163.com> writes:
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
parent zjh <fqbqrr 163.com> writes:
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
prev sibling parent reply Araq <rumpf_a web.de> writes:
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
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
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:
 [...]
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*.
You have some points, but do you have some constructive criticism? What *should* be done, instead of what should *not* be done?
Oct 25 2022
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
next sibling parent reply Paul Backus <snarwin gmail.com> writes:
On Monday, 24 October 2022 at 20:29:55 UTC, Walter Bright wrote:
 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.
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.
Oct 24 2022
parent Walter Bright <newshound2 digitalmars.com> writes:
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
prev sibling parent reply Dukc <ajieskola gmail.com> writes:
On Monday, 24 October 2022 at 20:29:55 UTC, Walter Bright wrote:
 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.
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.
Oct 24 2022
parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
parent reply Dukc <ajieskola gmail.com> writes:
On Monday, 24 October 2022 at 22:15:21 UTC, Walter Bright wrote:
 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.
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; } ```
Oct 25 2022
parent Dukc <ajieskola gmail.com> writes:
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
prev sibling next sibling parent ryuukk_ <ryuukk.dev gmail.com> writes:
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
prev sibling parent Timon Gehr <timon.gehr gmx.ch> writes:
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
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10/25/22 00:26, Walter Bright wrote:
 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. ...
Pretty sure this has already been proposed in some academic paper in the 1990's or earlier.
 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.
 
 - have such parameterized scope return annotations on fields of 
 aggregates.
Same problem. Let's see how far we can get without them. ...
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.
 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
parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 10/24/22 21:38, Walter Bright wrote:

 I'd appreciate if you would write this all up
I 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
parent Tejas <notrealemail gmail.com> writes:
On Tuesday, 25 October 2022 at 05:08:47 UTC, Ali Çehreli wrote:
 On 10/24/22 21:38, Walter Bright wrote:

 I'd appreciate if you would write this all up
I think this has already past the point where interested parties should get together in a virtual meeting to understand each other. Ali
Maybe Dconf online can be the place where this can happen 😃
Oct 24 2022
prev sibling parent jmh530 <john.michael.hall gmail.com> writes:
On Tuesday, 25 October 2022 at 04:38:48 UTC, Walter Bright wrote:
 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 :-/
+1
Oct 27 2022
prev sibling parent reply German Diago <germandiago gmail.com> writes:
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
next sibling parent reply zjh <fqbqrr 163.com> writes:
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
parent reply zjh <fqbqrr 163.com> writes:
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
next sibling parent zjh <fqbqrr 163.com> writes:
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
prev sibling parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
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
parent reply German Diago <germandiago gmail.com> writes:
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:
 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.
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.
Oct 25 2022
parent reply Alexandru Ermicioi <alexandru.ermicioi gmail.com> writes:
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
next sibling parent reply zjh <fqbqrr 163.com> writes:
On Tuesday, 25 October 2022 at 17:34:10 UTC, Alexandru Ermicioi 
wrote:

 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.
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
next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
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
next sibling parent zjh <fqbqrr 163.com> writes:
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.

 Ali
Well, this is just a `personal opinion`. Of course, maybe due to I can't make good use of it now.
Oct 25 2022
prev sibling parent reply Arun <aruncxy gmail.com> writes:
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
next sibling parent reply German Diago <germandiago gmail.com> writes:
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:
 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.
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
next sibling parent reply Imperatorn <johan_forsberg_86 hotmail.com> writes:
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:
 [...]
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.
Have you read this? https://raw.githubusercontent.com/reyvaleza/vibed/main/BuildWebAppsinVibe.pdf
Oct 26 2022
next sibling parent German Diago <germandiago gmail.com> writes:
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.pdf
No 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
prev sibling parent reply German Diago <germandiago gmail.com> writes:
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:
 On Wednesday, 26 October 2022 at 06:28:37 UTC, Arun 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.
Have you read this? https://raw.githubusercontent.com/reyvaleza/vibed/main/BuildWebAppsinVibe.pdf
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
parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
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:
 [...]
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.
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
Oct 26 2022
prev sibling next sibling parent Tejas <notrealemail gmail.com> writes:
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:
 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.
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.
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-4976d078e366
Oct 26 2022
prev sibling parent Tejas <notrealemail gmail.com> writes:
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:
 On Wednesday, 26 October 2022 at 01:06:27 UTC, Ali Çehreli 
 wrote:
 [...]
 [...]
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.
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.
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 137
Oct 26 2022
prev sibling parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 10/26/22 2:28 AM, Arun wrote:
 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.
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). -Steve
Oct 26 2022
prev sibling parent reply German Diago <germandiago gmail.com> writes:
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
parent zjh <fqbqrr 163.com> writes:
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
prev sibling parent German Diago <germandiago gmail.com> writes:
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:
 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.
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.
Oct 26 2022
prev sibling parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
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:
 [...]
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. [...]
+1
Oct 26 2022
prev sibling parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Sunday, 23 October 2022 at 23:02:41 UTC, Timon Gehr wrote:
 On 10/23/22 09:08, Imperatorn wrote:
 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:

 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.
That's good to know. Would be great news if Dip1000 would be finalized ☀️
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.
But, he's working on it ;) "hope is the last thing tha..."
Oct 24 2022
prev sibling parent reply Per =?UTF-8?B?Tm9yZGzDtnc=?= <per.nordlow gmail.com> writes:
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
parent Walter Bright <newshound2 digitalmars.com> writes:
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
prev sibling next sibling parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 10/22/22 17:12, ryuukk_ wrote:
 https://twitter.com/seanbax/status/1583654796791140352/photo/1
Is 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
parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Sunday, 23 October 2022 at 01:01:20 UTC, Ali Çehreli wrote:
 On 10/22/22 17:12, ryuukk_ wrote:
 https://twitter.com/seanbax/status/1583654796791140352/photo/1
Is 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
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.pdf
Oct 22 2022
prev sibling next sibling parent Mike Parker <aldacron gmail.com> writes:
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
prev sibling next sibling parent reply IGotD- <nise nise.com> writes:
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 imo
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.
Oct 23 2022
next sibling parent Paulo Pinto <pjmlp progtools.org> writes:
On Sunday, 23 October 2022 at 10:43:40 UTC, IGotD- wrote:
 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 imo
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.
"switch (var)" into "var switch".
Oct 23 2022
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
next sibling parent IGotD- <nise nise.com> writes:
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
prev sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 10/23/22 21:28, Walter Bright wrote:
 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.
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-statement
 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
parent reply Walter Bright <newshound2 digitalmars.com> writes:
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
parent reply Quirin Schroll <qs.il.paperinik gmail.com> writes:
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
parent reply bachmeier <no spam.net> writes:
On Monday, 24 October 2022 at 14:05:47 UTC, Quirin Schroll wrote:

 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.
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.
Oct 24 2022
parent ryuukk_ <ryuukk.dev gmail.com> writes:
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:

 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.
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.
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" switch
Oct 24 2022
prev sibling parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
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
next sibling parent reply German Diago <germandiago gmail.com> writes:
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
parent Timon Gehr <timon.gehr gmx.ch> writes:
On 10/27/22 18:08, German Diago 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 :/
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.
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.
Oct 27 2022
prev sibling parent reply Sergey <kornburn yandex.ru> writes:
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
parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
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 :/
D also has them: https://dlang.org/phobos/std_sumtype.html#match
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?
Oct 28 2022
next sibling parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
On Friday, 28 October 2022 at 12:34:42 UTC, ryuukk_ wrote:
 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 :/
D also has them: https://dlang.org/phobos/std_sumtype.html#match
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?
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 good
Oct 28 2022
parent reply Nick Treleaven <nick geany.org> writes:
On Friday, 28 October 2022 at 12:36:48 UTC, ryuukk_ wrote:
 On Friday, 28 October 2022 at 12:34:42 UTC, ryuukk_ wrote:
 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 :/
PHP is hardly a competitor to D.
 D also has them: 
 https://dlang.org/phobos/std_sumtype.html#match
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?
Has C or C++ actually added sum types to their standards?
 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 good
D 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
parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
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
next sibling parent reply Nick Treleaven <nick geany.org> writes:
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:
 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
Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.
Oct 28 2022
next sibling parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
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:
 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
Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.
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.pdf
 Final words
 I am still of the opinion that after a general model of 
 concurrency, a module version of the standard
library, and library support for coroutines, pattern matching is the most promising addition to the language for the (relatively) near future [P2000].
Oct 28 2022
next sibling parent reply Nick Treleaven <nick geany.org> writes:
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:
 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:
 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
Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.
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.pdf
That's pattern matching (I probably confused things mentioning circle). Presumably sum types would still be a library feature in C++.
Oct 28 2022
parent ryuukk_ <ryuukk.dev gmail.com> writes:
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:
 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:
 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
Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.
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.pdf
That's pattern matching (I probably confused things mentioning circle). Presumably sum types would still be a library feature in C++.
 10.1 Language Support for Variant
The 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 management
such that the active alternative need not be destroyed manually.
Oct 28 2022
prev sibling parent German Diago <germandiago gmail.com> writes:
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:
 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:
 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
Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.
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.pdf
 Final words
 I am still of the opinion that after a general model of 
 concurrency, a module version of the standard
library, and library support for coroutines, pattern matching is the most promising addition to the language for the (relatively) near future [P2000].
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.
Oct 28 2022
prev sibling parent Paulo Pinto <pjmlp progtools.org> writes:
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:
 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
Do you have a link? I saw the circle compiler extension and feedback wasn't all favourable. Standardising something is long and arduous.
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.
Oct 28 2022
prev sibling parent German Diago <germandiago gmail.com> writes:
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:
 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
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.
Oct 28 2022
prev sibling next sibling parent reply Paul Backus <snarwin gmail.com> writes:
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
parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
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:
 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!
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 mess
Oct 28 2022
parent reply Dukc <ajieskola gmail.com> writes:
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 Nullable
We do have a builtin nullable. Given a type `T`, the builtin nullable variant of it is `T*`.
Oct 28 2022
next sibling parent reply ryuukk_ <ryuukk.dev gmail.com> writes:
On Friday, 28 October 2022 at 14:15:28 UTC, Dukc wrote:
 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 Nullable
We do have a builtin nullable. Given a type `T`, the builtin nullable variant of it is `T*`.
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!
Oct 28 2022
parent reply IGotD- <nise nise.com> writes:
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
parent ryuukk_ <ryuukk.dev gmail.com> writes:
On Friday, 28 October 2022 at 14:42:14 UTC, IGotD- wrote:
 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 optional chaining (ex. let i = var1?.var2?.var3) like "and_then" or nested if let statements which is super ugly.
I should have developed further, but you did it for me so thanks
Oct 28 2022
prev sibling parent Tejas <notrealemail gmail.com> writes:
On Friday, 28 October 2022 at 14:15:28 UTC, Dukc wrote:
 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 Nullable
We do have a builtin nullable. Given a type `T`, the builtin nullable variant of it is `T*`.
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 that
Oct 28 2022
prev sibling parent Imperatorn <johan_forsberg_86 hotmail.com> writes:
On Friday, 28 October 2022 at 12:34:42 UTC, ryuukk_ wrote:
 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 :/
D also has them: https://dlang.org/phobos/std_sumtype.html#match
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?
How is sumtype buggy?
Oct 28 2022