{"id":468,"date":"2011-03-27T12:11:08","date_gmt":"2011-03-27T11:11:08","guid":{"rendered":"http:\/\/trigonakis.com\/blog\/?p=468"},"modified":"2011-04-17T12:33:02","modified_gmt":"2011-04-17T11:33:02","slug":"introduction-to-erlang-control-flow","status":"publish","type":"post","link":"http:\/\/trigonakis.com\/blog\/2011\/03\/27\/introduction-to-erlang-control-flow\/","title":{"rendered":"Introduction to Erlang : Control Flow"},"content":{"rendered":"<div class=\"seriesmeta\">This entry is part 8 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>Control Flow<\/h3>\n<p>As we saw in the previous post, pattern matching with different function clauses can be used in order to control the execution flow in Erlang. Erlang also provides the <strong><code>if<\/code><\/strong>, <strong><code>case<\/code><\/strong>, and <strong><code>receive<\/code><\/strong> control flow constructs that can be used in a function body. In this post I will only present the <code>if<\/code> and <code>case<\/code>statements since <code>receive<\/code> is used for message passing and I will write a dedicated post about the subject. Both <code>if<\/code> and <code>case<\/code> are similar to the equivalent statements of other programming languages.<\/p>\n<h3>if statement<\/h3>\n<p>The format of an <code>if<\/code> statement in Erlang is the following:<\/p>\n<pre lang=\"erlang\">\r\nif\r\n    Boolean_Expression1 ->\r\n\tIf_body1;\r\n    Boolean_Expression2 ->\r\n\tIf_body2;\r\n    ...\r\n    true ->\r\n\tIf_body_cath_all\r\nend\r\n<\/pre>\n<p>So the different clauses, except the last one, are like <code>else if<\/code> in other languages, while the last one (<code>true -><\/code>) is like the <code>else<\/code>; it succeeds when all the previous clauses have failed.<br \/>\n<!--more--><\/p>\n<h4>Examples<\/h4>\n<h5>month\/1<\/h5>\n<pre lang=\"erlang\">\r\nmonth(M) -> \r\n    if\r\n\tM == 1 -> jan;\r\n\tM == 2 -> feb;\r\n\tM == 3 -> mar;\r\n\tM == 4 -> apr;\r\n\tM == 5 -> may;\r\n\tM == 6 -> jun;\r\n\tM == 7 -> jul;\r\n\tM == 8 -> aug;\r\n\tM == 9 -> sep;\r\n\tM == 10 -> oct;\r\n\tM == 11 -> nov;\r\n\tM == 12 -> dec;\r\n\ttrue -> {error, not_valid_month_value}\r\n    end.\r\n<\/pre>\n<p>This is a different implementation of <code>month\/1<\/code> function that we saw in the previous post.<\/p>\n<h5>time\/1<\/h5>\n<pre lang=\"erlang\">\r\ntime(\"24:00\") ->\r\n    time(\"00:00\");\r\ntime(Time = [H1, H2, $:, M1, M2]) when ((H1 >= $0) and (H1 =< $2)) and\r\n\t\t\t\t       ((H2 >= $0) and (H2 =< $9)) and\r\n\t\t\t\t       ((M1 >= $0) and (M1 =< $5)) and\r\n\t\t\t\t       ((M2 >= $0) and (M2 =< $9)) and\r\n\t\t\t\t       not((H1 == $2) and (H2 > $4)) and\r\n\t\t\t\t       not(([H1, H2] == \"24\") and (not([M1, M2] == \"00\"))) ->\r\n    HH = list_to_integer([H1, H2]),\r\n    if\r\n\tHH == 12 ->\r\n\t    Time ++ \" PM\";\r\n\tHH > 12 ->\r\n\t    integer_to_list(HH - 12) ++ [$:, M1, M2 | \" PM\"];\r\n\ttrue ->\r\n\t    Time ++ \" AM\"\r\nend;\r\ntime(_) ->\r\n    incorrect_time_format.\r\n<\/pre>\n<p>This function can be used to convert the time from the 24h system to the AM\/PM one. A much nicer implementation can be programmed, but I used this one because it illustrates several things:<\/p>\n<ul>\n<li>pattern matching of strings as lists<\/li>\n<li>pattern matching of characters (<code>$:<\/code> has the value 58; the ASCII code of &#8220;:&#8221;)<\/li>\n<li>using guards<\/li>\n<li>using built-in (BIF) functions<\/li>\n<li>concatenating lists\/strings<\/li>\n<\/ul>\n<h3>case statement<\/h3>\n<p>The format of a <code>case<\/code> statement in Erlang is the following:<\/p>\n<pre lang=\"erlang\">\r\ncase Expression of\r\n    Value1 [when Guard1] ->\r\n\tCase_body1;\r\n    Value2 [when Guard2]->\r\n\tCase_body2;\r\n    _Other ->\r\n\tCase_body_catch_all\r\nend\r\n<\/pre>\n<p>Notice that the last clause (<code>_Other<\/code>) is like the <code>default<\/code> clause in other programming languages. The <code>Expression<\/code> should always return a value (if it is a function call) that will be used to perform the pattern matching.<\/p>\n<h4>Examples<\/h4>\n<h5>month\/1<\/h5>\n<pre lang=\"erlang\">\r\nmonth(M) -> \r\n    case M of\r\n\t1 -> jan;\r\n\t2 -> feb;\r\n\t3 -> mar;\r\n\t4 -> apr;\r\n\t5 -> may;\r\n\t6 -> jun;\r\n\t7 -> jul;\r\n\t8 -> aug;\r\n\t9 -> sep;\r\n\t10 -> oct;\r\n\t11 -> nov;\r\n\t12 -> dec;\r\n\t_Other -> {error, not_valid_month_value}\r\n    end.\r\n<\/pre>\n<p>This <code>month\/1<\/code> implementation looks &#8220;better&#8221; than the previous ones.<\/p>\n<h5>palindrome\/1<\/h5>\n<pre lang=\"erlang\">\r\npalindrome(List) when is_list(List) ->\r\n    case lists:reverse(List) of\r\n\tList ->\r\n\t    true;\r\n\t_ ->\r\n\t    false\r\n    end;\r\npalindrome(_) ->\r\n    {error, arg_not_list}.\r\n<\/pre>\n<p>This function checks if a list is a <i>palindrome<\/i>. Palindromes are the lists that remain the same if reversed. For example, <code>[a], [a,a], [a, b, a]<\/code> are all palindromes.<\/p>\n<h3>Next<\/h3>\n<p>In the next post, I will introduce <strong>recursion<\/strong>; one of the most important characteristics of a functional language.<\/p>\n","protected":false},"excerpt":{"rendered":"<div class=\"seriesmeta\">This entry is part 8 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>Control Flow As we saw in the previous post, pattern matching with different function clauses can be used in order to control the execution flow in Erlang. Erlang also provides the if, case, and receive control flow constructs that can be used in a function body. In this post I will only present the if [&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":[61,26,42],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p1ouW6-7y","_links":{"self":[{"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/posts\/468"}],"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=468"}],"version-history":[{"count":6,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/posts\/468\/revisions"}],"predecessor-version":[{"id":537,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/posts\/468\/revisions\/537"}],"wp:attachment":[{"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/media?parent=468"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/categories?post=468"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/trigonakis.com\/blog\/wp-json\/wp\/v2\/tags?post=468"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}