English

Funktioner, procedurer och metoder

En mycket viktig egenskap för ett programmeringsspråk är förmågan att bryta upp stora stycken kod i mindre delar. Detta är viktigt ur två avseenden. Dels för att öka läsbarheten. Det är mycket lättare att få överblick över ett litet stycke kod än det är att få överblick över ett stort stycke kod. Och dels för att man genom att bryta ut kod som används på flera ställen i ett program kan undvika att skriva samma kod flera gånger. Kodduplicering är i allmänhet dåligt och leder ofta till fel i program när man uppdaterar koden på ett ställe men glömmer ett annat.

Det normala sättet att dela upp kod i mindre delar är genom att skriva funktioner. Man kan se en funktion som ett litet miniprogram som ligger inuti det stora programmet. Funktioner hittar man i de flesta programmeringsspråk och de fungerar och ser ut ungefär på samma sätt överallt. I Java kallar man dem metoder men låt er inte luras av det, i praktiken är de exakt samma sak. En del språk har valt att skilja på funktioner, som kan returnera ett värde, och procedurer som inte returnerar något. Procedurer kan man hitta i bland annat Ada och Pascal. I språk som inte skiljer på funktioner och procedurer finns vanligen returtypen void för att markera en funktion som inte returnerar något värde.

Proceduren fångar kärnan i imperativ programmering. Ett stycke kod som inte returnerar något värde, men ändå utför något meningsfullt arbete. För att detta ska vara möjligt krävs ett globalt tillstånd som proceduren kan förändra eller möjligheten att utföra sidoeffekter.

Funktioner som behöver ta in data utifrån gör detta via sina argument. Argumenten deklareras normalt tillsammans med namnet på funktionen i funktionshuvudet. Om språket tillåter eller kräver en returtyp brukar även denna vara en del av funktionshuvudet.

Kodexempel i C

    Returtyp Namn ( Argument )                    int avrunda(float flyttal)
    {                                             {
       Lokala variabler                              int heltal;
       Funktionskropp                                heltal = (int)(flyttal + 0.5);
       Retursats                                     return heltal;
    }                                             }
  

Funktionen ovan har returtypen int och tar ett flyttal (float) som argument. Vi ser här att man kan deklarera lokala variabler i funktionerna. Att använda lokala variabler istället för globala är något man alltid ska sträva efter. I exemplet har jag deklarerat de lokala variablerna i början av funktionerna. Några av språken kräver att man gör så (Till exempel ANSI C och Pascal) medan andra tillåter att man inför nya variabler var som helst i koden (som C99, Java och PHP). Det är dock en god regel att alltid samla variabeldeklarationer i början av blocket de används i så att läsaren lätt kan hitta de variabler som är aktuella. I löst typade språk (som PHP) så deklarerar man egentligen aldrig variablerna, utan man använder dem bara rakt av.

En del programmeringsspråk (till exempel C) vill att man deklarerar nya funktioner ovanför den anropande funktionen i källkoden. Detta för att kompilatorn endast läser källkoden från början till slut en gång och endast tillåter att man anropar funktioner som den redan har sett. Andra språk (som Java) är inte lika noga med detta utan tillåter att man skriver metoder i godtycklig ordning.

Exempel i olika språk

Gemensamt för dessa exempel är att funktionerna har ett namn som används för att anropa funktionen från annan kod (avrunda) och argument som skickas med vid anropet (flyttal). Flera av exemplen har även en returtyp som talar om vad funktionen returnerar (i detta exempel ett heltal, integer). Det finns även språk där en funktion inte behöver ha någon specificerad returtyp, till exempel PHP.

Vi ser även ett exempel på en procedur i Ada. I detta exempel har jag valt att skriva ut resultatet.

Metod i Java

    Synlighet Returtyp Namn ( Argument )          public int avrunda(float flyttal)
    {                                             }
       Lokala variabler                              int heltal;
       Funktionskropp                                heltal = (int)(flyttal + 0.5);
       Retursats                                     return heltal;
    }                                             }
  

Funktion i Pascal

    'function' Namn ( Argument ) : Returtyp ;     function avrunda(flyttal : Float) : Int;
       Lokala variabler                              heltal : Int;
    begin                                         begin
       Funktionskropp                                heltal := Round(flyttal);
       Returvärdestilldelning                        avrunda := heltal;
    end;                                          end;
  

Funktion i Ada

    'function' Namn ( Argument ) 'return' Returtyp 'is'
                                                  function Avrunda(flyttal : Float) return Integer is
       Lokala variabler                              Heltal : Integer;
    'begin'                                       begin
       Funktionskropp                                Heltal := round(Flyttal);
       Retursats                                     return Heltal;
    'end' Namn;                                   end Avrunda;
  

Procedur i Ada

    'procedure' Namn ( Argument ) 'is'            procedure Avrunda(flyttal : Float) is
       Lokala variabler                              Heltal : Integer;
    'begin'                                       begin
       Funktionskropp                                Heltal := round(Flyttal);
                                                     Put_Line(Integer'Image(Heltal));
    'end' Namn;                                   end Avrunda;
  

Funktion i PHP

    'function' Namn ( Argument )                  function avrunda($flyttal)
    {                                             {
       Funktionskropp                                $heltal = (int)($flyttal + 0.5);
       Retursats                                     return $heltal;
    }                                             }