Babby's First Coding Guide

intro

I said I'd make an OP that's a coding guide, so here it is. I'll go over some
stuff that's probably very obvious to Holla Forums, but I just want to make sure
everyone's up to speed. This is a guide on imperative programming, so any
reference I make to programs or programming are implied to mean imperative.
Call me a fag if I'm wrong. I have no peers here, so I could use the criticism.

This is a guide mostly on ==coding==. I make a distinction between coding and
programming. Coding is like English Composition and programming is like
English Literature. That is, coding is just how to write, programming is what
to write. I'll write a bit about good programming later if anyone's
interested.

There are many programming paradigms, but I'm going over the imperative
paradigm here. Imperative programming is a lot like writing instructions for
assembling Ikea furnature. It's distinct from declarative programming, which is
more like writing mathmatical proofs. Object oriented programming is a subset
of imperative programming that has all of the same concerns as imperative
programming with the added concernse of delegating responsibilities to
different "objects". I know most of Holla Forums doesn't like object oriented
programming, and I tend to share that sentiment. At the very least, since
object oriented is a subset of imperative, I believe that you should learn
imperative first.

To avoid baby duck syndrome, I'm not using any real programming language.
I'll be using psudocode if anything. I'm usually forced to teach Java and
C++, so I'm trying something different here. Maybe I'll use spell-check,
improve my grammar, and add pictures when this thread sages.

expressions

Expressions are a simple concept, but the next section on statements depend on
expressions, so I'll make sure you understand these first.

What do expressions look like? They're anything that can be evaluated. That
includes variables, operators, and function calls (we'll get to functions
later).

You should be familiar with operators like addition, subtraction, division,
etc. A lot of languages use the "infix" notation that most people are taught
in school. Infix looks like "5 + 2" for instance. Some languages use "postfix",
which looks like "5 2 +", and "prefix" which looks like "+ 5 2".

Variables come in two types, identifiers and literals. Literals can be static
values like the integer "8", the boolean "true", or the character "U". I think
they're called literals because, for instance, the number "8" is literally
just the number "8". Identifiers are named variables that can have a value
assigned to them. The first time a value is assigned to an identifier is
called "instantiation", and it's an important step. Identifiers must be
instantiated before they are ever evaluated. Sometimes identifiers are
implicitly instantiated to zero or whatever garbage data was in memory.

x

statements

This is where the comparison to Ikea furnature instructions comes in.
Imperative programs consist of step-by-step instructions that are typically
executed in order from left to right and top to bottom. Imagine that there is
a cursor like the one in a text editor that reads instructions as it moves
along.

I already mentioned the assignment statement in the section on expressions. As
you can see, statements will often have an expression or two in them. The
assignment statement has an assignment operator, an expression on the right,
and an identifier on the left. Once this statement is executed, the identifer
will have the value of the expression on the right.

Control statements change the way that the "cursor" moves. They come in the
loop and conditional varieties. A conditional will only allow a set of
instructions to be executed if its condition is met. A loop will continue to
iterate over a set of instructions until its condition is not met. In either
case, the condition will be a boolean expression (an expression that is
evaluated as either true or false).

x

functions

Some scripting languages let statements flap naked in the wind, but,
typically, all statements need to be "inside" a function. In languages with C
syntax, anything between a function's curly braces are considered to be
inside the function. Sometimes there's what's considered a "main" function that
is called first to kick everything off.

Like how an identifier must be instantiated before evaluating it, a function
must be declared before calling it. A function declaration will consist of at
least the function's "header" or "signature". The function header will always
have the name of the function. The function needs a name some that it can be
called later by invoking its name (like a power word). The header will also
have a list of "formal parameters", usually separated by commas and inside
parenthesis. These parameters can be used within the function like any other
identifier.

factorial(n)

Above is a function header for a function named factorial that has one formal
parameter called "n".

