Lazarus

Miscellaneous => Other => Topic started by: lainz on April 24, 2021, 06:11:13 am

Title: Comparing Pascal and Rust
Post by: lainz on April 24, 2021, 06:11:13 am
Hi, I'm Pascal user not Rust user, but I take a look on that language last days.

What I've seen is:
- Rust uses only struct with associated methods (no classes), in FPC we call it advanced records.
- The memory is "moved" and can be only one owner at a time. Seems that the simple assign of a variable just moves it, in FPC we copy the variable, so we have copies. Also in Rust there is only a single pointer to a single data at the same time. This says to help to prevent having a variable for example in threads and in other places, and change them at the same time.
- There are references as well. Seems that in FPC this can be const modifier in functions and procedures?
- The types are a bit more strict than in FPC, for example there is no type conversion automatically, say you assign an Integer to a Double, that's not directly possible.
- The memory is erased when the scope ends, say a function. Same in FPC I think.

Well that's the far I get now with that language.

I see some things:
- Advanced records are available in FPC. No difference there.
- The memory is in FPC by default a copy of that record, not a move. Is possible to do a move and that the first instance is not valid anymore in FPC? Like moving a record to other record, inside the same function and / or to another functions.
- Passing a reference can be done with const or var parameters. In Rust it will be "&" for const and "mut &" for var. So no difference there.
- The memory is erased as well in FPC, when the functions ends, that is what I understand, so no difference.

So, they say Rust is more safe. On my experience is just that the compiler is very smart telling you where are the possible bugs you're making when coding. Other than that I see no point of using Rust.

Like typescript and javascript, the only difference is the compiler preventing you doing invalid stuff.

There's a mode or can be added to FPC that will help to prevent bugs? I alredy see some in Lazarus code editor, like unused variables, not initialized variables, missing return in a function. A lot of warinings about conversions.

Well that's it, I'm not saying one languages is better than the other. But just saying that FPC has already features that make it similar to Rust.
Title: Re: Comparing Pascal and Rust
Post by: PierceNg on April 24, 2021, 08:15:46 am
Rust has an evangelism strike force. Pascal has not. :P

Someone will surely correct me if I am wrong: Pascal records are stack-based, classes are heap-based, objects default to stack but can be heap-based. Dunno about advanced records. Rust structs default to stack but can be heap-based. Are Rust structs directly equivalent to Pascal advanced records?

In terms of language features, most of the newer languages like Rust, Swift, Kotlin etc support nullable or optional types. Such types are supposed to help deal with the null reference, which inventor Tony Hoare has called his billion dollar mistake.
Title: Re: Comparing Pascal and Rust
Post by: MarkMLl on April 24, 2021, 09:40:19 am
Put another way, people who say Rust is good are basically praising Pascal-like functionality which they perceive as superior to C-like functionality.

- The memory is erased as well in FPC, when the functions ends, that is what I understand, so no difference.

Not quite. By and large FPC makes variables inaccessible when they go out of scope, but the memory- and this includes strings which have been used for passwords etc.- is not erased/blanked/wiped/zeroed/randomised.

MarkMLl


Title: Re: Comparing Pascal and Rust
Post by: dbannon on April 24, 2021, 10:56:49 am
......
By and large FPC makes variables inaccessible when they go out of scope, but the memory- and this includes strings which have been used for passwords etc.- is not erased/blanked/wiped/zeroed/randomised.

And that would be because blanking out very large blocks of memory can be a time consuming thing. But few of us would store a (eg) password in a huge data array, should fpc null out smaller allocations and leaving the huge arrays alone ?

OK, thinking out loud, suppose an ANSIString can be told to blank out its memory before it goes out of scope ?  ANSIString.NullOnFree : boolean = false    ?

Davo
Title: Re: Comparing Pascal and Rust
Post by: avk on April 24, 2021, 11:28:08 am
... but the memory- and this includes strings which have been used for passwords etc.- is not erased/blanked/wiped/zeroed/randomised...

Does Rust do that sort of thing?
And seems like Rust has managed to outperform C++ in syntax ugliness?
Title: Re: Comparing Pascal and Rust
Post by: MarkMLl on April 24, 2021, 11:35:43 am
......
By and large FPC makes variables inaccessible when they go out of scope, but the memory- and this includes strings which have been used for passwords etc.- is not erased/blanked/wiped/zeroed/randomised.

