Software Languages

This attempts to document languages not as how they work individually, but instead as how they deviate from a standard core programming language. It starts with the most common language features and functionality, and then shows how certain languages differ.

We should consider the following languagese: C, C++, java, javascript, python, typescript, golang, bash, Ruby, Rust

Operators

  • almost all languages have very similar operators.
  • comparison: <, >, <=, >=, ==, !=, etc.
    • in C, C++, these return ints, not a boolean.
    • In Python, it also supports the “is” and “not” keywords.
    • In javascript, it also support ===, and !==, which is checking the type of object as well.
  • Assignment:
    • most languages support +=, -=, *=, /=, %=, |=, ^=, ~=, etc.
  • Increment, decrement:
    • almost all languages support ++ and – for incrementing/decrementing integers.
    • python is the exception, it does not support ++ or –, it supports += and -= though.
    • all support += and -=

Types

  • the way types are handled is split along patterns:
  • statically typed languages:
    • C, C++, java, golang, Rust
    • optionally typed: Scala, Kotlin, Python, Typescript.
    • Split by two patterns, types before or after variable names:
      • types before variables and functions are used in C, C++, java
      • types after variables are used in Python (unenforced), Typescript, Golang, Rust, and Scala.
        • delimited with a colon: Scala, Rust, Python, Typescript
        • delimited with a space: Golang
  • dynamically typed languages:
    • javascript (but Typescript adds types)
    • python (python supports type declarations but does not enforce them).
    • these do not declare the types of variables, and usually they can be re-assigned to completely different types.

Generics

  • Using <>: java, Rust,
  • Using []: Scala, Golang
  • Unsupported: older Golang, C, C++

Loops

  • all languages support keywords “for”.
    • standard for loop: for (exp0; exp1; exp2) {…} is supported by most languages, with some deviations:
      • golang does not require the parentheses.
      • python does not support that format.
    • python standard for loop: for x in range(n): …
  • almost all languages support a lowercase “break” or “continue”.
  • only golang does not support “while”, it uses for as its while loop.
  • for with collections is supported in most languages:
    • java: for (int x : coll) {…;}
    • Python: for x in arr:…
    • golang: for index, x := range coll {…}
    • C, C++: unsure.
    • javascript: for (let x in coll) {…;} for (let x of coll) {…;}
      • “in” iterates over indexes.
      • “of” iterates over values.

Code Structure

  • Most languages use squirrel brackets to establish blocks. Python and F# deviate from this, using indentation instead.
  • Semicolons are:
    • required in C, C++, java, Rust
    • recommended in javascript and typescript
    • allowed in Golang
    • not used in Python, Scala, F#, Ruby

Lambda Functions

  • Almost all languages allow functions to be first class citizens, objects, so they can be assigned to variables and passed around. Older versions of java (< 1.8) did not.
  • Some support a short-hand form of functions, lambda expressions:
    • java: () -> {…;}
    • Python:
    • javascript, scala: () => {…}

Switch Statements

  • most languages support the standard: switch (expr) { case 0: …; break; case 1: …; break; default: …; }
  • some minor deviations:
    • golang doesn’t require the parentheses, nor semicolons.
    • some languages don’t require the “break” statements, but most do.
  • Ruby uses “case”, “when”, and “end”. Break is not needed.
  • Base uses “case” and “esac”, conditions are string patterns followed by “)”, and need “;;” to close them.
  • Python does not have a switch statement, you can use if, elif, else instead.

Constants

  • In C, C++, javascript, golang: const keyword prefix
  • In java, scala, groovy, jython, jruby, etc.: final keyword prefix. Allowed in arguments too.
  • In python, bash: not supported.

Objects, Classes

  • not supported in C, but you can use structs as args in functions.

Variable Protections

  • Most languages support them in some manner.
  • Python does not enforce them, they are accomplished by the convention of prefixing variables with underscores.
  • Javascript also has weak enforcement, using underscores to indicate a private field.
  • Rust supports “pub” instead of public. It tends to be very terse.

Comments

  • fall into two categories:
    • Using “//” and “/* */”: C, C++, java, javascript, typescript, Golang, F#, most squirrel bracket languages.
    • Using “#”: Python, bash.

Compilation

  • System Languages: Compiles to OS bytecode: C, C++, Golang, Rust,
  • Compiles to a virtual runtime bytecode: java, scala, groovy, jython, jruby,
    • most system languages can also be compiled into the WASM format.
  • Interpreted or Scripted Languages: Python, Ruby, javascript, Lua, bash

Garbage Collection

  • Falls into two categories:
    • manually done: C, C++
    • Garbage collected: everything else.

Use of Pointers, Passing by Value or Reference

  • C, C++, Golang, and Rust support pointers. So you have explicit control over passing things by value or by reference.
    • Use “&” to get the memory address of a variable, which is a pointer.
    • C, C++, pointer types: * or: *
    • Golang pointer types: *
    • de-reference a pointer variable, in all languages: *
  • In java, primitives are always passed by value, and objects are always passed by reference.
  • In most scripting languages, passing by reference is normal.

Pre-processing

  • C, C++ support pre-processors, other languages do not typically use that.

