dw_fluffos_v1/
dw_fluffos_v1/fluffos-1.22c11/
dw_fluffos_v1/fluffos-1.22c11/ChangeLog.old/
dw_fluffos_v1/fluffos-1.22c11/Win32/
dw_fluffos_v1/fluffos-1.22c11/compat/
dw_fluffos_v1/fluffos-1.22c11/compat/simuls/
dw_fluffos_v1/fluffos-1.22c11/include/
dw_fluffos_v1/fluffos-1.22c11/mudlib/
dw_fluffos_v1/fluffos-1.22c11/testsuite/
dw_fluffos_v1/fluffos-1.22c11/testsuite/clone/
dw_fluffos_v1/fluffos-1.22c11/testsuite/command/
dw_fluffos_v1/fluffos-1.22c11/testsuite/data/
dw_fluffos_v1/fluffos-1.22c11/testsuite/etc/
dw_fluffos_v1/fluffos-1.22c11/testsuite/include/
dw_fluffos_v1/fluffos-1.22c11/testsuite/inherit/
dw_fluffos_v1/fluffos-1.22c11/testsuite/inherit/master/
dw_fluffos_v1/fluffos-1.22c11/testsuite/log/
dw_fluffos_v1/fluffos-1.22c11/testsuite/single/
dw_fluffos_v1/fluffos-1.22c11/testsuite/single/tests/compiler/
dw_fluffos_v1/fluffos-1.22c11/testsuite/single/tests/efuns/
dw_fluffos_v1/fluffos-1.22c11/testsuite/single/tests/operators/
dw_fluffos_v1/fluffos-1.22c11/testsuite/u/
dw_fluffos_v1/fluffos-1.22c11/tmp/
dw_fluffos_v1/lib/
dw_fluffos_v1/lib/binaries/cmds/
dw_fluffos_v1/lib/binaries/cmds/creator/
dw_fluffos_v1/lib/binaries/cmds/living/
dw_fluffos_v1/lib/binaries/cmds/player/
dw_fluffos_v1/lib/binaries/d/admin/obj/
dw_fluffos_v1/lib/binaries/d/liaison/
dw_fluffos_v1/lib/binaries/global/virtual/
dw_fluffos_v1/lib/binaries/global/virtual/setup_compiler/
dw_fluffos_v1/lib/binaries/obj/handlers/autodoc/
dw_fluffos_v1/lib/binaries/obj/handlers/terrain_things/
dw_fluffos_v1/lib/binaries/obj/misc/
dw_fluffos_v1/lib/binaries/obj/misc/buckets/
dw_fluffos_v1/lib/binaries/obj/monster/
dw_fluffos_v1/lib/binaries/obj/reactions/
dw_fluffos_v1/lib/binaries/obj/reagents/
dw_fluffos_v1/lib/binaries/secure/cmds/creator/
dw_fluffos_v1/lib/binaries/secure/master/
dw_fluffos_v1/lib/binaries/std/
dw_fluffos_v1/lib/binaries/std/dom/
dw_fluffos_v1/lib/binaries/std/effects/object/
dw_fluffos_v1/lib/binaries/std/guilds/
dw_fluffos_v1/lib/binaries/std/languages/
dw_fluffos_v1/lib/binaries/std/races/
dw_fluffos_v1/lib/binaries/std/room/
dw_fluffos_v1/lib/binaries/std/room/basic/
dw_fluffos_v1/lib/binaries/std/shops/
dw_fluffos_v1/lib/binaries/std/shops/inherit/
dw_fluffos_v1/lib/binaries/www/
dw_fluffos_v1/lib/cmds/guild-race/
dw_fluffos_v1/lib/cmds/guild-race/crafts/
dw_fluffos_v1/lib/cmds/guild-race/other/
dw_fluffos_v1/lib/cmds/playtester/
dw_fluffos_v1/lib/cmds/playtester/senior/
dw_fluffos_v1/lib/d/admin/
dw_fluffos_v1/lib/d/admin/log/
dw_fluffos_v1/lib/d/admin/mapper/31-10-01/mapmaker/event/
dw_fluffos_v1/lib/d/admin/meetings/
dw_fluffos_v1/lib/d/admin/obj/
dw_fluffos_v1/lib/d/admin/room/we_care/
dw_fluffos_v1/lib/d/admin/save/
dw_fluffos_v1/lib/d/dist/
dw_fluffos_v1/lib/d/dist/mtf/
dw_fluffos_v1/lib/d/dist/pumpkin/
dw_fluffos_v1/lib/d/dist/pumpkin/chars/
dw_fluffos_v1/lib/d/dist/pumpkin/desert/
dw_fluffos_v1/lib/d/dist/pumpkin/gumboot/
dw_fluffos_v1/lib/d/dist/pumpkin/hospital/
dw_fluffos_v1/lib/d/dist/pumpkin/inherit/
dw_fluffos_v1/lib/d/dist/pumpkin/map/
dw_fluffos_v1/lib/d/dist/pumpkin/plain/
dw_fluffos_v1/lib/d/dist/pumpkin/pumpkin/
dw_fluffos_v1/lib/d/dist/pumpkin/save/
dw_fluffos_v1/lib/d/dist/pumpkin/squash/
dw_fluffos_v1/lib/d/dist/pumpkin/terrain/
dw_fluffos_v1/lib/d/dist/pumpkin/woods/
dw_fluffos_v1/lib/d/dist/start/
dw_fluffos_v1/lib/d/learning/TinyTown/buildings/
dw_fluffos_v1/lib/d/learning/TinyTown/map/
dw_fluffos_v1/lib/d/learning/TinyTown/roads/
dw_fluffos_v1/lib/d/learning/add_command/
dw_fluffos_v1/lib/d/learning/arms_and_weps/
dw_fluffos_v1/lib/d/learning/chars/
dw_fluffos_v1/lib/d/learning/cutnpaste/
dw_fluffos_v1/lib/d/learning/examples/npcs/
dw_fluffos_v1/lib/d/learning/examples/player_houses/npcs/
dw_fluffos_v1/lib/d/learning/examples/terrain_map/basic/
dw_fluffos_v1/lib/d/learning/functions/
dw_fluffos_v1/lib/d/learning/handlers/
dw_fluffos_v1/lib/d/learning/help_topics/npcs/
dw_fluffos_v1/lib/d/learning/help_topics/objects/
dw_fluffos_v1/lib/d/learning/help_topics/rcs_demo/
dw_fluffos_v1/lib/d/learning/help_topics/rooms/
dw_fluffos_v1/lib/d/learning/help_topics/rooms/crowd/
dw_fluffos_v1/lib/d/learning/help_topics/rooms/situations/
dw_fluffos_v1/lib/d/learning/items/
dw_fluffos_v1/lib/d/learning/save/
dw_fluffos_v1/lib/d/liaison/
dw_fluffos_v1/lib/d/liaison/NEWBIE/doc/
dw_fluffos_v1/lib/d/liaison/NEWBIE/save/oldlog/
dw_fluffos_v1/lib/db/
dw_fluffos_v1/lib/doc/
dw_fluffos_v1/lib/doc/creator/
dw_fluffos_v1/lib/doc/creator/autodoc/include/reaction/
dw_fluffos_v1/lib/doc/creator/autodoc/include/ritual_system/
dw_fluffos_v1/lib/doc/creator/autodoc/include/talker/
dw_fluffos_v1/lib/doc/creator/autodoc/include/terrain_map/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/baggage/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/clock/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/clothing/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/cont_save/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/corpse/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/money/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/monster/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/scabbard/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/service_provider/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/state_changer/
dw_fluffos_v1/lib/doc/creator/autodoc/obj/wand/
dw_fluffos_v1/lib/doc/creator/autodoc/std/book_dir/
dw_fluffos_v1/lib/doc/creator/autodoc/std/key/
dw_fluffos_v1/lib/doc/creator/autodoc/std/learning/
dw_fluffos_v1/lib/doc/creator/autodoc/std/map/
dw_fluffos_v1/lib/doc/creator/autodoc/std/race/
dw_fluffos_v1/lib/doc/creator/autodoc/std/weapon_logic/
dw_fluffos_v1/lib/doc/creator/files/
dw_fluffos_v1/lib/doc/creator/policy/
dw_fluffos_v1/lib/doc/creator/room/
dw_fluffos_v1/lib/doc/effects/
dw_fluffos_v1/lib/doc/ideas/
dw_fluffos_v1/lib/doc/known_command/
dw_fluffos_v1/lib/doc/lpc/basic_manual/
dw_fluffos_v1/lib/doc/lpc/intermediate/
dw_fluffos_v1/lib/doc/new/add_command/
dw_fluffos_v1/lib/doc/new/handlers/
dw_fluffos_v1/lib/doc/new/living/
dw_fluffos_v1/lib/doc/new/living/race/
dw_fluffos_v1/lib/doc/new/living/spells/
dw_fluffos_v1/lib/doc/new/player/
dw_fluffos_v1/lib/doc/new/room/guild/
dw_fluffos_v1/lib/doc/new/room/outside/
dw_fluffos_v1/lib/doc/new/room/storeroom/
dw_fluffos_v1/lib/doc/object/
dw_fluffos_v1/lib/doc/playtesters/
dw_fluffos_v1/lib/doc/policy/
dw_fluffos_v1/lib/doc/weapons/
dw_fluffos_v1/lib/global/handlers/
dw_fluffos_v1/lib/global/virtual/setup_compiler/
dw_fluffos_v1/lib/include/
dw_fluffos_v1/lib/include/cmds/
dw_fluffos_v1/lib/include/effects/
dw_fluffos_v1/lib/include/npc/
dw_fluffos_v1/lib/include/shops/
dw_fluffos_v1/lib/net/daemon/chars/
dw_fluffos_v1/lib/net/inherit/
dw_fluffos_v1/lib/net/intermud3/
dw_fluffos_v1/lib/net/intermud3/services/
dw_fluffos_v1/lib/net/obj/
dw_fluffos_v1/lib/net/save/
dw_fluffos_v1/lib/net/smnmp/
dw_fluffos_v1/lib/net/snmp/
dw_fluffos_v1/lib/obj/amulets/
dw_fluffos_v1/lib/obj/b_day/
dw_fluffos_v1/lib/obj/examples/
dw_fluffos_v1/lib/obj/food/alcohol/
dw_fluffos_v1/lib/obj/food/chocolates/
dw_fluffos_v1/lib/obj/food/fruits/
dw_fluffos_v1/lib/obj/food/meat/
dw_fluffos_v1/lib/obj/food/nuts/
dw_fluffos_v1/lib/obj/food/seafood/
dw_fluffos_v1/lib/obj/food/vegetables/
dw_fluffos_v1/lib/obj/fungi/
dw_fluffos_v1/lib/obj/furnitures/artwork/
dw_fluffos_v1/lib/obj/furnitures/bathroom/
dw_fluffos_v1/lib/obj/furnitures/beds/
dw_fluffos_v1/lib/obj/furnitures/cabinets/
dw_fluffos_v1/lib/obj/furnitures/chairs/
dw_fluffos_v1/lib/obj/furnitures/chests/
dw_fluffos_v1/lib/obj/furnitures/clocks/
dw_fluffos_v1/lib/obj/furnitures/crockery/
dw_fluffos_v1/lib/obj/furnitures/cupboards/
dw_fluffos_v1/lib/obj/furnitures/cushions/
dw_fluffos_v1/lib/obj/furnitures/fake_plants/
dw_fluffos_v1/lib/obj/furnitures/lamps/
dw_fluffos_v1/lib/obj/furnitures/mirrors/
dw_fluffos_v1/lib/obj/furnitures/outdoor/
dw_fluffos_v1/lib/obj/furnitures/safes/
dw_fluffos_v1/lib/obj/furnitures/shelves/
dw_fluffos_v1/lib/obj/furnitures/sideboards/
dw_fluffos_v1/lib/obj/furnitures/sofas/
dw_fluffos_v1/lib/obj/furnitures/stoves/
dw_fluffos_v1/lib/obj/furnitures/tables/
dw_fluffos_v1/lib/obj/furnitures/wardrobes/
dw_fluffos_v1/lib/obj/handlers/
dw_fluffos_v1/lib/obj/handlers/autodoc/
dw_fluffos_v1/lib/obj/jewellery/anklets/
dw_fluffos_v1/lib/obj/jewellery/bracelets/
dw_fluffos_v1/lib/obj/jewellery/earrings/
dw_fluffos_v1/lib/obj/jewellery/misc/
dw_fluffos_v1/lib/obj/jewellery/necklaces/
dw_fluffos_v1/lib/obj/jewellery/rings/
dw_fluffos_v1/lib/obj/media/
dw_fluffos_v1/lib/obj/misc/buckets/
dw_fluffos_v1/lib/obj/misc/jars/
dw_fluffos_v1/lib/obj/misc/papers/
dw_fluffos_v1/lib/obj/misc/player_shop/
dw_fluffos_v1/lib/obj/misc/shops/
dw_fluffos_v1/lib/obj/misc/traps/
dw_fluffos_v1/lib/obj/monster/
dw_fluffos_v1/lib/obj/monster/godmother/
dw_fluffos_v1/lib/obj/monster/transport/
dw_fluffos_v1/lib/obj/plants/inherit/
dw_fluffos_v1/lib/obj/potions/
dw_fluffos_v1/lib/open/boards/
dw_fluffos_v1/lib/save/autodoc/
dw_fluffos_v1/lib/save/bank_accounts/
dw_fluffos_v1/lib/save/boards/frog/
dw_fluffos_v1/lib/save/books/bed_catalog/
dw_fluffos_v1/lib/save/creators/
dw_fluffos_v1/lib/save/mail/
dw_fluffos_v1/lib/save/mail/p/
dw_fluffos_v1/lib/save/newsrc/b/
dw_fluffos_v1/lib/save/newsrc/c/
dw_fluffos_v1/lib/save/newsrc/d/
dw_fluffos_v1/lib/save/newsrc/f/
dw_fluffos_v1/lib/save/newsrc/p/
dw_fluffos_v1/lib/save/newsrc/s/
dw_fluffos_v1/lib/save/newsrc/w/
dw_fluffos_v1/lib/save/players/c/
dw_fluffos_v1/lib/save/players/d/
dw_fluffos_v1/lib/save/players/g/
dw_fluffos_v1/lib/save/players/p/
dw_fluffos_v1/lib/save/players/s/
dw_fluffos_v1/lib/save/soul/data/
dw_fluffos_v1/lib/save/tasks/
dw_fluffos_v1/lib/save/vaults/
dw_fluffos_v1/lib/secure/cmds/lord/
dw_fluffos_v1/lib/secure/config/
dw_fluffos_v1/lib/secure/items/
dw_fluffos_v1/lib/secure/player/
dw_fluffos_v1/lib/soul/
dw_fluffos_v1/lib/soul/i/
dw_fluffos_v1/lib/soul/j/
dw_fluffos_v1/lib/soul/k/
dw_fluffos_v1/lib/soul/o/
dw_fluffos_v1/lib/soul/q/
dw_fluffos_v1/lib/soul/to_approve/
dw_fluffos_v1/lib/soul/u/
dw_fluffos_v1/lib/soul/v/
dw_fluffos_v1/lib/soul/wish_list/
dw_fluffos_v1/lib/soul/y/
dw_fluffos_v1/lib/soul/z/
dw_fluffos_v1/lib/std/creator/
dw_fluffos_v1/lib/std/effects/
dw_fluffos_v1/lib/std/effects/attached/
dw_fluffos_v1/lib/std/effects/external/
dw_fluffos_v1/lib/std/effects/fighting/
dw_fluffos_v1/lib/std/effects/other/
dw_fluffos_v1/lib/std/environ/
dw_fluffos_v1/lib/std/guilds/
dw_fluffos_v1/lib/std/hospital/
dw_fluffos_v1/lib/std/house/
dw_fluffos_v1/lib/std/house/onebedhouse/
dw_fluffos_v1/lib/std/house/onebedhut/
dw_fluffos_v1/lib/std/house/tworoomflat/
dw_fluffos_v1/lib/std/languages/
dw_fluffos_v1/lib/std/liquids/
dw_fluffos_v1/lib/std/nationality/
dw_fluffos_v1/lib/std/nationality/accents/
dw_fluffos_v1/lib/std/nationality/accents/national/
dw_fluffos_v1/lib/std/nationality/accents/regional/
dw_fluffos_v1/lib/std/npc/goals/
dw_fluffos_v1/lib/std/npc/goals/basic/
dw_fluffos_v1/lib/std/npc/goals/misc/
dw_fluffos_v1/lib/std/npc/inherit/
dw_fluffos_v1/lib/std/npc/plans/
dw_fluffos_v1/lib/std/npc/plans/basic/
dw_fluffos_v1/lib/std/outsides/
dw_fluffos_v1/lib/std/races/shadows/
dw_fluffos_v1/lib/std/room/basic/topography/
dw_fluffos_v1/lib/std/room/controller/
dw_fluffos_v1/lib/std/room/controller/topography/
dw_fluffos_v1/lib/std/room/furniture/games/
dw_fluffos_v1/lib/std/room/furniture/inherit/
dw_fluffos_v1/lib/std/room/inherit/carriage/
dw_fluffos_v1/lib/std/room/inherit/topography/
dw_fluffos_v1/lib/std/room/punishments/
dw_fluffos_v1/lib/std/room/topography/area/
dw_fluffos_v1/lib/std/room/topography/iroom/
dw_fluffos_v1/lib/std/room/topography/milestone/
dw_fluffos_v1/lib/std/shadows/
dw_fluffos_v1/lib/std/shadows/attached/
dw_fluffos_v1/lib/std/shadows/curses/
dw_fluffos_v1/lib/std/shadows/disease/
dw_fluffos_v1/lib/std/shadows/fighting/
dw_fluffos_v1/lib/std/shadows/room/
dw_fluffos_v1/lib/std/shops/controllers/
dw_fluffos_v1/lib/std/shops/objs/
dw_fluffos_v1/lib/std/shops/player_shop/
dw_fluffos_v1/lib/std/shops/player_shop/office_code/
dw_fluffos_v1/lib/std/socket/
dw_fluffos_v1/lib/www/
dw_fluffos_v1/lib/www/external/autodoc/
dw_fluffos_v1/lib/www/external/java/telnet/Documentation/
dw_fluffos_v1/lib/www/external/java/telnet/Documentation/images/
dw_fluffos_v1/lib/www/external/java/telnet/examples/
dw_fluffos_v1/lib/www/external/java/telnet/tools/
dw_fluffos_v1/lib/www/pics/
dw_fluffos_v1/lib/www/secure/creator/
dw_fluffos_v1/lib/www/secure/editors/
dw_fluffos_v1/lib/www/secure/survey_results/
A Brief Introduction to LPC  -  Functions
Ae First Rough Draft