And that would be because blanking out very large blocks of memory can be a time consuming thing. But few of us would store a (eg) password in a huge data array, should fpc null out smaller allocations and leaving the huge arrays alone ?

OK, thinking out loud, suppose an ANSIString can be told to blank out its memory before it goes out of scope ?  ANSIString.NullOnFree : boolean = false    ?

Davo

This is the real risk:

Code: Pascal  [Select][+][-]
  1. begin
  2.   plain := GetNonEchoedPasswordFromUser();
  3.   salt := GetRandomSalt;
  4.   plain := salt + plain;
  5.   crypt := Encrypt(plain);
  6.   plain := RandomChars(Length(plain))
  7. end;
  8.  

That obviously overwrites the plain variable before it goes out of scope, but it still risks leaving the plaintext password on the heap since the string might be reallocated when it's salted and the original is not overwritten.

MarkMLl
Title: Re: Comparing Pascal and Rust
Post by: avk on April 24, 2021, 01:06:22 pm
If you want a data type that cleans up when it goes out of scope, why not just create one?
For example:
Code: Pascal  [Select][+][-]
  1. unit CharDynArray;
  2.  
  3. {$mode objfpc}{$modeswitch advancedrecords}
  4.  
  5. interface
  6.  
  7. uses
  8.   SysUtils;
  9.  
  10. type
  11.  
  12.   TDynCharArray = record
  13.   private
  14.     FItems: PAnsiChar;
  15.     FLength: SizeInt;
  16.     procedure ReallocPtr(aNewLen: SizeInt);
  17.     procedure SetLen(aValue: SizeInt);
  18.     function  GetItem(aIndex: SizeInt): AnsiChar; inline;
  19.     procedure SetItem(aIndex: SizeInt; aValue: AnsiChar); inline;
  20.     class operator  Initialize(var a: TDynCharArray); inline;
  21.     class operator  Finalize(var a: TDynCharArray); inline;
  22.     class operator  Copy(constref aSrc: TDynCharArray; var aDst: TDynCharArray);
  23.     class operator  AddRef(var a: TDynCharArray);
  24.   public
  25.     procedure Clear;
  26.     property  Items[aIndex: SizeInt]: AnsiChar read GetItem write SetItem; default;
  27.     property  Length: SizeInt read FLength write SetLen;
  28.     property  Ptr: PAnsiChar read FItems;
  29.   end;
  30.  
  31. implementation
  32.  
  33. procedure TDynCharArray.ReallocPtr(aNewLen: SizeInt);
  34. var
  35.   NewPtr: PAnsiChar;
  36.   OldLen: SizeInt;
  37. begin
  38.   NewPtr := System.GetMem(aNewLen);
  39.   OldLen := Length;
  40.   if aNewLen > OldLen then
  41.     begin
  42.       System.Move(FItems^, NewPtr^, OldLen);
  43.       System.FillChar(NewPtr[OldLen], (aNewLen - OldLen), 0);
  44.     end
  45.   else  //aNewLen < OldLen
  46.     System.Move(FItems^, NewPtr^, aNewLen);
  47.   System.FillChar(FItems^, OldLen , 0);
  48.   System.FreeMem(FItems);
  49.   FItems := NewPtr;
  50. end;
  51.  
  52. procedure TDynCharArray.SetLen(aValue: SizeInt);
  53. begin
  54.   if aValue <> Length then
  55.     begin
  56.       if aValue = 0 then
  57.         begin
  58.           Clear;
  59.           exit;
  60.         end;
  61.       if aValue > 0 then
  62.         begin
  63.           ReallocPtr(aValue);
  64.           FLength := aValue;
  65.         end
  66.       else
  67.         raise EInvalidOpException.Create('Can not accept negative length value');
  68.     end;
  69. end;
  70.  
  71. function TDynCharArray.GetItem(aIndex: SizeInt): AnsiChar;
  72. begin
  73.   if SizeUInt(aIndex) < SizeUInt(Length) then
  74.     Result := FItems[aIndex]
  75.   else
  76.     raise EArgumentOutOfRangeException.CreateFmt('Index out of bounds(%d)', [aIndex]);
  77. end;
  78.  
  79. procedure TDynCharArray.SetItem(aIndex: SizeInt; aValue: AnsiChar);
  80. begin
  81.   if SizeUInt(aIndex) < SizeUInt(Length) then
  82.     FItems[aIndex] := aValue
  83.   else
  84.     raise EArgumentOutOfRangeException.CreateFmt('Index out of bounds(%d)', [aIndex]);
  85. end;
  86.  
  87. class operator TDynCharArray.Initialize(var a: TDynCharArray);
  88. begin
  89.   a.FItems := nil;
  90.   a.FLength := 0;
  91. end;
  92.  
  93. class operator TDynCharArray.Finalize(var a: TDynCharArray);
  94. begin
  95.   a.Clear;
  96. end;
  97.  
  98. class operator TDynCharArray.Copy(constref aSrc: TDynCharArray; var aDst: TDynCharArray);
  99. begin
  100.   if @aSrc <> @aDst then
  101.     begin
  102.       aDst.Clear;
  103.       if aSrc.Length <> 0 then
  104.         begin
  105.           aDst.Length := aSrc.Length;
  106.           System.Move(aSrc.FItems^, aDst.FItems^, aSrc.Length);
  107.         end;
  108.     end;
  109. end;
  110.  
  111. class operator TDynCharArray.AddRef(var a: TDynCharArray);
  112. var
  113.   OldPtr: PAnsiChar;
  114. begin
  115.   if a.Length <> 0 then
  116.     begin
  117.       OldPtr := a.FItems;
  118.       a.FItems := System.GetMem(a.Length);
  119.       System.Move(OldPtr^, a.FItems^, a.Length);
  120.     end;
  121. end;
  122.  
  123. procedure TDynCharArray.Clear;
  124. begin
  125.   if Length <> 0 then
  126.     begin
  127.       System.FillChar(FItems^, Length, 0);
  128.       FreeMem(FItems);
  129.       FItems := nil;
  130.       FLength := 0;
  131.     end;
  132. end;
  133.  
  134. end.
  135.  