Hoisting, Code order requirements, finding code

  • In C and C++, the compiler is not intelligent enough to use code before it has been declared. You must declare a definition of variables and functions before they are referred to. This is why you need to #include the header files from imports.
  • In almost everything else, the compiler is able to find and use code as it is called, even if its definition comes later in the file or in a completely different file.

Declaring Variables

  • Without initialization:
    • C, C++, java: ;
    • Go: <var|const> ;
    • Rust:

Naming Conventions

  • Variables:
    • C, C++, java, Golang: lowerCamelCase
    • Python: snake_case
  • Functions:
    • C, C++, java: lowerCamelCase
    • Go:
      • public: UpperCamelCase
      • private: lowerCamelCase
    • Python: snake_case
  • Packages, modules, directories…

Strings

  • Single quotes are characters: C, C++, java, Golang
  • double quotes are strings in every language.
  • single quotes are also strings: Python, Ruby, bash, javascript, typescript
  • interpolated strings:
    • java: more recently supported with triple back-ticks
    • scala: supported with pipes and triple quotes.
  • are primitives: in golang
  • are objects: in java and all higher level (scripted) languages.
  • C, C++ don’t have a string type, you must use arrays of characters: char s[] = “foo”; can still use double-quotes though, and don’t need to declare the size. hence it is mutable. They end with \0, the null terminating character. That counts toward its size.
  • in languages where strings are objects, they tend to have a lot of methods built in. In other languages, string functions tend to be in a separate package, like “strings” (golang), or in #include <string.h> in C, C++

Associative Arrays

  • aka dict, maps, hashes.
  • Golang: x := map[string]string{“foo”: “bar”}
  • C, C++:
  • java: Map<String, String> x = new HashMap<>();
  • ruby: x = {‘a’ => ‘x’, ‘b’ => ‘y’}

Regular Expressions

  • Using the /…/ syntax: javascript, ruby,
  • Other languages have a class for it.

Keywords not, and, or

  • supported in Python, Ruby,

Functional Programming Patterns

  • supported in java > 8
  • Python has some support with lambdas.
  • Golang has limited support.
  • Scala, Haskell, Kotlin, Ruby all have very strong support for functional programming techniques.
  • Javascript has decent support, has the forEach method.

Null Type

  • In Golang, Ruby: nil
  • In java, C, C++, javascript: null
  • Javascript also supports “undefined”

What is considered falsy

  • Javascript is flexible: undefined, null, empty strings, 0, false
  • Python is the only language that uses capitals for their boolean types: True, False
  • C, C++, the expression must produce 0 or an integer that is not 0
  • Java: the expression must produce a boolean

Boolean Types

  • Java: boolean
  • Golang: bool
  • C, C++: no built-in type, <stdbool.h> adds the type but it’s actually an int 0 or 1.
  • Python: bool, True or False

Declaring Functions

  • javascript: function name() {…;}
  • java: [private|public|protected] [static] [synchronized] <type|void> name() {…;}
  • C, C++: <type|void> name() {…;}
  • golang: func name() [type] {…}
  • Rust: fn name() {…}
  • Python: def name():
  • Ruby: def name or: def name( args )
  • bash: function name {…} or name() {…}

Arrays

  • C, C++: int x[] = {1, 2, 3};
  • java: int[] x = {1, 2, 3};
  • golang:
    • array: var [size]int x
    • slice: []int x = {1, 2, 3}
  • python: x = [1, 2, 3]
  • rust: let mut arr: [i32, 3] = [0; 3];
  • javascript: const x = [1, 2, 3];
  • in practically every language, array members are accessed like: arrName[i]
  • Array Literals:
    • declared with {}: C, C++, java
    • declared with []: Python, javascript
  • Constant Size:
    • C, C++, Golang, Rust, java, most system languages.
  • Dynamic size:
    • Golang slices, Python lists, java collections like Lists.
    • In javascript you can assign to indexes outside its current range and it just extends to meet it.

Code Structuring

  • There are three patterns:
    • Squirrel bracket blocks: most languages
    • Indentation: Python, F#
      • Tends to use four spaces as indentation.
    • Token based: Ruby, Bash
      • blocks end when a token is reached like “end”, “fi”, “done”, “esac”, etc.

Calling Package Functions

  • Ruby, C, C++: ::
  • Python: . (depends on the import statement used)
  • Java: not possible, must refer to the class’s static functions.

Instantiation

  • Using “new” keyword: java, C, C++, Go (optional, type is in parens)
  • Using static type’s new function: Ruby
  • Using type’s name: Python, javascript
    • implies there can only be one constructor. These languages tend to support optional arguments with defaults for functions/methods.

Support for Default Arguments, or function overloading

  • java: functions can be declared multiple times with different parameters.
  • Python, javascript: functions can be declared with default values for parameters.

Exceptions, Errors, try catch

  • Golang methods return errors, which can be ignored or re-thrown. It also supports panic, and try catch
  • java, supports checked or unchecked exceptions. functions can declare they throw some exceptions. Supports try catch finally. Supports try with resources.
  • Python: errors are always unchecked. Supports try and catch.

Scope Rules

  • most languages say a variable exists within its code block, class, or globally.
  • javascript allows “var” variables to exist after their block finishes.
  • Python and bash also allow their variables to exist after their block finishes.