Polyglot Redux

Programming Languages Notes

I’m sure my Miscellaneous Observations have been made before, but here is my list of most interesting languages:

JavaScript

My One True Love, supremely versatile & ubiquitous - the all-around, amazingly-powerful champ! It’s the #1 Most Active/Popular Language on GitHub.com for years running.

I hate to admit it, but for years I foolishly had nothing but scorn and derision for what is now, my favorite language.

ES6 has only increased my ~addiction~ love. While pure ES5 will always hold a special place in my heart, each time I use some ES6, I feel that radioactive spider-bite…

There were 4 factors which pushed me into the ES6 Camp:

  1. It’s fun. Seriously. There are tangible gains in beauty, clarity & productivity.
    • Subjective claims, you say? Let me show you a bit of ES6:
    • let expired = users.filter(u => Date.now() > u.trialDate)
    • Now you don’t have to pretend you know how to use Object.create or Object.defineProperty
    • See examples below
  2. As of July 2015, ES6 is an officially finalized standard now!
  3. Support is Effectively 100%*! … Ok, BabelJS is needed to patch your code so it’s ES5 compatible. Historically JS transpilers have been frowned upon. However, as of late (2014-15) things have changed as BabelJS has become a key enabler/driver of language advancement. Tons of companies including Microsoft & Facebook use it on some of the largest sites around.
  4. Latest versions of Node include the same V8 JS engine as Chrome v45, it’s v4.5

Examples

I’m going to show you what finally made me start drinking that ES6-flavoured KoolAid.

In my recent experience, ES6 helps you write code faster. To the point. Because code is more succinct, appreciably less brain power is needed to sift through and understand your old code (or that of a teammates).

I have regularly seen KLOC savings roughly of 20-50%. That’s like Kate Moss trim!

EcmaScript 5 vs ES 2016 - Demo: Classes, Destructuring, Sexiness

// /services/users.js
class Users {
  constructor(data) {
    this.users = data || [];
  }
  expired() {
    return this.users
      .filter(u => Date.now() > u.trialDate)
  }
}
  • No more tedious code to ‘extract’ and ‘check’ fields passed to a function. Cut to example add():
// /services/users.js
class Users {
  constructor(data) { this.users = data || []; }
  add({name, email, password}) {
    // Store pwd hash, We only need to define 1 explicit `var/let` - the other vars are 'defined' with the `{fields}` wizardry above ^^^
    let hash = getSha256(password);
    return http.post('/users', {
      'name': name,
      'email': email,
      'passwordHash': hash
    }).then(usr => this.users.push(usr)); // append user upon service response
  }
}

 

Jumping on ES6 can feel like going from:

huh

To

wtf

To

#winning

Just keep sifting through the new stuff. Check out string templates, auto this binding, more-sane inheritance…

Node.JS

Rust

Official Site

  • Pros
    • Imagine if there was a language as fast as C and as powerful as Python/C++, yet without the complexity/pitfalls that usually trap even the most skilled devs.
    • In fact I’d guess Rust is roughly as complex as the ES6 spec.
    • It includes a ton of extras:
      1. Essentially Rust transpiles from semi-dynamic syntax into pure C code!
      2. Including __all the best practices__ in C you would probably screw up on, I eventually always do.
        • Automatically you get:
        • Auto Memory management (no need for a slow garbage collector!)
        • Perfectly scoped Object ownership/locking (mutexting & context switching minimized)
        • Object lifetimes (automatically implemented*, and auto coded like you knew every edge case)
        • Prevent virtually all run time errors (seriously, your code-paths become explicit: you just can’t overlook a code-path)
    • Oh yeah, it throws in true language extensibility with a sensible ‘macro’ feature.
      • Need Comprehensions? Scala style? Done, and Like Python? Done.
        1. Too good to be true? Nah, It gets better:
        • Bleeding edge indicators (github.com stats) reveal Rust is highly competitive or even beating Go (Google’s hot-newish language)
          • About 4K More Stars than Go (currently around 12,200)
          • More total Contributors ( 2x! - 1,071 vs. Go’s 479 )
          • More forks ( 3X! - 2,343 vs. 765 )
          • Number of Open Issues, Loses by a hair ( 2,000 vs 1,730 from Go )
          • Pull Requests (Rust 70+ vs. Go’s 1)
        • I had to triple check the numbers too.
    • Other libraries are very stable due to the constructs & rules of rust.
    • Threading model usable by mere mortals
  • Cons
    • Decent web frameworks are relatively new, untested, and usually undocumented (though they are getting very impressive - as of March 2015).
    • Lots of early pre-1.0 breaking changes