Title: Re: Comparing Pascal and Rust
Post by: MarkMLl on April 24, 2021, 01:33:49 pm
If you want a data type that cleans up when it goes out of scope, why not just create one?
For example:

Somebody who's aware of the problem can far more easily preallocate a string of adequate length.

MarkMLl
Title: Re: Comparing Pascal and Rust
Post by: lainz on April 24, 2021, 01:55:58 pm
Rust has an evangelism strike force. Pascal has not. :P

Someone will surely correct me if I am wrong: Pascal records are stack-based, classes are heap-based, objects default to stack but can be heap-based. Dunno about advanced records. Rust structs default to stack but can be heap-based. Are Rust structs directly equivalent to Pascal advanced records?

In terms of language features, most of the newer languages like Rust, Swift, Kotlin etc support nullable or optional types. Such types are supposed to help deal with the null reference, which inventor Tony Hoare has called his billion dollar mistake.

Indeed, too much YouTube videos to start with.

I think you're right about stack and heap.

About Nullable types, FPC has them as well in Trunk. The thing is for example to work with SQL queries that can return null, or using null as an expected value.
Title: Re: Comparing Pascal and Rust
Post by: lainz on April 24, 2021, 01:57:27 pm
... but the memory- and this includes strings which have been used for passwords etc.- is not erased/blanked/wiped/zeroed/randomised...

Does Rust do that sort of thing?
And seems like Rust has managed to outperform C++ in syntax ugliness?

For the first question I don't know, what I wrote is what I've understood about the subject only reading their guide.

About ugliness, yes, maybe  :D
Title: Re: Comparing Pascal and Rust
Post by: lainz on April 24, 2021, 02:00:22 pm
Put another way, people who say Rust is good are basically praising Pascal-like functionality which they perceive as superior to C-like functionality.

- The memory is erased as well in FPC, when the functions ends, that is what I understand, so no difference.

Not quite. By and large FPC makes variables inaccessible when they go out of scope, but the memory- and this includes strings which have been used for passwords etc.- is not erased/blanked/wiped/zeroed/randomised.

MarkMLl

