{"id":450,"date":"2011-03-19T21:52:00","date_gmt":"2011-03-19T20:52:00","guid":{"rendered":"http:\/\/trigonakis.com\/blog\/?p=450"},"modified":"2011-04-07T16:06:31","modified_gmt":"2011-04-07T15:06:31","slug":"introduction-to-erlang-declaring-functions","status":"publish","type":"post","link":"http:\/\/trigonakis.com\/blog\/2011\/03\/19\/introduction-to-erlang-declaring-functions\/","title":{"rendered":"Introduction to Erlang : Declaring Functions"},"content":{"rendered":"<div class=\"seriesmeta\">This entry is part 7 of 16 in the series <a href=\"http:\/\/trigonakis.com\/blog\/series\/introduction-to-erlang\/\" class=\"series-57\" title=\"Introduction to Erlang\">Introduction to Erlang<\/a><\/div><h3>Functions<\/h3>\n<p>As you know by now, Erlang is a <strong>functional programming language<\/strong>. As this suggests, functions are the basic &#8220;ingredient&#8221; of an Erlang program. In my point of view, different programming paradigms pose different problem solving philosophy:<\/p>\n<ul>\n<li><i>Procedural<\/i>: describe the steps needed to be taken to solve the problem<\/li>\n<li><i>Object-orientation<\/i>: design the objects that will lead you to the solution<\/li>\n<li><i>Logical (Declarative)<\/i>: describe the problem properly and let the language solve it<\/li>\n<li><strong><i>Functional<\/i>: define small and precise functions that alltogether solve the problem<\/strong><\/li>\n<\/ul>\n<p>With this in mind, lets continue on how to declare a function (in a <code>module<\/code>).<\/p>\n<h3>Examples<\/h3>\n<p>While introducing functions, I will use several examples that implement list functions, although there are built-ins (BIFs) that implement the same functionality. The reason I will do so is that most of these functions are small, easy to understand, and operate on lists; one of the most, if not the most, important type in Erlang.<\/p>\n<h3>Declaring a Function<\/h3>\n<p>A simple function declaration has the following format:<\/p>\n<pre lang=\"erlang\">\r\nfunction_name(Argument1, Argument2, ...) ->\r\n    Statement1,\r\n    Statement2,\r\n    ... .\r\n<\/pre>\n<p>Where a <code>statement<\/code> can be another function call, an assignement, a comparison, a control statement (<code>if<\/code> for example), or a statement called for its side effects.<br \/>\n<!--more--><\/p>\n<h4>Pattern Matching<\/h4>\n<p>Multiple clauses of the funtion can be defined utilizing pattern matching. For example:<\/p>\n<pre lang=\"erlang\">\r\n% month\/1\r\nmonth(1) -> jan;\r\nmonth(2) -> feb;\r\nmonth(3) -> mar;\r\nmonth(4) -> apr;\r\nmonth(5) -> may;\r\nmonth(6) -> jun;\r\nmonth(7) -> jul;\r\nmonth(8) -> aug;\r\nmonth(9) -> sep;\r\nmonth(10) -> oct;\r\nmonth(11) -> nov;\r\nmonth(12) -> dec;\r\nmonth(_) -> uknown.\r\n\r\n% is_empty\/1\r\nis_empty([]) ->\r\n    true;\r\nis_empty([_ | _]) ->\r\n    false;\r\nis_empty(_) ->\r\n    {error, not_a_list}.\r\n<\/pre>\n<p>All the clauses will be pattern match sequentially (so the first clause is tested first, or at list this is the result the user sees) and the first to match will be used. Notice the following:<\/p>\n<ul>\n<li>the different clauses, except the last one, finish with a semicolon (<strong>;<\/strong>). The semicolon stands for the <code>or<\/code> in Erlang. The last one, as expected, terminates with a full stop (<strong>.<\/strong>)<\/li>\n<li>the last clause is a <i>catch all<\/i> one, because it will pattern match any input. The <strong>&#8216;_&#8217;<\/strong> variable is the <i>don&#8217;t care<\/i> variable that <strong>matches any value<\/strong>. The value that will be pattern matched with &#8216;_&#8217; will not be saved in a variable and you will not be able to retrieve its value once matched.<\/li>\n<li>in the <code>is_empty\/1<\/code> notice the pattern matching for lists. As we saw in the Data Types 2 post, an empty list pattern matches the <code>[]<\/code>, while a non-empty matches the <code>[Head | Tail]<\/code>. Interpret the second pattern matching as: since in <code>[Head | Tail]<\/code> <code>Tail<\/code> should be a list and <code>Head<\/code> should be a term, the list that pattern matches <strong>has to have at least one element<\/strong>, thus cannot be the empty list. For the same reason the pattern <code>[H1, H2 | Tail]<\/code> matches any list with 2 or more elements.<\/li>\n<\/ul>\n<pre lang=\"erlang\">\r\n 1> c(mon).\r\n{ok,mon}\r\n2> mon:month(3).\r\nmar\r\n3> mon:month(31).\r\nuknown\r\n4> c(mlists).\r\n{ok,mlists}\r\n5> mlists:is_empty([]).\r\ntrue\r\n6> mlists:is_empty([1]).\r\nfalse\r\n7> mlists:is_empty([1,2,3,4]).\r\nfalse\r\n8> mlists:is_empty({[1,2,3,4], a}).\r\n{error,not_a_list}\r\n<\/pre>\n<p>An interesting ability in pattern matching is the following:<\/p>\n<pre lang=\"erlang\">\r\ndupl_head([]) ->\r\n    [];\r\ndupl_head(List = [Head | _Tail]) ->\r\n    [Head | List].\r\n\r\n%instead of\r\ndupl_head2([]) ->\r\n    [];\r\ndupl_head2([Head | Tail]) ->\r\n    [Head, Head | Tail].\r\n<\/pre>\n<p>which duplicates the first element of the list:<\/p>\n<pre lang=\"erlang\">\r\n2> mlists:dupl_head([1,2,3,4]).\r\n[1,1,2,3,4]\r\n<\/pre>\n<p>What is interesting is that you can both &#8220;break&#8221; the list with pattern matching and &#8220;keep&#8221; the whole list for later use.<\/p>\n<h4>Guards<\/h4>\n<p>In addition to the pattern matching done on the clause&#8217;s arguments, you can use some additional constraints for selecting which clause matches. These constraints are called <strong>guards<\/strong> and can also be used with the <strong>case<\/strong> and <strong>receive<\/strong> construct (we will see them in later posts). A guard is signified by the <code>when<\/code> keyword:<\/p>\n<pre lang=\"erlang\">\r\nfunction(Arg1, Arg1, ...) when guard_expression ->\r\n   function_body;\r\n...\r\n<\/pre>\n<p>For example:<\/p>\n<pre lang=\"erlang\">\r\nabs(N) when is_integer(N), N < 0 ->\r\n    -N;\r\nabs(N) when is_integer(N) ->\r\n    N.\r\n\r\n% run\r\n2> mon:abs(1).\r\n1\r\n3> mon:abs(-1). \r\n1\r\n4> mon:abs(a). \r\n** exception error: no function clause matching mon:abs(a)\r\n5> mon:abs(-1.1).\r\n** exception error: no function clause matching mon:abs(-1.1)\r\n<\/pre>\n<p>Notice that <code>abs\/1<\/code> does not work with a <code>float<\/code> as input, because of the <code>is_integer\/1<\/code> guard. As you can see in this example, several guards can be used by separating the with comma (,).<\/p>\n<h5>Guard Expressions<\/h5>\n<p>Not every expression can be used as a guard. The following list mentions the allowed constructs:<\/p>\n<ul>\n<li>the atom true<\/li>\n<li>other constants (terms and bound variables), all regarded as false<\/li>\n<li>calls to the BIFs <code>is_atom\/1, is_binary\/1, is_bitstring\/1, is_boolean\/1, is_float\/1, is_function\/1, is_function\/2, is_integer\/1, is_list\/1, is_number\/1, is_pid\/1, is_port\/1, is_record\/2, is_record\/3, is_reference\/1, is_tuple\/1<\/code> that do type checks<\/li>\n<li>term comparisons<\/li>\n<li>arithmetic expressions<\/li>\n<li>boolean expressions<\/li>\n<li>contructs using the <code>andalso<\/code> and <code>orelse<\/code><\/li>\n<\/ul>\n<p>No user functions are allowed as guards, in order to avoid having side-effects (such as printing) within the guard.<\/p>\n<h6>Multiple Guard Expressions<\/h6>\n<p>As you already saw, you can use a comma (,) to have more than one guard for a clause. Comma has the same effect as the <code>and<\/code> keyword. For example:<\/p>\n<pre lang=\"erlang\">\r\nabs(N) when is_integer(N), N < 0 ->\r\n    -N;\r\nabs(N) when (is_integer(N)) and (N >= 0) ->\r\n    N.\r\n<\/pre>\n<p>The same is true about the semicolon (;) and the <code>or<\/code> keyword.<\/p>\n<pre lang=\"erlang\">\r\nis_number(N) when is_integer(N); is_float(N) ->\r\n    true;\r\nis_number(N) when not(is_integer(N) or is_float(N)) ->\r\n    false.\r\n<\/pre>\n<p>It should be obvious that the guard in the second clause does not make any sense, since it is already &#8220;covered&#8221; by the guard in the first clause. As you noticed, you can also use the <code>not<\/code> keyword for negation.<\/p>\n<p>Finally, the <code>orelse<\/code> and <code>andelse<\/code> are shortcut evaluations for the <code>or<\/code> and <code>and<\/code> respectively. They evaluate without looking at the right-hand side when possible ((<code>true orelse Whatever<\/code>) and (<code>false andelse Whatever<\/code>)).<\/p>\n<h3>Next<\/h3>\n<p>In the next post, I will introduce the <code>if<\/code> and <code>case<\/code> control flow statements.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"seriesmeta\">This entry is part 7 of 16 in the series <a href=\"http:\/\/trigonakis.com\/blog\/series\/introduction-to-erlang\/\" class=\"series-57\" title=\"Introduction to Erlang\">Introduction to Erlang<\/a><\/div><p>Functions As you know by now, Erlang is a functional programming language. As this suggests, functions are the basic &#8220;ingredient&#8221; of an Erlang program. In my point of view, different programming paradigms pose different problem solving philosophy: Procedural: describe the steps needed to be taken to solve the problem Object-orientation: design the objects that will [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"jetpack_publicize_message":"","jetpack_is_tweetstorm":false,"jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false}}},"categories":[40,51,28],"tags":[26,60,42],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p1ouW6-7g","_links":{"self":[{"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/posts\/450"}],"collection":[{"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/comments?post=450"}],"version-history":[{"count":15,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/posts\/450\/revisions"}],"predecessor-version":[{"id":512,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/posts\/450\/revisions\/512"}],"wp:attachment":[{"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/media?parent=450"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/categories?post=450"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/tags?post=450"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}