{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The Över operator: `⍥`\n",
"> Last week I was listening to a podcast on Hanselminutes, with Robert Martin talking about the SOLID principles... They all sounded to me like extremely bureaucratic programming that came from the mind of somebody that has not written a lot of code, frankly. --_Joel Spolsky_"
]
},
{
"attachments": {},
"cell_type": "markdown",
"metadata": {},
"source": [
"If you thought _rank_ looked startled, `⍤`, wait until you meet his big sister, [over](http://help.dyalog.com/latest/index.htm#Language/Symbols/Circle%20Dieresis.htm): `⍥`, _nom de guerre_ for _Circle Diaresis_. `Over` was introduced to Dyalog in version 18. Over is a function composition rule, similar to those that govern [tacit](tacit.ipynb) programming. Once you \"see\" this pattern, you'll see it everywhere. Let's take a look.\n",
"\n",
"`Over` complements jot `∘` and the atop version of `⍤` in that it specifies how a set of functions should be applied to common arguments. If we compare `f∘g` and `f⍤g`, when given a left argument, `∘` gives it to the left-hand function and `⍤` gives it to the right-hand function. Other than that, they are the same. For the monadic case, these are all the same:\n",
"\n",
"* `f∘g Y`\n",
"* `f⍤g Y`\n",
"* `f⍥g Y`\n",
"\n",
"In the dyadic case, look at the order of the leftmost two tokens:\n",
"\n",
"* `X f∘g Y` → `X f g Y`\n",
"* `X f⍤g Y` → `f X g Y`\n",
"\n",
"and `over` completes this by\n",
"\n",
"* `X f⍥g Y` → `(g X)f(g Y)`\n",
"\n",
"Clear as mud? But this really is a common pattern. For example, let's say we want to know if one vector is longer than another, we would previously have written:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"vscode": {
"languageId": "apl"
}
},
"outputs": [
{
"data": {
"text/html": [
"0\n",
""
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X ← ⍳7\n",
"Y ← ⍳9\n",
"(≢X)>(≢Y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using `over` we can instead now write"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"vscode": {
"languageId": "apl"
}
},
"outputs": [
{
"data": {
"text/html": [
"0\n",
""
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X >⍥≢ Y"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In words: first apply the right function to both arguments, then apply the left between the results. And of course, either side can be a user-defined function, too. Which vector have the most even numbers?"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"vscode": {
"languageId": "apl"
}
},
"outputs": [
{
"data": {
"text/html": [
"0\n",
""
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"X >⍥{+/0=2|⍵} Y"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"vscode": {
"languageId": "apl"
}
},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Dyalog APL",
"language": "apl",
"name": "dyalog-kernel"
},
"language_info": {
"file_extension": ".apl",
"mimetype": "text/apl",
"name": "APL"
}
},
"nbformat": 4,
"nbformat_minor": 4
}