Some languages provide the facility to declare functions and subroutines through the use of function prototyping.



Task

Demonstrate the methods available for declaring prototypes within the language. The provided solutions should include:

 An explanation of any placement restrictions for prototype declarations
 A prototype declaration for a function that does not require arguments
 A prototype declaration for a function that requires two arguments
 A prototype declaration for a function that utilizes varargs
 A prototype declaration for a function that utilizes optional arguments
 A prototype declaration for a function that utilizes named parameters
 Example of prototype declarations for subroutines or procedures (if these differ from functions)
 An explanation and example of any special forms of prototyping not covered by the above


Languages that do not provide function prototyping facilities should be omitted from this task.




;Forward procedure declare defined with no arguments and that returns a string
Declare.s booTwo()
;Forward procedure declare defined with two arguments and that returns a float
Declare.f moo(x.f, y.f)
;Forward procedure declare with two arguments and an optional argument and that returns a float
Declare.f cmoo(x.f, y.f, m.f = 0)
 
;*** The following three procedures are defined before their first use.
;Procedure defined with no arguments and that returns a string
Procedure.s boo(): ProcedureReturn "boo": EndProcedure
;Procedure defined with two arguments and that returns an float
Procedure.f aoo(x.f, y.f): ProcedureReturn x + y: EndProcedure
;Procedure defined with two arguments and an optional argument and that returns a float
Procedure.f caoo(x.f, y.f, m.f = 1): ProcedureReturn (x + y) * m: EndProcedure
 
;ProtoType defined for any function with no arguments and that returns a string
Prototype.s showString() 
;Prototype defined for any function with two float arguments and that returns a float
Prototype.f doMath(x.f, y.f)
;ProtoType defined for any function with two float arguments and an optional float argument and that returns a float
Prototype.f doMathWithOpt(x.f, y.f, m.f = 0) 
 
Define a.f = 12, b.f = 5, c.f = 9
Define proc_1.showString, proc_2.doMath, proc_3.doMathWithOpt ;using defined ProtoTypes
If OpenConsole("ProtoTypes and Forward Declarations")
 
  PrintN("Forward Declared procedures:")
  PrintN(boo())
  PrintN(StrF(a, 2) + " * " + StrF(b, 2) + " = " + StrF(moo(a, b), 2))
  PrintN(StrF(a, 2) + " * " + StrF(b, 2) + " + " + StrF(c, 2) + " = " + StrF(cmoo(a, b, c), 2))
  PrintN(StrF(a, 2) + " * " + StrF(b, 2) + " = " + StrF(cmoo(a, b), 2))
 
  ;set pointers to second set of functions
  proc_1 = @boo()
  proc_2 = @aoo()
  proc_3 = @caoo()
 
  PrintN("ProtoTyped procedures (set 1):")
  PrintN(proc_1())
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_2(a, b), 2))
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " ? " + StrF(c, 2) + " = " + StrF(proc_3(a, b, c), 2))
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_3(a, b), 2))
 
  ;set pointers to second set of functions
  proc_1 = @booTwo()
  proc_2 = @moo()
  proc_3 = @cmoo()
 
  PrintN("ProtoTyped procedures (set 2):")
  PrintN(proc_1())
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_2(a, b), 2))
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " ? " + StrF(c, 2) + " = " + StrF(proc_3(a, b, c), 2))
  PrintN(StrF(a, 2) + " ? " + StrF(b, 2) + " = " + StrF(proc_3(a, b), 2))
 
 
  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  CloseConsole()
EndIf
 
 
;*** If the forward Declaration above are not used then the following Procedure
;definitions each have to be placed before the call to the respective procedure.
 
;Procedure defined with no arguments and that returns a string
Procedure.s booTwo()
  ProcedureReturn "booTwo"
EndProcedure
 
;Procedure defined with two arguments and that returns an float
Procedure.f moo(x.f, y.f)
  ProcedureReturn x * y
EndProcedure
 
;Procedure defined with two arguments and an optional argument and that returns an float
Procedure.f cmoo(x.f, y.f, m.f = 0)
  ProcedureReturn (x * y) + m
EndProcedure
 