Programing Language: Syntactic and Semantic Difference of Map Function
In most language today, there's a “map” function, and encouraged by programers as good style. Map is typically used like this: map(function, list)
.
There's a critical point in the language spec on the behavior of “map”. Namely, whether the language specifies that the function passed to map must not have side-effects.
JavaScript Example
in JavaScript, its map is Array.prototype.map(f)
. However, the spec says it must be computed as a loop, that is, apply the function to elements in order.
〔see JS: Array.prototype.map〕
This means, JavaScript compiler cannot compile it into running parallel on multiple CPUs. It must apply the function to array element one at a time, in order.
Automatic parallel computation advantage of using map is lost.
See: Guy Steele Says: Don't Iterate, Recurse, and Get rid of lisp cons!
So, when you use “map” in JavaScript, the advantage is merely syntactical.
Lisp Example
In emacs lisp, the spec says the list elements are applied “in turn”.
So, this also means, it thwarts automatic parallel computation.
Consequence of the Map Function Spec
When a language, specifies the map behavior such that:
- the function used in map must have no side-effects.
- and or, the order of the function applying to the list element, is not specified.
Then, such language's “map” function can safely do automatic parallel computation.
Without the above requirement, the “map” is simply useful as a clean syntax of iteration.
Enforce or Not, and How
If a language specifies that the function passed to map must not have side-effects, then, there is the question of whether the language enforces it. If so, how.
If the language does not enforce it, then, the result can be tricky. Because, programers may just ignore it, or due to ignorance, and use map with function that has side-effect. The result is that, sometimes it may not work, and is hard to debug. Then, it creates a shroud of confusion.
If the language does enforce it, then the question is how. It will need a way to make sure that function does not have side effects. For most languages, such as lisp, JavaScript, Java, Python, there is no mechanism in the language to do this.
Conclusion
So, the conclusion here is, that even many of today's languages have “map”, but it is merely a trivial advantage of readability or syntactic style. The real fruit, the math properties that propel automatic transparent parallel computation, isn't there.
Then, given the situation, there's the question of whether you should still use “map” (or just go with iteration.).
It is still better to use map. Because, using “map” gives a explicit indication to readers, that the function does not have side-effects, and the order of application to list doesn't matter. In practice, most use of map does follow this.
In GNU Emacs community, I believe there's implicit coding style convention that tell people to use iteration (dotimes
and related) instead of “mapcar”. That's not good.
Programing Language Design
- Ontology of Programing Languages
- A Class of Programing Languages: Math Languages
- Why I Hate Exceptions
- Iterator, Enumerator, Abstraction Went Wrong
- Should Array Index Start at 0 or 1?
- Where does the “main” function in programing languages came from?
- Syntactic Semantic Difference of Map
- Should Map f Specify Order?
- Abuse of Logic Operators (Short-Circuit) as Control Flow
- Programing Language Idiocy: Bit Operators
- Hack of Bitmask as Boolean Parameters
- Function Dependency
- The Complexity of Java Access Specifiers