Drakkos - 2/12/2000

N.B     -       This is a work in project... a living document if
                you like.  If it appears to be dead when you view
                it, don't worry.  It's most likely just playing
                possum.

==============================================================================
Concepts still to be covered:

Not sure... perhaps nothing.
==============================================================================

All of the objects you write on Discworld will use functions.  Writing 
a complex program as a single, monolithic chunk of code is extremely
time-consuming and inefficient.  Instead, the principle of 'divide and 
conquer' can be adapted to programming to break programs into smaller, more 
manageable chunks.  In LPC, these chunks are known as 'functions', or
'methods'.

On Discworld, new objects are generally written using a combination of new
functions written by the coding creator, and the standard functions available 
as a part of the mudlib and the driver.  The mudlib and driver offer a nice 
range of functions for achieving large amounts of functionality, but in order 
to create new behaviour it will be necessary to write your own, unique 
functions.  The range of functions available as standard make the creator's 
job easier since it is not necessary to continually re-invent the wheel.


Function Categories
===================

These standard functions fall into three categories on Discworld... Efuns,
Lfuns and Sfuns:

Efun -  'Efun' is short for 'External function'.  Essentially, these 
        functions define the 'driver' for the MUD.  These functions are 
        impossible to duplicate in LPC code, and therefore must be defined 
        'externally' in the driver.  Since these functions are defined
        independently of any LPC code, they can be used globally over
        the whole MUD.  For example, the efun this_player() returns the
        object responsible for calling a function.  This cannot be
        simulated using LPC, and so must be defined in the driver.
        