Python

  • Pros
    • Overwhelmingly complete assortment of algorithms are already implemented in Python ( see: scilearnkit, numpy, matplotlib, pil/pillow, etc. )
    • Very Fun to write! Comprehensions and Decomposition are great features and make other languages seem just bloated!
    • Arrays, ‘Sequences’, Tuples etc. are relatively simple
# dummy code: defines a color + pixel-coord -
def pixel(x, y, r, g, b): return dict(x=x, y=y, r=r, g=g, b=b)
# Create a new pixel object and apply to set of vars
x, y, r, g, b = pixel(10, 20, 255, 255, 255)
# Now we can call pixel
  • Cons
    • Annoyingly, Python 2.x and 3.x are incompatible. The Great Schism continues, so many years later.
    • Some essential libraries are not nessacerily understood by some devs (numpy)

Haskell

  • Pros
    • Very rewarding when you finally memorize enough syntax to whip up comprehensions-based expressive patterns
    • You will learn mind-bending code patterns - often somewhat applicable to other languages.
  • Cons
    • Syntax & Patterns can be hard to get used to.
endless loop

SmallTalk-80

  • Pros
  • Cons
    • You will likely never use this language for anything. Zero projects. However it will have more of an impact on your coding style, faster than other functional languages… This should be in the pros list)

Work-in-progress (updated Dec. 2015)

Docker rocks. Boot2docker just sucks.

Overview

Updates November 2015

Boot2Docker

To everyone on OSX or Windows: Don’t let Boot2docker leave you with the impression that Docker sucks! It’s really just your antique OS.

  1. Docker is amazing, period.
  2. However it’s rough-around-the-edges, hackey utility, boot2docker - for OS X, Windows and old Linux Kernels - leaves a lot to be desired.

Issues

Boot2docker causes 99/100 headaches compared with using a native docker install locally. I should concede that it wraps several other complicated/flakey technologies: VirtualBox, x-platform Folder Sharing, and also the docker cli command runs in a network-client mode so, file copying, builds etc take a long time vs. running a native docker server. ============= Docker can currently only run natively on a Linux Kernel 3.4+ - and the current boot2docker vm actually runs v4. Bottom Line: Install the Latest Debian (w/ xfce or MATE) on your Mac/Windows box, … c’mon those games aren’t helping your code…

Boot2docker Key Commands

When you get error: ‘FATA[0000]’

  • Full error message:
    • FATA[0000] Get http:///var/run/docker.sock/v1.18/info: dial unix /var/run/docker.sock: no such file or directory. Are you trying to connect to a TLS-enabled daemon without TLS?
  • Solution: You need some info from boot2docker
    • Run this to get the 3 needed shell environment variables:
boot2docker shellinit
# Copy & paste the exports into the current shell, & retry $(docker info)

Get Docker Server IP Address

boot2docker ip

Now your app on port 3000 is available at something like: http://$(boot2docker ip):3000/

Boot2Docker Quick Start for OS X

  1. In a terminal on your brew able Mac:
brew install boot2docker
boot2docker init
boot2docker up
JavaScript Magic

[ Work-in-progress, Includes Future JavaScript Article Ideas ]

This post is geared to modern browsers and Node.JS/iojs.

Imperative vs. Recursive vs. Functional


// Imperative: The Fastest ( + very simple, no new pointers or excess allocs ):
function fib(n) {
  var a = 1, b = 1, c = 0;
  for(var i = 1; i < n-1; ++i) {
    c = a + b;
    a = b;
    b = c;
  }
  return b;
}

// Recursive: (FIREFOX or BABELJS Only) ES6 function definition with
//  parameter defaults used to set initial (internal/recursive) values
function fib(n, current=0, a=1, b=1, c=0) {
  current++;
  c = a + b;
  a = b;
  b = c;
  return current >= n ? b : fib(n, current, a, b, c);
}

