These thoughts are all "in the small", focusing on things I saw while 
trying to write my toy program.  They're not necessarily language-wide 
things.

* The language seems very large, and as had been said during the 
quarter, it's not clear what the core of the language is.

* I know we discussed this in class, but while writing my toy program, I 
could not keep straight the difference between calling functions with [] 
versus ().  Most of the time, it didn't matter -- most of my functions 
were one-argument anyway, but I was confused by the documentation about 
string.substring:  you show both foo.substring(i) and foo.substring[i], 
but only foo.substring[i..j], so I wasn't ever sure whether ranges were 
treated as single variables or whether they were zipped over...

* The semantics of begin, cobegin, forall and coforall need some 
clarification.  For instance, the spec should say explicitly something 
like, "Coforall <cond> { <body> } is sugar for forall <cond> { begin { 
<body> } }", rather than just the English prose it currently has.

* I ran across a bug in the implementation of coforall loops where if 
your iteration variable has structure (a tuple or something), the 
current compiler doesn't privatize the destructured values properly.  
Combining the first and third points above, why can't you say "'for 
<tuple> in <2+D domain> { <body> }' is sugar for 'for temp in <2+D 
domain> { const <tuple> = temp; <body> }'.  In all cases, temp is 
locally scoped to the current iteration of the loop."  Then your 
compiler bug goes away, because your semantic support for loops is 
simplified.

* I'd like to hierarchically define domains.  That is, given domains D1, 
D2, I want to define var D3 = [D1, D2] and have it be the cartesian 
product of them.  It's of no big deal to me whether you flatten those 
domains (e.g. if D1 and D2 were a 1-D and a 2-D domain, whether D3 would 
be a standard 3-D domain or a 1D x (2-D) domain) with coordinates ((x), 
(y, z)).

* File IO is sorely lacking :-p

* Idiomatically, I wanted the ability to construct lists of values and 
fold over them.  The best I came up with was to define sparse domains 
and add elements to them, then iterate over indices in the sparse 
domain.  That seems rather "meta" -- I want a list of those values, not 
have those values be indices to some other array.

* Also, once I'd defined a sparse domain, and an array using it, every 
time I added an element to the domain that array must be reallocated, 
no?  I'd like a way to say, "Here's a dense domain, and a sparse domain 
over it, and an array over *that*; now hang on a sec while I initialize 
the sparse domain... ok, *now* go ahead and allocate that array once and 
for all, thanks."

* There doesn't seem to be an easy way to re-order iterators, or if 
there is I didn't understand it clearly.  For instance, given the 
iteration [1..2, 1..4], which yields the pairs (1,1), (1,2), (1,3), 
(1,4), (2,1), (2,2), (2,3), (2,4) in that order, I'd like a simple way 
to "take the transpose" of that and get column major order.  If I'd had 
that, then I wouldn't have been bitten by the coforall bug above -- I 
could have used a forall loop instead. :)  I suspect I could work around 
this by having done forall (y,x) in [1..4, 1..2], which swaps the 
variables and also the iterator, but that feels not-clean, somehow.

Some slightly larger thoughts:

* The core of the language is a bigger issue.

* The syntax isn't well specified in the spec, I think due to its change 
over time.  But it wasn't clear why you had an optional "then" keyword, 
for instance; pick one syntax (e.g. C's, since you're very close to it 
already) and stick to it.  Or, if you want the flexibility, give 
examples of the different options.

* There's a heavy learning curve, I think, which is aggravated by the 
lack of examples.  A lot of the code I wrote was written via 
copy-paste-modify, and I wasn't always sure what syntax was critical and 
what was style and what was optional.


That's all for now; if I think of other stuff I'll send it your way.
~ben
