Stephen Brennan Tutorial on writing a shell

After learning to program in C language, the next best thing to attempt will be writing some small utility in C. I landed upon a great tutorial (https://brennan.io/2015/01/16/write-a-shell-in-c/) that taught how to write a shell with some builtin utilities in C. I tried that tutorial today and saw how to build a shell.

That's the best way to learn about the init, fork, parent process, child process and the shell loop itself. As a side-effect, I also setup and used CLion on my computer.

Deis Illustrated Guide to Kubernetes

https://dl.dropbox.com/s/jqh03qsqpbtf2pm/deis_kubernetes.png

Deis had published an easy to understand version of Kubernetes guide calling Children's Illustrated Guide to Kubernetes

It explains Containers and the need for container management pretty well. It focuses on Kubernetes. There are other container orchestration systems like DCOS that provide the same capabilities of container orchestration as explained in that guide.

The character rendering, which include, PHP app as a giraffe, Kubernetes as a ship captain, docker as whale, gopher as go lang app, elephant as postgresql app were great.

Runway - A distributed systems analysis tool by Salesforce

Diego Ongaro of Raft fame describes a tool that he has been working on at Salesforce. The tool http://runway.systems is intended to help the designers of distributed systems. The idea is, folks designing distributed systems can encode their encode their model, specify the states of the system, specify the invariant and run the simulations in the tool.

This tool will help in visualization and analysis of the distributed systems behavior under various conditions. Diego states that such a system would have been really helpful to him when, if it was available, when he was writing Raft.

In this approachable presentation, he illustrates the tool using.

Web of Stories - Donald Knuth

I am a Donald Knuth fan, and sometimes I strive to understand his lectures. Stumbled upon this website called webofstories.com that feature many scientists and carries extensive interviews with them, who reflect upon their life, their personal moments, their personal views on their achievements.

I watched the entire 3 hour interview with Donald Knuth and immensely enjoyed it.

One of the excellent moment was, when he shares his 2nd computer program, which was a learning tic-tac-toe. This was written for the IBM 650 Machine having just 10K bytes of memory.

http://www.columbia.edu/cu/computinghistory/650-2.jpg

Those days, the programs were written in punched-cards and a typical program would look something like this (location, instruction).

0001 0000010000
0002 0000000000-
0003 1000018003
0004 6100080007
0005 2400008003
0006 0100008000
0007 6900060005
0008 2019990003

Imagine writing an AI program in that. The difficulty of writing does not matter, just the possibility that it could be written and could be very was exciting, probably led Knuth to write it. This video shows his excitement when he shares that moment.

Other interview bits are interesting too. Knuth covers academia, maths, computer science, computer history, programming as art, typography, religion, his dates, his wife, his children and awards he has won. Many interesting things can be picked up.


"If it doesn't go well, so what, I tried, and I did it." - Donald Knuth on his thoughts, when delivering the lecture of "Science and Religion" at MIT.

Coconut Lang

With the trend in functional programming up, I noticed a new programming language called "coconut" that implements functional programing "style". This is written on top of "python", the coconut language scripts are compiled and translated to python.

For e.g, this factorial coconut program, will be translated to a valid python program.

def factorial(n):
    """Compute n! where n is an integer >= 0."""
    case n:
        match 0:
            return 1
        match _ is int if n > 0:
            return n * factorial(n-1)
    else:
        raise TypeError("the argument to factorial must be an integer >= 0")

You can notice the pattern matching style in the above program, which is not a syntax in Python. This program will then be converted into a valid python program.

Great many details can be found in the coconut-lang website.

Core Functional Programming Concepts

Found this introductory post on core functional programming concepts dealing with the subject succinctly. It is easy to approach functional programming, if we can recognize the following concepts held true by all the functional programs, and languages facilitating them.

  1. Functions are Pure

    • No side-effects, like printing something from the function.
    • When called with the same input, will always return the same output. We take that for granted, isn't it?
  2. Functions are first-class and are of higher order.

    • Treat function names as variables.
    • Toss function (names) as an argument to a function, and as a return value from a function.
  3. Variables are immutable.

    • Forget mutating variables in a program. If you want an updated value, create a new variable. When you are getting started with programming, you feel this is questionable. With experience under your belt, you start to prefer immutability of variables.
  4. Functions have referential transparency.

    • It follows from functions are pure requirement. The referential transparency requirement is about substituting the function call with return value, wherever the function is called, should not change the state of the program.
  5. Lambda Calculus

    • The mathematics behind functional programming. Take arguments and have a return valued. When evaluating multiple arguments, the function is evaluated one argument at a time, with result send to next one-arg-less function, kind of a tail-recursion. This concept is called currying.

Know Linux Version

New trick to know the version of your linux operating system.

cat /etc/*-release

Works fine!

# cat /etc/*-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=16.04
DISTRIB_CODENAME=xenial
DISTRIB_DESCRIPTION="Ubuntu 16.04.1 LTS"
NAME="Ubuntu"
VERSION="16.04.1 LTS (Xenial Xerus)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 16.04.1 LTS"
VERSION_ID="16.04"
HOME_URL="http://www.ubuntu.com/"
SUPPORT_URL="http://help.ubuntu.com/"
BUG_REPORT_URL="http://bugs.launchpad.net/ubuntu/"
UBUNTU_CODENAME=xenial

Rationale behind punishments

I stumbled upon a Explain Like I am Five Story which dealt with the rationale behind punishments. The topic of punishments is a complex one and needs balanced thinking. The author elucidated many reasons for which punishments are administered in society. We see the trends of those in both online and offline societies.

Punishments are administered for one of the following reasons.

  • Incapacitation

Is stopping somebody from doing an unacceptable behavior in the society again.

  • Restitution

Is getting something back for the victim of somebody who misbehaves, to compensate them for that which they've been deprived by the offender. Like charging fine and using it for taxes.

  • Retribution

Is like feeling of justice that deprived might get. Many of us think, this is the primary purpose for punishment. This is non measurable, but often paves way to other measurable impacts like incapacitation, restitution etc.

  • Rehabilitation

The purpose is to give the offender, time to reflect on the wrong doing, possibly empathize with the one affected.

  • Deterrence

Is about reducing the likelihood that misbehaviour will occur in the first place. The punishment is more for a warning to prevent a socially unacceptable behavior.

Many a social regulatory policies can be mapped to above concepts of negative reinforcements to prevent any undesirable outcomes.

Leslie Lamport on Teaching Concurrency

This post is a short discussion on the Leslie Lamport 's paper "Teaching Concurrency".

Lamport's basic premise is that understanding the system the most important part, and engineers often muddy their understanding with implementation details as soon as they start talking about programming languages suitable for concurrency.

He even challenges engineers to come up with the solution for concurrency problems without using "semaphores", "monitors", or any other construct that were invented and provided as a tool. Using those, he says, is like using the 'sort' to routine the language to implement a sorting algorithm.

The modern field of concurrency started with Dijkstra’s 1965 paper on the mutual exclusion problem. For most of the 1970s, one “solved” the mutual exclusion problem by using semaphores or monitors or conditional critical regions or some other language construct. This is like solving the sorting problem by using a programming language with a sort command. Most of your colleagues can explain how to implement mutual exclusion using a semaphore. How many of them can answer the following question: Can one implement mutual exclusion without using lower-level constructs that, like semaphores, assume mutually exclusive access to a resource?

Lamport's approach to problem solving suggests, we need to think of computing problem as series of states instead of series of steps. I think, series of steps tend to give some linearity the approach, while series of states tend to indicate that sub-parts of the system can have multiple states and the next state each sub-part can take only depends upon the current state and action that leads the state transition to the next state.

It is more useful to think about states than sequences of steps because what a computing device does next depends on its current state, not on what steps it took in the past.

To describe a computation we need to describe a sequence of states. More often, we need to describe the set of computations that can be produced by some particular computing device, such as an algorithm. There is one method that works in practice: describing a set of computations by

  1. the set of all initial initial states and
  2. A next-state relation that describes, for every state, the possible next states that is, the set of states reachable from that state by a single step.

On computational thinking.

How should we describe computations?

Most computer scientists would probably interpret this question to mean, what language should we use? Imagine an art historian answering “how would you describe impressionist painting?” by saying “in French”.

Programming and hardware-design languages don’t help an engineer understand what problem a system should solve. Thinking of computations as sequences of states, rather than as something described by a language, is the first step towards such understanding.

Lamport also describes in great details about importance of problem specification. Sometimes, when the problem is specified clearly and understood problem, the solution becomes easy. Most of our struggles seems to be with coming to grasp the problem specification.

The great contribution of Dijkstra’s paper on mutual exclusion was not his solution; it was stating the problem. (It is remarkable that, in this first paper on the subject, Dijkstra stated all the requirements that distinguish mutual exclusion from fundamentally simpler and less interesting problems.)

On concurrency, itself

He gives an example of concurrency problem that according to him is "trivial". It took me some reading to understand the problem. StackOverflow.com certainly helped.

Once an engineer understands what a computation is and how it is described, she can understand the most important concept in concurrency: invariance. A computing device does the correct thing only because it maintains a correct state. Correctness of the state is expressed by an invariant—a predicate that is true in every state of every computation.

Invariance is the key to understanding concurrent systems, but few engineers or computer scientists have learned to think in terms of invariants. Here is a simple example.

Now, the problem

Consider N processes numbered from 0 through N − 1 in which each process i executes

\begin{equation*} x[i] :=1; \end{equation*}
\begin{equation*} y[i] := x[(i-1)modN] \end{equation*}

and stops, where each \(x[i]\) initially equals 0. (The reads and writes of each \(x[i]\) are assumed to be atomic.)

This algorithm satisfies the following property: after every process has stopped, \(y[i]\) equals 1 for at least one process \(i\) .

It is easy to see that the algorithm satisfies this property; the last process \(i\) to write \(y[i]\) must set it to 1. But that process doesnt set \(y[i]\) to 1 because it was the last process to write y.

What a process does depends only on the current state, not on what processes wrote before it. The algorithm satisfies this property because it maintains an inductive invariant.

Explanation

The explanation on how \(y[i]\) equals for 1 at least one process \(i\) goes like this.

  1. The \(x_s\) model the following behavior: \(x[i]\) is 1 if and only if the process \(i\) has already run.
  2. After all processes have completed, all \(x_s\) are thus set to 1.
  3. The \(y_s\) are a bit trickier: \(y[i]\) is set if \(x[i-1]\) was set, that is, \(y[i]\) is 1 if and only if the predecessor of \(i\) had already run when \(i\) was doing its write to \(y\).

I essentially to had resort to StackOverflow.com post author's explanation to completely understand this.

The program invariant is:

If a process has set \(y[i]\), it must already have set \(x[i]\) to 1. This is true regardless whether \(y[i]\) is set to 0 or 1.

Proving this invariant is quite easy: In the beginning, none of the \(y_s\) is set, so it holds trivially. During program execution, each write to \(y[i]\) is sequenced after a write to \(x[i]\). Therefore the invariant also holds for every step of the program afterwards.

The further reasoning goes like this.

The last process to finish sets \(y[i]\) to 1 because, by definition of being the last process, its predecessor must have already finished execution at that point (ie. its y value is already set).

Which means, because of the invariant, its \(x\) value (which determines the last process' \(y\) value) has to be 1.

The alternate way to look at this problem can give some intuitive understanding too.

You cannot find an execution order in which all \(y_s\) are set to 0. Doing so would require all processes to execute before their predecessor. However, since our processes are arranged in a ring (that is, if I follow the predecessor chain I will eventually end up at my starting point again), this leads to the contradiction that at least one process must have finished executing before it wrote to \(y\).

To understand this concurrency problem, it requires some notion of syntax, a prior understanding of proving hypothesis, and possibly discussing the problem and solution.

Trying to understand itself, I guess, is a progress.

Edison's TODO list

Looks like Edison used TODO list too.

This article on openculture has a snapshot of his todo list from year 1888.

These were his 108 things he wanted todo.

1 - Cotton Picker

2 - New Standard Phonograph

3 - Hand turning phonograph

4 - New Slow speed cheap Dynamo

5 - New Expansion Pyromagnetic Dynamo

6 - Deaf Apparatus

7 - Electrical Piano

8 - Long distance standard Telephone Transmitter which employs devices of recording phonogh

9 - Telephone Coil of Fe [iron] by tt in Parafine or other insulator

10 - Platina Point Trans using new phono Recorder devices

11 - Gred Battery for Telephones

12 - * Long Distance

13 - * Phonoplex

14 - * Jump Telegraph

15 - * Voltmeter

16 - Improved Magnetic Bridge for practical work

17 - Motograph Mirror

18 - * Relay

19 - * Telephone practical

20 - Artificial Cable

21 - Phone motor to work on 100 volt ckts

22 - Duplicating Phono Cylinders

23 - Deposit in vacuo on lace, gold silver also on cotton molten chemical compound of lustrous surfaces to imitate silk also reg plating system

24 - Vacuous Ore milling Large Machine

25 - Magnetic Separator Large

26 - Locking material for Iron sand

27 - Artificial Silk

28 - Artificial filiments [sic]

29 - New [illeg.]

30 - Uninflammable Insulating Material

31 - Good wax for phonograph

32 - Phonographic Clock

33 - Large Phonograph for Novels, etc.

34 - Pig Iron Expmts with Electricity + Magnetism

35 - Malleablizing Cast now in Vacuo

36 - Drawing fine wire

37 - Joy phonograph for Dolls

38 - Cable Motograph

39 - Very Loud Motograph telephone with 1/3 siz phonogh motor.

40 - Magneto telephone with actual contact end magnet compression of an adjustable rubber press as in new phones

41 - Snow Compressor

42 - Glass plate water ore repeator

43 - Tinned faced [illeg.] for Stove Castings

44 - Refining Copper Electrically

45 - Quad neutral relay

46 - Cheap low induct Cop Insulating material for Lead Cable people

47 - Constant moved for nonfoundry

48 - 200 volt 20 cp lamp

49 - Cheap [illeg.] Indicator

50 - Recording Valt Indicator

51 - Box balancing System

52 - Alternating Machine + Transformer

53 - Sifua Surface Switches

54 - Vulcanizing [illeg.] African Rubber adullement

55 - Platinum wire [illeg.] cutting Machine

56 - Silver wire wood cutting system

57 - Silvering or Coppering bathing cloth in Vac for durability

58 - S Mater attend own with new devices for c speed

59 - Expansion mirror platwire in vacuo

60 - Photoghy

61 - Photoghy by camping heat after central points

62 - Boron fil.

63 - Hg [mercury] out of Lamp

64 - Phonaplex Repeater

65 - Squirting glass sheet tube etc. Nickel [illeg.]

66 - Artificial Mother Pearl

67 - Red Lead pencils equal to graphite

68 - India Ink

69 - Tracing Cloth

70 - Ink for blind

71 - Fluffy Incandescent Burner for gas

72 - Regenerative Kerosene Burner

73 - Centralized arc in arc Lamp

74 - Cai-[illeg] Tesla arc lamp test

75 - Strengthening alternating cli by sternt Dynamo

76 - ERR Cont [illeg.] reducers

77 - Electroplating Machines for Schenectady

78 - Condenser Transformer

79 - Sqr ft difraction gratings in silver by 5000 [illeg.] tool special [illeg.] lathe for ornamental purposes

80 - Photo Scant [illeg.]

81 - Cheap plan produce Mimeograph surfaces

82 - Miners battery + lamp

83 - Sorting Coal from Slate Machine

84 - Butter direct from Milk

85 - Burning asphalt Candles by high chimney

86 - Magnets RR signals

87 - Soften [illeg.] of books transfer to Cop plate + plate to [illeg.] matrix

88 - Telephone Repeater

89 - Substitute for Hard rubber

90 - Artificial Ivory

91 - Soften Vegetable Ivory to press in sheets

92 - Various batteries on [illeg.] Type

93 - Revolving Thermo

94 - Caller Indicator for Jump Telegh

95 - Marine Telegraphy

96 - Long distance speaking tube filled H20 2 dia pressure

97 - Lend plate battery for modifying attending Current

98 - Two revolving bands in battery Lead faced press in liquid close together + out into separate chambers to [illeg.]reduce by gas the other

99 - Siren phonogh

100 - Perm mag like an electromag of [illeg.] hand steel high polish separately magnetized + forced together powerfully[illeg.]

101 - Telephone working more [illeg.]

102 - Eartubes formed crescent [illeg.] wire

103 - Long strip 50 cp carbon under stress [illeg.] for

104 - Cheap Voltmeter

105 - Chalk Battery

106 - Dynamo or motor long tube in long magnetic field top bottom contacts forcing water through generator current by passage.

107 - Thermo battery slick Copper oxidized then plated over surface oxide nailed to make good contact [illeg.]

108 - Disk Phonogh