Changeset 4312
- Timestamp:
- 11/04/09 05:56:40 (3 weeks ago)
- Location:
- trunk/Specification
- Files:
-
- 16 modified
-
advanced/defining-dimensions.tex (modified) (1 diff)
-
advanced/domain-specific-languages.tex (modified) (1 diff)
-
advanced/operator-definitions.tex (modified) (1 diff)
-
advanced/overloading.tex (modified) (1 diff)
-
advanced/parallelism-locality/arrays-distributed.tex (modified) (1 diff)
-
advanced/parallelism-locality/defining-generators.tex (modified) (1 diff)
-
advanced/parallelism-locality/distributions.tex (modified) (1 diff)
-
advanced/parallelism-locality/early-termination.tex (modified) (1 diff)
-
advanced/parallelism-locality/intro.tex (modified) (1 diff)
-
advanced/parallelism-locality/primitives-distributions.tex (modified) (1 diff)
-
advanced/parallelism-locality/regions-threads.tex (modified) (1 diff)
-
advanced/parallelism-locality/shared-local.tex (modified) (1 diff)
-
advanced/parallelism-locality/transactions.tex (modified) (1 diff)
-
advanced/subscripting.tex (modified) (1 diff)
-
basic/overloading.tex (modified) (1 diff)
-
fortress/fortress.bib (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Specification/advanced/defining-dimensions.tex
r4271 r4312 18 18 \chapter{Dimension and Unit Declarations} 19 19 \chaplabel{declaring-dimunits} 20 21 \note{Dimensions and units are not yet supported.} 22 23 \begin{Grammar} 24 \emph{DimUnitDecl} 25 &::=& 26 \KWD{dim} \emph{Id} \options{\EXP{=} \emph{Type}} 27 (\KWD{unit} $|$ \KWD{SI\_unit}) \emph{Id}$^+$ 28 \options{\EXP{=} \emph{Expr}}\\ 29 &$|$& 30 \KWD{dim} \emph{Id} 31 \options{\EXP{=} \emph{Type}} \options{\KWD{default} \emph{Id}}\\ 32 &$|$& 33 (\KWD{unit} $|$ \KWD{SI\_unit}) 34 \emph{Id}$^+$ \options{\EXP{\mathrel{\mathtt{:}}} \emph{Type}} 35 \options{\EXP{=} \emph{Expr}}\\ 36 \end{Grammar} 37 38 \section{Dimension Declarations} 39 Dimensions may be explicitly declared; 40 every declared dimension must be declared at the top level 41 of a program component, 42 not within a block expression or trait. 43 Other dimensions may be constructed by multiplying and dividing other dimensions, 44 as described in \chapref{dimunits}. 45 An explicitly declared dimension may be a \emph{base dimension} (with no definition specified) 46 or a \emph{derived dimension} (with a definition specified in the form of an initialization expression). 47 48 The set of all dimensions has the algebraic structure of a free abelian group. 49 The identity element of this group is the dimension \TYP{Unity}, which represents dimensionlessness. 50 51 For every two dimensions \VAR{D} and \VAR{E}, there is a 52 dimension \EXP{D E} (which may also be written \EXP{D \cdot E}), 53 corresponding to the product of the dimensions \VAR{D} and \VAR{E} and a 54 dimension \EXP{D/E}, corresponding to the quotient of the 55 dimensions \VAR{D} and \VAR{E}. The syntactic sugar \EXP{1/D} is equivalent 56 to \EXP{\TYP{Unity}/D} for all dimensions \VAR{D}. 57 A dimension can be raised to a rational power where both 58 the numerator and the denominator of the rational power 59 must be a valid \emph{\KWD{nat} parameter} instantiation; 60 \EXP{D^{0}} is the same as \TYP{Unity}, 61 \EXP{D^{1}} is the same as \VAR{D}, and 62 \EXP{D^{m+n}} is the same as \EXP{D^{m} D^{n}}. 63 The syntactic sugar \EXP{D^{-n}} is the same as \EXP{\TYP{Unity}/D^{n}}. 64 65 Here are some examples of base dimension declarations: 66 %% dim Length 67 %% dim Mass 68 %% dim Time 69 %% dim ElectricCurrent 70 \begin{Fortress} 71 \(\KWD{dim} \TYP{Length}\)\\ 72 \(\KWD{dim} \TYP{Mass}\)\\ 73 \(\KWD{dim} \TYP{Time}\)\\ 74 \(\KWD{dim} \TYP{ElectricCurrent}\) 75 \end{Fortress} 76 Here are some examples of computed dimensions: 77 %% Length / Time 78 %% Velocity / Time 79 %% Length \cdot Mass / Time^2 80 %% Length Mass Time^(-2) 81 %% ElectricCurrent / Length^2 82 \begin{Fortress} 83 \(\TYP{Length} / \TYP{Time}\)\\ 84 \(\TYP{Velocity} / \TYP{Time}\)\\ 85 \(\TYP{Length} \cdot \TYP{Mass} / \TYP{Time}^{2}\)\\ 86 \(\TYP{Length}\mskip 4mu plus 4mu\TYP{Mass}\mskip 4mu plus 4mu\TYP{Time}^{-2}\)\\ 87 \(\TYP{ElectricCurrent} / \TYP{Length}^{2}\) 88 \end{Fortress} 89 and here some of these computed dimensions are given names through the use of 90 derived dimension declarations: 91 %% dim Velocity = Length / Time 92 %% dim Acceleration = Velocity / Time 93 %% dim CurrentDensity = ElectricCurrent / Length^2 94 \begin{Fortress} 95 \(\KWD{dim} \TYP{Velocity} = \TYP{Length} / \TYP{Time}\)\\ 96 \(\KWD{dim} \TYP{Acceleration} = \TYP{Velocity} / \TYP{Time}\)\\ 97 \(\KWD{dim} \TYP{CurrentDensity} = \TYP{ElectricCurrent} / \TYP{Length}^{2}\) 98 \end{Fortress} 99 100 \section{Unit Declarations} 101 Every unit belongs to exactly one dimension, which is the type of the unit. 102 A dimension may have more than one unit, 103 but one of these units may be singled out as the \emph{default unit} for that dimension 104 by adding a \KWD{default} clause: 105 %% dim Length default meter 106 %% dim Mass default kilogram 107 %% dim Time default second 108 \begin{Fortress} 109 \(\KWD{dim} \TYP{Length} \KWD{default} \TYP{meter}\)\\ 110 \(\KWD{dim} \TYP{Mass} \KWD{default} \TYP{kilogram}\)\\ 111 \(\KWD{dim} \TYP{Time} \KWD{default} \TYP{second}\) 112 \end{Fortress} 113 The default unit is used when a numerical type is multiplied by a 114 dimension to produce a new type (see \chapref{dimunits}). 115 If no default clause is specified for a base dimension, then it has 116 no default unit. If no default clause is specified for a derived 117 dimension, then it has a default unit if and only if all the 118 dimensions mentioned in its initialization expression have defaults, 119 in which case its default unit is calculated using the initialization 120 expression with each dimension replaced by its default unit. 121 122 Some units are explicitly declared; 123 every declared unit must be declared at the top level of 124 a program component, not 125 within a block expression or trait. 126 Other units may be constructed by multiplying and dividing other units. 127 An explicitly declared unit may be a \emph{base unit} (with no definition specified) 128 or a \emph{derived unit} (with a definition specified in the form of an initialization expression). 129 130 The set of all units, like the set of all dimensions, has the algebraic structure of a free abelian group. 131 The identity element of this group is the unit \TYP{dimensionless}, of 132 dimension \TYP{Unity}. 133 Note that there may be other units of dimension \TYP{Unity}, such as 134 \TYP{radian} and \TYP{steradian}, but only \TYP{dimensionless} is the 135 identity of the group of all units. 136 (Note that there is a straightforward homomorphism of units onto 137 dimensions, wherein every unit is mapped to its dimension.) 138 139 Here are some examples of base unit declarations: 140 %% unit meter : Length 141 %% unit kilogram : Mass 142 %% unit second : Time 143 %% unit ampere : ElectricCurrent 144 \begin{Fortress} 145 \(\KWD{unit} \TYP{meter} \mathrel{\mathtt{:}} \TYP{Length}\)\\ 146 \(\KWD{unit} \TYP{kilogram} \mathrel{\mathtt{:}} \TYP{Mass}\)\\ 147 \(\KWD{unit} \TYP{second} \mathrel{\mathtt{:}} \TYP{Time}\)\\ 148 \(\KWD{unit} \TYP{ampere} \mathrel{\mathtt{:}} \TYP{ElectricCurrent}\) 149 \end{Fortress} 150 Here are some examples of computed units: 151 %% meter / second 152 %% (meter / second) / second 153 %% meter \cdot kilogram / second^2 154 %% meter kilogram second^(-2) 155 %% ampere / meter^2 156 \begin{Fortress} 157 \(\TYP{meter} / \TYP{second}\)\\ 158 \((\TYP{meter} / \TYP{second}) / \TYP{second}\)\\ 159 \(\TYP{meter} \cdot \TYP{kilogram} / \TYP{second}^{2}\)\\ 160 \(\TYP{meter}\mskip 4mu plus 4mu\TYP{kilogram}\mskip 4mu plus 4mu\TYP{second}^{-2}\)\\ 161 \(\TYP{ampere} / \TYP{meter}^{2}\) 162 \end{Fortress} 163 and here some computed units are given names through the use of 164 derived unit declarations: 165 %% unit newton: Force = meter \cdot kilogram / second^2 166 %% unit joule: Energy = newton meter 167 %% unit pascal: Pressure = newton / meter^2 168 \begin{Fortress} 169 \(\KWD{unit} \TYP{newton}\COLON \TYP{Force} = \TYP{meter} \cdot \TYP{kilogram} / \TYP{second}^{2}\)\\ 170 \(\KWD{unit} \TYP{joule}\COLON \TYP{Energy} = \TYP{newton}\mskip 4mu plus 4mu\TYP{meter}\)\\ 171 \(\KWD{unit} \TYP{pascal}\COLON \TYP{Pressure} = \TYP{newton} / \TYP{meter}^{2}\) 172 \end{Fortress} 173 In the preceding examples, the initialization expression for each unit 174 is itself a unit. It is also permitted for the initialization 175 expression to be a dimensioned numerical value, in which case 176 the unit being declared is related to the unit of the dimensioned 177 numerical value by a numerical conversion factor. 178 179 As with an ordinary variable declaration, one may omit the dimension for a unit 180 if there is an initialization expression; the dimension of the declared unit is 181 the dimension of the unit of the expression. 182 183 \note{COMMENTED TEXT; I like the explanation below better. -- Eric 184 185 Every unit can be reduced to a canonical unit as follows. A base unit is 186 canonical; a \KWD{unit} parameter is canonical; a defined unit is replaced 187 by its initialization expression, 188 but only if the value of the expression 189 is a unit and not a dimensioned value, where every unit in that expression 190 is replaced by its canonical unit; 191 and finally all arithmetic is performed 192 so as to reduce the expression to a single unit. Two units are considered 193 equivalent if their canonical units are identical. 194 195 Now here is a slightly different process. 196 } 197 198 Every unit can be reduced to a canonical value as follows. A base unit is 199 multiplied by the value \EXP{1}; a \KWD{unit} parameter is multiplied by 200 the value \EXP{1}; a defined unit is replaced by its initialization 201 expression and then every unit in that expression is replaced by its 202 canonical form; 203 and finally all arithmetic is performed so as to reduce the 204 units to a single unit and the 205 numerical values to a single numerical value. A dimensioned value with unit 206 \VAR{U} is convertible by the \KWD{in} operator to a value with unit 207 \VAR{V} if the canonical values for \VAR{U} and \VAR{V} have the same 208 unit; the conversion involves multiplying the numerical value by the 209 ratio of the numerical value of the canonical form 210 of \VAR{V} to the numerical value of the canonical form of \VAR{U}. 211 212 For example, given the declarations: 213 %% dim Length 214 %% unit meter: Length; unit meters = meter 215 %% unit kilometer: Length = 10^3 meter; unit kilometers = kilometer 216 %% unit inch: Length = 2.54 \times 10^(-2) meter; unit inches = inch 217 %% unit foot: Length = 12 inch; unit feet = foot 218 %% unit mile: Length = 5280 foot; unit miles = mile 219 \begin{Fortress} 220 \(\KWD{dim} \TYP{Length}\)\\ 221 \(\KWD{unit} \TYP{meter}\COLON \TYP{Length}; \KWD{unit} \TYP{meters} = \TYP{meter}\)\\ 222 \(\KWD{unit} \TYP{kilometer}\COLON \TYP{Length} = 10^{3} \TYP{meter}; \KWD{unit} \TYP{kilometers} = \TYP{kilometer}\)\\ 223 \(\KWD{unit} \TYP{inch}\COLON \TYP{Length} = 2.54 \times 10^{-2} \TYP{meter}; \KWD{unit} \TYP{inches} = \TYP{inch} \)\\ 224 \(\KWD{unit} \TYP{foot}\COLON \TYP{Length} = 12\,\TYP{inch}; \KWD{unit} \TYP{feet} = \TYP{foot}\)\\ 225 \(\KWD{unit} \TYP{mile}\COLON \TYP{Length} = 5280\,\TYP{foot}; \KWD{unit} \TYP{miles} = \TYP{mile}\) 226 \end{Fortress} 227 then one can say \EXP{3\,\TYP{miles}\, \KWD{in}\, \TYP{kilometers}} and 228 the \KWD{in} operator will multiply the numerical value \EXP{3} by 229 the amount of 230 \EXP{((2.54 \times 10^{-2})(12)(5280)/10^{3})}, 231 or \EXP{25146/15625}. 232 233 Notice the subtle difference between these two declarations: 234 %% unit radian = meter/meter 235 %% unit radian = 1 meter/meter 236 \begin{Fortress} 237 \(\KWD{unit} \TYP{radian} = \TYP{meter}/\TYP{meter}\)\\ 238 \(\KWD{unit} \TYP{radian} = 1\,\TYP{meter}/\TYP{meter}\) 239 \end{Fortress} 240 The first declaration defines \TYP{radian} to be equivalent to 241 \TYP{dimensionless}, and so a value with unit \TYP{radian} can be used 242 anywhere a dimensionless value can be used, and vice versa. 243 The second declaration defines \TYP{radian} to be convertible to 244 \TYP{dimensionless} but not equivalent, and so it is necessary to use 245 the \KWD{in} operator (or multiplication and division by \TYP{radian}) 246 to convert between values in radians and truly dimensionless values. 247 248 249 \section{Abbreviating Dimension and Unit Declarations} 250 \seclabel{abbrev-dimunits} 251 252 For convenience, three forms of syntactic sugar are provided when declaring 253 dimensions and units. 254 First, in a \KWD{unit} declaration one may mention more than one name 255 before the colon, and the extra names are defined to be synonyms for the 256 first name; thus 257 %% unit foot feet ft_: Length 258 \begin{Fortress} 259 \(\KWD{unit} \TYP{foot}\mskip 4mu plus 4mu\TYP{feet}\mskip 4mu plus 4mu\mathrm{ft}\COLON \TYP{Length}\) 260 \end{Fortress} 261 means exactly the same thing as 262 %% unit foot: Length 263 %% unit feet: Length = foot 264 %% unit ft_: Length = foot 265 \begin{Fortress} 266 \(\KWD{unit} \TYP{foot}\COLON \TYP{Length}\)\\ 267 \(\KWD{unit} \TYP{feet}\COLON \TYP{Length} = \TYP{foot}\)\\ 268 \(\KWD{unit} \mathrm{ft}\COLON \TYP{Length} = \TYP{foot}\) 269 \end{Fortress} 270 Second, instead of the reserved word \KWD{unit} one may use the reserved 271 word \KWD{SI\_unit}, which has the effect of defining not only the 272 specified names but also names with the various SI prefixes attached. 273 If more than one name is specified, then the last name is assumed 274 to be a symbol and has symbol prefixes (such as \TYP{M} and \TYP{n}) 275 attached; all other names have the full prefixes (such as 276 \TYP{mega} and \TYP{nano}) attached. 277 Thus 278 %% SI_unit name1 name2 name3: ... 279 \begin{Fortress} 280 \(\KWD{SI{\char'137}unit} {name}_{1}\;\;{name}_{2}\;\;{name}_{3}\COLON \ldots\) 281 \end{Fortress} 282 may be regarded as an abbreviation for 283 %% unit~name1~name2~name3: ... 284 %% unit yotta~name1~yotta name2~Y name3 = 10^24~name1 285 %% unit zetta~name1~zetta name2~Z name3 = 10^21 ~name1 286 %% unit exa~name1~exa name2~E name3 = 10^18 ~name1 287 %% unit peta~name1~peta name2~P name3 = 10^15 ~name1 288 %% unit tera~name1~tera name2~T name3 = 10^12 ~name1 289 %% unit giga~name1~giga name2~G name3 = 10^9 ~name1 290 %% unit mega~name1~mega name2~M name3 = 10^6 ~name1 291 %% unit kilo~name1~kilo name2~k name3 = 10^3 ~name1 292 %% unit hecto~name1~hecto name2~h name3 = 10^2 ~name1 293 %% unit deka~name1~deka name2~da name3 = 10 ~name1 294 %% unit deci~name1~deci name2~d name3 = 10^(-1) ~name1 295 %% unit centi~name1~centi name2~c name3 = 10^(-2) ~name1 296 %% unit milli~name1~milli name2~m name3 = 10^(-3) ~name1 297 %% unit micro~name1~micro name2~micro name3 = 10^(-6) ~name1 298 %% unit nano~name1~nano name2~n name3 = 10^(-9) ~name1 299 %% unit pico~name1~pico name2~p name3 = 10^(-12) ~name1 300 %% unit femto~name1~femto name2~f name3 = 10^(-15) ~name1 301 %% unit atto~name1~atto name2~a name3 = 10^(-18) ~name1 302 %% unit zepto~name1~zepto name2~z name3 = 10^(-21) ~name1 303 %% unit yocto~name1~yocto name2~y name3 = 10^(-24) ~name1 304 \begin{Fortress} 305 \(\KWD{unit} {name}_{1}~{name}_{2}~{name}_{3}\COLON \ldots\)\\ 306 \(\KWD{unit} \TYP{yotta} {name}_{1}~\TYP{yotta} {name}_{2}~ \TYP{Y} {name}_{3} = 10^{24} {name}_{1}\)\\ 307 \(\KWD{unit} \TYP{zetta} {name}_{1}~\TYP{zetta} {name}_{2}~ \TYP{Z} {name}_{3} = 10^{21} {name}_{1}\)\\ 308 \(\KWD{unit} \TYP{exa} {name}_{1}~\TYP{exa} {name}_{2}~ \TYP{E} {name}_{3} = 10^{18} {name}_{1}\)\\ 309 \(\KWD{unit} \TYP{peta} {name}_{1}~\TYP{peta} {name}_{2}~ \TYP{P} {name}_{3} = 10^{15} {name}_{1}\)\\ 310 \(\KWD{unit} \TYP{tera} {name}_{1}~\TYP{tera} {name}_{2}~ \TYP{T} {name}_{3} = 10^{12} {name}_{1}\)\\ 311 \(\KWD{unit} \TYP{giga} {name}_{1}~\TYP{giga} {name}_{2}~ \TYP{G} {name}_{3} = 10^{9} {name}_{1}\)\\ 312 \(\KWD{unit} \TYP{mega} {name}_{1}~\TYP{mega} {name}_{2}~ \TYP{M} {name}_{3} = 10^{6} {name}_{1}\)\\ 313 \(\KWD{unit} \TYP{kilo} {name}_{1}~\TYP{kilo} {name}_{2}~ \TYP{k} {name}_{3} = 10^{3} {name}_{1}\)\\ 314 \(\KWD{unit} \TYP{hecto} {name}_{1}~\TYP{hecto} {name}_{2}~ \TYP{h} {name}_{3} = 10^{2} {name}_{1}\)\\ 315 \(\KWD{unit} \TYP{deka} {name}_{1}~\TYP{deka} {name}_{2}~ \TYP{da} {name}_{3} = 10 {name}_{1}\)\\ 316 \(\KWD{unit} \TYP{deci} {name}_{1}~\TYP{deci} {name}_{2}~ \TYP{d} {name}_{3} = 10^{-1} {name}_{1}\)\\ 317 \(\KWD{unit} \TYP{centi} {name}_{1}~\TYP{centi} {name}_{2}~ \TYP{c} {name}_{3} = 10^{-2} {name}_{1}\)\\ 318 \(\KWD{unit} \TYP{milli} {name}_{1}~\TYP{milli} {name}_{2}~ \TYP{m} {name}_{3} = 10^{-3} {name}_{1}\)\\ 319 \(\KWD{unit} \TYP{micro} {name}_{1}~\TYP{micro} {name}_{2}~ \mu {name}_{3} = 10^{-6} {name}_{1}\)\\ 320 \(\KWD{unit} \TYP{nano} {name}_{1}~\TYP{nano} {name}_{2}~ \TYP{n} {name}_{3} = 10^{-9} {name}_{1}\)\\ 321 \(\KWD{unit} \TYP{pico} {name}_{1}~\TYP{pico} {name}_{2}~ \TYP{p} {name}_{3} = 10^{-12} {name}_{1}\)\\ 322 \(\KWD{unit} \TYP{femto} {name}_{1}~\TYP{femto} {name}_{2}~ \TYP{f} {name}_{3} = 10^{-15} {name}_{1}\)\\ 323 \(\KWD{unit} \TYP{atto} {name}_{1}~\TYP{atto} {name}_{2}~ \TYP{a} {name}_{3} = 10^{-18} {name}_{1}\)\\ 324 \(\KWD{unit} \TYP{zepto} {name}_{1}~\TYP{zepto} {name}_{2}~ \TYP{z} {name}_{3} = 10^{-21} {name}_{1}\)\\ 325 \(\KWD{unit} \TYP{yocto} {name}_{1}~\TYP{yocto} {name}_{2}~ \TYP{y} {name}_{3} = 10^{-24} {name}_{1}\) 326 \end{Fortress} 327 where $\mu$ is the Unicode character U+00B5 MICRO SIGN. 328 Third, a \KWD{dim} declaration and a \KWD{unit} or 329 \EXP{\KWD{SI{\char'137}unit}} declaration 330 may be collapsed into a single declaration by writing the \KWD{unit} 331 or \EXP{\KWD{SI{\char'137}unit}} 332 declaration in place of the \KWD{default} clause in the \KWD{dim} declaration 333 and omitting the colon and dimension from the \KWD{unit} declaration. 334 Thus 335 %% dim Length SI_unit meter meters m_ 336 %% dim Power = Energy/Time SI_unit watt watts W_ = joule/second 337 \begin{Fortress} 338 \(\KWD{dim} \TYP{Length} \KWD{SI{\char'137}unit} \TYP{meter}\mskip 4mu plus 4mu\TYP{meters}\mskip 4mu plus 4mu\mathrm{m}\)\\ 339 \(\KWD{dim} \TYP{Power} = \TYP{Energy}/\TYP{Time} \KWD{SI{\char'137}unit} \TYP{watt}\mskip 4mu plus 4mu\TYP{watts}\mskip 4mu plus 4mu\mathrm{W} = \TYP{joule}/\TYP{second}\) 340 \end{Fortress} 341 is understood to abbreviate 342 %% dim Length default meter; SI_unit meter meters m_: Length 343 %% dim Power = Energy/Time default watt; SI_unit watt watts W_: Power = joule/second 344 \begin{Fortress} 345 \(\KWD{dim} \TYP{Length} \KWD{default} \TYP{meter}; \KWD{SI{\char'137}unit} \TYP{meter}\mskip 4mu plus 4mu\TYP{meters}\mskip 4mu plus 4mu\mathrm{m}\COLON \TYP{Length}\)\\ 346 \(\KWD{dim} \TYP{Power} = \TYP{Energy}/\TYP{Time} \KWD{default} \TYP{watt}; \KWD{SI{\char'137}unit} \TYP{watt}\mskip 4mu plus 4mu\TYP{watts}\mskip 4mu plus 4mu\mathrm{W}\COLON \TYP{Power} = \TYP{joule}/\TYP{second}\) 347 \end{Fortress} 348 In this way the names of the seven SI base units, along with all 349 possible plural and prefixed forms, may be concisely defined as follows: 350 %% dim Length SI_unit meter meters m_ 351 %% dim Mass default kilogram; SI_unit gram grams g_: Mass 352 %% dim Time SI_unit second seconds s_ 353 %% dim ElectricCurrent SI_unit ampere amperes A_ 354 %% dim Temperature SI_unit kelvin kelvins K_ 355 %% dim AmountOfSubstance SI_unit mole moles mol_ 356 %% dim LuminousIntensity SI_unit candela candelas cd_ 357 \begin{Fortress} 358 \(\KWD{dim} \TYP{Length} \KWD{SI{\char'137}unit} \TYP{meter}\mskip 4mu plus 4mu\TYP{meters}\mskip 4mu plus 4mu\mathrm{m} \)\\ 359 \(\KWD{dim} \TYP{Mass} \KWD{default} \TYP{kilogram}; \KWD{SI{\char'137}unit} \TYP{gram}\mskip 4mu plus 4mu\TYP{grams}\mskip 4mu plus 4mu\mathrm{g}\COLON \TYP{Mass}\)\\ 360 \(\KWD{dim} \TYP{Time} \KWD{SI{\char'137}unit} \TYP{second}\mskip 4mu plus 4mu\TYP{seconds}\mskip 4mu plus 4mu\mathrm{s}\)\\ 361 \(\KWD{dim} \TYP{ElectricCurrent} \KWD{SI{\char'137}unit} \TYP{ampere}\mskip 4mu plus 4mu\TYP{amperes}\mskip 4mu plus 4mu\mathrm{A}\)\\ 362 \(\KWD{dim} \TYP{Temperature} \KWD{SI{\char'137}unit} \TYP{kelvin}\mskip 4mu plus 4mu\TYP{kelvins}\mskip 4mu plus 4mu\mathrm{K}\)\\ 363 \(\KWD{dim} \TYP{AmountOfSubstance} \KWD{SI{\char'137}unit} \TYP{mole}\mskip 4mu plus 4mu\TYP{moles}\mskip 4mu plus 4mu\mathrm{mol}\)\\ 364 \(\KWD{dim} \TYP{LuminousIntensity} \KWD{SI{\char'137}unit} \TYP{candela}\mskip 4mu plus 4mu\TYP{candelas}\mskip 4mu plus 4mu\mathrm{cd}\) 365 \end{Fortress} 366 Note the subtle difference in the declaration of \TYP{Mass} that 367 allows the default unit to be \TYP{kilogram} rather than \TYP{gram}. 368 369 370 \section{Absorbing Units} 371 \seclabel{absorbing-units} 372 373 \begin{Grammar} 374 \emph{StaticParam} 375 &::=& \emph{Id} \option{\emph{Extends}} \options{\KWD{absorbs} \KWD{unit}} \\ 376 &$|$& \KWD{unit} \emph{Id} \options{\EXP{\mathrel{\mathtt{:}}} \emph{Type}} 377 \options{\KWD{absorbs} \KWD{unit}}\\ 378 \end{Grammar} 379 380 The declaration of a type parameter or a \KWD{unit} parameter for 381 a parameterized trait may contain a clause 382 ``\EXP{\KWD{absorbs}\;\;\KWD{unit}}''; at 383 most one static parameter of a trait may have this clause. An 384 instance of a parameterized trait 385 with a static parameter that ``\EXP{\KWD{absorbs}\;\;\KWD{unit}}'' may 386 be multiplied 387 or divided by a unit, the result being another instance of that 388 parameterized trait in which the static argument corresponding to 389 the unit-absorbing parameter has been multiplied or divided by the unit. 390 391 A few examples should make this clear. Given the declaration 392 %% trait Vector[\EltType extends Number absorbs unit, nat len\] \ldots end 393 \begin{Fortress} 394 \(\KWD{trait} \TYP{Vector}\llbracket\TYP{EltType} \KWD{extends} \TYP{Number} \KWD{absorbs}\;\;\KWD{unit}, \KWD{nat} \VAR{len}\rrbracket \ldots \KWD{end}\) 395 \end{Fortress} 396 then \EXP{\TYP{Vector}\llbracket\TYP{Float}, 3\rrbracket \TYP{meter}} 397 means the same as 398 \EXP{\TYP{Vector}\llbracket\TYP{Float}\mskip 4mu plus 4mu\TYP{meter}, 3\rrbracket}, 399 and \EXP{\TYP{Vector}\llbracket\TYP{Float}, 3\rrbracket / 400 \TYP{second}} means the same as 401 \EXP{\TYP{Vector}\llbracket\TYP{Float} / \TYP{second}, 3\rrbracket}. 402 Therefore, 403 %[(3 m_) (2 m_) (5 m_)] 404 \EXP{[(3\,\mathrm{m}) (2\,\mathrm{m}) (5\,\mathrm{m})]} 405 means the same as 406 %[3 2 5] m_ 407 \EXP{[3\;2\;5] \mathrm{m}}. 408 % 409 Similarly, given the declaration 410 %% trait Float[\unit U absorbs unit, nat e, nat s\] \ldots end 411 \begin{Fortress} 412 \(\KWD{trait} \TYP{Float}\llbracket\KWD{unit} U \KWD{absorbs}\;\;\KWD{unit}, \KWD{nat} e, \KWD{nat} s\rrbracket \ldots \KWD{end}\) 413 \end{Fortress} 414 then \EXP{\TYP{Float}\llbracket\TYP{meter}, 11, 53\rrbracket / 415 \TYP{second}} means the same as 416 \EXP{\TYP{Float}\llbracket\TYP{meter} / \TYP{second}, 11, 53\rrbracket}, and 417 \begin{Fortress} 418 %% Float[\dimensionless, 8, 24\] meter kilogram / second^2 419 \EXP{\TYP{Float}\llbracket\mathbin{\TYP{dimensionless}}, 8, 24\rrbracket \TYP{meter}\mskip 4mu plus 4mu\TYP{kilogram} / \TYP{second}^{2}} 420 \end{Fortress} 421 means the same as 422 \begin{Fortress} 423 %% Float[\dimensionless meter kilogram / second^2, 8, 24\] 424 \EXP{\TYP{Float}\llbracket\mathbin{\TYP{dimensionless}}\, \TYP{meter}\mskip 4mu plus 4mu\TYP{kilogram} / \TYP{second}^{2}, 8, 24\rrbracket}, 425 \end{Fortress} 426 which is the same as 427 %% Float[\meter kilogram / second^2, 8, 24\] 428 \begin{Fortress} 429 \EXP{\TYP{Float}\llbracket\TYP{meter}\mskip 4mu plus 4mu\TYP{kilogram} / \TYP{second}^{2}, 8, 24\rrbracket}. 430 \end{Fortress} 431 This is the mechanism by which meaning is given to the multiplication 432 and division of library-defined types by units. -
trunk/Specification/advanced/domain-specific-languages.tex
r4271 r4312 18 18 \chapter{Support for Domain-Specific Languages} 19 19 \chaplabel{syntax-expanders} 20 21 \note{This chapter will include the Fortress syntactic abstraction mechanism 22 described in ~\cite{fool09}.} -
trunk/Specification/advanced/operator-definitions.tex
r4271 r4312 18 18 \chapter{Operator Declarations} 19 19 \chaplabel{operatordefs} 20 21 \note{Multifix operators and keyword parameters are not yet supported.} 22 23 An operator declaration may appear anywhere a top-level function or 24 method declaration may appear. Operator declarations are like other 25 function or method declarations in all respects except that an 26 operator declaration has \KWD{opr} and has 27 an operator name (see \secref{operator-names} for a discussion of 28 valid operator names) instead of an identifier. The precise placement 29 of the operator name within the declaration depends on the fixity of 30 the operator. Like other functionals, operators may have overloaded 31 declarations (see \chapref{multiple-dispatch} for a discussion of 32 overloading). These overloadings may be of the same or differing 33 fixities. 34 35 \begin{Grammar} 36 \emph{FnDecl} 37 &::=& \option{\emph{FnMods}} \emph{FnHeaderFront} \emph{FnHeaderClause} 38 \options{\EXP{=} \emph{Expr}} \\ 39 40 \emph{FnHeaderFront} &::=& \emph{OpHeaderFront} \\ 41 42 \emph{OpHeaderFront} 43 &::=& \KWD{opr} \option{\KWD{BIG}} 44 (\{\EXP{\mapsto} $|$ \emph{LeftEncloser} $|$ \emph{Encloser}) \option{\emph{StaticParams}} 45 \option{\emph{Params}} \\ 46 &&(\emph{RightEncloser} $|$ \emph{Encloser}) \\ 47 &$|$& \KWD{opr} \emph{ValParam} 48 (\emph{Op} $|$ \emph{ExponentOp}) \option{\emph{StaticParams}} \\ 49 &$|$& \KWD{opr} \option{\KWD{BIG}} 50 (\emph{Op} $|$ \texttt{\^} $|$ \emph{Encloser} $|$ $\sum$ $|$ $\prod$) 51 \option{\emph{StaticParams}} \emph{ValParam} \\ 52 53 \emph{MdDecl} &::=& \emph{MdDef} \\ 54 &$|$& \option{\KWD{abstract}} 55 \option{\emph{MdMods}} \emph{MdHeaderFront} 56 \emph{FnHeaderClause} \\ 57 58 \emph{MdHeaderFront} &::=& \emph{OpMdHeaderFront} \\ 59 60 \emph{OpMdHeaderFront} 61 &::=& \KWD{opr} \option{\KWD{BIG}} 62 (\{\EXP{\mapsto} $|$ \emph{LeftEncloser} $|$ \emph{Encloser}) \option{\emph{StaticParams}} 63 \option{\emph{Params}} \\ 64 &&(\emph{RightEncloser} $|$ \emph{Encloser}) \\ 65 &&\options{\EXP{\ASSIGN} \texttt( \emph{SubscriptAssignParam} \texttt)} 66 \\ 67 &$|$& \KWD{opr} \emph{ValParam} 68 (\emph{Op} $|$ \emph{ExponentOp}) \option{\emph{StaticParams}} \\ 69 &$|$& \KWD{opr} \option{\KWD{BIG}} 70 (\emph{Op} $|$ \texttt{\^} $|$ \emph{Encloser} $|$ $\sum$ $|$ $\prod$) 71 \option{\emph{StaticParams}} \emph{ValParam} \\ 72 73 \emph{SubscriptAssignParam} 74 &::=& \emph{Varargs}\\ 75 &$|$& \emph{Param}\\ 76 \end{Grammar} 77 78 An operator declaration has one of eight 79 forms: 80 multifix operator declaration, 81 infix operator declaration, 82 prefix operator declaration, postfix operator declaration, 83 nofix operator declaration, 84 bracketing operator declaration, 85 subscripting operator method declaration, 86 and subscripted assignment operator method declaration. 87 Each is invoked according to specific rules of syntax. 88 An operator method declaration must be a functional method declaration, 89 a subscripting operator method declaration, or a subscripted assignment 90 operator method declaration. 91 92 \section{Multifix Operator Declarations} 93 94 A multifix operator declaration has \KWD{opr} 95 and then an operator name where a 96 functional declaration would have an identifier. 97 The declaration must not have any keyword parameters, and must 98 be capable of accepting at least two arguments. It is permissible 99 to use a varargs parameter; in fact, this is a good way to 100 define a multifix operator. 101 Static parameters (described in \chapref{trait-parameters}) 102 may also be present, between the operator and 103 the parameter list. 104 105 An expression consisting of a multifix operator applied to 106 an expression will invoke a multifix operator declaration. 107 The compiler considers all multifix operator declarations for that 108 operator that are both 109 accessible and applicable, and the most specific operator declaration 110 is chosen according to the usual rules for overloaded functionals. 111 The invocation will pass more than two arguments. 112 113 A multifix operator declaration may also be invoked 114 by an infix, a prefix, or nofix (but not a postfix) operator application if 115 the declaration is applicable. 116 117 Example: 118 \note{Example is commented out because it is not supported nor run by the interpreter yet.} 119 %\input{\home/advanced/examples/OprDecl.Multifix.tex} 120 121 \section{Infix Operator Declarations} 122 123 An infix operator declaration has \KWD{opr} 124 and then an operator name where a 125 functional declaration would have an identifier. 126 The declaration must have two value parameter, 127 which must not be a keyword parameter or varargs parameter. 128 Static parameters may also be present, 129 between the operator and the parameter list. 130 131 An expression consisting of an infix operator applied to 132 an expression will invoke an infix operator declaration. 133 The compiler considers all infix and multifix 134 operator declarations for that 135 operator that are both 136 accessible and applicable, and the most specific operator declaration 137 is chosen according to the usual rules for overloaded functionals. 138 139 Note that superscripting (\txt{{\char'136}}) may be defined using 140 an infix operator declaration even though it has very high precedence 141 and cannot be used as a multifix operator. 142 143 Example: 144 \input{\home/advanced/examples/OprDecl.Infix.tex} 145 146 \section{Prefix Operator Declarations} 147 148 A prefix operator declaration has \KWD{opr} 149 and then an operator name where a 150 functional declaration would have an identifier. 151 The declaration must have one value parameter, which must not be a keyword parameter 152 or varargs parameter. 153 Static parameters may also be present, between the operator and the parameter list. 154 155 An expression consisting of a prefix operator applied to 156 an expression will invoke a prefix operator declaration. 157 The compiler considers all prefix and multifix 158 operator declarations for that 159 operator that are both 160 accessible and applicable, and the most specific operator declaration 161 is chosen according to the usual rules for overloaded functionals. 162 163 Example: 164 \input{\home/advanced/examples/OprDecl.Prefix.tex} 165 166 \section{Postfix Operator Declarations} 167 \seclabel{postfix-opr-decl} 168 169 A postfix operator declaration has \KWD{opr} where a 170 functional declaration would have an identifier; 171 the operator name itself \emph{follows} the parameter list. 172 The declaration must have one value parameter, which must not be a keyword parameter 173 or varargs parameter. 174 Static parameters may also be present, between \KWD{opr} 175 and the parameter list. 176 177 An expression consisting of a postfix operator applied to 178 an expression will invoke a postfix operator declaration. 179 The compiler considers all postfix operator declarations for that 180 operator that are both 181 accessible and applicable, and the most specific operator declaration 182 is chosen according to the usual rules for overloaded functionals. 183 184 Example: 185 \input{\home/advanced/examples/OprDecl.Postfix.tex} 186 187 188 \section{Nofix Operator Declarations} 189 190 A nofix operator declaration has \KWD{opr} 191 and then an operator name where a functional declaration would have an 192 identifier. The declaration must have no parameters. 193 194 An expression consisting only of a nofix operator 195 will invoke a nofix operator declaration. 196 The compiler considers all nofix and multifix 197 operator declarations 198 for that operator that are both 199 accessible and applicable, and the most specific operator declaration 200 is chosen according to the usual rules for overloaded functionals. 201 202 Uses for nofix operators are rare, but those rare examples are very useful. 203 For example, if the \EXP{@} operator is used to construct subscripting ranges, 204 and it is the nofix declaration of \EXP{@} that allows a lone \EXP{@} to be 205 used as a subscript: 206 \input{\home/advanced/examples/OprDecl.Nofix.tex} 207 208 209 \section{Bracketing Operator Declarations} 210 \seclabel{bracketing-opr-decl} 211 212 A bracketing operator declaration has \KWD{opr} 213 where a functional declaration would have an identifier. 214 The value parameter list, rather than being surrounded by parentheses, 215 is surrounded by the brackets being defined. A bracketing operator 216 declaration may have any number of parameters, keyword parameters, 217 and varargs parameters in the value parameter list. Static parameters may 218 also be present, between \KWD{opr} and the parameter list. Any paired 219 Unicode brackets 220 may be so defined \emph{except} ordinary parentheses 221 and white square brackets. 222 223 An expression consisting of zero or more comma-separated expressions 224 surrounded by a bracket pair will invoke a bracketing operator 225 declaration. The compiler considers all bracketing operator 226 declarations for that type of bracket pair that are both accessible and applicable, and the most 227 specific operator declaration is chosen according to the usual rules for 228 overloaded functionals. 229 For example, the expression \EXP{\langle p,q \rangle} might invoke the 230 following bracketing method declaration: 231 \input{\home/advanced/examples/OprDecl.Bracketing.tex} -
trunk/Specification/advanced/overloading.tex
r4271 r4312 18 18 \chapter{Overloaded Functional Declarations} 19 19 \chaplabel{overloaded-declarations} 20 21 \note{Keyword and varargs parameters are not yet supported.} 22 23 Fortress allows multiple functional declarations to be in scope of a 24 particular program point. We call this overloading. 25 \chapref{multiple-dispatch} describes 26 how to determine which overloaded declarations are 27 applicable to a particular functional call, and when several 28 are applicable, how to select the most specific one among them. 29 In this chapter, we give a 30 set of rules on overloaded declarations that guarantee there 31 exists a most specific declaration for any given functional call. 32 These rules are complicated by the presence of coercion, which may 33 enlarge the set of declarations that are applicable to a functional 34 call, as discussed in \chapref{conversions-coercions}. 35 36 37 38 \section{Principles of Overloading} 39 \seclabel{principles-overloading} 40 41 Fortress allows multiple functional declarations of the same name to 42 be declared in a single scope. However, recall from \chapref{names} 43 the following shadowing rules: 44 \begin{itemize} 45 \item 46 dotted method declarations shadow top-level function declarations with 47 the same name, and 48 \item 49 dotted method declarations provided by a trait or object declaration 50 or object expression 51 shadow functional method declarations with the same name that are 52 provided by a different trait or object declaration 53 or object expression. 54 \end{itemize} 55 Also, note that a trait or object declaration 56 or object expression must not have a 57 functional method declaration and a dotted method declaration with the 58 same name, either directly or by inheritance. 59 Therefore, top-level functions can overload 60 with other top-level functions and functional methods, dotted methods with 61 other dotted methods, and functional methods with other functional methods 62 and top-level functions. 63 64 Overloading functional declarations allows the benefits of polymorphic 65 declarations. However, with these benefits comes the potential for 66 ambiguous calls at run time. Fortress provides overloading rules for the 67 \emph{declarations} of functionals to eliminate the \emph{possibility} 68 of ambiguous calls at run time, whether or not these calls actually 69 appear in the program. 70 71 For each functional application expression, it should be a static error 72 if there does not exist a statically most applicable declaration for 73 that expression. 74 Furthermore, these rules are checked statically. 75 In fact, the overloading rules 76 in Fortress allow the compiler to identify the 77 statically most specific declaration for a particular call. Therefore 78 an implementation strategy may be used in which the statically most 79 specific declaration is identified statically, and the runtime 80 dispatch mechanism need only consider dispatching among that 81 declaration plus declarations that are more specific than that 82 declaration (proof of this is given in \secref{proof-overloading-resolution}). 83 84 This chapter outlines several criteria for valid functional 85 overloading. At any given program point, there is a set of overloaded 86 declarations that are in scope. Fortress determines whether there is 87 a possibility for ambiguous calls from this set by comparing 88 declarations pairwise. The following three sections each describes a 89 rule to accept a pair of overloaded functional declarations. If a 90 pair of overloaded declarations satisfies any one of the three rules, 91 it is considered a valid overloading. 92 93 The overloading rules given in this chapter are disjoint. That is, at 94 most one rule applies to each pair of overloaded declarations. It is 95 possible for new rules to be added which allow additional 96 overloadings. 97 98 \label{adv-over-kwd} 99 Overloaded declarations must have static parameters that are identical 100 (up to $\alpha$-equivalence). Also, valid overloadings for 101 declarations that contain keyword or 102 varargs parameters are determined 103 by analyzing the expansion of these declarations as described in 104 \secref{applicability-with-special-params}. Therefore, static 105 parameters, keyword parameters, 106 and varargs parameters are ignored in 107 the remainder of this chapter. 108 109 An operator method declaration whose name is one of the operator parameters 110 (described in \secref{opr-ident}) 111 of its enclosing trait or object may be overloaded with other operator 112 declarations in the same component. Therefore, such an operator method 113 declaration must satisfy the overloading rules 114 with every operator declaration in the same component. 115 116 117 118 In addition, a functional which takes a single parameter of type 119 a naked type parameter of bound \TYP{Any} cannot be 120 overloaded. This restriction prevents ambiguous overloadings such as 121 the following: 122 %makeSet[\T extends Any\](x: T): Set[\T\] 123 %makeSet[\T extends Any\](x: T, y: T): Set[\T\] 124 \begin{Fortress} 125 \(\VAR{makeSet}\llbracket{}T \KWD{extends}\mskip 4mu plus 4mu\TYP{Any}\rrbracket(x\COLON T)\COLON \TYP{Set}\llbracket{}T\rrbracket\)\\ 126 \(\VAR{makeSet}\llbracket{}T \KWD{extends}\mskip 4mu plus 4mu\TYP{Any}\rrbracket(x\COLON T, y\COLON T)\COLON \TYP{Set}\llbracket{}T\rrbracket\) 127 \end{Fortress} 128 The type parameter of \EXP{\VAR{makeSet}} may be instantiated with 129 \TYP{(\mathbb{Z}, \mathbb{Z})} or \TYP{\mathbb{Z}}. If this is the 130 case then the call \EXP{\VAR{makeSet}(3, 4)}, where 3 and 4 have type 131 \TYP{\mathbb{Z}}, is ambiguous. 132 133 \secref{subtype-rule} states the \emph{Subtype Rule}, which stipulates 134 that the parameter type of one declaration be a subtype of the 135 parameter type of the other. In this case, there is no possibility of 136 ambiguous calls, because one declaration is more specific than the 137 other. This section also places a restriction on the return types of 138 the overloaded declarations to ensure that type safety is not 139 violated. \secref{incompatibility-rule} defines the \emph{ 140 Incompatibility Rule} that, if satisfied by a pair of declarations, 141 guarantees that neither declaration is applicable to the same 142 functional call. In \secref{more-specific-rule}, the \emph{Meet Rule} 143 requires the existence of a declaration that is more specific than 144 both overloaded declarations in the situation that both are applicable 145 to a given call. 146 147 In the remainder of this chapter, we build on the terminology and 148 notation defined in \chapref{multiple-dispatch} 149 and \chapref{conversions-coercions}. 150 151 152 153 \section{Subtype Rule} 154 \seclabel{subtype-rule} 155 156 If the parameter type of one declaration is a subtype of the parameter 157 type of another (and they are not the same) then there is no 158 ambiguity between these two declarations: for every call to which both 159 are applicable, the first is more specific. This is the basis of the 160 Subtype Rule. 161 162 The Subtype Rule also requires a relationship between the return types 163 of the two declarations. Without such a requirement, a program may 164 violate type safety. 165 166 \paragraph{The Subtype Rule for Functions and Functional Methods:} 167 Suppose that $\f(\Ps) : \Us$ and $\f(\Qs) : \Vs$ are two distinct 168 function or functional method declarations in a single scope. 169 If $\Ps \strictsubtype \Qs$ and $\Us \Ovrsubtype \Vs$ then $\f(\Ps)$ and 170 $\f(\Qs)$ are a valid overloading. 171 172 \paragraph{The Subtype Rule for Dotted Methods:} 173 Suppose that $\Ps_0.\f(\Ps) : \Us$ and $\Qs_0.\f(\Qs) : \Vs$ are two 174 distinct dotted method declarations provided by a trait or object $C$. 175 If $\Ps_0 \strictsubtype \Qs_0$, $\Ps \strictsubtype \Qs$, 176 and $\Us \Ovrsubtype 177 \Vs$ then $\Ps_0.\f(\Ps)$ and $\Qs_0.\f(\Qs)$ are a valid overloading. 178 179 \section{Incompatibility Rule} 180 \seclabel{incompatibility-rule} 181 182 The basic idea behind the Incompatibility Rule is that if there is no 183 call to which two overloaded declarations are both applicable 184 then there is no potential for ambiguous calls. In such a case, we say 185 that the declarations are incompatible. 186 Without coercion, incompatibility is equivalent to exclusion. 187 However, the presence of coercion complicates the definition of 188 incompatibility. To formally define incompatibility we first define the 189 following notation. 190 % 191 For types $T$ and $U$, 192 we say that $T$ and $U$ \emph{do not share coercions}, and write 193 $T \noshare U$, if any type that coerces to $T$ excludes any type 194 that coerces to $U$: 195 \[ 196 T \noshare U \iff \forall A,B: A \coercedefto T \logicand B \coercedefto U 197 \implies A \excludes B. 198 \] 199 % 200 We say that $T$ \emph{is incompatible with} $U$, and write $T 201 \incompatible U$, if $T$ and $U$ exclude, reject each other, and do 202 not share coercions: 203 \begin{align*} 204 T \incompatible U \iff 205 &T \excludes U \logicand T \rejects U \logicand U \rejects T \logicand T \noshare U \\ 206 \iff 207 &\phantom{\logicand\ } T \excludes U \\ 208 &\logicand\ (\forall A: A \coercedefto T \implies A \excludes U) \\ 209 &\logicand\ (\forall B: B \coercedefto U \implies B \excludes T) \\ 210 &\logicand\ (\forall A,B: A \coercedefto T \logicand B \coercedefto U 211 \implies A \excludes B) 212 \end{align*} 213 Note that if $T \incompatible U$ then no type is substitutable for 214 both $T$ and $U$. 215 216 \paragraph{The Incompatibility Rule for Functions and Functional Methods:} 217 218 Suppose that $\f(\Ps)$ and $\f(\Qs)$ are two distinct function or 219 functional method declarations in a single scope. 220 If $\Ps \incompatible \Qs$ then $\f(\Ps)$ and $\f(\Qs)$ are a valid overloading. 221 222 \paragraph{The Incompatibility Rule for Dotted Methods:} 223 Suppose that $\Ps_0.\f(\Ps)$ and $\Qs_0.\f(\Qs)$ are two distinct 224 dotted method declarations provided by a trait or object $C$. If 225 $\Ps \incompatible \Qs$ then $\Ps_0.\f(\Ps)$ and $\Qs_0.\f(\Qs)$ are 226 a valid overloading. 227 228 \section{Meet Rule} 229 \seclabel{more-specific-rule} 230 231 If neither the Subtype Rule nor the Incompatibility Rule holds for a 232 pair of overloaded declarations then the declarations introduce the 233 possibility of ambiguity. To avoid this ambiguity, we require a 234 \emph{disambiguating declaration}; this is, for every call to which 235 both declarations are applicable, there must be a third, more 236 specific, declaration that is also applicable. Thus, at run time, 237 neither of the pair of declarations is executed because the 238 disambiguating declaration is also applicable, and it is more specific 239 than both. 240 241 \note{What is "an intersection of two declarations"? 242 -- Sukyoung 243 244 For function declarations we require that the disambiguating 245 declaration be the intersection of the pair of overloaded 246 declarations.} 247 248 \paragraph{The Meet Rule for Functions:} 249 Suppose that $\f(\Ps)$ and $\f(\Qs)$ are two function 250 declarations in a single scope 251 such that neither $\Ps$ nor $\Qs$ is a subtype of the other and $\Ps$ and 252 $\Qs$ are not incompatible with one another. 253 Let $\mathpzc{S}$ be the set of types that $\Ps$ defines coercions from 254 and $\mathpzc{T}$ be the set of types that $\Qs$ defines coercions from. 255 $\f(\Ps)$ and $\f(\Qs)$ are a valid overloading if 256 there is a declaration $\f(\Ps \inter \Qs)$ in the scope. 257 258 all of the following hold: 259 \begin{itemize} 260 \item 261 either $\Ps \excludes \Qs$ or there is a declaration $\f(\Ps \inter 262 \Qs)$ in the scope, 263 and 264 \item 265 either $\Ps \morespecific \Qs$ or $\Qs \morespecific \Ps$ or for all 266 $\Ps' \in \mathpzc{S}$ and $\Qs' \in \mathpzc{T}$ one of the two 267 conditions holds: 268 \begin{itemize} 269 \item 270 $\Ps' \excludes \Qs'$, or 271 \item 272 there is a declaration $\f(\Ps' \inter \Qs')$ in the scope. 273 \end{itemize} 274 \end{itemize} 275 276 Recall that $\Ps \inter \Qs$ is the intersection of types $\Ps$ and $\Qs$ 277 as defined in \secref{internal-types}. 278 We write $\Ps \inter \Qs$ to denote the intersection of types $\Ps$ and $\Qs$. 279 If for some type $S$ we have $S \Ovrsubtype P$ and $S \Ovrsubtype Q$ then 280 $S \Ovrsubtype (P \intersect Q)$, but it is not necessarily the 281 case that $S = (P \intersect Q)$ since another type may be more 282 specific than both $P$ and $Q$. 283 \label{adv-over-comprises} 284 For example, suppose the following: 285 %trait S comprises {U,V} end 286 %trait T comprises {V,W} end 287 %trait U extends S excludes W end 288 %trait V extends {S,T} end 289 %trait W extends T end 290 % 291 %f(s:S) = 1 292 %f(t:T) = 1 293 %f(v:V) = 1 294 \begin{Fortress} 295 \(\KWD{trait} S \KWD{comprises} \{U,V\} \KWD{end}\)\\ 296 \(\KWD{trait} T \KWD{comprises} \{V,W\} \KWD{end}\)\\ 297 \(\KWD{trait} U \KWD{extends} S \KWD{excludes} W \KWD{end}\)\\ 298 \(\KWD{trait} V \KWD{extends} \{S,T\} \KWD{end}\)\\ 299 \(\KWD{trait} W \KWD{extends} T \KWD{end}\)\\[4pt] 300 \(f(s\COLONOP{}S) = 1\)\\ 301 \(f(t\COLONOP{}T) = 1\)\\ 302 \(f(v\COLONOP{}V) = 1\) 303 \end{Fortress} 304 Because of the \KWD{comprises} clauses of $S$ and $T$ and the \KWD{excludes} 305 clause of $U$, any subtype of both $S$ and $T$ must be a subtype of 306 $V$. Thus, $V = S \inter T$, and the declaration $f(V)$ 307 ``disambiguates'' $f(S)$ and $f(T)$, i.e., it is applicable to and more 308 specific for any call to which both $f(S)$ and $f(T)$ are applicable. 309 310 The Meet Rule shall not be difficult to obey, especially because 311 the compiler can give useful feedback. For example: 312 313 % foo(x:Number, y:ZZ64) = ... 314 % foo(x:ZZ64, y:Number) = ... 315 \begin{Fortress} 316 {\tt~~}\pushtabs\=\+\( \VAR{foo}(x\COLONOP\TYP{Number}, y\COLONOP\mathbb{Z}64) = \ldots\)\\ 317 \( \VAR{foo}(x\COLONOP\mathbb{Z}64, y\COLONOP\TYP{Number}) = \ldots\)\-\\\poptabs 318 \end{Fortress} 319 320 Assuming that \(\hbox{\ZZ64} \prec \hbox{\TYP{Number}}\), the compiler 321 reports that these two declarations are a problem because of ambiguity 322 and suggests that a new declaration for \EXP{\VAR{foo}({\ZZ64}, 323 {\ZZ64})} would resolve the ambiguity. As another example, consider: 324 325 % bar(x:Printable) = ... 326 % bar(x:Throwable) = ... 327 \begin{Fortress} 328 {\tt~}\pushtabs\=\+\( \VAR{bar}(x\COLONOP\TYP{Printable}) = \ldots\)\\ 329 \( \VAR{bar}(x\COLONOP\TYP{Throwable}) = \ldots\)\-\\\poptabs 330 \end{Fortress} 331 332 Assuming that $\hbox{\TYP{Printable}}$ and $\hbox{\TYP{Throwable}}$ 333 are neither comparable by the subtyping relation nor disjoint, the 334 compiler reports that these two declarations are a problem because 335 \TYP{Printable} and \TYP{Throwable} are incomparable but possibly 336 overlapping types. 337 As a result, these two declarations are statically rejected. 338 339 Unlike for functions, the Meet Rule for dotted methods only applies to 340 dotted methods that are provided by the same trait or object. This is 341 possible because two dotted methods are applicable to a given call 342 $\As_0.f(\As)$ only if they are both provided by the trait or object 343 $\As_0$. 344 345 \paragraph{The Meet Rule for Dotted Methods:} 346 Suppose that $\Ps_0.\f(\Ps)$ and $\Qs_0.\f(\Qs)$ are two dotted method 347 declarations provided by a trait or object $C$ such that neither 348 $(\Ps_0, \Ps)$ nor $(\Qs_0, \Qs)$ is a subtype of the other and $\Ps$ 349 and $\Qs$ are not incompatible with one another. 350 Let $\mathpzc{S}$ be the set of 351 types that $\Ps$ defines coercions from and $\mathpzc{T}$ be the set 352 of types that $\Qs$ defines coercions from. 353 $\Ps_0.\f(\Ps)$ and 354 $\Qs_0.\f(\Qs)$ are a valid overloading if 355 there is a declaration $\Rs_0.\f(\Ps 356 \inter \Qs)$ provided by $C$ with $\Rs_0 \Ovrsubtype (\Ps_0 \inter 357 \Qs_0)$. 358 359 all of the following hold: 360 \begin{itemize} 361 \item 362 either $\Ps \excludes \Qs$ or there is a declaration $\Rs_0.\f(\Ps 363 \inter \Qs)$ provided by $C$ with $\Rs_0 \Ovrsubtype (\Ps_0 \inter 364 \Qs_0)$, and 365 \item 366 either $\Ps \morespecific \Qs$ or $\Qs \morespecific \Ps$ or 367 for all $\Ps' \in \mathpzc{S}$ and 368 $\Qs' \in \mathpzc{T}$ one of the two conditions holds: 369 \begin{itemize} 370 \item 371 $\Ps' \excludes \Qs'$, or 372 \item 373 there is a declaration $\Rs_0.\f(\Ps' \inter \Qs')$ provided by $C$ 374 with $\Rs_0 \Ovrsubtype (\Ps_0 \inter \Qs_0)$. 375 \end{itemize} 376 \end{itemize} 377 378 Recall that functional methods can be viewed semantically as top-level 379 functions, as described in \secref{methods}. However, treating 380 functional methods as top-level functions for determining valid 381 overloading is too restrictive. In the following example: 382 \input{\home/advanced/examples/Overloading.tex} 383 if the functional methods were interpreted as top-level functions then 384 this program would define two top-level functions with parameter types 385 \EXP{\mathbb{Z}} and \EXP{\mathbb{R}}. 386 These declarations would be 387 statically rejected as 388 an invalid overloading because there is no 389 relation between \EXP{\mathbb{Z}} and \EXP{\mathbb{R}}; another trait 390 may extend them both without declaring its own version of the 391 functional method which may lead to an ambiguous call at run time. 392 However, notice that declaraions are ambiguous only for calls on 393 arguments that extend both \EXP{\mathbb{Z}} and \EXP{\mathbb{R}}, and 394 any type that extends both can include a new declaration that 395 disambiguates them. We use this intuition to allow such overloadings. 396 397 \paragraph{The Meet Rule for Functional Methods:} 398 Suppose that $\f(\Ps)$ and $\f(\Qs)$ are two functional method 399 declarations occurring in trait or object declarations or object expressions 400 such that neither $\Ps$ nor $\Qs$ is a subtype of the other and $\Ps$ and $\Qs$ 401 are not incompatible with one another. Let $\f(\Ps)$ and $\f(\Qs)$ 402 have self parameters at $i$ and $j$ respectively. 403 $\f(\Ps)$ and $\f(\Qs)$ are a valid 404 overloading if all of the following hold: 405 \begin{itemize} 406 \item 407 $i = j$ 408 \item if there exists a trait or object $C$ 409 that provides both $\f(\Ps)$ and $\f(\Qs)$ then $\Ps \neq \Qs$ and 410 there is a declaration $\f(\Ps \inter \Qs)$ provide by $C$ 411 having self parameter at $i$. 412 \end{itemize} 413 414 Also, let $\mathpzc{S}$ be the set of types that $\Ps$ 415 defines coercions from and $\mathpzc{T}$ be the set of types that 416 $\Qs$ defines coercions from. $\f(\Ps)$ and $\f(\Qs)$ are a valid 417 overloading if all of the following hold: 418 \begin{itemize} 419 \item 420 $i = j$ 421 \item 422 either $\Ps \excludes \Qs$ or if there exists a trait or object $C$ 423 that provides both $\f(\Ps)$ and $\f(\Qs)$ then $\Ps \neq \Qs$ and 424 there is a declaration $\f(\Ps \inter \Qs)$ provide by $C$, and 425 \item 426 either $\Ps \morespecific \Qs$ or $\Qs \morespecific \Ps$ or 427 for all $\Ps' \in \mathpzc{S}$ and 428 $\Qs' \in \mathpzc{T}$ one of the two conditions holds: 429 \begin{itemize} 430 \item 431 $\Ps' \excludes \Qs'$, or 432 \item 433 there is a declaration $\f(\Ps' \inter \Qs')$ provided by $C$. 434 \end{itemize} 435 \end{itemize} 436 437 Notice that the Meet Rule for functional methods requires the self 438 parameters of two overloaded declarations to be in the same position. 439 This requirement guarantees that no ambiguity is caused by the 440 position of the self parameter. Two declarations which differ in the 441 position of the self parameter must satisfy either the Subtype Rule or 442 the Incompatibility Rule to be a valid overloading. 443 444 Functional method declarations can overload with function declaraions. 445 A valid overloading between a functional method declaration and 446 a function declaration is 447 determined by applying the (more restrictive) Meet Rule for functions 448 to both declarations. 449 450 \section{Coercion and Overloading Resolution} 451 452 The overloading rules given in this chapter are 453 sufficient to prove the following two facts: 454 \begin{enumerate} 455 \item 456 If no declaration is applicable to a static call but there is a 457 declaration that is applicable with coercion then there exists a 458 single most specific declaration that is applicable with coercion to 459 the static call. 460 \item 461 If any declaration is applicable to a static call then there exists a 462 single most specific declaration that is applicable to the static call 463 and a single most specific declaration that is applicable to the 464 corresponding dynamic call. 465 \end{enumerate} 466 467 Moreover, we can prove that the most specific declaration that is 468 applicable to a dynamic call is more specific than the most specific 469 declaration that is applicable to the corresponding static call. 470 471 \appref{overloaded-functional} formally proves that 472 the rules discussed in the previous sections guarantee the static resolution of 473 coercion (described in \secref{resolving-coercion}) is well defined 474 for functions (the case for methods is analogous). Also in 475 \appref{overloaded-functional} is a proof that 476 the overloading rules for 477 function declarations are sufficient to guarantee no 478 undefined nor ambiguous calls at run time (again, 479 the case for methods is analogous). -
trunk/Specification/advanced/parallelism-locality/arrays-distributed.tex
r4295 r4312 18 18 \section{Distributed Arrays} 19 19 \seclabel{arrays} 20 21 \note{Distributions, array comprehensions, and 22 \TYP{HeapSequence} are not yet supported.} 23 24 Arrays, vectors, and matrices in Fortress are assumed to be spread out 25 across the machine. As in Fortran, Fortress arrays are complex data 26 structures; simple linear storage is encapsulated by the 27 \TYP{HeapSequence} type, which is used in the implementation of arrays 28 (see \secref{parallelism-fundamentals}). 29 The default distribution of 30 an array is determined by the Fortress libraries; in general it 31 depends on the size of the array, and on the size and locality 32 characteristics of the machine running the program. 33 For advanced 34 users, the distribution library (introduced in \secref{distributions}) 35 provides a way of combining and pivoting distributions, or of 36 redistributing two arrays so that their distributions match. 37 Programmers must create arrays by using 38 an array comprehension (\secref{comprehensions}) or 39 an aggregate expression (\secref{aggregate-expr}), or by using one of 40 the factory functions at the top of \figref{arrayFactories}. After calling 41 any of these factories, the elements of the resulting array must be 42 initialized using either indexed assignment or using one of the 43 initialization methods described at the bottom of the figure. 44 45 \begin{figure} 46 \begin{tabular}{|m{2.0in}|m{4.0in}|} 47 \hline 48 \EXP{\VAR{array}\llbracket{}E\rrbracket(\emph{size}\COLONOP{}I)\COLONOP\TYP{Array}\llbracket{}E,I\rrbracket} & {Creates an uninitialized 0-indexed array of the specified runtime-determined size. The size is an integer for a 1-dimensional array, a 2-tuple for a two-dimensional array, and so forth.} \\ 49 \hline 50 \EXP{{array}_{1}\llbracket{}E,n\rrbracket()} & {Creates an uninitialized 0-indexed 1-dimensional array of statically determined size $n$.} \\ 51 \hline 52 \EXP{{array}_{2}\llbracket{}E,n,m\rrbracket()} & {Creates an uninitialized 0-indexed 2-dimensional array of statically determined size $n$ by $m$.} \\ 53 \hline 54 \EXP{{array}_{3}\llbracket{}E,n,m,p\rrbracket()} & {Creates an uninitialized 0-indexed 3-dimensional array of statically determined size $n$ by $m$ by $p$.} \\ 55 \hline 56 \end{tabular} 57 \begin{tabular}{|m{2.0in}|m{4.0in}|} 58 \hline 59 \EXP{\VAR{a}.\VAR{fill}(v\COLONOP{}E)} & {Initializes all elements with value \VAR{v}.} \\ 60 \hline 61 \EXP{\VAR{a}.\VAR{fill}(f\COLONOP{}I\rightarrow{}E)} & {Calls \VAR{f} at each index and initializes the corresponding element with the result of the call.} \\ 62 \hline 63 \EXP{\VAR{a}.\VAR{init}(i\COLONOP{}I, v\COLONOP{}E)} & {Initializes element at index \VAR{i} with value \VAR{v}.} \\ 64 \hline 65 \end{tabular} 66 \caption{\figlabel{arrayFactories}Factories for creating arrays and methods for initializing their elements} 67 \end{figure} 68 69 Each array element may be initialized at most once using the methods of \figref{arrayFactories}; the programmer must assure that this initialization completes before any other access to the corresponding array element. The programmer must also assure that an element is initialized before it is first read.\footnote{The present implementation signals a fatal error in case of duplicate initialization, or if an uninitialized element is read.} Note that these factories and methods are intended to be used to library programmers to build higher-level functionality (for example, the \VAR{fill} methods themselves are defined in terms of calls to \VAR{init}, and the \VAR{array} factory is defined in terms of \EXP{{array}_{1}}, \EXP{{array}_{2}}, and so forth). 70 71 Because the elements of a fortress array may reside in multiple 72 regions of the machine, there is an additional method 73 \EXP{a.\VAR{region}(i)} which returns the region in which the array 74 element \EXP{a_i} resides. An element of an array is always local to 75 the region in which the array as a whole is contained, so 76 \EXP{(a.\VAR{region}(i)).\VAR{isLocalTo}(\VAR{region}(a))} must always 77 return \VAR{true}. When an array contains reference objects, the 78 programmer must be careful to distinguish the region in which the 79 array element \EXP{a_i} resides, \EXP{a.\VAR{region}(i)}, from the 80 region in which the object referred to by the array element resides, 81 \EXP{\VAR{region}(a_i)}. The former describes the region of the array 82 itself; the latter describes the region of the data referred to by the 83 array. These may differ. -
trunk/Specification/advanced/parallelism-locality/defining-generators.tex
r4295 r4312 18 18 \section{Use and Definition of Generators} 19 19 \seclabel{defining-generators} 20 21 Several expressions in Fortress make use of \emph{generator clause 22 lists} to express parallel iteration (see \secref{generators}). A 23 generator clause list binds a series of variables to the values produced by a 24 series of objects that extend the trait \TYP{Generator}. A generator clause 25 list is simply syntactic sugar for a nested series of invocations of 26 methods on these objects. 27 28 A type that extends \EXP{\TYP{Generator}\llbracket{}E\rrbracket} acts 29 as a generator of elements of type \VAR{E}. An instance of 30 \EXP{\TYP{Generator}\llbracket{}E\rrbracket} only needs to define the 31 \VAR{generate} method: 32 % generate[\R\](r:Reduction[\R\], body: E->R): R 33 \begin{Fortress} 34 {\tt~~~~}\pushtabs\=\+\( \VAR{generate}\llbracket{}R\rrbracket(r\COLONOP\TYP{Reduction}\llbracket{}R\rrbracket, \VAR{body}\COLON E\rightarrow{}R)\COLON R\)\-\\\poptabs 35 \end{Fortress} 36 The mechanics of object generation are embedded entirely in the 37 \VAR{generate} method. This method takes two arguments. The \VAR{generate} method invokes \VAR{body} once for each 38 object which is to be generated, passing the generated object as an 39 argument. Each call to \VAR{body} returns a result of type \VAR{R}; these results are combined using the reduction \VAR{r}, which encapsulates a monoidal operator on objects of type \VAR{R}. \emph{All the parallelism provided by a 40 particular generator is specified by definition of the \VAR{generate} method.} 41 42 In practice, calls to \VAR{generate} are produced by desugaring 43 expressions with generator clause lists, as described below 44 (\secref{desugaring-generators}). However it is possible to call the 45 \VAR{generate} method directly, as in the following example: 46 \input{\home/advanced/examples/Generators.ReductionClass.tex} 47 48 Any reduction must define two methods: an associative binary operation 49 \VAR{join}, and \VAR{empty}, a method that returns the identity of 50 this operation. Here we define reduction \TYP{SumZZ32} representing integer 51 addition. We use this to compute the sum of \EXP{3 x + 2} for \VAR{x} 52 drawn from the range \EXP{1\mathinner{\hbox{\tt\char'43}}100}, 53 yielding the expected answer of 15350. 54 55 \begin{figure} 56 \input{\home/advanced/examples/Generators.GeneratorDefn.tex} 57 \caption{\figlabel{generatorDefn}Sample \TYP{Generator} definition: blocked integer ranges.} 58 \end{figure} 59 60 For non-commutative reductions such as the \TYP{Concat} reduction used for 61 list comprehensions in \figref{generatedExpressions}, it is important to 62 note that results must be combined in the natural order of the 63 generator. If \VAR{join} is not associative, or \VAR{empty} is not 64 the identity of \VAR{join}, passing the reduction to \VAR{generate} 65 will produce unpredictable results. A generator is permitted to group 66 reduction operations in any way it likes consistent with its natural 67 order, and insert an arbitrary number of \VAR{empty} elements. 68 69 \figref{generatorDefn} defines a generator that generates the integers 70 between \VAR{lo} and \VAR{hi} in sequential blocks of size at most 71 \VAR{b}. In this example, we divide the range in half if it is larger 72 than the block size \VAR{b}; these two halves are computed in parallel 73 (recall that the arguments to the method call 74 \EXP{\VAR{reduction}.\VAR{join}} are evaluated in parallel). If the 75 range is smaller than \VAR{b}, then it is enumerated serially using a 76 \KWD{while} loop, accumulating the result \VAR{r} as it goes. Observe 77 that the parallelism obtained from a generator is \emph{dictated by 78 the code of the \VAR{generate} method}. While programmers using a 79 generator should assume that calls to \VAR{body} may occur in 80 parallel, the library programmer is free to choose the amount of 81 parallelism that is actually exposed. 82 83 This example uses \emph{recursive subdivision} to divide a blocked 84 range into approximately equal-sized chunks of work. Recursive 85 subdivision is the recommended technique for exposing large amounts of 86 parallelism in a Fortress program because it adjusts easily to varying 87 machine sizes and can be dynamically load balanced. 88 89 \TYP{Generator} defines the functional method 90 \EXP{\VAR{seq}(\KWD{self})} that returns an equivalent generator that 91 runs iterations of the body sequentially in natural order. In most 92 cases (such as in this example), it is prudent to override the default 93 definition of this method; the default implementation of \VAR{seq} 94 effectively collects the generated elements together in parallel and 95 traverses the result sequentially. 96 97 \note{ 98 Note that at the moment there is no way to tell the compiler for 99 performance reasons that we really mean it when we ask for 100 sequentiality, as opposed to saying that we should preserve sequential 101 semantics. Future versions of this specification may use the 102 \TYP{Local} distribution for this purpose, or provide additional 103 functions on generators which guarantee serial execution (rather than 104 simply providing sequential semantics). 105 } 106 107 The remainder of this section describes in detail the desugaring of 108 expressions with generator clause lists into invocations of the 109 \VAR{generate} methods of the generators in the 110 generator clause list. 111 \note{ 112 It then outlines how method overloading may be used 113 to specialize the behavior of particular combinations of generators 114 and reductions.} 115 116 \subsection{Simple Desugaring of Expressions with Generators} 117 \seclabel{desugaring-generators} 118 119 \note{NOTE: tweaked by hand by Jan, as above.} 120 121 \begin{figure} 122 \begin{tabular}{l@{\:\emph{body}\;\;=\;\;}l} 123 %BIG OP[ ] 124 \(\mathcal{C}[\;\;]\) 125 & 126 %u(body) 127 \(u(\emph{body})\) 128 \\ 129 %BIG OP[ x <- g, gs ] 130 \(\mathcal{C}[\,x \leftarrow g, \emph{gs}\,]\) 131 & 132 %g.generate(r, fn (x) => BIG OP [gs] body) 133 \(g.\VAR{generate}(r, \KWD{fn} (x) \Rightarrow \mathcal{C}[\emph{gs}]\:\emph{body})\) 134 \\ 135 %BIG OP[ p, gs ] 136 \(\mathcal{C}[\,p, \emph{gs}\,]\) 137 & 138 %p.generate(r, fn () => BIG OP [gs] body) 139 \(p.\VAR{generate}(r, \KWD{fn} () \Rightarrow \mathcal{C} [\emph{gs}]\:\emph{body})\) 140 \end{tabular} 141 \caption{\figlabel{simpleDesugar}Simple syntax-directed desugaring of 142 a generator clause list. Here the reduction $r$ and unit $u$ are 143 variables chosen by the desugarer to be distinct from the variables 144 in \emph{gs} and \emph{body}. } 145 \end{figure} 146 147 \begin{figure} 148 %%\begin{tabular}{ll|ll>{$\;\;\llbracket$}c<{$\rrbracket$}} 149 \begin{tabular}{ll|llc} 150 expr & type & \VAR{wrapper} & \EXP{u(\VAR{body})} & $r$ \\ 151 \hline 152 153 % SUM [ gs ] e 154 \EXP{\sum\limits_{\VAR{gs}} e} 155 & 156 $N$ 157 & 158 \EXP{\OPR{SUM}\llbracket{}N\rrbracket} 159 & 160 \EXP{\VAR{identity}\llbracket{}N\rrbracket(e)} 161 & 162 \EXP{\TYP{SumReduction}\llbracket{}N\rrbracket} 163 \\ 164 165 % <| e | gs |> 166 \( \langle\,e \mid \VAR{gs}\,\rangle\) 167 & 168 % List[\E\] 169 \( \TYP{List}\llbracket{}E\rrbracket\) 170 & 171 \EXP{\OPR{BIG} \langle\llbracket{}E\rrbracket\,\rangle} 172 & 173 \( \VAR{singleton\llbracket{}E\rrbracket}(e)\) 174 & 175 \EXP{\TYP{Concat}\llbracket{}E\rrbracket} 176 \\ 177 178 % lv := e, gs 179 \( \VAR{lv} \ASSIGN e, \VAR{gs}\) 180 & 181 \EXP{()} 182 & 183 built in 184 & 185 $\VAR{ignore}(\VAR{lv} \ASSIGN e)$ 186 & 187 \TYP{NoReduction} 188 189 \end{tabular} 190 \caption{Examples of wrappers for expressions with generator clause 191 lists. Top to bottom: big operators (here \EXP{\sum} is used as an 192 example; the appropriate library function is called on the 193 right-hand side), comprehensions (here list comprehensions are 194 shown; other comprehensions are similar to list comprehensions) and 195 generated assignment.} 196 \figlabel{generatedExpressions} 197 \end{figure} 198 199 An expression with a generator clause list \emph{gs} and body expression \emph{body} is desugared into the following general form: 200 \note{ 201 NOTE: tweaked by hand by Jan. Replaced BIG OP by $\mathcal{C}$, 202 emph'd gs and body.} 203 %wrapper(fn (r, u) => BIG OP[gs] body) 204 \begin{Fortress} 205 \( \VAR{wrapper}(\KWD{fn} (r, u) \Rightarrow \mathcal{C}[\emph{gs}]\:\emph{body})\) 206 \end{Fortress} 207 The generator clause list and body can be desugared using the 208 syntax-directed desugaring $\mathcal{C}$ defined in 209 \figref{simpleDesugar}. This yields a function that is in turn passed 210 as an argument to \VAR{wrapper}. The particular choice of the 211 function \VAR{wrapper} depends upon the construct that is being 212 desugared. For a reduction or a comprehension, the wrapper function 213 is the corresponding big operator definition; see 214 \secref{reduction-expr} and \secref{comprehensions}. For a \KWD{for} 215 loop (\secref{for-expr}) or a generated expression 216 (\secref{generated}), a special built-in wrapper is used. 217 Examples are shown in \figref{generatedExpressions}. 218 A wrapper function always has the following type: 219 %% wrapper( g:(Reduction[\R0\],T->R0)->R0): R 220 \begin{Fortress} 221 \(\VAR{wrapper}( g\COLONOP(\TYP{Reduction}\llbracket{}R_{0}\rrbracket,T\rightarrow{}R_{0})\rightarrow{}R_{0})\COLON R\) 222 \end{Fortress} 223 Here the type $T$ is the type of values returned by the body expression, 224 and \EXP{R_{0}} and \VAR{R} are arbitrary types chosen by the wrapper function. 225 226 Note that the function $g$ passed to the wrapper has essentially the 227 same type signature as the \VAR{generate} method itself. It is 228 instructive to think of \VAR{wrapper} as having the following similar 229 type signature:\footnote{In future, it is likely that Fortress will use 230 a desugaring that in fact yields a \TYP{Generator} rather than a 231 higher-order function. This permits type-directed nesting and 232 composition of generators.} 233 %% wrapper'( g: Generator[\T\] ): R (* NOT THE ACTUAL TYPE *) 234 \begin{Fortress} 235 \(\VAR{wrapper}'( g\COLON \TYP{Generator}\llbracket{}T\rrbracket )\COLON R \mathtt{(*}\;\hbox{\rm NOT THE ACTUAL TYPE \unskip}\;\mathtt{*)}\) 236 \end{Fortress} 237 238 \note{From here till the end of this chapter, copied from F1.0$\beta$.} 239 240 An array comprehension simply desugars into a factory function call 241 and a series of assignments: 242 \begin{center} 243 \begin{tabular}[c]{@{}l@{}} 244 % [ i1 = e1 | gs1 245 % i2 = e2 | gs2 246 % ... 247 % i_n = e_n | gs_n ] 248 \EXP{[\,\,\,i_{1} = e_{1} \mid {gs}_{1}}\\ 249 ~~~\EXP{i_{2} = e_{2} \mid {gs}_{2}} \\ 250 ~~~$\ldots$ \\ 251 ~~~\EXP{i_n = e_n \mid \VAR{gs}_n\,]} 252 \end{tabular} 253 \hspace{6em} 254 $\longrightarrow$ 255 \hspace{6em} 256 \begin{tabular}[c]{@{}l@{}} 257 \( \KWD{do}\;a = \VAR{array}()\)\\ 258 ~~~~~~\( a[i_{1}] \ASSIGN e_{1}, {gs}_{1}\)\\ 259 ~~~~~~\( a[i_{2}] \ASSIGN e_{2}, {gs}_{2}\)\\ 260 ~~~~~~\( \ldots\)\\ 261 ~~~~~~\( a[i_n] \ASSIGN e_n, \VAR{gs}_n\)\\ 262 ~~~~~~\( a\) \\ 263 \( \KWD{end}\) 264 \end{tabular} 265 \end{center} 266 267 The desugaring of a \KWD{for} loop depends upon the set of reduction 268 variables. 269 We conceptually desugar the \KWD{for} loop with reduction variables, 270 $r_1$, $r_2$, $\ldots$, $r_n$, reduced using the reduction operator 271 \EXP{\oplus} for type \EXP{(T_{1}, T_{2}, \ldots T_n)} 272 %% with the identity \EXP{(z_{1}, z_{2}, \ldots z_n)} 273 as follows: 274 \begin{center} 275 \EXP{\KWD{for} \VAR{gs} \KWD{do} \VAR{block} \KWD{end}} 276 \\ 277 $\longrightarrow$ 278 \\[2em] 279 \begin{tabular}[c]{l@{}l@{}l@{}l} 280 \EXP{(r_{1}, r_{2}, \ldots r_n)\; \mathord{\oplus}\!\!= }& 281 \EXP{\mathcal{T} 282 \llbracket(T_{1}, T_{2}, \ldots T_n), \oplus 283 \rrbracket[\VAR{gs}]} &\EXP{(\KWD{do}}&\\ 284 &&&\EXP{(r_{1}, r_{2}, \ldots r_{\mathrm{n}}) \mathrel{\mathtt{:}} (T_{1}, T_{2}, \ldots T_{\mathrm{n}}) \ASSIGN \TYP{Identity}\llbracket\oplus\rrbracket} \\ 285 &&&\EXP{\VAR{block}} \\ 286 &&&\EXP{(r_{1}, r_{2}, \ldots r_n)}\\ 287 &&\EXP{\;\KWD{end})}\\ 288 \end{tabular} 289 \end{center} 290 In practice, a tuple type is not a monoid. If there is only one 291 reduction variable, this is not a problem. If there are no reduction 292 variables, we simply use the type \TYP{NoReduction} used in desugaring 293 assignments. When there are multiple reduction variables, we use 294 nested applications of types extending the trait \TYP{ReductionPair}. 295 These types encode the common properties of the variables being 296 reduced. Recall that every reduction variable must at least have type 297 \TYP{Monoid}, so it is not difficult to guarantee that 298 \TYP{ReductionPair} itself also extends \TYP{Monoid}. 299 300 \subsection{Accounting for Dependencies among Generators} 301 \seclabel{generators-dependencies} 302 303 The naive desugaring for generator lists in 304 \figref{simpleDesugar} assumes there are always data 305 dependencies among generators. The actual desugaring makes use of the 306 \VAR{join} method in the \TYP{Generator} trait to group together 307 generators that have no data dependencies. The goal is to permit 308 library code to define more efficient merged generators for generator 309 pairs. For example, it is possible for the \VAR{join} method to take 310 the generator list \EXP{i \leftarrow 311 1\mathinner{\hbox{\tt\char'43}}100, j \leftarrow 312 2\mathinner{\hbox{\tt\char'43}}200} and generate a blocked 313 two-dimensional traversal. This could then be joined with \EXP{k 314 \leftarrow 3\mathinner{\hbox{\tt\char'43}}300} to obtain a 315 three-dimensional blocked traversal. 316 317 However, most generators will simply make use of the default 318 definition of \VAR{join} which calls \TYP{SimplePairGenerator}: 319 % object SimplePairGenerator[\ A extends Any, B extends Any \] 320 % (outer : Generator[\ A \], inner : Generator[\ B \]) extends Generator[\ (A, B) \] 321 % size : ZZ64 = outer.size DOT inner.size 322 % generate[\ R extends Monoid[\ R, OPLUS \], opr OPLUS \](body : (A, B) -> R):R = 323 % outer.generate(fn (a : A) => inner.generate(fn (b : B) => body (a,b))) 324 % join[\ N extends Any \](other : Generator[\ N \]) : Generator[\ ((A,B), N) \] = 325 % SimpleMapGenerator(outer.join(inner.join(other)), 326 % (fn (a,(b,n)) => ((a,b),n))) 327 % end 328 \begin{Fortress} 329 {\tt~}\pushtabs\=\+\( \KWD{object}\mskip 4mu plus 4mu\TYP{SimplePairGenerator}\llbracket\,A \KWD{extends}\mskip 4mu plus 4mu\TYP{Any}, B \KWD{extends}\mskip 4mu plus 4mu\TYP{Any}\,\rrbracket\)\\ 330 {\tt~~~~~~~~}\pushtabs\=\+\( (\VAR{outer} \mathrel{\mathtt{:}}\mskip 4mu plus 4mu\TYP{Generator}\llbracket\,A\,\rrbracket, \VAR{inner} \mathrel{\mathtt{:}}\mskip 4mu plus 4mu\TYP{Generator}\llbracket\,B\,\rrbracket) \KWD{extends}\mskip 4mu plus 4mu\TYP{Generator}\llbracket\,(A, B)\,\rrbracket\)\-\\\poptabs 331 {\tt~~}\pushtabs\=\+\( \VAR{size} \mathrel{\mathtt{:}}\mskip 4mu plus 4mu\mathbb{Z}64 = \VAR{outer}.\VAR{size} \cdot \VAR{inner}.\VAR{size}\)\\ 332 \( \VAR{generate}\llbracket\,R \KWD{extends}\mskip 4mu plus 4mu\TYP{Monoid}\llbracket\,R, \oplus\,\rrbracket, \KWD{opr} \mathord{\oplus}\,\rrbracket(\VAR{body} \mathrel{\mathtt{:}} (A, B) \rightarrow R)\COLONOP{}R =\)\\ 333 {\tt~~}\pushtabs\=\+\( \VAR{outer}.\VAR{generate}(\KWD{fn} (a \mathrel{\mathtt{:}}\mskip 4mu plus 4mu{A}) \Rightarrow \VAR{inner}.\VAR{generate}(\KWD{fn} (b \mathrel{\mathtt{:}}\mskip 4mu plus 4mu{B}) \Rightarrow \VAR{body} (a,b)))\)\-\\\poptabs 334 \( \VAR{join}\llbracket\,N \KWD{extends}\mskip 4mu plus 4mu\TYP{Any}\,\rrbracket(\VAR{other} \mathrel{\mathtt{:}}\mskip 4mu plus 4mu\TYP{Generator}\llbracket\,N\,\rrbracket) \mathrel{\mathtt{:}}\mskip 4mu plus 4mu\TYP{Generator}\llbracket\,((A,B), N)\,\rrbracket =\)\\ 335 {\tt~~}\pushtabs\=\+\( \TYP{SimpleMapGenerator}( \null\)\pushtabs\=\+\(\VAR{outer}.\VAR{join}(\VAR{inner}.\VAR{join}(\VAR{other})),\)\\ 336 \( (\KWD{fn} (a,(b,n)) \Rightarrow ((a,b),n)))\)\-\-\-\\\poptabs\poptabs\poptabs 337 \( \KWD{end}\)\-\\\poptabs 338 \end{Fortress} 339 Note how \TYP{SimplePairGenerator} itself overrides the \VAR{join} 340 method. When we attempt to join an existing pair of joined 341 generators, we first attempt to \VAR{join} the \VAR{inner} generator 342 of the pair with the \VAR{other} generator (the new innermost 343 generator) passed in. This means that every generator will have the 344 opportunity to combine with both its left and right neighbors if 345 neither has a dependency which prevents it. Note that we use a 346 \TYP{SimpleMapGenerator}, which simply applies a function to the 347 result of another generator, to re-nest the tuples produced by the 348 nested \VAR{join} operation. 349 350 Which pairs of adjacent traversals are combined using \VAR{join}? 351 This question is complicated by examples such as 352 % i<-1:100, j<-1:100, k<-i:100, l<-j:100. 353 \EXP{i\leftarrow{}1\COLONOP{}100, j\leftarrow{}1\COLONOP{}100, 354 k\leftarrow{}i\COLONOP{}100, l\leftarrow{}j\COLONOP{}100}. We can 355 either combine \VAR{i} and \VAR{j} traversals, or we can combine 356 \VAR{j} and \VAR{k} traversals. In the former case we can also 357 combine \VAR{k} and \VAR{l} traversals. The Fortress compiler is free 358 to choose any grouping subject to the following constraints: 359 \begin{itemize} 360 \item Two generators may not be combined using \VAR{join} if the second is data dependent upon the first. 361 \item Generator order must be preserved when invoking \VAR{join}. 362 \item When a chain of three or more generators is joined, the 363 traversals must be combined left-associatively. 364 \end{itemize} 365 We can obtain a simple greedy desugaring which joins together 366 traversals in accordance with the above rules by simply adding the 367 following desugaring rule which takes precedence over those given in 368 \figref{simpleDesugar} when each variable bound in $v_1$ does not occur free in $g_2$. 369 \begin{center} 370 %T[\R,BOXPLUS\][ v1 <- g1, v2 <- g2, gs ] body 371 \EXP{\mathcal{T}\llbracket{}R,\boxplus\rrbracket[\,v_{1} \leftarrow g_{1}, v_{2} \leftarrow g_{2}, \VAR{gs}\,]\;\VAR{body} 372 \;\;=\;\; 373 %T[\R,BOXPLUS\][ (v1,v2) <- g1.join(g2), gs ] body 374 \mathcal{T}\llbracket{}R,\boxplus\rrbracket[\,(v_{1},v_{2}) \leftarrow g_{1}.\VAR{join}(g_{2}), \VAR{gs}\,]\;\VAR{body}} 375 %%\\ 376 %%\hfill when $\VAR{BV}[v_{1}]$ does not intersect $\VAR{FV}[g_2]$ 377 \end{center} 378 %where the set of bound variables in $v_1$ does not intersect with the set of 379 %free variables in $g_2$. 380 381 382 \subsection{Using Overloading to Adapt Generators and Traversals} 383 384 Overloaded instances of the \VAR{generate} method can be used to adapt 385 a generator to the particular properties of the reduction being 386 performed. For example, a commutative monoid need only maintain a 387 single variable \VAR{result} containing the reduced value so far: 388 % value object BlockedRange(lo: ZZ64, hi: ZZ64, b: ZZ64) extends Generator[\ZZ64\] 389 % ... 390 % generate[\R extends CommutativeMonoid[\ R, OPLUS\], opr OPLUS\](body : ZZ64 -> R) : R = do 391 % result : R = Identity[\OPLUS\] 392 % traverse(l,u) = 393 % if u-l+1 <= max(b,1) then 394 % i : ZZ64 = l 395 % while i <= u do 396 % t = body(i) 397 % atomic result := result OPLUS t 398 % i += 1 399 % end 400 % () 401 % else 402 % mid = LC l/2 RC + LF u/2 RF 403 % (traverse(l,mid), traverse(mid+1,u)) 404 % () 405 % end 406 % traverse(lo, hi) 407 % result 408 % end 409 % end 410 \begin{Fortress} 411 {\tt~}\pushtabs\=\+\( \KWD{value}\;\;\KWD{object} \TYP{BlockedRange}(\VAR{lo}\COLON \mathbb{Z}64, \VAR{hi}\COLON \mathbb{Z}64, b\COLON \mathbb{Z}64) \KWD{extends} \TYP{Generator}\llbracket\mathbb{Z}64\rrbracket\)\\ 412 {\tt~~}\pushtabs\=\+\( \ldots\)\\ 413 \( \VAR{generate}\llbracket{}R \KWD{extends} \TYP{CommutativeMonoid}\llbracket\,R, \oplus\rrbracket, \KWD{opr} \mathord{\oplus}\rrbracket(\VAR{body} \mathrel{\mathtt{:}} \mathbb{Z}64 \rightarrow R) \mathrel{\mathtt{:}} R = \;\KWD{do}\)\\ 414 {\tt~~}\pushtabs\=\+\( \VAR{result} \mathrel{\mathtt{:}} R = \TYP{Identity}\llbracket\mathord{\oplus}\rrbracket\)\\ 415 \( \VAR{traverse}(l,u) =\)\\ 416 {\tt~~}\pushtabs\=\+\( \KWD{if} u-l+1 \leq \max(b,1) \KWD{then}\)\\ 417 {\tt~~}\pushtabs\=\+\( i \mathrel{\mathtt{:}} \mathbb{Z}64 = l\)\\ 418 \( \KWD{while} i \leq u \KWD{do}\)\\ 419 {\tt~~}\pushtabs\=\+\( t = \VAR{body}(i)\)\\ 420 \( \KWD{atomic} \VAR{result} \ASSIGN \VAR{result} \oplus t\)\\ 421 \( i \mathrel{+}= 1\)\-\\\poptabs 422 \( \KWD{end}\)\\ 423 \( ()\)\-\\\poptabs 424 \( \KWD{else}\)\\ 425 {\tt~~}\pushtabs\=\+\( \VAR{mid} = \lceil l/2 \rceil + \lfloor u/2 \rfloor\)\\ 426 \( (\VAR{traverse}(l,\VAR{mid}), \VAR{traverse}(\VAR{mid}+1,u))\)\\ 427 \( ()\)\-\\\poptabs 428 \( \KWD{end}\)\-\\\poptabs 429 \( \VAR{traverse}(\VAR{lo}, \VAR{hi})\)\\ 430 \( \VAR{result}\)\-\\\poptabs 431 \( \KWD{end}\)\-\\\poptabs 432 \( \KWD{end}\)\-\\\poptabs 433 \end{Fortress} 434 435 The choice of whether to apply this transformation is left up to the 436 author of the generator; when many iterations run in parallel the 437 \VAR{result} variable becomes a scalability bottleneck and this 438 technique should not be used. 439 440 Various other properties of the reduction operator can be exploited: 441 \begin{itemize} 442 \item Idempotent reductions permit redundant computation. For 443 example, when computing the maximum element of a set it might be 444 simpler to enumerate set elements more than once. 445 446 \item On the other hand, sometimes a more efficient non-idempotent 447 operator can be used for a reduction if the generator promises never 448 to produce duplicates---this fact can be used to advantage in set, 449 multiset, or map comprehensions. 450 451 \item If the reduction operator has a zero, this can be used to exit 452 early from a partial computation. This requires that the body 453 expression have no visible side effects such as writes or \KWD{io} actions. 454 \end{itemize} 455 456 At the moment, the author of a \TYP{Generator} is responsible for 457 taking advantage of opportunities such as these. In future, we expect 458 some standardized support for efficient versions of various traversals 459 based on experience with the definitions provided here. 460 461 \subsection{Making a Serial Version of a Generator or Distribution} 462 \seclabel{serial-generator} 463 464 \note{ 465 TODO: the mechanism for generator serialization is once again magic. 466 Formerly we constrained generator structure so the serialization was 467 straightforward (but this probably made things slow).} 468 469 A generator \VAR{g} can be made sequential simply by calling the builtin function \VAR{sequential} as follows: 470 %v <- sequential(g) 471 \begin{Fortress} 472 \(v \leftarrow \VAR{sequential}(g)\) 473 \end{Fortress} 474 The resulting generator yields its elements in the natural order 475 specified by the original generator. Several builtin generators (such 476 as those for array indices) have an associated distribution. For 477 these generators, \VAR{sequential} function simply re-distributes the 478 underlying object as follows: 479 %sequential(r) = Sequential.distribute(r) 480 \begin{Fortress} 481 \(\VAR{sequential}(r) = \TYP{Sequential}.\VAR{distribute}(r)\) 482 \end{Fortress} 483 As a convenient shorthand, the \VAR{sequential} function is also 484 defined to work for distributions themselves. The complete declarations of 485 the overloaded \VAR{sequential} function are as follows: 486 %sequential[\ E extends Any \](g : Generator[\E\]) : Generator[\E\] 487 %sequential[\ E extends Any \](d : Distribution) : Distribution 488 \begin{Fortress} 489 \(\VAR{sequential}\llbracket\,E \KWD{extends}\mskip 4mu plus 4mu\TYP{Any}\,\rrbracket(g \mathrel{\mathtt{:}}\mskip 4mu plus 4mu\TYP{Generator}\llbracket{}E\rrbracket) \mathrel{\mathtt{:}}\mskip 4mu plus 4mu\TYP{Generator}\llbracket{}E\rrbracket\)\\ 490 \(\VAR{sequential}\llbracket\,E \KWD{extends}\mskip 4mu plus 4mu\TYP{Any}\,\rrbracket(d \mathrel{\mathtt{:}}\mskip 4mu plus 4mu\TYP{Distribution}) \mathrel{\mathtt{:}}\mskip 4mu plus 4mu\TYP{Distribution}\) 491 \end{Fortress} 492 The \VAR{sequential} function has special meaning to the Fortress 493 implementation; there is no need to distinguish reduction variables in 494 loops for which generator is surrounded by a direct call to 495 \VAR{sequential}. -
trunk/Specification/advanced/parallelism-locality/distributions.tex
r4295 r4312 18 18 \section{Distributions} 19 19 \seclabel{distributions} 20 21 \note{Distributions are not yet supported. 22 Examples in this section are not tested.} 23 24 Most of the heavy lifting in mapping threads and arrays to regions is performed 25 by \emph{distributions}. An instance of the trait 26 \TYP{Distribution} describes the parallel structure of ranges and 27 other numeric generators (such as the generators for the index space 28 of an array), and provides for the allocation and distribution of 29 arrays on the machine: 30 %trait Distribution 31 % distribute[\E, B extends ArrayIndex\](Range[\B\]):Range[\B\] 32 % distribute[\E, B extends ArrayIndex\](a:Array[\E,B\]):Array[\E,B\] = 33 % distributeFromTo[\E,B\](a,a.distribution,self) 34 %end 35 \begin{Fortress} 36 \(\KWD{trait}\mskip 4mu plus 4mu\TYP{Distribution}\)\\ 37 {\tt~~}\pushtabs\=\+\( \VAR{distribute}\llbracket{}E, B \KWD{extends}\mskip 4mu plus 4mu\TYP{ArrayIndex}\rrbracket(\TYP{Range}\llbracket{}B\rrbracket)\COLONOP\TYP{Range}\llbracket{}B\rrbracket\)\\ 38 \( \VAR{distribute}\llbracket{}E, B \KWD{extends}\mskip 4mu plus 4mu\TYP{ArrayIndex}\rrbracket(a\COLONOP\TYP{Array}\llbracket{}E,B\rrbracket)\COLONOP\TYP{Array}\llbracket{}E,B\rrbracket =\)\\ 39 {\tt~~}\pushtabs\=\+\( \VAR{distributeFromTo}\llbracket{}E,B\rrbracket(a,a.\VAR{distribution},\KWD{self})\)\-\-\\\poptabs\poptabs 40 \(\KWD{end}\) 41 \end{Fortress} 42 43 Abstractly, a \TYP{Distribution} acts as a transducer for generators 44 and arrays. The \VAR{distribute} method applied to a multidimensional 45 \TYP{Range} organizes its indices into the leaves of a tree whose 46 inner nodes correspond to potential levels of parallelism and locality 47 in the underlying computation, producing a fresh \TYP{Range} whose 48 behavior as a \TYP{Generator} may differ from that of the passed-in 49 \TYP{Range}. The \VAR{distribute} method applied to an array creates 50 a copy of that array distributed according to the given distribution. 51 This is specified in terms of a call to the overloaded function 52 \VAR{distributeFromTo}. This permits the definition of specialized 53 versions of this function for particular pairs of distributions. 54 55 The intention of distributions is to separate the task of data 56 distribution and program correctness. That is, it should be possible 57 to write and debug a perfectly acceptable parallel program using only 58 the default data distribution provided by the system. Imposing a 59 distribution on particular computations, or designing and implementing 60 distributions from scratch, is a task best left for performance 61 tuning, and one which should not affect the correctness of a working 62 program. 63 64 There is a \TYP{DefaultDistribution} which is defined by the 65 underlying system. This distribution is designed to be reasonably 66 adaptable to different system scales and architectures, at the cost of 67 some runtime efficiency. Arrays and generators that are not 68 explicitly allocated through a distribution are given the 69 \TYP{DefaultDistribution}. 70 71 There is a generator, \VAR{indices}, 72 associated with every array. This generator is distributed in the 73 same way as the array itself. When we re-distribute an array, we also 74 re-distribute the generator; thus 75 \EXP{d.\VAR{distribute}(a.\VAR{indices})} is equivalent to 76 \EXP{(d.\VAR{distribute}(a)).\VAR{indices}}. 77 78 There are a number of built-in distributions: 79 \begin{tabbing} 80 \begin{tabular}{ll} 81 \TYP{DefaultDistribution} & Name for distribution chosen by system. \\ 82 \TYP{Sequential} 83 & Sequential distribution. 84 Arrays are allocated in one contiguous piece of memory. \\ 85 \TYP{Local} & Equivalent to \TYP{Sequential}. \\ 86 \TYP{Par} & Blocked into chunks of size 1. \\ 87 \TYP{Blocked} & Blocked into roughly equal chunks. \\ 88 \EXP{\TYP{Blocked}(n)} & Blocked into \VAR{n} roughly equal chunks. \\ 89 \TYP{Subdivided} & Chopped into $2^k$-sized chunks, recursively. \\ 90 \EXP{\TYP{Interleaved}(d_{1}, d_{2},\ldots d_{n})} 91 & The first \VAR{n} dimensions are distributed according to \EXP{d_{1} \ldots d_{n}}, \\ 92 & with subdivision alternating among 93 dimensions. \\ 94 \EXP{\TYP{Joined}(d_{1}, d_{2},\ldots d_{n})} 95 & The first \VAR{n} dimensions are distributed according to \EXP{d_{1} \ldots d_{n}}, \\ 96 & subdividing completely in each 97 dimension before proceeding to the next. 98 \end{tabular} 99 \end{tabbing} 100 From these, a number of composed distributions are provided: 101 \begin{tabbing} 102 \begin{tabular}{ll} 103 \EXP{\TYP{Morton}} 104 & Bit-interleaved Morton order~\cite{morton}, recursive subdivision 105 in all dimensions.\\ 106 \EXP{\TYP{Blocked}(x_{1}, x_{2}, \ldots x_{n})} 107 & Blocked in \VAR{n} dimensions into chunks of size \EXP{x_{i}} in dimension \VAR{i}; \\ 108 & remaining dimensions (if any) are local. 109 \end{tabular} 110 \end{tabbing} 111 112 To allocate an array which is local to a single thread (and most 113 likely allocated in contiguous storage), the \TYP{Local} 114 distribution can be used: 115 %a = Local.distribute [ 1 0 0 ; 0 1 0 ; 0 0 1 ] 116 \begin{Fortress} 117 \(a = \TYP{Local}.\VAR{distribute} [\,1\;0\;0 ; 0\;1\;0 ; 0\;0\;1\,]\) 118 \end{Fortress} 119 Other distributions can be requested in a similar way. 120 121 122 Distributions can be constructed and given names: 123 %spatialDist = Blocked(n,n,1) (* Pencils along the $z$ axis *) 124 \begin{Fortress} 125 \(\VAR{spatialDist} = \TYP{Blocked}(n,n,1) \mathtt{(*}\;\hbox{\rm Pencils along the $z$ axis \unskip}\;\mathtt{*)}\) 126 \end{Fortress} 127 The system will lay out arrays with the same distribution in the same 128 way in memory (as much as this is feasible), and will run loops with 129 the same distribution in the same way (as much as this is feasible). 130 By contrast, if we replace every occurrence of \VAR{spatialDist} by 131 \EXP{\TYP{Blocked}(n,n,1)}, this code will likely divide up arrays and 132 ranges into the same-sized pieces as above, but these pieces need not 133 be collocated. -
trunk/Specification/advanced/parallelism-locality/early-termination.tex
r4295 r4312 18 18 \section{Early Termination of Threads} 19 19 \seclabel{early-termination} 20 21 As noted in \secref{threads-parallelism}, an implicit thread 22 can be terminated if its group is going to throw an exception. 23 Similarly, a spawned thread \VAR{t} may be terminated by calling 24 \EXP{t.\VAR{stop}()}. A successful attempt to terminate a thread causes the 25 thread to complete asynchronously. There is no guarantee that 26 termination attempts will be prompt, or that they will occur at all; 27 the implementation will make its best effort. If a thread completes 28 normally or exceptionally before an attempt to terminate it succeeds, 29 the result is retained and the termination attempt is simply dropped. 30 31 At present stopping a thread immediately causes it to cease execution; 32 no outstanding \KWD{finally} blocks are run and the thread is not 33 considered to return a result. 34 35 \note{From here till the end of this section, copied from F1.0$\beta$.} 36 37 A termination attempt acts as if a special hidden \emph{stop 38 exception} is thrown in that thread. This exception cannot be 39 thrown by \KWD{throw} or caught by \KWD{catch}; however, \KWD{finally} 40 clauses are run as with any other exception. If the stopped thread 41 was in the middle of an \KWD{atomic} expression, the effects of that 42 expression are rolled back just as with an ordinary \KWD{throw}. A 43 special wrapper around every spawned thread is provided by the 44 Fortress implementation; it catches the stop exception and transforms 45 it into a deferred \TYP{Stopped} exception. This is visible to the 46 programmer and should be caught by invoking the \VAR{val} method on 47 the thread object. Implicit threads are terminated only if another 48 thread in the group completes abruptly, and the threads that are 49 terminated are ignored for the purposes of the completion of the 50 group. 51 52 Typical code for stopping a thread looks something like the following 53 example: 54 %x : ZZ64 := 0 55 %t = spawn do 56 % try 57 % atomic if x=0 then abort() else () end 58 % finally 59 % x := 1 60 % end 61 % end 62 %t.stop() 63 %try 64 % t.val() 65 %catch s 66 % Stopped => x += 2; x 67 %end 68 \begin{Fortress} 69 \(x \mathrel{\mathtt{:}} \mathbb{Z}64 \ASSIGN 0\)\\ 70 \(t = \null\)\pushtabs\=\+\(\KWD{spawn}\;\;\KWD{do}\)\\ 71 {\tt~~~~~~}\pushtabs\=\+\( \KWD{try}\)\\ 72 {\tt~~}\pushtabs\=\+\( \KWD{atomic}\;\;\KWD{if} x=0 \KWD{then} \VAR{abort}() \KWD{else} () \KWD{end}\)\-\\\poptabs 73 \( \KWD{finally}\)\\ 74 {\tt~~}\pushtabs\=\+\( x \ASSIGN 1\)\-\\\poptabs 75 \( \KWD{end}\)\-\\\poptabs 76 \( \KWD{end}\)\-\\\poptabs 77 \(t.\VAR{stop}()\)\\ 78 \(\KWD{try}\)\\ 79 {\tt~~}\pushtabs\=\+\( t.\VAR{val}()\)\-\\\poptabs 80 \(\KWD{catch} s\)\\ 81 {\tt~~}\pushtabs\=\+\( \TYP{Stopped} \Rightarrow x \mathrel{+}= 2; x\)\-\\\poptabs 82 \(\KWD{end}\) 83 \end{Fortress} 84 Here the spawned thread \VAR{t} blocks until it is killed by the call 85 to \EXP{\VAR{t}.\VAR{stop}()}; it sets \VAR{x} to 1 in the 86 \KWD{finally} clause before exiting. In this case, the call to 87 \EXP{\VAR{t}.\VAR{val}()} will throw \TYP{Stopped}, which is caught, 88 causing 2 to be added to \VAR{x} and returning 3. 89 90 Note that there is a race in the above code, so the \KWD{try} block in 91 \VAR{t} may not have been entered when \EXP{\VAR{t}.\VAR{stop}()} is 92 called, causing $x$ to be 2 at the end of execution. Note also that 93 the call to \EXP{\VAR{t}.\VAR{stop}()} occurs asynchronously; in the 94 absence of the call to \EXP{\VAR{t}.\VAR{val}()}, the spawning thread 95 would not have waited for \VAR{t} to complete. -
trunk/Specification/advanced/parallelism-locality/intro.tex
r4295 r4312 16 16 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17 17 18 \note{Distributions are not yet supported.} 19 18 20 \label{parallel-intro} 21 Fortress is designed to make parallel programming as simple and as 22 painless as possible. This chapter describes the internals of 23 Fortress parallelism designed for use by authors of library code (such as 24 \emph{distributions}, generators, and arrays). We adopt a multi-tiered 25 approach to parallelism: 26 \begin{itemize} 27 28 \item At the highest level, we provide libraries that allocate 29 locality-aware distributed 30 shared arrays (\secref{arrays}) and implicitly 31 parallel constructs such as tuples and loops. Synchronization is 32 accomplished through the use of atomic sections (\secref{atomic}). 33 More complex synchronization makes use of abortable atomicity, 34 described in \secref{transactions}. 35 36 \item There is an extensive library of distributions, which 37 permits the programmer to specify locality and data distribution 38 explicitly (\secref{distributions}). 39 40 \item 41 Immediately below that, the \KWD{at} expression requests that a 42 computation take place in a particular region of the machine 43 (\secref{parallelism-fundamentals}). 44 We also provide a mechanism to 45 terminate a spawned thread early (\secref{early-termination}). 46 47 \item Finally, there are mechanisms for constructing new generators 48 via recursive subdivision into tree structures with individual 49 elements at the leaves. 50 \secref{defining-generators} explains how 51 iterative constructs such as \KWD{for} loops and comprehensions 52 are desugared into calls to methods of trait \TYP{Generator}, and how 53 new instances of this trait may be defined. 54 55 \end{itemize} 56 57 We begin by describing the abstraction of \emph{regions}, which Fortress 58 uses to describe the machine on which a program is run. -
trunk/Specification/advanced/parallelism-locality/primitives-distributions.tex
r4295 r4312 18 18 \section{Placing Threads} 19 19 \seclabel{parallelism-fundamentals} 20 21 A thread can be placed in a particular region by using an \KWD{at} 22 expression: 23 \input{\home/advanced/examples/Parallel.At.a.tex} 24 25 In this example, two implicit threads are created; the first computes 26 \EXP{a_i} locally, the second computes \EXP{a_j} in the region where 27 the $j^{th}$ element of $a$ resides, specified by 28 \EXP{a.\VAR{region}(j)}. The expression after \KWD{at} must return a 29 value of type \TYP{Region}, and the block immediately following 30 \KWD{do} is run in that region; the result of the block is the result 31 of the \KWD{at} expression as a whole. Often it is more graceful to 32 use the \EXP{\KWD{also}\;\KWD{do}} construct 33 (described in\secref{also-block}) 34 in these cases: 35 \input{\home/advanced/examples/Parallel.At.b.tex} 36 37 We can also use \KWD{at} with a \KWD{spawn} expression: 38 \input{\home/advanced/examples/Parallel.At.c.tex} 39 40 Finally, note that it is possible to use an \KWD{at} expression within 41 a block: 42 \input{\home/advanced/examples/Parallel.At.d.tex} 43 We can think of this as the degenerate case of \EXP{\KWD{also}\; 44 \KWD{do}}: a thread group is created with a single implicit thread 45 running the contents of the \KWD{at} expression in the given region; when 46 this thread completes control returns to the original location. 47 48 Note that the regions given in an \KWD{at} expression are non-binding: 49 the Fortress implementation may choose to run the computations 50 elsewhere---for example, thread migration might not be possible within 51 an \KWD{atomic} expression, or load balancing might cause code to be 52 executed in a different region. In general, however, implementations 53 should attempt to respect thread placement annotations when they are 54 given. -
trunk/Specification/advanced/parallelism-locality/regions-threads.tex
r4295 r4312 18 18 \section{Regions} 19 19 \seclabel{regions} 20 21 Every thread (either explicit or implicit) and every object in Fortress, 22 and every element of a Fortress array (the physical storage for that array 23 element), has an associated \emph{region}. 24 The Fortress libraries provide a function \VAR{region} 25 which returns the region in which a given object resides. 26 Regions abstractly describe the structure of 27 the machine on which a Fortress program is running. They are 28 organized hierarchically to form a tree, the \emph{region hierarchy}, 29 reflecting in an abstract way the degree of locality which those 30 regions share. The distinguished region \TYP{Global} represents the root 31 of the region hierarchy.\footnote{Note: the initial implementation of the Fortress language assumes a single machine with shared memory and exposes only the \TYP{Global} region.} 32 The different levels of this tree reflect underlying 33 machine structure, such as execution engines within a CPU, memory 34 shared by a group of processors, or resources distributed across the 35 entire machine. The function \EXP{\VAR{here}()} returns the region in which execution is currently occurring. Objects which reside in regions near the leaves of 36 the tree are local entities; those which reside at higher levels of 37 the region tree are logically spread out. 38 The method call 39 \EXP{r.\VAR{isLocalTo}(s)} returns \VAR{true} if \VAR{r} is contained 40 within the region tree rooted at \VAR{s}. 41 42 It is important to understand that regions and the structures 43 (such as distributions, \secref{distributions}) 44 built on top of them exist 45 purely for performance purposes. The placement of a thread or an 46 object does not have any semantic effect on the meaning of a program; 47 it is simply an aid to enable the implementation to make informed 48 decisions about data placement. 49 50 It might not be possible for an object or a thread to reside in a given 51 region. Threads of execution reside at the \emph{execution level} of 52 the region hierarchy, generally the bottommost level in the region 53 tree. Each thread is generally associated with some region at the 54 execution level, indicating where it will preferentially be run. 55 The programmer can affect the choice of region by using an \KWD{at} 56 expression (\secref{parallelism-fundamentals}) when the thread is 57 created. A thread may have an associated region which is not at 58 the execution level of the region hierarchy, either because a higher 59 region was requested with an \KWD{at} expression or because scheduling 60 decisions permit the thread to run in several possible execution 61 regions. The region to which a thread is assigned may also change 62 over time due to scheduling decisions. 63 For the object associated with a spawned thread, 64 the \VAR{region} function provided by the Fortress libraries 65 returns the region of the associated thread. 66 67 68 The \emph{memory level} of the region hierarchy is where individual 69 reference objects reside; on a machine with nodes composed of multiple 70 processor cores sharing a single memory, this generally will not be a 71 leaf of the region hierarchy. 72 Imagine a constructor for a reference 73 object is called by a thread residing in region \VAR{r}, yielding an 74 object \VAR{o}. Except in very rare circumstances (for example when a 75 local node is out of memory) either 76 %r.isLocalTo(region(o)) 77 \EXP{r.\VAR{isLocalTo}(\VAR{region}(o))} or 78 %region(o).isLocalTo(r) 79 \EXP{\VAR{region}(o).\VAR{isLocalTo}(r)} ought to hold: data is 80 allocated locally to the thread which runs the constructor. For a value object 81 \VAR{v} being manipulated by a thread residing in region \VAR{r} either 82 %region(v).isLocalTo(r) 83 \EXP{\VAR{region}(v).\VAR{isLocalTo}(r)} or 84 %r.isLocalTo(region(v)) 85 \EXP{r.\VAR{isLocalTo}(\VAR{region}(v))} 86 (value objects always appear to be local). 87 88 Note that \VAR{region} is a top-level function provided by the Fortress libraries 89 and can be overridden by any functional method. 90 The chief example of this is arrays, which are 91 generally composed from many reference objects; the \VAR{region} function 92 can be 93 overridden to return the location of the array as a 94 whole---the region which contains all of its constituent reference objects. -
trunk/Specification/advanced/parallelism-locality/shared-local.tex
r4295 r4312 18 18 \section{Shared and Local Data} 19 19 \seclabel{threadlocal} 20 21 \note{The method \VAR{copy} is not yet supported.} 22 23 Every object in a Fortress program is considered to be either 24 \emph{shared} or \emph{local} (collectively referred to as the 25 \emph{sharedness} of the object). A local object must be transitively 26 reachable (through zero or more object references) from the variables 27 of at most one running thread. A local object may be accessed more 28 cheaply than a shared object, particularly in the case of atomic reads 29 and writes. Sharedness is ordinarily managed implicitly by the 30 Fortress implementation. 31 Control over sharedness is intended to be a 32 performance optimization; however, functions such as \VAR{isShared} and 33 \VAR{localize} provided by the Fortress libraries 34 can affect program semantics, and must be used with care. 35 36 The sharedness of an object must be contrasted with its region. The 37 region of an object describes where that object is located on the 38 machine. The sharedness of an object describes whether the object is 39 visible to one thread or to many. A local object need not actually 40 reside in a region near the thread to which it is visible (though 41 ordinarily it will). 42 43 The following rules govern sharedness: 44 \begin{itemize} 45 \item Reference objects are initially local when they are constructed. 46 \item The sharedness of an object may change as the program executes.\footnote{Note, for example, that the present Fortress implementation immediately makes every object shared after construction, so that \VAR{isShared()} will always return \VAR{true}.} 47 \item If an object is currently transitively reachable from more than 48 one running thread, it must be shared. 49 \item When a reference to a local object is stored into a field of a 50 shared object, the local object must be \emph{published}: Its 51 sharedness is changed to shared, and all of the data to which it 52 refers is also published. 53 \item The value of a local variable referenced by a thread must be 54 published before that thread may be run in parallel with the thread 55 which created it. Values assigned to the variable while the 56 threads run in parallel must also be published. 57 \item A field with value type is assigned by copying, and thus has the 58 sharedness of the containing object or closure. 59 \end{itemize} 60 61 Publishing can be expensive, particularly if the structure being 62 broadcast is large and heavily nested; this can cause an apparently 63 short \KWD{atomic} expression (a single write, say) to run arbitrarily 64 long. To avoid this, the library programmer can request that an 65 object be published by calling the semantically transparent function 66 \VAR{shared} provided by the Fortress libraries: 67 \input{\home/advanced/examples/Parallel.Shared.a.tex} 68 A local copy of an object can be obtained by calling \VAR{copy}, a 69 method on trait \TYP{Any}: 70 \note{Example is commented out because it is not yet supported nor run by the interpreter.} 71 % %localVar := sharedVar.copy() 72 % \begin{Fortress} 73 % \(\VAR{localVar} \ASSIGN \VAR{sharedVar}.\VAR{copy}()\) 74 % \end{Fortress} 75 76 Two additional functions are provided which permit different choices of 77 program behavior based on the sharedness of objects: 78 \begin{itemize} 79 \item The function \EXP{\VAR{isShared}(o)} returns \VAR{true} when 80 \VAR{o} is shared, and \VAR{false} when it is local. This permits 81 the program to take different actions based on sharedness. 82 \item The function \EXP{\VAR{localize}(o)} is provided that attempts to make a local version of object \VAR{o}, by copying if necessary 83 equivalent to the following expression: 84 \note{Example is commented out because it is not yet supported nor run by the interpreter.} 85 %% \input{\home/advanced/examples/Parallel.Shared.b.tex} 86 %% %% %if o.isShared then o.copy() else o end 87 %% %% \begin{Fortress} 88 %% %% \(\KWD{if} o.\VAR{isShared} \KWD{then} o.\VAR{copy}() \KWD{else} o \KWD{end}\) 89 %% %% \end{Fortress} 90 \end{itemize} 91 These functions must be used with extreme caution. For example, 92 \VAR{localize} should be used only when there is a unique 93 reference to the object being localized. The \VAR{localize} function 94 can have unexpected behavior if there is a reference to \VAR{o} from 95 another local object \VAR{p}. Updates to \VAR{o} will be visible 96 through \VAR{p}; subsequent publication of \VAR{p} will publish 97 \VAR{o}. By contrast, if \VAR{o} was already shared, and referred to 98 by another shared object, the newly-localized copy will be entirely 99 distinct; changes to the copy will not be visible through \VAR{p}, and 100 publishing \VAR{p} will not affect the locality of the copy. -
trunk/Specification/advanced/parallelism-locality/transactions.tex
r4295 r4312 18 18 \section{Abortable Atomicity} 19 19 \seclabel{transactions} 20 21 Fortress provides a user-level \EXP{\VAR{abort}()} function which 22 abandons execution of the innermost \KWD{atomic} expression and rolls back its 23 changes, requiring the \KWD{atomic} expression to execute again from 24 the beginning. This permits an atomic section to perform consistency 25 checks as it runs. 26 Invoking the \VAR{abort} function not within an \KWD{atomic} expression has 27 no effect. 28 The functionality provided by 29 \EXP{\VAR{abort}()} can be abused; it is possible to induce deadlock 30 or livelock by creating an atomic section that always fails. Here is 31 a simple example of a program using \EXP{\VAR{abort}()} which is 32 incorrect because Fortress does not guarantee that the two implicit 33 threads (created by evaluating the two elements of the tuple) will 34 always run in parallel; it is possible for the first element of the 35 tuple to continually abort without ever running the second element of 36 the tuple: 37 \note{The example is commented out because it is not yet supported nor run by the interpreter.} 38 %% \input{\home/advanced/examples/Parallel.Abort.a.tex} 39 40 Fortress also includes a \KWD{tryatomic} expression, which attempts to 41 run its body expression atomically. If it succeeds, the result is returned; 42 if it aborts due to a call to \VAR{abort} or due to conflict 43 (as described in \secref{atomic}), 44 the checked exception \TYP{TryAtomicFailure} is thrown. In addition, \KWD{tryatomic} is permitted to throw \TYP{TryAtomicFailure} in the absence of conflict; however, it is not permitted to fail unless some other thread performs an access to shared state while the body is being run. 45 Conceptually \KWD{atomic} can be defined in terms of \KWD{tryatomic} as follows: 46 \input{\home/advanced/examples/Parallel.Abort.b.tex} 47 Unlike the above definition, an implementation may choose to suspend a 48 thread running an \KWD{atomic} expression which invokes \VAR{abort}, 49 re-starting it at a later time when it may be possible to make further 50 progress. The above definition restarts the body of the \KWD{atomic} 51 expression immediately without suspending. -
trunk/Specification/advanced/subscripting.tex
r4295 r4312 18 18 \section{Subscripting Operator Method Declarations} 19 19 \seclabel{subscripting-ops} 20 21 A subscripting operator method declaration has 22 \KWD{opr} where a method declaration would have an identifier. 23 The value parameter list, rather than being surrounded by parentheses, 24 is surrounded by a pair of brackets. A subscripting operator method 25 declaration may have any number of value parameters, keyword parameters, 26 and varargs parameters in that 27 value parameter list. Static parameters may also be present, between 28 \KWD{opr} and the left bracket. Any paired 29 Unicode brackets may be so defined \emph{except} ordinary 30 parentheses and white square brackets; in particular, the square 31 brackets ordinarily used for indexing may be used. 32 33 An expression consisting of a subexpression immediately 34 followed (with no intervening whitespace) by zero or more 35 comma-separated expressions surrounded by brackets will 36 invoke a subscripting operator method declaration. Methods 37 for the expression preceding the bracketed expression list are 38 considered. The compiler considers all subscripting operator method 39 declarations that are both accessible and applicable, and the most 40 specific method declaration is chosen according to the usual overloading 41 rules. For example, the expression \EXP{\VAR{foo}_p} might invoke the 42 following subscripting method declaration because expressions in the square 43 brackets are rendered as subscripts: 44 \input{\home/advanced/examples/OprDecl.Subscripting.tex} 45 46 47 20 48 \section{Subscripted Assignment Operator Method Declarations} 21 49 \seclabel{subscripted-assignment} 50 51 A subscripted assignment operator method declaration has 52 \KWD{opr} where a method declaration would have an identifier. The value 53 parameter list, rather than being surrounded by parentheses, is 54 surrounded by a pair of brackets; this is then followed by the 55 operator \txt{:=} and then a second value parameter list in parentheses, 56 which must contain exactly one non-keyword 57 value parameter. A subscripted 58 assignment operator method declaration may have any number of value 59 parameters within the brackets; these value parameters may include 60 keyword parameters and 61 varargs parameters. A result type 62 may appear after the second value parameter list, but it must be \TYP{()}. 63 Static parameters may also be present, between \KWD{opr} 64 and the left bracket. Any paired Unicode brackets may be so 65 defined \emph{except} ordinary parentheses and white square brackets; in 66 particular, the square brackets ordinarily used for indexing may 67 be used. 68 69 An assignment expression consisting of an expression immediately 70 followed (with no intervening whitespace) by zero or more 71 comma-separated expressions surrounded by brackets, followed by the 72 assignment operator \txt{:=}, followed by another expression, will 73 invoke a subscripted assignment operator method declaration. Methods 74 for the expression preceding the bracketed expression list are 75 considered. The compiler considers all subscript operator method 76 declarations that are both accessible and applicable, and the most 77 specific method declaration is chosen according to the usual overloading 78 rules. When a compound assignment operator (described in 79 \secref{operator-app-expr}) is used with a subscripting operator and 80 a subscripted assignment operator, for example \EXP{a_{3} \mathrel{+}= k}, 81 both a subscripting operator declaration and a subscripted assignment 82 operator declaration are required. 83 For example, the assignment \EXP{\VAR{foo}_p \ASSIGN \VAR{myWidget}} might 84 invoke the following subscripted assignment method declaration: 85 \input{\home/advanced/examples/OprDecl.SubscriptedAssignment.tex} 86 87 88 89 22 90 \section{Conditional Operator Declarations} 23 91 \seclabel{conditional-operators-impl} 92 93 A \emph{conditional operator} is a binary operator (other than `\txt{:}' and 94 `\txt{::}') that 95 is immediately followed by `\txt{:}'; see \secref{conditional-operators}. 96 A conditional operator expression \EXP{x@\COLONOP{}y} is syntactic sugar for 97 \EXP{x@(\KWD{fn} () \Rightarrow y)}; that is, the right-hand operand 98 is converted to a ``thunk'' 99 (zero-parameter function) that then becomes the right-hand operand of the 100 corresponding unconditional operator. Therefore a conditional 101 operator is simply implemented as an overloading of the operator that 102 accepts a thunk. 103 104 105 It is also permitted for a conditional operator to have a preceding as 106 well as a following colon. A conditional operator expression 107 \EXP{x\COLONOP@\COLONOP{}y} is syntactic sugar for \EXP{(\KWD{fn} () 108 \Rightarrow x)@(\KWD{fn} () \Rightarrow y)}; 109 that is, each operand is converted to a thunk. This mechanism is 110 used, for example, to define the results-comparison operator 111 \txt{:$\sim$:}, which takes exceptions into account. 112 113 114 The conditional $\wedge$ and $\vee$ operators for 115 boolean values, for example, are implemented as follows: 116 \input{\home/library/examples/ConditionalOps.tex} 117 118 119 24 120 \section{Big Operator Declarations} 25 121 \seclabel{big-operators-impl} 122 123 A \emph{big operator} such as $\sum$ or $\prod$ is declared as a usual 124 operator declaration. 125 See \secref{defining-generators} for an example declaration of a big operator. 126 A big operator application is either a \emph{reduction expression} 127 described in \secref{reduction-expr} or a \emph{comprehension} 128 described in \secref{comprehensions}. -
trunk/Specification/basic/overloading.tex
r4271 r4312 18 18 \chapter{Overloading and Multiple Dispatch} 19 19 \chaplabel{multiple-dispatch} 20 21 \section{Terminology and Notation} 22 \seclabel{overloading-terms} 23 \section{Applicability to Named Functional Calls} 24 \seclabel{functional-applicability} 25 \section{Applicability to Dotted Method Calls} 26 \seclabel{dotted-method-applicability} 27 \section{Applicability for Functionals with Varargs 28 %and Keyword 29 Parameters} 30 \seclabel{applicability-with-special-params} 31 \section{Overloading Resolution} 32 \seclabel{resolving-overloading} -
trunk/Specification/fortress/fortress.bib
r4307 r4312 48 48 } 49 49 50 @InProceedings{fool09, 51 title = "Growing a Syntax", 52 author = "Eric Allen and Ryan Culpepper and Janus Dam Nielsen and Jon Rafkind and Sukyoung Ryu", 53 booktitle = "Foundations of Object-Oriented Languages", 54 year = 2009 55 } 56 50 57 @misc{FortressInterpreter, 51 58 author = "Sun's Programming Language Research Group", … … 91 98 } 92 99 100 @techreport{morton, 101 author = "G. M. Morton", 102 title = "A computer oriented geodetic data base and a new technique in file sequencing", 103 institution = "IBM Ltd.", 104 month = mar, 105 year = 1966 106 } 107 93 108 @techreport{nistSP811, 94 109 author = "Barry N. Taylor",

