Comparative Programming Language

Taught by Professor Toby Donaldson

History of Programming Languages

Programming languages are developed organically based on the developer's needs.

The three most influential languages were Fortran, LISP, and COBOL

Fortran (1957), stands for Formula Translator, was the first language to incorporate variables, before this it was machine languages. John Backus developed this with engineering and science users in mind. Fortran is still actively used today.

LISP (1958), stands for list processing, developed by John McCarthy is a language with a simple core, developed with math users in mind.

COBOL (1950's), asscoiated with Grace Hoppe, for business users, stands for Common Business Oriented Language.

we briefly mentioned the below languages

Algol (1960's), was another pioneer language, but was not heavily adopted.

SmallTalk (1970's), asscoiated with Alan Kay and XEROX parc, help popularized object oriented programming in North America. inspired by Simula and LISP

Prolog (1970's), developed with logic in mind, for AI and parsing English, syntax is based on first order logic.

Ways to Organize Languages:

Declarative vs Procedural

Declarative languages like markup, SQL, prolog.

Procedural languages like Von Neuman (C Ada Fortran) , Object Oriented (java, smalltalk), or Script (python ruby perl)

Compiled vs Interpretted

Compiled programs (C, Fortran) are very efficient, compilers can find errors before program is run, and it can do static analysis (checking something against the soruce code)

Interpretted programs (like Python, LISP) are good for fast development, allow codes to be created on the fly, but it is slower than compiled codes


Golang

Developed at Google, a way to replace C++ for writing server, the developers thought C++ took too long to compile.

Go compiles fast, comparable to interpret languages.

Concurrency Support has “Go routines” that are lightweight processes to handle concurrency tasks.

No Exceptions Go relies on explicit error codes return from functions. Whereas error handling in C++, java, leads to convoluted code that treats too many situations as error. Go forces you to explicitly deal with error. (No error you would return nil)

Lightweight typing Go lets you leave off the type, but is still statically typed

Novel use of interface Go does not have classes,but still object oriented by introducing interface

Closure allows passing functions (lambda functions)

Go has really modern set of libraries like fmt thats relevant to web dev.

Go run lets you compile and run in one step

if variables or functions are Uppercase, then its public, (other languages have a explicit public for these things)

Go has a built in formatter (Go fmt) that conforms your code when you save

the := initializes and gives values to a variable , the type is inferred

name := ""

the above is similar to var name string, name = ""

var name string
fmt.Scanf("&s", &name) 
// needs an address of name because Scanf writes in value at the name address

Go uses for for both for and while like in other languages

the for loop pattern is

for i := 0l i < 10; i++ {
    //do stuff
}

//range loop
s := "some string"
for i,c := range s{
    //do stuff
    fmt.Printf("s[%v] = '%v'\n", i, c)  // the %v gets the unicode value, %c gets the char 
}

the Go compiler says its an error if a variable is declared but not used, the aim is to make things practical by taking out superfluous variables

because of this, the _ keyword is a blank variable in Go, it allows the compiler to run if you dont care about the declared variable.

array is immutable in Go, problem is the length is part of the type.

slice is a dynamic array , builds ontop of an array

var sl []int = []int{1,2,3} gives starting values to the sl slice

alternatively sl := []int{1,2,3}

we can use the builtin keywords append and make to generate slices

map is declared like var notes map[type of key] type of value the string is the type of the key, and int value

Go returns a value 0 if a key is not there in the map. different from how other languages does it.

panic is for error checking, and panic immediately ends the program

Go didn't add destructors, instead, the defer keyword allows statements to run after function ends, effectively Go programmers adds deferobject.close()

Go does not have inheritence, instead, it has a concept of embed. so if structA has structB inside, and structC. StructA is of a separate type than structB and structC.

need to understand how Go methods and functions interact with method sets

in Go, some key words are bound at language design time, and can't be unbound, like For loop


Compile Time Binding (Static Binding) vs Runtime Binding (Dynamic Binding)

different languages decide on the binding differently, runtime binding gives more flexibility, while compile time binding lets you find mistakes much faster.

Go, C++, Java, Haskell -> are all compiled time binding languages,

Javascript, Python, Ruby, Scheme/Lisp -> are all binding done at runtime.

the bindings are not all distinct like this, all languages implement a mix of both

Memory Allocation

Static -> compile time - eg. global variable , the original Fortran only had static memory variables. but problem is, when we start using functions, we want functions to have their own local variables. so static allocated programs had a hard time accomodating for local variables. which leads to...

Stack (or call stack) -> is created in run time, each stack contains stack frame that stores the local variables at the current function.and automatically pop when the function exits.

Heap ( dynamic)

Summary Of Go easy language for getting a job, write a web server etc.


Scheme

Though Scheme has loop feature, the course only studies recursion.

Distinctions among symbols, variables, functions and lists: - x : variable x - 'x : symbol x - (x parameter1 parameter 2) : function x with 2 parameters - '(my dog has fleas): a list of 4 elements which are symbols

Example:

(min 3 1) evalutes to 1

'(min 3 1) evalutes to (min 3 1)

List Processing

In scheme, we can think of lists like stacks with main operations: car as peek() that returns the first element, and cdr as pop() that returns the rest of the list.

Example: (car '(+ 1 2 3) ) evaluates to '+' sign

Note that '+' sign returned from the above example is not considered the addition operator but just a symbol. Thus, using the returned '+' to feed a calculation pipe line will cause errors:

(+ 1 2) evaluates 3

((car '(+ 1 2 3)) 1 2) causes errors

Scheme uses the lazy evaluation technique in evaluating logic operations and and or. Scheme stops evaluating and at the first found false argument; and stops evaluating or at the first found true argument. A similar fearture can be seen in C.

Scheme uses cond or if to branch the flow.

(define len ;; this is taught in class
    (lambda (lst)
        (cond
            ((null? lst) 0) ;; base case
            (else 
                (+ 1 (len (cdr lst) ) ) )
        )
    )
)
By @Andy Yao in
Tags :