digitalmars.D - A D vs. Rust example
- Don Allen (133/133) Oct 20 2022 I've mentioned in past messages that I had ported a suite of
- jmh530 (3/23) Oct 20 2022 TIL that this works...I thought it would only work for
- =?UTF-8?Q?Ali_=c3=87ehreli?= (5/7) Oct 20 2022 Similar nested function examples appear at the following point during
- jmh530 (3/11) Oct 20 2022 I suppose I just don't make much use of nested functions. Might
- user1234 (6/15) Oct 20 2022 Thanks, that's very interesting.
- IGotD- (34/42) Oct 20 2022 Actually, Rust is even worse for embedded, OS, near hardware
- Don Allen (16/61) Oct 20 2022 Thank you for your evaluation of Rust for embedded work based on
- Don Allen (16/16) Oct 20 2022 Where I do think D would do well by emulating Rust is in the area
- rikki cattermole (4/7) Oct 20 2022 IDE's such as IntelliJ IDEA (D's plugin) call Dscanner all the time to
- =?UTF-8?Q?Ali_=c3=87ehreli?= (3/10) Oct 20 2022 And there is 'dub lint' that uses dscanner under the hood.
- Don Allen (11/19) Oct 21 2022 In my experience, it is an issue. dub lint does not warn about
- rikki cattermole (8/12) Oct 21 2022 DScanner of course is separate from dub, so that isn't an issue if you
- H. S. Teoh (7/10) Oct 20 2022 [...]
- Timon Gehr (7/19) Oct 20 2022 Such warnings don't carry over well to D though, because template
- Paulo Pinto (14/51) Oct 21 2022 Useless or not, it is becoming a thing,
- Guillaume Piolat (9/10) Oct 21 2022 Not sure it will be Rust though.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/15) Oct 21 2022 It is also not true. C/C++ are still completely dominating.
- Guillaume Piolat (13/17) Oct 21 2022 Of course. In the small field of audio, I still haven't seen a
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (8/13) Oct 21 2022 And in addition you have a large number of languages that use DSP
- Quirin Schroll (30/36) Oct 27 2022 There aren’t many languages that have both, templates and
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (31/46) Oct 27 2022 I have found that it is to some extent possible to do such type
- ryuukk_ (11/19) Oct 27 2022 Go annihilated both Java/C# and became the cloud native language
- Imperatorn (6/18) Oct 27 2022 OOP is amazing when you stay true to it, which basically no
- H. S. Teoh (34/57) Oct 27 2022 IMO, D doesn't really need any of the heavyweight OO features because
- jmh530 (8/26) Oct 27 2022 Timon argued on the C++ pattern matching thread [1] that we need
- Timon Gehr (14/38) Oct 27 2022 You can use that for generics if you allow type parameters, but I am not...
- Paulo Pinto (3/13) Oct 21 2022 None of them have the industry backing at the same scale.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (10/11) Oct 21 2022 There are two key use situations that Carbon is meant to address,
- Paulo Pinto (8/19) Oct 21 2022 If you bothered to follow the links I posted above, you will see
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (4/7) Oct 21 2022 Certification for embedded is not about maximizing the
- Walter Bright (2/5) Oct 22 2022 D's gc has turned out to be ideal for CTFE programming.
- Imperatorn (4/19) Oct 23 2022 I have also experienced this. We tried using Rust at work for
- Sergey (2/4) Oct 23 2022 Sad D-man in BetterC mode
- Imperatorn (4/8) Oct 23 2022 Yup, I'm trying to convince the rest of the team we should go
- matheus (8/12) Oct 23 2022 Maybe I'm comparing very different things, but for me this Rust
- Imperatorn (19/32) Oct 23 2022 Yeah, that's why I don't like "hyped" languages.
- ryuukk_ (38/57) Oct 23 2022 That's not all true, TLS version is not needed
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (15/27) Oct 24 2022 But Go has not changed all that much until recently, with minimal
- IGotD- (12/19) Oct 24 2022 I'm not sure what that means. When large companies make languages
- surlymoor (5/6) Oct 20 2022 Thanks for the write-up.
- Don Allen (2/8) Oct 20 2022 Kool-aid does strange things to the human mind :-)
- Steven Schveighoffer (10/20) Oct 20 2022 I would caution against judgment of Rust based on a newcomer's
- Don Allen (25/45) Oct 20 2022 I've written about 10,000 lines of Rust over several years,
- Steven Schveighoffer (10/29) Oct 21 2022 I agree that if you have to use escapes in your safe code to write
- Walter Bright (4/6) Oct 21 2022 The original closure implementation in D did not allocate, and simply er...
- Walter Bright (3/9) Oct 21 2022 I'm glad you wrote this. I thought I was the oldest D programmer! I'm ve...
- Don Allen (5/16) Oct 22 2022 Thank you.
- rassoc (20/38) Oct 20 2022 To be honest, these kind of access patterns are smelly and there almost ...
- Don Allen (19/60) Oct 20 2022 "smelly" and "elegant" are in the nose and eye of the beholder.
- rassoc (4/6) Oct 21 2022 National Spaghetti Day is coming up on January 4th. ;)
- Don Allen (16/34) Oct 21 2022 You should have gone to another therapist to correct your
- IGotD- (16/25) Oct 21 2022 It already exists and it is called Swift. A few engineers from
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (21/25) Oct 21 2022 Swift is probably the best option for writing applications for
- Stefan Hertenberger (17/58) Oct 21 2022 You don't need to reorder, just use references
- Jack Applegame (3/19) Oct 21 2022 Heh. You don't need closures, just use regular functions.
- matheus (12/15) Oct 21 2022 First of all I don't use Rust, I took a look years ago and I
- IGotD- (9/13) Oct 21 2022 I think the point is despite the example is very simple, it's
- Paulo Pinto (3/17) Oct 21 2022 Yeah, but the ecosystem doesn't swallow anything, that is the
- Imperatorn (2/17) Oct 21 2022 Yes, the ecosystem is the problem. Not the language
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (28/30) Oct 21 2022 Please stop saying it is an ecosystem issue. That is not they key
- IGotD- (8/17) Oct 21 2022 Yes, that's my take on it too. The only way out of this is that D
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (12/13) Oct 21 2022 I don't think forking D is a going to work. I think the future of
- Walter Bright (2/3) Oct 22 2022 We welcome DIP proposals from anyone, and once approved, anyone can impl...
- Bruce Carneal (4/14) Oct 22 2022 ...
- Walter Bright (2/6) Oct 21 2022 I repeat my request to make it a HackerNews or Reddit article!
- Don Allen (6/48) Oct 21 2022 Which is contrary to the purpose of using closures -- to capture
- Stefan Hertenberger (2/6) Oct 21 2022 You are right, not sure what i had in mind while writing this :(
- Walter Bright (4/7) Oct 21 2022 The way dip1000 works with closures is to treat the uplevel variables as...
- victoroak (29/44) Oct 21 2022 I think the way it would be advised to write it in Rust would be
- Don Allen (30/77) Oct 22 2022 I think it's clear that my Scheme-ish attempt to use Rust
- Stefan Hertenberger (22/22) Oct 23 2022 I guess, it really depends on what happens in bar and baz but my
- Dukc (15/31) Oct 24 2022 Yes, I believe this shows maybe the biggest weakaness of Rust. I
- Don Allen (36/69) Oct 25 2022 I'd disagree about "biggest". My use of closures would get me a
- Tejas (15/19) Oct 25 2022 But Rust is a system level programming language, it was designed
- Don Allen (11/31) Oct 25 2022 That's true and is essentially what I'm saying -- Rust is fine
- Sergey (7/13) Oct 25 2022 But the browser not really "ordinary" application. And all users
- Don Allen (18/31) Oct 26 2022 If you think that the user experience would be any different if
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (23/33) Oct 26 2022 Browsers are generally written in C++? They use a dedicate GC for
- Don Allen (14/39) Oct 26 2022 Opinion stated as fact. And how do you know that a
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (3/6) Oct 26 2022 This is a useless argument. Browsers support realtime
- Paulo Pinto (8/14) Oct 26 2022 There is nothing more real time that weapons targeting and
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (11/15) Oct 26 2022 Apples and oranges.
- Don Allen (5/11) Oct 26 2022 And are you aware that when and if there is a real-time
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (18/20) Oct 26 2022 Turning off the GC is not an option that will work out as there
- Imperatorn (6/14) Oct 27 2022 I don't understand your argument.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (7/9) Oct 27 2022 Modern browsers such as Firefox and Chrome are nothing like NSCA
- =?UTF-8?Q?Ali_=c3=87ehreli?= (22/29) Oct 27 2022 Ok.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (17/25) Oct 27 2022 No. The argument was whether it makes sense to use Rust for
- =?UTF-8?Q?Ali_=c3=87ehreli?= (24/45) Oct 28 2022 I did not bring D to the table.
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (18/32) Oct 28 2022 Which is the same thing. This was the context, Don implied that
- H. S. Teoh (15/19) Oct 26 2022 [...]
- Siarhei Siamashka (8/15) Oct 25 2022 When developing C++ code, I was solving this problem by just
- Imperatorn (5/14) Oct 25 2022 Hey buddy, someone else on the internet that has used Squirrel. I
- Siarhei Siamashka (20/36) Oct 29 2022 Well, it was not too hard to find Squirrel once you decide that
- Walter Bright (4/8) Oct 27 2022 The fact that D's GC is what enables advanced CTFE programming is often
- rikki cattermole (4/5) Oct 27 2022 Allocate and free memory?
- Walter Bright (4/10) Oct 27 2022 Yes, it is technically possible. But there's no actual purpose to malloc...
- Ola Fosheim =?UTF-8?B?R3LDuHN0YWQ=?= (5/8) Oct 28 2022 It is clearly better to use high level code in CTFE than
- =?UTF-8?Q?Ali_=c3=87ehreli?= (17/24) Oct 28 2022 I want to ask comprehensions and generators as seen in the context of
- Walter Bright (7/10) Oct 27 2022 The trouble with that is much of the UTF-8 out there is not valid. You d...
- H. S. Teoh (14/25) Oct 27 2022 You don't have to refuse anything. Just substitute it with the Unicode
- rikki cattermole (5/11) Oct 27 2022 Officially you are meant to support only well formed UTF and anything
- Walter Bright (9/23) Oct 27 2022 That's one way to deal with it. But until it is so processed, it isn't a...
- Dukc (20/37) Oct 28 2022 Good point. But it could be easily solved by making the naturally
- Walter Bright (11/17) Oct 29 2022 I've discovered that:
- Dukc (10/15) Oct 31 2022 No need, but a bit of benefit since some bugs could be catched at
I've mentioned in past messages that I had ported a suite of personal financial management tools successfully from C to D after first attempting the work with Rust. I thought I'd give you an example of one of the many headaches I encountered with Rust, because it's illustrative of my contention that Rust's memory- and thread-safety without a GC makes the programmer a much more active participant in the memory-management system than do languages equipped with a GC. It's a primary reason why Rust is so much more difficult to learn than languages with GC support. I'm a Scheme enthusiast and have written a lot of it over my many years. A common pattern that is so easy to address in Scheme is a situation where a number of variables get set, usually at the head of a loop, and those variables (sometimes mutable, if they are, for example, Sqlite prepared statements) are needed by a number of functions that are part of the processing. Being able to define closures inside the loop that see those variables as part of their environment makes the code simpler, cleaner, and easier to write, as opposed to passing the needed variables as arguments to the functions at every calling site, C-style. Rust has closures. Great. So here's an example of an attempt to do something along the lines described above with a single mutable variable: ```` fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; let mut baz = || { foo = 42; }; bar(); println!("{}", &mut foo); baz(); println!("{}", &mut foo); } ```` I have a single mutable variable, foo, and two closures, bar and baz, that each mutate the variable. This solution isn't so bad, yes? Except it doesn't compile: ```` Compiling playground v0.0.1 (/playground) error[E0499]: cannot borrow `foo` as mutable more than once at a time --> src/main.rs:7:19 | 4 | let mut bar = || { | -- first mutable borrow occurs here 5 | foo = 17; | --- first borrow occurs due to use of `foo` in closure 6 | }; 7 | let mut baz = || { | ^^ second mutable borrow occurs here 8 | foo = 42; | --- second borrow occurs due to use of `foo` in closure 9 | }; 10 | bar(); | --- first borrow later used here error[E0499]: cannot borrow `foo` as mutable more than once at a time --> src/main.rs:11:20 | 7 | let mut baz = || { | -- first mutable borrow occurs here 8 | foo = 42; | --- first borrow occurs due to use of `foo` in closure ... 11 | println!("{}", &mut foo); | ^^^^^^^^ second mutable borrow occurs here 12 | baz(); | --- first borrow later used here For more information about this error, try `rustc --explain E0499`. error: could not compile `playground` due to 2 previous errors ```` The problem is that the mutable borrows of foo in each of the closures occur, in effect, when the closure is defined, not when it is called. The compiler views this just as it would two assignments to foo -- two mutable borrows in the same scope -- and refuses to compile the program. The solution is to use "interior mutability", which I view as a bit of a hack to get around the limitations of compile-time borrow-checking. Interior mutability lets you mutate variables that look immutable to the compiler and the safety of what you do is checked at runtime (so much for "zero cost"). Here's what the code looks like to fix the above using this approach: ```` use std::cell::RefCell; fn main() { let foo = RefCell::new(5); let bar = || { *foo.borrow_mut() = 17; }; let baz = || { *foo.borrow_mut() = 42; }; bar(); println!("{}", foo.borrow()); baz(); println!("{}", foo.borrow()); } ```` This works, but at the cost of readability and some runtime efficiency. The D equivalent: ```` import std.stdio; void main() { int foo; void bar() { foo = 17; } void baz() { foo = 42; } bar(); writeln(foo); baz(); writeln(foo); } ```` This is just one of multiple examples I personally encountered where Rust's approach to memory- and thread-safety makes life difficult for its users. On simple cost-benefit grounds, I can see using Rust for writing OS drivers (or even an entire OS) or for use in embedded systems, especially if there's a real-time constraint; in other words, where a GC would be unsuitable. But for ordinary applications on today's hardware? Use of Rust instead of D, Go, Nim, etc. makes no sense to me.
Oct 20 2022
On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:[snip] The D equivalent: ```` import std.stdio; void main() { int foo; void bar() { foo = 17; } void baz() { foo = 42; } bar(); writeln(foo); baz(); writeln(foo); } ```` [snip]TIL that this works...I thought it would only work for global/static variables.
Oct 20 2022
On 10/20/22 07:09, jmh530 wrote:TIL that this works...I thought it would only work for global/static variables.Similar nested function examples appear at the following point during one of my presentations: https://www.youtube.com/watch?v=dRORNQIB2wA&t=2419s Ali
Oct 20 2022
On Thursday, 20 October 2022 at 15:54:45 UTC, Ali Çehreli wrote:On 10/20/22 07:09, jmh530 wrote:I suppose I just don't make much use of nested functions. Might consider making more useof them, when needed.TIL that this works...I thought it would only work forglobal/staticvariables.Similar nested function examples appear at the following point during one of my presentations: https://www.youtube.com/watch?v=dRORNQIB2wA&t=2419s Ali
Oct 20 2022
On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:[...] This is just one of multiple examples I personally encountered where Rust's approach to memory- and thread-safety makes life difficult for its users. On simple cost-benefit grounds, I can see using Rust for writing OS drivers (or even an entire OS) or for use in embedded systems, especially if there's a real-time constraint; in other words, where a GC would be unsuitable. But for ordinary applications on today's hardware? Use of Rust instead of D, Go, Nim, etc. makes no sense to me.Thanks, that's very interesting. I've remarked that the problem in the first example is that Rust does not seem to detect that the two closures are not escaped, i.e it seems it has no notion of a difference between nested functions and lambdas.
Oct 20 2022
On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:This is just one of multiple examples I personally encountered where Rust's approach to memory- and thread-safety makes life difficult for its users. On simple cost-benefit grounds, I can see using Rust for writing OS drivers (or even an entire OS) or for use in embedded systems, especially if there's a real-time constraint; in other words, where a GC would be unsuitable. But for ordinary applications on today's hardware? Use of Rust instead of D, Go, Nim, etc. makes no sense to me.Actually, Rust is even worse for embedded, OS, near hardware programming. The memory model just gets in the way of doing those things. Example of things in OS programming are often intrusive containers, pointers/references pointing in all directions and sometimes even to itself, multiple use of containers for the same object, chicken and egg problems. This is where the memory model of just Rust breaks down. Of course you have to use unsafe everywhere but as soon as you do that, things get ugly very quickly. For these tasks C++ is still the obvious choice. However, this is not normal programming and you have to do tricks that you never usually do in application programming. In short Rust is a useless language for embedded and it would take forever to become productive. Also information how to do this in Rust is difficult to find as most of Rust programs are just normal applications and that is also what Rust was originally designed for. I've tried several languages in order to evaluate how it can deal with embedded programs (more advanced than just blinking a LED, real resource handling). I've evaluated Rust, D, Nim, Swift among others and Rust got the place at very bottom by a great margin. There were simply things I couldn't do in Rust and even if it possible it would have taken ages do figure out how to do it. The other languages were more easy, not perfect and you had do deal with some quirks but you understood why and how you could work around them. Just like you I found out how the memory model isn't even zero cost with that you quickly have to resort to reference counting and with that RefCell (which is a runtime check) must be used as you suddenly have several possible paths of mutuable borrows. For financial software I would run from Rust faster than a rabbit. It's just too complicated and other languages offer faster developing times with more convenient libraries. I'm puzzled with the high popularity of Rust, like some kind of mass exorcism.
Oct 20 2022
On Thursday, 20 October 2022 at 14:26:07 UTC, IGotD- wrote:On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:Thank you for your evaluation of Rust for embedded work based on actual experience, which I don't have. I think the lesson of both yours and my experience is that you have to actually try it, get your hands dirty, to understand whether Rust is suitable for both your problem domain and your programming style. You will learn nothing from reading the hype (Exhibit A: the "affectionately named" Book; was this written by a 12-year-old?). I mention the programming style because, for example, someone who had spent their programming life writing C would likely not have encountered the closure issue I did. If all the functions are at top level and everything they need is passed to them as arguments, no problem.This is just one of multiple examples I personally encountered where Rust's approach to memory- and thread-safety makes life difficult for its users. On simple cost-benefit grounds, I can see using Rust for writing OS drivers (or even an entire OS) or for use in embedded systems, especially if there's a real-time constraint; in other words, where a GC would be unsuitable. But for ordinary applications on today's hardware? Use of Rust instead of D, Go, Nim, etc. makes no sense to me.Actually, Rust is even worse for embedded, OS, near hardware programming. The memory model just gets in the way of doing those things. Example of things in OS programming are often intrusive containers, pointers/references pointing in all directions and sometimes even to itself, multiple use of containers for the same object, chicken and egg problems. This is where the memory model of just Rust breaks down. Of course you have to use unsafe everywhere but as soon as you do that, things get ugly very quickly. For these tasks C++ is still the obvious choice. However, this is not normal programming and you have to do tricks that you never usually do in application programming. In short Rust is a useless language for embedded and it would take forever to become productive. Also information how to do this in Rust is difficult to find as most of Rust programs are just normal applications and that is also what Rust was originally designed for. I've tried several languages in order to evaluate how it can deal with embedded programs (more advanced than just blinking a LED, real resource handling). I've evaluated Rust, D, Nim, Swift among others and Rust got the place at very bottom by a great margin. There were simply things I couldn't do in Rust and even if it possible it would have taken ages do figure out how to do it. The other languages were more easy, not perfect and you had do deal with some quirks but you understood why and how you could work around them.Just like you I found out how the memory model isn't even zero cost with that you quickly have to resort to reference counting and with that RefCell (which is a runtime check) must be used as you suddenly have several possible paths of mutuable borrows. For financial software I would run from Rust faster than a rabbit. It's just too complicated and other languages offer faster developing times with more convenient libraries. I'm puzzled with the high popularity of Rust, like some kind of mass exorcism.People (alarmingly frequently) mindlessly jump on band-wagons. We're seeing it in today's politics, but I'll stop right there before destroying this forum :-)
Oct 20 2022
Where I do think D would do well by emulating Rust is in the area of helpful compiler warnings: noting unused variables, constants and imported symbols, pointing out unnecessary parentheses, etc. I do realize that Walter has emphasized compilation speed in dmd and that is a worthy goal. In pursuit of that, some of what I'm suggesting may not be possible with dmd's current level of analysis of the source code. But to the extent that tradeoff exists, I'd suggest re-thinking it. The Rust compiler is much slower than dmd, but I personally did not find its speed (or lack thereof) to be a big issue for me while I was doing Rust development (on contemporary hardware with ~4ghz processors, 32 GB of memory and an NVME SSD). Perhaps there's a cake-and-eat-it solution that would make the additional analysis and resulting warnings optional, so those running on old hardware or care more about compilation speed than the warnings could have it their way too.
Oct 20 2022
On 21/10/2022 4:25 AM, Don Allen wrote:Where I do think D would do well by emulating Rust is in the area of helpful compiler warnings: noting unused variables, constants and imported symbols, pointing out unnecessary parentheses, etc.IDE's such as IntelliJ IDEA (D's plugin) call Dscanner all the time to verify code and get warnings. So in practice this shouldn't be an issue.
Oct 20 2022
On 10/20/22 08:33, rikki cattermole wrote:On 21/10/2022 4:25 AM, Don Allen wrote:And there is 'dub lint' that uses dscanner under the hood. AliWhere I do think D would do well by emulating Rust is in the area of helpful compiler warnings: noting unused variables, constants and imported symbols, pointing out unnecessary parentheses, etc.IDE's such as IntelliJ IDEA (D's plugin) call Dscanner all the time to verify code and get warnings. So in practice this shouldn't be an issue.
Oct 20 2022
On Thursday, 20 October 2022 at 15:33:06 UTC, rikki cattermole wrote:On 21/10/2022 4:25 AM, Don Allen wrote:In my experience, it is an issue. dub lint does not warn about unused imports or unused constants, for example. I also don't use an IDE, unless you consider nvim an IDE. And I don't use dub to build my code (I'm open to it, but I've found the documentation thoroughly inadequate), so using its lint to check my code is more than a bit of a pain. So for me, the D existing tools to statically evaluate code in a manner similar to the Rust compiler are just not where I would like them to be.Where I do think D would do well by emulating Rust is in the area of helpful compiler warnings: noting unused variables, constants and imported symbols, pointing out unnecessary parentheses, etc.IDE's such as IntelliJ IDEA (D's plugin) call Dscanner all the time to verify code and get warnings. So in practice this shouldn't be an issue.
Oct 21 2022
On 22/10/2022 9:11 AM, Don Allen wrote:And I don't use dub to build my code (I'm open to it, but I've found the documentation thoroughly inadequate), so using its lint to check my code is more than a bit of a pain.DScanner of course is separate from dub, so that isn't an issue if you do something different.So for me, the D existing tools to statically evaluate code in amanner similar to the Rust compiler are just not where I would like them to be. DScanner is currently being rewritten to use dmd-fe, so these semantically required checks will be implementable (as long as all files required to compile a module is provided).
Oct 21 2022
On Thu, Oct 20, 2022 at 03:25:36PM +0000, Don Allen via Digitalmars-d wrote:Where I do think D would do well by emulating Rust is in the area of helpful compiler warnings: noting unused variables, constants and imported symbols, pointing out unnecessary parentheses, etc.[...] It would be good to file these as enhancement requests to bugzilla, so that they don't get lost in the dusts of forum history. T -- If you want to solve a problem, you need to address its root cause, not just its symptoms. Otherwise it's like treating cancer with Tylenol...
Oct 20 2022
On 10/20/22 18:49, H. S. Teoh wrote:On Thu, Oct 20, 2022 at 03:25:36PM +0000, Don Allen via Digitalmars-d wrote:Such warnings don't carry over well to D though, because template expansion is untyped. Therefore, by default the compiler will check whether the _generated code_ has any of those issues, which is usually just an annoyance. Lots of false positives. I also don't think people should be encouraged to remove unnecessary parentheses, otherwise they will start to also omit necessary ones.Where I do think D would do well by emulating Rust is in the area of helpful compiler warnings: noting unused variables, constants and imported symbols, pointing out unnecessary parentheses, etc.[...] It would be good to file these as enhancement requests to bugzilla, so that they don't get lost in the dusts of forum history. T
Oct 20 2022
On Thursday, 20 October 2022 at 14:26:07 UTC, IGotD- wrote:On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:Useless or not, it is becoming a thing, https://www.autosar.org/news-events/details/autosar-investigates-how-the-programming-language-rust-could-be-applied-in-adaptive-platform-context/ https://opensource.googleblog.com/2022/10/announcing-kataos-and-sparrow.html https://azure.microsoft.com/en-us/blog/delivering-consistency-and-transparency-for-cloud-hardware-security/ https://techcommunity.microsoft.com/t5/internet-of-things-blog/previewing-rust-on-azure-sphere/ba-p/3494988 https://github.com/orgs/esp-rs/projects/1 https://www.eenewseurope.com/en/arm-joins-the-rust-foundation/ https://www.phoronix.com/news/Rust-Is-Merged-Linux-6.1 I could keep posting links about Rust's rise on the embedded space, but I think you got the point. Naturally I also agree that systems programming languages with GC should be used, but unless we have a big name pushing them, affine type systems have won for low level systems coding.This is just one of multiple examples I personally encountered where Rust's approach to memory- and thread-safety makes life difficult for its users. On simple cost-benefit grounds, I can see using Rust for writing OS drivers (or even an entire OS) or for use in embedded systems, especially if there's a real-time constraint; in other words, where a GC would be unsuitable. But for ordinary applications on today's hardware? Use of Rust instead of D, Go, Nim, etc. makes no sense to me.Actually, Rust is even worse for embedded, OS, near hardware programming. The memory model just gets in the way of doing those things. Example of things in OS programming are often intrusive containers, pointers/references pointing in all directions and sometimes even to itself, multiple use of containers for the same object, chicken and egg problems. This is where the memory model of just Rust breaks down. Of course you have to use unsafe everywhere but as soon as you do that, things get ugly very quickly. For these tasks C++ is still the obvious choice. However, this is not normal programming and you have to do tricks that you never usually do in application programming. In short Rust is a useless language for embedded and it would take forever to become productive. Also information how to do this in Rust is difficult to find as most of Rust programs are just normal applications and that is also what Rust was originally designed for. I've tried several languages in order to evaluate how it can deal with embedded programs (more advanced than just blinking a LED, real resource handling). I've evaluated Rust, D, Nim, Swift among others and Rust got the place at very bottom by a great margin. There were simply things I couldn't do in Rust and even if it possible it would have taken ages do figure out how to do it. The other languages were more easy, not perfect and you had do deal with some quirks but you understood why and how you could work around them. ...
Oct 21 2022
On Friday, 21 October 2022 at 10:16:10 UTC, Paulo Pinto wrote:affine type systems have won for low level systems coding.Not sure it will be Rust though. In the new native language camp, Jai and Odin makes use of Scala-like "context" pointer passed to each function to pass around an allocator, a logger... being true to the monadic nature of allocation and logging. With an important difference there, Odin apparently uses a fixed context, and Jai a custom one where you can put anything. Now THAT is an interesting feature to have for embedded.
Oct 21 2022
On Friday, 21 October 2022 at 11:54:59 UTC, Guillaume Piolat wrote:On Friday, 21 October 2022 at 10:16:10 UTC, Paulo Pinto wrote:It is also not true. C/C++ are still completely dominating. Reactive systems are also done using special tools (functional style). Low level programming is not some narrow field that can be shoehorned into any singular dev environment.affine type systems have won for low level systems coding.Not sure it will be Rust though.nature of allocation and logging. With an important difference there, Odin apparently uses a fixed context, and Jai a custom one where you can put anything. Now THAT is an interesting feature to have for embedded.Implicit context pointers have been suggested for Carbon too. (hidden parameter to functions)
Oct 21 2022
On Friday, 21 October 2022 at 12:11:13 UTC, Ola Fosheim Grøstad wrote:It is also not true. C/C++ are still completely dominating. Reactive systems are also done using special tools (functional style). Low level programming is not some narrow field that can be shoehorned into any singular dev environment.Of course. In the small field of audio, I still haven't seen a single competitive Rust product, despite a lot more ecosystem work from people. And D is super niche there, it's all C++ except formerly FLStudio and Bitwig maybe (the two best DAWs were NOT made with C++). Ironically, Rust not having a lot of support for classical inheritance means people have been building libraries and framework that lacks that essential implementation-hiding subtyping, meaning a creep up of complexity from their subtypes. But building and agreeing on abstractions is what define the ecosystem.
Oct 21 2022
On Friday, 21 October 2022 at 13:53:28 UTC, Guillaume Piolat wrote:work from people. And D is super niche there, it's all C++ except formerly FLStudio and Bitwig maybe (the two best DAWs were NOT made with C++).And in addition you have a large number of languages that use DSP building blocks written in C. Both for composition, prototyping and application extensions (like in scriptable audio applications).But building and agreeing on abstractions is what define the ecosystem.One big weakness in C++ and D is that generic definitions cannot be checked without instantiation.
Oct 21 2022
On Friday, 21 October 2022 at 15:13:44 UTC, Ola Fosheim Grøstad wrote:On Friday, 21 October 2022 at 13:53:28 UTC, Guillaume Piolat wrote:There aren’t many languages that have both, templates and generics; C++/CLI and C++/CX are the only ones I know and I happen to have some experience with them. (In this nomenclature: *template* = independent copy of the implementation for every distinct instantiation, cf. C++ or D templates, especially class templates with mutable static variables; *generic* = one depend on the argument types.) D could introduce generics and it would actually profit more from them than e.g. C++ would because D has first-class reference types and almost no user-defined implicit conversions. Templates are not really a replacement for generics. As an example where generics (would) shine and templates fall flat, consider [range interfaces](https://dlang.org/phobos/std_range_interfaces.html). We have (among others) `InputRange` and `BidirectionalRange`. A function taking an `InputRange!Base` parameter should allow for an argument of type `BidirectionalRange!Derived` (with `Derived` and `Base` classes or interfaces). In D, that is not possible because we cannot express the [variance](https://en.wikipedia.org/wiki/Covariance_and_contravariance (computer_science)) of a type parameter; templates are inherently antithetical to that. Imagine how much more attractive D would be to OO crowd if it had first-class value type boxing, generics with variance and wildcards, and all the other OO stuff modern OO-fist languages minimum to call itself object-oriented. There was some talk (by Átila, IIRC) that having first-class classes and OO in D was a design error. I have no idea whether there is actually a plan to fade those out improve them to be competitive on that front.But building and agreeing on abstractions is what define the ecosystem.One big weakness in C++ and D is that generic definitions cannot be checked without instantiation.
Oct 27 2022
On Thursday, 27 October 2022 at 17:37:59 UTC, Quirin Schroll wrote:There aren’t many languages that have both, templates and generics; C++/CLI and C++/CX are the only ones I know and I happen to have some experience with them.I have found that it is to some extent possible to do such type checks of generics with C++ concepts. I've made some attempts for a generic graphics library I've started on, but it gets tedious quite fast. I would imagine you could do some of the same in D in a more ad-hoc matter, but that would be even more tedious. It basically involves setting up all the constraints and then test them with a single static assert (which involves instantiation, but in the definition file without explicitly using the instance methods). The C++ concept-feature is helpful in this regard, but not helpful enough to make it pleasant… which basically limits my eagerness to use of it in practice. Still, a move in the right direction. D has a chance to learn from C++ and create a better concept-feature. Don't replicate it, look at the use cases where C++ concepts become tedious or difficult to get right, then design something better.D could introduce generics and it would actually profit more from them than e.g. C++ would because D has first-class reference types and almost no user-defined implicit conversions.This is probably true, but you could instead try to find a way to clearly specify and statically check template requirements.Imagine how much more attractive D would be to OO crowd if it had first-class value type boxing, generics with variance and wildcards, and all the other OO stuff modern OO-fist languages minimum to call itself object-oriented.That is a reasonable angle given the large number of programmers closer look at how templates are done and find out what is missing. When was the last time a feature was added to support generic programming?There was some talk (by Átila, IIRC) that having first-class classes and OO in D was a design error. I have no idea whether there is actually a plan to fade those out improve them to be competitive on that front.OO is not a mistake, I agree. I find it quite frustrating to not have inheritance when programming in Go. Just basic things like having a linked list node in the super class makes things much simpler/cost-efficient when you are mixing types in data-structures.
Oct 27 2022
On Thursday, 27 October 2022 at 17:37:59 UTC, Quirin Schroll wrote:Imagine how much more attractive D would be to OO crowd if it had first-class value type boxing, generics with variance and wildcards, and all the other OO stuff modern OO-fist languages minimum to call itself object-oriented. There was some talk (by Átila, IIRC) that having first-class classes and OO in D was a design error. I have no idea whether there is actually a plan to fade those out improve them to be competitive on that front.without the OOP features Rust is becoming the system language of choice without the OOP features Zig is making a dent without the OOP features The more OOP you put in a language, the worst it becomes features doesn't cut it OOP is nice only when kept very simple and minimal
Oct 27 2022
On Thursday, 27 October 2022 at 19:29:15 UTC, ryuukk_ wrote:On Thursday, 27 October 2022 at 17:37:59 UTC, Quirin Schroll wrote:OOP is amazing when you stay true to it, which basically no languages do. The only good example of it is something like smalltalk. Or *maybe* Erlang if you think of each process as an object (Yes, of course there are other languages, but to name some)[...]language without the OOP features Rust is becoming the system language of choice without the OOP features Zig is making a dent without the OOP features The more OOP you put in a language, the worst it becomes features doesn't cut it OOP is nice only when kept very simple and minimal
Oct 27 2022
On Thu, Oct 27, 2022 at 07:29:15PM +0000, ryuukk_ via Digitalmars-d wrote:On Thursday, 27 October 2022 at 17:37:59 UTC, Quirin Schroll wrote:IMO, D doesn't really need any of the heavyweight OO features because typical idiomatic D code doesn't rely heavily on OO, but on other idioms like structs for by-value exchange of data, ranges, and DbI. When the entire language is predicated on OO, like in Java, then you need all the advanced machinery to make OO more tolerable. But when you can simply step outside of the OO box and solve things with other tools, then there isn't a big need for heavy OO machinery.Imagine how much more attractive D would be to OO crowd if it had first-class value type boxing, generics with variance and wildcards, and all the other OO stuff modern OO-fist languages offer. Using itself object-oriented.I think it's a bit extreme to call OO support a design error... but I'd say it's true that in most of my D code, I find little need for OO. D-centric idioms like structs, ranges, DbI, metaprogramming, CTFE, already cover most of the areas that languages like Java use OO for; as a result, the role of OO in D is much narrower than in Java.There was some talk (by tila, IIRC) that having first-class classes and OO in D was a design error. I have no idea whether there is actually a plan to fade those out improve them to be competitive on that front.without the OOP features Rust is becoming the system language of choice without the OOP features Zig is making a dent without the OOP features The more OOP you put in a language, the worst it becomesI disagree. OOP itself isn't bad; it has its place. For certain things, like programming widget hierarchies, OO totally makes sense, and I'd even recommend using OO idioms for that. What's bad is the fallacious philosophy that OO is the be-all and end-all of programming paradigms (the fanboy attitude that unfortunately permeated the scene in the early days of Java), where you try to shoehorn OO into everything else where it doesn't fit, ending up with ridiculous things. Like static singleton "classes" with static methods, whose sole purpose of existence is to give you bragging rights that your code is fully OO-certified, without "bad" things like global functions and global variables. (Spoiler: you just used them, only under a different name.) Sometimes, I daresay even oftentimes, an in-register int or by-value struct is good enough (or even better); there is no need to carry around that excess baggage needed for runtime polymorphism and inheritance, just so you can brag that "everything is an object" and OO-approved and certified.doesn't cut it OOP is nice only when kept very simple and minimalI'd say OOP works very well -- within its own niche. There are many more things in programming than are in the little garden of OO. T -- Two wrongs don't make a right; but three rights do make a left...
Oct 27 2022
On Thursday, 27 October 2022 at 17:37:59 UTC, Quirin Schroll wrote:On Friday, 21 October 2022 at 15:13:44 UTC, Ola Fosheim Grøstad wrote:Timon argued on the C++ pattern matching thread [1] that we need "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`.)". This bears some similarity with generics. [1] https://forum.dlang.org/post/tj633h$1g4e$1 digitalmars.comOn Friday, 21 October 2022 at 13:53:28 UTC, Guillaume Piolat wrote:There aren’t many languages that have both, templates and generics; C++/CLI and C++/CX are the only ones I know and I happen to have some experience with them. (In this nomenclature: *template* = independent copy of the implementation for every distinct instantiation, cf. C++ or D templates, especially class templates with mutable static static variables cannot depend on the argument types.) [snip]But building and agreeing on abstractions is what define the ecosystem.One big weakness in C++ and D is that generic definitions cannot be checked without instantiation.
Oct 27 2022
On 10/27/22 22:43, jmh530 wrote:On Thursday, 27 October 2022 at 17:37:59 UTC, Quirin Schroll wrote:You can use that for generics if you allow type parameters, but I am not convinced that D is currently willing to add all the type system features (type constraints etc) and backend support [2] that would need to come with that to make it convenient to use. I agree that it would be pretty useful though (and it would enable type checking for some templates too). It can actually be designed to play nice with templates in general (which `inout` and lifetimes would also require). (If you instantiate a template with something that has generic arguments in it, implicitly add generic parameters to the template instance and instantiate it with the appropriate arguments.) [2] Although interestingly, some of that is already implemented in typeinfo; the original non-templated built-in AA implementation was basically a generic type.On Friday, 21 October 2022 at 15:13:44 UTC, Ola Fosheim Grøstad wrote:Timon argued on the C++ pattern matching thread [1] that we need "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`.)". This bears some similarity with generics. [1] https://forum.dlang.org/post/tj633h$1g4e$1 digitalmars.comOn Friday, 21 October 2022 at 13:53:28 UTC, Guillaume Piolat wrote:There aren’t many languages that have both, templates and generics; C++/CLI and C++/CX are the only ones I know and I happen to have some experience with them. (In this nomenclature: *template* = independent copy of the implementation for every distinct instantiation, cf. C++ or D templates, especially class templates with mutable static variables cannot depend on the argument types.) [snip]But building and agreeing on abstractions is what define the ecosystem.One big weakness in C++ and D is that generic definitions cannot be checked without instantiation.
Oct 27 2022
On Friday, 21 October 2022 at 11:54:59 UTC, Guillaume Piolat wrote:On Friday, 21 October 2022 at 10:16:10 UTC, Paulo Pinto wrote:None of them have the industry backing at the same scale.affine type systems have won for low level systems coding.Not sure it will be Rust though. In the new native language camp, Jai and Odin makes use of Scala-like "context" pointer passed to each function to pass around an allocator, a logger... being true to the monadic nature of allocation and logging. With an important difference there, Odin apparently uses a fixed context, and Jai a custom one where you can put anything. Now THAT is an interesting feature to have for embedded.
Oct 21 2022
On Friday, 21 October 2022 at 12:41:07 UTC, Paulo Pinto wrote:None of them have the industry backing at the same scale.There are two key use situations that Carbon is meant to address, according to the authors: 1. C++ interop 2. when Rust doesn't perform as well as you like I don't think Rust will take over low level programming. Rust is more of a high level language with some lower level capabilities. That is sufficient for many applications, of course, but it does not have the key characteristics that allows you to maximize the utilization of hardware.
Oct 21 2022
On Friday, 21 October 2022 at 12:50:27 UTC, Ola Fosheim Grøstad wrote:On Friday, 21 October 2022 at 12:41:07 UTC, Paulo Pinto wrote:If you bothered to follow the links I posted above, you will see how the likes of ARM,Google Expressif, and Microsoft are of a different opinion, even though they seat at ISO C++. And the car industry standard for high integrity systems is now certifying Rust for the same purpose alongside C++17. But what do they know.None of them have the industry backing at the same scale.There are two key use situations that Carbon is meant to address, according to the authors: 1. C++ interop 2. when Rust doesn't perform as well as you like I don't think Rust will take over low level programming. Rust is more of a high level language with some lower level capabilities. That is sufficient for many applications, of course, but it does not have the key characteristics that allows you to maximize the utilization of hardware.
Oct 21 2022
On Friday, 21 October 2022 at 13:06:13 UTC, Paulo Pinto wrote:And the car industry standard for high integrity systems is now certifying Rust for the same purpose alongside C++17. But what do they know.Certification for embedded is not about maximizing the utilization of hardware. You can do embedded programming in Java too.
Oct 21 2022
On 10/21/2022 3:16 AM, Paulo Pinto wrote:Naturally I also agree that systems programming languages with GC should be used, but unless we have a big name pushing them, affine type systems have won for low level systems coding.D's gc has turned out to be ideal for CTFE programming.
Oct 22 2022
On Thursday, 20 October 2022 at 14:26:07 UTC, IGotD- wrote:On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:I have also experienced this. We tried using Rust at work for embedded but it slowed us down so much to the point we decided to just do it in C instead.[...]Actually, Rust is even worse for embedded, OS, near hardware programming. The memory model just gets in the way of doing those things. Example of things in OS programming are often intrusive containers, pointers/references pointing in all directions and sometimes even to itself, multiple use of containers for the same object, chicken and egg problems. This is where the memory model of just Rust breaks down. Of course you have to use unsafe everywhere but as soon as you do that, things get ugly very quickly. For these tasks C++ is still the obvious choice. However, this is not normal programming and you have to do tricks that you never usually do in application programming. [...]
Oct 23 2022
On Sunday, 23 October 2022 at 12:19:24 UTC, Imperatorn wrote:On Thursday, 20 October 2022 at 14:26:07 UTC, IGotD- wrote: we decided to just do it in C instead.Sad D-man in BetterC mode
Oct 23 2022
On Sunday, 23 October 2022 at 12:23:14 UTC, Sergey wrote:On Sunday, 23 October 2022 at 12:19:24 UTC, Imperatorn wrote:Yup, I'm trying to convince the rest of the team we should go with betterC. But it's hard to get ppl to try new things (except Rust for some reason)On Thursday, 20 October 2022 at 14:26:07 UTC, IGotD- wrote: we decided to just do it in C instead.Sad D-man in BetterC mode
Oct 23 2022
On Sunday, 23 October 2022 at 12:44:15 UTC, Imperatorn wrote:... Yup, I'm trying to convince the rest of the team we should go with betterC. But it's hard to get ppl to try new things (except Rust for some reason)Maybe I'm comparing very different things, but for me this Rust trend reminds me something similar to Ruby On Rails. Some years ago most companies where I live were hiring mostly RoR developers, even the company that I work for, but now at least where I live it's very hard to find a position for RoR, in fact Matheus.
Oct 23 2022
On Sunday, 23 October 2022 at 13:38:03 UTC, matheus wrote:On Sunday, 23 October 2022 at 12:44:15 UTC, Imperatorn wrote:Yeah, that's why I don't like "hyped" languages. language (quite easy to learn), has good support (ecosystem) and IDEs. Sure it's a bit verbose, but the upsides make it worth it. D has so much potential to be a replacement for many other languages. betterC, maybe even R or Julia. What is needs though is to be stable and have an LTS branch. Companies don't really care at all what language you use, they care about economics and risk mitigation. If I say to my team "let's write the next thing in D", the first question will be about ecosystem, IDEs and other things **surrounding** the language, not the language itself, no matter how good it is, unfortunately. I really hope that one day we will have a bigger following (which will enable us to make better tools), because there are so many things D is better at than many other languages.... Yup, I'm trying to convince the rest of the team we should go with betterC. But it's hard to get ppl to try new things (except Rust for some reason)Maybe I'm comparing very different things, but for me this Rust trend reminds me something similar to Ruby On Rails. Some years ago most companies where I live were hiring mostly RoR developers, even the company that I work for, but now at least where I live it's very hard to find a position for RoR, developers now. Matheus.
Oct 23 2022
On Sunday, 23 October 2022 at 14:55:56 UTC, Imperatorn wrote:Yeah, that's why I don't like "hyped" languages.language (quite easy to learn), has good support (ecosystem) and IDEs. Sure it's a bit verbose, but the upsides make it worth it.D has so much potential to be a replacement for many other languages.betterC, maybe even R or Julia.What is needs though is to be stable and have an LTS branch.Companies don't really care at all what language you use, they care about economics and risk mitigation.If I say to my team "let's write the next thing in D", the first question will be about ecosystem, IDEs and other things surrounding the language, not the language itself, no matter how good it is, unfortunately.I really hope that one day we will have a bigger following (which will enable us to make better tools), because there are so many things D is better at than many other languages.That's not all true, TLS version is not needed Go became the cloud native language without that BS bloat driven corporates As they figured it out, Oracle started to speed up development of the language: - multiple GCs - pattern matching - var - data class - green threads - graalvm - record - pattern matching - green thread - nativeaot Go now is being held back by corporates (amazon/google/microsoft), just like rust D should be free to experiment, not every language needs to be taken hostage by corporates As you said, corporates don't care about what language they use, they'll dump it if they find something that suits their cost requirements better - simplifying the language - finishing the existing features - drastically improving ergonomics in some areas - invest massively in tooling - keep experiment with new ideas and take a look at the backlog of DIPs That's what i'd do if i knew how to make and had to work on a language Mistakes of the past need to go, otherwise people will constantly look for alternative, that alternative needs to be D+1 that fixed past mistakes, and not double down on them, because demography mean the people who rely the mistake will disappear, and the new generation of devs will choose something else
Oct 23 2022
On Sunday, 23 October 2022 at 19:39:49 UTC, ryuukk_ wrote:That's not all true, TLS version is not needed Go became the cloud native language without that BSBut Go has not changed all that much until recently, with minimal breakage.Go now is being held back by corporates (amazon/google/microsoft), just like rustHow is Rust held back by corporations though?D should be free to experiment, not every language needs to be taken hostage by corporates[…]Mistakes of the past need to go, otherwise people will constantly look for alternative, that alternative needs to be D+1 that fixed past mistakes, and not double down on them, because demography mean the people who rely the mistake will disappear, and the new generation of devs will choose something elseYes, but since there is no willingness to take breaking changes in D there seems to be some kind of gridlock as far as language design and evolution goes. Right now there seems to be a flurry of alternatives that aim for the same use scenario as C++. Within 5-10 years some of them will gather a following or C++/Rust will evolve fast enough to keep the competing solutions at a distance. How can D position itself without a significant change in strategy, which would require a new leadership style? Can you see that happening within a timespan of 3 years?
Oct 24 2022
On Sunday, 23 October 2022 at 19:39:49 UTC, ryuukk_ wrote:Go now is being held back by corporates (amazon/google/microsoft), just like rust D should be free to experiment, not every language needs to be taken hostage by corporates As you said, corporates don't care about what language they use, they'll dump it if they find something that suits their cost requirements betterI'm not sure what that means. When large companies make languages they can't push too much abstract compiler technology ideas on the masses because that would hurt the adoption. When companies throw millions into new languages, that would be a waste of money if nobody can use it. One use case is Swift which in my mind is not that difficult but still some Apple developers think it is too complicated. The Apple management is keeping the language developers on a leach so that they don't get out of hand with their academics. Imagine trying to push Rust onto Apple developers, that simply wouldn't have worked and they would have rejected it.
Oct 24 2022
On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:[...]Thanks for the write-up. I'm not endorsing this point of view, but I think the argument made by Rust proponents (fanatics?) would be that your code is unidiomatic, and your point is thereby moot.
Oct 20 2022
On Thursday, 20 October 2022 at 19:51:41 UTC, surlymoor wrote:On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:Kool-aid does strange things to the human mind :-)[...]Thanks for the write-up. I'm not endorsing this point of view, but I think the argument made by Rust proponents (fanatics?) would be that your code is unidiomatic, and your point is thereby moot.
Oct 20 2022
On 10/20/22 4:33 PM, Don Allen wrote:On Thursday, 20 October 2022 at 19:51:41 UTC, surlymoor wrote:I would caution against judgment of Rust based on a newcomer's perspective, though I think it's probably a fair assessment of the *ease of learning* of Rust. I will note that you are not using closures in your D code, but nested functions. Is there not a way to do that in Rust? Many people discount D because their attempts to make it do the things in the way they are used to result in horrible performance, or weird problems. -SteveOn Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:Kool-aid does strange things to the human mind :-)[...]Thanks for the write-up. I'm not endorsing this point of view, but I think the argument made by Rust proponents (fanatics?) would be that your code is unidiomatic, and your point is thereby moot.
Oct 20 2022
On Thursday, 20 October 2022 at 21:28:19 UTC, Steven Schveighoffer wrote:On 10/20/22 4:33 PM, Don Allen wrote:I've written about 10,000 lines of Rust over several years, revised many times in consultation with a couple of people in the Rust community who were particularly helpful. I've been writing code professionally and otherwise for longer than most of you, since I'm now 80 (first line of code in 1960 -- IBM 1620 assembly language). I understand Rust pretty well at this point, so I don't think the "newcomer" description applies. The language is more difficult to master than other I've used (a lot). And if you insist on never writing "unsafe", there are things that are simply impossible to do that are routine in more traditional languages. But, much like Haskell, once you satisfy the compiler, your program will be correct, modulo logic errors or doing something stupid in an "unsafe" block. You won't ever see a segfault due to de-referencing an uninitialized pointer and things of that ilk.On Thursday, 20 October 2022 at 19:51:41 UTC, surlymoor wrote:I would caution against judgment of Rust based on a newcomer's perspective, though I think it's probably a fair assessment of the *ease of learning* of Rust.On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:Kool-aid does strange things to the human mind :-)[...]Thanks for the write-up. I'm not endorsing this point of view, but I think the argument made by Rust proponents (fanatics?) would be that your code is unidiomatic, and your point is thereby moot.I will note that you are not using closures in your D code, but nested functions. Is there not a way to do that in Rust?No. Nested functions don't see their enclosing environment in Rust.Many people discount D because their attempts to make it do the things in the way they are used to result in horrible performance, or weird problems.I did run into that in D, mostly in the area of needing to be aware of preventing the GC from snatching strings I'd passed to C code (sqlite) (you and I shared that adventure last year). This came about in my case because I was porting C code to D, which is mostly very easy, but I missed this gotcha.-Steve
Oct 20 2022
On 10/20/22 10:46 PM, Don Allen wrote:I've written about 10,000 lines of Rust over several years, revised many times in consultation with a couple of people in the Rust community who were particularly helpful. I've been writing code professionally and otherwise for longer than most of you, since I'm now 80 (first line of code in 1960 -- IBM 1620 assembly language). I understand Rust pretty well at this point, so I don't think the "newcomer" description applies.OK, apologies.The language is more difficult to master than other I've used (a lot). And if you insist on never writing "unsafe", there are things that are simply impossible to do that are routine in more traditional languages.I agree that if you have to use escapes in your safe code to write useful programs, the utility of the memory safety goes way down. This is why I'm very keen to see D safe be much easier to isolate.No. Nested functions don't see their enclosing environment in Rust.Hm... closures in D typically mean an allocation. So maybe my terminology is messed up.Yes, I remember. I'm still not satisfied with the lack of ability to ensure something is stored on the stack. -SteveMany people discount D because their attempts to make it do the things in the way they are used to result in horrible performance, or weird problems.I did run into that in D, mostly in the area of needing to be aware of preventing the GC from snatching strings I'd passed to C code (sqlite) (you and I shared that adventure last year). This came about in my case because I was porting C code to D, which is mostly very easy, but I missed this gotcha.
Oct 21 2022
On 10/21/2022 5:52 PM, Steven Schveighoffer wrote:Hm... closures in D typically mean an allocation. So maybe my terminology is messed up.The original closure implementation in D did not allocate, and simply errored if an allocation was necessary. Sometimes I wonder if it would have been better to not have generalized it.
Oct 21 2022
On 10/20/2022 7:46 PM, Don Allen wrote:I've written about 10,000 lines of Rust over several years, revised many times in consultation with a couple of people in the Rust community who were particularly helpful. I've been writing code professionally and otherwise for longer than most of you, since I'm now 80 (first line of code in 1960 -- IBM 1620 assembly language). I understand Rust pretty well at this point, so I don't think the "newcomer" description applies.I'm glad you wrote this. I thought I was the oldest D programmer! I'm very pleased there are more of us using D! I hope I'm as sharp as you are when I'm 80.
Oct 21 2022
On Saturday, 22 October 2022 at 01:35:52 UTC, Walter Bright wrote:On 10/20/2022 7:46 PM, Don Allen wrote:Thank you. The great comedian Red Buttons, at Sid Caesar's 80th birthday celebration: "When my father turned 80, I asked him "Pop, what does a man of 80 think about? He said '81'".I've written about 10,000 lines of Rust over several years, revised many times in consultation with a couple of people in the Rust community who were particularly helpful. I've been writing code professionally and otherwise for longer than most of you, since I'm now 80 (first line of code in 1960 -- IBM 1620 assembly language). I understand Rust pretty well at this point, so I don't think the "newcomer" description applies.I'm glad you wrote this. I thought I was the oldest D programmer! I'm very pleased there are more of us using D! I hope I'm as sharp as you are when I'm 80.
Oct 22 2022
On 20/10/2022 15:37, Don Allen via Digitalmars-d wrote:Rust has closures. Great. So here's an example of an attempt to do something along the lines described above with a single mutable variable: ```` fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; let mut baz = || { foo = 42; }; bar(); println!("{}", &mut foo); baz(); println!("{}", &mut foo); } ````To be honest, these kind of access patterns are smelly and there almost always exists a more elegant alternative. Regarding that example code above, the burrow checker will be happy if you reorder it slightly: ```rust fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; bar(); println!("{}", &mut foo); // just moved this down here let mut baz = || { foo = 42; }; baz(); println!("{}", &mut foo); } ```
Oct 20 2022
On Thursday, 20 October 2022 at 22:41:34 UTC, rassoc wrote:On 20/10/2022 15:37, Don Allen via Digitalmars-d wrote:"smelly" and "elegant" are in the nose and eye of the beholder. As I said in my original post, this kind of code is very common in Scheme.Rust has closures. Great. So here's an example of an attempt to do something along the lines described above with a single mutable variable: ```` fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; let mut baz = || { foo = 42; }; bar(); println!("{}", &mut foo); baz(); println!("{}", &mut foo); } ````To be honest, these kind of access patterns are smelly and there almost always exists a more elegant alternative.Regarding that example code above, the burrow checker will be happy if you reorder it slightly: ```rust fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; bar(); println!("{}", &mut foo); // just moved this down here let mut baz = || { foo = 42; }; baz(); println!("{}", &mut foo); } ```Except the re-ordering you suggest is not possible in the actual code from which this example was derived. In the real code, the mutable variables are sqlite statements where multiple closures refer to several of them and the closures are called in multiple places. You are taking advantage of this simple derived case, where each closure is called in only one place, and also the fact that mutable references are dropped after their last use, to arrange for only one mutable reference to foo active at any time, which is what the borrow checker wants. In the real code, because the closures refer to multiple mutable variables and there are multiple call sites to each closure, it isn't possible to segregate the closures and their call sites to satisfy the borrow checker, but use of interior mutability does work.
Oct 20 2022
On 21/10/2022 05:36, Don Allen via Digitalmars-d wrote:As I said in my original post, this kind of code is very common in Scheme.Right, I walked that path before, even shiny R7RS, and I'm glad I went to speech therapy for my lisp.where multiple closures refer to several of them and the closures are called in multiple placesNational Spaghetti Day is coming up on January 4th. ;) In all seriousness, though, I'm not here to invalidate your experiences with Rust. While I've been using D for quite a bit now, I get to experience some pretty uncomfortable cognitive dissonance doing so. I still love it, but D often times offers a slightly less performant and reliable way to tackle a certain set of hard problems. Even if I never get to experience Rust professionally, I'm still quite happy that it set a new baseline for safe languages to come and evolve to.
Oct 21 2022
On Friday, 21 October 2022 at 07:02:01 UTC, rassoc wrote:On 21/10/2022 05:36, Don Allen via Digitalmars-d wrote:You should have gone to another therapist to correct your tendency to offer opinions about code you haven't seen.As I said in my original post, this kind of code is very common in Scheme.Right, I walked that path before, even shiny R7RS, and I'm glad I went to speech therapy for my lisp.where multiple closures refer to several of them and the closures are called in multiple placesNational Spaghetti Day is coming up on January 4th. ;)In all seriousness, though, I'm not here to invalidate your experiences with Rust. While I've been using D for quite a bit now, I get to experience some pretty uncomfortable cognitive dissonance doing so. I still love it, but D often times offers a slightly less performant and reliable way to tackle a certain set of hard problems. Even if I never get to experience Rust professionally, I'm still quite happy that it set a new baseline for safe languages to come and evolve to.Since you've said something substantive, I'll comment. I actually agree with you that Rust has shown the world that inherently memory- and thread-safe languages are possible. Haskell did some of that before Rust did, but they didn't quite finish the job. But I think there is an opportunity to create a memory-safe language with a GC that avoids many of the difficulties of Rust. And I think thread-safety should be an option, not a requirement, because there are applications that are inherently single-threaded. Those applications should not have to adhere to the rules that keep multi-threaded applications safe, as is the case in Rust, the only alternative being to sprinkle your code with "unsafe" blocks, or use thread_local!, which works, but makes the code similarly messy.
Oct 21 2022
On Friday, 21 October 2022 at 14:04:25 UTC, Don Allen wrote:But I think there is an opportunity to create a memory-safe language with a GC that avoids many of the difficulties of Rust. And I think thread-safety should be an option, not a requirement, because there are applications that are inherently single-threaded. Those applications should not have to adhere to the rules that keep multi-threaded applications safe, as is the case in Rust, the only alternative being to sprinkle your code with "unsafe" blocks, or use thread_local!, which works, but makes the code similarly messy.It already exists and it is called Swift. A few engineers from the Rust team helped engineer Swift. The syntax similarities between Swift and Rust are obvious. In Swift they added a lot of lowering in order to hide the more explicit Rust syntax. If you see the results after the lowering then the Rust syntax shines through even more. Swift added reference counting as GC (much because of objective-C) and the result is that the language is quite usable, much more easy to use than Rust. You will not end up with senseless life time compiler error as in Rust. Swift isn't safe as "nothing can go wrong" but safe enough for me. For embedded systems, Swift isn't an ideal candidate as it relies on its own foundation library, objective-C runtime and C++ standard library. Though there has been people who has successfully ported Swift to OS-less systems.
Oct 21 2022
On Friday, 21 October 2022 at 14:46:16 UTC, IGotD- wrote:Swift added reference counting as GC (much because of objective-C) and the result is that the language is quite usable, much more easy to use than Rust. You will not end up with senseless life time compiler error as in Rust.Swift is probably the best option for writing applications for Apple products, but I don't feel that it will be accepted for portable system level programming, no matter how it changes in the future. Even if it became a Rust/C++ replica it would still be perceived as being beholden to a singular entity. I can see why the Carbon docs put so much emphasis on no entity having more than 50% influence. "Backed by Google" is a selling point, but "Owned by Google" is a liability. As more languages appear I think having a more cooperative collaborative approach to design will be something people look for. Selecting a specific language is a big investment as languages get more complex (even TypeScript has grown to become rather complex). Developers don't want a single "political group" to block a design extension that matters to 20% of the users. Since languages copy features from each other they are sometimes not all that different in ordinary programming, but cultures can be very different still. So that dimension will perhaps be more and more important in the next few decades.
Oct 21 2022
On Thursday, 20 October 2022 at 22:41:34 UTC, rassoc wrote:On 20/10/2022 15:37, Don Allen via Digitalmars-d wrote:You don't need to reorder, just use references ```rust fn main() { let mut foo = 5; let bar = |val: &mut i32| { *val = 17; }; let baz = |val: &mut i32| { *val = 42; }; bar(&mut foo); println!("{}", &mut foo); baz(&mut foo); println!("{}", &mut foo); } ```Rust has closures. Great. So here's an example of an attempt to do something along the lines described above with a single mutable variable: ```` fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; let mut baz = || { foo = 42; }; bar(); println!("{}", &mut foo); baz(); println!("{}", &mut foo); } ````To be honest, these kind of access patterns are smelly and there almost always exists a more elegant alternative. Regarding that example code above, the burrow checker will be happy if you reorder it slightly: ```rust fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; bar(); println!("{}", &mut foo); // just moved this down here let mut baz = || { foo = 42; }; baz(); println!("{}", &mut foo); } ```
Oct 21 2022
On Friday, 21 October 2022 at 07:37:41 UTC, Stefan Hertenberger wrote:You don't need to reorder, just use references ```rust fn main() { let mut foo = 5; let bar = |val: &mut i32| { *val = 17; }; let baz = |val: &mut i32| { *val = 42; }; bar(&mut foo); println!("{}", &mut foo); baz(&mut foo); println!("{}", &mut foo); } ```Heh. You don't need closures, just use regular functions.
Oct 21 2022
On Friday, 21 October 2022 at 07:37:41 UTC, Stefan Hertenberger wrote:... You don't need to reorder, just use references ...First of all I don't use Rust, I took a look years ago and I didn't like its syntax, so I don't know how someone could rewrite the case presented in the original post. But I think people are missing the point of Don Allen, he showed a snipped code and its simplicity, and for it seems it's not easy to do in some languages, at least without changing a lot. For example, I wrote this a while ago: "The problem that took him 5 years to fix in C++, I solved in a minute with D". https://forum.dlang.org/thread/oyfejgtjsupbdgckfdjz forum.dlang.org Matheus.
Oct 21 2022
On Friday, 21 October 2022 at 10:19:13 UTC, matheus wrote:But I think people are missing the point of Don Allen, he showed a snipped code and its simplicity, and for it seems it's not easy to do in some languages, at least without changing a lot.I think the point is despite the example is very simple, it's required to have very detailed knowledge about the Rust compiler and its lifetime system in order to understand this problem. Sure you rewrite in some undefined "idiomatic Rust" but is it good language design when such detailed knowledge and order of statements is required? D is in the other end of this spectrum, it swallows almost anything.
Oct 21 2022
On Friday, 21 October 2022 at 10:36:27 UTC, IGotD- wrote:On Friday, 21 October 2022 at 10:19:13 UTC, matheus wrote:Yeah, but the ecosystem doesn't swallow anything, that is the problem.But I think people are missing the point of Don Allen, he showed a snipped code and its simplicity, and for it seems it's not easy to do in some languages, at least without changing a lot.I think the point is despite the example is very simple, it's required to have very detailed knowledge about the Rust compiler and its lifetime system in order to understand this problem. Sure you rewrite in some undefined "idiomatic Rust" but is it good language design when such detailed knowledge and order of statements is required? D is in the other end of this spectrum, it swallows almost anything.
Oct 21 2022
On Friday, 21 October 2022 at 10:42:52 UTC, Paulo Pinto wrote:On Friday, 21 October 2022 at 10:36:27 UTC, IGotD- wrote:Yes, the ecosystem is the problem. Not the languageOn Friday, 21 October 2022 at 10:19:13 UTC, matheus wrote:Yeah, but the ecosystem doesn't swallow anything, that is the problem.[...]I think the point is despite the example is very simple, it's required to have very detailed knowledge about the Rust compiler and its lifetime system in order to understand this problem. Sure you rewrite in some undefined "idiomatic Rust" but is it good language design when such detailed knowledge and order of statements is required? D is in the other end of this spectrum, it swallows almost anything.
Oct 21 2022
On Friday, 21 October 2022 at 10:42:52 UTC, Paulo Pinto wrote:Yeah, but the ecosystem doesn't swallow anything, that is the problem.Please stop saying it is an ecosystem issue. That is not they key thing that prevents adoption. This is just a sleeping pill that makes people go for apathy believing that they cannot change the trajectory. Which is wrong. The main issue with D is not lacking an ecosystem, D has an ecosystem that can grow and that allows you to be productive in system level programming. System level programming does not require a gigantic eco system. But D is adding new stuff to a code base that is difficult to evolve rather than focusing on design issues people complain about. The core difference is that C++ and Rust are clearly showing in their releases that they are working on compensating for design flaws that people care about. The main issue for D is a lack of strategy that involves architecting a modern D compiler, that people want to work on, and an objective strategy for selecting design issues that needs to be addressed. Without a solid strategy you can neither get rid of design issues or grow in a predictable manner. For an outsider D as a project looks more like a one-man-person-with-entourage than a cooperative effort. This does not grow confidence in the project. Rust and C++ are much less about any singular entity, but more of a collaborative effort. That is good for confidence and for long term viability and evolution. It is great for D that there is a foundation now, but has it really changed the structure of the project, and how strategies are formed, to any significant degree?
Oct 21 2022
On Friday, 21 October 2022 at 11:51:46 UTC, Ola Fosheim Grøstad wrote:The main issue for D is a lack of strategy that involves architecting a modern D compiler, that people want to work on, and an objective strategy for selecting design issues that needs to be addressed. Without a solid strategy you can neither get rid of design issues or grow in a predictable manner. For an outsider D as a project looks more like a one-man-person-with-entourage than a cooperative effort. This does not grow confidence in the project.Yes, that's my take on it too. The only way out of this is that D is forked. Problem with this is that language designers and people with good understanding in compiler technology are not the average programmer and are rare. If you are one of those and want to continue evolving D, then fork it rather than trying to fight this project.
Oct 21 2022
On Friday, 21 October 2022 at 13:14:41 UTC, IGotD- wrote:The only way out of this is that D is forked.I don't think forking D is a going to work. I think the future of D depends on how the foundation is structured and how it operates. D needs a _strong_ and _inclusive_ organizer/leader to head the foundation. Without such a person it will be difficult to switch to a new gear. Finding such a leader would probably be the single-most important thing that could happen. (Right now I have some hope for Carbon as a C++ alternative, but it is impossible to tell what Carbon will look like at this point. Not even when it comes to basic things like integer math. Carbon might be great, or it might not be great, or it might not happen at all. We'll see in 5-10 years…)
Oct 21 2022
On 10/21/2022 6:14 AM, IGotD- wrote:Yes, that's my take on it too. The only way out of this is that D is forked.We welcome DIP proposals from anyone, and once approved, anyone can implement them.
Oct 22 2022
On Friday, 21 October 2022 at 13:14:41 UTC, IGotD- wrote:On Friday, 21 October 2022 at 11:51:46 UTC, Ola Fosheim Grøstad wrote:... For those with time and a fork-it bent I'd suggest contributing to SDC as an alternative, or prelude, to a complete fork.The main issue for D is a lack of strategy that involves architecting a modern D compiler, that people want to work on, and an objective strategy for selecting design issues that needs to be addressed. ...Yes, that's my take on it too. The only way out of this is that D is forked.
Oct 22 2022
On 10/21/2022 3:19 AM, matheus wrote:For example, I wrote this a while ago: "The problem that took him 5 years to fix in C++, I solved in a minute with D". https://forum.dlang.org/thread/oyfejgtjsupbdgckfdjz forum.dlang.orgI repeat my request to make it a HackerNews or Reddit article!
Oct 21 2022
On Friday, 21 October 2022 at 07:37:41 UTC, Stefan Hertenberger wrote:On Thursday, 20 October 2022 at 22:41:34 UTC, rassoc wrote:Which is contrary to the purpose of using closures -- to capture free variables in the lexical environment, rather than having to pass them as arguments. What you have done above could (and should) be re-written with ordinary functions.On 20/10/2022 15:37, Don Allen via Digitalmars-d wrote:You don't need to reorder, just use references ```rust fn main() { let mut foo = 5; let bar = |val: &mut i32| { *val = 17; }; let baz = |val: &mut i32| { *val = 42; }; bar(&mut foo); println!("{}", &mut foo); baz(&mut foo); println!("{}", &mut foo); } ```[...]To be honest, these kind of access patterns are smelly and there almost always exists a more elegant alternative. Regarding that example code above, the burrow checker will be happy if you reorder it slightly: ```rust fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; bar(); println!("{}", &mut foo); // just moved this down here let mut baz = || { foo = 42; }; baz(); println!("{}", &mut foo); } ```
Oct 21 2022
On Friday, 21 October 2022 at 13:44:56 UTC, Don Allen wrote:Which is contrary to the purpose of using closures -- to capture free variables in the lexical environment, rather than having to pass them as arguments. What you have done above could (and should) be re-written with ordinary functions.You are right, not sure what i had in mind while writing this :(
Oct 21 2022
On 10/21/2022 6:44 AM, Don Allen wrote:Which is contrary to the purpose of using closures -- to capture free variables in the lexical environment, rather than having to pass them as arguments. What you have done above could (and should) be re-written with ordinary functions.The way dip1000 works with closures is to treat the uplevel variables as if they are passed by ref to the nested function. Which is of course how they are implemented.
Oct 21 2022
On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:```` fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; let mut baz = || { foo = 42; }; bar(); println!("{}", &mut foo); baz(); println!("{}", &mut foo); } ````I think the way it would be advised to write it in Rust would be something like this instead of using RefCell: ``` fn main() { struct State { foo: i32 } impl State { fn bar(&mut self) { self.foo = 17; } fn baz(&mut self) { self.foo = 42; } } let mut state = State { foo: 0 }; state.bar(); println!("{}", state.foo); state.baz(); println!("{}", state.foo); } ``` The problem is that both closures have a mutable reference to the same value and this is not allowed in Rust, you could solve this making the functions get a mutable reference to the variable but using a struct in this case is better IMO.
Oct 21 2022
On Saturday, 22 October 2022 at 05:35:22 UTC, victoroak wrote:On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:I think it's clear that my Scheme-ish attempt to use Rust closures was not a good idea. The fundamental problem with using Rust closures in this way is that the borrow-checker thinks any mutable borrows that occur in the closure happen at the time the closure is defined, not when it is called. This is one of those situations where trying to insure safety at compile time can be too conservative, which the Rust folks concede. Interior mutability and reference counting are both run-time ways to get around the compiler when it prevents you from doing things that are actually safe but can't be proven safe at compile time. I never actually fixed the code from which my example is drawn, which I wrote quite awhile ago, because at that point I'd reached my personal Rust-pain threshold and moved on to D, returning my blood pressure to normal. But if I were going to fix it, I agree with you that your (very nice) solution is preferable. Avoiding closures and instead using functions/methods results in the mutable borrows occurring at call time, which solves the problem, since my call pattern doesn't violate the "one mutable borrow at a time" rule. I'm sure Refcell would also work, as it did with my little example, but it's messier and introduces a bit of runtime overhead (which I doubt would matter in the application in question running on 4 GHz hardware, so I think the readability issue is primary). I'd also add that in effect, what you are doing is manually creating closures by using a struct and struct methods (behind the scenes, Rust closures are built by the compiler with structs in much the same way). But by doing it manually, you get finer grained control over how and when the mutable borrows occur, so they happen in a smarter way than what the compiler is doing.```` fn main() { let mut foo = 5; let mut bar = || { foo = 17; }; let mut baz = || { foo = 42; }; bar(); println!("{}", &mut foo); baz(); println!("{}", &mut foo); } ````I think the way it would be advised to write it in Rust would be something like this instead of using RefCell: ``` fn main() { struct State { foo: i32 } impl State { fn bar(&mut self) { self.foo = 17; } fn baz(&mut self) { self.foo = 42; } } let mut state = State { foo: 0 }; state.bar(); println!("{}", state.foo); state.baz(); println!("{}", state.foo); } ``` The problem is that both closures have a mutable reference to the same value and this is not allowed in Rust, you could solve this making the functions get a mutable reference to the variable but using a struct in this case is better IMO.
Oct 22 2022
I guess, it really depends on what happens in bar and baz but my solution would be something like this. ```rust fn main() { let mut foo = 5; let bar = || -> i32 { // do something here 17 }; let baz = || -> i32 { // do something here 42 }; foo = bar(); println!("{}", foo); foo = baz(); println!("{}", foo); } ``` As always one uses the best fitting tool to solve the problem and in your case it was D ?!
Oct 23 2022
On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:```` use std::cell::RefCell; fn main() { let foo = RefCell::new(5); let bar = || { *foo.borrow_mut() = 17; }; let baz = || { *foo.borrow_mut() = 42; }; bar(); println!("{}", foo.borrow()); baz(); println!("{}", foo.borrow()); } ````Yes, I believe this shows maybe the biggest weakaness of Rust. I could live with a language having a syntax like that (still better than C++, at least the old standards), but it does slows down working compared to most other new-generation languages. Too bad. Rust's error handling seems so advanced. I'm not talking only about the ability to be safe without a stop-the-world GC, but about it's ability to detect other errors too. A good example is it's UTF-8 string type. Not only it is guaranteed to point to valid memory, it is statically guaranteed to point to valid UTF-8! A D programmer needs to rely on contract programming instead. Although I think that placing a few asserts is still be a good idea even in Rust. Disclaimer: the above is likely to be humbug because I have no usage experience of Rust, only studied it's docs.
Oct 24 2022
On Monday, 24 October 2022 at 20:04:00 UTC, Dukc wrote:On Thursday, 20 October 2022 at 13:37:07 UTC, Don Allen wrote:I'd disagree about "biggest". My use of closures would get me a summons from the Rust Unidiomatic Police. In other words, my guess is that not many run across the problem I did. A more serious weakness, in my opinion, is the difficulty of dealing with global state. Statics must be initialized, but the initializer must be known at compile-time. So if you want to define a global that you need to initialize with a value only known at run-time and will never change again, you must define it as mutable, with all the issues that raises. And its type will need to be Option<the type you really want> and the compile-time-known initializer will have to be None. You then mutate it to be Some(what-you-want) at run-time. References to this will have to be in an "unsafe" block, even though the situation would be perfectly safe if immutable statics could be initialized at runtime (I think they may be trying to fix this with something available only in the nightly version, but I am not positive). Then there's the problem I've mentioned earlier -- Rust considers everything to be multi-threaded, even if it isn't. And it imposes restrictions on the programmer that are only needed in multi-threaded situations, such as considering mutable statics to be unsafe. Even if the mutable static is wrapped in a mutex, you still need to use unsafe blocks to refer to it.```` use std::cell::RefCell; fn main() { let foo = RefCell::new(5); let bar = || { *foo.borrow_mut() = 17; }; let baz = || { *foo.borrow_mut() = 42; }; bar(); println!("{}", foo.borrow()); baz(); println!("{}", foo.borrow()); } ````Yes, I believe this shows maybe the biggest weakness of Rust.I could live with a language having a syntax like that (still better than C++, at least the old standards), but it does slows down working compared to most other new-generation languages. Too bad. Rust's error handling seems so advanced. I'm not talking only about the ability to be safe without a stop-the-world GC,Not all GCs are stop-the-world. And, in my opinion, the negativity about garbage collectors is exaggerated. There's an awful lot of software out there written in gc-ed languages, e.g., Python, Go, Javascript, that we all use every day, even on our phones, and that performs adequately or more than adequately.but about it's ability to detect other errors too. A good example is it's UTF-8 string type. Not only it is guaranteed to point to valid memory, it is statically guaranteed to point to valid UTF-8! A D programmer needs to rely on contract programming instead. Although I think that placing a few asserts is still be a good idea even in Rust.Yes, there are a lot of positive things to say about Rust. But for me, the insistence on no GC disqualifies it from use in situations where a GC-ed language would do the job, because of the cost in programming difficulty that that insistence imposes, e.g., lifetime hell and frustrating battles with the borrow-checker. And that difficulty is compounded by the multi-threaded assumption and the handling of statics.Disclaimer: the above is likely to be humbug because I have no usage experience of Rust, only studied it's docs.
Oct 25 2022
On Tuesday, 25 October 2022 at 17:16:58 UTC, Don Allen wrote:There's an awful lot of software out there written in gc-ed languages, e.g., Python, Go, Javascript, that we all use every day, even on our phones, and that performs adequately or more than adequatelyBut Rust is a system level programming language, it was designed for writing device drivers, filesystems, and other resource constrained and latency critical software, where languages with runtime environments can't be used, even if you're okay with them Even the actual software libraries used by higher level languages in mobile applications are wrappers over the extremely power/compute efficient C/C++ libraries that were written with misery and paranoia, it's not as if a higher level languages' tech stack doesn't involve lower level language, but the opposite is true Thus, Rust always assumes the worst case scenarios and makes the programmer distort their code to make it compile, and, unless you use lots of unsafe, the code really belongs to "if it compiles, it doesn't have memory bugs" camp of software
Oct 25 2022
On Tuesday, 25 October 2022 at 17:37:22 UTC, Tejas wrote:On Tuesday, 25 October 2022 at 17:16:58 UTC, Don Allen wrote:That's true and is essentially what I'm saying -- Rust is fine for what it was designed for, but it is not suitable for ordinary application development. But this is ignored by many in the Rust community and even by Mozilla, which, for example, is using Rust in Firefox.There's an awful lot of software out there written in gc-ed languages, e.g., Python, Go, Javascript, that we all use every day, even on our phones, and that performs adequately or more than adequatelyBut Rust is a system level programming language, it was designed for writing device drivers, filesystems, and other resource constrained and latency critical software, where languages with runtime environments can't be used, even if you're okay with themEven the actual software libraries used by higher level languages in mobile applications are wrappers over the extremely power/compute efficient C/C++ libraries that were written with misery and paranoia, it's not as if a higher level languages' tech stack doesn't involve lower level language, but the opposite is trueExcept I'm talking about the pain inflicted on the *user* of the language, not the pain it took to create the language and its supporting libraries.Thus, Rust always assumes the worst case scenarios and makes the programmer distort their code to make it compile, and, unless you use lots of unsafe, the code really belongs to "if it compiles, it doesn't have memory bugs" camp of softwareThere are plenty of examples of gc-ed languages that do the same without Rust's difficulty.
Oct 25 2022
On Tuesday, 25 October 2022 at 18:11:28 UTC, Don Allen wrote:On Tuesday, 25 October 2022 at 17:37:22 UTC, Tejas wrote: That's true and is essentially what I'm saying -- Rust is fine for what it was >designed for, but it is not suitable for ordinary application development. But this >is ignored by many in the Rust community and even by Mozilla, which, for example,But the browser not really "ordinary" application. And all users will be happy if it will be as fast as possible and consume not too much memory. Actually users will be happy if every app will have those parameters. Instead of that we have Intellij IDEA and Electron apps which are very far from being *blazingly fast*.is using Rust in Firefox
Oct 25 2022
On Tuesday, 25 October 2022 at 21:38:44 UTC, Sergey wrote:On Tuesday, 25 October 2022 at 18:11:28 UTC, Don Allen wrote:If you think that the user experience would be any different if Mozilla used Go or D for the work they are doing with Firefox, then you and I just need to agree to disagree. I can re-cite my own recent experience, stated here more than once: I wrote a suite of personal financial management applications in C 10 years ago. It got ugly and hard to maintain, so I re-wrote much of it in Rust. When I tired of dealing with Rust's challenges, I turned to D. The performance of the C, Rust and D versions of the most processor-intensive application are within a few percent of each other, indistinguishable in actual use.On Tuesday, 25 October 2022 at 17:37:22 UTC, Tejas wrote: That's true and is essentially what I'm saying -- Rust is fine for what it was >designed for, but it is not suitable for ordinary application development. But this >is ignored by many in the Rust community and even by Mozilla, which, for example,But the browser not really "ordinary" application. And all users will be happy if it will be as fast as possible and consume not too much memory.is using Rust in FirefoxActually users will be happy if every app will have those parameters. Instead of that we have Intellij IDEA and Electron apps which are very far from being *blazingly fast*.Electron is at least partly implemented in C++. I've tried the Atom editor, which is based on Electron, and it *is* annoyingly slow. Do you think not using Rust is their problem? Or maybe they got some algorithms wrong, or used badly implemented bloatware, or .... (a long list of how applications can be made to perform badly regardless of programming language).
Oct 26 2022
On Wednesday, 26 October 2022 at 14:59:02 UTC, Don Allen wrote:If you think that the user experience would be any different if Mozilla used Go or D for the work they are doing with Firefox, then you and I just need to agree to disagree.Browsers are generally written in C++? They use a dedicate GC for dealing with javascript objects. The renderer for Chrome called Skia is written in C++ and is gradually moving rendering to the graphics co-processor. You cannot easily do these things with a run-of-the-mill GC as in Go, and not at all with a freeze-the-world GC. Browsers do a lot of work in the background. A browser is basically one gigantic runtime for javascript. You don't want to deal with another heavy runtime at the same time. That would make performance tuning very difficult. That said, I don't know how much Firefox relies on Rust. Wikipedia says that Mozilla dropped Servo (the engine that was being implemented in Rust).dealing with Rust's challenges, I turned to D. The performance of the C, Rust and D versions of the most processor-intensive application are within a few percent of each other, indistinguishable in actual use.You probably didn't generate much garbage. And frankly, you can easily write a well-performing basic financial application in Python without paying any attention to algorithms or memory. So I don't think this is a good use case for comparison.Electron is at least partly implemented in C++. I've tried the Atom editor, which is based on Electron, and it *is* annoyingly slow.Electron is just a stripped down browser with some additonal APIs. Electron applications are written in Javascript. It is possible to make javascript applications perform well, but you need to design the software carefully and do some performance tuning.
Oct 26 2022
On Wednesday, 26 October 2022 at 15:48:02 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 26 October 2022 at 14:59:02 UTC, Don Allen wrote:Opinion stated as fact. And how do you know that a freeze-the-world GC, if that were used, would be a browser's performance bottleneck, with all the network-imposed delays users experience when browsing? I speak from decades of performance-analysis experience where I found that programmers are horrible at guessing why their programs perform as they do. Which leads to the rule "Do the measurements, then we'll talk". And how, pray tell, would the use of Go or D prevent "moving rendering to the graphics co-processor"? Which, of course, takes performance pressure off the code on running the main processor.If you think that the user experience would be any different if Mozilla used Go or D for the work they are doing with Firefox, then you and I just need to agree to disagree.Browsers are generally written in C++? They use a dedicate GC for dealing with javascript objects. The renderer for Chrome called Skia is written in C++ and is gradually moving rendering to the graphics co-processor. You cannot easily do these things with a run-of-the-mill GC as in Go, and not at all with a freeze-the-world GC.Browsers do a lot of work in the background. A browser is basically one gigantic runtime for javascript. You don't want to deal with another heavy runtime at the same time. That would make performance tuning very difficult. That said, I don't know how much Firefox relies on Rust. Wikipedia says that Mozilla dropped Servo (the engine that was being implemented in Rust).Interesting conclusion, based on zero knowledge of what my application does.dealing with Rust's challenges, I turned to D. The performance of the C, Rust and D versions of the most processor-intensive application are within a few percent of each other, indistinguishable in actual use.You probably didn't generate much garbage. And frankly, you can easily write a well-performing basic financial application in Python without paying any attention to algorithms or memory. So I don't think this is a good use case for comparison.
Oct 26 2022
On Wednesday, 26 October 2022 at 17:06:33 UTC, Don Allen wrote:And how do you know that a freeze-the-world GC, if that were used, would be a browser's performance bottleneck, with all the network-imposed delays users experience when browsing?This is a useless argument. Browsers support realtime applications.
Oct 26 2022
On Wednesday, 26 October 2022 at 17:48:19 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 26 October 2022 at 17:06:33 UTC, Don Allen wrote:There is nothing more real time that weapons targeting and guiding systems, where a couple of ms means the wrong guys die, what is a frame dropped in a browser compared with a big hole where it wasn't supposed to be one. US and France have several of those systems powered by bare metal Java with real time GC.And how do you know that a freeze-the-world GC, if that were used, would be a browser's performance bottleneck, with all the network-imposed delays users experience when browsing?This is a useless argument. Browsers support realtime applications.
Oct 26 2022
On Wednesday, 26 October 2022 at 18:33:24 UTC, Paulo Pinto wrote:There is nothing more real time that weapons targeting and guiding systems, where a couple of ms means the wrong guys die, what is a frame dropped in a browser compared with a big hole where it wasn't supposed to be one.Apples and oranges. Browser applications generate a lot of garbage, there are many things going on in the background as browsers are high level development environments. There is no way you can use a freeze-the-world GC as the primary collection mechanism and be competitive. And most likely not using Go's GC either. Not to mention that the memory consumption nearly doubles when you start to rely on the GC. If writing a heavy "realtime" runtime using a run-of-the-mill GC was competitive, then people would do it to save money.
Oct 26 2022
On Wednesday, 26 October 2022 at 17:48:19 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 26 October 2022 at 17:06:33 UTC, Don Allen wrote:And are you aware that when and if there is a real-time requirement, you can turn off the GC? And speaking of useless, I'm done discussing this with you.And how do you know that a freeze-the-world GC, if that were used, would be a browser's performance bottleneck, with all the network-imposed delays users experience when browsing?This is a useless argument. Browsers support realtime applications.
Oct 26 2022
On Wednesday, 26 October 2022 at 21:17:01 UTC, Don Allen wrote:And are you aware that when and if there is a real-time requirement, you can turn off the GC?Turning off the GC is not an option that will work out as there is no period of time that isn't "realtime", but you can keep GC managed objects on a separate thread. That approach only makes sense if you can separate out and shield significant work suitable for GC from the other work that has to be done. For the most part using owning pointers and arenas is a more flexible approach if you cannot use a generic GC for most of your program. Browsers do use a GC for resources that are "owned" by javascript, but the browser code then have full control over the collection strategy. That is not the case for a generic run-of-the- mill language solution. The moment you have to micromanage a large number of objects by pinning and unpinning them because they are leaving the GC context you might find that the benefits of using a managed solution is lost. So the overall complexity goes down with choosing something more homogeneous (like owning pointers).
Oct 26 2022
On Wednesday, 26 October 2022 at 22:09:46 UTC, Ola Fosheim Grøstad wrote:On Wednesday, 26 October 2022 at 21:17:01 UTC, Don Allen wrote:I don't understand your argument. Why wouldn't it be possible to make a browser with a GC? You mean there are no browsers made in SML, OCaml, Eiffel, D, Go,[...]Turning off the GC is not an option that will work out as there is no period of time that isn't "realtime", but you can keep GC managed objects on a separate thread. That approach only makes sense if you can separate out and shield significant work suitable for GC from the other work that has to be done. [...]
Oct 27 2022
On Thursday, 27 October 2022 at 18:32:15 UTC, Imperatorn wrote:I don't understand your argument. Why wouldn't it be possible to make a browser with a GC?Modern browsers such as Firefox and Chrome are nothing like NSCA Mosaic or gopher. They are runtimes for application development/games. You cannot make a competitive runtime if your foundation is a source for non-deterministic effects and unnecessary resource consumption. It is possible, but not workable.
Oct 27 2022
On 10/27/22 11:50, Ola Fosheim Grøstad wrote:Modern browsers such as Firefox and Chrome are nothing like NSCA Mosaic or gopher.Ok.They are runtimes for application development/games.Ok.You cannot make a competitive runtime if your foundation is a source for non-deterministic effects and unnecessary resource consumption.Your argument seems to be based on finding a narrow case where your point is true and then concluding that some other related thing is false. Here, just because we can imagine a case where "non-deterministic effects and unnecessary resource consumption" can be harmful, D is not usable. That kind of argumentation was used before: - "There are corner cases where ranges are inferior to iterators, so ranges must be bad." This logic is proven to be wrong because we know from experience that ranges are very useful. - "There are corner cases where 'static if' does not make sense, so 'static if' is bad." This conclusion is proven to be wrong because we have tons of experience that 'static if' is very useful. (Some "considerate" C++ "experts" failed on this one.) Now, to break your logic, I present Weka.IO, world's fastest file system, written in D. Period. Having that example in front of me, I bet even I can write a browser that would be considered "modern".It is possible, but not workable.As I've shown above, it is possible and workable. Ali
Oct 27 2022
On Thursday, 27 October 2022 at 20:54:32 UTC, Ali Çehreli wrote:Your argument seems to be based on finding a narrow case where your point is true and then concluding that some other related thing is false. Here, just because we can imagine a case where "non-deterministic effects and unnecessary resource consumption" can be harmful, D is not usable.No. The argument was whether it makes sense to use Rust for building the core engine of Firefox or not. The position I argued against was that you could just as well do it with a standard freeze-the-world GC or Go with full GC. The argument isn't strictly related to D, that is something you brought to the table. 99% of all languages use some kind of GC, most of the programs written are done using some kind of GC. Having automatic memory management is the norm, not the outlier. That does not mean that non-GC applications can be replaced with a run-of-the-mill GC solution and be competitive. It makes sense to use languages like Rust for even mundane things like cloud web services where you want to conserve memory. I am not a Rust user at this point, but I also don't assume that people who use it don't understand the tradeoffs.Now, to break your logic, I present Weka.IO, world's fastest file system, written in D. Period.Do they use the regular D GC all the way?As I've shown above, it is possible and workable.I have absolutely no idea what you are referring to here.
Oct 27 2022
On 10/27/22 15:11, Ola Fosheim Grøstad wrote:No. The argument was whether it makes sense to use Rust for building the core engine of Firefox or not.No. Your argument was about GC not being usable for such applications.The position I argued against was that you could just as well do it with a standard freeze-the-world GC or Go with full GC. The argument isn't strictly related to D, that is something you brought to the table.I did not bring D to the table. This thread is titled "A D vs. Rust example" where people are trying to convince the OP that their real-world experience is false because browsers support realtime applications as well.99% of all languages use some kind of GC, most of the programs written are done using some kind of GC. Having automatic memory management is the norm, not the outlier.Everybody knows that.That does not mean that non-GC applications can be replaced with a run-of-the-mill GC solution and be competitive.Everybody would agree with that. How does that point make any sense in this discussion though? Who was arguing doing any of that? If you are referring to the claim that some percentage of languages (including D) cannot be used to write a browser, that is simply false. Because my claim is different: Many programming languages (including D) can be written to write a browser. There...It makes sense to use languages like Rust for even mundane things like cloud web services where you want to conserve memory.What are you saying? Who would ever not want to conserve memory?I am not a Rust user at this point, but I also don't assume that people who use it don't understand the tradeoffs.Some people do understand the tradeoffs but many others just follow the tide.None whatsoever.Now, to break your logic, I present Weka.IO, world's fastest file system, written in D. Period.Do they use the regular D GC all the way?I was quoting you. You said "It is possible, but not workable." But now I see: You were using the niche application of "realtime applications in the browser" to prove that a run-of-the-mill GC cannot be used for it. Fine with me as long as you don't argue that a run-of-the-mill GC (e.g. the one in D) cannot be used to write a browser. AliAs I've shown above, it is possible and workable.I have absolutely no idea what you are referring to here.
Oct 28 2022
On Friday, 28 October 2022 at 16:03:07 UTC, Ali Çehreli wrote:On 10/27/22 15:11, Ola Fosheim Grøstad wrote:Which is the same thing. This was the context, Don implied that Mozilla could have used the builtin GC: «If you think that the user experience would be any different if Mozilla used Go or D for the work they are doing with Firefox, then you and I just need to agree to disagree.» They can't without affecting performance and resource usage. It is not competitive. It is possible, but not workable.No. The argument was whether it makes sense to use Rust forbuilding thecore engine of Firefox or not.No. Your argument was about GC not being usable for such applications.Hence the file system example had nothing to do with argument about using the standard GC. Everybody here knows that you can use D as a C/C++ replacement with no GC. But if you remove the GC then there is no point to the argument as then you don't have a significantly lower cost than you get by using Rust.Do they use the regular D GC all the way?None whatsoever.It is possible with the GC, but not workable, i.e. Firefox would not be competitive against Chrome.I was quoting you. You said "It is possible, but not workable."As I've shown above, it is possible and workable.I have absolutely no idea what you are referring to here.Fine with me as long as you don't argue that a run-of-the-mill GC (e.g. the one in D) cannot be used to write a browser.It is possible, but not workable… That's just reality. You have to do better than the most used browser for there to be any point to even start on such a venture.
Oct 28 2022
On Wed, Oct 26, 2022 at 05:06:33PM +0000, Don Allen via Digitalmars-d wrote: [...]I speak from decades of performance-analysis experience where I found that programmers are horrible at guessing why their programs perform as they do. Which leads to the rule "Do the measurements, then we'll talk".[...] +1, speaking as one who writes C every day and who used to write a ton of C++, I can say that most C/C++ programmers are lousy at guessing where the performance bottlenecks actually are. Most of them (including myself) get it wrong 99% of the time, and are liable to optimize prematurely in places that are nowhere near the real bottleneck. These days, whenever people try to tell me X or Y is "inefficient", I just ignore them until they can show me actual measurements. Preferably profiler output that pinpoints where exactly in the code the program is spending most of its time in. T -- People tell me I'm stubborn, but I refuse to accept it!
Oct 26 2022
On Tuesday, 25 October 2022 at 17:16:58 UTC, Don Allen wrote:Yes, there are a lot of positive things to say about Rust. But for me, the insistence on no GC disqualifies it from use in situations where a GC-ed language would do the job, because of the cost in programming difficulty that that insistence imposes, e.g., lifetime hell and frustrating battles with the borrow-checker. And that difficulty is compounded by the multi-threaded assumption and the handling of statics.When developing C++ code, I was solving this problem by just embedding a Lua interpreter (and also a much less known http://squirrel-lang.org/ because its syntax resembles C). This approach provides GC and easy programming for the parts of a program, which are not performance critical. Seems like Rust also can do this just fine: https://docs.rs/rlua/latest/rlua/
Oct 25 2022
On Tuesday, 25 October 2022 at 17:42:42 UTC, Siarhei Siamashka wrote:On Tuesday, 25 October 2022 at 17:16:58 UTC, Don Allen wrote:Hey buddy, someone else on the internet that has used Squirrel. I thought I was alone :D I wish I could have used D instead tho[...]When developing C++ code, I was solving this problem by just embedding a Lua interpreter (and also a much less known http://squirrel-lang.org/ because its syntax resembles C). This approach provides GC and easy programming for the parts of a program, which are not performance critical. Seems like Rust also can do this just fine: https://docs.rs/rlua/latest/rlua/
Oct 25 2022
On Tuesday, 25 October 2022 at 17:47:00 UTC, Imperatorn wrote:On Tuesday, 25 October 2022 at 17:42:42 UTC, Siarhei Siamashka wrote:Well, it was not too hard to find Squirrel once you decide that you want "something like Lua, but with C syntax" and go to the google search with this request :-) Lua is great, but I wasn't completely happy about 1-based indexing and wanted to try something new. And nowadays I see that there's also mruby competing in the same niche, so there's no shortage of available solutions.On Tuesday, 25 October 2022 at 17:16:58 UTC, Don Allen wrote:Hey buddy, someone else on the internet that has used Squirrel. I thought I was alone :D[...]When developing C++ code, I was solving this problem by just embedding a Lua interpreter (and also a much less known http://squirrel-lang.org/ because its syntax resembles C). This approach provides GC and easy programming for the parts of a program, which are not performance critical. Seems like Rust also can do this just fine: https://docs.rs/rlua/latest/rlua/I wish I could have used D instead thoIronically, D was also considered for this particular project, but got rejected because it was seen as a long term maintenance hazard. Thankfully my more experienced colleagues explained me what's wrong with D language and many years later I see that they were absolutely right on every account. Lua or Squirrel interpreter is small and simple enough and can be just included as a part of the C++ project source tree. Even if the upstream developers release new incompatible versions in the future, nobody can force us to upgrade. Being small and simple, the interpreter code is also perfectly maintainable and customizable without depending on any third party. You know that you are in full control and this feels great.
Oct 29 2022
On 10/25/2022 10:16 AM, Don Allen wrote:Not all GCs are stop-the-world. And, in my opinion, the negativity about garbage collectors is exaggerated. There's an awful lot of software out there written in gc-ed languages, e.g., Python, Go, Javascript, that we all use every day, even on our phones, and that performs adequately or more than adequately.The fact that D's GC is what enables advanced CTFE programming is often overlooked. It's a killer feature enabling a killer feature. After all, whatcha gonna do with malloc/free in CTFE?
Oct 27 2022
On 28/10/2022 12:40 PM, Walter Bright wrote:After all, whatcha gonna do with malloc/free in CTFE?Allocate and free memory? CTFE is just an application VM, even if we have limitations, they are not inherent to the theory ;)
Oct 27 2022
On 10/27/2022 4:51 PM, rikki cattermole wrote:On 28/10/2022 12:40 PM, Walter Bright wrote:I meant this at a more meta level - people write their own allocators a lot.After all, whatcha gonna do with malloc/free in CTFE?Allocate and free memory?CTFE is just an application VM, even if we have limitations, they are not inherent to the theory ;)Yes, it is technically possible. But there's no actual purpose to malloc/free in CTFE. The GC works just fine, and it's memory safe, and it's much more convenient.
Oct 27 2022
On Thursday, 27 October 2022 at 23:40:11 UTC, Walter Bright wrote:The fact that D's GC is what enables advanced CTFE programming is often overlooked. It's a killer feature enabling a killer feature.It is clearly better to use high level code in CTFE than system-like code. Maybe you could consider adding more high level features such a comprehensions and generators for the purpose of improved CTFE?
Oct 28 2022
On 10/28/22 00:25, Ola Fosheim Grøstad wrote:On Thursday, 27 October 2022 at 23:40:11 UTC, Walter Bright wrote:Yes, high level code is always better.The fact that D's GC is what enables advanced CTFE programming is often overlooked. It's a killer feature enabling a killer feature.It is clearly better to use high level code in CTFE than system-like code.Maybe you could consider adding more high level features such a comprehensions and generators for the purpose of improved CTFE?I want to ask comprehensions and generators as seen in the context of Python but you could not have meant it because Python does not have CTFE. D uses range algorithms for comprehensions and generators. For example, the following program instantiates a struct template with a value computed from a generator: struct S(size_t N) { float[N] arr; } void main() { import std.algorithm : map, sum; import std.range : iota; auto s = S!(iota(10).sum)(); // <-- Generator used in CTFE pragma(msg, s.arr.length); } Ali
Oct 28 2022
On 10/24/2022 1:04 PM, Dukc wrote:it's UTF-8 string type. Not only it is guaranteed to point to valid memory, it is statically guaranteed to point to valid UTF-8!The trouble with that is much of the UTF-8 out there is not valid. You don't want, for example, your html page to refuse to display at all because there's a couple invalid UTF-8 sequences in it. You don't want your text editor to refuse to load a file with invalid UTF-8 in it, either. You don't want your forms processor to summarily reject anything with invalid UTF-8 in it. A better approach is to have the string processing be tolerant of invalid UTF-8.
Oct 27 2022
On Thu, Oct 27, 2022 at 04:37:12PM -0700, Walter Bright via Digitalmars-d wrote:On 10/24/2022 1:04 PM, Dukc wrote:You don't have to refuse anything. Just substitute it with the Unicode replacement character in your standard library, and no downstream code will need to worry about it anymore. And should you ever need to process invalid sequences (e.g., in a utility to repair broken encodings), just read it as binary and process it that way.it's UTF-8 string type. Not only it is guaranteed to point to valid memory, it is statically guaranteed to point to valid UTF-8!The trouble with that is much of the UTF-8 out there is not valid. You don't want, for example, your html page to refuse to display at all because there's a couple invalid UTF-8 sequences in it. You don't want your text editor to refuse to load a file with invalid UTF-8 in it, either. You don't want your forms processor to summarily reject anything with invalid UTF-8 in it.A better approach is to have the string processing be tolerant of invalid UTF-8.Which makes string-processing code more fragile and possibly more complex. Better to let the standard library replace all invalid sequences with the replacement character so that downstream code doesn't have to worry about it anymore. T -- Doubtless it is a good thing to have an open mind, but a truly open mind should be open at both ends, like the food-pipe, with the capacity for excretion as well as absorption. -- Northrop Frye
Oct 27 2022
On 28/10/2022 12:55 PM, H. S. Teoh wrote:Officially you are meant to support only well formed UTF and anything else you are expected to reject. In practice yes, replacement character can be what you decode (which is what I do).A better approach is to have the string processing be tolerant of invalid UTF-8.Which makes string-processing code more fragile and possibly more complex. Better to let the standard library replace all invalid sequences with the replacement character so that downstream code doesn't have to worry about it anymore.
Oct 27 2022
On 10/27/2022 4:55 PM, H. S. Teoh wrote:You don't have to refuse anything. Just substitute it with the Unicode replacement character in your standard library, and no downstream code will need to worry about it anymore.That's one way to deal with it. But until it is so processed, it isn't a string if the string requires strict UTF-8.And should you ever need to process invalid sequences (e.g., in a utility to repair broken encodings), just read it as binary and process it that way.Yes, but you can't do it with strings, if strings don't allow invalid sequences.I've coded a lot of Phobos to be tolerant of invalid UTF-8. It turns out that it's *unusual* to need to decode UTF-8 at all. It's robust, not fragile.A better approach is to have the string processing be tolerant of invalid UTF-8.Which makes string-processing code more fragile and possibly more complex.Better to let the standard library replace all invalid sequences with the replacement character so that downstream code doesn't have to worry about it anymore.Then you have another processing step, and have to make a copy of the string. As I wrote, I have some experience with this. Being tolerant of invalid UTF-8 is a winning strategy.
Oct 27 2022
On Friday, 28 October 2022 at 04:27:25 UTC, Walter Bright wrote:Good point. But it could be easily solved by making the naturally tolerant functions to accept `ubyte`s.I've coded a lot of Phobos to be tolerant of invalid UTF-8. It turns out that it's *unusual* to need to decode UTF-8 at all. It's robust, not fragile.A better approach is to have the string processing be tolerant of invalid UTF-8.Which makes string-processing code more fragile and possibly more complex.Don't you remember? Ranges are lazy. No copy needed. And IIRC Rust also has a lazy iterator over an unvalidated binary blob to accomplish the same. And it's not an extra step. If you don't validate a string, then the string processing functions (that need to decode) have to do that anyway. The Rust way has the advantages that: - No string handling function needs to throw anything. The could all be `nothrow`. - If two string handling functions that need to decode are chained to each other, they don't need to both reduntantly check for invalid UTF-8. - You don't accidently forget to check for invalid UTF-8, or recheck an already checked string. The first two could also be accomplished by asserting on invalid UTF-8 instead of throwing an exception, but only static guarantees give the third advantage.Better to let the standard library replace all invalid sequences with the replacement character so that downstream code doesn't have to worry about it anymore.Then you have another processing step, and have to make a copy of the string. As I wrote, I have some experience with this. Being tolerant of invalid UTF-8 is a winning strategy.
Oct 28 2022
On 10/28/2022 2:07 AM, Dukc wrote:- No string handling function needs to throw anything. The could all be `nothrow`. - If two string handling functions that need to decode are chained to each other, they don't need to both reduntantly check for invalid UTF-8. - You don't accidently forget to check for invalid UTF-8, or recheck an already checked string.I've discovered that: 1. throwing on invalid UTF-8 is the wrong solution. Phobos' autodecode does that. It was a huge mistake, but is a problem with Phobos, not D itself. 2. very, very few string algorithms have any need to decode the UTF-8. String copying, searching, hashing, etc., all have no need to decode. I've fixed a lot of the algorithms in Phobos to not decode. 3. detecting bad UTF-8 encodings only happens when decoding is needed. It costs nothing extra, as it falls out of the decoding logic. Then, one can decide to safely ignore it, or use the Replacement Char. It works fine. There just is no need to purify the strings.
Oct 29 2022
On Sunday, 30 October 2022 at 02:29:36 UTC, Walter Bright wrote:3. detecting bad UTF-8 encodings only happens when decoding is needed. It costs nothing extra, as it falls out of the decoding logic. Then, one can decide to safely ignore it, or use the Replacement Char.If the algorithm does not throw on invalid UTF, I guess so.It works fine. There just is no need to purify the strings.No need, but a bit of benefit since some bugs could be catched at compile time. Then again, it'd be catching only one class of errors of the countess one that are possible. Rust's solution would still be of no help if we're excepting letters but receive numbers instead and forget to check. So maybe complexity-to-benefit ratio of it is still unfavourable. Someone with experience with Rust string handling could maybe judge it.
Oct 31 2022