Functional Programming Project

Motivation

The majority of the work you do in this class will revolve around a significant functional programming project of your own design. This project gives you a chance to develop a larger functional program from start to finish.

The project is intentionally open-ended and underspecified. The goal is to flex a different set of functional programming muscles than you use in other aspects of the course. While Hasklets focus on helping you learn specific FP skills in a constrained context, the project is about applying these skills to a larger problem and doing something cool with them.

The project is also your main chance in this course to make high-level design decisions, such as how to identity important concepts in your domain and encode them as types.

Team Size and Project Scope

Each project team will consist of 2-4 students. I know some of you will want to work alone–sorry! There are several reasons that I’m requiring you work in teams:

  1. I want to encourage you to try to do something ambitious. This is hard to do in 6-7 weeks with only one person.

  2. I strongly believe you learn more through collaborating on a project than working alone. When you work alone, you are essentially practicing what you picked up in class (or from the web, or wherever). When you work with others, you must discuss your plans and solution strategy, and you’ll be constantly critiquing and improving each others work.

  3. It makes overseeing the projects tractable for me. With 20 projects, it’s hard to keep track of each one and provide individualized feedback. With 5-10, this is much more manageable.

The scope of the project should be relatively ambitious. I would rather see you attempt something interesting and challenging and fall a bit short than to breeze through with an easier project. The scope must be large enough to allow you to apply multiple ideas from the course and so that every team member can contribute significantly to it over 6-7 weeks.

A typical project will probably require several modules and several hundred lines of Haskell code. If you’re pushing the bounds of functional programming or applying some very advanced techniques, your project may be a bit smaller than that.

You may also choose a project that encourages you to explore a functional programming topic outside of the main course content, such as functional reactive programming or arrows. In this case, part of the project challenge will be learning the new topic, and this should be taken into account when determining the scope of your project.

Below is a list of project ideas that can also help you establish the scope of your project.

Deliverables

Over the term, you will submit the following deliverables related to the course project. Each deliverable is described in more depth below. (Note: these dates and descriptions are subject to minor changes during the term.)

Project proposal

Deadlines:

  • First draft: Apr 21
  • Peer Review: Apr 26 (in-class workshop on Apr 27)
  • Revision: Apr 30

The project proposal is a brief written statement of what you plan to do for your project. We will do one round of peer review, then you will revise and resubmit your proposal taking into account the feedback of your peers.

I will read these and make additional suggestions, if necessary. In some cases, I may meet with you individually for further clarification or to brainstorm related ideas. Ultimately, I will approve your proposal and you will get to work.

Your project proposal should include the following:

  • A high-level overview of what your project is about. This should answer the following questions: What is the domain? Who are the users? What kinds of things will those users do with your project? What similar applications, libraries, or languages already exist and how will yours be different?

  • A list of the most important objects or concepts to be represented in your project, and a brief (1-2 sentence) description of each. For example, if you’re creating a calendar application, the most important concepts might be appointments, calendars, and daily agendas. The concepts you identify will usually correspond to types or type classes in your Haskell code.

  • A list of the most important or most interesting operations to be implemented in your project, and a brief (1-2 sentence) description of each. Especially interesting are operations that compose two objects to produce another objects of the same type. For example, if you’re creating a calendar application, the most important operations might be adding an appointment to a calendar, generating a daily agenda from a calendar, and merging two calendars into one (there might be several operations for merging calendars with different conflict resolution schemes, or one operation that is parameterized by the resolution scheme). These operations will usually correspond to functions in your Haskell code.

  • A brief statement about what ideas from the course (or what external ideas) you intend/hope to apply in your project. Naturally, the ideas you apply may change as your project develops and you learn new things during the course.

Overall, your proposal should be approximately two pages, and not more than four. There is no minimum text requirement. The important thing is that all of the information is there for anyone to evaluate your proposal quickly and give well-informed advice.

Milestones (2)

Deadlines:

  • Milestone #1: May 12
  • Milestone #2: May 26

There will be two milestones during the term. For each milestone, you will submit your current progress on your project to be reviewed by your peers. We will workshop your milestone submissions on Canvas, similar to the process for Hasklets but in more depth. For each of the project milestone workshops, workshop participants will submit brief written feedback in advance.

The milestones serve several purposes:

  • They encourage you to make steady progress on your project throughout the term.
  • They provide a source of early feedback that you can still act on before it’s too late.
  • They provide a chance to see what other students are working on, which may inspire you to try different things with your own project.

You should submit either a .zip file or a link to a public GitHub/GitLab repository. Your submission should include:

  • The source code for your project.

  • A README file, which must include the following:

    • A brief description of your project goals (you can take this from your project proposal), and your current progress toward achieving those goals.
    • Instructions for how to run your project (e.g. which file to load in GHCi), including several example inputs, if applicable.
    • In Milestone #1: a list of 2–4 design questions that you have about your project, that you would like to discuss during the workshop.
    • In Milestone #2: a list of 2-4 design decisions that you made and detailed rationale describing why you made them using concepts, ideas, and terms from the class. (You may also still want to include questions as part of this discussion, if there are aspects you’re unsure about.)

Milestone feedback (2)

Deadlines:

  • Milestone #1 Feedback: May 19
  • Milestone #2 Feedback: Jun 1

To provide good feedback, it is essential to both carefully study the other team’s source code and to actually run it and play around with it (e.g. in GHCi).

You should submit 3–4 detailed comments for the other team. The comments should:

  • Call attention to clever aspects of their design.
  • Identify opportunities for abstraction.
  • Identify opportunities for applying concepts from class.
  • Suggest how to generalize aspects of the project.
  • Suggest general improvements.
  • Ask questions about design rationale.
  • Note something that you learned from studying their project.