Lfun -  An 'Lfun', on the other hand, is a function that is 'inherited'
        from a specific object.  Only files which inherit the object,
        or have the function defined locally, can use the function.  
        For example, the function add_exit() is defined in the object 
        /std/room.  Only objects which, at some point, inherit 'std/room' 
        (or have the function coded locally) can use the function.
         
Sfuns - 'Sfun', or 'Simulated Functions', are like Efuns in that they
        can be used globally, but are not defined in the driver.  Instead,
        they are made up of LPC code stored in an object called 
        /secure/simul_efun.c.  As far as most creators need know, however, 
        there is no difference between using an efun and an sfun... the 
        functionality is purely transparent.

Typically any object on Discworld may utilise all three types of function
to achieve the desired aims.


Function Arguments
==================

Functions allow the creator to modularise a program by breaking code up into
segments that can be executed, or called, independently of the main program.  
In order to make functions flexible, they usually work with a list of
'arguments', and return a value based on what the function does and the 
arguments that are 'passed in' to the function.  Arguments provide the means 
of passing information between functions.  Note that unless a function is
qualified as 'varargs' (more on this later), you must pass in the correct
number of arguments.


Defining Functions
==================

Let us look at an example of how a simple function works.  Let us consider a
function called 'sum' that takes two numbers as arguments, and returns the 
sum of these two numbers:

    int sum(int x, int y) {
        return (x + y);
    }

