### More arithmetic operations now implemented in compiler

#### By gls on Jul 22, 2011

The Fortress compiler now implements some additional arithmetic operations.

For type\(\mskip3mu\) \(\newcommand\EXP[1]{#1} \newcommand\KWD[1]{\mathrel{\mathtt{#1}}} \newcommand\KWDVAR[1]{\mathord{\mathtt{#1}}} \newcommand\OPR[1]{\mathbin{\mathtt{#1}}} \newcommand\BIGOPR[1]{\mathop{\lower0.4ex\hbox{\vrule height 1.2em depth 0.1em width 0pt\Large$\mathtt{#1}$}}} \newcommand\BIGOP[1]{\mathop{\lower0.2ex\hbox{\Large$#1$}}} \newcommand\TYP[1]{\mathord{\mathrm{#1}}} \newcommand\VAR[1]{\mathord{\mathit{#1}}} \newcommand\STR[1]{\hbox{\tt\usefont{T1}{pcr}{m}{n}\selectfont#1}} \newcommand\CONDEQ{\mathrel{\mathtt{:}}=\mathrel{\mathtt{:}}} \newcommand\ASSIGN{\mathrel{\mathtt{:}}=} \newcommand\COLON{\mathpunct{\mathtt{:}}} \newcommand\COLONOP{\mathinner{\mathtt{:}}} \newcommand\SHORTCUT[1]{\mathrel{\mathord{#1}\mathord{:}}} \newcommand\twointersectand{\mathbin{\wedge\mskip-10mu\wedge}} \newcommand\twointersector{\mathbin{\vee\mskip-10mu\vee}} \newcommand\twointersectxor{\mathbin{\underline{\vee\mskip-10mu\vee}}} \newcommand\twointersectnot{\mathbin{\neg\mskip-8mu\neg}} \newcommand\verythin{{\mskip 1.5mu}} \newcommand\ultrathin{{\mskip 0.75mu}} \def\Vvert{\mathrel{\vert\mskip-1.5mu\vert\mskip-1.5mu\vert}} \def\VVert{\mathrel{\vert\mskip-1.5mu\vert\mskip-1.5mu\vert\mskip-1.5mu\vert}} \def\sequiv{\mathrel{\hbox{\raise0.215ex\hbox to 0pt{$\equiv$\hss}\lower0.215ex\hbox{$\equiv$}}}} \newcommand\bigllbracket{\bigl[\mkern-5mu\bigl[} \newcommand\bigrrbracket{\bigr]\mkern-5mu\bigr]} \newcommand\Bigllbracket{\Bigl[\mkern-5.5mu\Bigl[} \newcommand\Bigrrbracket{\Bigr]\mkern-5.5mu\Bigr]} \newcommand\biggllbracket{\biggl[\mkern-6mu\biggl[} \newcommand\biggrrbracket{\biggr]\mkern-6mu\biggr]} \newcommand\Biggllbracket{\Biggl[\mkern-6.5mu\Biggl[} \newcommand\Biggrrbracket{\Biggr]\mkern-6.5mu\Biggr]} \newcommand\leftllbracket{\left[\mkern-5.5mu\left[} \newcommand\rightrrbracket{\right]\mkern-5.5mu\right]}\EXP{\mathbb{Z}32}\mskip3mu\):

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\twointersectnot}(\KWDVAR{self})\COLON \mathbb{Z}32}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\twointersectand}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}32)\COLON \mathbb{Z}32}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\twointersector}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}32)\COLON \mathbb{Z}32}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\twointersectxor}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}32)\COLON \mathbb{Z}32}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MIN}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}32)\COLON \mathbb{Z}32}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MAX}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}32)\COLON \mathbb{Z}32}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MINMAX}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}32)\COLON (\mathbb{Z}32, \mathbb{Z}32)}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\VAR{even}(\KWDVAR{self})\COLON \TYP{Boolean}}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\VAR{odd}(\KWDVAR{self})\COLON \TYP{Boolean}}\mskip3mu\) |

The first four are bitwise NOT, AND, OR, and XOR operations. \(\OPR{MINMAX}\mskip3mu\) returns a 2-tuple of its two arguments, sorted so that the first element of the tuple is not larger than the second value.

For type\(\mskip3mu\) \(\EXP{\mathbb{Z}64}\mskip3mu\):

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\twointersectnot}(\KWDVAR{self})\COLON \mathbb{Z}64}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\twointersectand}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}64)\COLON \mathbb{Z}64}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\twointersector}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}64)\COLON \mathbb{Z}64}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\twointersectxor}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}64)\COLON \mathbb{Z}64}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MIN}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}64)\COLON \mathbb{Z}64}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MAX}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}64)\COLON \mathbb{Z}64}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MINMAX}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{Z}64)\COLON (\mathbb{Z}64, \mathbb{Z}64)}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\VAR{even}(\KWDVAR{self})\COLON \TYP{Boolean}}\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\VAR{odd}(\KWDVAR{self})\COLON \TYP{Boolean}}\mskip3mu\) |

