Old Notes Circa 2018 - Haskell, DevOps etc

03-09-2018

Signatures of RWS monads

  • Reader Monad:

    1ask :: Reader r r
    2asks :: (r -> a) -> Reader r a
    3local :: (r -> r) -> Reader r a -> Reader r a
    4runReader :: Reader r a -> r -> a
    
  • Writer Monad:

    1tell :: w -> Writer w ()
    2execWriter :: Writer w a -> w
    3runWriter :: Writer w a -> (a, w)
    
  • State Monad:

     1runState :: State s a -> s -> (a, s)
     2evalState :: State s a -> s -> a
     3execState :: State s a -> s -> s
     4
     5get :: State s s
     6get = State $ \s -> (s, s)
     7
     8put :: s -> State s ()
     9put s = State $ \_ -> ((), s)
    10
    11modify :: (s -> s) -> State s ()
    12modify f = get >>= \x -> put (f x)
    13
    14eoovalState :: State s a -> s -> a
    15evalState act = fst . runState act
    16
    17execState :: State s a -> s -> s
    18execState act = snd . runState act
    

Push a local git repo to a server

1## Create a bare repo on the server
2git init --bare
3## Add the remote origin on the local server
4git remote add origin shu@linode:git-repos/docs
5## Push to the server with update option
6git push -u origin master

03-10-2018