Now what does all that mean?  Let's look at it in stages, starting with the 
first line:


    int         sum         (int x, int y)    {
     |           |                 |          |
    [1]         [2]               [3]        [4]


[1] This is the 'return type'... the type of the value the function sends 
    back when it is finished executing.  For more information on the
    different kinds of return type, see part 2 of this introductory tutorial.
    Note that even if you do not want to actually return a value, you must
    explicitly declare your function as 'void'.
[2] The name of the function.  This is the name by which the function will be 
    'called' by code.  Functions must be called with their name and any 
    arguments they take.    
[3] This is the parameter list.  This is the list of information required by 
    the function before it can execute.  In this case, two variables of type
    int are passed in to the function.  The letter after the variable type (x 
    and y respectively) are the names by which these values can be accessed
    within the function.  It doesn't matter what these names are, provided
    they are not words already reserved by the LPC language... they are simply 
    labels that can be used to manipulate data.
[4] This is the starting brace of the function, indicating where the block of
    code that belongs to the function begins.
    
Now the second line:


    return      (x + y);
      |            |
     [5]          [6]
     
[5] The 'return' keyword is used to halt execution of a function and send the
    value that follows back to where the code was called.  All functions except
    those that are defined to return a 'void' or 'int' value must explicitly
    return a value of the correct type.  Functions declared as void cannot
    return a value... if execution of the function is to halt, a return 
    statement by itself must be placed on the line.  Functions of type int
    will return 0 by default if a specific return value is omitted.
[6] This is the expression that handles the functionality of this particular
    function... it simply adds the contents of the value labelled 'y' to the
    contents of the value labelled 'x'.  The expression here could just as
    easily be an explicit value, a variable itself, or even another function.
    For example, 'return 1;', 'return x', or 'return some_other_function()'
    are all valid return types, and will return 1, the contents of variable 
    x, and whatever the function 'some_other_function()' returns, 
    respectively.
    
And finally, the third line (a simple line!):


       }
       |
      [7]
      
