www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Comparing Rust and D As Better C

reply Dibyendu Majumdar <mobile majumdar.org.uk> writes:
I am working on porting a C project to Rust and Better C in order 
to get a real world idea of what the differences are.

First impressions of Rust vs D As Better C:

Rust has traits - nothing equivalent in the D As Better C subset.
Another difference is Rust has enumerated types - with D a 
library solution is possible.
Rust appears to have a good tooling in VS Code with pretty good 
IDE that gives you hints, flags errors as you type code, and 
allows you to lookup docs.

I suspect porting the code to D subset will be trivial. Porting 
to Rust is at the moment a challenging task (I am trying to 
replicate the C code as much as possible, including writing 
allocators etc.)

I suspect this project will take some time to complete, but I 
hope to share more comparisons of code etc.
Dec 15 2020
next sibling parent reply Dennis <dkorpel gmail.com> writes:
On Tuesday, 15 December 2020 at 23:25:02 UTC, Dibyendu Majumdar 
wrote:
 I am working on porting a C project to Rust and Better C in 
 order to get a real world idea of what the differences are.
Is it a public C project?
 First impressions of Rust vs D As Better C:

 Rust has traits - nothing equivalent in the D As Better C 
 subset.
 Another difference is Rust has enumerated types - with D a 
 library solution is possible.
 Rust appears to have a good tooling in VS Code with pretty good 
 IDE that gives you hints, flags errors as you type code, and 
 allows you to lookup docs.
Fair points, but I don't see the link to porting C code. C has no traits, C has no enumerated types, and IDE features are not needed when doing a simple translation. At least my C to D translation work has been very straightforward so far, maybe Rust requires more refactoring so then it's handy.
 I suspect porting the code to D subset will be trivial.
There are syntax changes and some stricter rules with implicit pointer conversions, integer truncation, and switch case fallthrough etc, but there is mostly a 1 to 1 map from C constructs to D (betterC) constructs. The most challenging part is non-trivial uses of the C preprocessor. Often there is an easy solution where you can get the same behavior with D features (`import` `version()`, `static if ()`, `enum`, `mixin template`), but crazy things are possible with text macros and you hope to not encounter them. Also it can be annoying when system headers are used that are not in druntime (e.g. regex.h, stdatomic.h), that means you need to make them yourself, find an existing binding, or find a replacement for their use. My experience is mostly based on my translations of certain single-header C libraries, glfw and libsoundio. I've written some notes about the translation of those last two which might interest you: https://github.com/dkorpel/libsoundio-d#translation-events https://github.com/dkorpel/glfw-d/wiki/Notes-on-the-translation-process
 Porting to Rust is at the moment a challenging task (I am 
 trying to replicate the C code as much as possible, including 
 writing allocators etc.)
I have no experience with writing Rust. I do know there is a migration tool for it though: https://github.com/immunant/c2rust
Dec 15 2020
parent reply Dibyendu Majumdar <mobile majumdar.org.uk> writes:
On Wednesday, 16 December 2020 at 00:36:03 UTC, Dennis wrote:
 On Tuesday, 15 December 2020 at 23:25:02 UTC, Dibyendu Majumdar 
 wrote:
 I am working on porting a C project to Rust and Better C in 
 order to get a real world idea of what the differences are.
Is it a public C project?
Yes.
 First impressions of Rust vs D As Better C:

 Rust has traits - nothing equivalent in the D As Better C 
 subset.
 Another difference is Rust has enumerated types - with D a 
 library solution is possible.
 Rust appears to have a good tooling in VS Code with pretty 
 good IDE that gives you hints, flags errors as you type code, 
 and allows you to lookup docs.
Fair points, but I don't see the link to porting C code. C has no traits, C has no enumerated types, and IDE features are not needed when doing a simple translation. At least my C to D translation work has been very straightforward so far, maybe Rust requires more refactoring so then it's handy.
The enumerated types are important feature for my project which currently uses unions. I may or may not use traits, I do not know yet. At the moment I am struggling to implement the memory allocator scheme in Rust. I may end up having to forgo this and just use standard Rust facilities for memory management. With D I don't think I will have any issues.
 I have no experience with writing Rust. I do know there is a 
 migration tool for it though:
 https://github.com/immunant/c2rust
