Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-devel / 2000-10

let Pascal stay Pascal

4 messages · 4 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Andrzej Gąsienica-Samek

Hi there!

I found something that drives me mad, and besides that I found a little bug in the compiler. First thing. I know Pascal really well and I had to write something in PPC. Simplest possible example looks like this:

var
  a: Integer;
function fact: Integer;
begin
  fact := 1;
  if a  0 then
  begin
    Dec(a);
    fact := (a+1)*fact;
  end;
end;
begin
  a := 3;
  Writeln(fact);
end.

Of course it will write 6, and give the variable "a" value 0. Not in PPC. I think that Pascal should stay Pascal, not C or C++. When you add C-like operators - ok. It'll be harder to read code for others, it'll not be easier to write code, but it's your choice. But all basic concepts must be in harmony with Wirth's Pascal. Result variable is really convenient, but in Delphi. Borland gives the result variable one name for all functions - "Result". It's much clearer and easier to use it than using function name all the time. It's easier than to change function name. But using the name of a parameter-less function not in assignment in that function must always call it. Let Pascal stay Pascal...

Now the small bug I mentioned at the beginning. Compiling program with PPC386 for Win95:

var
  a: Comp;
begin
  a := 2E40;
end.

gives error:

Free Pascal Compiler version 1.0.2 [2000/10/12] for i386 Copyright (c) 1993-2000 by Florian Klaempfl
Target OS: Win32 for i386
Compiling a.pas
a.pas(2,3) Note: Local variable A is assigned but never used Linking a.exe
Compilation aborted :6
Runtime error 207 at 0x0043DB68
0x0043DB68
0x0043DD55
0x004AAE50
0x004AA471

waiting for the appearence of unsigned and 64-bit integers, regards,
-Andrzej Gasienica-Samek

Jonas Maebe
Show quoted text 19 lines
var a: Integer; function fact: Integer; begin fact := 1; if a 0 then begin Dec(a); fact := (a+1)*fact; end; end; begin a := 3; Writeln(fact); end. Of course it will write 6, and give the variable "a" value 0. Not in PPC.

It does if you use -So (Turbo Pascal compatibility mode) or -Sd (Delphi compatibility more). You indeed have to write

fact := (a+1)*fact();

if you want "fact" to be called again in FPC or Obj-FPC mode, which is indeed quite C-like. One reason is that we also introduced the C++ feature "function overloading". So if you have

***
type
  tf = function: longint;
procedure p(f: tf);
begin
end;
procedure p(l: longint);
begin
end;
function f: longint;
begin
  p(f);
end;
***

then the compiler wouldn't know which overloaded procedure to call if f could also mean "call the function...

Use the -So (TP mode) command line switch if you want to disable all these features and as such the changes compared to TP.

Jonas

Peter Vreman
to Andrzej Gąsienica-Samek: Hi there! I found something that drives me mad, and besides that I found a little bug in…
you wrote 34 lines
Hi there! I found something that drives me mad, and besides that I found a little bug in the compiler. First thing. I know Pascal really well and I had to write something in PPC. Simplest possible example looks like this: var a: Integer; function fact: Integer; begin fact := 1; if a 0 then begin Dec(a); fact := (a+1)*fact; end; end; begin a := 3; Writeln(fact); end. Of course it will write 6, and give the variable "a" value 0. Not in PPC. I think that Pascal should stay Pascal, not C or C++. When you add C-like operators - ok. It'll be harder to read code for others, it'll not be easier to write code, but it's your choice. But all basic concepts must be in harmony with Wirth's Pascal. Result variable is really convenient, but in Delphi. Borland gives the result variable one name for all functions - "Result". It's much clearer and easier to use it than using function name all the time. It's easier than to change function name. But using the name of a parameter-less function not in assignment in that function must always call it. Let Pascal stay Pascal...

You've 3 possibilities:
1. Use -So on the commandline
2. Add {$mode tp} to the top of the source
3. Use 'fact:=(a+1)*fact();'

Next time read the documentation before saying thing like 'Let Pascal stay Pascal'

Show quoted text 25 lines
Now the small bug I mentioned at the beginning. Compiling program with PPC386 for Win95: var a: Comp; begin a := 2E40; end. gives error: Free Pascal Compiler version 1.0.2 [2000/10/12] for i386 Copyright (c) 1993-2000 by Florian Klaempfl Target OS: Win32 for i386 Compiling a.pas a.pas(2,3) Note: Local variable A is assigned but never used Linking a.exe Compilation aborted :6 Runtime error 207 at 0x0043DB68 0x0043DB68 0x0043DD55 0x004AAE50 0x004AA471 waiting for the appearence of unsigned and 64-bit integers,

They are already available !

Peter

S. Schicktanz

Hello!

Sorry for my messing up with this thread, especially since this is my first post here and I'm not even arguing FPC in the first place.

But anyway, I'd like to say a couple of words on the following:

Jonas Maebe wrote 19 lines
>var > a: Integer; > >function fact: Integer; >begin > fact := 1; > if a 0 then > begin > Dec(a); > fact := (a+1)*fact; > end; >end; > >begin > a := 3; > Writeln(fact); >end. > >Of course it will write 6, and give the variable "a" value 0. Not in PPC.

This is a citation from a previous message - and what it says is plain wrong, IMHO. This way of using a recursive function can only work occasionally, as it DEPENDS on the order of evaluation of the operands of an expression - which is to my knowledge NOT defined in (even With's original) definition of Pascal.
So this function MAY return the correct factorial of the entry value of a, it may return 0, or it may even return something weird, if by any means the oder of evaluation might change in midstream.

but wrote 8 lines
It does if you use -So (Turbo Pascal compatibility mode) or -Sd (Delphi compatibility more). You indeed have to write fact := (a+1)*fact(); if you want "fact" to be called again in FPC or Obj-FPC mode, which is indeed quite C-like. One reason is that we also introduced the C++ feature "function overloading". So if you have

[deleted]

I disagree.
Even with overloaded functions, the compiler CAN tell from the side of an assignment whether to CALL the function or to assign to it's result variable:

IF the function appears on the right side of an assignment THEN call it { if this can possibly be done from syntax } ELSE assign to it's result variable.

This might need a little refinement for functions returning pointers, which is an extension to Pascal though and where it would make real sense to present something new (like using <function name>() for a 0- parameter function to call on the left side of an assignment). Maybe even this is not needed, because to assign to the result of a recursive call of a function, you have to use the dereference operator (^) to give the compiler enough of a clue that it has to CALL the function instead of assigning to it's result variable. So the strategy for recursive function usage might be formulated as following:

IF the function appears on the right side of an assignment THEN call it { if this can possibly be done from syntax } ELSE
IF the function appears as part of an expression,
THEN call it { if this can possibly be done from syntax } ELSE assign to it's result variable.

This, of course, does not apply to function parameters (or variables), which is really what you presented:

Show quoted text 15 lines
type tf = function: longint; procedure p(f: tf); begin end; procedure p(l: longint); begin end; function f: longint; begin p(f); end;

Here you do need some means to tell apart recursive use and function call - but in the context of procedural parameters, which are an extension to Wirth's Pascal.

Thank you for reading.

----------------------------------------------------------- MfG, S. Schicktanz - acht zwei fuenf vier sieben Achmuehle / Eurasburg (derzeit noch) -----------------------------------------------------------