[7] This is the closing brace of the function, indicating where this 
    particular block of code ends.
        
        
So there it is, our first function!  And how do we use it?  Well if the
function was defined locally in an object (more on this later), we'd use
it like so:

    sum(5 , 8);
     |     |
    [8]   [9]
           
    
[8] The name of the function, which corresponds to number [2] above.
[9] The parameter list, which corresponds to number [3] above.  In this case,
    value 'x' would be 5, and value 'y' would be 8.

Which would return the value of five + eight.  Remember, though, if you don't 
actually do anything with the returned value, nothing will happen.  The
returned value (thirteen) will simply dissipate into the ether.  For this
reason, we'd either use the result instantly in a more complex expression,
or store it in an appropriate variable until we need it:

    int bing;
    
    bing = sum(5 , 8);


Function Prototypes
===================

If the function is defined in code before it actually gets called by anything,
then this will work perfectly.  But if it isn't, you will get an error when you
try and load the object saying that 'sum()' is an undefined function.  This
is because LPC will not realise that a function has actually been defined if
it is called before it ever sees it.  For example, we have two functions, 
one that calls another:

    void bing() {
        bong();
    }
    
    void bong() {
        printf ("bing!\n");
    }
    
When we attempt to compile this object, the driver comes to the function call
to bong() in bing(), and thinks to itself 'I don't know what this function 
is.  I better stop compiling'.  It then spits out an error message saying it
doesn't know the function.  However, if the order of the functions were 
reversed in the code:

    void bong() {
        printf ("bing!\n");
    }

    void bing() {
        bong();
    }
    