Indeed, for that I've opened this thread. I noticed they're doing *almost* the same  :D
Title: Re: Comparing Pascal and Rust
Post by: dbannon on April 24, 2021, 02:04:43 pm
OK, both those approaches would work but we won't win any "gee, thats better than rust" competitions that way I am afraid.

Generally, when I want to store some text, is in an ANSIString, I don't want to build new type and preallocating and remembering to overwrite at the end of a method (and any incidental exits) is just too hard (sits with thumb in mouth and sulks).

But by telling ANSIString that it is its responsibility to clean up when necessary sounds attractive.  That 'telling' happens right at the start of the method, but gets acted on whenever necessary. After all, ANSIString already has some clean up code already. But I'd hate to waste the time overwriting every data structure just for the very occasional time its needed, as rust does.

(No, I am not planning to put in a bug report, just, perhaps, demonstrating how easily we could match Rust if we thought it worthwhile !)

Davo
Title: Re: Comparing Pascal and Rust
Post by: pathfinder on April 24, 2021, 02:16:25 pm
Why Rust when there is already Ada/SPARK?
Title: Re: Comparing Pascal and Rust
Post by: MarkMLl on April 24, 2021, 02:38:22 pm
But by telling ANSIString that it is its responsibility to clean up when necessary sounds attractive.  That 'telling' happens right at the start of the method, but gets acted on whenever necessary. After all, ANSIString already has some clean up code already. But I'd hate to waste the time overwriting every data structure just for the very occasional time its needed, as rust does.

I think that when this was debated on the ML years ago attributes such as codepages were still a glimmer in the developers' eyes. I agree that something like that would be a step forwards.

MarkMLl
Title: Re: Comparing Pascal and Rust
Post by: MarkMLl on April 24, 2021, 02:44:38 pm
Why Rust when there is already Ada/SPARK?

Never heard of it.

OK, every damnfool has heard of Ada, even if he insists on spelling it as ADA. But the point is that there are a lot of Rust evangelists at large, and there are a lot of Pascal evangelists in here, and some vanishingly small number elsewhere who believe that Ada and other early ALGOL derivatives remain relevant, so the question is either

* How can Pascal evangelists promote it against RUST?

or (to a more limited extent)

* Does Rust provide a viable alternative to Pascal?

If Ada/SPARK is at all relevant to either of those, then I suggest that you provide your own "compare and contrast", possibly in a separate thread, like OP did in this one.

MarkMLl
Title: Re: Comparing Pascal and Rust
Post by: pathfinder on April 24, 2021, 03:21:13 pm
Quote
then I suggest that you provide your own "compare and contrast", possibly in a separate thread, like OP did in this one.

I would suggest you understand what a rhetorical statement means. 

Further, I would suggest with the tone you carry that it isn't beneficial to Lazarus/FPC with the already tiny market it has.  If I was looking to possibly use this product versus, say, Racket, I'd go with the community that doesn't have confrontational members.  Like Racket.

Anyway, thanks for providing me with a last post and a reason to go with something else.
Title: Re: Comparing Pascal and Rust
Post by: Warfley on April 24, 2021, 04:09:11 pm
I see some things:
- Advanced records are available in FPC. No difference there.
- The memory is in FPC by default a copy of that record, not a move. Is possible to do a move and that the first instance is not valid anymore in FPC? Like moving a record to other record, inside the same function and / or to another functions.
- Passing a reference can be done with const or var parameters. In Rust it will be "&" for const and "mut &" for var. So no difference there.
- The memory is erased as well in FPC, when the functions ends, that is what I understand, so no difference.

So, they say Rust is more safe. On my experience is just that the compiler is very smart telling you where are the possible bugs you're making when coding. Other than that I see no point of using Rust.

Rust is more typesafe because the access is controlled on a finer granularity. For example, let's say you want to give a record read access to another record in pascal
Code: Pascal  [Select][+][-]
  1. type TTestRec = record
  2.   SomeReference: PInteger;
  3. end;
  4.  
  5. function createRec(constref reference: Integer): TTestRec;
  6. begin
  7.   Result := @reference; // at this point the information that this is a constant reference is lost, no way to get that information into the record
  8. end;
  9.  
  10. var
  11.   i: Integer;
  12.   test: TTestRec;
  13. begin
  14.   i := 42;
  15.   test := createRec(i);
  16.   test.SomeReference := 32; // i just overwrote something that should be constant
  17. end;
  18.  