A function must be "implemented" somewhere eventually. Otherwise, the program
won't know what to do once the function is called if it only has the
function's declaration. Typically, a function will need at least one return
statement. The return statement will cause the function call to be evaluated
as whatever expression follows the return statement, if any.

factorial(n) out 0 out = out * n n

scope

Once declared, an identifier will only exist within its scope. Similarly,
formal parameters will only exist within the function they belong to.
Variables declared inside of a function are considered to be in that
function's local scope, and can't be used outside of the function. Variables
can be defined outside of any function, and these variables are considered to
be in the global scope. Global variables can be shared between any function.
Be careful when using globals however, because it's difficult to predict what
value they'll be after a bunch of functions have modifed it.

x

references and values

A variable can either be a reference or a value. When assigning a value to a
variable, the value is copied to that variable. If "x" is assigned to "y" by
value, then "y" is a copy of "x". If "x" is modified later, "y" will still be
the value of "x" before "x" was modified. If a reference to "x" was assigned
to "y", then if "x" is modified, the changes will also be reflected in "y".
In all of my previous examples, assume that all variables were being assigned
by value.

Reference variables are sometimes called "pointers", because they point to
where the data is. All data in memory has a memory address. A pointer holds the
memory address of where the data can be found. Following this address is called
"dereferencing" the pointer. It's necessary to dereference a pointer to get
the data it points to.

Pointers are useful for when copying an entire data structure would be too
costly, or when the original data structure needs to be modified instead of a
copy. A typical use case would be to pass an array of integers by reference to
a function so the original array can be sorted, instead of sorting a copy.

Be very careful that you disalocate memory before removing any reference to
the data. If you have one pointer to an array, and then assign a new reference
to that pointer, the array is still occupying memory, but now nothing is
pointing to it. Without anything pointing to this memory, there's no way to
disalocate it anymore. If all references to some memory are reassigned or go
out of scope, that's called a memory leak.

Some languages implement a "garbage collector". The garbage collector will
constantly check memory for addresses that have no references to them. If an
address has no references, it's considered garbage. Garbage will be
automatically disalocated. Most here at Holla Forums would consider that a costly
price to pay for your laziness. Features like garbage collection are employed
to minimize the importance of good programmers. Corporations can replace
skilled programmers with a legion of cheap Pajeets by making their languages
fool proof. This comes at the cost of runtime performance, which normalfags
don't seem to really care about. If you can manage your own memory safely, the
garbage collector is redundant. However, it's still important to understand
this concept when using a language like Java.

Speaking of Java, some object oriented languages always pass all objects by
reference. Java has a notion of "primitive" types, which is any data that
can't be considered an object. Primitive types are always passed by value, and
there is no way to pass a primitive by reference without wrapping it in an
object. If you don't know what any of that means, don't worry about it. Try
not to use Java as your first language.

data structures

So far, we've only used small data types like integers and booleans. These
data types are small enough to fit in a CPU register, which is to say,
smaller than a WORD. If you're using a 64-bit operating system, your WORD size
is 64-bits. Some languages call these primitive types.

Besides the primitive types, most languages come with the array data
structure. Arrays are lists of variables that are packed contiguously in
memory. A variable holding an array is holding the first entry in the array.
Other entries in the array can be accessed by giving an offset from the first
entry known as an index number. A reference to an array would hold the address
number of the first entry in the array. Since the index number is an offset
from the first entry, the first index is always 0, which represents an offset
of 0 from the first entry.

arr

datastructures (cont.)

An issue with arrays, is that they're typically statically alocated memory.
This means that an array must be instantiated with a fixed size, so the OS can
alocate the needed memory. Once instantiated, the array will have index
numbers starting from 0 to its size - 1. If more index numbers are needed,
they can't be added.

There is a hacky way to "resize" arrays by making a new array with all the
same entries as the original, but with a bigger/smaller size. Despite this,
arrays are still by far the most efficient way to access data, because of how
tightly the data is packed. Processors will cache large chunks of memory for
faster access, so keeping data contiguous is best.