The driver has already seen the function bong() before it is called in bing(),
and so is quite happy to compile normally.

Of course, this would be extremely awkward if you had to significantly 
restructure the format of your code every time you wanted to add a new 
function to be called.  You'd have to make sure that all functions that are
called within other functions are defined before the compiler ever sees them.
Nightmare!
      
To avoid this, a 'function prototype' should be included at the top of the 
file... essentially, this tells the MUD what the returned type of a particular 
function is, what its name is, and what arguments it requires and in what 
order.  This function prototype is used by the MUD to validate function 
calls, and also checks to make sure that the parameter list of the function 
prototype matches with the parameter list of the actual function, and makes 
sure their return types are the same.  For our 'sum' function, the function 
prototype would look like:

    int sum(int, int);.

Almost exactly the same as the first line of the function above, but with two
subtle differences.  One is that the parameter list has no labels to identify
the values in the function: we are not interested in what the values are at 
this point, only what data type they are going to be.  You can include the
labels if you like, but the MUD will simply ignore them when it compiles the
object.  The second difference is that the line does not end with a brace 
'{', but with a semi-colon ';'.  This is because the function prototype isn't
a function itself, but a statement telling the MUD what form the function 
takes.

If your function prototype disagrees with your function definition, then
the MUD will throw up an error when you try and load the object. 


