Currently, we can have custom iterables, and we can coerce a List<T> into a Iterable<T> (because it implements Iterable<T>). However, we can't do so for Set<T>, which results in the need for temporary variables and unduly complex code structures. It would be very useful if Set<T> had the Iterable<T> interface so it could behave the same as List<T>. While we recognize that sets are "unordered," we also know that we can currently iterate through them using the standard for-each loop. This is particularly important when speaking about built-in libraries that expect an Iterable<T> argument.
For example, using today's Apex Code:
String[] listString = new String[] { 'A', 'B', 'C' };
Set<String> setString = new Set<String>{ 'A', 'B', 'C' };
String listStringJoin = String.join(listString, '--');
String setStringJoin = String.join(setString, '--'); // Compiler error, must implement Iterable<T>.
// Workaround
String setStringJoin = String.join(new List<String>(setString), '--'); // Works great!
Ideally, setString should be a valid parameter for String.join, because we're simply looking to join all the values together. The order is unimportant (as demonstrated by the workaround), but the extra code makes it more cumbersome to read. Worse, many developers are inclined to use heap variables instead of temporary variables, which compounds what should be a relatively short piece of code.
Implementing the Iterable<T> interface would allow sets to behave like normal lists in places where it shouldn't matter if it is a list or a set.