[Swift-commit] r6372 - trunk/docs/merged/refmanual

ketan at ci.uchicago.edu ketan at ci.uchicago.edu
Mon Mar 11 17:14:26 CDT 2013


Author: ketan
Date: 2013-03-11 17:14:25 -0500 (Mon, 11 Mar 2013)
New Revision: 6372

Added:
   trunk/docs/merged/refmanual/swiftlang
Log:
Swift language reference manual draft

Added: trunk/docs/merged/refmanual/swiftlang
===================================================================
--- trunk/docs/merged/refmanual/swiftlang	                        (rev 0)
+++ trunk/docs/merged/refmanual/swiftlang	2013-03-11 22:14:25 UTC (rev 6372)
@@ -0,0 +1,842 @@
+
+////
+Swift Language Reference Manual, asciidoc format
+////
+
+:toc:
+:numbered:
+
+////
+Settings:
+////
+:miscellaneous.newline: \n
+
+= Swift Language Referance Manual
+This reference manual semi-formally outlines the Swift language conventions
+
+== Support
+
+An overview of Swift may be found at:
+
+http://www.ci.uchicago.edu/swift/guides/trunk/userguide/userguide.html
+
+The Swift user discussion mailing list is found here:
+
+https://lists.ci.uchicago.edu/cgi-bin/mailman/listinfo/swift-user
+
+== Usage
+
+Swift code is conventionally written in +\*.swift+ files.
+After writing the Swift program
++program.swift+, run:
+
+----
+swift -sites.file sites.xml -config cf -tc.file tc program.swift
+----
+
+Swift accepts many commandline arguments. Following are the most frequently used:
+
++-config <cf>+:: The config file
+
+== Program Structure
+
+Swift programs are composed of declaration of and calls to _composite_
+functions.  These share syntax with C-like languages.  The following is a
+complete Swift program:
+
+----
+tracef("%s: %i\n", "The answer is", 42);
+----
+
+== Comments
+
+Swift supports C/C++ comments:
+
+----
+# This is a comment
+// This is a comment
+/* This is a
+comment */
+/** Also a
+comment */
+----
+
+== Dataflow Evaluation
+
+Swift expressions are evaluated in _dataflow_ order:
+
+----
+int z1,z2;
+int y;
+int x = f(y);
+y = g(2);
+z1 = h(x,y,1);
+z2 = h(x,y,2);
+int output = r(z1,z2);
+----
+
+This allows code to execute as concurrently as possible, limited
+only by data availability.  In this example, +g()+ runs first, because it
+is dependent only on a literal.  When +y+ is set, +f()+ runs, setting
++x+.  Then, two invocations of +h()+ execute.  Finally, +z1+ and +z2+
+are set, allowing +r()+ to run.
+
+Variables may be assigned only once. Multiple assignment is typically
+detected at compile time, although in some cases it will result in a
+run time error. Unassigned variables that are inputs to functions
+will lead to a stall in progress.
+
+== App functions
+
+Swift code is written in composite functions.
+
+Composite functions have the form:
+
+----
+[(<output list>)] app function_name [(<input list>)]
+{
+  statement;
+}
+----
+
+An empty input or output list may be omitted or written as +()+.
+
+The output list may have more than one entry.  Thus, assignments
+may be written as:
+----
+x1, x2 = f(i1, i2);
+// or equivalently:
+(x1, x2) = f(i1, i2);
+----
+
+== Types
+
+Swift provides a similar range of primitive types to many other
+programming languages. Files are a primitive type in Swift, unlike
+in many other languages, and have a number of special characteristics
+that merit special mention.
+Two basic kinds of data structure are provided: arrays and structs.
+
+=== Primitive Types
+
+Swift has the conventional types:
+
++string+:: A complete string (not an array of characters).
++int+:: A 64-bit integer.
++float+:: A 64-bit (double-precision) floating point number.
++boolean+:: A boolean (true/false).
++file+:: A file (see Section Files).
+
+Literals for these types use conventional syntax:
+
+* +int+ literals are written as decimal numbers, e.g. +-1234+
+* +float+ literals are written as decimal numbers with a decimal point,
+    e.g +5493.352+ or +1.0+.
+    The literals +NaN+ and +inf+ may be used.  In some contexts +int+
+    literals are promoted automatically to +float+.
+* +boolean+ literals
+* +string+ literals are enclosed in double quotes, with a range of escape
+    sequences supported:
+** \\ for a single backslash
+** \" for a quote
+** \n for newline
+** \t for tab
+** \a
+** \b
+** \f
+** \r
+** \v
+** hexadecimal escape codes, e.g. \xf2
+
+
+The literals +true+ and +false+ may be used for boolean.
+
+----
+int four = 2+2;
+string s = "hello ";
+string hw = s + "world";
+----
+
+=== Files
+
+A file is a first-class entity in Swift that in many ways can be treated
+as any other variable.  The main difference is that a file can be
+*mapped* to path in a filesystem.  Assigning to a mapped file variable
+results in a file being created in the file system at the specified path.
+File variables can also be initialized with data from a pre-existing
+file using the +input_file+ function. File paths are relative to the
+working directory for Turbine.
+
+For example, if +/home/user/in.txt+ is a file with some data in it,
+the following Swift program will copy the file to +/home/user/out.txt+.
+----
+  type file;
+  
+  app (file o) cp_app(file i){
+      cp @i @o;
+  }
+
+  file x <"/home/user/in.txt">;
+  file y <"/home/user/out.txt">;
+
+  y = cp_app(x); 
+
+
+=== Arrays
+
+Arrays are declared with empty square brackets:
+
+----
+int A[];
+----
+
+Arrays are indexed using square brackets.
+
+Each array index can only be assigned to once.
+
+Arrays may be used as inputs or outputs of functions.
+
+Arrays are part of Swift dataflow semantics. An array is closed
+when all possible insertions to it are complete.
+
+----
+int A[];
+
+foreach i in [1:10] {
+  A[i] = i;
+  tracef("Element %i is %i\n", i, A[i]);
+}
+----
+
+Array literals may be expressed with list syntax:
+----
+int C[] = [4,5,6];
+----
+
+=== Structs
+
+In Swift, structs are defined with the +type+ keyword.  They define
+a new type.
+
+----
+type person
+{
+  string name;
+  int age;
+  int events[];
+}
+----
+
+Structs are accessed with the +.+ syntax:
+
+----
+person p;
+p.name = "Abe";
+p.age = 90;
+----
+
+=== Defining new types
+
+New types can be defined with +type+, which creates a new type that is a
+specialization of an existing type.  That is, it is a distinct type that is not
+interchangeable.  
+
+----
+type messagefile;
+----
+
+== Control structures
+
+Swift provides control structures that may be placed as statements
+inside a composite function.
+
+=== Conditionals
+
+==== If statement
+
+If statements have the form:
+
+----
+if (<condition>)
+{
+  statement;
+  ...
+}
+else
+{
+  statement;
+  ...
+}
+----
+
+As required by dataflow processing, progress blocks on the availability
+of the condition value.
+
+==== Switch statement
+
+----
+int a = 20;
+switch (a)
+{
+  case 1:
+    int c;
+    c = a + a;
+    b = a + 1;
+  case 20:
+    b = 1;
+  case 2000:
+    b = 2;
+  default:
+    b = 2102 + 2420;
+}
+tracef("b: %i\n", b);
+----
+
+=== Iteration
+
+Iteration is performed with the +foreach+ and +iterate+ statement.
+
+==== Foreach loop
+
+The +foreach+ loop allows for parallel iteration over an array:
+
+----
+string A[];
+foreach value, index in A
+{
+  tracef("A[%i] = %s\n", index, value);
+}
+----
+
+The +index+ and +value+ variables are automatically declared.  The
++index+ variable may be omitted from the syntax.
+
+A special case of the foreach loop occurs when combined with the
+array range operator. This is the idiomatic way to iterate over
+a range of integer values in Swift. The Swift compiler has special
+handling for this case that avoids constructing an array.
+
+----
+foreach i in [start:stop:step] {
+    ...
+}
+----
+
+==== Iterate loop
+
+The +iterate+ loop allows for sequential iteration.
+
+----
+iterate months {
+  tracef("%i\n", months);
+ } until (months==12);
+----
+
+The general form is:
+----
+iterate var
+{
+  statement;
+  ...
+} until (expression);
+----
+
+*Performance Tip:* use the +foreach+ loop instead of +iterate+ if your
+loop iterations are independent and can be executed in parallel.
+
+== Operators
+
+The following binary arithmetic operators on numbers are defined:
+
++++ (plus), +-+ (minus), +\*+ (times), +/+ (divide),
++%/+ (integer divide), +%%+ (modulus), +**+ (power)
+
++&&+ (boolean and), +||+ (boolean or),
++==+ (equals), +!=+ (not equals), +>+ (greater than), +<+ (less than),
++>=+ (greater than or equal to), +<=+ (less than or equal to)
+
+The following unary operators are defined:
+
++-+ (negate), +!+ (boolean not)
+
+String concatenation is also performed with +++ (plus).
++==+ and +!=+ may also be used on strings.
+
+=== Output
+
++trace(anything, anything, ...)+:: Report the value of any variable
++tracef("anything %format", anything, ...)+:: Report the value of any variable
+
+
+=== String functions
+
++ at strcat(string,string)+: Concatenation
+
+///////////////////////////////////////////////////
+
+=== Math
+
+ #include <math.swift>
+
++floor(float i) -> int+:: Round down
++ceil(float i) -> int+:: Round up
++round(float i) -> int+:: Round nearest
++log(float i) -> float+:: Natural logarithm
++exp(float i) -> float+:: Natural exponentiation: e^i^
++sqrt(float i) -> float+:: Square root
++is_nan(float i) -> boolean+:: Check for NaN
++abs_integer(int) -> int+:: Absolute value
++abs_float(float) -> float+:: Absolute value
+
+ #include <random.swift>
+
++random() -> float+:: Obtain random number
+
++randint(int start, int end)+::
+Obtain random integer from +start+, inclusive, to +end+, exclusive
+
+ #include <stats.swift>
+
++sum_integer(int[]) -> int+:: Sum
++avg(int|float[]) -> float+:: Average
+
+=== System
+
+ #include <sys.swift>
+
++getenv(string) -> string+:: Obtain an environment variable
+
+[[argv]]
+==== Command line
+
+Consider this command line:
+
+ turbine -l -n 3 program.tcl -v -a=file1.txt file2.txt --exec="prog thing1 thing2" --help file4.txt
+
+The arguments to +program.tcl+ are just the tokens after +program.tcl+
+
++args() -> string+::
+
+Obtain all arguments as single string
++
+E.g., +"-v -a=file1.txt file2.txt --exec="prog thing1 thing2" --help file4.txt"+
+
+The remaining functions are convenience functions oriented around
+Swift conventions.  Under these conventions, the example command above
+has _flagged_ arguments +v+, +a=file.txt+, +exec="prog thing1
+thing2"+, and +help+. The command has _unflagged_ arguments
++file2.txt+ and +file4.txt+
+
++argc()+::
+Get count of unflagged arguments
+
++argv(string)+::
+_(argument-value)_
+Given a string, returns the flagged argument with that key:
++
++argv("a") -> file1.txt+
+
++argp(int)+::
+_(argument-positional)_
+Given an integer, returns the unflagged argument at that index:
++
++argp(2) -> file4.txt+
++
+Given 0, returns the program name,
++
++argp(0) -> /path/to/program.tcl+
+
++argv_accept(string...)+::
+
+If program is given command line arguments not contained in given list,
+abort.
+E.g., +argv_accept("x")+ would cause program failure at run time
+
++argv_contains(string) -> boolean+::
+
+Test if the command line contains the given flagged argument:
++
++argv_contains("v") -> true+
+
+==== Debugging
+
+ #include <assert.swift>
+
++assert(boolean condition, string message)+::
+If condition is false, report +message+ and exit immediately.
+
+[[Turbine_information]]
+==== Turbine information
+
++adlb_servers()    -> int+:: Number of ADLB servers
++turbine_engines() -> int+:: Number of Turbine engines
++turbine_workers() -> int+:: Number of Turbine workers
+
+=== Files
+
++filename(file) -> string+::   Obtain the name of a file
++input_file(string) -> file+:: Obtain a +file+.  At run time, the
+filesystem is checked for the given file name
++readFile(file) -> string+::   Read file as a string
++writeFile(string) -> file+::  Write string to file
++glob(string) -> file[]+:: Perform glob operation, returning files
+that match.  Available glob symbols include:
++
+* +*+: any character sequence (including the zero-length sequence)
+* +?+: any character
+* +[chars]+: any of the given characters
+* +\x+: character +x+
+* +{a,b,c,...}+ any of +a+, +b+, +c+, etc.
+
+== Defining Leaf functions
+
+In typical Swift applications, the computationally intensive parts of the
+application are not written in the Swift language.  Rather,
+the work is done by _leaf functions_ that are _composed_ together with
+Swift code.  Leaf functions may be extension or app functions.
+The builtin functions mentioned above are implemented as extension
+functions in Tcl.
+
+=== Swift extension functions
+
+Currently we support Tcl extension functions, where a function is implemented
+as a Tcl function.  Tcl has good support for wrapping native C/C\++ functions,
+so this provides an indirect way to call C/C++ functions from Swift.
+
+Several components are required to implement a Tcl extension:
+
+-  Tcl bindings to your function.
+-  For complex types such as structures, arrays and files, you may need
+   additional logic to marshal inputs and outputs to/from the global
+   data store.
+-  The requisite files required to build a Tcl package (e.g pkgIndex.tcl)
+-  Swift declarations for the function that specify the type of the function
+    and the Tcl implementation.
+
+==== Simple Tcl Function Example
+In this first example we will implement a trivial Tcl extension function
+that doubles an integer.  Here is the Tcl code that will go in
++myextension.tcl+:
+
+----
+namespace eval myextension {
+  proc double { x } {
+    return [ expr $x * 2 ]
+  }
+}
+----
+
+* TODO: info on how to create Tcl package, e.g. pkgIndex.tcl
+
+Here is the Swift function definition that will go in +myextension.swift+:
+----
+ at pure
+(int o) double (int i) "myextension" "0.0.1" [
+  "set <<o>> [ myextension::double <<i>> ]"
+];
+----
+
+The above definition has, from left to right, the output arguments,
+the name of the new Swift function, input arguments, the name
+of the Tcl package containing the file, and the minimum version
+of that package.
+
+We tell the compiler how to call our Tcl function using inline
+Tcl code as a template with variable names surrounded by +<< >>+
+indicating where variables should be substituted.
+
+We can also tell the Swift compiler a little about the function so
+that it can better optimize your programs.
+For example, +double+ has no side-effects and produces the same result each
+time for the same arguments (i.e. is deterministic), so we can flag
+it as a + at pure+ function.
+
+If your function has a long running time and should be dispatched
+to a worker process for execution, then you need to label the
+function as a leaf function, for example:
+
+----
+ at dispatch=LEAF
+(int o) process (int i) "pkg" "0.0.1" [
+  "set <<o>> [ pkg::process <<i>> ]"
+];
+----
+
+==== Swift/Tcl Data Type Mapping
+If you are defining Tcl functions in the way above with inline
+Tcl code, Swift types are mapped to Tcl types in the following way:
+
+* int/float/string/bool are converted to the standard
+  Tcl representations
+* blobs are represented as a Tcl list with first element a pointer
+  to the data, and the second element the length of the data
+
+==== Writing Custom Tcl interfaces
+For Tcl functions that take complex argument types, such as arrays
+or structures, you currently need to write a Tcl wrapper function
+that is directly passed references to data in Swift's global data store.
+In this case your function must manually retrieve/store data from/to the
+global distributed data store.
+
+----
+(int o) complex (int arr[]) "pkg" "0.0.1" "complex";
+----
+
+* TODO: guide to do this.  Can look in turbine/lib for examples
+
+
+=== App functions
+
+App functions are functions that are implemented as command-line
+programs.  These command-line programs can be brought into a Swift
+program as functions with typed inputs and outputs.
+
+An app function definition comprises:
+
+* The standard components of a Swift function declaration: input and
+    output arguments and the function name.  Note that the output
+    variable types are restricted to individual +file+#s#.
+* The command line, which comprises an initial string which is the
+    executable to run, and then a series of arguments which are
+    the command-line arguments to pass to the program.
+
+App arguments can be:
+
+* Literals such as numbers or strings.
+* File variables (passed as file paths).
+* Other variables, which are converted to string arguments.
+    Arrays (including multi-dimensional arrays) are expanded to
+    multiple arguments.
+* Arbitrary expressions surrounded by parentheses.
+
+Standard input, output and error can be redirected to files.
+
+Join files together:
+----
+#include <files.swift>
+
+app (file out) cat (file inputs[]) {
+  "/bin/cat" inputs @stdout=out
+}
+
+main {
+  file joined <"joined.txt"> = cat(glob("*.txt"));
+}
+----
+
+Sleep an arbitrary amount of time:
+----
+
+app (void signal) sleep (int secs) {
+  "/bin/sleep" secs
+}
+
+main {
+  foreach time in [1:5] {
+    void signal = sleep(time);
+    // Wait on output signal so that trace occurs after sleep
+    wait(signal) {
+      trace("Slept " + fromint(time));
+    }
+  }
+}
+----
+
+
+[[Optimizations]]
+== Optimizations
+STC performs a range of compiler optimizations that can significantly
+speed up most Swift programs.  The optimization level can be controlled
+by the +-O+ command line option.  Almost always the default optimization
+level +-O2+ is your best choice.
+
+----
+# No optimizations at all (not recommended)
+stc -O0 example.swift example.tcl
+
+# Basic optimizations (not recommended)
+stc -O1 example.swift example.tcl
+
+# Standard optimizations (recommended)
+stc example.swift example.tcl
+# OR
+stc -O2 example.swift example.tcl
+
+# All optimizations (including ones that sometimes hurt performance)
+stc -O3 example.swift example.tcl
+----
+
+Individual optimizations can be toggled on using +-T <opt name>+
+or off with +-t <opt name>+, but this typically is only useful for
+debugging.
+
+[[Turbine]]
+== Running in Turbine
+
+The following describes how to run Turbine programs.
+
+=== Architecture
+
+Turbine runs as an MPI program consisting of many processes.  Turbine
+programs are ADLB programs.  Thus, they produce and execute discrete
+tasks that are distributed and load balanced at run time.
+
+Each process runs in a _mode_: _engine_, _worker_, or _server_.
+
+Engines:: Evaluate the Swift logic.  Produces tasks
+Workers:: Performs tasks
+Servers:: Distributes tasks
+
+Typical Swift programs perform compute-intensive work in extension
+functions.  These always execute on workers.
+
+Engines split up the control logic work among themselves.  This
+results in the generation of calls to extension functions.
+
+Servers distribute tasks in a scalable, load balanced manner.  They
+also store Swift data (integers, strings, etc.).
+
+=== Concurrency
+
+The available concurrency and efficiency in your Swift script is
+limited by the following factors:
+
+* The available concurrency in the Swift logic.  Sequential
+  dependencies will be evaluated sequentially.  +foreach+ loops and
+  branching function calls may be evaluated concurrently
+* The number of workers available to process leaf functions
+  concurrently
+* The number of engines and servers available to control the Turbine
+  run.  Adding more engines and servers usually improves performance
+  but costs processes
+
+=== Invocation
+
+The general form of a Turbine invocation for STC-generated
++program.tcl+ is:
+
+----
+turbine <turbine arguments> <program.tcl> <program arguments>
+----
+
+The program arguments are available to Swift (<<argv>>).
+
+Turbine accepts the following arguments:
+
++-l+:: Enable +mpiexec -l+ ranked output formatting
++-n+:: The total number of Turbine MPI processes
+
+The user controls the Turbine run time configuration through
+environment variables:
+
++TURBINE_ENGINES+:: Number of Turbine engines
+
++ADLB_SERVERS+:: Number of ADLB servers
+
+The remaining processes are workers.  These values are available to
+Swift (<<Turbine_information, Turbine information>>).
+
++TURBINE_LOG=0+:: Disable logging
+
++ADLB_EXHAUST_TIME+::
+Time in seconds taken by ADLB task servers to shut down.  May include
+a decimal point.  Default +0.1+ .  In very large runs, this may be set to
+5 to ensure correctness.
+
++TURBINE_LAUNCH_OPTS+::
+Provide other arguments to +mpiexec+, such as a machine file, etc.
+
++TURBINE_SRAND+::
+If unset or empty, the random number generator seed will be set to the
+process rank for each process, giving reproducible results.  If set to
+an integer +seed+, the random number generator seed for each process
+will be set to +seed+ + +rank+.
++
+For non-reproducible random results, use the following shell commands:
++
+----
+export TURBINE_SRAND=$( date +%s )
+turbine ...
+----
++
+The seed is recorded in the log.
+
+=== Configuration
+
+The following describes how to turn Swift/T programs in Turbine
+on more complex systems.
+
+[[Build_settings]]
+==== Build settings
+
+If +exm-setup.zsh+ does not succeed, you may need to change how it
+tries to configure and compile Swift/T.
+
+Swift/T is built with standard Ant (Java) and Autotools/Makefile
+(C,Tcl) techniques.  The primary control is thus the arguments to
++ant+ or +configure+.
+
+==== Manual configuration
+
+You do not need to use +exm-setup.zsh+ to install Swift/T.  To perform
+the installation using +configure+/+make+, simply untar the
+distribution package and do:
+
+----
+cd c-utils
+./configure ...
+make install
+
+cd ../lb
+./configure ...
+make install
+
+cd ../turbine
+./configure ...
+make install
+
+cd ../stc
+ant -Ddist.dir=... -Dturbine.home=...
+----
+
+* You may use +./configure --help+ and the
+  link:turbine-sites.html[Sites Guide] for further options.
+* You can use +exm-setup.zsh+ as a guide to this process, as it is a
+  simple linear shell script that automates the +configure+/+make+
+  process.
+
+==== Non-standard MPI locations
+
+Configure Turbine with:
+
+----
+ --enable-custom --with-mpi-include=/path/to/mpi.h/include
+                 --with-mpi-lib-dir=/path/to/mpi_lib/lib
+                 --with-mpi-lib-name=funny.mpi.a
+----
+
+==== Known systems
+
+See the
+http://www.mcs.anl.gov/exm/local/guides/turbine-sites.html[Turbine Sites Guide]
+for information about specific systems with Turbine installations.
+
+=== Performance enhancements
+
+1. Disable logging/debugging via environment
+2. Disable logging/debugging at configure/compile time
++
+** Configure c-utils with +--disable-log+
++
+3. Configure everything with +--enable-fast+. This disables assertions
+   and other checks
+4. When making performance measurements, always subtract 1 second
+   (or the value of +ADLB_EXHAUST_TIME+) from the Turbine run time
+   due to the ADLB shutdown protocol, which does not start until the
+   system is idle for that amount of time.
+
+////
+Local Variables:
+mode: doc
+End:
+////




More information about the Swift-commit mailing list