// Text-book-Bad Example - poor function scope w/ multiple mutable external values
function fib(n) {
  if (!arr) { var arr = [1,1]; n=n-2; };// Bad
  if (n===-1) {return [arr[0]];}
  if (n===0) {return arr;}
  var proc = function() {
    --n;
    arr.push(arr[arr.length-1] + arr[arr.length-2]);
    return (n===0 ? arr : proc());
    // Bad: inner recursive function not needed, hint: variables used are from parent function scope
  };
  var ans = proc();
  return ans[ans.length-1];
}

Promises: Awesome!


// Example Using bluebird Promises and it's
var Promise = require('bluebird'),
    fs = Promise.promisifyAll(require('fs')),
    less = Promise.promisifyAll(require('less'));

function writeFileData(data) {
  return fs.writeFileAsync('/tmp/output.css', data);
}
// Bluebird makes something like this perhaps uncomfortably simple and succinct:
fs.readFileAsync('./style.less') // Call promisified readFile()
  .then(less.renderAsync)         // Hand off to less.render
  .then(writeFileData);      // Function to recieve the css contents (1st parameter)

  1. While, native ES6 Promises are great, I prefer the robust Bluebird Promise Library.
  2. Library or not, modern browsers have supported Promise for years.
  3. Promises can be utilized without crazy patterns - implicit deferred is preferable.
  4. $q just sucks just use bluebird, see above.
  5. Worth mentioning: Bluebirds Benchmarks are best-case tests, so take note if doing crazy fancy promise chains

Java vs JavaScript

Rate Limiting / Debouncing / Throttling

  1. In JavaScript David Walsh implemented debounce in less than 20 lines!
  2. In Java, JDebounce, an library which is a lot more complicated, at ~500+ lines.
  3. _ Comparing the two: _
  4. The JavaScript is fast & uses first-class functions to achieve brilliant simplicity.
  5. Whereas the Java has many more moving parts, annotations are used to apply behaviour at compile-time, and there’s a ton of XML, just for funsies!

Inversion of Control Techniques

Work-in-progress

Docker Firewall Setup

Setup Docker Host Firewall

  1. Debian/Ubuntu Server is assumed
  2. Designed to run on Docker Host Server

Install Requirements

# Ultimate Firewall Needed
apt-get update && apt-get install -y ufw nmap curl

Get your Internal & External IP Addresses

# Get your IP Addresses, simple output:
hostname --all-ip-addresses

# OR use ip tool, example:
ip addr

Firtewall (UFW) Setup - Example Cmds

ufw logging on # on=low - medium might be better for diagnostics
ufw logging medium
# First, block all the things
ufw default deny incoming

# REQUIRED: CHOOSE *ONE* OF THE FOLLOWING DEFAULT OUTBOUND RULES:
ufw default deny outgoing
ufw default allow outgoing


# Allow and log all new ssh connections,
ufw allow log proto tcp from any to any port 22
## Allow http traffic (w/o explicit logging)
ufw allow out on docker0 53/udp to 172.17.0.1/16
ufw allow out on eth0 to any port 53
ufw allow out on eth0 from 0.0.0.0/0 to any port 80 proto tcp
ufw allow out on eth0 from 0.0.0.0/0 to any port 443 proto tcp

# Verbose: ufw allow proto tcp from any to any port 80
ufw allow 80/tcp
ufw allow 443/tcp
ufw allow log 22/tcp
ufw limit ssh # Basic Rate limit 4 SSH brute force mitigation

# Set your ext IP
export EXTERNAL_IP=123.123.123.123
# Update docker IP if needed
export DOCKER_IP=172.17.42.1
# Forward tcp 8080 traffic to  Dockerized App
ufw allow proto tcp from $EXTERNAL_IP port 8080 to $DOCKER_IP port 3000

Enable / Start Firewall

Be Careful, Don’t Lock out your SSH port (sshd defaults to 22)

ufw --force enable

ufw reset

Test Your Firewall

Important: USE A REMOTE IP ADDR/LOCATION

# Verify dependency
apt-get update && apt-get install -y nmap

