| | 20 | |
| | 21 | \note{Keyword and varargs parameters, |
| | 22 | array comprehensions, |
| | 23 | dimensions and units, |
| | 24 | tests and properties, |
| | 25 | distributions, |
| | 26 | some ASCII conversion, and |
| | 27 | some common types are not yet supported. |
| | 28 | |
| | 29 | From \secref{programming-env} to \secref{apitool} are out of date. |
| | 30 | |
| | 31 | Some examples in this chapter are not tested nor run by the interpreter.} |
| | 32 | |
| | 33 | \note{Eric: Note that APIs are difficult to remove from fortresses: we have |
| | 34 | to first remove every component referring to them. Also note |
| | 35 | that an autogenerated API source file isn't automatically compiled |
| | 36 | into the fortress. I think the error should be signaled when the |
| | 37 | programmer tries to compile the API.} |
| | 38 | |
| | 39 | In this chapter, we provide a high-level overview of the entire Fortress |
| | 40 | language. We present most features in this chapter through the use of examples, |
| | 41 | which should be accessible to programmers of other languages. |
| | 42 | In this chapter, unlike the rest of the specification, |
| | 43 | no attempt is made to provide complete descriptions |
| | 44 | of the various language features presented. Instead, we intend this overview to |
| | 45 | provide useful context for reading other sections of this specification, |
| | 46 | which provide rigorous definitions for what is merely |
| | 47 | introduced here. |
| | 48 | |
| | 49 | \section{The Fortress Programming Environment} |
| | 50 | \seclabel{programming-env} |
| | 51 | |
| | 52 | Although Fortress is independent of the properties of a particular |
| | 53 | platform on which it is implemented, it is helpful for concreteness |
| | 54 | to present the programming model used in the Fortress reference implementation. |
| | 55 | In this programming model, |
| | 56 | Fortress source code is stored in files and organized in |
| | 57 | directories, and there is a text-based shell from which we can store |
| | 58 | environment variables and issue commands to execute and compile |
| | 59 | programs. |
| | 60 | |
| | 61 | A Fortress program can be processed in one of two ways: |
| | 62 | |
| | 63 | \begin{itemize} |
| | 64 | |
| | 65 | \item It can be \emph{executed}. The Fortress program is stored in a file with |
| | 66 | the suffix ``\shellcommand{.fss}'' and executed directly from an underlying |
| | 67 | operating |
| | 68 | system shell by calling the command ``\shellcommand{fortress run}'' on it. |
| | 69 | For example, |
| | 70 | suppose we write the following \(\hbox{\rm``\STR{Hello,~world!}''}\) program |
| | 71 | to a file ``\shellcommand{HelloWorld.fss}'': |
| | 72 | \input{\home/preliminaries/examples/Overview.shell.a.tex} |
| | 73 | |
| | 74 | The first line is an \emph{export statement}; |
| | 75 | we ignore it for the moment. |
| | 76 | The second line defines a function \VAR{run}, |
| | 77 | which takes a parameter named \VAR{args} |
| | 78 | and prints the string \(\hbox{\rm``\STR{Hello,~world!}''}\). |
| | 79 | Note that the parameter \VAR{args} |
| | 80 | does not include a declaration of its type. |
| | 81 | In many cases, |
| | 82 | types can be elided in Fortress and inferred from context. |
| | 83 | (In this case, |
| | 84 | the type of \VAR{args} is inferred based on the program's export statement, |
| | 85 | explained in \secref{overview:apis}.) |
| | 86 | |
| | 87 | We can execute this program by issuing the following command to the shell: |
| | 88 | |
| | 89 | \shellcommand{fortress run HelloWorld.fss} |
| | 90 | |
| | 91 | The instruction \shellcommand{fortress run} can be abbreviated as \shellcommand{fortress}: |
| | 92 | |
| | 93 | \shellcommand{fortress HelloWorld.fss} |
| | 94 | |
| | 95 | \item It can be \emph{compiled}. In this case, the Fortress program is |
| | 96 | compiled into a |
| | 97 | \emph{component}, which is stored in a hidden persistent cache maintained by the implementation, |
| | 98 | called a \emph{fortress}. Typically, a single fortress holds all the components |
| | 99 | of a user, or group of users sharing programs and libraries. |
| | 100 | In our examples, |
| | 101 | we often refer to the fortress we are storing components in |
| | 102 | as \emph{the resident fortress}. |
| | 103 | |
| | 104 | For example, we could have written our \(\hbox{\rm``\STR{Hello,~world!}''}\) |
| | 105 | program as follows: |
| | 106 | \input{\home/preliminaries/examples/HelloWorld.tex} |
| | 107 | |
| | 108 | We can compile this program, by issuing the command |
| | 109 | ``\shellcommand{fortress compile}'' on it: |
| | 110 | |
| | 111 | \shellcommand{fortress compile HelloWorld.fss} |
| | 112 | |
| | 113 | As a result of this command, a component named ``\TYP{HelloWorld}'' is stored |
| | 114 | in the resident fortress. The name of this component is provided by |
| | 115 | the enclosing component declaration surrounding the code. If there is |
| | 116 | no enclosing component declaration, then the contents of the file are |
| | 117 | understood to belong to a single component whose name is that of the |
| | 118 | file it is stored in, minus its suffix. For example, suppose we write the |
| | 119 | following program in a source file named ``\shellcommand{HelloWorld2.fss}'': |
| | 120 | \input{\home/preliminaries/examples/HelloWorld2.tex} |
| | 121 | |
| | 122 | When we compile this file: |
| | 123 | |
| | 124 | \shellcommand{fortress compile HelloWorld2.fss} |
| | 125 | |
| | 126 | the result is that a new component with the name \TYP{HelloWorld2} is stored |
| | 127 | in the resident fortress. |
| | 128 | Once this component is compiled, |
| | 129 | we can execute it by issuing |
| | 130 | the following command: |
| | 131 | |
| | 132 | \shellcommand{fortress run HelloWorld2.fss} |
| | 133 | |
| | 134 | Compiling a source file allows us to catch static errors before running a program. |
| | 135 | It also allows the system to perform static optimizations on a program and use those |
| | 136 | optimizations when executing. |
| | 137 | |
| | 138 | Once a program is compiled, the cached code will be used during execution unless |
| | 139 | modifications have been made to the source file since the most recent compilation. |
| | 140 | If the source file is newer, the program is recompiled before execution. |
| | 141 | |
| | 142 | \end{itemize} |
| | 143 | |
| | 144 | A source file must contain exactly one component declaration, and its name must |
| | 145 | match the file name. |
| | 146 | |
| | 147 | In a compiled file, |
| | 148 | multiple component declarations may be included. |
| | 149 | For example, we could write the following file |
| | 150 | \shellcommand{HelloWorld3.fss}: |
| | 151 | |
| | 152 | %component HelloWorld |
| | 153 | % export Executable |
| | 154 | % run(args) = print "Hello, world!" |
| | 155 | %end |
| | 156 | % |
| | 157 | %component HelloWorld2 |
| | 158 | % export Executable |
| | 159 | % run(args) = print "Hi, it's me again!" |
| | 160 | %end |
| | 161 | \begin{Fortress} |
| | 162 | \(\KWD{component} \TYP{HelloWorld}\)\\ |
| | 163 | {\tt~~~}\pushtabs\=\+\( \KWD{export} \TYP{Executable}\)\\ |
| | 164 | \( \VAR{run}(\VAR{args}) = \VAR{print}\;\hbox{\rm``\STR{Hello,~world!}''}\)\-\\\poptabs |
| | 165 | \(\KWD{end}\)\\[4pt] |
| | 166 | \(\KWD{component} \TYP{HelloWorld2}\)\\ |
| | 167 | {\tt~~~}\pushtabs\=\+\( \KWD{export} \TYP{Executable}\)\\ |
| | 168 | \( \VAR{run}(\VAR{args}) = \VAR{print}\;\hbox{\rm``\STR{Hi,~it's~me~again!}''}\)\-\\\poptabs |
| | 169 | \(\KWD{end}\) |
| | 170 | \end{Fortress} |
| | 171 | |
| | 172 | When we compile this file, the result is that both the components |
| | 173 | \TYP{HelloWorld} and \TYP{HelloWorld2} are stored in the resident fortress. |
| | 174 | |
| | 175 | If a fortress already contains a component with the same name as a |
| | 176 | newly installed component, the new component shadows the old one. For |
| | 177 | example, if we first compile the source file \shellcommand{HelloWorld3.fss} |
| | 178 | above and then compile the following file \shellcommand{HelloWorld4.fss}: |
| | 179 | |
| | 180 | %component HelloWorld |
| | 181 | % export Executable |
| | 182 | % run(args) = print "I didn't expect that!" |
| | 183 | %end |
| | 184 | \begin{Fortress} |
| | 185 | \(\KWD{component} \TYP{HelloWorld}\)\\ |
| | 186 | {\tt~~~}\pushtabs\=\+\( \KWD{export} \TYP{Executable}\)\\ |
| | 187 | \( \VAR{run}(\VAR{args}) = \VAR{print}\;\hbox{\rm``\STR{I~didn't~expect~that!}''}\)\-\\\poptabs |
| | 188 | \(\KWD{end}\) |
| | 189 | \end{Fortress} |
| | 190 | |
| | 191 | then executing the component \TYP{HelloWorld} on our fortress will result in |
| | 192 | printing of the following text: |
| | 193 | |
| | 194 | \begin{verbatim} |
| | 195 | I didn't expect that! |
| | 196 | \end{verbatim} |
| | 197 | |
| | 198 | We can also ``remove'' a component from a fortress. |
| | 199 | For example: |
| | 200 | |
| | 201 | \shellcommand{fortress remove HelloWorld} |
| | 202 | |
| | 203 | After issuing this command, we can no longer refer to \shellcommand{HelloWorld} |
| | 204 | component when issuing commands to the fortress. |
| | 205 | (However, a removed component might still exist as a constituent of other, |
| | 206 | \emph{linked}, components; see \secref{overview:apis}.) |
| | 207 | |
| | 208 | \label{overviewComponent} |
| | 209 | \section{Exports and Imports} |
| | 210 | \seclabel{overview:apis} |
| | 211 | |
| | 212 | When a component is defined, it can include \emph{export statements}. |
| | 213 | For example, |
| | 214 | all of the components we have defined thus far |
| | 215 | have included the export statement ``\EXP{\KWD{export} \TYP{Executable}}''. |
| | 216 | Export statements list various \emph{APIs} |
| | 217 | that a component implements. |
| | 218 | Unlike in other languages, APIs in |
| | 219 | Fortress are themselves program constructs; programmers can rely on |
| | 220 | standard APIs, and declare new ones. API declarations are sequences of |
| | 221 | declarations of |
| | 222 | variables, functions, and other program constructs, along with their |
| | 223 | types and other |
| | 224 | supporting declarations. For example, here is the definition of API |
| | 225 | \TYP{Executable}: |
| | 226 | \input{\home/preliminaries/examples/Executable.tex} |
| | 227 | |
| | 228 | This API contains the declaration of a single function \VAR{run}, |
| | 229 | whose type is \EXP{(\TYP{String}\ldots) \rightarrow ()}. This type is an |
| | 230 | \emph{arrow type}; it declares the type of a function's parameter, |
| | 231 | and its return type. The function \VAR{run} includes a single |
| | 232 | parameter; the notion \EXP{(\TYP{String}\ldots)} indicates that it is a |
| | 233 | \emph{varargs} parameter; the function \VAR{run} can be called with an |
| | 234 | arbitrary number of string arguments. For example, here are |
| | 235 | valid calls to this function: |
| | 236 | |
| | 237 | %run("a simple", " example") |
| | 238 | %run("run(...)") |
| | 239 | %run("Nobody", "expects", "that") |
| | 240 | \begin{Fortress} |
| | 241 | \(\VAR{run}(\hbox{\rm``\STR{a~simple}''},\;\hbox{\rm``\STR{~example}''})\)\\ |
| | 242 | \(\VAR{run}(\hbox{\rm``\STR{run(...)}''})\)\\ |
| | 243 | \(\VAR{run}(\hbox{\rm``\STR{Nobody}''},\;\hbox{\rm``\STR{expects}''},\;\hbox{\rm``\STR{that}''})\) |
| | 244 | \end{Fortress} |
| | 245 | |
| | 246 | |
| | 247 | The return type of \VAR{run} is \EXP{()}, pronounced ``void''. |
| | 248 | Type \EXP{()} may be used in Fortress as a return type |
| | 249 | for functions that have no meaningful return value. |
| | 250 | There is a single value with type \EXP{()}: |
| | 251 | the value \EXP{()}, also pronounced ``void''. |
| | 252 | References to value \EXP{()} as opposed |
| | 253 | to type \EXP{()} are resolved by context. |
| | 254 | |
| | 255 | As with components, APIs can be defined in files and compiled. APIs |
| | 256 | must be defined in files with the suffix \shellcommand{.fsi}. |
| | 257 | An \shellcommand{.fsi} file contains |
| | 258 | source code for exactly one API, and its name must match the file name, |
| | 259 | minus the suffix. |
| | 260 | If there are no explicit ``\KWD{api}'' |
| | 261 | headers, the file is understood to define a single API whose name is |
| | 262 | the name of the containing file (minus its suffix). |
| | 263 | |
| | 264 | An API is compiled with the shell command ``\shellcommand{fortress compile}''. |
| | 265 | When an API is compiled, |
| | 266 | it is installed in the resident fortress. |
| | 267 | |
| | 268 | |
| | 269 | For example, if we store |
| | 270 | the following API in a file named ``\shellcommand{Zeepf.fsi}'': |
| | 271 | \input{\home/preliminaries/examples/Zeepf.tex} |
| | 272 | then we can compile this API with the following shell command: |
| | 273 | |
| | 274 | \shellcommand{fortress compile Zeepf.fsi} |
| | 275 | |
| | 276 | This command compiles the API \TYP{Zeepf} |
| | 277 | and installs it in the resident fortress. |
| | 278 | %If we omit the enclosing API declaration, |
| | 279 | %so that the file \shellcommand{Zeepf.fsi} consists solely of the following code: |
| | 280 | |
| | 281 | %foo: String -> () |
| | 282 | %baz: String -> String |
| | 283 | %\begin{Fortress} |
| | 284 | %\(\VAR{foo}\COLON \TYP{String} \rightarrow ()\)\\ |
| | 285 | %\(\VAR{baz}\COLON \TYP{String} \rightarrow \TYP{String}\) |
| | 286 | %\end{Fortress} |
| | 287 | |
| | 288 | %then the file is assumed to consist of the declaration of a single API |
| | 289 | %named \TYP{Zeepf}. |
| | 290 | |
| | 291 | Unlike component compilation, API compilation does not shadow |
| | 292 | existing elements of a fortress. |
| | 293 | If we attempt to compile an API with the same name as an API |
| | 294 | already defined |
| | 295 | in the resident fortress, an error is signaled |
| | 296 | and the fortress is left unchanged. To remove an API, we must |
| | 297 | first remove all components referring to the API, |
| | 298 | and then issue the shell command ``\shellcommand{fortress removeApi}''. |
| | 299 | |
| | 300 | |
| | 301 | A component that exports an API must provide a definition |
| | 302 | for every program construct declared in the API. For example, because |
| | 303 | our component \TYP{HelloWorld}: |
| | 304 | \input{\home/preliminaries/examples/HelloWorld.tex} |
| | 305 | exports the API \TYP{Executable}, it must include a definition for the |
| | 306 | function \VAR{run}. |
| | 307 | The definition of \VAR{run} in \TYP{HelloWorld} need not include |
| | 308 | declarations of the |
| | 309 | parameter type or return type of \VAR{run}, as these can be inferred |
| | 310 | from the |
| | 311 | definition of API \TYP{Executable}. |
| | 312 | |
| | 313 | Components are also allowed to \emph{import} APIs. A component that |
| | 314 | imports an API is allowed to use any of the program constructs |
| | 315 | declared in that API. For example, the following component imports the API |
| | 316 | \TYP{Zeepf} and calls the function \VAR{foo} declared in \TYP{Zeepf}: |
| | 317 | \input{\home/preliminaries/examples/Blargh.tex} |
| | 318 | |
| | 319 | The component \TYP{Blargh} imports declaration \VAR{foo} from the API \TYP{Zeepf} |
| | 320 | and exports the API |
| | 321 | \TYP{Executable}. Its \VAR{run} function is defined by calling function |
| | 322 | \VAR{foo}, defined in \TYP{Zeepf}. |
| | 323 | In an import statement of the form: |
| | 324 | %import A.{S} |
| | 325 | \begin{Fortress} |
| | 326 | \(\KWD{import}\:A.\{S\}\) |
| | 327 | \end{Fortress} |
| | 328 | all names in the list of names \VAR{S} are imported from API $A$, and can be |
| | 329 | referred to as unqualified names within the importing component. In |
| | 330 | the example above, the names we have imported consist of a |
| | 331 | single name: \VAR{foo}. If we had instead written: |
| | 332 | \input{\home/preliminaries/examples/Blargh2.tex} |
| | 333 | then we would have been able to refer to both \VAR{foo} and \VAR{baz} |
| | 334 | as unqualified names in \TYP{Blargh}. |
| | 335 | |
| | 336 | Note that no component refers directly to another component, |
| | 337 | or to constructs defined in another component. |
| | 338 | Instead, \emph{all external references go through APIs}. |
| | 339 | This level of indirection provides us with significant power. |
| | 340 | It provides a way to hide implementation details in a component. |
| | 341 | Also, our intention is that in future implementations, |
| | 342 | it will be possible to make use of APIs to provide sophisticated |
| | 343 | link and upgrade operations for the purposes of building |
| | 344 | large programs. |
| | 345 | %Programmers will be able to link together components from separate |
| | 346 | %programming teams, swap in revised components into deployed |
| | 347 | %applications, and even test components that rely on expensive libraries |
| | 348 | %by wiring them up to special |
| | 349 | %\emph{mock components} that provide just enough functionality to allow |
| | 350 | %for testing. |
| | 351 | |
| | 352 | Components that contain no import statements and export the API |
| | 353 | \TYP{Executable} are referred to as \emph{executable components}. They |
| | 354 | can be compiled and executed directly as stand-alone components. All |
| | 355 | of our \TYP{HelloWorld} components are executable components. |
| | 356 | However, |
| | 357 | if a component imports one or more APIs, it cannot be executed as a |
| | 358 | stand-alone program. Instead, its imports are resolved to |
| | 359 | other components that export all of the APIs it imports, |
| | 360 | to form a new \emph{compound} component. For example, we define |
| | 361 | the following component in a file named \shellcommand{Ralph.fss}: |
| | 362 | \note{The example is commented out because it is not supported yet nor run by the interpreter.} |
| | 363 | %\input{\home/library/examples/Ralph.compile.tex} |
| | 364 | |
| | 365 | We can now issue the following shell commands: |
| | 366 | |
| | 367 | \shellcommand{fortress compile Ralph.fss} \\ |
| | 368 | \shellcommand{fortress compile Blargh.fss} \\ |
| | 369 | \shellcommand{fortress run Blargh.fss} \\ |
| | 370 | |
| | 371 | The first two commands compile files \shellcommand{Ralph.fss} and |
| | 372 | \shellcommand{Blargh.fss}, |
| | 373 | respectively, and install them in the resident fortress. The third |
| | 374 | command tells the resident fortress to run component \TYP{Blargh}. |
| | 375 | References to API \TYP{Zeepf} in \TYP{Blargh} are resolved to their |
| | 376 | implementation in component \TYP{Ralph}. |
| | 377 | |
| | 378 | All references to API \TYP{Zeepf} in \TYP{Gary} are resolved |
| | 379 | to the declarations provided in \TYP{Ralph}. |
| | 380 | |
| | 381 | Note that forming the compound component \TYP{Gary} has no effect on the |
| | 382 | components \TYP{Ralph} and \TYP{Blargh}. |
| | 383 | These components remain in the resident |
| | 384 | fortress, and they can be linked together with other components to |
| | 385 | form yet more compound components. |
| | 386 | Conversely, if \TYP{Blargh} or \TYP{Ralph} is |
| | 387 | recompiled, deleted, or otherwise updated, |
| | 388 | there is no effect on \TYP{Gary}. |
| | 389 | Conceptually, \TYP{Gary} contains its own copies |
| | 390 | of the components \TYP{Blargh} and \TYP{Ralph}, |
| | 391 | and these copies are not corrupted by actions on other components. |
| | 392 | For this reason, we say that components in Fortress |
| | 393 | are \emph{encapsulated}. (Of course, there are optimization tricks |
| | 394 | that a fortress can use to maintain the illusion of encapsulation |
| | 395 | without actually copying. But these tricks are beyond the scope of |
| | 396 | this specification.) |
| | 397 | |
| | 398 | Compound components are \emph{upgradable}: They can be upgraded with |
| | 399 | new components that export some of the APIs used by their |
| | 400 | constituents. For example, if a new version of \TYP{Ralph} is compiled and |
| | 401 | installed in the resident fortress, |
| | 402 | we can manually \emph{upgrade} \TYP{Gary} with |
| | 403 | the new version by performing the following shell command: |
| | 404 | |
| | 405 | \shellcommand{fortress upgrade NewGary from Gary with Ralph} |
| | 406 | |
| | 407 | This command produces a new component, named \shellcommand{NewGary}, |
| | 408 | resulting from an upgrade of \shellcommand{Gary} with \shellcommand{Ralph}. |
| | 409 | The components referred to as \shellcommand{Gary} and \shellcommand{Ralph} |
| | 410 | are unaffected. An important property of fortress components is that |
| | 411 | they are \emph{stateless}; once constructed, they are never modified. |
| | 412 | Even if a component is ``removed'' from a fortress, the components |
| | 413 | it is a constituent of are unaffected. |
| | 414 | |
| | 415 | However, we can rebind \emph{the name} \shellcommand{Gary} |
| | 416 | in the resident fortress to our new component with the following command: |
| | 417 | |
| | 418 | \shellcommand{fortress upgrade Gary from Gary with Ralph} |
| | 419 | |
| | 420 | or simply: |
| | 421 | |
| | 422 | \shellcommand{fortress upgrade Gary with Ralph} |
| | 423 | |
| | 424 | Now, the original component referred to by \shellcommand{Gary} is |
| | 425 | shadowed; it cannot be referred to directly from the shell. |
| | 426 | However, it might still exist in the fortress as a constituent of |
| | 427 | other components, which are unmodified by the upgrade. |
| | 428 | To upgrade all components in a fortress at once |
| | 429 | with a new version of \shellcommand{Ralph} (rebinding all |
| | 430 | names to the resulting upgrades), we can issue the command: |
| | 431 | |
| | 432 | \shellcommand{fortress upgradeAll Ralph} |
| | 433 | |
| | 434 | \section{Automatic Generation of APIs} |
| | 435 | \seclabel{apitool} |
| | 436 | |
| | 437 | Note that the component named \TYP{Zeepf} exports the API |
| | 438 | \TYP{Zeepf}. Components and APIs exist in separate namespaces, and therefore |
| | 439 | it is allowed for a component to have the same name as an API. |
| | 440 | In fact, if we hadn't already defined and compiled API \TYP{Zeepf}, |
| | 441 | we could generate it automatically |
| | 442 | from the definition of component \TYP{Zeepf} |
| | 443 | with the following shell command: |
| | 444 | |
| | 445 | \shellcommand{fortress api Zeepf.fss} |
| | 446 | |
| | 447 | This command generates a new source file, \shellcommand{Zeepf.fsi}, in the |
| | 448 | same directory as \shellcommand{Zeepf.fss}, which includes declarations for |
| | 449 | all program constructs defined in \shellcommand{Zeepf.fss}. |
| | 450 | |
| | 451 | In general, if a component $C$ exports an API $A$ with the same name as $C$, |
| | 452 | it is possible to automatically generate a source file |
| | 453 | for the API $A$ from $C$ |
| | 454 | by issuing the shell command \shellcommand{fortress api} on the file |
| | 455 | containing the definition of $C$. |
| | 456 | This API contains declarations for all definitions in $C$ that are not |
| | 457 | declared in other APIs exported by $C$, and that do not include |
| | 458 | the modifier \KWD{private}. |
| | 459 | If a source file with the name of $A$ already exists in the |
| | 460 | same directory as the source file of $C$, an error is signaled, |
| | 461 | and no file is created. |
| | 462 | |
| | 463 | If there is more than one component defined in a file, |
| | 464 | APIs are generated for all components defined in the file that |
| | 465 | export APIs with the same name as the respective component. |
| | 466 | Each generated API is placed in a separate source file whose |
| | 467 | name corresponds to the name of the API it defines. |
| | 468 | |
| | 469 | Note that the API corresponding to an automatically generated source |
| | 470 | file is not automatically added to the resident fortress; the source |
| | 471 | file must still be compiled via a separate action. Often, programmers |
| | 472 | may want to edit the autogenerated file before compiling it to the |
| | 473 | fortress. |
| | 474 | |
| | 475 | It is not always desirable for a component to export an API of the same name. |
| | 476 | Many components will export only publicly defined standard APIs. |
| | 477 | However, automatic generation of APIs from components may be useful, |
| | 478 | particularly for components defined internally by a development team. |
| | 479 | Large projects may contain many internally defined components that |
| | 480 | are never released externally, |
| | 481 | except as constituents of compound components. |
| | 482 | |
| | 483 | \section{Rendering} |
| | 484 | |
| | 485 | One aspect of Fortress that is quite different from many other languages |
| | 486 | is that various program constructs are rendered in particular fonts, |
| | 487 | so as to emulate mathematical notation. |
| | 488 | For example, variable names are rendered in italic fonts. |
| | 489 | Many other program constructs have their own rendering rules. For |
| | 490 | example, the operator \verb$^$ indicates superscripting in |
| | 491 | Fortress. |
| | 492 | A function definition consisting of the following ASCII characters: |
| | 493 | |
| | 494 | \begin{verbatim} |
| | 495 | f(x) = x^2 + sin x - cos 2 x |
| | 496 | \end{verbatim} |
| | 497 | |
| | 498 | is rendered as follows: |
| | 499 | |
| | 500 | \input{\home/preliminaries/examples/Overview.Rendering.a.tex} |
| | 501 | |
| | 502 | Array indexing, written with brackets: |
| | 503 | |
| | 504 | \begin{verbatim} |
| | 505 | a[i] |
| | 506 | \end{verbatim} |
| | 507 | |
| | 508 | is rendered as follows: |
| | 509 | |
| | 510 | \input{\home/preliminaries/examples/Overview.Rendering.b.tex} |
| | 511 | |
| | 512 | There are many other examples of special rendering conventions. |
| | 513 | |
| | 514 | Fortress also supports the use of Unicode characters~\cite{Unicode} in |
| | 515 | identifiers. In order to make it easy to enter such characters with |
| | 516 | today's input devices, Fortress defines a convention for keyboard |
| | 517 | entry: ASCII names (and abbreviations) of Unicode characters can be |
| | 518 | written in a program in all caps (with spaces replaced by underscores). |
| | 519 | Such identifiers are converted to Unicode characters. For example, |
| | 520 | the identifier: |
| | 521 | |
| | 522 | \begin{verbatim} |
| | 523 | GREEK_CAPITAL_LETTER_LAMBDA |
| | 524 | \end{verbatim} |
| | 525 | |
| | 526 | is automatically converted into the identifier: |
| | 527 | |
| | 528 | $\Lambda$ |
| | 529 | |
| | 530 | There are also ASCII abbreviations for writing down commonly used |
| | 531 | Fortress characters. For example, ASCII identifiers for all Greek |
| | 532 | letters are converted to Greek characters |
| | 533 | (e.g., ``\txt{lambda}'' becomes $\lambda$ |
| | 534 | and ``\txt{LAMBDA}'' becomes $\Lambda$). |
| | 535 | Here are some other common ASCII shorthands: |
| | 536 | |
| | 537 | \begin{tabular}{rclrcl} |
| | 538 | \txt{BY} & \emph{becomes} & $\times$ & |
| | 539 | \txt{TIMES} & \emph{becomes} & $\times$ \\ |
| | 540 | \txt{DOT} & \emph{becomes} & $\csdot$ & |
| | 541 | \txt{CROSS} & \emph{becomes} & $\times$ \\ |
| | 542 | \txt{CUP} & \emph{becomes} & $\cup$ & |
| | 543 | \txt{CAP} & \emph{becomes} & $\cap$ \\ |
| | 544 | \txt{BOTTOM} & \emph{becomes} & $\bot$ & |
| | 545 | \txt{TOP} & \emph{becomes} & $\top$ \\ |
| | 546 | \txt{SUM} & \emph{becomes} & $\sum$ & |
| | 547 | \txt{PROD} & \emph{becomes} & $\prod$ \\ |
| | 548 | \txt{INTEGRAL} & \emph{becomes} & $\int$ & |
| | 549 | \txt{EMPTYSET} & \emph{becomes} & $\emptyset$ \\ |
| | 550 | \txt{SUBSET} & \emph{becomes} & $\subset$ & |
| | 551 | \txt{NOTSUBSET} & \emph{becomes} & $\not\subset$ \\ |
| | 552 | \txt{SUBSETEQ} & \emph{becomes} & $\subseteq$ & |
| | 553 | \txt{NOTSUBSETEQ} & \emph{becomes} & $\not\subseteq$ \\ |
| | 554 | \txt{EQUIV} & \emph{becomes} & $\equiv$ & |
| | 555 | \txt{NOTEQUIV} & \emph{becomes} & $\not\equiv$ \\ |
| | 556 | \txt{IN} & \emph{becomes} & $\in$ & |
| | 557 | \txt{NOTIN} & \emph{becomes} & $\not\in$ \\ |
| | 558 | \txt{LT} & \emph{becomes} & $<$ & |
| | 559 | \txt{LE} & \emph{becomes} & $\leq$ \\ |
| | 560 | \txt{GT} & \emph{becomes} & $>$ & |
| | 561 | \txt{GE} & \emph{becomes} & $\geq$ \\ |
| | 562 | \txt{EQ} & \emph{becomes} & $=$ & |
| | 563 | \txt{NE} & \emph{becomes} & $\neq$ \\ |
| | 564 | \txt{AND} & \emph{becomes} & $\wedge$ & |
| | 565 | \txt{OR} & \emph{becomes} & $\vee$ \\ |
| | 566 | \txt{NOT} & \emph{becomes} & $\neg$ & |
| | 567 | \txt{XOR} & \emph{becomes} & $\oplus$ \\ |
| | 568 | \txt{INF} & \emph{becomes} & $\infty$ & |
| | 569 | \txt{SQRT} & \emph{becomes} & $\surd$ \\ |
| | 570 | \end{tabular} |
| | 571 | |
| | 572 | A comprehensive description of ASCII conversion is provided in |
| | 573 | \appref{ascii-unicode}. |
| | 574 | |
| | 575 | \section{Some Common Types in Fortress} |
| | 576 | |
| | 577 | Fortress provides a wide variety of standard types, including |
| | 578 | \TYP{String}, \TYP{Boolean}, and various numeric types. |
| | 579 | The floating-point type \EXP{\mathbb{R}64} (written in ASCII as \verb$RR64$) |
| | 580 | is the type of 64-bit precision floating-point numbers. |
| | 581 | For example, the following function takes a 64-bit |
| | 582 | float and returns a 64-bit float: |
| | 583 | \input{\home/preliminaries/examples/Overview.Types.tex} |
| | 584 | |
| | 585 | Predictably, 32-bit precision floats are written \EXP{\mathbb{R}32}. |
| | 586 | |
| | 587 | 64-bit integers are denoted by the type \EXP{\mathbb{Z}64} and |
| | 588 | 32-bit integers by the type \EXP{\mathbb{Z}32} |
| | 589 | and infinite precision integers by the type \EXP{\mathbb{Z}}. |
| | 590 | |
| | 591 | \section{Functions in Fortress} |
| | 592 | Fortress allows recursive, and mutually recursive function definitions. |
| | 593 | Here is a simple definition of a \VAR{factorial} function in Fortress: |
| | 594 | |
| | 595 | \input{\home/preliminaries/examples/Overview.Function.factorial.tex} |
| | 596 | |
| | 597 | \subsection{Juxtaposition and function application} |
| | 598 | |
| | 599 | In the definition of \VAR{factorial}, |
| | 600 | note the juxtaposition of parameter \VAR{n} with the recursive |
| | 601 | call \EXP{\VAR{factorial}(n - 1)}. |
| | 602 | In Fortress, as in mathematics, |
| | 603 | multiplication is represented through juxtaposition. |
| | 604 | By default, |
| | 605 | two expressions of numeric type that are juxtaposed |
| | 606 | represent a multiplication. |
| | 607 | On the other hand, |
| | 608 | juxtaposition of an expression of function type |
| | 609 | with another expression to its right |
| | 610 | represents function application, |
| | 611 | as in the following example: |
| | 612 | |
| | 613 | \input{\home/preliminaries/examples/Overview.Juxt.sin.tex} |
| | 614 | |
| | 615 | Moreover, juxtaposition of expressions of string type |
| | 616 | represents concatenation, as in the following example: |
| | 617 | |
| | 618 | \input{\home/preliminaries/examples/Overview.Juxt.String.tex} |
| | 619 | |
| | 620 | In fact, juxtaposition is an operator in Fortress, |
| | 621 | just like \EXP{+} and \EXP{-}, |
| | 622 | that is overloaded based on the runtime types of its arguments. |
| | 623 | |
| | 624 | There is a special case concerning juxtaposition that is important to mention: |
| | 625 | When writing a numeric literal, the \emph{digit-group separator}, |
| | 626 | \txt{NARROW NO-BREAK SPACE} (U+202F), |
| | 627 | may be included between the digits in order to improve readability. |
| | 628 | In ASCII, |
| | 629 | this character can be abbreviated in the context of a numeric literal |
| | 630 | (\emph{and only in this context}) with the character \txt{'}. |
| | 631 | For example, the number 299,792,458 can be denoted in ASCII by the |
| | 632 | following numeric literal: |
| | 633 | |
| | 634 | \begin{verbatim} |
| | 635 | 299'792'458 |
| | 636 | \end{verbatim} |
| | 637 | |
| | 638 | This literal is converted into Unicode by replacing all occurrences of |
| | 639 | \txt{'} with \txt{NARROW NO-BREAK SPACE}: |
| | 640 | %299 792 458 |
| | 641 | \begin{Fortress} |
| | 642 | \(299{}\;792{}\;458\) |
| | 643 | \end{Fortress} |
| | 644 | This is not an application of the juxtaposition operator; |
| | 645 | rather, it is a single token. |
| | 646 | Note that commas cannot be used to separate digits because ambiguities |
| | 647 | would arise with the use of commas in other expressions, |
| | 648 | such as tuples. |
| | 649 | |
| | 650 | \subsection{Keyword Parameters} |
| | 651 | |
| | 652 | Functions in Fortress can be defined to take keyword arguments by |
| | 653 | providing default values for parameters. In |
| | 654 | the following example: |
| | 655 | |
| | 656 | %makeColor(red:ZZ64 = 0, green:ZZ64 = 0, blue:ZZ64 = 0) = |
| | 657 | % if 0 <= red <= 255 AND 0 <= green <= 255 AND 0 <= blue <= 255 |
| | 658 | % then Color(red,green,blue) |
| | 659 | % else throw Error end |
| | 660 | \begin{Fortress} |
| | 661 | \(\VAR{makeColor}(\VAR{red}\COLONOP\mathbb{Z}64 = 0, \VAR{green}\COLONOP\mathbb{Z}64 = 0, \VAR{blue}\COLONOP\mathbb{Z}64 = 0) =\)\\ |
| | 662 | {\tt~~~}\pushtabs\=\+\( \KWD{if} 0 \leq \VAR{red} \leq 255 \wedge 0 \leq \VAR{green} \leq 255 \wedge 0 \leq \VAR{blue} \leq 255 \)\\ |
| | 663 | \( \KWD{then} \TYP{Color}(\VAR{red},\VAR{green},\VAR{blue})\)\\ |
| | 664 | \( \KWD{else}\;\;\KWD{throw} \TYP{Error} \KWD{end}\)\-\\\poptabs |
| | 665 | \end{Fortress} |
| | 666 | |
| | 667 | the function \VAR{makeColor} takes three keyword arguments, all of |
| | 668 | which default to \EXP{0}. If we call it as follows: |
| | 669 | |
| | 670 | %makeColor(green = 255) |
| | 671 | \begin{Fortress} |
| | 672 | \(\VAR{makeColor}(\VAR{green} = 255)\) |
| | 673 | \end{Fortress} |
| | 674 | |
| | 675 | the arguments \VAR{red} and \VAR{blue} are both given the value \EXP{0}. |
| | 676 | |
| | 677 | There are some other aspects of this example worth mentioning. |
| | 678 | For example, |
| | 679 | the body of this function consists of an \KWD{if} expression. |
| | 680 | The test of the \KWD{if} expression checks that |
| | 681 | all three parameters have values between \EXP{0} and \EXP{255}. The |
| | 682 | boolean operator \EXP{\leq} is \emph{chained}: An expression of |
| | 683 | the form \EXP{x \leq y \leq z} is equivalent to the expression |
| | 684 | \EXP{x \leq y \wedge y \leq z}, just as in mathematical notation. |
| | 685 | The \KWD{then} clause provides an example of a constructor call in Fortress, |
| | 686 | and the \KWD{else} clause shows us an example |
| | 687 | of a \KWD{throw} expression in Fortress. |
| | 688 | \note{How can we tell this from the example? |
| | 689 | Indeed, in general, we can't distinguish constructors from other functions |
| | 690 | looking only at the call sites.} |
| | 691 | |
| | 692 | \subsection{Varargs Parameters} |
| | 693 | It is also possible to define functions that take a variable number of |
| | 694 | arguments. |
| | 695 | For example: |
| | 696 | \input{\home/preliminaries/examples/Overview.Function.printFirst.tex} |
| | 697 | |
| | 698 | This function takes an arbitrary number of integers and prints the first |
| | 699 | one (unless it is given zero arguments; then it throws an exception). |
| | 700 | |
| | 701 | \subsection{Function Overloading} |
| | 702 | \seclabel{overview-function-overloading} |
| | 703 | Functions can be overloaded in Fortress |
| | 704 | by the types of their parameters. Calls to overloaded functions are |
| | 705 | resolved based on the runtime types of the arguments. For example, |
| | 706 | the following function is overloaded based on parameter type: |
| | 707 | |
| | 708 | \input{\home/preliminaries/examples/Overview.Function.size.tex} |
| | 709 | |
| | 710 | |
| | 711 | If we call \VAR{size} on an object with runtime type \TYP{Cons}, the |
| | 712 | second definition of \VAR{size} will be invoked \emph{regardless of the static type of the argument}. |
| | 713 | Of course, function applications are |
| | 714 | statically checked to ensure that \emph{some} definition will be |
| | 715 | applicable at run time, and that the definition to apply will |
| | 716 | be unambiguous. |
| | 717 | |
| | 718 | |
| | 719 | \subsection{Function Contracts} |
| | 720 | |
| | 721 | Fortress allows \emph{contracts} to be included in function declarations. |
| | 722 | Among other things, |
| | 723 | contracts allow us to \emph{require} |
| | 724 | that the argument to a function satisfies a given set of constraints, |
| | 725 | and to \emph{ensure} that the resulting value satisfies some constraints. |
| | 726 | They provide essential documentation for the clients of a function, |
| | 727 | enabling us to express semantic properties |
| | 728 | that cannot be expressed through the static type system. |
| | 729 | |
| | 730 | Contracts are placed at the end of a function header, before the function body. |
| | 731 | For example, we can place a contract on our \VAR{factorial} function requiring |
| | 732 | that its argument be nonnegative as follows: |
| | 733 | \input{\home/preliminaries/examples/Overview.Function.contract.a.tex} |
| | 734 | |
| | 735 | We can also ensure that the result of \VAR{factorial} is itself nonnegative: |
| | 736 | \input{\home/preliminaries/examples/Overview.Function.contract.b.tex} |
| | 737 | |
| | 738 | The variable \KWD{outcome} is bound in the \KWD{ensures} clause |
| | 739 | to the return value of the function. |
| | 740 | |
| | 741 | \section{Some Common Expressions in Fortress} |
| | 742 | We have already seen an \KWD{if} expression in Fortress. Here's an |
| | 743 | example of a \KWD{while} expression: |
| | 744 | |
| | 745 | \input{\home/preliminaries/examples/Overview.Expression.whileE.tex} |
| | 746 | |
| | 747 | A sequence of expressions in Fortress may be delimited by \KWD{do} and |
| | 748 | \KWD{end}. Here is an example of a function that prints three words: |
| | 749 | |
| | 750 | \input{\home/preliminaries/examples/Overview.Expression.printThreeWords.tex} |
| | 751 | |
| | 752 | A \emph{tuple} expression contains a sequence of elements delimited by |
| | 753 | parentheses and separated by commas: |
| | 754 | |
| | 755 | \input{\home/preliminaries/examples/Overview.Expression.tuple.tex} |
| | 756 | |
| | 757 | When a tuple expression is evaluated, the various subexpressions are |
| | 758 | evaluated \emph{in parallel}. For example, the following tuple |
| | 759 | expression |
| | 760 | denotes a parallel computation: |
| | 761 | |
| | 762 | \input{\home/preliminaries/examples/Overview.Expression.tuple.factorial.tex} |
| | 763 | |
| | 764 | The elements in this expression may be evaluated in parallel. |
| | 765 | This same computation can be expressed as follows: |
| | 766 | |
| | 767 | \input{\home/preliminaries/examples/Overview.Expression.alsodo.tex} |
| | 768 | |
| | 769 | \section{For Loops Are Parallel by Default} |
| | 770 | Here is an example of a simple \KWD{for} loop in Fortress: |
| | 771 | \input{\home/preliminaries/examples/Overview.Expression.forLoop.tex} |
| | 772 | This \KWD{for} loop iterates |
| | 773 | over all elements \VAR{i} between \EXP{1} and \EXP{10} |
| | 774 | and prints the value of \VAR{i}. |
| | 775 | Expressions such as \EXP{1\COLONOP{}10} |
| | 776 | are referred to as \emph{range expressions}. |
| | 777 | They can be used in any context where |
| | 778 | we wish to denote all the integers between a given pair of integers. |
| | 779 | |
| | 780 | A significant difference between Fortress |
| | 781 | and most other programming languages |
| | 782 | is that \emph{for loops are parallel by default}. |
| | 783 | Thus, printing in the various iterations |
| | 784 | of this loop can occur in an arbitrary order, such as: |
| | 785 | |
| | 786 | 5 4 6 3 7 2 9 10 1 8 |
| | 787 | |
| | 788 | \section{Atomic Expressions} |
| | 789 | |
| | 790 | In order to control interactions of parallel executions, Fortress |
| | 791 | includes the notion of \emph{atomic expressions}, as in the following |
| | 792 | example: |
| | 793 | |
| | 794 | \input{\home/preliminaries/examples/Overview.Expression.atomicE.tex} |
| | 795 | |
| | 796 | An atomic expression |
| | 797 | is executed in such a manner that all other threads observe either that |
| | 798 | the computation has completed, or that it has not yet begun; no other |
| | 799 | thread observes an atomic expression to have only partially completed. |
| | 800 | Consider the following parallel computation: |
| | 801 | \input{\home/preliminaries/examples/Overview.Expression.Also.b.tex} |
| | 802 | |
| | 803 | Both parallel blocks are atomic; thus the second parallel block either |
| | 804 | observes that both \VAR{x} and \VAR{y} have been updated, or that |
| | 805 | neither has. Thus, possible values of the outermost \KWD{do} |
| | 806 | expression are 0 and 2, but not 1. |
| | 807 | |
| | 808 | \section{Dimensions and Units} |
| | 809 | |
| | 810 | Numeric types in Fortress can be annotated with physical units and |
| | 811 | dimensions. For example, the following function declares that its |
| | 812 | parameter is a tuple represented in the units \EXP{\mathrm{kg}} and |
| | 813 | \EXP{\mathrm{m}/\mathrm{s}}, |
| | 814 | respectively: |
| | 815 | |
| | 816 | \note{I MANUALLY EDITED THIS CODE -Victor} |
| | 817 | %kineticEnergy(m:RR64 kg_, v:RR64 m_/s_):RR64 kg_ m_^2/s_^2 = (m v^2) / 2 |
| | 818 | \begin{Fortress} |
| | 819 | \(\VAR{kineticEnergy}(m\COLONOP\mathbb{R}64\mskip 4mu plus 4mu\mathrm{kg}, v\COLONOP\mathbb{R}64\mskip 4mu plus 4mu\mathrm{m}/\mathrm{s})\COLONOP\mathbb{R}64\mskip 4mu plus 4mu\mathrm{kg}\mskip 4mu plus 4mu\mathrm{m}^{2}/\mathrm{s}^{2} = (m\ v^{2}) / 2\) |
| | 820 | \end{Fortress} |
| | 821 | |
| | 822 | A value of type \EXP{\mathbb{R}64\mskip 4mu plus 4mu\mathrm{kg}} is a |
| | 823 | 64-bit float representing a measurement in kilograms. |
| | 824 | When the function \VAR{kineticEnergy} is called, two values in its tuple |
| | 825 | argument are statically checked to ensure that they are in the right units. |
| | 826 | |
| | 827 | All commonly used dimensions and units are provided in \library. |
| | 828 | Unit symbols are encoded with trailing underscores; |
| | 829 | such identifiers are rendered in roman font. |
| | 830 | For example the unit \EXP{\mathrm{m}} is represented as \verb$m_$. |
| | 831 | For each unit, both longhand and shorthand names are provided |
| | 832 | (e.g., \EXP{\mathrm{m}}, |
| | 833 | \EXP{\mathrm{meter}}, and \EXP{\mathrm{meters}}). |
| | 834 | The various names of a given unit can be used interchangeably. |
| | 835 | Also, some units (and dimensions) are defined to be synonymous |
| | 836 | with algebraic combinations of other units (and dimensions). |
| | 837 | For example, the unit \EXP{\mathrm{N}} is defined to be synonymous |
| | 838 | with the unit \EXP{\mathrm{kg}\mskip 4mu plus 4mu\mathrm{m}/\mathrm{s}^{2}} |
| | 839 | and the dimension \EXP{\mathrm{Force}} is defined to be synonymous with |
| | 840 | \EXP{\mathrm{Mass}\mskip 4mu plus 4mu\mathrm{Acceleration}}. |
| | 841 | Likewise, the dimension \EXP{\mathrm{Acceleration}} |
| | 842 | is defined to be synonymous with \EXP{\mathrm{Velocity}/\mathrm{Time}}. |
| | 843 | |
| | 844 | Measurements in the same unit can be compared, added, subtracted, |
| | 845 | multiplied and divided. |
| | 846 | Measurements in different units can be multiplied and divided. |
| | 847 | For example, we can write the following variable declaration: |
| | 848 | |
| | 849 | %v : RR m_/s_ = (3 meters_ + 4 meters_) / 5 seconds_ |
| | 850 | \begin{Fortress} |
| | 851 | \(v \mathrel{\mathtt{:}} \mathbb{R}\mskip 4mu plus 4mu\mathrm{m}/\mathrm{s} = (3\,\mathrm{meters} + 4\,\mathrm{meters}) / 5\,\mathrm{seconds}\) |
| | 852 | \end{Fortress} |
| | 853 | |
| | 854 | However, the following variable declaration is a static error: |
| | 855 | |
| | 856 | %v : RR m_/s_ = (3 meters_ + 4 seconds_) / 5 seconds_ |
| | 857 | %I CREATED THE CODE BELOW MANUALLY -Victor |
| | 858 | \begin{Fortress} |
| | 859 | \(v \mathrel{\mathtt{:}} \mathbb{R}\mskip 4mu plus 4mu\mathrm{m}/\mathrm{s} = (3\,\mathrm{meters} + 4\,\mathrm{seconds}) / 5\,\mathrm{seconds}\) |
| | 860 | \end{Fortress} |
| | 861 | |
| | 862 | In addition, the following variable declaration is a static error |
| | 863 | because the unit of the left hand side of this declaration |
| | 864 | is \EXP{\mathrm{m}/\mathrm{s}} |
| | 865 | whereas the unit of the right hand side |
| | 866 | is simply \EXP{\mathrm{m}} (or \EXP{\mathrm{meters}}): |
| | 867 | |
| | 868 | %v : RR m_/s_ = (3 meters_ + 4 meters_) / 5 |
| | 869 | \begin{Fortress} |
| | 870 | \(v \mathrel{\mathtt{:}} \mathbb{R}\mskip 4mu plus 4mu\mathrm{m}/\mathrm{s} = (3\,\mathrm{meters} + 4\,\mathrm{meters}) / 5\) |
| | 871 | \end{Fortress} |
| | 872 | |
| | 873 | It is also possible to convert a measurement in one unit to |
| | 874 | a measurement of another unit of the same dimension, |
| | 875 | as in the following example: |
| | 876 | |
| | 877 | %kineticEnergy(3.14 kg_, 32 f_/s_ in m_/s_) |
| | 878 | \begin{Fortress} |
| | 879 | \(\VAR{kineticEnergy}(3.14\,\mathrm{kg}, 32\,\mathrm{f}/\mathrm{s} \KWD{in} \mathrm{m}/\mathrm{s})\) |
| | 880 | \end{Fortress} |
| | 881 | |
| | 882 | The second argument to \EXP{\VAR{kineticEnergy} } is a measurement in |
| | 883 | feet per second, |
| | 884 | converted to meters per second. |
| | 885 | |
| | 886 | \section{Aggregate Expressions} |
| | 887 | \seclabel{overview-aggregate} |
| | 888 | As with mathematical notation, Fortress includes special syntactic support for |
| | 889 | writing down many common kinds of collections, such as arrays, matrices, vectors, maps, sets, and lists |
| | 890 | simply by enumerating all of the collection's elements. |
| | 891 | We refer to an expression formed by enumerating the elements of a |
| | 892 | collection as an \emph{aggregate expression}. |
| | 893 | The elements of an aggregate expression are computed in parallel. |
| | 894 | |
| | 895 | For example, we can define an array \VAR{a} in Fortress by explicitly writing down its elements, enclosed in brackets |
| | 896 | and separated by whitespace, as follows: |
| | 897 | |
| | 898 | \label{arrayAInf} |
| | 899 | \input{\home/preliminaries/examples/Overview.Expression.aggregate.a.tex} |
| | 900 | |
| | 901 | Two-dimensional arrays can be written down by separating rows by newlines (or by semicolons). For example, we can |
| | 902 | bind \VAR{b} to a two-dimensional array as follows: |
| | 903 | |
| | 904 | \label{arrayBInf} |
| | 905 | \input{\home/preliminaries/examples/Overview.Expression.aggregate.b.tex} |
| | 906 | |
| | 907 | There is also support for writing down arrays of dimension three and higher. We bind \VAR{c} to a three-dimensional |
| | 908 | array as follows: |
| | 909 | |
| | 910 | \label{arrayCInf} |
| | 911 | \input{\home/preliminaries/examples/Overview.Expression.aggregate.c.tex} |
| | 912 | |
| | 913 | Various slices of the array along the third dimension are separated by pairs of semicolons. |
| | 914 | (Higher dimensional arrays |
| | 915 | are also supported. When writing a four-dimensional |
| | 916 | array, slices along the fourth dimension are separating by triples of semicolons, and so on.) |
| | 917 | |
| | 918 | Vectors are written down just like one-dimensional arrays. |
| | 919 | Similarly, matrices are written down just like two-dimensional arrays. |
| | 920 | Whether an array aggregate expression evaluates to an array, a vector, or a |
| | 921 | matrix is inferred from context |
| | 922 | (e.g., the static type of a variable that such an expression is bound to). |
| | 923 | Of course, all elements of vectors and matrices must be numbers. |
| | 924 | |
| | 925 | Note that there is a syntactic conflict between the use of juxtaposition to |
| | 926 | represent elements along a row in an array and the use of juxtaposition to represent |
| | 927 | applications of the juxtaposition operator, and the use of spaces to seperate digits in a numeric literal. |
| | 928 | In order to include an application of the juxtaposition operator or a numeric literal with spaces |
| | 929 | as an outermost subexpression of an array aggregate, it is necessary to include extra parentheses. For example, |
| | 930 | the following aggregate expression represents a counterclockwise rotation matrix by an angle $\theta{}$ in $\mathbb{R}64^2$: |
| | 931 | |
| | 932 | \input{\home/preliminaries/examples/Overview.Expression.aggregate.d.tex} |
| | 933 | |
| | 934 | |
| | 935 | A set can be written down by enclosing its elements in braces and separating its elements by commas. |
| | 936 | Here we bind \VAR{s} to the set of integers \EXP{0} through \EXP{4}: |
| | 937 | |
| | 938 | \input{\home/preliminaries/examples/Overview.Expression.aggregate.s.tex} |
| | 939 | |
| | 940 | The elements of a list are enclosed in angle brackets (written in ASCII as |
| | 941 | \verb$<|$ and \verb$|>$): |
| | 942 | \input{\home/preliminaries/examples/Overview.Expression.aggregate.l.tex} |
| | 943 | |
| | 944 | The elements of a map are enclosed in curly braces, with key/value pairs |
| | 945 | joined by the arrow \EXP{\mapsto} (written in ASCII as \verb$|->$): |
| | 946 | \input{\home/basic/examples/Expr.Map.tex} |
| | 947 | |
| | 948 | \section{Comprehensions} |
| | 949 | Another way in which Fortress mimics mathematical notation is in its support for |
| | 950 | \emph{comprehensions}. Comprehensions describe the elements of a collection by |
| | 951 | providing a rule that holds for all of the collection's elements. The elements |
| | 952 | of the collection are computed in parallel by default. |
| | 953 | For example, we define a set \VAR{s} that consists of all elements of another |
| | 954 | set \VAR{t} divided by 2, as follows: |
| | 955 | \input{\home/preliminaries/examples/Overview.Expression.comprehension.s.tex} |
| | 956 | |
| | 957 | The expression to the left of the vertical bar |
| | 958 | explains that elements of \VAR{s} consist of every value \EXP{x/2} |
| | 959 | for every valid value of \VAR{x} (determined by the right hand side). |
| | 960 | The expression to the right of the vertical bar |
| | 961 | explains how the elements \VAR{x} are to be \emph{generated} |
| | 962 | (in this case, from the set \VAR{t}). |
| | 963 | The right hand side of a comprehension can consist of multiple generators. |
| | 964 | For example, the following set consists of every element |
| | 965 | resulting from the sum of an element of \VAR{s} with an element of \VAR{t}: |
| | 966 | \input{\home/preliminaries/examples/Overview.Expression.comprehension.sum.tex} |
| | 967 | |
| | 968 | The right hand side of a comprehension can also contain |
| | 969 | \emph{filtering expressions} to constrain the elements provided by other clauses. |
| | 970 | For example, we can stipulate that \VAR{v} consists of |
| | 971 | all nonnegative elements of \VAR{t} as follows: |
| | 972 | \input{\home/preliminaries/examples/Overview.Expression.comprehension.filter.tex} |
| | 973 | |
| | 974 | There is a comprehension expression for every form of aggregate expression. |
| | 975 | For example, here is a list comprehension in Fortress: |
| | 976 | \input{\home/preliminaries/examples/Overview.Expression.comprehension.l.tex} |
| | 977 | The elements of this list consist of |
| | 978 | all elements of the set \VAR{v} multiplied by \EXP{2}. |
| | 979 | |
| | 980 | In the case of an array comprehension, the expression to the left of the bar |
| | 981 | includes a tuple indexing the elements of the array. |
| | 982 | For example, the following comprehension describes a \EXP{3 \times 3} |
| | 983 | array, all of whose elements are zero. |
| | 984 | %[(x,y) = 0 | x <- {0,1,2}, y <- {0,1,2}] |
| | 985 | \begin{Fortress} |
| | 986 | \([(x,y) = 0 \mid x \leftarrow \{0,1,2\}, y \leftarrow \{0,1,2\}]\) |
| | 987 | \end{Fortress} |
| | 988 | |
| | 989 | The collection of elements \EXP{0} through \EXP{2} can also be expressed via a range expression, as follows: |
| | 990 | %[(x,y) = 0 | x <- 0:2, y <- 0:2] |
| | 991 | \begin{Fortress} |
| | 992 | \([(x,y) = 0 \mid x \leftarrow 0\COLONOP{}2, y \leftarrow 0\COLONOP{}2]\) |
| | 993 | \end{Fortress} |
| | 994 | |
| | 995 | An array comprehension can consist of multiple clauses. The clauses are run in the order provided, |
| | 996 | with declarations from later clauses shadowing declarations from earlier clauses. For example, the following |
| | 997 | comprehension describes a \EXP{3 \times 3} identity matrix: |
| | 998 | |
| | 999 | %[(x,y) = 0 | x <- 0:2, y <- 0:2 |
| | 1000 | % (x,x) = 1 | x <- 0:2] |
| | 1001 | \begin{Fortress} |
| | 1002 | \(\ [ \)\pushtabs\=\+\((x,y) = 0 \mid x \leftarrow 0\COLONOP{}2, y \leftarrow 0\COLONOP{}2\)\\ |
| | 1003 | \( (x,x) = 1 \mid x \leftarrow 0\COLONOP{}2]\)\-\\\poptabs |
| | 1004 | \end{Fortress} |
| | 1005 | |
| | 1006 | |
| | 1007 | |
| | 1008 | \section{Summations and Products} |
| | 1009 | As with mathematical notation, Fortress provides syntactic support for |
| | 1010 | summations and productions (and other big operations) over the elements of a collection. |
| | 1011 | For example, an alternative definition of \VAR{factorial} is as follows: |
| | 1012 | |
| | 1013 | \input{\home/preliminaries/examples/Overview.Expression.big.tex} |
| | 1014 | |
| | 1015 | This function definition can be written in ASCII as follows: |
| | 1016 | |
| | 1017 | \begin{verbatim} |
| | 1018 | factorial(n) = PROD[i <- 1:n] i |
| | 1019 | \end{verbatim} |
| | 1020 | |
| | 1021 | The character \EXP{\prod} is written \txt{PROD}. Likewise, |
| | 1022 | \EXP{\sum} is written \txt{SUM}. |
| | 1023 | As with comprehensions, the values in the iteration are generated from specified collections. |
| | 1024 | |
| | 1025 | \label{overviewTest} |
| | 1026 | \section{Tests and Properties} |
| | 1027 | Fortress includes support for automated program testing. |
| | 1028 | A new test in a component can be defined using the \KWD{test} modifier |
| | 1029 | on a top-level function definition with type ``\EXP{()\rightarrow()}''. |
| | 1030 | For example, here is a test function that calls to the \VAR{factorial} |
| | 1031 | function on some representative values |
| | 1032 | result in values greater than or equal to what was provided: |
| | 1033 | \input{\home/preliminaries/examples/Overview.Tests.tex} |
| | 1034 | |
| | 1035 | %test factorialResultLarger [x <- 0:100] = x <= factorial(x) |
| | 1036 | \begin{Fortress} |
| | 1037 | \(\KWD{test} \VAR{factorialResultLarger} [x \leftarrow 0\COLONOP{}100] = x \leq \VAR{factorial}(x)\) |
| | 1038 | \end{Fortress} |
| | 1039 | |
| | 1040 | The values for \VAR{x} are generated from the provided range |
| | 1041 | \EXP{0\COLONOP{}100}. |
| | 1042 | |
| | 1043 | Programs are also allowed to include \emph{property} declarations, documenting boolean conditions that a program is |
| | 1044 | expected to obey. Property declarations are similar syntactically to test declarations. Unlike test declarations, |
| | 1045 | property declarations do not specify explicit finite collections over which the property is expected to hold. |
| | 1046 | Instead, the parameters in a property declaration are declared to have types, and the property is expected to hold |
| | 1047 | over all values of those types. For example, here is a property declaring that \VAR{factorial} is greater than or equal |
| | 1048 | to every argument of type \EXP{\mathbb{Z}}: |
| | 1049 | |
| | 1050 | %property factorialResultAlwaysLarger = FORALL (x : ZZ) (x <= factorial(x)) |
| | 1051 | \begin{Fortress} |
| | 1052 | \(\KWD{property} \VAR{factorialResultAlwaysLarger} = \forall (x \mathrel{\mathtt{:}} \mathbb{Z})\; (x \leq \VAR{factorial}(x))\) |
| | 1053 | \end{Fortress} |
| | 1054 | |
| | 1055 | When a property declaration includes a name, the property identifier is bound to a function whose parameter and body are that of the property, |
| | 1056 | and whose return type is \TYP{Boolean}. |
| | 1057 | A function bound in this manner is referred to as a \emph{property function}. |
| | 1058 | A property function can be called from within tests to ensure that a |
| | 1059 | property holds at least for all values in some finite set of values. |
| | 1060 | |
| | 1061 | \section{Objects and Traits} |
| | 1062 | \seclabel{overview-objects-traits} |
| | 1063 | |
| | 1064 | A great deal of programming can be done simply through the use of |
| | 1065 | functions, top-level |
| | 1066 | variables, and standard types. However, Fortress also includes a trait and object system for |
| | 1067 | defining new types, as well as objects that belong to them. Traits in Fortress exist in |
| | 1068 | a multiple inheritance hierarchy rooted at trait \TYP{Object}. |
| | 1069 | A trait declaration includes a set of method declarations, |
| | 1070 | some of which may be abstract. |
| | 1071 | For example, here is a declaration of a simple trait named \TYP{Moving}: |
| | 1072 | |
| | 1073 | \label{movingDim} |
| | 1074 | \input{\home/preliminaries/examples/Overview.Moving.tex} |
| | 1075 | |
| | 1076 | The set of traits extended by trait \TYP{Moving} are listed in braces after |
| | 1077 | \KWD{extends}. Trait \TYP{Moving} inherits all |
| | 1078 | methods declared by each trait it extends. |
| | 1079 | The two methods \VAR{position} and \VAR{velocity} declared in trait \TYP{Moving} |
| | 1080 | are \emph{abstract}; they contain no body. |
| | 1081 | Their return types are vectors of length 3, whose elements are |
| | 1082 | of type \EXP{\mathbb{R}}. |
| | 1083 | As in mathematical notation, |
| | 1084 | a vector of length $n$ with element type $T$ is written |
| | 1085 | \EXP{T^{n}}. |
| | 1086 | |
| | 1087 | Traits can also declare concrete methods, |
| | 1088 | as in the following example: |
| | 1089 | |
| | 1090 | \label{fastDim} |
| | 1091 | \input{\home/preliminaries/examples/Overview.Fast.tex} |
| | 1092 | |
| | 1093 | Trait \TYP{Fast} extends a single trait, \TYP{Moving}. (Because it extends |
| | 1094 | only one trait, we can elide the braces in its \KWD{extends} clause.) |
| | 1095 | It inherits both abstract methods defined in \TYP{Moving}, and it provides |
| | 1096 | a concrete body for method \VAR{velocity}. |
| | 1097 | |
| | 1098 | Trait declarations can be extended by other trait declarations, |
| | 1099 | as well as by \emph{object declarations}. |
| | 1100 | There are two kinds of object declarations: |
| | 1101 | \emph{singleton declarations} and |
| | 1102 | \emph{constructor declarations}. |
| | 1103 | |
| | 1104 | A singleton declaration declares a sole, stand-alone, \emph{singleton object}. |
| | 1105 | For example: |
| | 1106 | \input{\home/preliminaries/examples/Overview.Sol.tex} |
| | 1107 | |
| | 1108 | The object \TYP{Sol} extends two traits: \TYP{Moving} and \TYP{Stellar}, |
| | 1109 | and provides definitions for the abstract methods it inherits. Objects must |
| | 1110 | provide concrete definitions for all abstract methods they inherit. \TYP{Sol} |
| | 1111 | also defines a field \VAR{spectralClass}. |
| | 1112 | For every field included in an object |
| | 1113 | definition, an implicit getter is defined for that field. Calls to |
| | 1114 | the getter of the field of an object consist of an expression |
| | 1115 | denoting the object |
| | 1116 | followed by a dot and the name of the field. For example, here is a call to the |
| | 1117 | getter \VAR{spectralClass} of object \TYP{Sol}: |
| | 1118 | |
| | 1119 | |
| | 1120 | |
| | 1121 | %Sol.spectralClass |
| | 1122 | \begin{Fortress} |
| | 1123 | \(\TYP{Sol}.\VAR{spectralClass}\) |
| | 1124 | \end{Fortress} |
| | 1125 | |
| | 1126 | If a field includes modifier \KWD{settable}, |
| | 1127 | an implicit setter is defined for the |
| | 1128 | field. Calls to setters look like assignments. |
| | 1129 | Here is an assignment to field \VAR{spectralClass} |
| | 1130 | of object \TYP{Sol}: |
| | 1131 | |
| | 1132 | %Sol.spectralClass := G3 |
| | 1133 | \begin{Fortress} |
| | 1134 | \(\TYP{Sol}.\VAR{spectralClass} \ASSIGN G_{3}\) |
| | 1135 | \end{Fortress} |
| | 1136 | |
| | 1137 | In fact, |
| | 1138 | all accesses to a field from outside the object to which the field belongs |
| | 1139 | must go through the getter of the field, and all assignments to it must go |
| | 1140 | through the setter. (There is simply no other way |
| | 1141 | syntactically to refer to the field.) |
| | 1142 | |
| | 1143 | If a field includes modifier \KWD{hidden}, no implicit getter is defined for the object. |
| | 1144 | |
| | 1145 | |
| | 1146 | The self parameter of a method can be given a position other than the default |
| | 1147 | position. For example, here is a definition of a type where the |
| | 1148 | self parameters appear in nonstandard positions: |
| | 1149 | |
| | 1150 | \input{\home/preliminaries/examples/Overview.List.tex} |
| | 1151 | |
| | 1152 | In both methods \VAR{cons} and \VAR{append}, the self parameter occurs as the second parameter. |
| | 1153 | Calls to these methods look more like function calls than method calls. For example, in the following |
| | 1154 | call to \VAR{append}, the receiver of the call is \EXP{l_{2}}: |
| | 1155 | |
| | 1156 | \input{\home/preliminaries/examples/Overview.append.tex} |
| | 1157 | |
| | 1158 | |
| | 1159 | A constructor declaration declares an \emph{object constructor}. |
| | 1160 | In contrast to singleton declarations, a constructor declaration includes |
| | 1161 | value parameters in its header, as in the following example: |
| | 1162 | \label{particleDim} |
| | 1163 | \input{\home/preliminaries/examples/Overview.Particle.tex} |
| | 1164 | |
| | 1165 | Every call to the constructor of \TYP{Particle} yields a new object. |
| | 1166 | For example: |
| | 1167 | \input{\home/preliminaries/examples/Overview.p1.tex} |
| | 1168 | |
| | 1169 | The parameters to an object constructor implicitly define |
| | 1170 | fields of the object, along with their getters (by default). These parameters |
| | 1171 | can include all of the modifiers that an ordinary field can. For example, |
| | 1172 | a parameter can include the modifier \KWD{hidden}, in which case a getter |
| | 1173 | is not implicitly defined for the field. |
| | 1174 | |
| | 1175 | In the definition of \TYP{Particle}, it is the implicitly defined getters of |
| | 1176 | fields \VAR{position} and \VAR{velocity} that provide concrete definitions |
| | 1177 | for the inherited abstract methods from trait \TYP{Moving}. |
| | 1178 | |
| | 1179 | In both singleton and constructor declarations, |
| | 1180 | implicitly defined getters and setters can be overridden by defining |
| | 1181 | explicit getters and setters, |
| | 1182 | using the modifiers \KWD{getter} and \KWD{setter}. For example, |
| | 1183 | we alter the definition |
| | 1184 | of \TYP{Particle} to include an explicit |
| | 1185 | getter for field \VAR{velocity} as follows: |
| | 1186 | |
| | 1187 | %object Particle(position : (RR Length)^3, |
| | 1188 | % velocity : (RR Velocity)^3) |
| | 1189 | % extends Moving |
| | 1190 | % getter velocity() = do |
| | 1191 | % print "velocity getter accessed" |
| | 1192 | % velocity |
| | 1193 | % end |
| | 1194 | %end |
| | 1195 | \begin{Fortress} |
| | 1196 | \(\KWD{object} \TYP{Particle}(\null\)\pushtabs\=\+\(\VAR{position} \mathrel{\mathtt{:}} (\mathbb{R}\mskip 4mu plus 4mu\TYP{Length})^{3},\)\\ |
| | 1197 | \( \VAR{velocity} \mathrel{\mathtt{:}} (\mathbb{R}\mskip 4mu plus 4mu\TYP{Velocity})^{3})\)\-\\\poptabs |
| | 1198 | {\tt~~}\pushtabs\=\+\( \KWD{extends} \TYP{Moving}\)\\ |
| | 1199 | \( \KWD{getter} \VAR{velocity}() = \;\KWD{do}\)\\ |
| | 1200 | {\tt~~}\pushtabs\=\+\( \VAR{print}\;\hbox{\rm``\STR{velocity~getter~accessed}''}\)\\ |
| | 1201 | \( \VAR{velocity}\)\-\\\poptabs |
| | 1202 | \( \KWD{end}\)\-\\\poptabs |
| | 1203 | \(\KWD{end}\) |
| | 1204 | \end{Fortress} |
| | 1205 | |
| | 1206 | The explicitly defined getter first prints a message and then returns |
| | 1207 | the value of the |
| | 1208 | field \VAR{velocity}. \emph{Note that the final variable reference in this getter refers |
| | 1209 | directly to the field \VAR{velocity}, not to the getter.} Only within an object definition |
| | 1210 | can fields be accessed directly. In fact, even in an object definition, fields are only |
| | 1211 | accessed directly when they are referred to as simple variables. In the following definition |
| | 1212 | of \TYP{Particle}, the getter \VAR{velocity} is recursively accessed through the special variable |
| | 1213 | \KWD{self} (bound to the receiver of the method call): |
| | 1214 | |
| | 1215 | %object Particle(position : (RR Length)^3, |
| | 1216 | % velocity : (RR Velocity)^3) |
| | 1217 | % extends Moving |
| | 1218 | % getter velocity() = do |
| | 1219 | % print "velocity getter accessed" |
| | 1220 | % self.velocity |
| | 1221 | % end |
| | 1222 | %end |
| | 1223 | \begin{Fortress} |
| | 1224 | \(\KWD{object} \TYP{Particle}(\null\)\pushtabs\=\+\(\VAR{position} \mathrel{\mathtt{:}} (\mathbb{R}\mskip 4mu plus 4mu\TYP{Length})^{3},\)\\ |
| | 1225 | \( \VAR{velocity} \mathrel{\mathtt{:}} (\mathbb{R}\mskip 4mu plus 4mu\TYP{Velocity})^{3})\)\-\\\poptabs |
| | 1226 | {\tt~~}\pushtabs\=\+\( \KWD{extends} \TYP{Moving}\)\\ |
| | 1227 | \( \KWD{getter} \VAR{velocity}() = \;\KWD{do}\)\\ |
| | 1228 | {\tt~~}\pushtabs\=\+\( \VAR{print}\;\hbox{\rm``\STR{velocity~getter~accessed}''}\)\\ |
| | 1229 | \( \mathord{\KWD{self}}.\VAR{velocity}\)\-\\\poptabs |
| | 1230 | \( \KWD{end}\)\-\\\poptabs |
| | 1231 | \(\KWD{end}\) |
| | 1232 | \end{Fortress} |
| | 1233 | |
| | 1234 | Now, the result of a call to getter \VAR{velocity} is an infinite loop (along with a lot of output). |
| | 1235 | |
| | 1236 | \subsection{Traits, Getters, and Setters} |
| | 1237 | Although traits do not include field declarations, they can include getter and setter declarations, as in the following |
| | 1238 | alternative definition of trait \TYP{Moving}: |
| | 1239 | |
| | 1240 | %trait Moving extends { Tangible, Object } |
| | 1241 | % getter position(): (RR Length)^3 |
| | 1242 | % getter velocity(): (RR Velocity)^3 |
| | 1243 | %end |
| | 1244 | \begin{Fortress} |
| | 1245 | \(\KWD{trait} \TYP{Moving} \KWD{extends} \{\,\TYP{Tangible}, \TYP{Object}\,\}\)\\ |
| | 1246 | {\tt~~}\pushtabs\=\+\( \KWD{getter} \VAR{position}()\COLON (\mathbb{R}\mskip 4mu plus 4mu\TYP{Length})^{3}\)\\ |
| | 1247 | \( \KWD{getter} \VAR{velocity}()\COLON (\mathbb{R}\mskip 4mu plus 4mu\TYP{Velocity})^{3}\)\-\\\poptabs |
| | 1248 | \(\KWD{end}\) |
| | 1249 | \end{Fortress} |
| | 1250 | |
| | 1251 | Now, an object extending trait \TYP{Moving} must provide the definitions of |
| | 1252 | \emph{getters} (as opposed to ordinary methods) |
| | 1253 | for \VAR{position} and \VAR{velocity}. |
| | 1254 | The advantage of this definition is that we can use getter |
| | 1255 | notation on a variable of static type \TYP{Moving}: |
| | 1256 | |
| | 1257 | % v : Moving = ... |
| | 1258 | % v.position |
| | 1259 | \begin{Fortress} |
| | 1260 | {\tt~}\pushtabs\=\+\( v \mathrel{\mathtt{:}} \TYP{Moving} = \ldots\)\\ |
| | 1261 | \( v.\VAR{position}\)\-\\\poptabs |
| | 1262 | \end{Fortress} |
| | 1263 | |
| | 1264 | In fact, getters can be declared in a trait definition using field declaration syntax, as in the following example |
| | 1265 | (which is equivalent to the definition of \TYP{Moving} above): |
| | 1266 | |
| | 1267 | %trait Moving extends { Tangible, Object } |
| | 1268 | % position: (RR Length)^3 |
| | 1269 | % velocity: (RR Velocity)^3 |
| | 1270 | %end |
| | 1271 | \begin{Fortress} |
| | 1272 | \(\KWD{trait} \TYP{Moving} \KWD{extends} \{\,\TYP{Tangible}, \TYP{Object}\,\}\)\\ |
| | 1273 | {\tt~~}\pushtabs\=\+\( \VAR{position}\COLON (\mathbb{R}\mskip 4mu plus 4mu\TYP{Length})^{3}\)\\ |
| | 1274 | \( \VAR{velocity}\COLON (\mathbb{R}\mskip 4mu plus 4mu\TYP{Velocity})^{3}\)\-\\\poptabs |
| | 1275 | \(\KWD{end}\) |
| | 1276 | \end{Fortress} |
| | 1277 | |
| | 1278 | Getter declarations in trait definitions must not include bodies. |
| | 1279 | A getter declaration can include the various modifiers |
| | 1280 | allowed on a field declaration, with similar results. |
| | 1281 | For example, if the modifier \KWD{settable} is used, then a |
| | 1282 | setter is implicitly declared, in addition to a getter. |
| | 1283 | |
| | 1284 | \section{Features for Library Development} |
| | 1285 | The language features introduced above are sufficient for the vast majority of applications programming. However, Fortress |
| | 1286 | has also designed to be a good language for \emph{library} programming. In fact, much of the Fortress language as viewed |
| | 1287 | by applications programmers actually consists of code defined in libraries, written in a small core language. By defining as |
| | 1288 | much of the language as possible in libraries, our aim is to allow the language to evolve gracefully as new demands are placed on it. |
| | 1289 | In this section, we briefly mention some of the features that make Fortress a good language for library development. |
| | 1290 | |
| | 1291 | \subsection{Generic Types and Static Parameters} |
| | 1292 | As in other languages, Fortress allows types to be parametric with respect to other types, as well as other ``static'' parameters, |
| | 1293 | including integers, booleans, dimensions, units, and operators. |
| | 1294 | Fortress provides some standard parametric types, |
| | 1295 | such as \TYP{Array} and \TYP{Vector}. |
| | 1296 | Programmers can also define new traits, objects, and functions that include static parameters. |
| | 1297 | |
| | 1298 | \subsection{Specification of Locality and Data Distribution} |
| | 1299 | Fortress includes a facility for expressing programmer intent concerning the distribution of large data structures |
| | 1300 | at run time. This intent is expressed through special data structures called \emph{distributions}. |
| | 1301 | In fact, all arrays and matrices include distributions. These distributions |
| | 1302 | are defined in \library. |
| | 1303 | In most cases, the default distributions |
| | 1304 | will provide programmers with good performance over a variety of machines. However, in some circumstances, |
| | 1305 | performance can be improved by overriding the default selection of distributions. |
| | 1306 | Moreover, some programmers might wish to define new distributions, tailored for particular |
| | 1307 | platforms and programs. |
| | 1308 | |
| | 1309 | \subsection{Operator Overloading} |
| | 1310 | Operators in Fortress can be overloaded with new definitions. |
| | 1311 | Here is an alternative definition of the \VAR{factorial} function, defined as a postfix operator: |
| | 1312 | |
| | 1313 | \input{\home/preliminaries/examples/Overview.factorial.tex} |
| | 1314 | |
| | 1315 | As with mathematical notation, Fortress allows operators to be defined as prefix, postfix, |
| | 1316 | and infix. More exotic operators can even be defined as subscripting (i.e., applications of the |
| | 1317 | operators look like subscripts), and as bracketing (i.e., applications of the operators |
| | 1318 | look like the operands have been simply enclosed in brackets). |
| | 1319 | |
| | 1320 | \subsection{Definition of New Syntax} |
| | 1321 | Fortress provides a facility for the definition of new syntax in libraries. |
| | 1322 | This facility is useful for defining libraries for domain-specific languages, |
| | 1323 | such |
| | 1324 | as SQL, XML, etc. |
| | 1325 | It is also used to encode some of |
| | 1326 | the language constructs seen by applications |
| | 1327 | programmers. |