Compare this to rust:
Code: C  [Select][+][-]
  1. struct SomeStruct<'a> {
  2.    SomeRef: &'a i32,
  3. }
  4.  
  5. fn createStruct(reference: &i32) -> SomeStruct {
  6.     return SomeStruct {
  7.         SomeRef: reference
  8.     };
  9. }
  10.  
  11. fn main() {
  12.     let i = 42;
  13.     let test = createStruct(&i);
  14.     *test.SomeRef = 32; // this throws a compiler error, because the reference is not mutable
  15. }
  16.  
The problem here is that the mutability information can not propagate in pascal through anything but function parameter. So unless we all start going fully functional now, we will loose this information eventually.
This means that no matter how smart the FPC is, it simply can not provide the type safety rust provides, because the language simply can not provide for the information on the level that rust does.

Pascal does not have a concept of immuatble memory locations. But you don't even need to go so far to rust to see it, C for instance does also have it:
Code: C  [Select][+][-]
  1. struct SomeStruct {
  2.   int const *SomeRef;
  3. }
  4.  
  5. SomeStruct createStruct(int const *ref) {
  6.   return {
  7.     SomeRef: ref
  8.   };
  9. }
  10.  
  11. int main() {
  12.   int i = 42;
  13.   SomeStruct test = createStruct(&i);
  14.   *(test.i) = 32; // compiler error
  15. }

But thats not where rusts safety ends, you might have noticed the <'a> in the struct definitionm this is a lifetime information of that struct. Rust tracks the lifetime information of all references on a language level, so if we modify the main function a little bit:
Code: C  [Select][+][-]
  1. fn main() {
  2.     let test: SomeStruct;
  3.     {  // create a scope, all local variables defined within here will be destroyed afterwards
  4.         let i = 42;
  5.         test = createStruct(&i);
  6.     } // the scope ends, i is destroyed, test.SomeRef is a dangling pointer
  7.     println!("{}", *test.SomeRef); // error, as rust notices the lifetime disparity
  8. }
The rust compiler notices that the lifetime of the struct and the one of the reference don't align and throws an error
This completely solves the problems of dangling pointers. But this also requires the user to provide additional lifetime information at a granular level, which requires special syntactical constructs.

The next thing is that rust tracks the number of references, it ensures that there is always only one mutable access:
Code: C  [Select][+][-]
  1. fn main() {
  2.     let mut i = 42;
  3.     let test1 = createStruct(&mut i);
  4.     let test2 = createStruct(&mut i); // throws error because there was already one mutable reference
  5.     println!("{}", *test1.SomeRef);
  6.     println!("{}", *test2.SomeRef);
  7. }

Also while a reference is active (in rust speak the variable is borrowed), it can not be changed:
Code: C  [Select][+][-]
  1. fn main() {
  2.     let mut i = 42;
  3.     let test1 = createStruct(&i);
  4.     i = 32; // throws an error because test1 borrows it
  5.     println!("{}", *test1.SomeRef);
  6. }

This makes use-after-free and double-free impossible, but this is only possible due to precise tracking of the mutability and lifetime information. It is mathematically impossible to ensure this during compiletime in Pascal, this is only possible in Rust because the language is restricted through the enforcement of mutability and lifetimes which makes this a computable problem.

So about your last statement:
Quote
Well that's it, I'm not saying one languages is better than the other. But just saying that FPC has already features that make it similar to Rust.
The answer is simply no. Pascal has neither the capabilities to restrict mutability nor lifetime on a syntactic level. Therefore the features that the Rust compiler provides are impossible to do on Pascal code.


It should also be noted that the syntactical makeup of a language changes the behavior of the developer. In for example C, everything is mutable unless defined otherwise, in rust it is the other way around. This leads to C developers having more things mutable than strictly being neccessary, simply because the developer did not bother to add the const modifier. By doing it the other way around, rust ensures that the developer only makes the things mutable that are neccessary to have mutable.
Title: Re: Comparing Pascal and Rust
Post by: MarkMLl on April 24, 2021, 04:11:24 pm
Look, I really don't see what your problem is here.

Sure, Pascal is rapidly heading for "niche" if not "boutique", because it is /perceived/ as being an obsolete, inflexible language that hasn't been touched for 40 years.

