Intro to Computers
A von Neumann computer is a machine that can execute step-by-step instructions.The program (and the data the program
manipulates) is held in volatile and non-volatile storage.
Although slower than volatile storage, non-volatile storage does
not lose information when the electrical power is removed or the
computer is off. For speed, information is temporarily stored in
volatile storage while it is being processed by the CPU and saved
in non-volatile storage before the computer is switched off and
hopefully before it loses power.
The I/O hardware transfers information into and out of the
computer. The (wired or wireless) internet connection and touch
screen are examples of hardware that do both input and output.
Examples of input only devices are the keyboard
, mouse
,
microphone, camera, scanner, and gyroscope inside the handheld
smartphone or tablet that detects when the phone is rotated.
Examples of output only devices are the non-touch screen
, headphones, speakers, printer, and the
vibration motor inside a cell phone.
Text, video, programs and every type of information are always
processed by the hardware in binary digits form. Every
possible kind of information can be represented in binary digits
form— which are sentences containing an alphabet of only two
digits— 0 and 1. For example, the information which is the letter
‘A’ is represented in the ASCII standard by the number 65— which
is equivalent to 1000001 in binary digits. See the Binary Data
lesson for elaboration.
The hardware is dumb, unaware what the 1s and 0s represent, and
moves the binary data around as instructed by the steps in a
software program— i.e. all the intelligence is contained in the
program.
Even the instruction steps of a program (a.k.a. machine
code instructions) are stored as binary digits in the
hardware. For example, the instruction to copy some binary digits
(e.g. 1000001 for letter ‘A’) to a storage location, is itself
also a very long word of 0 and 1 digits (that is determined
by the address numbers for the source and destination storage
locations).
But humans don’t think in terms of cryptic words containing only
1s and 0s. We think at a much higher semantic level of
instructions that express what the program should accomplish.
Thus higher-level programming languages were invented.
Why Learn
Programming?
Robots
have started replacing repetitive, uncreative jobs that
humans currently do. Most uncreative jobs will probably not
exist by 2033. This is creating a global
financial crisis. Manual labor jobs transferred to Asia, but
Asians won’t forever work
for less salary than a robot.
Programs are written in the vocabulary and grammar of a
higher-level programming language, and are translated by running a
program called a compiler, which converts to the low-level
cryptic binary digits form that the hardware can run.
For now, it is only important to understand that for some programming languages the programmer must compile each (change to the) program before it can be run. Whereas, programs written in some other programming languages are automatically compiled (or interpretively “compiled”) Just In Time as they run. Typically, only statically typed languages must be precompiled.
There are many qualities for comparing types of programming
languages.
It is not necessary for the novice to fully comprehend the
remainder of this lesson. The following obtuse concepts should be
mastered over time.
The declarative property is where there can exist only one possible set of statements that can express each specific modular semantic.This definition of declarative is distinctively local in semantic scope, meaning that it requires that a modular semantic maintain its consistent meaning regardless where and how it’s instantiated and employed in global scope. Thus each declarative modular semantic should be intrinsically orthogonal to all possible others— and not an impossible (due to incompleteness theorems) global algorithm or model for witnessing consistency, which is also the point of “More Is Not Always Better” by Robert Harper, Professor of Computer Science at Carnegie Mellon University, one of the designers of Standard ML.
The imperative property3 is the dual, where semantics are inconsistent under composition and/or can be expressed with variations of sets of statements.
Applicative, nominal typing, namespaces, named
fields, and w.r.t. to operational level of semantics then pure
functional programming.Hyper Text Markup Language a.k.a.
HTML— the language for static web pages— is an example of a highly
(but not perfectly3) declarative language that (at
least before HTML 5) had no capability to express dynamic
behavior. HTML is perhaps the easiest language to learn.
For dynamic behavior, an imperative scripting language such as
JavaScript was usually combined with HTML. HTML without JavaScript
fits the declarative definition because each nominal type (i.e.
the tags) maintains its consistent meaning under composition
within the rules of the syntax.
A competing definition for declarative is the commutative and idempotent properties of the semantic statements, i.e. that statements can be reordered and duplicated without changing the meaning. For example, statements assigning values to named fields can be reordered and duplicated without changed the meaning of the program, if those names are modular w.r.t. to any implied order. Names sometimes imply an order, e.g. cell identifiers include their column and row position— moving a total on spreadsheet changes its meaning. Otherwise, these properties implicitly require global consistency of semantics. It is generally impossible to design the semantics of statements so they remain consistent if randomly ordered or duplicated, because order and duplication are intrinsic to semantics. For example, the statements “Foo exists” (or construction) and “Foo does not exist” (and destruction). If one considers random inconsistency endemical of the intended semantics, then one accepts this definition as general enough for the declarative property. In essence this definition is vacuous as a generalized definition because it attempts to make consistency orthogonal to semantics, i.e. to defy the fact that the universe of semantics is dynamically unbounded and can’t be captured in a global coherence paradigm.
Requiring the commutative and idempotent properties for the (structural evaluation order of the) lower-level operational semantics converts operational semantics to a declarative localized modular semantic, e.g. pure functional programming (including recursion instead of imperative loops). Then the operational order of the implementation details do not impact (i.e. spread globally into) the consistency of the higher-level semantics. For example, the order of evaluation of (and theoretically also the duplication of) the spreadsheet formulas doesn’t matter because the outputs are not copied to the inputs until after all outputs have been computed, i.e. analogous to pure functions.
C, Java, C++, C#, PHP, and JavaScript aren’t
particularly declarative. Copute’s syntax and Python’s
syntax are more declaratively coupled to
intended results, i.e. consistent syntactical semantics
that eliminate the extraneous so one can readily
comprehend code after they’ve forgotten it. Copute and
Haskell enforce determinism of the operational semantics and
encourage “don’t repeat
yourself” (DRY), because they
only allow the pure functional paradigm.
Turing-complete programming languages are capable of every
imaginable computation. The imperative language must support
modifying data (at infinite possible storage locations), and
unbounded recursion— i.e. the ability to invoke small programs
(a.k.a. functions) which can invoke themselves ad
infinitum.
HTML is not Turing-complete. HTML can be supplemented with a
Turing-complete language such as JavaScript.
C, Java, C++, C#, JavaScript, Python, PHP, Haskell, and Copute
are (comparable to) Turing-complete.
Statically typed programming languages enable the
declaration of the set of rules (a.k.a. invariants) that each type
of functions and data must obey. Consistent adherence to these
rules throughout the program is checked by the compiler when the
program is compiled, i.e. at compile-time. Untyped3
(a.k.a. dynamic) languages don’t check such rules at compile-time
(rules other than those implicit in the language grammar).
Typing carries the tsuris of making sure all the checked rules compile without error. Sometimes it is impossible and typing must be discarded (a.k.a. cast to the Top type4) in a portion of the program. Ostensibly either typing or sufficient unit tests are necessary to achieve large scale programs and modularity. Typing can be more declarative, because it automatically checks opaque2 imperativity and unintended semantics w.r.t. to the rules declared.
C, Java, C++, C#, Haskell, and Copute are statically typed.
JavaScript, Python, and PHP are not.
Objected-oriented languages enable the declaration of subsets
(i.e. a subtype with more rules and thus less members) for a
preexisting set of rules (i.e. for a preexisting type). This
enables preexisting programs to interopt
with new types of data without modifying the preexisting
program— a requirement
for S-modularity. For example, a program that operates on
the fruit data type, will (without alteration) also
operate on new subtypes of fruit such as banana,
apple, and orange.
Subtyping enhances modularity, but with the tradeoff
of less compositional degrees-of-freedom. Learning when to
use and not use subtyping is the art of becoming a master
programmer, but isn’t a prerequisite to get started with learning
programming.
Java, C++, C#, and Copute are statically subtyped. JavaScript,
Python and PHP are statically unityped3, thus not
statically subtyped. C and Haskell are statically typed, but not
statically subtyped.