Fall 2023
Section 2

Style Guide

Programs are easier to read and to understand when they are written in a familiar style and follow standard coding conventions. Most organizations that develop software therefore require programmers to write programs that follow the organization's preferred style and coding conventions. Programs are generally written once, read many times, and edited over and over again. Style conventions help both you and any other programmer using your code to more easily understand what you were thinking when you wrote the code.

In addition to following the design principles taught in class, all code must...

We hope that these conventions will make your code easier to read, debug, and edit.

Document Structure

  1. Each file should adhere to the following general pattern (as appropriate)...
     
    // imports first
    import khoury.EnabledTest
    import khoury.runEnabledTests
    import khoury.testSame
    
    // ******************************************************************
    // Data
    // ******************************************************************
    
    // data types
    // (with associated examples)
    
    // represents ...
    interface IContract {
        // declarations
    }
    
    // represents ...
    data class AmazingType(val field1: Int, val field2: String): IContract {
        // determines if the object ...
        fun isMethod1(val param: String): Boolean {
            // code
        }
    
        // produces ...
        fun method2(): String {
            // code
        }
    }
    
    val amazingEg1 = AmazingType(1, "a")
    val amazingEg2 = AmazingType(2, "b")
    
    @EnabledTest
    fun testAmazingType() {
        testSame(
            amazingEg1.isMethod("a"),
            // expected result,
            "comment1",
        )
    
        testSame(
            amazingEg1.method2(),
            // expected result,
            "comment2",
        )
    
        // more tests
    }
    
    // generally useful constants
    
    // ******************************************************************
    // Functions
    // ******************************************************************
    
    // this function does...
    fun foo(x: Int) {
        // code
    }
    
    @EnabledTest
    fun testFoo() {
        testSame(
            foo(1),
            // expected result,
            "comment",
        )
    
        // more tests
    }
    
    // more functions
    
    fun main() {
        // any code intended to run at the start
        // (does not include tests)
    }
    
    runEnabledTests(this)
    main()
    

Term Names

Use names that make sense with respect to the problem, for your data types, field names, functions, constants, parameters, and tests. Also make sure to capitalize terms appropriately based upon their type...

Data Types Title case (interfaces start with I)
interface IContract { ... }

data class MyDataClass(...)

enum class MyEnumeration { ... }
Enumeration values All caps with underscores between words
enum class MyEnumeration {
    ONE,
    VALUE_TWO,
}
Function names/parameters,
variables/values,
and class fields
All lower-case, with the exception of the first letter of each word after the first (known as lower camel case)
val myModelParameter: Int = 42

fun myFun(myParam: Int) {
    val twiceParamOne = 2 * paramOne
}

data class MyDataClass(val fieldOne: Int, val two: String, val theVeryLast: Boolean)

General

  1. Use proper indentation. Use the indentation style of ktlint.
  2. Keep lines narrow. Generally do not exceed 80 columns for code or comments. You can see your current column at the bottom-right in Visual Studio Code. Attempt to break long lines into logically distinct tasks.