Day 1: Parallelism Implicit threads * do / also do: the simplest case - zeno.fss used as an example here * lack of guarantees for implicit threads - can be serialized/interleaved statically - thread creation ~ cost of fn call - can use any lightweight threading mechanism - lots of questions here. * tuples * function/method applications * extremem expressions * expressions with generators - zeno.fss as an example again, but perhaps not the best choice for this in hindsight. - loops - reductions - comprehensions -> this part was not as well structured as the more formal intro Guy gave on day 2; it was supposed to just show the constructs, but stimulated enough discussion that it ended up being wide-ranging. * Sidebar: Generalized if expressions. Took longer than desired. * Had planned to talk about exception and label/exit semantics at this point, but time was short. Ended up as a sidebar on day 2. * atomic and synchronization (again got shorter shrift than I had hoped; had inteded to cover use case from zeno.fss). Important for future: prepare good short examples demonstrating both atomicity and isolation. - Multiple worlds view: whole language except IO available inside transaction. - Data races allowed between threads within a transaction; use nested transactions to resolve. * Spawned threads - A separate work stealing cloud - Fair with respect to parent, any other spawned threads. - Like pthreads or Java threads, used for I/O concurrency etc. - Not allowed inside atomic now, some question about this. * Had intended to close with abort, but did not get to it. ------------------------------------------------------------ Day 2: Library overview Library Overview * Library Components * Rationale for what is where * Some conventions Equivalence and Ordering * SEQV * Equality[\T\] * StandardPartialOrder[\T\] and StandardTotalOrder[\T\] Numerics * Numeric types, and the ones you should use * Operations on RR64 * Operations on Integral * On the need for coercion; widen and narrow * Matrices and Vectors * Feature (in)completeness Array Hierarchy * Array1, Array2, Array3: Arrays with static bounds * Array: Arrays with dynamic bounds * Use of overloading to extract static bounds from dynamic arrays * Immutable arrays (only 1-D so far) * 0-indexing and other internal naughtiness * The three array generators Didn't get to ranges in detail, but Guy covered them: Ranges * FullRange * Partial ranges; array indexing ------------------------------------------------------------ Generators * Note that anything collection-like is a Generator of its elements * Indexed and ZeroIndexed [Skipped] * Guy already covered the basic concepts from our ancient talks * Focused on how to define an instance of Generator (define the generate method). * Need to define seq(self) * Usually need to define map * Often need to define IN * Useful to define loop if you care about performance Reductions * Already covered most stuff in Guy's talks, so quick. Defining BIG operators * Example: SUM - Type signature of BIG operator definition. - Similarity to generate * Example: MAX - Using Maybe to add a zero to an operation that lacks it. - Cleaning up the results of the call to generate. * Example: AND - Using label/exit to deal with zeros - Extended sidebar on label/exit + implicit threads. - Behavior wrt atomic? ------------------------------------------------------------ Day 3: Desugaring Will be migrating very soon, so won't say much about the actual code. Things desugared: * Conditional operators -> thunks a AND: b -> a AND (fn () => b) * Spawn expr -> Thread(fn () => expr) * Generalized if and while if expr1 then block1 elif expr2 then block2 elif expr3 then block3 else block4 end -> if expr1 then block1 else if expr2 then block2 else if expr3 then block3 else block4 end end end * Boolean if and while otherwise unchanged. * Generalized if if x <- expr then block_t else block_e end -> (expr).cond(fn x => block_t, fn () => block_e) trait Condition[\E\] extends { ZeroIndexed[\E\], SequentialGenerator[\E\] } ... getter holds(): Boolean = cond[\Boolean\](fn (_:E):Boolean => true, fn () => false) getter get(): E throws NotFound = cond[\E\](identity[\E\], fn () => throw NotFound) opr |self|: ZZ32 = if self.holds() then 1 else 0 end ... cond[\G\](t: E -> G, e: () -> G): G generate[\G\](r:Reduction[\G\], body: E -> G): G = cond[\G\](t,fn () => r.empty()) ... opr IN(x:E, self):Boolean = cond[\Boolean\](fn (e:E):Boolean => x=e, fn () => false) end * Generalized while while x <- expr do block end -> while (expr).cond(fn x => do block; true, fn () => false) do () end * Note that the entire loop has moved up into the guarding condition! * Does this matter much? Not really. * Generated expressions a[i] := f(i), i <- a.indices() -> for i <- a.indices() do a[i] := f(i) end [then desugar as below] * For loops: for [empty] do block end -> block for i <- e, gs do block end -> (e).loop(fn i => for gs do block end) for p, gs do block end -> (p).loop(fn ()=> for gs do block end) Empty generators aren't legal syntax, but they're helpful in explaining the desugaring. Example: for i <- g, p(i), j <- 0#i do ...body... end Desugars to: (g).loop(fn i => (p(i)).loop(fn () => (0#i).loop(fn j => ...body...))) * Reductions and comprehensions: BIG OP[ gs ] expr -> BIG OP(fn (reduction, unit) => DS[gs] expr) { expr | gs } -> BIG { fn (reduction, unit) => DS[gs] expr } * RHS applyes the BIG operator as though it were an ordinary function (or an ordinary prefix or bracketing operator). - Syntax of Fortress doesn't let us say this within code. - Simple to construct corresponding AST, though. DS[ ] expr -> unit(expr) DS[ i <- e, gs ] expr -> (e).generate( reduction, fn i => DS[ gs ] expr ) DS[ p, gs ] expr -> (p).generate( reduction, fn () => DS[ gs ] expr ) * Essentially isomorphic to the loop desugaring. * We separate the reduction from the unit because they end up being defined and used very differently in practice. - use the unit, once, to wrap the body expression - use the reduction many times to reduce each generator clause - usually specify the two independently as well - eg disjoint union reduction on maps gets used for both map comprehensions and BIG UPLUS.