Alex Alex - 8 months ago 77
Pascal Question

How do i call a function within a function?

i'm creating a mini program in pascal to read music albums. The problem i'm facing is calling the readTracks() function within my readAlbum() function. Any help would be great, thank you :)

The current error when executing the code is:
Error: Incompatible types: got "albumRecord" expected "albumRecord.Dynamic Array Of trackRecord

type

trackRecord = record
trackName:string;
fileLocation: string;
end;

albumRecord = record
albumName:string;
tracks: array of trackRecord;
end;

function readTracks():albumRecord;
var
i:Integer;
numOfTracks:Integer;
begin
numOfTracks := readInteger('Enter number of tracks: ');
setLength(result.tracks, numOfTracks);

for i:= 0 to high(result.tracks)do
begin
Writeln('Enter Track ',i+1,' Details: ');
result.tracks[i].trackName := readString('Enter track name: ');
result.tracks[i].fileLocation := readString('Enter file
location: ');
end;

end;

function readAlbum (prompt: string): albumRecord;
begin
result.albumName := readString('Enter Album Name: ');
result.tracks := readTracks();
end;

Answer Source

I think you have managed to confuse yourself by the way you have declared your albumRecord.Tracks. What you should have done is to declare a trackArray type and declared your readTracks to return an instance of this array type.

Your main problem was that your readAlbum returns an albumRecord, but you had set up its tracks field to be assigned from readTracks, which returns the wrong type, i.e. albumRecord, rather than an array of tracks.

Put another way, as you have declared readAlbum to return an albumRecord, the compiler will generate code which, on entry to the function, sets up an instance of albumRecord on the stack, which is eventually returned as the return value of the function when it completes. Your code in the function is simply to fill out the fields of this record, not create another instance of it as your result.tracks := readTracks() would have done, given how you had declared readTracks.

The code below changes the declarations and code inside readTracks so that it does what you intend.

uses TerminalUserInput;

type

trackRecord = record
    trackName:string;
    fileLocation: string;
end;

trackArray = array of trackRecord;

albumRecord = record
    albumName:string;
    tracks: trackArray;
end;

function readTracks():trackArray;
var
    i:Integer;
    numOfTracks:Integer;
begin
    numOfTracks := readInteger('Enter number of tracks: ');
    setLength(result, numOfTracks);

    for i:= 0 to high(result)do
    begin
        Writeln('Enter Track ',i+1,' Details: ');
        result[i].trackName := readString('Enter track name: ');
        result[i].fileLocation := readString('Enter file location: ');
    end;

end;

function readAlbum (prompt: string): albumRecord;
begin
    result.albumName := readString('Enter Album Name: ');
    result.tracks := readTracks();
end;

begin
  readAlbum('New album');
end.

Btw, I think you would find your code much clearer, when you come back to it after a while if you got into the habit of using a naming convention for declarations of record- and array types which distinguishes them from instances of them. One convention is to precede the type-name with a 'T', so your would be TtrackRecord, TalbumRecord, TtrackArray.

Also btw, in your q you say

The current error when executing the code is: Error: Incompatible types

Actually, that is not quite correct. The error occurs while the compiler is compiling the code, not when your code is executing. This is an important difference: your error is known as a compile-time error, whereas one which occurs when your program is executing (which it can only do once it has been successfully compiled) is known as a run-time error.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download