Errata for the Fortress Language Specification

This article lists errata in the Fortress Language Specification, Version 1.0 Beta as well as discrepancies between the specification and the current implementation. This page is not definitive; if you find errors or discrepancies, please add them here. See also Project Status for details on what is and is not yet implemented.

1.1 Fortress in a Nutshell

In the sample program, the set expression syntax is not implicitly imported. In order to use the following:

  planets = { Mercury, Venus, Earth, Mars, Jupiter, Saturn, Uranus, Neptune }

the Set library must be explicitly imported.

 import Set.{...}

statement is added. See 2.11 Aggregate Expressions below.

2.1 The Fortress Programming Environment

The fortress command script (Fortress/bin/fortress) does not implement the script, compile, api, run, or other commands as described in section 2.1 Overview. Instead, this command compiles and runs the .fss file named on the command line. The HelloWorld.fsx program in this section is compiled and run with

 fortress HelloWorld.fsx

and not with

 fortress script HelloWorld.fsx # <<-- this is not implemented

The fss fortress shell command (Fortress/bin/fss) exists for executing these commands, but in the current implementation, using the fortress shell fss yields errors.

2.2 Exports, Imports, and Linking Components

api is not implemented in this release.

Since the fortress and fss commands are still incomplete, the remainder of this section (i.e. use of fortress compile, fortress link, and fortress run commands.) to build and operate within a fortress does not yet work.

2.11 Aggregate Expressions

The special syntax for list and set aggregate expressions is not implicitly imported.

In order to use list aggregate literals, such as

 l = <|0,1,2,3,4|>

you must first explicitly import a List implementation:

 import ArrayList.{...}

or

 import PureList.{...}

To use set aggregates, import from Set:

 import Set.{...}
 export Executable
 run(args:String...) :() = do
   mySet = {0,1,2,3,4}
   println mySet
   end

Map aggregates do not work yet (#29). The following program

 import Map.{...}
 export Executable
 run(args:String...) :() = do
   myMap = {'a' |-> 0, 'b' |-> 1}
   end

yields the error com.sun.fortress.interpreter.evaluator.Evaluator.forMapExpr not implemented

Library APIs may be used in the interim to construct maps. See the examples in the ProjectFortress/test_library directory.

10.3 Value Objects

In the example,

 value object Complex(settable real : Double, settable imaginary : Double = 0)
   opr +(self, other :Complex) = Complex(real + other.real , imaginary + other.imaginary)
 end

Double should be the real type, RR

 value object Complex(settable real : RR, settable imaginary : RR = 0)
   opr +(self, other :Complex) = Complex(real + other.real , imaginary + other.imaginary)
 end

12.2 Function Applications

The use of ... in function applications (as opposed to function declarations) on p. 94, as in

 f(1, [2 3]...) returns <|1, <|2, 3|>, 0|> 
 f(1, 2, 3, [4 5]...) returns <|1, <|2, 3, 4, 5|>, 0|> 
 f(1, 2, 3, 17 # 3...) returns <|1, <|2, 3, 17, 18, 19|>, 0|>

is defined in 13.27.5 Tuple Expressions on p. 120.

13.7 Function Expressions

In the example,

  fn (x : Double) => if x < 0 then -x else x end

Double should be the real type, RR

  fn (x : RR) => if x < 0 then -x else x end

13.10 Assignment

Note that Matrix Unpasting (6.5) is another form of assignment statement.

In the example on p. 104

 (a[i], b.x, c)UPD= f(t, u, v)

there is no UPD operator; this is a hypothetical example. For the + and AND operators, this would appear as

 (a[i], b.x, c) += f(t, u, v)
 (a[i], b.x, c) AND= f(t, u, v)

13.14 Generators

For an array a, the a.indices() operator generates indices. a.bounds() yields a Range of the array bounds. See details at Array Indices and additional information about generators at Define a Generator.

15 Overloading and Multiple Dispatch

The statement "there exists a unique most specific declaration for every call" in the second paragraph is referring to run time overload resolution. It assumes the static overload resolution performed at compile time did not find an ambiguity. An example of such a static error is the call to m below:

  export Executable

  trait MyType
    m(self, b : YourType)
  end

  object YourType 
    m(a : MyType, self) = ()
  end

  run(args:String...) :() = do

    a : MyType = YourType
    b : YourType = YourType

    m(a,b) (* This call is ambiguous *)

    end