functions.rst 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. .. _functions:
  2. =================
  3. Functions
  4. =================
  5. .. index::
  6. single: Functions
  7. Functions are first class values like integer or strings and can be stored in table slots,
  8. local variables, arrays and passed as function parameters.
  9. Functions can be implemented in Squirrel or in a native language with calling conventions
  10. compatible with ANSI C.
  11. --------------------
  12. Function declaration
  13. --------------------
  14. .. index::
  15. single: Function Declaration
  16. Functions are declared through the function expression::
  17. local a = function(a, b, c) { return a + b - c; }
  18. or with the syntactic sugar::
  19. function ciao(a,b,c)
  20. {
  21. return a+b-c;
  22. }
  23. that is equivalent to::
  24. this.ciao <- function(a,b,c)
  25. {
  26. return a+b-c;
  27. }
  28. a local function can be declared with this syntactic sugar::
  29. local function tuna(a,b,c)
  30. {
  31. return a+b-c;
  32. }
  33. that is equivalent to::
  34. local tuna = function(a,b,c)
  35. {
  36. return a+b-c;
  37. }
  38. is also possible to declare something like::
  39. T <- {}
  40. function T::ciao(a,b,c)
  41. {
  42. return a+b-c;
  43. }
  44. //that is equivalent to write
  45. T.ciao <- function(a,b,c)
  46. {
  47. return a+b-c;
  48. }
  49. //or
  50. T <- {
  51. function ciao(a,b,c)
  52. {
  53. return a+b-c;
  54. }
  55. }
  56. ^^^^^^^^^^^^^^^^^^
  57. Default Paramaters
  58. ^^^^^^^^^^^^^^^^^^
  59. .. index::
  60. single: Function Default Paramaters
  61. Squirrel's functions can have default parameters.
  62. A function with default parameters is declared as follows: ::
  63. function test(a,b,c = 10, d = 20)
  64. {
  65. ....
  66. }
  67. when the function *test* is invoked and the parameter c or d are not specified,
  68. the VM autometically assigns the default value to the unspecified parameter. A default parameter can be
  69. any valid squirrel expression. The expression is evaluated at runtime.
  70. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  71. Function with variable number of paramaters
  72. ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  73. .. index::
  74. single: Function with variable number of paramaters
  75. Squirrel's functions can have variable number of parameters(varargs functions).
  76. A vararg function is declared by adding three dots (`...`) at the end of its parameter list.
  77. When the function is called all the extra parameters will be accessible through the *array*
  78. called ``vargv``, that is passed as implicit parameter.
  79. ``vargv`` is a regular squirrel array and can be used accordingly.::
  80. function test(a,b,...)
  81. {
  82. for(local i = 0; i< vargv.len(); i++)
  83. {
  84. ::print("varparam "+i+" = "+vargv[i]+"\n");
  85. }
  86. foreach(i,val in vargv)
  87. {
  88. ::print("varparam "+i+" = "+val+"\n");
  89. }
  90. }
  91. test("goes in a","goes in b",0,1,2,3,4,5,6,7,8);
  92. ---------------
  93. Function calls
  94. ---------------
  95. .. index::
  96. single: Function calls
  97. ::
  98. exp:= derefexp '(' explist ')'
  99. The expression is evaluated in this order: derefexp after the explist (arguments) and at
  100. the end the call.
  101. A function call in Squirrel passes the current environment object *this* as a hidden parameter.
  102. But when the function was immediately indexed from an object, *this* shall be the object
  103. which was indexed, instead.
  104. If we call a function with the syntax::
  105. mytable.foo(x,y)
  106. the environment object passed to 'foo' as *this* will be 'mytable' (since 'foo' was immediately indexed from 'mytable')
  107. Whereas with the syntax::
  108. foo(x,y) // implicitly equivalent to this.foo(x,y)
  109. the environment object will be the current *this* (that is, propagated from the caller's *this*).
  110. It may help to remember the rules in the following way:
  111. foo(x,y) ---> this.foo(x,y)
  112. table.foo(x,y) ---> call foo with (table,x,y)
  113. It may also help to consider why it works this way: it's designed to assist with object-oriented style.
  114. When calling 'foo(x,y)' it's assumed you're calling another member of the object (or of the file) and
  115. so should operate on the same object.
  116. When calling 'mytable.foo(x,y)' it's written plainly that you're calling a member of a different object.
  117. ---------------------------------------------
  118. Raw calls
  119. ---------------------------------------------
  120. .. index::
  121. single: Raw calls
  122. It is possible to call a function overriding the default calling semantics by utilizing the keywork *rawcall*.
  123. Rawcall allows to invoke a function specifying the *this* object explicitly::
  124. local retval = rawcall(functionobj,thisobj,parameters);
  125. for example::
  126. local env = {}
  127. function test(a,b) {
  128. return a + b;
  129. }
  130. local ret = rawcall(test,env,1,2) //passes the table env as 'this' to the function test
  131. ---------------------
  132. Post-call Initializer
  133. ---------------------
  134. Since version 3.2 Squirrel offers a syntactic sugar to initialize the object returned by a function call(anf class instance creation).
  135. The post-call initializer has the following syntax::
  136. function test() {
  137. local retval = { x = 0, y = 0};
  138. return retval;
  139. }
  140. local ret1 = test() { x = 10, y = 20 }
  141. local ret2 = test() { x = 30, y = 40 }
  142. that is equivalent to::
  143. function test() {
  144. local retval = { x = 0, y = 0};
  145. return retval;
  146. }
  147. local ret1 = test() { x = 10, y = 20 }
  148. ret1.x = 10;
  149. ret1.y = 20;
  150. local ret2 = test() { x = 30, y = 40 }
  151. ret1.x = 30;
  152. ret1.y = 40;
  153. this is also usable with classes::
  154. class vector3 {
  155. x = 0;
  156. y = 0;
  157. z = 0;
  158. }
  159. local v0 = vector3() { x = 1, y = 2, z = 3 };
  160. local v2 = vector3() { x = 4, y = 5, z = 6 };
  161. and can be nested::
  162. class entity {
  163. position = null;
  164. direction = null;
  165. }
  166. local ret = entity() {
  167. position = vector3() { x = 1, y = 2, z = 3 }
  168. direction = vector3() { x = 0, y = 1, z = 0 }
  169. }
  170. ---------------------------------------------
  171. Binding an environment to a function
  172. ---------------------------------------------
  173. .. index::
  174. single: Binding an environment to a function
  175. while by default a squirrel function call passes as environment object 'this', the object
  176. where the function was indexed from. However, is also possible to statically bind an evironment to a
  177. closure using the following syntax.::
  178. function test[env_obj](a,b) {
  179. return a + b;
  180. }
  181. local test = function[env_obj](a,b) {
  182. return a + b;
  183. }
  184. local function test[env_obj](a,b) {
  185. return a + b;
  186. }
  187. It is also possible to statically bind an evironment to a closure using the built-in method ``closure.bindenv(env_obj)``.
  188. The method bindenv() returns a new instance of a closure with the environment bound to it.
  189. When an environment object is bound to a function, every time the function is invoked, its
  190. 'this' parameter will always be the previously bound environent.
  191. This mechanism is useful to implement callbacks systems similar to C# delegates.
  192. .. note:: The closure keeps a weak reference to the bound environmet object, because of this if
  193. the object is deleted, the next call to the closure will result in a ``null``
  194. environment object.
  195. ---------------------------------------------
  196. Lambda Expressions
  197. ---------------------------------------------
  198. .. index::
  199. single: Lambda Expressions
  200. ::
  201. exp := '@' '(' paramlist ')' exp
  202. Lambda expressions are a syntactic sugar to quickly define a function that consists of a single expression.
  203. This feature comes handy when functional programming patterns are applied, like map/reduce or passing a compare method to
  204. array.sort().
  205. here a lambda expression::
  206. local myexp = @(a,b) a + b
  207. that is equivalent to::
  208. local myexp = function(a,b) { return a + b; }
  209. a more useful usage could be::
  210. local arr = [2,3,5,8,3,5,1,2,6];
  211. arr.sort(@(a,b) a <=> b);
  212. arr.sort(@(a,b) -(a <=> b));
  213. that could have been written as::
  214. local arr = [2,3,5,8,3,5,1,2,6];
  215. arr.sort(function(a,b) { return a <=> b; } );
  216. arr.sort(function(a,b) { return -(a <=> b); } );
  217. other than being limited to a single expression lambdas support all features of regular functions.
  218. in fact are implemented as a compile time feature.
  219. ---------------------------------------------
  220. Free Variables
  221. ---------------------------------------------
  222. .. index::
  223. single: Free Variables
  224. A free variable is a variable external from the function scope as is not a local variable
  225. or parameter of the function.
  226. Free variables reference a local variable from a outer scope.
  227. In the following example the variables 'testy', 'x' and 'y' are bound to the function 'foo'.::
  228. local x=10,y=20
  229. local testy="I'm testy"
  230. function foo(a,b)
  231. {
  232. ::print(testy);
  233. return a+b+x+y;
  234. }
  235. A program can read or write a free variable.
  236. ---------------------------------------------
  237. Tail Recursion
  238. ---------------------------------------------
  239. .. index::
  240. single: Tail Recursion
  241. Tail recursion is a method for partially transforming a recursion in a program into an
  242. iteration: it applies when the recursive calls in a function are the last executed
  243. statements in that function (just before the return).
  244. If this happenes the squirrel interpreter collapses the caller stack frame before the
  245. recursive call; because of that very deep recursions are possible without risk of a stack
  246. overflow.::
  247. function loopy(n)
  248. {
  249. if(n>0){
  250. ::print("n="+n+"\n");
  251. return loopy(n-1);
  252. }
  253. }
  254. loopy(1000);