Answers.Body: <p>First thing first, a C function may not return an array (without some hoops jumping). It may however return a struct, fair and square: struct is a value, array is not.</p>
  <p>Structural values arise naturally in many contexts. Unfortunately, most of them are recursive, which you rule out. The non-recursive example - off the top of my head - would be tokenizing a programming language, where a token is comprised of a <code>type</code>, and a <code>value</code> (and a type of <code>value</code> depends on <code>type</code>). I don't know if you consider it too complicated for your students.</p>
  <p>Now to the real point. Structs is not about Cartesian products. They are not about the computational power. They are about the expressiveness. Reconsider complex numbers.</p>
  <pre><code>void add(double z1[2], double z2[2], double result[2]);
  </code></pre>
  <p>vs</p>
  <pre><code>struct complex {
      double re;
      double im;
  }
  
  struct complex add(complex z1, complex z2);
  </code></pre>
  <p>Which one is more expressive? Which one is less error-prone?</p>
  <hr />
  <p>Yes, you could do everything with the basic <code>int</code>s, but why should you?</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-11T16:34:54.430Z
Answers.Text: Upvoted. The first time I heard someone talk about "product types" I thought, why are you using pseudo-mathematical vocabulary to talk about such a practical concept? Why are you trying to hide behind these big words?
Answers.UserDisplayName: Stef
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-12T15:57:48.633Z
Answers.Text: @Stef the word "produt type" only really  makes sense if you also introduce the word "sum type" ([introductory example](https://mb21.github.io/blog/2021/01/23/functional-programming.html#algebraic-data-types))
Answers.UserDisplayName: mb21
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T10:59:19.170Z
Answers.Text: Yes, precisely, this is more or less the point to look for good examples on the theme. The fact that structs will allow us to "return something" will be the crucial point in trying to make them appreciate the idea: it's more or less **the** way through which thay can start to understand what we mean by "expressiveness". If I just tell them "we want more expressiveness" they will look at me like crazy: they have absolutely no ground to base this term. Yes, structs are a tool for expressiveness.
Answers.UserDisplayName: user9137
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T11:07:20.033Z
Answers.Text: @Stef it's not "pseudo-mathematical", it's "computer science". All the concepts that we use have a meaning, when a concept survive through a lot of evolution is because it is useful, and the usefulness of a concept is based also on its practicality. I am not hiding anything, nor know why should you think so. The "conceptual" terms serve their goals of being clear, concise, well known. Moreover, the students would not be bad served by using a good name: the cartesian product carries the same name, it is well linked to the concept, and is the only thing already familiar to the students.
Answers.UserDisplayName: user9137
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T11:14:30.433Z
Answers.Text: Oh I forgot to mention that I like the tokenizing / language context, thanks.
Answers.UserDisplayName: user9137
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T11:20:07.297Z
Answers.Text: @user9137 My point is that "product type" is neither clear nor concise nor well-known, and the main reason it is used when talking about struct in C is to reference the concept of Cartesian product in mathematics. It's a perfect example of using big math words to make things sound more intimidating. This has nothing to do with computer science; it only has to do with using pseudomathematical speech to make things sound more theoretical.
Answers.UserDisplayName: Stef
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T11:26:22.140Z
Answers.Text: @user9137 Please don't believe I'm saying this to attack you. You specifically wrote your question in a way that expressed your worry that students would think the concept is too theoretical and not as useful as "just using several int variables". I'm telling you that to this day I still remember, back when I was a student and a teacher tried to talk to us about "product types", how I thought "Why is this teacher trying to make everything sound so abstract and complicated by using big pseudo-mathematical words for simple concepts?"
Answers.UserDisplayName: Stef
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T11:31:50.417Z
Answers.Text: @user9137 This answer is really on point when it says *"Structs is not about Cartesian products. They are not about the computational power. They are about the expressiveness."*. What is the difference between (1) two variables z_re and z_im; (2) one array z[2]; (3) one struct z with two fields z.re and z.im? From a very theoretical, very abstract point of view, there is no difference, and no grand speech about Cartesian product is going to make one of the three better than the other two. But when writing your functions to add and to multiply complex numbers you'll wish you chose option 3.
Answers.UserDisplayName: Stef
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-11T01:29:33.537Z
Answers.LastActivityDate: 2024-02-11T01:36:59.983Z
Answers.LastEditDate: 2024-02-11T01:36:59.983Z
Answers.UserDisplayName: user58697
Answers.Body: <p>I have a few thoughts for you. First, a useful context to consider is Machine Learning, which is both scientific, and regularly involves mixed data types.  Your administrative examples could pretty easily be recast to machine learning examples with just a tiny bit of massaging.  Mathematical examples tend purely towards numbers, so might pose exactly the motivational difficulty for the topic that you've fingered.</p>
  <p>That said, a simple idea for a first motivating example is a standard (x,y) plane point, but with a label.  So, place point A at (0,10) and point B at (10,-10).  Heck, create 26 points, one for each letter of the alphabet, at random places.  Or any largish number of points, arranged however you'd wish.</p>
  <p>Then calculate the midpoints.  Since there are a lot of points, you'll naturally want a function.</p>
  <p>The need for the structure comes as so: you can't return something like <code>[label:&quot;midpoint between A and B&quot;,x:5,y:-5]</code> as an array, and the number of points would make the results impractical to interpret without the labels.  Hence, we really need the struct.</p>
  <p>If you really want to dig into the example, you could try doing it without the struct first, and the kids will see how difficult it becomes before the struct simplifies everything.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-10T18:27:27.310Z
Answers.Text: Thanks! These are really interesting starting points. I hadn't thought about ML because I don't know much about it, I'll try to search for something.
Answers.UserDisplayName: user9137
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-10T13:35:37.827Z
Answers.LastActivityDate: 2024-02-10T13:35:37.827Z
Answers.UserDisplayName: Ben I.
Answers.Body: <p>The other answers suggest using <code>struct</code> to implement complex coordinates. While these may be familiar to students with a scientific background, they suffer from the fact that they're homogeneous, so could easily be implemented as <code>int complexnum[2];</code>.</p>
  <p>What makes structures interesting is that they collect heterogeneous types, so you should use that kind of example to motivate. While it's not science-related, a simple phone directory will be something they can relate to.</p>
  <pre><code>struct contact {
      char name[100];
      char address[100];
      char city[20];
      char state[200];
      char zip[10];
      char phone[20];
  };
  </code></pre>
  <p>If you want something more scientitic, make this a catalog of stars. This will contain the name (a string), magnitude (float), astronomical coordinates (two floats).</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-11T21:34:03.887Z
Answers.LastActivityDate: 2024-02-11T21:34:03.887Z
Answers.UserDisplayName: Barmar
Answers.Body: <p>The primary purpose of abstractions is to give names to collections of more basic ideas. Instead of writing, &quot;I traveled by putting one foot in front of the other such that at least one foot was always on the ground,&quot; we instead write, &quot;I walked.&quot; Not only is the second version shorter, but it unifies several discrete motions into a single action so that the reader can understand with less thought. The first sentence requires the reader to take multiple ideas (&quot;traveled,&quot; &quot;one foot in front of the other,&quot; &quot;one foot always on the ground&quot;) and compose them in their head to arrive at the idea being communicated. Writing only in only the most basic ideas forces the reader to do more work. We want computers to do the work!</p>
  <p>If your students have learned about functions, you can make this comparison:</p>
  <ul>
  <li>A function is a collection of instructions that has been given a name.</li>
  <li>A struct is a collection of data that has been given a name.</li>
  </ul>
  <p>Since your class is science-oriented, let's make a catalogue of planets. Please forgive any language errors as C is not my primary language.</p>
  <pre class="lang-c prettyprint-override"><code>struct Planet
  {
      char *name;
      double mass; /* kg */
      double length_of_year; /* Earth days */
      double distance_from_sun; /* km */
  };
  </code></pre>
  <p>Even if the data fields are homogenous, you can still emphasize the importance of names. For example, let's consider Kepler's third law: the ratio of the square of a planet's year to the cube of the planet's distance from the sun is a constant. We can verify this law by printing the ratio for each planet.</p>
  <pre class="lang-c prettyprint-override"><code>#include &lt;math.h&gt;
  
  Planet mercury;
  mercury.name = &quot;Mercury&quot;;
  mercury.mass = 3.3e23;
  mercury.length_of_year = 115.88;
  mercury.distance_from_sun = 57.91e6;
  
  /* all the other planets */
  
  Planet solar_system[10] = {mercury, venus, earth, mars, jupiter, saturn, uranus, neptune, pluto, sedna};
  
  for(int i = 0; i &lt; 10; i++)
  {
      Planet planet = solar_system[i];
      double kepler_ratio = pow(planet.length_of_year, 2)/pow(planet.distance_from_sun, 3);
      printf(&quot;%s: %e&quot;, planet.name, kepler_ratio);
  }
  </code></pre>
  <p>Now imagine the same code using just <code>double[3]</code> to store the data of each planet.</p>
  <pre class="lang-c prettyprint-override"><code>double solar_system[10][3] = {{3.3e23, 115.88, 57.91e6}, /* etc. */};
  char *planet_names[10] = {&quot;Mercury&quot;, &quot;Venus&quot;, /* etc. */};
  
  for(int i = 0; i &lt; 10; i++)
  {
      double planet_data[3] = solar_system[i];
      double kepler_ratio = pow(planet_data[1], 2)/pow(planet_data[2], 3);
      printf(&quot;%s: %e&quot;, planet_name[i], kepler_ratio);
  }
  </code></pre>
  <p>You can ask your class,</p>
  <ul>
  <li>Are we sure we got the subscripts right?</li>
  <li>Are the names of the planets matched up with the data in the other array?</li>
  <li>What happens when we realize that the planet masses aren't used and delete that data?</li>
  <li>How much time to you want to spend counting indices to get the right data in the right place when we have a computer sitting right here that can count for us?</li>
  </ul>
  <p>Sure, you could read the comments (if there are any and they are correct) on the arrays to see what each index means. But, the first version is easier to read. Why is it easier to read? We are using names that humans understand. Instead of interpreting code, the reader is interpreting human language. In the first version with the struct, we only have to check that the code correctly implements Kepler's third law.</p>
  <p>We humans have problems we want to solve, and computers are one tool that can help. As much as possible, we want to express our problems in human terms that we can understand. The only thing a computer understands is voltages on wires (even <code>1</code> and <code>0</code> are symbolic abstractions of electrical activity). The purpose of a compiler/interpreter is to automatically translate human concepts into machine activity. The closer that the code we write approaches human language and ideas, the easier it is to understand and debug.</p>
  
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-12T13:51:33.580Z
Answers.Text: Playing Devil's Advocate: You could use N arrays of 1 element instead of 1 array of arrays of N elements (problem => introducing/removing an element is a pain). You could use named constants for the indexes (problem => what if the index varies depending on which array is used?).
Answers.UserDisplayName: Matthieu M.
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T06:16:49.197Z
Answers.Text: @MatthieuM. That's actually the way I work in my job. Some equipment dumps out timestamped data to a csv file, and I analyze it with arrays, one for each column. This is less of a pain that I implied in my answer since, luckily, the python Numpy library lets me treat each column of data as a single variable since most mathematical operations are implicitly element-by-element, removing the need for for-loops. Then again, there's no real cohesion in the data in each row other than being measured in the same moment. There's not much gained with a Data struct.
Answers.UserDisplayName: Mark H
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T08:06:34.977Z
Answers.Text: Well... in your case it's easy because you're talking about an immutable "struct of array". Now, try to sort those "virtual" struct based on the lexicographical order of the tuple of the first two "virtual" fields. Good luck ;)
Answers.UserDisplayName: Matthieu M.
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T11:10:53.257Z
Answers.Text: This!! Thanks! Great answer, it deals precisely and accurately with the important points.
Answers.UserDisplayName: user9137
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T13:47:15.837Z
Answers.Text: @MatthieuM. [`numpy.lexsort`](https://numpy.org/doc/stable/reference/generated/numpy.lexsort.html#numpy.lexsort): Get an array of indices that sorts according to the criteria, then use those indices to sort all the other columns in the same way. :)
Answers.UserDisplayName: Mark H
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-13T13:49:01.280Z
Answers.Text: @MarkH: I am sure the students will be very happy to implement it as a learning exercise :)
Answers.UserDisplayName: Matthieu M.
Answers.ContentLicense: CC BY-SA 4.0
Answers.CreationDate: 2024-02-12T10:12:30.403Z
Answers.LastActivityDate: 2024-02-12T10:12:30.403Z
Answers.UserDisplayName: Mark H
Body: <p>I'm soon going to introduce product types (C <code>struct</code> and the like in different languages).
  The audience is 17 year old with a long term goal in scientific studies, who have by now a very limited knowledge of programming, mainly only basic loops in C with integers and integer arrays.</p>
  <p>I would like to motivate the need and usefulness of this concept, knowing that they're going to say &quot;but we like to do everything with our basic <code>int</code>s&quot;.
  I would moreover like to propose examples that are interesting, realistic, and with a glimpse to theoretical aspects (I am going to tell them not too late that what we are doing is a cartesian product of the considered base types).</p>
  <p>By now, my main idea is the classic points in the plane, maybe complex numbers.
  It's very good for my goals (there are reasons why it's a classic), but it has the only disadvantage that the two combined base types are the same.
  The risk is that, having them already been exposed to arrays, their first impression of <code>struct</code> is a needless complication when they could have easily used an array of length 2.</p>
  <p>Of course there are all those &quot;real (accountant) world&quot; situations, where I put together a name and an age, or an item and a price and so on.
  But the students are in science education, I'm not particularly fond of accounting and administrative applications, and most of all I would like to avoid the consolidation of the view that computer science is a tool for accountants.
  Instead, I'd prefer something about science or computing.</p>
  <p>There is also the obvious construction of a linked list in C, but it's too complicated for them: no pointers.</p>
  <p>Put somehow differently, from another angle (their): why would I want to define a new type if I do not do software engineering? I can bring all my data in primitive and disaggregated form as I have done for years: the advantage of creating a new type is not worth the burden of having to learn things.
  Where even is this advantage again?
  (Writing this line I am remembering of blub language and how it's difficult to make these motivations even for experienced computer scientists, doing it for young students does not seem an easy thing, seen from here).</p>
  <p>I'd like instead that they could be put in a situation where they <em>want</em> to construct new types.</p>
  <p>Any suggestions?</p>
  <p>(I have asked chatGPT too and it seems to be stuck in my same position).</p>
  
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-02-10T22:49:37.500Z
Comments.Text: There are lots of real world situations that do not involve accounting. Take examples from their personal lives, be it text messaging, campus management, sports or gaming entities. Take a look at introductions to OOP, they have exactly the same problem of realistic and interesting yet simple objects.
Comments.UserDisplayName: Bergi
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-02-11T01:33:28.487Z
Comments.Text: Frankly, structs are *much* more interesting and useful if you have pointers to play with. They are also going to need both pointers and structs if they're ever going to do any (nontrivial) graph theory. Are you absolutely sure that you can't teach pointers?
Comments.UserDisplayName: Kevin
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-02-12T13:53:28.387Z
Comments.Text: Why do you think they will reject the idea of using a struct, and instead insist on using arrays? Did this already happen to you before with other students?
Comments.UserDisplayName: Matthieu M.
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-02-13T10:36:43.620Z
Comments.Text: @Kevin oh I know unfortunately well that the game is much better with pointers (let's say frankly that C without pointers is not C, and consequently also not useful). Unfortunately it's absolutely out of discussion here, the curriculum is what it is and I can't say much about it. Also the idea of using C as an introductory language is, in my view, not a good idea.
Comments.UserDisplayName: user9137
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-02-13T10:39:56.203Z
Comments.Text: @njuffa nice idea about using an array for a tree, but also this is our of reach. We are at the very beginning, trees are too complicated and I risk making more confusion having to merge 2 goals or even 3: trees, structs, how to encode something (not trivial) with something else (also not so trivial even if relatively known). Arbitrary precision also very very nice, and again too much for the class, but from this maybe I can draw some examples, thanks!
Comments.UserDisplayName: user9137
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-02-13T10:45:25.827Z
Comments.Text: @MatthieuM. Mmh, yes I know the students' ways of thinking quite a bit now and this is a common problem. Not certain of course, but surely something to be considered when planning the lessons. This is also one of the reasons why it's not a good idea for a curriculum to talk about lists (or arrays) before structs: the topics are quite cleary reversed on the path in pedagogical terms. Structs deal with still constant size data, lists/arrays are *the* introduction to arbitrarily sized data (see the wonderful HTDP book for a reference on a very well thought learning path for absolute beginners).
Comments.UserDisplayName: user9137
Comments.ContentLicense: CC BY-SA 4.0
Comments.CreationDate: 2024-02-13T13:26:04.230Z
Comments.Text: @njuffa I may agree. But, especially regarding pointers, I can't do much: this is the curriculum and my care is to try to make the best out of it.
Comments.UserDisplayName: user9137
Tags: <student-motivation><data-structure><struggling-students>
Title: Introduction to product type: motivation and examples
ThreadText: # Introduction to product type: motivation and examples
  
  (Asked by: username_0 on 2024-02-10)
  
  I'm soon going to introduce product types (C `struct` and the like in different languages).
  The audience is 17 year old with a long term goal in scientific studies, who have by now a very limited knowledge of programming, mainly only basic loops in C with integers and integer arrays.
  
  I would like to motivate the need and usefulness of this concept, knowing that they're going to say "but we like to do everything with our basic `int`s".
  I would moreover like to propose examples that are interesting, realistic, and with a glimpse to theoretical aspects (I am going to tell them not too late that what we are doing is a cartesian product of the considered base types).
  
  By now, my main idea is the classic points in the plane, maybe complex numbers.
  It's very good for my goals (there are reasons why it's a classic), but it has the only disadvantage that the two combined base types are the same.
  The risk is that, having them already been exposed to arrays, their first impression of `struct` is a needless complication when they could have easily used an array of length 2.
  
  Of course there are all those "real (accountant) world" situations, where I put together a name and an age, or an item and a price and so on.
  But the students are in science education, I'm not particularly fond of accounting and administrative applications, and most of all I would like to avoid the consolidation of the view that computer science is a tool for accountants.
  Instead, I'd prefer something about science or computing.
  
  There is also the obvious construction of a linked list in C, but it's too complicated for them: no pointers.
  
  Put somehow differently, from another angle (their): why would I want to define a new type if I do not do software engineering? I can bring all my data in primitive and disaggregated form as I have done for years: the advantage of creating a new type is not worth the burden of having to learn things.
  Where even is this advantage again?
  (Writing this line I am remembering of blub language and how it's difficult to make these motivations even for experienced computer scientists, doing it for young students does not seem an easy thing, seen from here).
  
  I'd like instead that they could be put in a situation where they *want* to construct new types.
  
  Any suggestions?
  
  (I have asked chatGPT too and it seems to be stuck in my same position).
  
  **Tags:** student-motivation, data-structure, struggling-students
  
  > **Comments:**
  > **username_1**: There are lots of real world situations that do not involve accounting. Take examples from their personal lives, be it text messaging, campus management, sports or gaming entities. Take a look at introductions to OOP, they have exactly the same problem of realistic and interesting yet simple objects.  
  > **username_2**: Frankly, structs are *much* more interesting and useful if you have pointers to play with. They are also going to need both pointers and structs if they're ever going to do any (nontrivial) graph theory. Are you absolutely sure that you can't teach pointers?  
  > **username_3**: Why do you think they will reject the idea of using a struct, and instead insist on using arrays? Did this already happen to you before with other students?  
  > **username_0**: @username_2 oh I know unfortunately well that the game is much better with pointers (let's say frankly that C without pointers is not C, and consequently also not useful). Unfortunately it's absolutely out of discussion here, the curriculum is what it is and I can't say much about it. Also the idea of using C as an introductory language is, in my view, not a good idea.  
  > **username_0**: @njuffa nice idea about using an array for a tree, but also this is our of reach. We are at the very beginning, trees are too complicated and I risk making more confusion having to merge 2 goals or even 3: trees, structs, how to encode something (not trivial) with something else (also not so trivial even if relatively known). Arbitrary precision also very very nice, and again too much for the class, but from this maybe I can draw some examples, thanks!  
  > **username_0**: @MatthieuM. Mmh, yes I know the students' ways of thinking quite a bit now and this is a common problem. Not certain of course, but surely something to be considered when planning the lessons. This is also one of the reasons why it's not a good idea for a curriculum to talk about lists (or arrays) before structs: the topics are quite cleary reversed on the path in pedagogical terms. Structs deal with still constant size data, lists/arrays are *the* introduction to arbitrarily sized data (see the wonderful HTDP book for a reference on a very well thought learning path for absolute beginners).  
  > **username_0**: @njuffa I may agree. But, especially regarding pointers, I can't do much: this is the curriculum and my care is to try to make the best out of it.  
  
  ---
  
  ## 4 answers
  
  ### Answer by username_9 on 2024-02-12. Score: 6 | Accepted answer
  
  The primary purpose of abstractions is to give names to collections of more basic ideas. Instead of writing, "I traveled by putting one foot in front of the other such that at least one foot was always on the ground," we instead write, "I walked." Not only is the second version shorter, but it unifies several discrete motions into a single action so that the reader can understand with less thought. The first sentence requires the reader to take multiple ideas ("traveled," "one foot in front of the other," "one foot always on the ground") and compose them in their head to arrive at the idea being communicated. Writing only in only the most basic ideas forces the reader to do more work. We want computers to do the work!
  
  If your students have learned about functions, you can make this comparison:
  
  * A function is a collection of instructions that has been given a name.
  * A struct is a collection of data that has been given a name.
  
  Since your class is science-oriented, let's make a catalogue of planets. Please forgive any language errors as C is not my primary language.
  
  ```c
  struct Planet
  {
      char *name;
      double mass; /* kg */
      double length_of_year; /* Earth days */
      double distance_from_sun; /* km */
  };
  
  ```
  
  Even if the data fields are homogenous, you can still emphasize the importance of names. For example, let's consider Kepler's third law: the ratio of the square of a planet's year to the cube of the planet's distance from the sun is a constant. We can verify this law by printing the ratio for each planet.
  
  ```c
  #include <math.h>
  
  Planet mercury;
  mercury.name = "Mercury";
  mercury.mass = 3.3e23;
  mercury.length_of_year = 115.88;
  mercury.distance_from_sun = 57.91e6;
  
  /* all the other planets */
  
  Planet solar_system[10] = {mercury, venus, earth, mars, jupiter, saturn, uranus, neptune, pluto, sedna};
  
  for(int i = 0; i < 10; i++)
  {
      Planet planet = solar_system[i];
      double kepler_ratio = pow(planet.length_of_year, 2)/pow(planet.distance_from_sun, 3);
      printf("%s: %e", planet.name, kepler_ratio);
  }
  
  ```
  
  Now imagine the same code using just `double[3]` to store the data of each planet.
  
  ```c
  double solar_system[10][3] = {{3.3e23, 115.88, 57.91e6}, /* etc. */};
  char *planet_names[10] = {"Mercury", "Venus", /* etc. */};
  
  for(int i = 0; i < 10; i++)
  {
      double planet_data[3] = solar_system[i];
      double kepler_ratio = pow(planet_data[1], 2)/pow(planet_data[2], 3);
      printf("%s: %e", planet_name[i], kepler_ratio);
  }
  
  ```
  
  You can ask your class,
  
  * Are we sure we got the subscripts right?
  * Are the names of the planets matched up with the data in the other array?
  * What happens when we realize that the planet masses aren't used and delete that data?
  * How much time to you want to spend counting indices to get the right data in the right place when we have a computer sitting right here that can count for us?
  
  Sure, you could read the comments (if there are any and they are correct) on the arrays to see what each index means. But, the first version is easier to read. Why is it easier to read? We are using names that humans understand. Instead of interpreting code, the reader is interpreting human language. In the first version with the struct, we only have to check that the code correctly implements Kepler's third law.
  
  We humans have problems we want to solve, and computers are one tool that can help. As much as possible, we want to express our problems in human terms that we can understand. The only thing a computer understands is voltages on wires (even `1` and `0` are symbolic abstractions of electrical activity). The purpose of a compiler/interpreter is to automatically translate human concepts into machine activity. The closer that the code we write approaches human language and ideas, the easier it is to understand and debug.
  
  > **Comments:**
  > **username_3**: Playing Devil's Advocate: You could use N arrays of 1 element instead of 1 array of arrays of N elements (problem => introducing/removing an element is a pain). You could use named constants for the indexes (problem => what if the index varies depending on which array is used?).  
  > **username_9**: @MatthieuM. That's actually the way I work in my job. Some equipment dumps out timestamped data to a csv file, and I analyze it with arrays, one for each column. This is less of a pain that I implied in my answer since, luckily, the python Numpy library lets me treat each column of data as a single variable since most mathematical operations are implicitly element-by-element, removing the need for for-loops. Then again, there's no real cohesion in the data in each row other than being measured in the same moment. There's not much gained with a Data struct.  
  > **username_3**: Well... in your case it's easy because you're talking about an immutable "struct of array". Now, try to sort those "virtual" struct based on the lexicographical order of the tuple of the first two "virtual" fields. Good luck ;)  
  > **username_0**: This!! Thanks! Great answer, it deals precisely and accurately with the important points.  
  > **username_9**: @MatthieuM. [`numpy.lexsort`](https://numpy.org/doc/stable/reference/generated/numpy.lexsort.html#numpy.lexsort): Get an array of indices that sorts according to the criteria, then use those indices to sort all the other columns in the same way. :)  
  > **username_3**: @username_9: I am sure the students will be very happy to implement it as a learning exercise :)  
  
  ---
  
  ### Answer by username_4 on 2024-02-11. Score: 7
  
  First thing first, a C function may not return an array (without some hoops jumping). It may however return a struct, fair and square: struct is a value, array is not.
  
  Structural values arise naturally in many contexts. Unfortunately, most of them are recursive, which you rule out. The non-recursive example - off the top of my head - would be tokenizing a programming language, where a token is comprised of a `type`, and a `value` (and a type of `value` depends on `type`). I don't know if you consider it too complicated for your students.
  
  Now to the real point. Structs is not about Cartesian products. They are not about the computational power. They are about the expressiveness. Reconsider complex numbers.
  
  ```
  void add(double z1[2], double z2[2], double result[2]);
  
  ```
  
  vs
  
  ```
  struct complex {
      double re;
      double im;
  }
  
  struct complex add(complex z1, complex z2);
  
  ```
  
  Which one is more expressive? Which one is less error-prone?
  
  ---
  
  Yes, you could do everything with the basic `int`s, but why should you?
  
  > **Comments:**
  > **username_5**: Upvoted. The first time I heard someone talk about "product types" I thought, why are you using pseudo-mathematical vocabulary to talk about such a practical concept? Why are you trying to hide behind these big words?  
  > **username_6**: @username_5 the word "produt type" only really  makes sense if you also introduce the word "sum type" ([introductory example](https://username_6.github.io/blog/2021/01/23/functional-programming.html#algebraic-data-types))  
  > **username_0**: Yes, precisely, this is more or less the point to look for good examples on the theme. The fact that structs will allow us to "return something" will be the crucial point in trying to make them appreciate the idea: it's more or less **the** way through which thay can start to understand what we mean by "expressiveness". If I just tell them "we want more expressiveness" they will look at me like crazy: they have absolutely no ground to base this term. Yes, structs are a tool for expressiveness.  
  > **username_0**: @username_5 it's not "pseudo-mathematical", it's "computer science". All the concepts that we use have a meaning, when a concept survive through a lot of evolution is because it is useful, and the usefulness of a concept is based also on its practicality. I am not hiding anything, nor know why should you think so. The "conceptual" terms serve their goals of being clear, concise, well known. Moreover, the students would not be bad served by using a good name: the cartesian product carries the same name, it is well linked to the concept, and is the only thing already familiar to the students.  
  > **username_0**: Oh I forgot to mention that I like the tokenizing / language context, thanks.  
  > **username_5**: @username_0 My point is that "product type" is neither clear nor concise nor well-known, and the main reason it is used when talking about struct in C is to reference the concept of Cartesian product in mathematics. It's a perfect example of using big math words to make things sound more intimidating. This has nothing to do with computer science; it only has to do with using pseudomathematical speech to make things sound more theoretical.  
  > **username_5**: @username_0 Please don't believe I'm saying this to attack you. You specifically wrote your question in a way that expressed your worry that students would think the concept is too theoretical and not as useful as "just using several int variables". I'm telling you that to this day I still remember, back when I was a student and a teacher tried to talk to us about "product types", how I thought "Why is this teacher trying to make everything sound so abstract and complicated by using big pseudo-mathematical words for simple concepts?"  
  > **username_5**: @username_0 This answer is really on point when it says *"Structs is not about Cartesian products. They are not about the computational power. They are about the expressiveness."*. What is the difference between (1) two variables z_re and z_im; (2) one array z[2]; (3) one struct z with two fields z.re and z.im? From a very theoretical, very abstract point of view, there is no difference, and no grand speech about Cartesian product is going to make one of the three better than the other two. But when writing your functions to add and to multiply complex numbers you'll wish you chose option 3.  
  
  ---
  
  ### Answer by username_7 on 2024-02-10. Score: 5
  
  I have a few thoughts for you. First, a useful context to consider is Machine Learning, which is both scientific, and regularly involves mixed data types. Your administrative examples could pretty easily be recast to machine learning examples with just a tiny bit of massaging. Mathematical examples tend purely towards numbers, so might pose exactly the motivational difficulty for the topic that you've fingered.
  
  That said, a simple idea for a first motivating example is a standard (x,y) plane point, but with a label. So, place point A at (0,10) and point B at (10,-10). Heck, create 26 points, one for each letter of the alphabet, at random places. Or any largish number of points, arranged however you'd wish.
  
  Then calculate the midpoints. Since there are a lot of points, you'll naturally want a function.
  
  The need for the structure comes as so: you can't return something like `[label:"midpoint between A and B",x:5,y:-5]` as an array, and the number of points would make the results impractical to interpret without the labels. Hence, we really need the struct.
  
  If you really want to dig into the example, you could try doing it without the struct first, and the kids will see how difficult it becomes before the struct simplifies everything.
  
  > **Comments:**
  > **username_0**: Thanks! These are really interesting starting points. I hadn't thought about ML because I don't know much about it, I'll try to search for something.  
  
  ---
  
  ### Answer by username_8 on 2024-02-11. Score: 2
  
  The other answers suggest using `struct` to implement complex coordinates. While these may be familiar to students with a scientific background, they suffer from the fact that they're homogeneous, so could easily be implemented as `int complexnum[2];`.
  
  What makes structures interesting is that they collect heterogeneous types, so you should use that kind of example to motivate. While it's not science-related, a simple phone directory will be something they can relate to.
  
  ```
  struct contact {
      char name[100];
      char address[100];
      char city[20];
      char state[200];
      char zip[10];
      char phone[20];
  };
  
  ```
  
  If you want something more scientitic, make this a catalog of stars. This will contain the name (a string), magnitude (float), astronomical coordinates (two floats).
  
  
  ---
  
  