# Set scan target
export TARGET_HOST=123.123.123.123

# Example Scan Commands:
# Fast open port check
nmap -p 1-10240,27017 -T5 $TARGET_HOST
# Thorough scan
nmap -p 1-10240,27017 --open -v -APN $TARGET_HOST
# Svc Inspection
nmap -p 1-10240,27017 -O --osscan-guess $TARGET_HOST

DONE! Now you should see ONLY the ports you configured!

Docker server Setup

Docker Host Server Setup

Basic Monitoring Tools

# Debian/BSD Requirements / Updates + monitoring tools: atop & htop
apt-get update && apt-get install -y vim-nox git-core curl atop htop build-essential libssl-dev linux-image-amd64 linux-headers-amd64 sudo

# OSX, Debian & RHEL: Host OS Tuning
sysctl -w vm.max_map_count=262144

# Updates Profile init scripts before appending new scripts below
mkdir ~/backups
cp ~/.bash* ~/backups/

# Debian/BSD:  Append Shell Environment Shortcuts + XTERM Colors
curl -o- https://raw.githubusercontent.com/justsml/system-setup-tools/master/modules/vim-update.sh | bash

curl -sSL https://raw.githubusercontent.com/justsml/system-setup-tools/master/home-scripts/.bashrc >> ~/.bashrc
curl -sSL https://raw.githubusercontent.com/justsml/system-setup-tools/master/home-scripts/.bash_aliases >> ~/.bash_aliases
# Read into current shell (login steps already missed the aliases file)
source ~/.bashrc

# Docker pre reqs
# sudo apt-get install -y linux-image-virtual linux-image-extra-virtual
# Install Docker, straight from the horses mouth
curl -sSL https://get.docker.com/ | sh

Only for SELinux Enabled Systems

# SELinux fixes (optional)
# chcon -Rt svirt_sandbox_file_t /mongodb
# chcon -Rt svirt_sandbox_file_t /elastic

Simple Database Setup/Startup

MongoDB v3 Server

mkdir /mongodb
docker run --name mongo -p 27017:27017 -v /mongodb:/data -d mongo:latest bash -c 'mongod --logpath /data/mongodb.log --logappend --dbpath /data/data --storageEngine=wiredTiger'
mkdir /elastic
docker run --name elastic -d -p 9200:9200 -p 9300:9300 -v /elastic:/data elasticsearch bash -c 'elasticsearch --cluster.name elastic_cluster --node.name elastic01 --path.data /data/elastic-data --path.logs /data/elastic-logs '

You just lit up 2 database docker instances!!! If it were any easier, I’m pretty sure you couldn’t invoice for it.

Package up your NodeJS/Ruby/Python/Web App

  1. Add a blank file named Dockerfile in your project root.
  2. (Optional, Recommended) Add a .dockerignore using .gitignore rules to exclude large non-essential paths. By default all project files are included.

Create a Dockerfile

# Example for NodeJS
FROM node:0.12
EXPOSE [3000]
COPY . /app/
WORKDIR /app
RUN apt-get update \
	&& apt-get dist-upgrade -y
RUN ["npm", "install"]
# Overridable Command
CMD ["npm", "start"]

It’s easier to show how to start using the Dockerfile and demonstrate the results via console (see commands below).

In terminal, cd to your project folder and run the following build command everytime you deploy changes - or want to change/upgrade OS or Env config)

docker build -t app-name-here .

Docker Commands to Learn

Build Docker Image Every Deploy/Change

docker build -t app-name-here .
docker run -d --name webapp01 -p 3000:3000 --link mongo:mongo --link elastic:elastic app-name-here

Run Interactively (non-daemon, in terminal)

docker run -it --name webapp01 -p 3000:3000 --link mongo:mongo --link elastic:elastic app-name-here bash

Delete Container Instance or Image

Important: Any data not stored on the mounted volume path will be lost!!

# Delete Image
docker rmi -f app-name-here
docker rm -f webapp01
# now re-run your `docker run...` from ^^^
# So for example, let's kill your db instances above, run: ( start with something like `docker stop {mongo,elastic}` )
docker rm -f mongo elastic

Tag Cloud

Jekyll::Drops::SiteDrop