Sign in Join

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

Mailing lists / fpc-pascal / 2011-12

Forward declarations

16 messages · 12 people · –

Reply by email Subscribe to this list Your subscription

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

Timothy Groves

Can anyone think of a situation in which you would *have* to use forward declared functions? I'm trying to come up with an example for such for my book, and I am drawing a blank.

Reply by email

Rainer Stratmann
to Timothy Groves
Timothy Groves wrote 6 lines
Can anyone think of a situation in which you would *have* to use forward declared functions? I'm trying to come up with an example for such for my book, and I am drawing a blank. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal
procedure fwproc; forward;
procedure myprocedure;
begin
 fwproc;
end;
procedure fwproc;
begin
end;

Reply by email

Michael Fuchs
to Rainer Stratmann
Rainer Stratmann wrote 11 lines
procedure fwproc; forward; procedure myprocedure; begin fwproc; end; procedure fwproc; begin end;

Bad example, in this case there is no need for implementing fwproc after myprocedure.

g
Michael

Reply by email

Mattias Gaertner
to Timothy Groves: Can anyone think of a situation in which you would *have* to use forward declared…
Can anyone think of a situation in which you would *have* to use forward declared functions? I'm trying to come up with an example for such for my book, and I am drawing a blank.

Traverse a html tree. For example with div and p nodes. Both div and p nodes can have children that are div and p nodes.

procedure Proc(RootNode: TNode);
  procedure ReadChildrenv(Node: TNode); forward;
  procedure ReadP(Node: TNode);
  begin
    ...
    ReadChildren(Node);
  end;
  procedure ReadDiv(Node: TNode);
  begin
    ...
    ReadChildren(Node);
  end;
  procedure ReadChildren(Node: TNode);
  begin
    for Child in Node do begin
      if Child is Div then ReadDiv(Child)
      else if Child is P then ReadP(Child);
    end;
  end;
begin
  ReadChildren(RootNode);
end;

Mattias

Reply by email

Anton Shepelev
to Timothy Groves: Can anyone think of a situation in which you would *have* to use forward declared…

Timothy Groves:

Can anyone think of a situation in which you would *have* to use forward declared functions? I'm trying to come up with an example for such for my book, and I am drawing a blank.

Pascal User Manual and Report says:

Procecure (function) identifiers may be used be-
fore the procedure (funtion) declaration if
there is a forward declaration. Forward decla-
rations are necessary to allow mutually recur-
sive procedures and functions that are not nest-
ed. The form is as follows:

        procedure Q(X:T); Forward;
        procedure P(Y:T);
        begin
          Q(A)
        end;
        procedure Q;
          { parameters and result types are not repeated }
        begin
          P(B)
        end;

But are "mutually recursive procedures and func- tions" necessary?

Anton

Reply by email

Mark Morgan Lloyd
to Timothy Groves: Can anyone think of a situation in which you would *have* to use forward declared…
Timothy Groves wrote
Can anyone think of a situation in which you would *have* to use forward declared functions? I'm trying to come up with an example for such for my book, and I am drawing a blank.

Classic recursive-descent parser? An expression is a sequence of terms, a term is a sequence of factors, one of the possibilities for a factor is a parenthesised expression.

However, there's probably still a way round that in a unit, by moving the first mention of one of those into the definition part. Or similarly you might be able to avoid it by using object definitions.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]

Reply by email

Timothy Groves
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote
However, there's probably still a way round that in a unit, by moving the first mention of one of those into the definition part. Or similarly you might be able to avoid it by using object definitions.

Absolutely. Because in both of those cases, you've already declared the procedure forward.

However, this section of the book is covering only ISO Pascal. I will be covering more advanced Pascal implementations (especially FPC) later on, but for the beginning section, I will be assuming no access to such.

Reply by email

Rainer Stratmann
to Anton Shepelev: Timothy Groves: Pascal User Manual and Report says: Procecure (function) identifiers may…
Anton Shepelev wrote
Fward  decla- rations  are  necessary to allow mutually recur- sive procedures and functions that are not nest- ed.

Forward declarations are the only option in special situations: If your program is huge and you only have this option to go on. Later you can clean up step by step the code.
I search my project but didn't find a forward declaration anymore (so I did my homework). But I am sure that at some point it was necessary.

Reply by email

Tony Whyman
to Timothy Groves: there is no other reason to use forward-declared procedures that I can think of, and I…

You could apply the same logic to the Pascal "label" statement. You can (and should) always use a different construct and you could therefore claim that the "label" statement is unnecessary because you cannot think of a situation where there is no alternative - but it exists. And sometimes it is convenient to use. You could even go further and say that the multiplication operator is unnecessary because you can always achieve the same thing through repeated summation. But, of course, it is more convenient to use multiplication.