Markdown tips

  • Indent fenced code block within a list: indent 4 spaces from the list

  • Snippets for md: [ for link; ![ for image; ** for bold

  • Useful commands: TableFormat, Toc, HeaderIncrease, HeaderDecrease

Useful git alias

  • gwS: show staus

  • gwd: show diff

  • gcam: git commit -a -m

  • glb: brief log

  • gls: summary log

  • gld: detailed log

  • glg: graphic log

Vim tips

  • :let or :let g: to show variables

  • :nmap or :imap to show key bindings

Save the log of tmux pane

  1. In the pane of interest, get into the ex by pressing Clt-A :

  2. Type :capture-pane -S -30000 to capture the last 30k lines

  3. Type :save-buffer my-log.txt to save it

03-13-2018

Regex tips

  • You can put any regex in lookahead, but not in lookbehind.
RegEX Lookaround Comments
(?=foo) Lookahead Asserts that what immediately follows the current position in the string is foo
(?<=foo) Lookbehind Asserts that what immediately precedes the current position in the string is foo
(?!foo) Negative Lookahead Asserts that what immediately follows the current position in the string is not foo
(?<!foo) Negative Lookbehind Asserts that what immediately precedes the current position in the string is not foo

Vim magic mode

  • Use :help \magic for more details.
  1. magic: default, have to escape \(, \{, \|, \+
  2. verymagic: use \v to activate, (, {, |, + are magic chars.
  3. nomagic: use \M to activate, have to escape \*, \., \$.
  4. noverymagic: use \V to activate.

03-14-2018

git-annex workflow for me

  • Still setup a bare git repo in the cloud:

    1git init --bare
    2git annex init "cloud"
    
  • Clone the clound repo to your laptop/desktop

    1git clone shu@linode:annex-repo annex-repo-laptop
    2git annex add .
    3git commit -a -m "checking in on the laptop"
    4git annx sync --content
    

03-15-2018

Haskell Language Extensions

Type Families

  • Two flavors: data families or type synonym families
  • Can be used at top lelel or within a type class
  • Type synonym families is an alternative to functional dependency
  • When defined within a type class, the familiy keyword is dropped
  • By default the kind sigature is * if not specified

Functional Dependencies

  • This is to address the issue caused by multi parameter type classes: one type parameter determines the other type

Exisitential Qualification

  • Bundle a bunch of types that share some common traits into one type

03-16-2018

Architecutre patterns illustrated by Haskell packages

  • Relaxed layers: Monad Transformers
  • Broker: extensible-effects
  • Pipe: pipes ad conduit
  • Data flow: monad-par
  • Map/Reduce: monad-par and ivish
  • Software transaction memory: stm
  • P2P with actor: distributed-process
  • Publish/Subscribe with reactive: sodium
  • Resource management: pipes-safe and resourcet

03-17-2018

Concurrency vs parallelism

  • Concurrency is about interruptability
  • Parallelism is about independency
  • Usually it's a mix of both
  • There are 3 ways of dealing with concurency: locks, actors, or stm
  • Locks are old way of doing concurrency and it does not scale, too low level
  • Actors use messages to communicate, it's really suitable for distributed computing
  • For mutli-core computing, stm is the way to go

STM

  • A composible way of doing concurrency
  • An idea borrowed from RDBMS
  • Three key operations: atomically, retry, and orElse

03-19-2018

Notes from wiwikn

  • :sprint to inspect a thunk
  • seq to force the order of evalation
  • A irrefutable pattern is lazy pattern -- it's always matched, and a bottom will be resulted if it can't be matched finally.
  • Endo in Data.Monoid is the endomorphism: it takes a type a and returns a function of a -> a.

03-20-2018

IT notes

  • List installed packages

    dpkg -l

  • List all the files of an installed package on Ubuntu

    dpkg -L packg_name

03-21-2018

Notes from concurrent haskell

  • MagicHash extension: Int# is the unboxed integer type
  • Take any immutable data structure and warp it in MVar to make it mutable
  • There are two types of exceptions: those thrown by pure functions, or IO exceptions
  • Exceptions in Haskell can only be caught in IO monad.

03-25-2018

  • const a is same as _ -> a
  • liftM is just fmap for Monads; lift is just liftM for monad transformers

03-26-2018

Notes on category theory for programmers

  • Horizontal composition of natural transformations is [D, E] (G, G') . [C, D] (F, F'), so the result is a [C, E] (G . F, G' . F'). This is a bit complicated since it composes natural transformations of functors of differnt kinds, i.e., functors mapping different categories.
  • Veritcal composition is [C, D] (H, G) . [C, D] (G, F), and the result is a [C, D] (H, F). That's ususal case of composition.

04-06-2018

IT tips

  • Curl: curl -L your_url > your.file : use -L to follow redirections

  • tar: tar -xjvf xxx.tar.bz2: use -j to uncompress bz2 files; -z for gz files.

  • add a user to ALCS group: smbldap-usermod -G ALCS tsenthilnathan

04-18-2018

Vim tips

  • zM to open all folds; zR to fold everything; za to toggle.

04-25-18

Haskell

  • Reader and State Monad (also for RWS/RWST) are wrappers around functions. So basically you are constructing a monad by providing functions.

  • When you run the monad, you unwrap the monad and run the underlying function

04-26-2019

Haskell

  • let is real expression, while where is just syntatic sugar
  • You can use ; to separate multiple expressions on one line, otherwise they need to be aligned up

04-27-2018

Hakyll Notes

  • Provider is the list of files under the source dir, plus a in-memory store
  • ID is the cleaned up version of file path
  • Rule is a RWST monad, it's env has provider/IDs/pattern, it's output is a rule set which has routes and compilers
  • There are two entries in the store for each item: one for the body and one for the meta data
  • Meta data itself has two parts: Ymal meta data if any, and modified time.

04-30-2018

Haskell Notes

  • Treat unsafePerformIO as a promise to the compiler. It says I promise that you can treat this IO action as if it were a pure value and nothing will go wrong. It's useful because there are times you can build a pure interface to a computation implemented with impure operations, but it's impossible for the compiler to verify when this is the case; instead unsafePerformIO allows you to put your hand on your heart and swear that you have verified that the impure computation is actually pure, so the compiler can simply trust that it is.

05-01-2018

Haskell Notes

  • Function application (space, not $ sign) has higher priority than function composition (.) operator. So for the expressions below are equivalent:
1   go = fmap concat . mapM applyElem
2   go = (fmap concat) . (mapM applyElem)

05-22-2018

Category Theory

  • Monoidal category: A tesor product exists, and unital and associateve laws for the product
  • Monoidal Functor: A functor that preserves the moniodal structure of the source and destination categroies; there are strict Monoidal functor and lax Monoidal ones. And applicative functors are lax Monoidal functors.

Postgres commands

1    \l: list database
2    \c <db name>: connect to a database
3    \dt: show tables
4    \d <table name>: show schema of a tble
5    copy (select * from projects_project where id = 640) to '/tmp/640.csv';

05-23-2018

function

  • injective = faithful, non-collapsing
  • surjetive = full, covering all destination category (codomain)

05-24-2018

Limit

  • Limit of a digram ( which is the base of the cones ) is the terminal object in the category of cones
  • there is one to one mapping: (isomorphism)
    • a morphism from c to Limit D in the category of C
    • a morphism from a cone to the cone of Limit D
  • So the limit exists of there is isomorphism between the two (contravianat) hom-functors above

05-25-2018

Debugging SST application

  • Reload data: dump out pd db; drop database sst; load
  • sst/urls.py has all the api mappings
  • 5 elements: prediciton, is actual, copy of prediction, is edited, robusteness
  • babel version probably is not right; with Rajiv's js files it all works
  • Disable CSRF in the Django setting

05-28-2018

Process a file line by line

1while read i ; do git clone  "$i" ; done < selected.github

07-05-2018

Power outage recovery

  1. Need to bring back sldap service on storage. Some db files are corrupted and need be chown ldap:ldap ..., then servcie sldap restart.
  2. On master, infinitiband service is not up. service restart network to bring it up. then mount -a to mount the NFS drives.
  3. On master, need to start/restart postfix and saslauthd services
  4. On local server, need to restart network and httpd services

07-09-2018

Category Theory

  1. Everybody knows this: A monad is just a moniod in the category of endofucnctors. Here the implied Product is the functor composition.
  2. Here is another fun one: An applicative functor is just a moniod in the category of endofunctors with Day convolution as the Product.
  3. A moniodal functor perseres the product operator of the source/dest categories.
  4. A closed functor perserves the arrow of the source/dest categories.
  5. Of course if it only preserves one direction, it's called lax moniodal or closed functor.

08-09-2018

Haskell

Existential types

1(exists x. p x x) -> c  forall x. p x x -> c

It tells us that a function that takes an existential type is equivalent to a polymorphic function. This makes perfect sense, because such a function must be prepared to handle any one of the types that may be encoded in the existential type. It’s the same principle that tells us that a function that accepts a sum type must be implemented as a case statement, with a tuple of handlers, one for every type present in the sum. Here, the sum type is replaced by a coend, and a family of handlers becomes an end, or a polymorphic function.

GADTs

Thinking about types often requires us to think in a logical manner. We often need to consider things inductively when constructing them, and recursively when destructing them.

08-21-2018

Free Moniod

  1. Constructed from the generator set, and only identify the generated tuples with unit law and associativity law. For example (0, 3) is same as (3, 0), and (1, (2, 3)) is same as ((1, 2), 3).
  2. The intution is that we don't collapse them further using the binary operator, as we would identify (0, 3) with (1, 2). We will leave this step open, then different operators will generate different moniods.
  3. In essence free monoid is a list.

08-22-2018

Haskell operator

  1. 9 is the highest precedence
  2. Left associativity means starting from the left: for example - is left associative: 1 - 2 - 3 is same as ((1 - 2) - 3).

08-30-2018

Distributions

  1. Gamma is the sum of exponentials; and Beta is the ratio of two gammas.
  2. Geometric is the special case of negative binomial where the success is one.
  3. Hyper Geometric is almost like negative bionomial without replacement.
  4. Pareto is the exponential gamma mixture -- the prior on the rate parameter follows gamma distribution.

09-03-2018

End and Natrual Transformation

  1. Yoneda lemma in Haskell as an End:
1forall x. (a -> x) -> f x == f a

Think of (endo)functor f as a containter, it says if you give me a function from a to x, and I can always give you a container of x, then this function or transformation equvialently has a container of a.

  1. Yoneda lemma in Haskell as a Coend:
1Exists x. ((x -> a),  f x) == f a

Think of (endo)functor f as a containter, it says if you have one pair of a function from x to a and a container of x, then I just simpley fmap the function and give you a container of a.

01-11-2019

Javascript notes

  1. JS's object model is prototype based, not class based. There is no notion of class in JS. And in essence object is simply a list of key-value pairs.
  2. So the inheritance works via prototype: if a property is not found in the current object, it tries to find out in the prototype (parent) object, all the way up to the null.
  3. To implement this design, each object has __prototype__ reference to it's parent object.
  4. In JS function is the first class citizen, and in this sense it's sort of a functional language.
  5. Function is always an object, with its __prototype__ ponits to an object whose constructor points right back to the function.
  6. You can of course add properties to the prototype of a function, which will be shared by all the objects created with this function/object.
  7. On the other hand, if you need object-specific properties, you can use contructors in the function.

01-29-2019

Modern C++

  • Use auto and decltype
  • User uniform initializer with { }
  • Be specific and uniform with default *structors ( 6 of them ): default, delete, or custom.
  • Specify the owner of resources: owners are responsible for the life cycle management of the underlying resources, non-owners are just users of resources.
  • Use handle model instead of raw pointers
  • Only use raw pointers for dynamic dispatching
  • Only user pointers to point to ONE object, not a sequence of objects; in other words, stay away from pointer arithmetic
  • Whener use a pointer, carry the size info with it: span, view.
  • Use zstring for c-style zero terminated string
  • Use in-member initialization first, then initialization list (in the right order), and lastly assignment within the constuctro.
  • DRY in constructor: call/delgate to simpler constructors in more complex ones
  • Use range-based for loop whenever possible: much better than the old style for loop

Effective Modern C++

  • auto uses almost as the same rules of type inference of templating
  • 3 cases of inference rules: parameter is reference & point; universal reference; plain type
    • reference & pointer: remove the referenceness of expressoion, then match with parameter
    • universal reference: if expr is lvalue, then the type is lvalue, otherwise use rule #1
    • plain type: losing constness, referenceness, voliteness..
  • auto is almost what you want, except for proxy types, where you need to do a static cast.
  • Prefer using long-or-dependent-type your-short-type to typedef.
  • Use { } initializer with care: compiler has strong preference for std:initailizer_list based constructor. So if this is a concern, use old styles ( ) way of calling constructors. On the other hand, uniform initialization is very handy to initialize containers.
  • Use auto for function pointer
  • Use nullptr instead of 0 or NULL
  • Use delete if you want to disable some functions
  • Use override in derived class for virtual functions

More Effective Modern C++

  • Copy constuctor is used to initialize a new object; assignemnet operator is to overwrite the lhs object with the rhs one. Same for move semantics counterparts.
  • Explictly use default an delete for all 5/6 members that could be auto generated by the compiler.
  • Use unique_ptr for most owner pointers; use make_unique_ptr in C++14
  • Use weak_ptr to detect dangling pointer, implementing cache, etc.
  • std::move unconditionally casts the parmater to a rvalue
  • std::forward<T> conditionally casts: only when the parameter is a rvalule.
  • && could be a rvalue ref or a universal one
  • Universal one is used for type deuction, in auto or template functions

Even More Effective Modern C++

  • Use high-level async/future/promise abstraction for concurrent programming
  • Only use low level std:thread if you need to finer control like priority setting
  • Don't use raw mutex, use scoped_guard instead
  • Understand 3 levels of threads: hard, soft, and language-level
  • Undertand joinable vs unjoinable threads

02-02-2019

keyword static

  • static is confusing since it means different things in differernt contexts.
  • Static variable:
    • Static global variable: static means no access outside the file where it's defined; In this sense it is the opposite of extern. By default, constant global variables are static by default (you can use explicit extern to override it), and non-constant global variables are extern by default (you can use static to override it)
    • Static local variable: static changes the duration of the variable - only one copy during the whole life cycle of the program. That's usually meaning of being static.
  • Static function: this has the similiar meaning as that of global variable: static says it's for internal linkage only, can't be accessed outside the defining file.
  • Static for class member and class member functions: one copy, no this pointer passed in.

Concurrent programming

  • You can do mutlithreading on a single core - it won't improve your performance in terms of throughtput, but it can improve latency.
  • Parallelization is usually a higher level of abstraction: it's task-based rather than thread based. It aims for high performance.
  • Two ways of sharing data: shared memory vs message passing. The former one is faster but error prone.

02-05-2019

Haskell Exceptions

  • There are two types of exs: sync and async.
  • For sync exs, they are generated by throw (from pure code) or throwIO. And there are two strategies for handling them:
    • clean up and rethrow: onException, finally, bracket
    • try to recover: catch, handle, try.
  • For async exs, they are generated by throwTo - it's the message from the outside world to your, and you have to rethrow it. If you try to recover from it, then you are beaking this invariance.
  • You can tell it's sync or async by the tyep info, but it's not guranteed.
  • Package Control.Exception.Safe provides wrappers around functions in Control.Exception, so use the safe ones.

Functor, Applicative, Monad, Monoid, Traversable

  • The essence of all those abstractions is deal with effects: instead of having a plain function a -> b, we are dealing with a effectfull function a -> F b where F captures the effect -- having a writer monad in mind helps.
  • Kleisli arrow a -> M b forms a category (of arrows), with the usual (.) as the composition thus as the bind >>= operator
  • You can reduce the bind operator to join operator M M a -> M a, and think this as the mappend of a monid (of endofunctors), you get the saying of Monad is just a moniod of endofunctors.
  • If we can not get a full monad, in other words, we can not define a bind operator for the arrow a -> F b, they still form a catgory (of arrows), one quesiton we can ask is that: can we get some interesting functor for this category ? How about a functor that can lift the arrow into T a -> F (T b) ? It turns out this special functor is called traversable, where the method traverse is like the fmap for a normal functor.
  • Note there are two functors invovled for traverse: an applicative functor F and a traversable functor T. Therefore there two ways of composing them: F . T or T . F, and the natrual transformation between them is defined as sequenceA.

Two examples with traversable

  • Most commonly used traversable is a list: and the behavior of list traversing is defined as applicative style fold of :, i.e., traverse f = foldr cons_f (pure []) where cons_f x ys = liftA2 (:) (f x) ys

  • The most straight forward example is for side effects:

    1traverse (putStr . show) [1..10]
    
  • The applicative behavior of a list is the full combination: liftA2 f xs ys = [f x y | x <- xs, y <- ys]

    1rep x = replicate x x
    2traverse rep [1..3]
    3--[[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
    
  • The applicative behavior of a Maybe is aborting the moment one input is Nothing

    1half x = if even x then Just (x `div` 2) else Nothing
    2traverse half [2,4..10]
    3--Just [1,2,3,4,5]
    4traverse half [1..10]
    5-- Nothing
    

Arrows

  • Arrow is different from monad, where monad is used to compose effectful functions, arrow is to compose steps.
  • If you look at the signature of an effectful function a -> M b, a monad is only parameterized by the type of output, thus has no control of the input.
  • On the other hand, an arrow takes two type parameters: arr (a -> b), so in this sense arrow is more general.
  • While the essential behavior of a monad is its bind operator, arrow needs two:
    • >>>, the usual composition operator
    • One of those: ***, &&&, first, or second. This is need to forward output from previous steps