Pascal vs C

All off topic discussions go here. Everything from the funny thing your cat did to your favorite tv shows. Non-programming computer questions are ok too.
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Pascal vs C

Post by onlyonemac »

Funny how everyone missed my new big point of the functions/procedures thing in Pascal. In my opinion it is far more elegant to abstract something than to break it down into subtypes to the point where the relationship between then is lost - that's how functions and procedures are in Pascal, where a subroutine has to be given a different name just because it happens to need to return a value e.g. an error code.

In C, "int open_file(char *filename);" and "void close_file(int file_descriptor);" can be both referred to as "procedures" to handle files or "functions" to handle files - the terms are interchangable. The code is consistent and the documentation can be consistent as well.

In Pascal, one would have to be "Function open_file(filename:Char):Integer" (might have the syntax slightly wrong there, but the important part is the "Function" keyword) and the other would be "Procedure close_file(file_descriptor:Integer)". So while these are both logically in the same category, as subroutines to handle files, the code and the documentation are both forced to be inconsistent not because of the meaning of the functions but simply because one needs to return a file descriptor and the other one doesn't.

Another thing that results from this, too, is that in C the return value of a function can be dumped, whereas in Pascal a "function" is required to have somewhere to return its value, meaning something like some of the C standard library functions (such as "strcpy" which returns the destination pointer as a return value of the function - probably to allow one to write "new_string = strcpy(malloc(strlen(old_string) + 1), old_string);" which is very useful, by the way) would be really painful to use or something which returns an error code which isn't really needed while we're just getting the basics written (we'll add the error handlers later).

To me these are both serious flaws.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
User avatar
Kazinsal
Member
Member
Posts: 559
Joined: Wed Jul 13, 2011 7:38 pm
Libera.chat IRC: Kazinsal
Location: Vancouver
Contact:

Re: Pascal vs C

Post by Kazinsal »

Also, a point re: pascal being "antiquated": If Pascal is antiquated, so is C; both were created around 1968-1970.
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Pascal vs C

Post by onlyonemac »

Kazinsal wrote:Also, a point re: pascal being "antiquated": If Pascal is antiquated, so is C; both were created around 1968-1970.
Yeah but C has been kept up to date. Pascal has had a few attempts at being updated, none of which really flow on from the original language in the same way that C has been slowly built up and had new features integrated in an elegant way.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

PascalABC.NET :)

Post by alexfru »

For those desperately wanting a bunch of features from other languages and not wanting to leave Pascal there's little-known PascalABC.NET.
Documentation seems to be in Russian only, so, I'll try to summarize some features you don't find in Pascal circa Turbo Pascal (extracted from these slides):
  • Variable definitions anywhere between begin and end as in C99/C++
  • Variable initialization at the place of definition as in C/C++
  • Variable definition in for as in C99/C++
  • Type deduction from initializers similar to auto in C++11, also short syntax for definition+initialization of records from initializers (types deduced, names are automatic, e.g. Item1, Item2, etc akin to C++ make_pair)
  • Lambda functions and short function definition syntax as in functional languages and one-liner lambda functions of Python
  • BigInteger
  • Dynamic arrays
  • Sets of any type
  • Arbitrary length strings
  • Procedure/function variables as function pointers in C/C++
  • Operators += and *= as in C/C++
  • switch/case on strings, not just on integers
  • ranges instead of loops as in Python
  • Lists, stacks, dict(ionary)s
  • LINK/select/where
  • foreach on lines of text file as in Perl
  • Write/WriteLn printing aggregate types like arrays, records and sets
  • Library extensions
  • .NET
  • OpenMP
  • etc
User avatar
Artlav
Member
Member
Posts: 178
Joined: Fri Aug 21, 2009 5:54 am
Location: Moscow, Russia
Contact:

Re: Pascal vs C

Post by Artlav »

onlyonemac wrote:Another thing that results from this, too, is that in C the return value of a function can be dumped, whereas in Pascal a "function" is required to have somewhere to return its value
Huh?
The only difference i see is that in C the return statement is a result+exit combined, while in pascal it's two separate pieces.
Which is actually more useful for return codes, since in C you would have to define additional variable for it, adding a whole extra line.

Code: Select all

function decode_error(w:word):dword;
begin
 result:=0;
 if (w and $01)<>0 then result:=result or ERR_RUN;
 if (w and $02)<>0 then result:=result or ERR_HCRESET;
 if (w and $04)<>0 then result:=result or ERR_GRESET;
 if (w and $08)<>0 then result:=result or ERR_EGSM;