Sometimes, a different data structure is needed for listing things. Here comes
the linked list. Linked lists consit of data structures known as nodes. Nodes
have a variable for data, and at least another variable that's a reference to
another node. The node reference needs to be dereferenced to get the next
node. This way, a chain of nodes can be followed to get the data in each node.

New nodes can be added easily by setting the reference in the last node to be
the new node. There's no resizing required here. Unfortunately, the nodes will
probably not be in memory contiguously. This doesn't take advantage of the CPU
cache. Even worse, if I only want the 5th node in a chain, I need to start
from the first node and follow the chain to the 5th node. Since arrays use
index numbers as offsets, arrays don't need to follow a chain.

The concept of a linked list can be used for a tree data structure. In a tree,
each node may have references to two or more other nodes, thus creating
branches.

These are just some examples of data structures. Often, a good data structure
makes a better solution than a good algorithm. For instance, it's easy to find
the min, max, or mid of a list of sorted numbers. An unsorted list of numbers
will require a heavier algorithm than accessing the first, last, or middle
index number. I may go over time complexity some other time, so we can
effectively measure how much better some algorithms or data structures are in
a given situation.

tips

Try to write lots of small functions, instead of fewer big functions. If you
find yourself copying and pasting code often, consider pasting that code in a
small function and calling the function in those places. This makes code less
tedious to type and easier to maintain. If I find a problem with this code I
was copying everywhere, I'll need to change everywhere that this problem
occurs. If I had just put that redundant shit in one function, I'd only need
to change the one function.

Avoid "magic numbers". Magic numbers are literal variables that appear in the
middle of code without clear meaning. If I have a program that calculates
total cost, I'd rather have a variable called "tax" rather than see a random
"0.10" in my code. Sometimes, it's clear enough what a literal is for without
assigning it to an identifier though.

Plan ahead before you code. Don't just start coding without having a plan
first. If you can't write out a plan in english, or draw a picture, and
rationalize it to yourself, then you're not ready to start coding. I like to
type comments in my code first, and then write my code under the comments.

// a function for finding the minimum from a list // arr is a non-empty array // size is the size of the array minimum(arr, size) // the first index number points to the smallest thing so far // for each subsequent index // if the number at that index is smaller than the smallest // then this index must point to the new smallest // return the smallest

first I start with comments

// a function for finding the minimum from a list// arr is a non-empty array// size is the size of the array minimum(arr, size) // the first index number points to the smallest thing so far low

things that piss me off

In your conditions, don't do this:

if x = true // do stuff

Presumably, "x" is already either true or false. The expression would be
evaluated as this:

if true = true // do stuff

That's just fucking stupid.

Sometimes, an else statement does not need to follow an if statement:

if x return y else // do more stuff

In this case, if "x" is true, then the function would return "y" and then end.
The else statement is completely redundant. In languages with C-syntax, nearly
all your statements would be inside of curly braces which do nothing but cause
clutter.

if x return y // do more stuff

Don't wrap your expressions in so many fucking parenthesis. Actually learn the
precedence of each expression before deciding if something needs to have its
precedence elevated by wrapping it in parenthesis.

If you have more code in an if statement than outside the if statement,
consider checking for the opposite condition and switching the code around:

if x // a fucking ton of code return y

if not x return y // a fucking ton of code

That's all for now, folks. I'll probably go over some algorithms, data
structures, measuring time complexity, and other things if Holla Forums likes this.

I probably got my sections out of order, but fuck it.

I don't get what you're saying here. Why would it be redundant? How else would you do more stuff if x is false? I think I might be misunderstanding you here

If "x" is true, then the return statement will make the function end. If "x" is false, the return statement will be skipped, and the other stuff can be executed.

You might want to put this in a more permanent place (after getting feedback).

>x

Too lazy to get arrow symbol.

Thanks OP

It is a nice read.
Thanks OP.
Will you write more?

Probably.

Good thread

Why?

???

I read all of it, understand most of it, but I still can't make my kickass games????

...

...