Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Assembly brought us addresses also known as untyped pointers. C mapped them directly as typed pointers but introduced Algol's null as a unique pointer value, compatible with all typed pointers. The big issue with null in C is that since every pointer can be null, one never can use a pointer safely without a manual check.</p> <p>In higher-level languages, having null is awkward since it really conveys two distinct notions:</p> <ul> <li>Telling that something is <strong>undefined</strong>.</li> <li>Telling that something is <strong>optional</strong>.</li> </ul> <p>Having undefined variables is pretty much useless, and yields to undefined behavior whenever they occur. I suppose everybody will agree that having things undefined should be avoided at all costs.</p> <p>The second case is optionality and is best provided explicitly, for instance with an <a href="http://www.ocaml-tutorial.org/null_pointers,_asserts_and_warnings" rel="noreferrer">option type</a>.</p> <hr> <p>Let's say we're in a transport company and we need to create an application to help create a schedule for our drivers. For each driver, we store a few informations such as: the driving licences they have and the phone number to call in case of emergency.</p> <p>In C we could have:</p> <pre><code>struct PhoneNumber { ... }; struct MotorbikeLicence { ... }; struct CarLicence { ... }; struct TruckLicence { ... }; struct Driver { char name[32]; /* Null terminated */ struct PhoneNumber * emergency_phone_number; struct MotorbikeLicence * motorbike_licence; struct CarLicence * car_licence; struct TruckLicence * truck_licence; }; </code></pre> <p>As you observe, in any processing over our list of drivers we'll have to check for null pointers. The compiler won't help you, the safety of the program relies on your shoulders.</p> <p>In OCaml, the same code would look like this:</p> <pre><code>type phone_number = { ... } type motorbike_licence = { ... } type car_licence = { ... } type truck_licence = { ... } type driver = { name: string; emergency_phone_number: phone_number option; motorbike_licence: motorbike_licence option; car_licence: car_licence option; truck_licence: truck_licence option; } </code></pre> <p>Let's now say that we want to print the names of all the drivers along with their truck licence numbers.</p> <p>In C:</p> <pre><code>#include &lt;stdio.h&gt; void print_driver_with_truck_licence_number(struct Driver * driver) { /* Check may be redundant but better be safe than sorry */ if (driver != NULL) { printf("driver %s has ", driver-&gt;name); if (driver-&gt;truck_licence != NULL) { printf("truck licence %04d-%04d-%08d\n", driver-&gt;truck_licence-&gt;area_code driver-&gt;truck_licence-&gt;year driver-&gt;truck_licence-&gt;num_in_year); } else { printf("no truck licence\n"); } } } void print_drivers_with_truck_licence_numbers(struct Driver ** drivers, int nb) { if (drivers != NULL &amp;&amp; nb &gt;= 0) { int i; for (i = 0; i &lt; nb; ++i) { struct Driver * driver = drivers[i]; if (driver) { print_driver_with_truck_licence_number(driver); } else { /* Huh ? We got a null inside the array, meaning it probably got corrupt somehow, what do we do ? Ignore ? Assert ? */ } } } else { /* Caller provided us with erroneous input, what do we do ? Ignore ? Assert ? */ } } </code></pre> <p>In OCaml that would be:</p> <pre><code>open Printf (* Here we are guaranteed to have a driver instance *) let print_driver_with_truck_licence_number driver = printf "driver %s has " driver.name; match driver.truck_licence with | None -&gt; printf "no truck licence\n" | Some licence -&gt; (* Here we are guaranteed to have a licence *) printf "truck licence %04d-%04d-%08d\n" licence.area_code licence.year licence.num_in_year (* Here we are guaranteed to have a valid list of drivers *) let print_drivers_with_truck_licence_numbers drivers = List.iter print_driver_with_truck_licence_number drivers </code></pre> <p>As you can see in this trivial example, there is nothing complicated in the safe version:</p> <ul> <li>It's terser.</li> <li>You get much better guarantees and no null check is required at all.</li> <li>The compiler ensured that you correctly dealt with the option</li> </ul> <p>Whereas in C, you could just have forgotten a null check and boom...</p> <p>Note : these code samples where not compiled, but I hope you got the ideas.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload