Project 1 — Functional Programming

CS-364: Programming Languages

Spring 2022

For this assignment, you will implement several functions using the Reason programming language. You will be provided with the interface for various functions or a specific problem, and you are responsible for implementing the specified functionality.

Project 1 will give you time to practice the concepts we cover in class with respect to the functional programming paradigm. These skills will help prapare you for the remaining programming assignments.

For this assignment, you will be programming in Reason, a dialect of OCaml. There are two parts to this assignment.

You may not work in teams for this project.

Requirements

Working alone, create and submit the following four (4) artifacts:

  • A Reason source file, p1a.re, that contains your implementations of the function interfaces required for P1a.
  • A Reason source file, p1b.re, that contains your implementations of the function interfaces required for P1b.
  • A plain UTF-8 text file called references.txt providing a citation for each resource you used (excluding class notes, and assigned readings) to complete the assignment. For example, if you found a Stack Overflow answer helpful, provide a link to it. Additionally, provide a brief description of how the resource helped you. You should create a separate version of this file for both P1a and P1b.

Unless otherwise noted, you may use standard library functions.

P1a: Basic Functional Programming

Create a Reason file named p1a.re, and implement the following function interfaces.

  1. c_to_f
    
                      let c_to_f = (temp: float) : float => {
                        /* ... */
                      };					
                    
    Given a temperature in Celsius, return the temperature in Fahrenheit.
  2. split_tip
    
                      let split_tip = ((price: float), (n: int)) : option(float) => {
                        /* ... */
                      };					
                    
    Given the total price of a meal, and the number of ways to split the check n, return Some(<float>), where float is the price with 20% tip split n ways. If n is less than 1 or price is less than 0, return None.
  3. triangle_area
    
                      let triangle_area = ((s1: float), (s2: float), (s3: float)) : option(float) => {
                        /* ... */
                      };					
                    
    Return Some(<float>) where float is the area of a triangle with those sides. If the sides do not form a valid triangle, return None.
  4. repeat
    
                      let repeat = ((f: 'a => 'a), (arg: 'a), (n: int)) : 'a => {
                        /* ... */
                      };					
                    
    Given a unary function f, an argument to the function arg, and an integer n, return f applied to arg n times.
  5. list_length
    
                      let list_length = (l: list('a)) : int => {
                        /* ... */
                      };				
                    
    Given a list, return the length of the list.

P1b: Higher-Order Functions and Advanced Types

Create a Reason file named p1b.re, and implement the following function interfaces:

  1. salutations
    
                      let salutations = (l: list(string)) : list(string) => {
                        /* ... */
                      };					
                    
    Given a list of strings, return a list of strings with greetings. For example, if you are provided with the following input list
    Example input:
    ["Harry", "Ron", "Hermione", "Minerva", "Albus"]
    your code should return the following list
    Example output:
    ["Salutations, Harry", "Salutations, Ron", "Salutations, Hermione", "Salutations, Minerva", "Salutations, Albus"]
  2. dot_product
    
                      let dot_product =  ((l1: list(int)), (l2: list(int))) : option(int) => {
                        /* ... */
                      };					
                    
    Given two lists of integers of equal length, return Some <int>, where int is the dot product of the two lists. If the lists are not the same length, return None.
  3. count
    
                      let count =  ((l: list ('a)), (e: 'a)) : int => {
                        /* ... */
                      };					
                    
    Given a list of elements, l, and an element, e, return the number of occurrences of e in l.
  4. pre_order
    
                      let pre_order = (t: int_tree) : list(int) => {
                        /* ... */
                      };					
                    
    Given an integer tree, t, return a list of the tree items in the order that they are visited by a pre-order traversal.
  5. int_tree_map
    
                      let int_tree_map = ((f: int => int), (t: int_tree)) : int_tree => {
                        /* ... */
                      };					
                    
    Given a unary function, f, and an integer tree, t, return a new integer tree with f applied to all nodes of t.

Resources

For this part of the assignment, one resource is provided:

  • p1btree.re — provides the implementation of an integer tree and some helper functions

Commentary

Documentation is your friend! Here are some external resources you might find helpful:

Recall that Reason is a dialect of OCaml. You are able to make use all of OCaml's standard library and pervasives as a result. While it is possible to implement all of the function interfaces on your own, you may find it easier to use library functions in some cases (check out the List module in particular).

When implementing code in Reason, make a particular effort to use local bindings to:

  • break down your calculations into simpler steps.
  • avoid recalculating the same values multiple times.

You will most likely need to define recursive helper functions. To improve the performance of your code, be sure to make your functions tail-recursive whenever possible.

If you are still stuck, you can post on Piazza or approach the professor.

Video Guides

Video guides are provided to help you get started with various aspects of this project. Note that there may be errors and mistakes in these videos. You should not blindly follow the steps taken in these videos!

Starting P1a and Uploading to SLUGS

What to Submit

P1a

You must turn in a tar.gz file containing these files:

  • references.txt: your file of citations
  • source_files: including
    • p1a.re (contains your answers for P1a)
    • These source files must include a comment with the project identifier: 38a1108d19f54a1fab115779487fbbcea3ae1843

P1b

You must turn in a tar.gz file containing these files:

  • references.txt: your file of citations
  • source_files: including
    • p1b.re (contains your answers for P1b)
    • These source files must include a comment with the project identifier: 38a1108d19f54a1fab115779487fbbcea3ae1843

Generating the compressed file for SLUGS

Note, you can use the CS-364 Makefile to generate a submission archive:

                
                make fullsubmit
                
              
The Makefile is available here. Be sure to update the IDENTIFIER and EXECUTABLE variables appropriately.

Grading Rubric

P1 Grading (out of 50 points):

  • 40 points: autograder tests
    • 20 — autograder tests for P1a
    • 20 — autograder tests for P1b
  • 4 points: clear description in your References
    • 4 — Citations provided are properly formatted and descriptive.
    • 2 — Citations are provided but might not help identify/find the resources used.
    • 0 — little to no effort. Citations do not provide correct information.
  • 6 points: code cleanliness
    • 6 — code is mostly clean and well-commented
    • 3 — code is sloppy and/or poorly commented in places
    • 0 — little to no effort to organize and document code
  • -5 points: per each use of a disallowed library function
    • 0 — you did not use any disallowed library functions (good job!)
    • -5 — you used a disallowed library function once