Some notes on Group Project 3: Problem 1 -- Many people didn't include the SPECIFICATION. -- A lot of papers didn't take into consideration the reuse of the queue list when a single node was deleted - we were expecting at least a shift-by-one of all remaining elements, or, even better, a "wrap-around" of the queue (circular-queue!) -- Many people found programming in Haskell harder and more complex than in Java. Possible reasons for the assessment: (1) no previous exposure to Haskell, but experience with Java, (2) programming in Haskell can be more abstract and mathematical. -- Some papers didn't have the "create" and didn't even specify the constructor (which is what is used in the java implementation!) as part of the specifications. Also, they didn't flag overflow and underflow - worse, they didn't even test for overflow and underflow conditions. -- About comparing implementations, very few papers went into any sort of details - indeed this is not an easy comparison. E.g. Haskell has some inherent sources of decreased efficiency due to the fact that it is purely functional: there are no updatable values. Java also has some such performance issues, e.g. due to many runtime checks (dynamic binding). Both object-orientation and functional programming can be done at a high level of abstraction (in OO via classes, inheritance, overriding, etc., in Haskell mainly due to higher-order functions). Both Java and Haskell include forms of polymorphism, however they are quite different. ... In general we were looking for discussion of efficiency, level of abstraction, limitations,... Problem 2 -- Many people claimed that their mPLs support only pass-by-value! But then what is the use of procedures if you can't return what has been computed? (other than through global variables) -- Most people got the abstract syntax notation right (almost, that is, because the data constructor was often missing ), but many lost some points because it didn't match the discussion on it. The classic example was that it was said that parameters are passed by reference and value, but nowhere was there an indication in the syntax or later in the discussion how the compiler is supposed to know what kind of passing mode it is. -- In part b, we were looking for notions on scoping, parameter passing, arithmetic rules, lifetimes of variables, binding, type casting etc... -- For part c, many people were talking more about parsers rather than how they would implement the notions of part b!