It is nice to include at least one entirely positive comment in your feedback (e.g. something clever or something you learned). However, the goal is to help the other team improve their project, so focus on providing substantial, insightful, and constructive criticism.

Final project submission and report

Deadline: Jun 9

Your final project submission will consist of three pieces: (1) your source code, (2) a README file, and (3) a report describing your project.

Source code:

Your source code will be evaluated along three dimensions: correctness, readability, and elegance. Here are some questions that we’ll be asking when evaluating your source code.

Correctness:

  • Does the code do what it’s intended to do?
  • Do data types accurately represent their objects/concepts?
  • Do functions return the correct outputs?
  • How are bad inputs to functions handled? From better to worse, they might be: ruled out by the type system, reported as an error value (e.g. Nothing), reported by a dynamic error (e.g. the error function), or not handled/considered at all.

Readability:

  • Does the code adhere to basic Haskell style conventions?
  • Are the types of functions explicitly declared?
  • Is the code well-documented?
  • Are functions generally small and straightforward?

Elegance:

  • Does the code demonstrate a mastery of functional programming?
  • Does the code use generalization and abstraction to factor out repeated patterns in functions?
  • Are higher-order functions used where appropriate?
  • Are type classes used where appropriate?
  • Are monads or other abstraction techniques used for simplifying code with effects?
  • Is the project extensible, and in what ways?

README:

Your README file should describe how to install and run your project. In particular, it should clearly state:

  • What external libraries (if any) does your project depend on?
  • What module should be loaded into GHCi? (Or, what command to run to compile and execute your project.)
  • (Important!) What are some example expressions to evaluate in GHCi, or some example input sequences, that show off the important aspects of your project?

Project report:

The project report is your chance to demonstrate that you understand not just the mechanics of the course content (needed to write working code and answer midterm problems), but also the higher-level motivation and rationale for these concepts and how they can be applied to improve the design of a functional program.

Your project report should consist of several sections. The first few can be adapted from your project proposal, but should be updated and expanded to more accurately and completely describe your final project.

  • A high-level overview of what your project is about. This should answer the following questions: What is the domain? Who are the users? What kinds of things can those users do with your project? Are there similar tools/languages that exist already, and if so, how are they different?

  • A list and brief description of the most important types, type classes, and functions defined in your project. The goal of this section is to guide the reader through your source code, putting things into their proper context. It isn’t necessary to describe every helper function, but this section should provide a reasonably complete overview of the content of your project.

  • (Most important!) Describe in detail 2-4 design decisions you made during your project. For example, you might describe the design rationale for choosing to use a higher-order type to represent a particular concept, or for choosing to define a type class. These should emphasize how you applied ideas from the course (or external ideas you learned about) to the design of your project. It would be very helpful here to include snippets from old versions (or hypothetical alternative versions) of your project to compare and contrast with the final version.

    The range of 2-4 design decisions is to accommodate different levels of depth. For example, if you made a more obvious design decision, such as to use a monad transformer to combine effects, there is probably only so much you can say and so this might be one of four such descriptions. However, if you made a design decision with more subtle implications (e.g. that involves trading off one desirable quality for another) or a less obvious solution, then you will have much more to say and also a few alternative designs to discuss, and so this might be one of only two such descriptions.

Project Ideas

Here are some project topics/ideas to help get your brainstorming started, and to give a sense of the intended scope of the project.

Language/DSL implementation: Functional programming is well-suited to implementing languages, and many of the techniques you will learn are directly applicable to this task (e.g. higher-order abstract syntax, managing effects with monads). In addition to syntax and semantics, you might consider implementing a type system, parser, pretty printer, and/or some interesting program analysis. A good way to incorporate ideas from the course is to think about extensibility: can you modularly extend your language with both new operations and new interpretations?

Game: A graphics-intensive action game may be out-of-scope for this course, but there are still many interesting possibilities. Previous projects have included a text-based backgammon game engine and micro-DSL for describing strategies to play against, a text adventure engine with a higher-order representation of interactive objects. For terminal graphics there are nice ncurses bindings on Hackage. One advantage of game projects is that they’re fun for your peers to evaluate. :-)

Math: The Haskell community has a long tradition of adopting ideas from mathematics (especially algebra and category theory). This is reflected, for example, in the names of widely used type classes, such as Functor and Monad. It may be hard to find unexplored territory here, but a great functional programming project might demonstrate how a mathematical concept can be realized in Haskell, then show how this concept can be applied to solve a functional programming problem (e.g. by providing a useful abstraction or making a program somehow more extensible).

Hasklet manager: As a more concrete project idea, consider some infrastructure for managing Hasklets. This could provide several different interfaces, one interface for the instructor who must specify a new Hasklet, one for the TA to triage the submissions and generate group assignments, and one for students, who must complete and submit Hasklets, then later review their group members’ submissions. There are many clever things you might do to help the TA generate group assignments without reading every one in detail, such as using automated testing and specifying (higher order?) heuristics for identifying potentially interesting or problematic solutions.

Simplified Haskell: A simplified version of Haskell suitable for teaching intro to computer science courses. There are a variety of ways that this could be achieved, e.g. by defining a custom Prelude, by implementing a custom interpreter for a subset of Haskell, or by modifying GHC. The custom Prelude approach may not have enough meat for a CS 583 project, but it might be possible to do this in an interesting way that I haven’t foreseen. Our other PL faculty member, Martin Erwig would be happy to serve as the client for this project.


Back to course home page