Forward declared procedures exist in Jensen and Wirth Pascal and they exist for the purpose of allowing the convenience of those who sometimes find it easier or clearer to code an algorithm using mutual recursion. Why do you need a deeper explanation?

Tony Whyman
MWA Software

Timothy Groves wrote 8 lines
On 11-12-22 04:04 PM, Anton Shepelev wrote: > But are "mutually recursive procedures and functions" necessary? there is no other reason to use forward-declared procedures that I can think of, and I need *something* to demonstrate why you might need them. _______________________________________________ fpc-pascal maillist - http://lists.freepascal.org/mailman/listinfo/fpc-pascal

Reply by email

Rich Saunders
to Tony Whyman
Tony Whyman wrote
[explanation snipped] Why do you need a deeper explanation?

He is not asking for an explanation. (I think he knows what it is and can see why it might be useful.)

He is asking for a compelling example as a use case that illustrates the need for this language construct.

I haven't seen one in any replies yet.

Reply by email

Jürgen Hestermann
to Timothy Groves: Can anyone think of a situation in which you would *have* to use forward declared…
Can anyone think of a situation in which you would *have* to use forward declared functions? I'm trying to come up with an example for such for my book, and I am drawing a blank.

Well, maybe this one:

-------------------------------------------------------------------
type      SorterProcType  = function (String1,String2 : shortstring) :
boolean;
function CompareIt1(String1,String2 : shortstring) : boolean; forward;
function CompareIt2(String1,String2 : shortstring) : boolean; forward;
function CompareIt3(String1,String2 : shortstring) : boolean; forward;
const SortCriteria : SortProcType = CompareIt1;

-------------------------------------------------------------------

I don't know of another way that you can use one of the "CompareIt1/2/3" functions in the const declaration for "SortCriteria" (but maybe there is one).

Reply by email

Tomas Hajny
to Jürgen Hestermann
Jürgen Hestermann wrote 21 lines
Timothy Groves schrieb: > Can anyone think of a situation in which you would *have* to use > forward declared functions? I'm trying to come up with an example for > such for my book, and I am drawing a blank. > Well, maybe this one: ------------------------------------------------------------------- type SorterProcType = function (String1,String2 : shortstring) : boolean; function CompareIt1(String1,String2 : shortstring) : boolean; forward; function CompareIt2(String1,String2 : shortstring) : boolean; forward; function CompareIt3(String1,String2 : shortstring) : boolean; forward; const SortCriteria : SortProcType = CompareIt1; ------------------------------------------------------------------- I don't know of another way that you can use one of the "CompareIt1/2/3" functions in the const declaration for "SortCriteria" (but maybe there is one).

In this case, you could directly include the implementation with the CompareIt* declaration (unless CompareIt1 needs to access SortCriteria too, of course - that would change the picture).

Tomas

Reply by email

Jonas Maebe
to Timothy Groves: there is no other reason to use forward-declared procedures that I can think of, and I…
Timothy Groves wrote
On 11-12-22 04:04 PM, Anton Shepelev wrote: > But are "mutually recursive procedures and functions" necessary? think they are only unnecessary in the same sense that having

procedures/functions as a whole are unnecessary, just like for/do, while/do, repeat/until etc:
* functions/procedures can be implemented by manually implementing a stack
* loops can be implemented with a combination of if/then and goto
* mutually recursive procedures and functions can be implemented by merging them into a single procedure/function, combining their parameter lists and adding a boolean to select between the code bodies of the two functions (or again by implementing the recursion via manually implemented stacks)

The fact that something can also be implemented in a different way does not mean it's not appropriate or even necessary to write readable code.

Jonas

Reply by email

leledumbo
to Jonas Maebe

Back to high school time, I use it for turn based battle system for a game. I have two mutually (tail-)recursive procedures where one is the player movement decision (full with prompts) while the other is the enemy's (some AI calculation takes the decision). The battle could start ambushed (enemy first) or preemptive strike (player first). Because of this, the first procedure to call could be either of the two, and because both are mutually recursive, one needs to be declared forward.

View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Forward-declarations-tp5095571p5097085.html Sent from the Free Pascal - General mailing list .

Reply by email

Timothy Groves
to leledumbo
leledumbo wrote 9 lines
Back to high school time, I use it for turn based battle system for a game. I have two mutually (tail-)recursive procedures where one is the player movement decision (full with prompts) while the other is the enemy's (some AI calculation takes the decision). The battle could start ambushed (enemy first) or preemptive strike (player first). Because of this, the first procedure to call could be either of the two, and because both are mutually recursive, one needs to be declared forward.

Thanks! This is a bit more complex than I want for an example in my book, but you've twigged my imagination, and I can use this idea for an example that I can use.

Reply by email