Function Scope
==============

Now, what did we mean by 'defined locally in an object'?

Well, like variables, functions also have a 'scope'.  If a function is
defined in the same object that calls it, then it is said to be defined
locally.  It is also said to be local if the function is inherited
by an object.  In both of these cases, the function is an lfun.  If a function 
is located in the driver, it is said to be an 'external' function... it exists 
independently of the object and can thus be called anywhere.  In both of these 
cases, a function is called using the calling convention shown above.

However, sometimes it is necessary to call a function that belongs to another 
object.  To take an example, let's say we want to get the name of a player and 
store it in another object.  It is necessary to call these functions in a 
different manner.  There are two normal ways of doing this. One is to use the 
call_other efun... this can take a number of forms, but the simplest would be:

    call_other(object name, ({"name of function", parameter 1, parameter 2,   
                ...}));
                
Yikes!  There is, however, a much easier way, and that is to use the -> 
operator on the object:

    object_name->function(arguments);
    
So, say we have an object variable called 'ob' that points to a player object.  
If we want to get the name of this object, we can use the line:

    ob->query_name();
    
Which simply means, 'call the function 'query_name' on the object labelled 
'ob' with no arguments'.  Query_name() doesn't actually take arguments, but
if we were calling a function that did... for example, adjust_xp, we 
would simply pass the arguments in between the brackets as above: 
ob->adjust_xp (1000).

Note that we don't need to do this with sfuns and efuns... we always use 
the function_name (arguments) format, since they are in scope to all objects.


Chapter Summary
===============

In this chapter, we looked at how functions work on Discworld, and how the 
three categories of functions: lfuns, efuns, and sfuns, may be used within
code.  We also looked at how we may pass information into a function through
the use of argument lists, and how we may return data from a function for
later use.

-   There are three types of functions on Discworld. Lfuns, efuns, and sfuns.
-   Lfuns are 'local functions', and are defined locally in an object or in
    an object inherited by the current object.
-   Efuns are 'external functions', and are defined in the driver of the 
    MUD.
-   Sfuns are 'simulated functions', and are written in LPC, although they
    may be accessed globally like efuns.
-   Function definitions take the form of return_type name (argument_list)
-   Code belonging to a function must be enclosed in braces: { }.
-   Functions with a return type defined must 'return' an appropriate value.
    Void functions may simply 'return'.  Integer functions will return 0
    unless another return is specified.    
-   Functions that are called before their code is defined will cause the
    driver to throw up an undefined function parse error.
-   Function prototypes may be included at the start of an object to ensure
    the driver is aware the code is defined after a function is called.
-   Like variables, functions have a scope.  Efuns and sfuns may be called
    simply by the name of the function and any arguments.  Lfuns local to
    an object may be called the same way.  Lfuns in other functions must
    be accessed with either the call_other efun, or the -> object operator.