It is kind of useless for my purposes.
Dec 23 2020
next sibling parent reply welkam <wwwelkam gmail.com> writes:
On Thursday, 24 December 2020 at 00:41:35 UTC, Dibyendu Majumdar 
wrote:
 At the moment I am struggling to implement the memory allocator 
 scheme in Rust
The easiest way to port C to Rust is trough D. D is so close to C that if you just copy pasted C code to D file it might just work without changes or very minimum changes. Furthermore D`s code plasticity together with language features allow to iteratively massage code base to more closely resemble Rust code making transition to Rust easier.
Dec 23 2020
parent Dibyendu Majumdar <mobile majumdar.org.uk> writes:
On Thursday, 24 December 2020 at 03:58:57 UTC, welkam wrote:
 On Thursday, 24 December 2020 at 00:41:35 UTC, Dibyendu 
 Majumdar wrote:
 At the moment I am struggling to implement the memory 
 allocator scheme in Rust
The easiest way to port C to Rust is trough D. D is so close to C that if you just copy pasted C code to D file it might just work without changes or very minimum changes. Furthermore D`s code plasticity together with language features allow to iteratively massage code base to more closely resemble Rust code making transition to Rust easier.
The point of my project is to compare what a current C project would look like in Rust vs D as Better C subset. Each port should exploit strengths of the language else it would not be a meaningful comparison. In this particular case, using an allocator makes sense because it is not useful to manage memory at object level (the project is a language implementation - so lots of objects are created but they all get thrown away at once).
Dec 24 2020
prev sibling parent bpr <brogoff gmail.com> writes:
On Thursday, 24 December 2020 at 00:41:35 UTC, Dibyendu Majumdar 
wrote:
 The enumerated types are important feature for my project which 
 currently uses unions. I may or may not use traits, I do not 
 know yet.

 At the moment I am struggling to implement the memory allocator 
 scheme in Rust. I may end up having to forgo this and just use 
 standard Rust facilities for memory management. With D I don't 
 think I will have any issues.
Have you seen this? https://os.phil-opp.com/allocator-designs/ Also https://doc.rust-lang.org/reference/items/unions.html I didn't find it that difficult to convert C to Rust in the past but you may have some special C. C++ is a different story. For now, Rust lacks const-generics (can't parameterize templates with constants) and HKT (higher kinded types, expressed in C++ as template template parameters) so designs that make use of these won't carry over directly. IIRC DasBetterC has all of D's static metaprogramming features. Rust has macros, which I've used in the past to work around the lack of const-generics.
Dec 24 2020
prev sibling next sibling parent sighoya <sighoya gmail.com> writes:
On Tuesday, 15 December 2020 at 23:25:02 UTC, Dibyendu Majumdar 
wrote:
Rust has traits - nothing equivalent in the D As Better C subset.
look at https://forum.dlang.org/post/mcfcvaavvugwkubrwatx forum.dlang.org
Dec 23 2020
prev sibling parent Dibyendu Majumdar <mobile majumdar.org.uk> writes:
In my C project (which is a compiler project for a scripting 
language) I have the following design.

I use allocators to manage memory.
Strings encountered during lexing are interned because the 
scripting language needs this feature
Various objects such as ASTs, instructions, constants etc. get 
created, and objects can reference other objects.
At the end of the compilation, everything is discarded by the 
allocators.

Simple and classic way I guess.

I have not yet looked at porting to D as I think I can pretty 
much keep this design in D.

In Rust though there is simply no way for references to be kept 
between data structures. Even if I as a programmer know that the 
references are safe because all memory is managed by allocators 
that have a longer life than the individual objects, there is no 
way to convince Rust that this is the case.

So with Rust I need to use either smart (ref counted) pointers, 
or use indirection (such as integer handles) that are copy-able, 
and so the compiler is happy with those.

I can see why this is the way in Rust. I can also see why Rust 
cannot trust the programmer, and therefore doesn't allow me to 
express the design I have today.

Just thought this might of interest. One implication is that if 
Rust is safe, D can never be safe in the same way. To be safe as 
Rust you'd have to prevent sharing of references completely. 
(oversimplified but broadly speaking)
Jan 15 2021