For type\(\mskip3mu\) \(\EXP{\mathbb{R}64}\mskip3mu\):

\(\mskip3mu\)\(\EXP{\KWD{getter} \VAR{isNaN}(\ultrathin)\COLON \TYP{Boolean} }\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MIN}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{R}64)\COLON \mathbb{R}64 }\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MAX}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{R}64)\COLON \mathbb{R}64 }\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MINNUM}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{R}64)\COLON \mathbb{R}64 }\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MAXNUM}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{R}64)\COLON \mathbb{R}64 }\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MINNUMMAX}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{R}64)\COLON (\mathbb{R}64, \mathbb{R}64) }\mskip3mu\) | |

\(\mskip3mu\)\(\EXP{\KWD{opr}\, \mathord{\OPR{MINMAXNUM}}(\KWDVAR{self}, \VAR{other}\COLON\mathbb{R}64)\COLON (\mathbb{R}64, \mathbb{R}64) }\mskip3mu\) |

\(\OPR{MIN}\mskip3mu\) and\(\mskip3mu\) \(\OPR{MAX}\mskip3mu\) return NaN is either argument is NaN;\(\mskip3mu\) \(\OPR{MINNUM}\mskip3mu\) and\(\mskip3mu\) \(\OPR{MAXNUM}\mskip3mu\), if either argument is NaN, return the other argument (and so the result is NaN only if both arguments are NaN).\(\mskip3mu\) \(\OPR{MINNUMMAX}\mskip3mu\) and\(\mskip3mu\) \(\OPR{MINMAXNUM}\mskip3mu\) both return a 2-tuple of the two arguments, sorted so that the first element of the tuple is not larger than the second value; but if one argument is NaN and the other is some non-NaN value\(\mskip1.5mu\) \(\VAR{v}\mskip1.5mu\), then\(\mskip3mu\) \(\OPR{MINNUMMAX}\mskip3mu\) returns\(\mskip3mu\) \(\EXP{(v,\TYP{NaN})}\mskip3mu\) but\(\mskip3mu\) \(\OPR{MINMAXNUM}\mskip3mu\) returns\(\mskip3mu\) \(\EXP{(\TYP{NaN},v)}\mskip3mu\).

For type\(\mskip1.5mu\) \(\TYP{String}\mskip1.5mu\):

\(\mskip3mu\)\(\EXP{\KWD{opr} \unicode{x5E}(\KWDVAR{self}, n\COLON \mathbb{Z}32)\COLON \TYP{String}}\mskip3mu\) |

(This last operation returns the concatenation of\(\mskip1.5mu\) \(\VAR{n}\mskip1.5mu\) copies of the string.)

One can also make a character, given its codepoint, by using\(\mskip1.5mu\) \(\VAR{makeCharacter}\mskip1.5mu\):

\(\mskip3mu\)\(\EXP{\VAR{makeCharacter}(n\COLON \mathbb{Z}32)\COLON \TYP{Character}}\mskip3mu\) |

I'm curious, at what stage is this project? Is anyone actually using Fortress today for small projects in scientific computing? Would you recommend that people do, at the project's current state? If not, when do you expect it'd get there?

Posted by

Szabolcson August 08, 2011 at 01:44 AM EDT #I noticed ZZ32 and ZZ64 have methods even() and odd(), but Character has lots of method names starting with 'is', e.g. isFortressIdentifierPart(). Sure, most of the latter names come straight from Java, but are you adopting the convention that methods returning Boolean start with 'is' or not?

I only ask because names of methods/classes tend to get set in stone and are difficult to change later...

(FWIW given the mathematical flavour of Fortress I'd suggest not using 'is'.)

Posted by

Jonathanon August 19, 2011 at 01:58 AM EDT #@Jonathan: You make a good point about the inconsistency of the use of the prefix "is" in the names of predicate methods. Part of the problem is tradition: mathematicians tend not to use "is", especially for short adjectives such as "even" and "odd" and "prime". On the other hand, the character predicates and their names were taken pretty much wholesale form Java. We need to think this issue through more carefully.

Posted by

Guy Steeleon September 02, 2011 at 11:50 AM EDT #@Szaboics: The intepreter works (and has for several years), but supports a version of the type system that is now obsolescent. We are pushing to get the compiler to process some small demonstration scientific applications so that we can measure parallel scaling.

Posted by

Guy Steeleon September 02, 2011 at 11:52 AM EDT #Hello, I'm wondering if this project is still alive?

Posted by

Astrychon July 11, 2012 at 10:21 AM EDT #Guy Steele was here in London talking about Fortress (which I missed alas), so I assume it's alive and kicking:

http://days2012.scala-lang.org/node/434

Nobody is waiting more eagerly than me to try out a near-complete version. It seems like the language I'd want to use for everything - a little like Scala but with added simplicity.

Posted by

Jonathanon July 20, 2012 at 05:36 PM EDT #