end;
vs

Code: Select all

uint32 decode_error(uint16 w)
{
 uint32 res=0;
 if (w & 0x01) res|=ERR_RUN;
 if (w & 0x02) res|=ERR_HCRESET;
 if (w & 0x04) res|=ERR_GRESET;
 if (w & 0x08) res|=ERR_EGSM;
 return res;
}
onlyonemac wrote:In Pascal, one would have to be "Function open_file(filename:Char):Integer" (might have the syntax slightly wrong there, but the important part is the "Function" keyword) and the other would be "Procedure close_file(file_descriptor:Integer)". So while these are both logically in the same category, as subroutines to handle files, the code and the documentation are both forced to be inconsistent not because of the meaning of the functions but simply because one needs to return a file descriptor and the other one doesn't.
I don't get how is it different from void sub(); and int sub(); - you use different words as well.

In documentation, both functions and procedures are subroutines, for example.
I don't get what the inconsistency is.
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: Pascal vs C

Post by Kevin »

Artlav wrote:Totally agree. I miss them quite often, and my own compiler is not up to speed yet...
You're writing a Pascal compiler? Nice.
Kevin wrote:arrays need to be declared with their size instead of deriving it from the initialiser list
+1
To be fair, though, that would probably the kind of syntax extension that the FPC developers would be likely to accept for the native FPC modes if someone provided a patch.
Kevin wrote:The other one is that the compiler isn't really meant for making changes to or even writing your own system unit. If a compilerproc is missing or has the wrong interface, you usually get a fatal internal error with a number and no useful message. Next thing is grepping the compiler source for the number and checking what was really missing. That's not quite how I'd like the error handling to be.
Hm? Never had that problem.
Won't it just fail to compile with "fpc_so_and_so not found" error?
Maybe they actually improved it? I haven't updated my cross compiler from 2.4.x yet.
onlyonemac wrote:Funny how everyone missed my new big point of the functions/procedures thing in Pascal.
Because it's actually a minor detail. In C, you replace int with void; in Pascal, you replace function with procedure. There needs to be a way to say that there is no return value and I wouldn't call one or the other inherently better.

C avoids the procedure keyword, but introduces a void type instead, which is a rather strange type and comes with more inconsistencies. First of all, most people don't even think you can declare void variables at all (and in fact some got mad at me and told me it doesn't make any sense when I said that "extern const void" is the correct type for a symboll declared in the linker script). That's not quite correct, but there is no way to define a void variable or to have a void literal. This results in special syntax for void functions: Because you'll have a hard time finding anything void that you could return, "return" changes its syntax to work without a return value. And at the end of the function, it can even be left out. If this isn't inconsistent, what would be? (It's convenient, though, so I don't mind...)

You also have functions that are declared to take a void argument (which is the only way to declare a function without arguments), but then they work without being passed anything. In fact, it's even an error if you're bold enough to take the prototype literal and pass something "extern const void"!
Another thing that results from this, too, is that in C the return value of a function can be dumped, whereas in Pascal a "function" is required to have somewhere to return its value
For all I know, this is not true, at least not in modern Pascal dialects.
onlyonemac wrote:Yeah but C has been kept up to date. Pascal has had a few attempts at being updated, none of which really flow on from the original language in the same way that C has been slowly built up and had new features integrated in an elegant way.
Actually, to me modern Pascal dialects like ObjFPC fit very nicely into the original language. C appears to have had the larger changes, where even basic parts of the syntax have been deprecated (but are still supported by current compilers): Think of K&R style function declarations, including functions with no specified argument list and/or return type, implicit function declarations...
Artlav wrote:The only difference i see is that in C the return statement is a result+exit combined, while in pascal it's two separate pieces.
Actually, FPC gives you the choice. It supports the short exit(0); syntax, which I use most times. But there are still cases, as you mention, where the old Pascal syntax is more convenient and I'm happy to use it in those cases.
Developer of tyndur - community OS of Lowlevel (German)
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Pascal vs C

Post by onlyonemac »

Artlav wrote:
onlyonemac wrote:Another thing that results from this, too, is that in C the return value of a function can be dumped, whereas in Pascal a "function" is required to have somewhere to return its value
Huh?
In C, the following is valid:

Code: Select all

int test_function()
{
return 0;
}

int main(int argc, char *argv[])
{
test_function();
exit(0);
}
whereas in Pascal the following is not valid:

Code: Select all

function test_function();
begin
test_function := 0;
end

begin
(* lol I have no idea how to do an "int main" in Pascal *)
test_function();
exit(0);
end.
and the line "test_function();" has to read "some_variable := test_function();".
Artlav wrote:

Code: Select all

function decode_error(w:word):dword;
begin
 result:=0;
 if (w and $01)<>0 then result:=result or ERR_RUN;
 if (w and $02)<>0 then result:=result or ERR_HCRESET;
 if (w and $04)<>0 then result:=result or ERR_GRESET;
 if (w and $08)<>0 then result:=result or ERR_EGSM;
end;
I was under the impression that to specify a return value you have to write "<name_of_function> := value;" not "result := value;" - another inconsistency of the language.
Artlav wrote:
onlyonemac wrote:In Pascal, one would have to be "Function open_file(filename:Char):Integer" (might have the syntax slightly wrong there, but the important part is the "Function" keyword) and the other would be "Procedure close_file(file_descriptor:Integer)". So while these are both logically in the same category, as subroutines to handle files, the code and the documentation are both forced to be inconsistent not because of the meaning of the functions but simply because one needs to return a file descriptor and the other one doesn't.
I don't get how is it different from void sub(); and int sub(); - you use different words as well.

In documentation, both functions and procedures are subroutines, for example.
I don't get what the inconsistency is.
The inconsistency is simply that in C we can call a "procedure" (which conceptually does not return a value) a "function with return value of type void". It is not an error to place a "return" statement in a rpocedure in C, as long as the return value is of type void. "Void" is furthermore an important concept, because it also allows one to declare arbitrary blocks of memory and pointers to those blocks without having to make any untyped blocks of memory arrays of unsighed char.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Pascal vs C

Post by onlyonemac »

Kevin wrote:Because it's actually a minor detail. In C, you replace int with void; in Pascal, you replace function with procedure. There needs to be a way to say that there is no return value and I wouldn't call one or the other inherently better.
No, you're wrong. In C a subroutine *always* has a return value, but if there is no actual "value" to return then we say that the return value is of type void (which basically means, a variable/value type that cannot hold anything).
Kevin wrote:First of all, most people don't even think you can declare void variables at all (and in fact some got mad at me and told me it doesn't make any sense when I said that "extern const void" is the correct type for a symboll declared in the linker script).
It doesn't matter what most people think, we're talking about the languages themselves, assuming that a programmer is fluent in his language of choice. People's knowledge of a language has nothing to do with the capabilities of that language itself.
Kevin wrote:You also have functions that are declared to take a void argument (which is the only way to declare a function without arguments), but then they work without being passed anything. In fact, it's even an error if you're bold enough to take the prototype literal and pass something "extern const void"!
I'm not sure what you're referring to. I assume you're referring to the old prototype syntax of "int get_last_error(void);" to specify that the function does not take any arguments, but that is an old syntax that I haven't seen in anything since the 90s. These days, if a function takes no argumetns then you just write it as such: "int get_last_error();"; if the function takes a void argument then you write it as such "int get_last_error(void useless_argument);". A void argument and no argument are not the same thing, just as a void return value is not the same as having no return value (the latter of which cannot be done in C).
onlyonemac wrote:Yeah but C has been kept up to date. Pascal has had a few attempts at being updated, none of which really flow on from the original language in the same way that C has been slowly built up and had new features integrated in an elegant way.
Case in point, see below:
Kevin wrote:Actually, FPC gives you the choice. It supports the short exit(0); syntax, which I use most times. But there are still cases, as you mention, where the old Pascal syntax is more convenient and I'm happy to use it in those cases.
Whoa, super cool!!! Now we have a whole TWO DIFFERENT WAYS of returning from a function!
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
User avatar
Artlav
Member
Member
Posts: 178
Joined: Fri Aug 21, 2009 5:54 am
Location: Moscow, Russia
Contact:

Re: Pascal vs C

Post by Artlav »

