Arrow mania
7 min read

Arrow mania

The Fortress language is a lesser-known programming language currently in development which among other things promises to simplify concurrency via parallelism. It also allows the definition of various operators and complicated precedence rules in ASCII, defining the way code will be presented in LaTeX and how some character combinations would be translated to symbols.

There was an article in the wiki that drew my attention about defining which ASCII sequences should map to every Unicode arrow-like character. It's an amusing article with little applicability for most conventional programming languages. Only a small minority of them define the way their code should be presented, however, a couple do allow the definition of operators or functions of a reasonable set of non-alphanumeric ASCII characters.

This is of use for, e.g, Haskell, Clojure programmers who might want to use the following sensible guidelines if implementing some sort of Mathematical operator that has an adopted arrow symbol. I hope the original author does not mind this article being copied in here. I claim no rights and no ownership. Enjoy the copy below and the gist.

Representing "Arrows" in ASCII

Here is a set of guiding principles for defining ASCII-expressible tokens for arrows and arrow-like things.

Just as we reserved a space of ASCII-expressible tokens to serve for brackets, we can reserve some tokens that would otherwise never occur in practice for arrows. Unfortunately, it's hard to express up and down arrows, but we can do quite well for left and right arrows.

We will just describe right arrows here. Left arrows are obtained by a fairly obvious reversal of characters and using < for >. Bidirectional arrows are made by using two heads rather than a head and a tail.

A right arrow has a right-pointing tail, a body, and a right-pointing head. The body may include a center. At least one of the head, the center, and the tail must be nonempty.

A right-pointing tail consists of some number (possibly zero) of | characters followed by some number (possibly zero) of > characters; among these may be interspersed * characters, but never two * characters in a row, and never a * at the left-hand end.

A body consists of some nonzero number of -, =, and ~ characters. If the body consists of more than two characters, then it may contain a center, provided that there must be at least one body character on each side of the center. (If there is no center, we may simply say that the center is empty.)

A nonempty center consists of some nonzero number of / characters, some nonzero number of | characters, or a single *.

A right-pointing head consists of either (a) some number of |, <, and > characters provided that at least one > is present and that any < must be followed (not necessarily immediately) by a >; or (b) some nonzero number of \ characters or some nonzero number of / characters, followed by some number (possibly zero) of | characters (this case is used for harpoons); or (c) no characters (this case is used for arrow tails and tacks). In either case (a) or case (b), there may be interspersed * characters, but never two * characters in a row, and never a * at the right-hand end. If the head belongs to case (b), then the body must contain at least two characters.

Certain of these are used as Twiki for Unicode arrows. As a rule, we try to make faithful pictures of the arrows, but by convention we use =- for a triple shaft and -=- for a quadruple shaft; |> indicates an open arrowhead, and * indicates blackness.

