Thread:Sinthorion/@comment-25330335-20170525042041

There is more to this post that it may seem...

<!-- Alright, so I watched a video today that has gotten me thinking about what I good program looks like. I typed up a preliminary style guide, and I'd like you to look over it for me. It's in Markdown, so there might be a few quirky things in this post...

The problem is to avoid dealing with global program state. Storing program state and other mutable variables in the global scope can be very harmful for any program, specificially one that is large and does a lot of complex things. Programs like that must be well-written in order to be understood, maintained, and extended. [Video](https://www.youtube.com/watch?v=QM1iUe6IofM).
 * 1) How to write good functional code

Object oriented programming is one way to prevent dealing with the global state. It does this by taking encapsulation way too far, by making everything an object. Some problems do greatly benfit from using objects and grouping data together in logical arrangements with operations that logically fit with that data, but in a lot of cases, grouping everything in objects results in a lot of unessasary and increasingly abstract and meaningless classes. All this acomplishes is to split up your code into smaller and smaller peices and tends to make things more difficult to understand.

Using pure functions should be preferrable to grouping things into objects. These are passed parameters and return values. They don't see things that are not in their scope, and operate on only their data. It allows for easily understandable code.
 * 1) Functions

Nested functions allow for more readable and maintainable larger functions. These can be named, although they do not have to be. Functions can be grouped inside other routines as _function literals_ which can be helpful for both memory management and keeping things clean.
 * 1) Nested Functions

Function Literals can be used when a function can be split into subroutines that don't nessasarily need to be named and are specific to that function. They should be preferred to named functions when nested in other functions, with a few exceptions (see below).
 * 1) Function Literals

In cases where a function needs to be called multiple times as a subroutine of another function (although it is still specific to it's parent routine), then it should be named appropriately. This should only be used if it definetly makes sense. If in doubt, resort to either a function literal (if there is no reason to call the function multiple times), or create a new global function.
 * 1) Named Nested Functions

Needs Thought
 * 1) Functions as First Class Citizens

Structs should be preferred to classes, because they simplify the object-oriented paradigm to only the nessasary basics. However, if a certain language's implementation of structs does not allow member functions or constructors/destructors, classes should be preferred.
 * 1) Structs

Data grouping is the main reason to use structs. If grouping data isn't the goal, global functions should be used instead.
 * 1) Data

Methods/Member functions of struct types should be used sparingly, although there are situations in which their use makes logical sense. This is usually when the method is doing something very specific to that data in the struct. If in doubt as to whether or not a function belongs to a struct or not, make it global.
 * 1) Methods/Member functions

These are just a small subset of struct member functions, but they are very important. First of all, the usage (or existance!) of these for structs depends on your language. If they do exist, then it is important to create only basic constructors that handle the data for their function and do no more. Because structs are not the same as classes, you shouldn't usually implement the default constructor, because inital values can be implemented as part of the data definitions of the struct. Destructors should only be used if your data needs to do something before it is destroyed, and should be used sparingly.
 * 1) Constructors/Destructors

Inheritance will more often get in your way than help you. The important thing to remember about struct types is that tey are only to be used to group data, with methods as things on the side. Inheritance usually has more to do with implementations of functions, and is therefore undermining the ideas that keep structs clean. Structs usually do not have access modifiers. Access modifiers usually are used in situations where inheritance or overmuch encapsulation are happening. Access modifiers should not be used in structs, because if there is something that you wish you could flag as private, chances are it should be a subroutine of another function.
 * 1) Comparing with Classes
 * 2) Inheritance
 * 1) Access Modifiers

Programs should be very loosely encapsulated in modules or packages. Too much abstraction is not a good thing, and prevents the programmer from doing what they need to be able to do to manipulate data. Loosly encapsulated functions and types allow for good structure to programs while preventing cross-referencing from capsules being a huge concern. Depending on your language, access modifiers should be used in modules in order to make it clear what can be referenced where in different parts of the code. This usually just improves readability. Access modifiers should also be used for global variables (such as const and enum values). -->  
 * 1) Encapsulation
 * 1) Access Modifiers