--- tags: programming, style --- # Aardvark F# Coding Guidelines For a complete set on F# formatting guidelines refer to https://docs.microsoft.com/en-us/dotnet/fsharp/style-guide/formatting ## Capitalization ```javascript= //variables - lowerCase let a = 5 //functions - lowerCase let add a b = a+b //types - UpperCase type Rectangle = { min : V2d //fields lowerCase max : V2d } //union types - UpperCase type Shape = | Rectangle //union cases - upperCase | Circle //modules - UpperCase module Serialization = ... //namespaces - UpperCase namespace Aardvark.IO //FShade semantics - UpperCase ... |> Sg.uniform "LineWidth" ... ``` ## Variable Naming Clean Code Handbook, Chapter 2 https://www.investigatii.md/uploads/resurse/Clean_Code.pdf > One difference between a smart programmer and a professional programmer is that the professional understands that **clarity is king**. Professionals use their powers for good and write code that others can understand. (Robert C. Martin) * `types` are nouns * `functions` are verbs * `bool` ... names starting with `is`, `has`, `can` (notice the lower case :smile:) * use plural or singular consciously * avoid encoding datastructure into name e.g. ` points` instead of `pointList` * no prefixes like `m_` or `_` in general * functions returning an `option` should start with `try` ## Good Guidance from Bad Code (Kit Eason - Stylish F#) > Characteristic 1: It's hard to work out what is going on when looking closely at any particular piece of code. poor _semantic focus_ > Characteristic 2: It's hard to be sure that any change will have the effects one wants, and only those effects hard to _revise_ > Characteristic 3: It's hard to be certain of the author's intent bad _motivational transparency_ > Characteristic 4: It's hard to tell without experimentation whether the code will be efficient poor _mechanical sympathy_ ## Consistent Media App Naming An `App` consist of `Model`, `update`, `view`, and `Actions`. Since Aardvark.Media is an approach to tame complexity, we tend to end up with extremely large projects due to the inherent complexity of the problems we strive to solve. Therefore, consistent naming is key for understanding someone else's or even your own code. We at least need one `App`, which composes everything. We should also express this in the `App` name like `MainApp`, or we could just simple call it `App`. The same stands for `Model` and `Action`. ```javascript= //the location of actions can vary type Action = | DoStuff of int //Model.fs type Model = { field : ... } //App.fs module App = let update model action = ... let view model = ... ``` That was rather straighforward, but naming becomes important when we want to compose apps, for instance, we add a `DrawingApp`. ```javascript= //DRAWING //the location of actions can vary type DrawingAction = | AddPoint of V3d //DrawingModel.fs type DrawingModel = { points : list<V3d> } //DrawingApp.fs module DrawingApp = let update (model:DrawingModel) (action:DrawingAction) = ... let view (model:MDrawingModel) = ... //MAINAPP //the location of actions can vary type Action = | DrawingMessage of DrawingAction | DoStuff of int //Model.fs type Model = { drawingModel : DrawingModel field : ... } //App.fs module App = let update (model : Model) (action : Action) = match action with | DrawingMessage a -> let drawingModel = DrawingApp.update model.drawingModel { model with drawingModel = drawingModel} ... let view (model : MModel) = DrawingApp.view model.drawingModel |> UI.map DrawingMessage ... ```