{"id":351,"date":"2014-07-05T19:10:43","date_gmt":"2014-07-06T01:10:43","guid":{"rendered":"http:\/\/dev.iachieved.it\/iachievedit\/?p=351"},"modified":"2014-07-05T19:10:43","modified_gmt":"2014-07-06T01:10:43","slug":"a-tuple-by-any-other-name","status":"publish","type":"post","link":"https:\/\/dev.iachieved.it\/iachievedit\/a-tuple-by-any-other-name\/","title":{"rendered":"A Tuple By Any Other Name"},"content":{"rendered":"<p>Apple&#8217;s new Swift language provides support for a common data structure known as the <i>tuple<\/i>.  Unlike the venerable array and dictionary, however, what precisely a tuple is and how it behaves is different among programming languages.  What do we mean by this?<\/p>\n<p>In Python you can get the number of elements in a tuple:<\/p>\n<p><code><br \/>\n$ python<br \/>\nPython 2.7.6 (default, May 30 2014, 22:21:15)<br \/>\n[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.34.2)] on darwin<br \/>\nType \"help\", \"copyright\", \"credits\" or \"license\" for more information.<br \/>\n>>> currentConditions = (\"Mostly Cloudy\", \"90\", \"9\")<br \/>\n>>> len(currentConditions)<br \/>\n3<br \/>\n<\/code><\/p>\n<p>In Python you typically cannot access the tuple elements by name, but do so by index:<\/p>\n<p><code><br \/>\n>>> currentConditions[0]<br \/>\n'Mostly Cloudy'<br \/>\n<\/code><\/p>\n<p>There <i>is<\/i> a mechanism for creating so-called named tuples in Python using the <code><a href=\"https:\/\/docs.python.org\/2\/library\/collections.html#collections.namedtuple\">collections<\/a><\/code> module.  <\/p>\n<p>You can iterate over the elements in the tuple in Python:<\/p>\n<p><code><br \/>\n>>> for e in currentConditions:<br \/>\n...     print e<br \/>\n...<br \/>\nMostly Cloudy<br \/>\n90<br \/>\n9<br \/>\n<\/code><\/p>\n<p>Erlang provides a tuple datatype similar to that of Python:  you can create arbitrary groups of data bundled together.  In our previous example all of the elements in the tuple were of the same type, namely a string.  This does not have to be the case.  In Erlang:<\/p>\n<p><code><br \/>\n7> CurrentConditions = {\"Mostly Cloudy\", 90, 9}.<br \/>\n{\"Mostly Cloudy\",90,9}<br \/>\n<\/code><\/p>\n<p>Neither Python or Erlang allow you to change a given element member in the tuple, but for different reasons.  In Erlang you can&#8217;t change the value of a variable once its been set, whereas in Python tuples are immutable (cannot change) types.  To get around that in Erlang one might do:<\/p>\n<p><code><br \/>\n11> UpdatedConditions = setelement(2,CurrentConditions,89).<br \/>\n{\"Mostly Cloudy\",89,9}<br \/>\n<\/code><\/p>\n<p>In Python the following is effective:<\/p>\n<p><code><br \/>\n>>> cc = list(currentConditions)<br \/>\n>>> cc[1] = '89'<br \/>\n>>> currentConditions = tuple(cc)<br \/>\n<\/code><\/p>\n<p>Erlang <i>does provide<\/i> named elements in a special type of tuple called a <b><a href=\"http:\/\/learnyousomeerlang.com\/a-short-visit-to-common-data-structures#records\">record<\/a><\/b>.  <\/p>\n<p>Now let&#8217;s turn to Swift tuples.  We prefer using the REPL feature of Swift from the command line rather than using the Playground.  See our <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/?p=336\">previous post<\/a> if you aren&#8217;t familiar with using Swift from the terminal.  Of course, you can also follow along in the Playground.<\/p>\n<p><code><br \/>\n$ swift -repl<br \/>\nWelcome to Swift!  Type :help for assistance.<br \/>\n  1> var currentConditions = (\"Mostly Cloudy\", 89, 9)<br \/>\ncurrentConditions: (String, Int, Int) = {<br \/>\n  0 = \"Mostly Cloudy\"<br \/>\n  1 = 89<br \/>\n  2 = 9<br \/>\n}<br \/>\n<\/code><\/p>\n<p>The first thing we notice is how Swift takes the tuple created and shows you what the constituent datatypes are.  In this case our <code>currentConditions<\/code> variable is a <code>(String, Int, Int)<\/code> tuple.  We can access the constituent members using a <i>dot syntax<\/i> notation, which is in contrast to the <i>bracket syntax<\/i> of Python:<\/p>\n<p><code><br \/>\n  2> currentConditions.0<br \/>\n$R1: String = \"Mostly Cloudy\"<br \/>\n<\/code><\/p>\n<p>Unlike Python, Swift tuples support <i>named<\/i> elements by default (that is, no need to use any special imports).  This is handy for treating a tuple like a lightweight <code>struct<\/code>, commonly used in <a href=\"http:\/\/en.wikipedia.org\/wiki\/Struct_(C_programming_language)\">C and C++<\/a>.<\/p>\n<p><code><br \/>\n var currentConditions:(conditions:String, temperature:Int, wind:Int) = (\"Mostly Cloudy\", 89, 9)<br \/>\ncurrentConditions: (conditions: String, temperature: Int, wind: Int) = {<br \/>\n  conditions = \"Mostly Cloudy\"<br \/>\n  temperature = 89<br \/>\n  wind = 9<br \/>\n}<br \/>\n<\/code><\/p>\n<p>With this variable definition we can do this:<\/p>\n<p><code><br \/>\n  2> currentConditions.temperature<br \/>\n$R1: Int = 89<br \/>\n<\/code><\/p>\n<p>Also unlike Python, Swift tuples are mutable and we can change the constituent elements:<\/p>\n<p><code><br \/>\n  3> currentConditions.temperature = 87<br \/>\n  4> currentConditions<br \/>\n$R3: (conditions: String, temperature: Int, wind: Int) = {<br \/>\n  conditions = \"Mostly Cloudy\"<br \/>\n  temperature = 87<br \/>\n  wind = 9<br \/>\n}<br \/>\n<\/code><\/p>\n<p>What is not mutable is the datatype of a given element.  That is, we cannot assign a <code>String<\/code> to an element that is defined as an <code>Int<\/code>:<\/p>\n<p><code><br \/>\n  5> currentConditions.temperature = \"87\"<br \/>\n<REPL>:5:31: error: cannot convert the expression's type '()' to type 'Int'<br \/>\ncurrentConditions.temperature = \"87\"<br \/>\n<\/code><\/p>\n<p>Tuples can also contain <a href=\"http:\/\/dev.iachieved.it\/iachievedit\/?p=314\">optionals<\/a>.  Observe:<\/p>\n<p><code><br \/>\n  1> var currentConditions:(String?,Int?,Int?)<br \/>\ncurrentConditions: (String?, Int?, Int?) = {<br \/>\n  0 = nil<br \/>\n  1 = nil<br \/>\n  2 = nil<br \/>\n}<br \/>\n  2> currentConditions.0=\"Partly Cloudy\"<br \/>\n  3> currentConditions<br \/>\n$R2: (String?, Int?, Int?) = {<br \/>\n  0 = \"Partly Cloudy\"<br \/>\n  1 = nil<br \/>\n  2 = nil<br \/>\n}<br \/>\n<\/code><\/p>\n<p>If we wanted to uppercase the current condition string we would have to apply the exclamation mark to our index:<\/p>\n<p><code><br \/>\n  5> currentConditions.0!.uppercaseString<br \/>\n$R4: String = \"PARTLY CLOUDY\"<br \/>\n<\/code><\/p>\n<p>or we could use unwrapping:<\/p>\n<p><code><br \/>\n 10> if let conditions = currentConditions.0 {<br \/>\n 11.     println(conditions.uppercaseString)<br \/>\n 12. }<br \/>\nPARTLY CLOUDY<br \/>\n<\/code><\/p>\n<p>So far, Swift tuples appear to be more robust and useful than Python tuples.  Well, before we make the assumption that they are, let&#8217;s try obtaining the number of elements in the tuple with the global <code>countElements<\/code> function:<\/p>\n<p><code><br \/>\n  5> countElements(currentConditions)<br \/>\n<REPL>:5:1: error: cannot convert the expression's type '$T3' to type 'ForwardIndex'<br \/>\ncountElements(currentConditions)<br \/>\n^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~<br \/>\n<\/code><\/p>\n<p>Oops.  Unlike Python, you <i>cannot<\/i> obtain the number of elements in the tuple.  Okay, then let&#8217;s iterate over the tuple:<\/p>\n<p><code><br \/>\n  6> for e in currentConditions {<br \/>\n  7.     println(e)<br \/>\n  8. }<br \/>\n<REPL>:6:10: error: type '(conditions: String, temperature: Int, wind: Int)' does not conform to protocol 'Sequence'<br \/>\n<\/code><\/p>\n<p>Denied.  Swift&#8217;s pithy reply &#8220;does not conform to protocol &#8216;Sequence'&#8221; is a obtuse way of saying you can&#8217;t iterate over it.  If you have a background in C or C++ these things should not come as a shock.  It wouldn&#8217;t have occurred to you to &#8220;get the length&#8221; of a <code>struct<\/code> or iterate over it.  A <code>struct<\/code> is <i>not<\/i> an array or a list, silly!  <\/p>\n<p>Our conclusion?  While Swift tuples are useful, particularly for returning multiple values from a function or grouping together related data, they are <i>not<\/i> a replacement for arrays or proper structures and classes.  You cannot iterate over them or add any setter logic to a named element.  For example, consider a tuple defined as <code>(name:String,birthday:String,age:Int)<\/code>.  In reality <code>age<\/code> should be a calculated property of a <code>Person<\/code>, not a named element of a tuple.  There&#8217;s nothing necessarily <i>wrong<\/i> about a tuple defined as such, but if you find yourself with tuples that you want to modify after they are set, or you want to iterate on the elements, you probably are using the wrong datatype.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Apple&#8217;s new Swift language provides support for a common data structure known as the tuple. Unlike the venerable array and dictionary, however, what precisely a tuple is and how it behaves is different among programming languages. What do we mean by this? In Python you can get the number of elements in a tuple: $ [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-351","post","type-post","status-publish","format-standard","hentry","category-swift"],"_links":{"self":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/351"}],"collection":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/comments?post=351"}],"version-history":[{"count":13,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/351\/revisions"}],"predecessor-version":[{"id":364,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/posts\/351\/revisions\/364"}],"wp:attachment":[{"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/media?parent=351"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/categories?post=351"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dev.iachieved.it\/iachievedit\/wp-json\/wp\/v2\/tags?post=351"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}