Looping with Foreach
Tags: dlang, lua, javascript, csharp
Published: 2019-12-29 21:20:32

Traversing data is one of the most common elements of programming. Generally this means you have some sort of collection. If you are interested in seeing the different ways languages approach the foreach loop visit [Rosetta Code](http://www.rosettacode.org/wiki/Loops/Foreach). However I do not think it does a good job of showing the nuances of the approach. I will start with the basics in D, and use D as the bed for comparing differences. 

# List of Items 

```dlang
// D
import std;
void main()
    auto vehicles = ["car", "truck", "boat", "rv"];
    foreach(vehicle; vehicles) {
        writeln(vehicle);
    } 
}
```

It uses a specific keyword `foreach` and separates the variable declaration (on the left) from the iterable (on the right) with a semicolon. D has type inference and does not require a type to be specified for the variable.

```javascript
// Javascript 
["car", "truck", "boat", "rv"].forEach(
  function (vehicle) {
    console.log(vehicle);
  }
);
```

Here we see that foreach provided as a function which takes a lambda. This method lives on the array type and is not available to other iterable types. D provides a generic template to operate in this manner.

```dlang
// D
vehicles.each!(vehicle =>
writeln(vehicle));
```

```csharp
// C#
string[] things = {"car", "truck", "boat", "rv"};
 
foreach (var thing in things)
{
    Console.WriteLine(thing);
}
```

C# also has type inference which is explicitly requested. `in` separate the variable from the iterable. If you are dealing with the List type C# provides a ForEach method just like Javascript, unlike D it is not available to other iterable types.

```lua
-- Lua 
auto vehicles = {'car', 'truck', 'boat', 'rv'} 
for key, vehicle in ipairs(vehicles) do                                                                         
  print(key, vehicle)
end
```

Lua uses just the keyword `for` probably because it does not provide a C style `for` loop. 

It also has `ipairs` to iterate over positive keys in order. Lua does not have arrays or lists, the only data structure is a table (conceptually an associative array). This means iteration is defined by that extra call.

# Dictionary 

```lua
-- Lua 
vehicleMake= {truck='Dodge', car='Honda', boat='Schaefer', rv='Forest River' }
for key, value in pairs(vehicleMake) do                       
  print(key, value)
end
```

Instead here we use `pairs` to get at everything in the table. Let's revisit the other languages.

```csharp
// C#
var vehicleMake = new Dictionary<string, string>
{
    ["car"] = "Honda",
    ["truck"] = "Dodge",
    ["boat"] = "Schaefer",
    ["rv"] = "Forest River",
}

foreach(var item in vehicleMake) {
    System.Output.WriteLine($"{item.Key} {item.Value}");
}

```

In this case we see that the key and value are provided in a wrapping type and is not automatically expanded within foreach.

```dlang
// D
auto vehicleMake = ["truck" : "Dodge", "car" : "Honda", "boat" : "Schaefer", "rv" : "Forest River"];
foreach(key, value; vehicleMake) {                    
  writeln(key, ": ", value);
}
```

D maintains the same syntax for dictionary iteration. But it is not only available to dictionary, A range returning a tuple will expand within foreach. 

```dlang 
//D 
auto vehicleMake = [tuple("truck", "Dodge", 8), 
tuple("car", "Honda", 4), 
tuple("boat", "Schaefer", 5), 
tuple("rv", "Forest River", 8)].map!(x => x);
foreach(key, value, num; vehicleMake) {
    writeln(key, ": ", value, "-", num);
}
```

The [comma operator](https://dlang.org/deprecate.html#Using%20the%20result%20of%20a%20comma%20expression) is deprecated and there is hope to use it for expansion during assignments, not just in foreach.

You should also notice the identity map used on the array. This is because arrays get special treatment with foreach and so tuple expansion does not happen and this trick turns it into a range. 

Another language which takes advantage of tuples to make this work is Python.

```python
#Python 
vehicleMake = {"truck" : "Dodge", "car" : "Honda", "boat" : "Schaefer", "rv" : "Forest River"}

for key, value in vehicleMake.items():
    print(key, value)
```

The call for items() provides a tuple used to expand into key and value. 

# Changing Types

In this little experiment I am going to utilize the basic for each with the two types (array, associative array). You be the judge.

```dlang 
// D
auto arr = ["one", "two"];
auto dict = [1:"one", 2:"two"];

writeln("Array:");
foreach(value; arr) writeln(value);

writeln("Dictionary:");
foreach(value; dict) writeln(value);

/* // output 
Array:
one
two
Dictionary:
two
one
*/
```

```csharp
// C#
using System;
using System.Collections.Generic;
					
public class Program {
    public static void Main() {

var arr = new string[] {"one", "two"};
var dict = new Dictionary<int, string>() { [1] ="one", [2] ="two"};

Console.WriteLine("Array:");
foreach(var val in arr) 
   Console.WriteLine(val);

Console.WriteLine("Dictionary:");
foreach(var val in dict) 
   Console.WriteLine(val);

   } 
} 

/* // output 
Array:
one
two
Dictionary:
[1, one]
[2, two]
*/
```

```lua
-- Lua 
arr = {"one", "two"}
dict = {[1] ="one", [2] ="two", [0]="zero" } 

print("Array:");
for value in ipairs(arr) do print(value) end

print("Dictionary:");
for value in ipairs(dict) do print(value) end

--[[ output
Array:
1
2
Dictionary:
1
2
--]]
```

Notice the dictionary does not print `0`.

I needed to modify the Lua dictionary in order to demonstrate this languages odd behavior. Because I used integers as a key Lua sees it the same as the array (they are the same because they are both tables). Other dictionaries with strings would not print if you use `ipairs`. 

```python
# Python
arr = {"one", "two"} 
dict = {1:"one", 2:"two"} 

print("Array:") 
for value in arr:
    print(value)

print("Dictionary:") 
for key in dict:
    print(key)

# output 
#Array:
#two
#one
#Dictionary:
#1
#2
```

Python provides the dictionary key rather than the value as other languages have.