-> U+2192 RIGHTWARDS ARROW
-/-> U+219B RIGHTWARDS ARROW WITH STROKE
~> U+219D RIGHTWARDS WAVE ARROW
->> U+21A0 RIGHTWARDS TWO HEADED ARROW
-> U+21A3 RIGHTWARDS ARROW WITH TAIL
|-> U+21A6 RIGHTWARDS ARROW FROM BAR
=/=> U+21CF RIGHTWARDS DOUBLE ARROW WITH STROKE
=> U+21D2 RIGHTWARDS DOUBLE ARROW
=-> U+21DB RIGHTWARDS TRIPLE ARROW
~~> U+21DD RIGHTWARDS SQUIGGLE ARROW
->| U+21E5 RIGHTWARDS ARROW TO BAR
|=|> U+21E8 RIGHTWARDS WHITE ARROW
||=|> U+21F0 RIGHTWARDS WHITE ARROW FROM WALL
-|-> U+21F8 RIGHTWARDS ARROW WITH VERTICAL STROKE
-||-> U+21FB RIGHTWARDS ARROW WITH DOUBLE VERTICAL STROKE
-|> U+21FE RIGHTWARDS OPEN-HEADED ARROW
-*-*> U+2794 HEAVY WIDE-HEADED RIGHTWARDS ARROW
=*-*> U+2799 HEAVY RIGHTWARDS ARROW
--*> U+279B DRAFTING POINT RIGHTWARDS ARROW
=*=*> U+279C HEAVY ROUND-TIPPED RIGHTWARDS ARROW
-|*> U+279D TRIANGLE-HEADED RIGHTWARDS ARROW
-*-|*> U+279E HEAVY TRIANGLE-HEADED RIGHTWARDS ARROW
=*=|*> U+27A1 BLACK RIGHTWARDS ARROW
|*=*=*> U+27A7 SQUAT BLACK RIGHTWARDS ARROW
|=|>*> U+27A9 RIGHT-SHADED WHITE RIGHTWARDS ARROW
|*=|> U+27AA LEFT-SHADED WHITE RIGHTWARDS ARROW
-> U+27B3 WHITE-FEATHERED RIGHTWARDS ARROW
*>-> U+27B5 BLACK-FEATHERED RIGHTWARDS ARROW
*>-*> U+27B8 HEAVY BLACK-FEATHERED RIGHTWARDS ARROW
*>-|*> U+27BC WEDGE-TAILED RIGHTWARDS ARROW
*>*>-|*> U+27BD HEAVY WEDGE-TAILED RIGHTWARDS ARROW
--> U+27F6 LONG RIGHTWARDS ARROW
==> U+27F9 LONG RIGHTWARDS DOUBLE ARROW
|--> U+27FC LONG RIGHTWARDS ARROW FROM BAR
|==> U+27FE LONG RIGHTWARDS DOUBLE ARROW FROM BAR
~~~> U+27FF LONG RIGHTWARDS SQUIGGLE ARROW
-|->> U+2900 RIGHTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE
-||->> U+2901 RIGHTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE
=|=> U+2903 RIGHTWARDS DOUBLE ARROW WITH VERTICAL STROKE
|->> U+2905 RIGHTWARDS TWO-HEADED ARROW FROM BAR
|=> U+2907 RIGHTWARDS DOUBLE ARROW FROM BAR
-|-> U+2914 RIGHTWARDS ARROW WITH TAIL WITH VERTICAL STROKE
-||-> U+2915 RIGHTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE
->> U+2916 RIGHTWARDS TWO-HEADED ARROW WITH TAIL
-|->> U+2917 RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE
-||->> U+2918 RIGHTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE
-- U+291A RIGHTWARDS ARROW-TAIL
-- U+291C RIGHTWARDS DOUBLE ARROW-TAIL
-><*> U+291E RIGHTWARDS ARROW TO BLACK DIAMOND
|-><*> U+2920 RIGHTWARDS ARROW FROM BAR TO BLACK DIAMOND
~-> U+2933 WAVE ARROW POINTING DIRECTLY RIGHT
-=-> U+2B46 RIGHTWARDS QUADRUPLE ARROW
<- U+2190 LEFTWARDS ARROW
<-/- U+219A LEFTWARDS ARROW WITH STROKE
<~ U+219C LEFTWARDS WAVE ARROW
<<- U+219E LEFTWARDS TWO HEADED ARROW
<-< U+21A2 LEFTWARDS ARROW WITH TAIL
<-| U+21A4 LEFTWARDS ARROW FROM BAR
<=/= U+21CD LEFTWARDS DOUBLE ARROW WITH STROKE
<= U+21D0 LEFTWARDS DOUBLE ARROW
<-= U+21DA LEFTWARDS TRIPLE ARROW
<~~ U+21DC LEFTWARDS SQUIGGLE ARROW
|<- U+21E4 LEFTWARDS ARROW TO BAR
<|=| U+21E6 LEFTWARDS WHITE ARROW
<-|- U+21F7 LEFTWARDS ARROW WITH VERTICAL STROKE
<-||- U+21FA LEFTWARDS ARROW WITH DOUBLE VERTICAL STROKE
<|- U+21FD LEFTWARDS OPEN-HEADED ARROW
<-- U+27F5 LONG LEFTWARDS ARROW
<== U+27F8 LONG LEFTWARDS DOUBLE ARROW
<--| U+27FB LONG LEFTWARDS ARROW FROM BAR
<==| U+27FD LONG LEFTWARDS DOUBLE ARROW FROM BAR
<=|= U+2902 LEFTWARDS DOUBLE ARROW WITH VERTICAL STROKE
|=> U+2906 LEFTWARDS DOUBLE ARROW FROM BAR
--< U+2919 LEFTWARDS ARROW-TAIL
--<< U+291B LEFTWARDS DOUBLE ARROW-TAIL
<*><- U+291D LEFTWARDS ARROW TO BLACK DIAMOND
<*><-| U+291F LEFTWARDS ARROW FROM BAR TO BLACK DIAMOND
<*|=*= U+2B05 LEFTWARDS BLACK ARROW
<~~~ U+2B33 LONG LEFTWARDS SQUIGGLE ARROW
<<-|- U+2B34 LEFTWARDS TWO-HEADED ARROW WITH VERTICAL STROKE
<<-||- U+2B35 LEFTWARDS TWO-HEADED ARROW WITH DOUBLE VERTICAL STROKE
<<-| U+2B36 LEFTWARDS TWO-HEADED ARROW FROM BAR
<-|-< U+2B39 LEFTWARDS ARROW WITH TAIL WITH VERTICAL STROKE
<-||-< U+2B3A LEFTWARDS ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE
<<-< U+2B3B LEFTWARDS TWO-HEADED ARROW WITH TAIL
<<-|-< U+2B3C LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH VERTICAL STROKE
<<-||-< U+2B3D LEFTWARDS TWO-HEADED ARROW WITH TAIL WITH DOUBLE VERTICAL STROKE
<-~ ⬿ U+2B3F WAVE ARROW POINTING DIRECTLY LEFT
<-=- U+2B45 LEFTWARDS QUADRUPLE ARROW
<-> U+2194 LEFT RIGHT ARROW
<~> U+21AD LEFT RIGHT WAVE ARROW
<-/-> U+21AE LEFT RIGHT ARROW WITH STROKE
<=/=> U+21CE LEFT RIGHT DOUBLE ARROW WITH STROKE
<=> U+21D4 LEFT RIGHT DOUBLE ARROW
<-|-> U+21F9 LEFT RIGHT ARROW WITH VERTICAL STROKE
<-||-> U+21FC LEFT RIGHT ARROW WITH DOUBLE VERTICAL STROKE
<|-|> U+21FF LEFT RIGHT OPEN-HEADED ARROW
<--> U+27F7 LONG LEFT RIGHT ARROW
<==> U+27FA LONG LEFT RIGHT DOUBLE ARROW
<=|=> U+2904 LEFT RIGHT DOUBLE ARROW WITH VERTICAL STROKE
<|=|> U+2B04 LEFT RIGHT WHITE ARROW
<*|=*=|*> U+2B0C LEFT RIGHT BLACK ARROW
--\ U+21C0 RIGHTWARDS HARPOON WITH BARB UPWARDS
--/ U+21C1 RIGHTWARDS HARPOON WITH BARB DOWNWARDS
--\| U+2953 RIGHTWARDS HARPOON WITH BARB UP TO BAR
--/| U+2957 RIGHTWARDS HARPOON WITH BARB DOWN TO BAR
|--\ U+295B RIGHTWARDS HARPOON WITH BARB UP FROM BAR
|--/ U+295F RIGHTWARDS HARPOON WITH BARB DOWN FROM BAR
/-- U+21BC LEFTWARDS HARPOON WITH BARB UPWARDS
\-- U+21BD LEFTWARDS HARPOON WITH BARB DOWNWARDS
|/-- U+2952 LEFTWARDS HARPOON WITH BARB UP TO BAR
|\-- U+2956 LEFTWARDS HARPOON WITH BARB DOWN TO BAR
/--| U+295A LEFTWARDS HARPOON WITH BARB UP FROM BAR
\--| U+295E LEFTWARDS HARPOON WITH BARB DOWN FROM BAR
/==/ U+21CB LEFTWARDS HARPOON OVER RIGHTWARDS HARPOON
\==\ U+21CC RIGHTWARDS HARPOON OVER LEFTWARDS HARPOON
/--/ U+294A LEFT BARB UP RIGHT BARB DOWN HARPOON
\--\ U+294B LEFT BARB DOWN RIGHT BARB UP HARPOON
/--\ U+294E LEFT BARB UP RIGHT BARB UP HARPOON
\--/ U+2950 LEFT BARB DOWN RIGHT BARB DOWN HARPOON
|-- U+22A2 RIGHT TACK
|- U+22A6 ASSERTION
|= U+22A7 MODELS
|== U+22A8 TRUE
||-- U+22A9 FORCES
|||- U+22AA TRIPLE VERTICAL BAR RIGHT TURNSTILE
||== U+22AB DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
|-/- U+22AC DOES NOT PROVE
|=/= U+22AD NOT TRUE
||-/- U+22AE DOES NOT FORCE
||=/= U+22AF NEGATED DOUBLE VERTICAL BAR DOUBLE RIGHT TURNSTILE
|--- U+27DD LONG RIGHT TACK
--| U+22A3 LEFT TACK
---| U+27DE LONG LEFT TACK
-| U+2ADE SHORT LEFT TACK
--|| U+2AE3 DOUBLE VERTICAL BAR LEFT TURNSTILE
==| U+2AE4 VERTICAL BAR DOUBLE LEFT TURNSTILE
==|| U+2AE5 DOUBLE VERTICAL BAR DOUBLE LEFT TURNSTILE
-||- U+27DB LEFT AND RIGHT TACK
=||= U+27DA LEFT AND RIGHT DOUBLE TURNSTILE

Note that, under these rules, the ASCII token =/= for "not equals" is considered an "arrow", not that it really matters. The other two cases of interest that have empty head and empty tail are -||- for ⟛ U+27DB LEFT AND RIGHT TACK and =||= for U+27DA LEFT AND RIGHT DOUBLE TURNSTILE.