onlyonemac wrote:and the line "test_function();" has to read "some_variable := test_function();".
It doesn't.
Just calling a function without assigning it's result to anything like your example did is perfectly fine, and was so since the original pascal, AFAIK.
Would have been awful otherwise, i agree.
onlyonemac wrote:lol I have no idea how to do an "int main" in Pascal
You did it right, actually. :)
onlyonemac wrote:I was under the impression that to specify a return value you have to write "<name_of_function> := value;" not "result := value;" - another inconsistency of the language.
Both are correct these days. The function_name method is the older way, which got deprecated since it makes it difficult to rename functions.
onlyonemac wrote:The inconsistency is simply that in C we can call a "procedure" (which conceptually does not return a value) a "function with return value of type void".
I don't see how it is less inconsistent.
"A function without a return type is called a procedure" on one hand, "a procedure is called a function with a void return type" on the other hand.
Same thing, different approach angle.
alexfru
Member
Member
Posts: 1111
Joined: Tue Mar 04, 2014 5:27 am

Re: Pascal vs C

Post by alexfru »

onlyonemac wrote:It is not an error to place a "return" statement in a rpocedure in C, as long as the return value is of type void.
ANSI C and C99:
A return statement with an expression shall not appear in a function whose return type is void.
Some compilers, however, allow code like this:

Code: Select all

void a(void) {}
void b(void) { return a(); }
Kevin
Member
Member
Posts: 1071
Joined: Sun Feb 01, 2009 6:11 am
Location: Germany
Contact:

Re: Pascal vs C

Post by Kevin »

I assume that you agree with all I said about C when you didn't quote that part? It would have been good style to be explicit about that.
onlyonemac wrote:In C a subroutine *always* has a return value, but if there is no actual "value" to return then we say that the return value is of type void (which basically means, a variable/value type that cannot hold anything).
You may say so, but it's still not like any other return value. You get special syntax instead where return is only allowed without a value: "A return statement with an expression shall not appear in a function whose return type is void. A return statement without an expression shall only appear in a function whose return type is void." (C11, 6.8.6.4). This is an exception, no matter what you say about return values.

Interestingly, despite the standard forbidding it, gcc seems to accept an expression of type void for return types (but as I mentioned, passing a void value for an empty argument list (declared with void) doesn't work).
It doesn't matter what most people think, we're talking about the languages themselves, assuming that a programmer is fluent in his language of choice. People's knowledge of a language has nothing to do with the capabilities of that language itself.
It's good that we agree on that, because you seem to be fluent neither in C nor in Pascal, see below:
I'm not sure what you're referring to. I assume you're referring to the old prototype syntax of "int get_last_error(void);" to specify that the function does not take any arguments, but that is an old syntax that I haven't seen in anything since the 90s. These days, if a function takes no argumetns then you just write it as such: "int get_last_error();"; if the function takes a void argument then you write it as such "int get_last_error(void useless_argument);". A void argument and no argument are not the same thing, just as a void return value is not the same as having no return value (the latter of which cannot be done in C).
Please, please, please, before you engage in hair splitting, go do your homework and learn C.

"int get_last_error()" is the old deprecated syntax. It doesn't mean that the function doesn't get any arguments, but that the argument list is unspecified. You can call it with any arguments. Quoting the standard: "The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature." (C11, 6.11.6)

"int get_last_error(void)" is the correct current syntax. It's somewhat inconsistent because passing a void value isn't actually allowed, whereas a function declared "int get_last_error(int)" takes an int argument. This is an exception, but clearly defined. ("The special case of an unnamed parameter of type void as the only item in the list specifies that the function has no parameters." - C11, 6.7.6.3)

If you have a named parameter of type void - like your "int get_last_error(void useless_argument)" - the exception doesn't apply any more (yay for consistency!) and that will actually result in a compiler error. (C11, 6.9.1, paragraph 5 explicitly forbids using an identifier for a single void argument.)

And the K&R syntax I was talking about is something like the following (really old, but it's an example taken from the current standard!):

Code: Select all

extern int max(a, b)
    int a, b;
{
    return a > b ? a : b;
}
Developer of tyndur - community OS of Lowlevel (German)
onlyonemac
Member
Member
Posts: 1146
Joined: Sat Mar 01, 2014 2:59 pm

Re: Pascal vs C

Post by onlyonemac »

Frankly these quotes and accompanying argument threads are getting too complicated for me to keep track of with my screenreader, but nobody has yet to explain why Pascal is *better* than C. And so far the issue of "Pascal is not used anymore" has not been addressed either, and as far as I'm concerned that is still a reason alone not to use it for anything new.
When you start writing an OS you do the minimum possible to get the x86 processor in a usable state, then you try to get as far away from it as possible.

Syntax checkup:
Wrong: OS's, IRQ's, zero'ing
Right: OSes, IRQs, zeroing
Locked