Rust gets an enormous amount of positive press, maybe deservedly and maybe not. Comparing and contrasting the two is very useful irrespective of the angle.

Ada is /perceived/ as being oversize, inflexible and moribund except possibly in the context of large-project maintenance in defense contractors.

I stress /perceived/ in all three cases there, because just about everybody here knows that at least in the case of Pascal and Ada things are much more complex.

Now if you have something useful to say that either contributes to the Rust vs Pascal debate or positions Ada as being relevant to it we're all most interested to see your contribution.

MarkMLl
Title: Re: Comparing Pascal and Rust
Post by: MarkMLl on April 24, 2021, 04:19:10 pm
The answer is simply no. Pascal has neither the capabilities to restrict mutability nor lifetime on a syntactic level. Therefore the features that the Rust compiler provides are impossible to do on Pascal code.

Thanks very much for that, very interesting. I must say that OP's point about very strict typing was also something I consider attractive.

Thinking back to various bare metal stuff I've done in the past, some of the mutability aspect could probably be handled by changing protection attributes on different areas of memory... in some ways that would be finer-grained but it would also be much more work.

Noting the (non-)mutability aspect of functional languages, but when did this sort of thing enter the mainstream? With a nod to @Pathfinder (if he's still around) did Ada or any other self-professed "safe" language implement that sort of thing?

MarkMLl
Title: Re: Comparing Pascal and Rust
Post by: lainz on April 24, 2021, 04:43:14 pm
So about your last statement:
Quote
Well that's it, I'm not saying one languages is better than the other. But just saying that FPC has already features that make it similar to Rust.
The answer is simply no. Pascal has neither the capabilities to restrict mutability nor lifetime on a syntactic level. Therefore the features that the Rust compiler provides are impossible to do on Pascal code.

Indeed, this is the thing on my comparison, that FPC can't do. But the things in common are say the advanced records, constants and references, well other things was proved that FPC can't (by default), like strings (on the heap) erasing (that can be added if someone does it) and that by default memory is a copy in FPC and not a single pointer at a time.

Is impossible actually, but it is impossible to implement as well?
Title: Re: Comparing Pascal and Rust
Post by: Warfley on April 24, 2021, 04:43:57 pm
Noting the (non-)mutability aspect of functional languages, but when did this sort of thing enter the mainstream? With a nod to @Pathfinder (if he's still around) did Ada or any other self-professed "safe" language implement that sort of thing?

MarkMLl
I don't know which was the first language to have that, but it is a big thing in C, so it is already pretty old.

In C you have the concept of objects (this is the name that the C standard gives, has nothing to do with OOP) and each object can have certain modifiers. For example:
Code: C  [Select][+][-]
  1. int i; // this is an int object
  2. int *i; // this is a pointer object pointing to an int object
  3. int const i; // this is an int object with a const modifier
These objects can be constructed sequentially, where each modifier modifies the type to the left of it.
For example
Code: C  [Select][+][-]
  1. int const * volatile * const i
This is a constant pointer object, pointing to a volatile pointer object pointing to a constant int object.
Note that a modifier in front of a definition only effects the first object in the chain:
Code: Pascal  [Select][+][-]
  1. const int *i;
  2. // is the same as
  3. int const *i;
  4. // not
  5. int * const i;
Which is a pitfall where many beginners fall into because they assume the pointer is const, but in reality the value pointed to is const.

This allows for very granular access control, for example:
Code: C  [Select][+][-]
  1. int * const i;
makes the pointer immutable, this could for example be used to make access to shared memory, which has a fixed location in memory, so you can't change the pointer, but you the int value behind that pointer is not modifyable:
Code: Pascal  [Select][+][-]
  1. i = &othervar; // compiler error, the pointer is const
  2. *i = 42; // works fine

This can be put anywhere
Code: C  [Select][+][-]
  1. struct Test {
  2.   int const *i; // a pointer to a constant integer
  3.   int * const p; // A constant pointer to a variable integer
  4. }

I think that this is something that is really lacking in pascal. You can only have this form of access control in function parameters, and then there is only one layer:
Code: Pascal  [Select][+][-]
  1. procedure foo(constref param1: Integer; const param2: PInteger);
Here you have a pointer to a constant integer as well as a constant pointer to an integer. But you can't go deeper then that, and constref is rather new anyway, so for a long time we didn't even have that.
Also as I noted above this is not enforced, so:
Code: Pascal  [Select][+][-]
  1. procedure foo(constref param: Integer);
  2. var test: PInteger;
  3. begin
  4.   test := @ param;
  5.   test^ := 42; // I just changed a constant value, without a compiler error or warning
  6. end;
In C this looks different:
Code: C  [Select][+][-]
  1. void foo(int const *param) {
  2.   int *test = param; // does not work
  3.   int const *test2 = param; // only this works
  4.   // workaround
  5.   test = (int*)param;
  6. }
So you can work around this, but this requires effort, so you need to be at least in some form conciously aware of what you are doing, and in C++ this is even more explicit:
Code: C  [Select][+][-]
  1. int *test = const_cast<int *>(param);
Making it clear to everyone who reads it that you made a concious decision to remove the const here, which might be neccessary at times, but should require a good bit of explaination, as usually some things are const for a reason.

I really like this and miss that pascal does not have something comparable to this, as especially the possibility to return constant pointers would be great (e.g. give read access to a field of a class without having to worry that data will be changed)
Title: Re: Comparing Pascal and Rust
Post by: Warfley on April 24, 2021, 04:59:11 pm
Indeed, this is the thing on my comparison, that FPC can't do. But the things in common are say the advanced records, constants and references, well other things was proved that FPC can't (by default), like strings (on the heap) erasing (that can be added if someone does it) and that by default memory is a copy in FPC and not a single pointer at a time.

Is impossible actually, but it is impossible to implement as well?
But your comparison completely misses the point why rust is the way it is and why it is so popular among the low level development community. The typesafety does not stem from advanced records or constants or references in particular, but the special way they are implemented. Sure both pascal and rust have andvanced records, so does C++ or C#, but the thing that makes rust advanced records special is the runtime tracking of the record and the members due to runtime information annotations (the <'a> in my example). Sure pascal has references, so does nearly any language, but the thing that is special about rust is the reference tracking and enforcement of maximum references which requires runtime information and fine grained mutability information. And yes there are constants in rust and pascal and again, C++, C#, Java, you name it, but the thing that is special about rust is the granularity of that information, that is completely lost in Pascal.

And by the term impossible I mean mathematically provable impossible (via rices theorem) in the current way the language is defined. It requires massive changes to the Pascal language syntax and semantic to make this possible. Basically to do this one would need to turn pascal into rust. Sure this is possible, but I don't think that it is quite so good of an idea to trying to mirror another language tail to foot, because if I wanted to have rust, I'd use rust not Rustlike pascal?
Title: Re: Comparing Pascal and Rust
Post by: lainz on April 24, 2021, 05:07:37 pm
Thanks Warfley, as I said I don't know fully Rust so mi comparison can be wrong as well. That's the good part of the forum where others can know more than one.

Indeed about not using Pascal for everything. But maybe I don't have a target application for Rust yet so my comparison was biased in that point too. Not like I will do a system that needs to run so fast or so secure, that I only need to use records, ensure they are not changed and so on. Maybe any application can benefit from it, just I'm not fully aware of the concerns maybe.

Thanks for all the comments, learning from others all days is really good in this forum.
Title: Re: Comparing Pascal and Rust
Post by: Warfley on April 24, 2021, 05:28:56 pm
A software that famously is transitioning to Rust is Firefox. This needs to be highly secure and really fast, which is why Rust is perfect.

But no, rust is not a language for every software, it does not even try to be. If you don't need the performance, but the safety, you are much better advised using a garbage collected language like Java, where all these memory problems are also solved by having a garbage collector. In Pascal you could use reference counted interfaces, if you are unsure about memory management.

Rust is a really specific language for a really specific niche. Low level high performance development. Operating Systems, Browsers, Simulators, etc.

But that said, some features could of course be considered for Pascal, Pascal does not need to go full rust, but something like the fine grained const modifiers as they are in C (as I mentioned above) could be a great addition to pascals type system (of course in a pascallian way and only as an opt in solution with a special mode switch).
Title: Re: Comparing Pascal and Rust
Post by: marcov on April 24, 2021, 06:56:56 pm
A software that famously is transitioning to Rust is Firefox. This needs to be highly secure and really fast, which is why Rust is perfect.

It is why they designed it that way. Rust comes from the Mozilla foundation, the originator was a Mozilla employee.  So it would be pretty bad if it wasn't suitable ;-)

Anyway, alternate safe helpers would be possible, and a directive to switch to them for critical sections of code also seems possible. But if you would pass strings outside those areas, it would be dangerous again. That can be helped by having some runtime property attached to every string, but that is slowing for the bulk of applications that don't need it.

Thinking about it, my guess it would then only work if an application and the libraries it uses would be compiled with such switch, meaning you would need a special distribution of the compiler/libraries/lazarus etc.
Title: Re: Comparing Pascal and Rust
Post by: MarkMLl on April 24, 2021, 07:06:25 pm
It is why they designed it that way. Rust comes from the Mozilla foundation, the originator was a Mozilla employee.  So it would be pretty bad if it wasn't suitable ;-)

But you ought to see some of the stuff that's emerged from places like IBM... not to mention MS et al. Remember in the late 80s when Bill Gates (at his most rapacious) said that in a few years absolutely everything would be written in Visual Basic?

Quote
Thinking about it, my guess it would then only work if an application and the libraries it uses would be compiled with such switch, meaning you would need a special distribution of the compiler/libraries/lazarus etc.

I'd already got there thinking about the string-wipe problem and system functions like ReadLn(). However, (a) would doing this properly in the RTL/FCL/LCL really introduce unacceptable overhead when compared with the performance lost in X11 and higher-level stuff? (b) having maximal checks enabled during development- even if aspects could be turned off for release- might still be viable.

MarkMLl
Title: Re: Comparing Pascal and Rust
Post by: marcov on April 24, 2021, 07:27:25 pm
Quote
Thinking about it, my guess it would then only work if an application and the libraries it uses would be compiled with such switch, meaning you would need a special distribution of the compiler/libraries/lazarus etc.

I'd already got there thinking about the string-wipe problem and system functions like ReadLn(). However, (a) would doing this properly in the RTL/FCL/LCL really introduce unacceptable overhead when compared with the performance lost in X11 and higher-level stuff? (b) having maximal checks enabled during development- even if aspects could be turned off for release- might still be viable.

(a) FPC is used for other things than X11, including memory databases etc, iow not just GUI apps.
(b) It can be, but it simply needs a separate unit tree. But practical final delivery is still far in the distance. First somebody needs to work on it and proof its worth.
 
Title: Re: Comparing Pascal and Rust
Post by: PierceNg on April 25, 2021, 03:26:29 am
It should also be noted that the syntactical makeup of a language changes the behavior of the developer. In for example C, everything is mutable unless defined otherwise, in rust it is the other way around. This leads to C developers having more things mutable than strictly being neccessary, simply because the developer did not bother to add the const modifier. By doing it the other way around, rust ensures that the developer only makes the things mutable that are neccessary to have mutable.

Thanks for the illustrative writeup.
Title: Re: Comparing Pascal and Rust
Post by: circular on April 25, 2021, 09:06:07 am
But you ought to see some of the stuff that's emerged from places like IBM... not to mention MS et al. Remember in the late 80s when Bill Gates (at his most rapacious) said that in a few years absolutely everything would be written in Visual Basic?
I would be glad to have a link to that.  :)

About the subject of erasing a string, assigning a new value doesn't work. Though you can simply do:
Code: Pascal  [Select][+][-]
  1. password := GetThePassword();
  2. ...
  3. if password <> '' then
  4. begin
  5.   FillChar(password[1], length(password), 0); // erase the content
  6.   password := ''; // erase the reference, so one cannot follow it to get the length of it
  7. end;
Title: Re: Comparing Pascal and Rust
Post by: MarkMLl on April 25, 2021, 09:56:15 am
But you ought to see some of the stuff that's emerged from places like IBM... not to mention MS et al. Remember in the late 80s when Bill Gates (at his most rapacious) said that in a few years absolutely everything would be written in Visual Basic?
I would be glad to have a link to that.  :)

I think that predates links :-) My attention was drawn to it by an associate, and I suspect that- like just about everything else he thought he knew about computers- it had been in Byte.

MarkMLl
TinyPortal © 2005-2018