Using Scala’s Parser Combinators To Generate Expression Trees


I found this post in my drafts that I forgot to publish, as a sequel to this earlier post –  Scanning annotations in class path.   Though now probably out-of-date, I thought I’d still record it as a part of my experience so that I can refer to it anytime I like.  If it benefits you, it will be a positive side-effect.  The DSL used various transformation functions which closely resembled MongoDB’s aggregation-projection framework functions, like the Arithmetic operations for add, subtract, etc… and the String operations like concat, toLower, etc…

# Custom DSL: 
# Transform a field by using a built-in Arithmetic Operators. 
# It takes in an input field and an expression containing built-in 
# arithmetic function and returns the result by setting it on the 
# output field. 
# 
# syntax: 
# db.things.transform("outputFieldName", "{ $add: ["$age", 1] }") ##################################################################

The user will use the above DSL to apply the transformation to the totalAmount. Say, we are offering 20% discount on totalAmount, then we’d expect the user to say something like –

db.orders.transform('totalAmount', '{ $subtract: ["$totalAmount", { $multiply: ["$totalAmount", 0.2] } ] }')

If you look at the second argument of the transform, the user expresses the discount on totalAmount as series of arithmetic operations to be carried out on totalAmount field and then save the result back into totalAmount field. We receive the above arguments from user as Json Strings and I need to parse this string Json to domain model. This domain model would then be told to evaluate at runtime to apply the transformation to every document in the orders collection.

So, it is important to see, how the string representation can closely represent the domain model without any impedance mismatch. So, how do I do this? Well, to start out, I view this as

Subtract(Field("totalAmount"), Multiply((Field("totalAmount"), Literal(0.2)))

To generalize the above, I could represent it as

FunctionExpression(FieldExpression("someField"), FunctionExpression(FieldExpression("someField"), ConstantExpression(someValue))

So each of them is really an expression, i.e, either a terminal expression like FieldExpression or ConstantExpression or a non-terminal Expression like SubtractFunction or MultiplyFunction, in general, let’s call the non-terminal function expression as FunctionExpression that refers other Expressions. To be more precise, it is the Interpreter Pattern

  1. Literal Expression for representing Constants
  2. Field Expression that gets a field value from a document
  3. Function Expression that operates on arguments that are themselves – Expressions.

Below is the domain model that can represent the above concepts

 
       +––––––––––+            
       |Expression|<-–––––––––+
       +–-–––-––-–+           |
         |   |  |             |
    +––––+   |  +––––––+      |
    |        |         |      |
+–––-–––+ +––-––+ +––––-–––+  |
|Literal| |Field| |Function+––+
+–––––––+ +–––––+ +––––––––+   

Here is the model expressed as code.

sealed trait Expression {
  def evaluate(document: BSONObject): Literal
}

final case class Literal(val value: Any) extends Expression {
  def evaluate(document: BSONObject) = this
}

final case class Field(name: String) extends Expression {
  def evaluate(document: BSONObject) = 
    document(name) match {
      case Some(value) => Literal(value)
      case None        => Literal(null)
    }
}

sealed abstract class Function(expressions: Expression*) extends Expression

Furthering the discussion, I can now represent Arithmetic functions, String functions and their sub-types like

                                       
                                        +--------+
                                        |Function|
                                        +--------+
                        ________________/    |   \_________________
                       /                     |                     \
              +------------------+        +--------------+      +------------+
     _________|ArithmeticFunction|        |StringFunction|      |DateFunction|
    /         +------------------+        +--------------+      +------------+
   /       ______/   |    \___  \_____         |   |____ \_______
  /       /          |        \       \        |        \        \
+---+ +--------+ +------+ +--------+ +---+  +-------+ +-------+ +------+
|Add| |Multiply| |Divide| |Subtract| |Mod|  |ToLower| |ToUpper| |Concat|
+---+ +--------+ +------+ +--------+ +---+  +-------+ +-------+ +------+

Translating the above to code.

abstract class ArithmeticFunction(expressions: Expression*) extends Function(expressions: _*) {
  def value(literal: Literal): Double = literal match {
    case Literal(null) => 0
    case Literal(x)    => x.toString.toDouble
  }
}

final case class Add(expressions: Expression*) extends ArithmeticFunction(expressions: _*) {
  def evaluate(document: BSONObject) = {
    val result = expressions.foldLeft(0d) { (sum, expression) =>
      sum + value(expression.evaluate(document))
    }
    Literal(result)
  }
}

final case class Subtract(minuend: Expression, subtrahend: Expression) extends ArithmeticFunction(minuend, subtrahend) {
  def evaluate(document: BSONObject) = {
        val left = value(minuend.evaluate(document))
        val right = value(subtrahend.evaluate(document))
        Literal(left - right)
  }
}

On similar lines String aggregation functions can also be represented as.

abstract class StringFunction(expressions: Expression*) extends Function(expressions: _*) {
  def value(literal: Literal): String = literal match {
    case Literal(null) => ""
    case Literal(x)    => x.toString
  }
}

final case class Concat(expressions: Expression*) extends StringFunction(expressions: _*) {
  def evaluate(document: BSONObject) = {
    val result = expressions.foldLeft("") { (concatenated, expression) =>
        concatenated + value(expression.evaluate(document))
    }
    Literal(result)
  }
}

final case class ToLower(expression: Expression) extends StringFunction(expression) {
  def evaluate(document: BSONObject) = {
    val string = value(expression.evaluate(document))
    Literal(string.toLowerCase)
  }
}

final case class Length(expression: Expression) extends StringFunction(expression) {
  def evaluate(document: BSONObject) = {
    val string = value(expression.evaluate(document))
    Literal(string.length)
  }

So, the next step for me is to parse the above and convert it to the above domain model. One of the ways to achieve this is to parse and construct Expression tree out of this manually, but Scala offers Parser Combinators which do the heavy lifting for you. This is where functional programming paradigm really shines. It attacks this problem by breaking stuff in to smaller pieces, that is, using composition to control complexity.

Lets say, if you were to do this manually, you would write a parser that has parse method that may look something like –

def parse(jsonExpression: String) : Expression = {
         //parses the string and returns an Expression tree.
     }

This in my opinion, is a monolithic parser and a very big-step to take. Instead how about breaking this parse method into number of smaller parse methods that only caters to a small bit of the input and then compose these small parse methods to form a big parse method, returning ParseResult?

def parse(input: String) : ParseResult = {
         //parses the string and returns an Expression tree.
     }

Further, each small parse method does what it can –

  • It is either able to parse and return the result
  • if it cannot do anything sensible with that input, it either fails or passes that input to the next parse method down the chain.

So the parser either succeeds or fails. As we are in functional programming paradigm, we do not throw exception to signal failure and return type for success, instead let us introduce abstractions that represent success and failure.

sealed abstract class ParseResult[+T]

case class Success[T](result: T, in: Input) extends ParseResult[T]

case class Failure(msg: String, in: Input) extends ParseResult[Nothing]

We can understand that the Success will wrap the result of parsing and failure will wrap the parse error message, but why are both taking in Input? Well, it turns out that we need to analyze a part of the input and return the remaining part in result for the next parser in chain to work upon it.

This is all good, we looked at parsing, but we have not combined parsers yet, after all Parser Combinators = Parser + Combinators.
We need to use combinators and combine these small parsers to create a complex parser. In reality this is functional composition at the rescue, we use higher order function that takes in 2 parsers and applies transformation to generate a complex parser. Lets create one such combinator

def combinator(parser1: Input => ParseResult, parser2: Input => ParseResult): Input => ParseResult = {
  ...
}

In Scala, the class Parser, like class Map is both, a function and a class.

abstract class Parser[+T] extends (Input => ParseResult[T]) {
  def apply(in: Input): ParseResult[T]
}

So the above combinator now becomes

def combinator[T, U, R](parser1: Parser[T], parser2: Parser[U]): Parser[R] = {
  ...
}

But as the combinator method would be present on the Parser[T] itself, the correct signature would be

abstract class Parser[+T] extends (Input => ParseResult[T]) {
  def apply(in: Input): ParseResult[T]
  def combinator[U, R](parser: Parser[U]): Parser[R] = { 
     ...
  }
}

Well, in reality, this combinator method does not exist on Scala Parser class, instead you will find many combinators, for example you can string parsers together with sequential composition operator ~ or use the | combinator for alternative composition.

If you take a look at the Scala’s Parser class, you will find more interesting operations like flatMap and map on the parser, this tells us that, in Scala, a Parser is a Monad.

abstract class Parser[+T] extends (Input => ParseResult[T]) {
  def apply(in: Input): ParseResult[T]
  def flatMap[U](f: T => Parser[U]): Parser[U]
      = Parser{ in => this(in) flatMapWithNext(f)}

  def map[U](f: T => U): Parser[U] 
      = Parser{ in => this(in) map(f)}

  
  def ^^ [U](f: T => U): Parser[U] = map(f).named(toString+"^^")

}

Next, look at Parser Input. Best is to read Martin’s Odersky’s book – Programming in Scala pp744 section on Parser input. But just to inline some of it here –

… parser reads streams of tokens instead of a raw sequence of characters. A separate lexical analyzer is then used to convert a stream of raw characters into a stream of tokens…

  
type Input = Reader[Elem]

The class Reader is similar to a Stream, but it also keeps track of the positions of all the elements it reads. The type Elem represents individual input elements. It is an abstract member of the Parsers trait:

  
type Elem

This means that subclasses and subtraits of Parsers need to instantiate class Elem to the type of input elements that are being parsed. For instance, RegexParsers and JavaTokenParsers fix Elem to be equal to Char…

So the next step is to create your own parsers from scratch or try the parsers available in JavaTokenParsers to see how they work. I’ll leave that as an exercise for the reader.

Next, I need to now create small parsers and eventually combine them into a complex parser that parses the above expression and builds an Expression tree. Before you create these small parsers, the approach is to express the above in the Backus–Naur Form and then use Scala’s DSL . So I ended up creating the BNF that represents the above expressions

BNF:

value ::= obj | floatingPointNumber 
              | "null" 
              | "true" 
              | "false" 
              | quotedField 
              | singleQuotedField 
              | quotedStringLiteral 
              | singleQuotedStringLiteral.

obj ::= "{" function "}".
fn ::= fnName ":" fnArgs.
fnArgs ::= "[" values "]" | value.
values ::= value { "," value }.

Other examples of the above BNF would be:

// 1. Concat first name and last name  fields using delimiter - ", "
// 2. Calculate length of the salutation field and the concatenated first and last names
"""{ $length: [
                "$salutation", 
                { $concat : ["$fname", ", ", "$lname" ] } 
              ] 
    }"""

Now, let us implement the above BNF

  def value: Parser[Expression] =
    (
      obj
       | floatingPointNumber        ^^ (s => Literal(s.toDouble))
       | "null"                     ^^ (s => Literal(null))
       | "true"                     ^^ (s => Literal(true))
       | "false"                    ^^ (s => Literal(false))
       | quotedField
       | singleQuotedField
       | quotedStringLiteral
       | singleQuotedStringLiteral
    )

  def field: Parser[String] = """([a-zA-Z_]\w*([\.][a-zA-Z_0-9]\w*)*)""".r

  def quotedField: Parser[Expression]       = "\"$" ~> field <~ "\"" ^^ (Field(_))

  def singleQuotedField: Parser[Expression] = "\'$" ~> field <~ "\'" ^^ (Field(_))

  def quotedStringLiteral: Parser[Expression] =
    ("\"" + """([^"\p{Cntrl}\\\$\.]|\\[\\'"bfnrt]|\\u[a-fA-F0-9]{4})*""" + "\"").r ^^ (s => Literal(s.replaceAllLiterally("\"", "")))

  def singleQuotedStringLiteral: Parser[Expression] =
    ("\'" + """([^'\p{Cntrl}\\\$\.]|\\[\\'"bfnrt]|\\u[a-fA-F0-9]{4})*""" + "\'").r ^^ (s => Literal(s.replaceAllLiterally("\'", "")))

  def obj: Parser[Expression] = "{"~> fn <~"}"

  def fnArgs: Parser[List[Expression]] = "["~> repsep(value, ",") <~"]"  | (value ^^ (List(_)))
  def fnName: Parser[String] = "$"~> """[a-zA-Z_]\w*""".r
  def fn: Parser[Expression] = fnName~":"~fnArgs ^^ { 
    case "add"~":"~args => Add(args: _*) 
    case "subtract"~":"~args => Subtract(args: _*) 
    case "multiply"~":"~args => Multiply(args: _*) 
    case "divide"~":"~args => Divide(args: _*) 
    case "concat"~":"~args => Concat(args: _*) 
    case "length"~":"~args => Length(args: _*) 
  } 

  def parse(input: String): Expression = parseAll(obj, input) match { 
    case Success(value, _)     => value 
    case NoSuccess(message, _) => throw new IllegalArgumentException(s"Parsing Failed: $message") 
  } 
}

Now, the above highlighted lines will keep on growing as functions grow. How do I confirm the fn function code to OCP? For that, you may want to look at this post

Next, you may ask, is it possible to TDD this parser? Well, the answer is Yes! In fact, it turns out that is type of evolution of parsers is very much aligned with the spirit of TDD, where we build a little, get the feedback, and evolve a testable design by employing principle of composition. I find this at perfect harmony. We are using Specs2 and here are the Parser Specifications.

@RunWith(classOf[JUnitRunner])
class ParserSpecs extends Specification {

  trait ExpressionParser extends Parser with Scope {
    def Result[T](result: ParseResult[T]): T = result match {
      case Success(value, _) =>  value
      case NoSuccess(message, _) => throw new IllegalArgumentException(s"Parsing Failed Message: $message")
    }
  }

  "Parse" should {
    "return Literal for null" in new ExpressionParser {
      //Given
      val input = "null"

      //When
      val expression = Result(parseAll(value, input))

      //Then
      expression mustEqual Literal(null)
    }

    "return Literal for true" in new ExpressionParser {
      //Given
      val input = "true"

      //When
      val expression = Result(parseAll(value, input))

      //Then
      expression mustEqual Literal(true)
    }

    "return Literal for false" in new ExpressionParser {
      //Given
      val input = "false"

      //When
      val expression = Result(parseAll(value, input))

      //Then
      expression mustEqual Literal(false)
    }

    "return Literal for Integer" in new ExpressionParser {
      //Given
      val input = "2"

      //When
      val expression = Result(parseAll(value, input))

      //Then
      expression mustEqual Literal(2)
    }

    "return Literal for Decimal" in new ExpressionParser {
      //Given
      val input = "2.4"

      //When
      val expression = Result(parseAll(value, input))

      //Then
      expression mustEqual Literal(2.4)
    }

    "return Field for fieldName" in new ExpressionParser {
      //Given
      val input = """"$age""""

      //When
      val expression = Result(parseAll(value, input))

      //Then
      expression mustEqual Field("age")
    }

    "fail to parse field that has trailing dot" in new ExpressionParser {
      //Given
      val input = """"$address.""""

      //When-Then
      Result(parseAll(value, input)) must throwA[IllegalArgumentException]
    }

    "fail to parse field that has extra dot between levels" in new ExpressionParser {
      //Given
      val input = """"$address..line""""

      //When-Then
      Result(parseAll(value, input)) must throwA[IllegalArgumentException]
    }

    "fail to parse field begins with a dot" in new ExpressionParser {
      //Given
      val input = """"$.address""""

      //When-Then
      Result(parseAll(value, input)) must throwA[IllegalArgumentException]
    }

    "fail to parse field that is prefixed with multiple $" in new ExpressionParser {
      //Given
      val input = """"$address""""

      //When-Then
      Result(parseAll(value, input)) must throwA[IllegalArgumentException]
    }

    "fail to parse field without a name" in new ExpressionParser {
      //Given
      val input = "$"

      //When-Then
      Result(parseAll(value, input)) must throwA[IllegalArgumentException]
    }


    "return Literal for string" in new ExpressionParser {
      //Given
      val input = """"age""""

      //When
      val expression = Result(parseAll(value, input))

      //Then
      expression mustEqual Literal("age")
    }

    "return function name" in new ExpressionParser {
      //Given
      val funcName = "function"
      val input = "$" + funcName

      //When
      val functionName = Result(parseAll(fnName, input))

      //Then
      funcName mustEqual functionName
    }

    "fail to parse function name containing reserved prefix $" in new ExpressionParser {
      //Given
      val funcName = "$function"
      val input = "$" + funcName

      //When-Then
      Result(parseAll(fnName, input)) must throwA[IllegalArgumentException]
    }

    "fail to parse function without a name" in new ExpressionParser {
      //Given
      val input = "$"

      //When-Then
      Result(parseAll(fnName, input)) must throwA[IllegalArgumentException]
    }


    "return empty args" in new ExpressionParser {
      //Given
      val input = "[]"

      //When
      val args = Result(parseAll(fnArgs, input))

      //Then
      args must beEmpty
    }

    "return Number argument" in new ExpressionParser {
      //Given
      val input = "[1]"

      //When
      val args = Result(parseAll(fnArgs, input))

      //Then
      args mustEqual List(Literal(1))
    }

    "return Number and String args" in new ExpressionParser {
      //Given
      val input = """[1, "age"]"""

      //When
      val args = Result(parseAll(fnArgs, input))

      //Then
      args mustEqual List(Literal(1), Literal("age"))
    }

    "return Number, String and Field args" in new ExpressionParser {
      //Given
      val input = """[1, "age", "$name"]"""

      //When
      val args = Result(parseAll(fnArgs, input))

      //Then
      args mustEqual List(Literal(1), Literal("age"), Field("name"))
    }

    "return Function arg" in new ExpressionParser {
      //Given
      val input = """[{ $add: [1, "$age"]}]"""

      //When
      val args = Result(parseAll(fnArgs, input))

      //Then
      args mustEqual List(Add(Literal(1), Field("age")))
    }

    "fail to parse incomplete args" in new ExpressionParser {
      //Given
      val input = "[1"

      //When-Then
      Result(parseAll(fnArgs, input)) must throwA[IllegalArgumentException]
    }

    "fail to parse ill-formed args" in new ExpressionParser {
      //Given
      val input = "[1]]"

      //When-Then
      Result(parseAll(fnArgs, input)) must throwA[IllegalArgumentException]
    }

    "return Add function" in new ExpressionParser {
      //Given
      val input = """$add: [1, "$age"]"""

      //When
      val add = Result(parseAll(fn, input))

      //Then
      add mustEqual Add(Literal(1), Field("age"))
    }

    "return empty Add function" in new ExpressionParser {
      //Given
      val input = """$add: []"""

      //When
      val add = Result(parseAll(fn, input))

      //Then
      add mustEqual Add()
    }

    "return recursive add function" in new ExpressionParser {
      //Given
      val input = """$add: [1, { $add: [2, "$age"]}]"""

      //When
      val add = Result(parseAll(fn, input))

      //Then
      add mustEqual Add(Literal(1), Add(Literal(2), Field("age")))
    }
    
    "return Multiply function" in new ExpressionParser {
      //Given
      val input = """$multiply: [1, "$age"]"""

      //When
      val multiply = Result(parseAll(fn, input))

      //Then
      multiply mustEqual Multiply(Literal(1), Field("age"))
    }

    "return empty multiply function" in new ExpressionParser {
      //Given
      val input = """$multiply: []"""

      //When
      val multiply = Result(parseAll(fn, input))

      //Then
      multiply mustEqual Multiply()
    }

    "return recursive multiply function" in new ExpressionParser {
      //Given
      val input = """$multiply: [1, { $multiply: [2, "$age"]}]"""

      //When
      val multiply = Result(parseAll(fn, input))

      //Then
      multiply mustEqual Multiply(Literal(1), Multiply(Literal(2), Field("age")))
    }
    
    "return concat function" in new ExpressionParser {
      //Given
      val input = """$concat: [1, "$age"]"""

      //When
      val concat = Result(parseAll(fn, input))

      //Then
      concat mustEqual Concat(Literal(1), Field("age"))
    }

    "return empty concat function" in new ExpressionParser {
      //Given
      val input = """$concat: []"""

      //When
      val concat = Result(parseAll(fn, input))

      //Then
      concat mustEqual Concat()
    }

    "return recursive concat function" in new ExpressionParser {
      //Given
      val input = """$concat: [1, { $concat: [2, "$age"]}]"""

      //When
      val concat = Result(parseAll(fn, input))

      //Then
      concat mustEqual Concat(Literal(1), Concat(Literal(2), Field("age")))
    }

    "allow single function at top-level within obj" in new ExpressionParser {
      //Given
      val input = """{ $add: [1, { $multiply: [2, "$age"]}] }"""

      //When
      val objExpr = Result(parseAll(obj, input))

      //Then
      objExpr mustEqual Add(Literal(1), Multiply(Literal(2), Field("age")))
    }

    "fail when more than 1 function is defined at top-level in obj" in new ExpressionParser {
      //Given
      val input = """{ $add: [1, { $multiply: [2, "$age"]}], $multiply: [] }"""

      //When-Then
      Result(parseAll(obj, input)) must throwA[IllegalArgumentException]
    }

    "return Subtract function" in new ExpressionParser {
      //Given
      val input = """$subtract: [1, "$age"]"""

      //When
      val subtract = Result(parseAll(fn, input))

      //Then
      subtract mustEqual Subtract(Literal(1), Field("age"))
    }

    "return empty Subtract function" in new ExpressionParser {
      //Given
      val input = """$subtract: []"""

      //When
      val subtract = Result(parseAll(fn, input))

      //Then
      subtract mustEqual Subtract()
    }

    "return Subtract function with 1 argument" in new ExpressionParser {
      //Given
      val input = """$subtract: [1.0]"""

      //When
      val subtract = Result(parseAll(fn, input))

      //Then
      subtract mustEqual Subtract(Literal(1d))
    }

    "return recursive subtract function" in new ExpressionParser {
      //Given
      val input = """$subtract: [1, { $subtract: [2, "$age"]}]"""

      //When
      val subtract = Result(parseAll(fn, input))

      //Then
      subtract mustEqual Subtract(Literal(1), Subtract(Literal(2), Field("age")))
    }

    "return Divide function" in new ExpressionParser {
      //Given
      val input = """$divide: [1, "$age"]"""

      //When
      val divide = Result(parseAll(fn, input))

      //Then
      divide mustEqual Divide(Literal(1), Field("age"))
    }

    "return empty Divide function" in new ExpressionParser {
      //Given
      val input = """$divide: []"""

      //When
      val divide = Result(parseAll(fn, input))

      //Then
      divide mustEqual Divide()
    }

    "return Divide function with 1 argument" in new ExpressionParser {
      //Given
      val input = """$divide: [1.0]"""

      //When
      val divide = Result(parseAll(fn, input))

      //Then
      divide mustEqual Divide(Literal(1d))
    }

    "return recursive Divide function" in new ExpressionParser {
      //Given
      val input = """$divide: [1, { $divide: [2, "$age"]}]"""

      //When
      val divide = Result(parseAll(fn, input))

      //Then
      divide mustEqual Divide(Literal(1), Divide(Literal(2), Field("age")))
    }
  }
}

I know this was a long post but I did not see it as a point to split this into multiple ones. So thank-you for your time and patience.

The Difference between संस्कार, वासना, कर्म, अकर्म and विकर्म


I learnt about the precise difference between these words at Karmayoga workshop session How is Karma Yoga Acting Without Acting? held by Sri Aurobindo Society for Indian Culture (SAFIC). The speaker Anuradha Choudary from IIT – Kharagpur, delineated these terms without any ambiguity. Her approach of deconstructing the process of acting and then reconstructing it left me with an awe.

Acting

When we say acting, so many questions arise as in who needs to act, what needs to be acted, with whom and so on.

To whom are these questions arising? These questions probably arise only to human beings. But where are these questions arising? In the human mind. There can be two reasons for it due to the two unique aspects of human beings:

  1. Development of mental faculty – Because of this faculty, we are able to question our self and introspect.
  2. Free will – Freedom to choose what action to do, freedom to decide, freedom to allow things to happen to us.

The Process Of Karma

  1. Every action we do leaves an impression – For example, if we go to an ice-cream shop and try out for the first time an unknown flavor, it leaves an impression – either we like or dislike the ice-cream. This is called Samskara (संस्कार) or impression.
  2. Next time when we visit the shop, it is quite likely that we may end-up ordering the same flavor, why? Because we liked it earlier. Here we have developed the tendency to buy the same ice-cream we always liked. This is called Vasana (वासना) or tendency.
  3. If we repeat this again and again and order the same ice-cream without thinking (in auto-pilot mode), then it has become a habit and when we act out of our tendencies, it is called Karma (कर्म) or action.

Now, this becomes a cycle, here we have created a karmic cycle. Even the tiniest of our actions will also create the karmic cycle.

Breaking the karmic Cycle

The karmic cycle continues to occur until we start questioning and being aware of why I am choosing what I am choosing. The cycle can be broken by exercising our free will – the ability to choose consciously each and every time without dipping into tendencies or habits. This is called Akarma (अकर्म).

Akarma is any action based out of rational choice and not the tendencies. The question to ask here is – Why am I choosing what am I choosing? Now, the free will starts to play out.  You don’t create extra karmic circuits here.  It’s like driving on a highway and not circuitous by-lanes. 

Vikarma (विकर्म)

Here an individual consciously chooses to enter the karmic cycle, fully knowing the good or the bad consequences of the action. If it is a wrong action, then we are ready to face the consequences of action. It’s like consciously choosing to enter in the by-lanes and avoiding highway.

But Why Do We Act The Way We Act?

Our actions depends on the inputs that we get through the senses, and how we interpret the inputs gives rise to the actions we perform. This interpretation is based on the lens we choose (unconsciously or consciously) to see the world. The five lenses or Panchklesha (पञ्च क्लेश) we normally use are –

अविद्यास्मितारागद्वेषाभिनिवेशाः पञ्च क्लेशाः॥३॥

Avidyāsmitārāgadveṣābhiniveśāḥ pañca kleśāḥ

The third verse of the second chapter of Patanjali’s Yoga Sutras

  1. Avidya (अविद्या) – Ignorance
  2. Asmita (अस्मिता) – The sense of “I”
  3. Raga (राग) – Likes
  4. Dvesha (द्वेष) – Dislikes
  5. Abhinivesh (अभिनिवेश) – Fear of dissolution
  • Avidya (अविद्या) – Due to ignorance we don’t possess the ability to see the problems or pains of others. Ignorance distorts the reality when we don’t stop to check whether what we see is the truth or is there any other facet of it.  One of the ways to overcome avidya is to put ourselves into other person’s shoe/role, see the problem from their perspective.  At times we don’t even see our own problems or pains, for example – we harm ourselves when we get angry.  
  • Asmita (अस्मिता) – A sense of ‘I am the doer’ comes with this. Introspecting on this a little deeper takes us to the question who am I, really? This raises further questions…Am I the body? Am I the mind? Am I the body? Or do I have the body? Am I the mind or do I have the mind? Am I the emotions or do I have the emotions? when we act, we act from the basis of our projected identity of what I think I am and not from what “I am” really is.
  • Raga (राग) and Dvesha (द्वेष) – Often out of sense of doer-ship, we attribute all the happenings to self and decide what to do based on our likes and dislikes.
  • Abhinivesh (अभिनिवेश) – Because of our limited identification with the body, we fear our nonexistence.  Fear of survival, leads to lot of pain and suffering we experience.

How To Act Without Acting?

Before acting we will need to be vigilant and prevent unconscious use any of the above lenses, else our action will get coloured. If we become off-guard, then we are setting up ourselves for the karmic cycle. This cause-effect cascade right from the root-cause is beautifully explained in the Srimad BhagvadGita in Chapter 2, verses 62 and 63 –

ध्यायतो विषयान्पुंसः सङ्गस्तेषूपजायते। 
सङ्गात् संजायते कामः कामात्क्रोधोऽभिजायते।।2.62।।
क्रोधाद्भवति संमोहः संमोहात्स्मृतिविभ्रमः।
स्मृतिभ्रंशाद् बुद्धिनाशो बुद्धिनाशात्प्रणश्यति।।2.63।।
dhyayato visayan pumsah sangasteshupajayate 
sangatsanjayate kamah kamat krodhobhijayate।।2.62।।
krodhadbhavatisammohah smmohat smrtivibhramah 
smrtibhramsad-buddhinaso buddhinasat pranasyati ।।2.63।।
A person who dwells upon objects, an attachment is born with reference to them
From attachment is born desire and from desire, anger is born. 
From anger comes delusion and from delusion comes the loss of memory. 
Because of loss of memory, the mind becomes incapacitated and when the mind is incapacitated, the person is destroyed.

Hence, cleaning of the lenses is essential to get clarity of the action.

Execution Time Of This Process Cycle

This leap into executing an action happens so quickly (in less than seconds) that we don’t even register the kleshas that we use before acting. Effectively we need to buy time until we become adept at injecting the registration (step-back and inject) at run-time in the process to work. Various approaches can be tried:

  • Slowing down before acting is one possible solution, but may not be effective all the time.
  • Another approach that has worked for me is to defer the action temporarily and avoid committing to act.

If you have other approaches, please put them in the comment box below and I’ll happily add and try the technique myself.

Glossary Of Definitions

  • संस्कार (Samskara) = Initial Impressions.
  • वासना (Vasana) = Tendency or Patterned Reactions, it is a regular reactionary pattern based on likes and dislikes (preferences).
  • कर्म  (Karma) = Action based out of the above tendencies. Hence we have karmic cycle or karmic circuit. 
  • अकर्म (Akarma) = Action based out of choice and not the tendencies.
  • विकर्म (Vikarma) = Consciously entering the karmic cycle and ready to face the consequences of action.

RESTful Life?


The raw form of the poem just came to me without explicit act of thinking about it. I’ve then refactored and gotten it reviewed, improvised it further today to its near-to-final shape!

Life seeking many things, but instead getting a 404 NOT FOUND,

Expecting things to be 200 OK, but ending up in a 500 INTERNAL SERVER ERROR,

Pivoting our seeking and efforts, we do a 307 TEMPORARY or a 308 PERMANENT REDIRECTION

But life starts responding with 206 PARTIAL CONTENT and 207 MULTI-STATUS RESPONSES from our earlier seekings

Seeds sown culminate in a 201 CREATED through infinite seekings and progressive meanderings!

Making your program spicy – Currying & Partial Function Application (PFA)

Tags

, , ,


Languages like Clojure don’t have currying, but PFA, where has Haskell currying and not PFA; Scala has both and Groovy wants you to call methods like curry(), rcurry() or ncurry() and lo! Java (Java13 is latest as of this post) has neither.

This year at Functional Conf 2019, on the Bootcamp day for the JVM track, I took to a live demo of currying and partial function application. Starting with the overview of the concept in Java, I showed a practical DI example, how to make our own curry/uncurry and using PFA showed how to curry library functions. Followed it by live coding in different languages

Code is on https://github.com/DhavalDalal/FunctionalConference-2019-Currying-PFA-Demo.

Slides are on https://www.slideshare.net/DhavalDalal/currying-and-partial-function-application-pfa:

Booting Into Functional Programming


This year at Functional Conf 2019, on the Bootcamp day for the JVM track, I started with a 90-min whirlwind tour of the FP land primarily meant for developers wanting to embark on their functional programming journey – Booting into FP. Java was used to understand most of the concepts, however, where it fell short to explain certain concepts, I used Scala to demonstrate it and additionally used Haskell to bring about compare and contrast.

Code is on https://github.com/DhavalDalal/FunctionalConference-2019-Booting-Into-FP-Demo.

Slides are on https://www.slideshare.net/DhavalDalal/booting-into-functional-programming:

Few extension methods on IEnumerable, Func, Predicate, and IDictionary that I found useful


I found it helpful to add these extension methods on while doing Functional Programming in C#.

  • IEnumerable
  • Func
  • Predicate
  • IDictionary

IEnumerable Extensions

Lets start with IEnumerable extension methods. But before that, below are the usage examples of each of these extension APIs:

Doing Side-effect on each value (single-valued or a 2-element-tupled enumerable)

// Single-Valued
string [] names = { "Brahma", "Vishnu", "Mahesh" };
names
  .Select(name => name.ToUpper())
  .ForEach(Console.WriteLine);
// BRAHMA
// VISHNU
// MAHESH

//2-element-tuple
IList alphabets = new List { 'a', 'b' };
IList numbers = new List { 1, 2 };
IList combinations = new List();
foreach (var alphabet in alphabets) {
  foreach (var number in numbers) {
    combinations.Add((alphabet, number));
  }
}

combinations
  .ForEach((a, n) => Console.WriteLine($"({a}, {n})"));
// (a, 1)
// (a, 2)
// (b, 1)
// (b, 2)

Peeking each value

var result = "all mimsy were the borogoves and the momeraths"
  .Split(" ")
  .Peek(word => Console.WriteLine($"Where({word})"))
  .Where(word => word.Length < 4)
  .Peek(word => Console.WriteLine($"Select({word})"))
  .Select(word => word.ToUpper())
  .Aggregate("", (acc, elem) => acc + " " + elem)
  .Trim();

// Where(all)
// Select(all)
// Where(mimsy)
// Where(were)
// Where(the)
// Select(the)
// Where(borogoves)
// Where(and)
// Select(and)
// Where(the)
// Select(the)
// Where(momeraths)

Console.WriteLine(result); // ALL THE AND THE

Producing infinite values using Iterate and Generate

// Using Iterate
bool IsPrime(int number) {
  return IEnumerableExtensions.Iterate(2, x => x + 1)
    .Take(number)
    .Where(n => n  number % n != 0);
}
   
Console.WriteLine(IsPrime(2)); // True
Console.WriteLine(IsPrime(3)); // True
Console.WriteLine(IsPrime(4)); // False

// Using Generate
string Captcha(int howMany) {
  var random = new Random();
  return IEnumerableExtensions.Generate(() => random.Next(65, 123))
    .Where(integer => Char.IsLetter((char)integer))
    .Select(integer => (char)integer)
    .Take(howMany)
    .Aggregate(new StringBuilder(), (acc, elem) => acc.Append(elem))
    .ToString();
}

Console.WriteLine(Captcha(4)); //RVkn, Ccmo etc... each run produces different output.

Scanning reduction

// Using Scan to print Running Sum
new List { 1, 2, 3, 4 }
  .Scan(0, (acc, elem) => acc + elem)
  .ForEach(Console.WriteLine); 

// 1 
// 3 
// 6 
// 10

De-constructing an IEnumerable

var (first, second, third, rest) = new List { 1, 2, 3, 4 };
Console.WriteLine($"First = {first}");   // 1
Console.WriteLine($"Second = {second}"); // 2
Console.WriteLine($"Third = {third}");   // 3
Console.WriteLine($"Rest = {rest}");     // IEnumerable of remaining elements.

Maximum and Minimum By a key

var people = new [] {
  new { Name = "Eina", Age = 10 },
  new { Name = "Mina", Age = 15 },
  new { Name = "Dika", Age = 19 },
  new { Name = "Tika", Age = 10 },
  new { Name = "Maka", Age = 28 },
  new { Name = "Naka", Age = 35 },
  new { Name = "Saka", Age = 28 },
  new { Name = "Taka", Age = 45 }
}.ToList();

Console.WriteLine("*** Eldest person ***");
Console.WriteLine(people.MaxBy(p => p.Age)); // { Name = Taka, Age = 45 }
Console.WriteLine("*** Youngest person ***");
Console.WriteLine(people.MinBy(p => p.Age)); // { Name = Eina, Age = 10 }

Finally, here is the IEnumerable extension class which implements all the above APIs.

static class IEnumerableExtensions {
  // Doing Side-Effects
  // Single-Valued
  public static void ForEach<T>(this IEnumerable<T> @this, Action<T> action) {
    if (@this == null)
      throw new ArgumentNullException("Require non-null source!");

    if (action == null)
      throw new ArgumentNullException("Require non-null action!");

    foreach (T item in @this) {
      action(item);
    }
  }
  // 2-element-tuple enumerable
  public static void ForEach<T1, T2>(this IEnumerable<(T1, T2)> @this, Action<T1, T2> action) {
    if (@this == null)
      throw new ArgumentNullException("Require non-null source!");

    if (action == null)
      throw new ArgumentNullException("Require non-null action!");

    foreach (var item in @this) {
      action(item.Item1, item.Item2);
    }
  }

  // Peek (but don't do side-effect)
  public static IEnumerable<T> Peek<T>(this IEnumerable<T> @this, Action<T> action) {
    IEnumerable<T> PeekedEnumerable() {
      foreach (T item in @this) {
        action(item);
        yield return item;
      }
    }
    
    if (@this == null)
      throw new ArgumentNullException("Require non-null list!");

    if (action == null)
      throw new ArgumentNullException("Require non-null action!");

    return PeekedEnumerable();
  }

  // Produce Infinite values using functions.
  public static IEnumerable<T> Iterate<T>(T inital, Func<T, T> next) {
    var nextValue = inital;
    while(true) {
      yield return nextValue;
      nextValue = next(nextValue);
    }
  }
  
  public static IEnumerable<T> Generate<T>(Func<T> generator) {
    while(true) {
      yield return generator();
    }
  }
  // Deconstruction
  public static void Deconstruct<T>(this IEnumerable<T> @this, 
    out T first, out IEnumerable<T> rest) {
    if (@this == null) {
      throw new ArgumentException("Collection cannot be null!");
    }
    first = @this.First();
    rest =  @this.Skip(1);
  }
  
  public static void Deconstruct<T>(this IEnumerable<T> @this, 
    out T first, out T second, out IEnumerable<T> rest) => 
      (first, (second, rest)) = @this;
  
  public static void Deconstruct<T>(this IEnumerable<T> @this, 
    out T first, out T second, out T third, out IEnumerable<T> rest) => 
      (first, second, (third, rest)) = @this;
  
  // Scanned Reduction
  public static IEnumerable<U> Scan<T, U>(this IEnumerable<T> @this, U identity, Func<U, T, U> func) {
    IEnumerable<U> ScannedEnumerable() {
      var acc = identity;
      foreach (var item in @this) {
        acc = func(acc, item);
        yield return acc;
      }
    }
    return ScannedEnumerable();
  }
  // Minimum and Maximum by a key  
  public static T MinBy<T, Key>(this IEnumerable<T> @this, Func<T, Key> selector) {
    if (@this == null)
      throw new ArgumentNullException("Require non-null list!");

    if (selector == null)
      throw new ArgumentNullException("Require non-null selector!");
    
    var minimum = @this.First();
    var minKey = selector(minimum);
    var comparer = Comparer<Key>.Default;
    foreach (var item in @this) {
      var currentKey = selector(item);
      if (comparer.Compare(currentKey, minKey) < 0) {
        minKey = currentKey;
        minimum = item;
      }
    }
    return minimum;
  }
  
  public static T MaxBy<T, Key>(this IEnumerable<T> @this, Func<T, Key> selector) {
    if (@this == null)
      throw new ArgumentNullException("Require non-null list!");

    if (selector == null)
      throw new ArgumentNullException("Require non-null selector!");
    
    var maximum = @this.First();
    var maxKey = selector(maximum);
    var comparer = Comparer<Key>.Default;
    foreach (var item in @this) {
      var currentKey = selector(item);
      if (comparer.Compare(currentKey, maxKey) > 0) {
        maxKey = currentKey;
        maximum = item;
      }
    }
    return maximum;
  }    
}

Function Extensions

Here are the examples of Function Composition and Currying.

Func<int, int> Square = x => x*x;
 
int Multiply(int x, int y) => x * y;

var uncurriedMultiply = new Func<int, int, int>(Multiply);
var multiplyCurried = uncurriedMultiply.Curry();
    
Console.Out.WriteLine($"multiplyCurried(2)(3) = {multiplyCurried(2)(3)}"); // 6
 
var uncurry = multiplyCurried.Uncurry();
Console.Out.WriteLine($"uncurry(2, 3) = {uncurry(2, 3)}"); // 6
    
// Express Twice in terms of multiplyCurried
int Twice(int x) => multiplyCurried(2)(x);

// Express Triple in terms of multiplyCurried
var thrice = multiplyCurried(3);
Func<int, int> Triple = x => thrice(x);
 
var st = Square.AndThen(Triple);
Console.Out.WriteLine($"st(2) = {st(2)}"); // 12
 
var ts = Square.Compose(Triple);
Console.Out.WriteLine($"ts(2) = {ts(2)}"); // 36

var twice = new Func<int, int>(Twice);
var ds = twice.AndThen(Square);
Console.Out.WriteLine($"ds(2) = {ds(2)}"); // 16

Now, lets look at the definitions of Function extension methods. All of them are Higher-Order functions.

public static class FuncExtensions {
  // Compose functions using AndThen and Compose
  public static Func<A, C> AndThen<A, B, C>(this Func<A, B> f1, Func<B, C> f2) =>
    a => f2(f1(a));

  public static Func<A, C> Compose<A, B, C>(this Func<B, C> f1, Func<A, B> f2) =>
    a => f1(f2(a));

  // Curry and Uncurry for 2-arg function
  public static Func<A, Func<B, C>> Curry<A, B, C>(this Func<A, B, C> f) =>
    a => b => f(a, b);

  public static Func<A, B, C> Uncurry<A, B, C>(this Func<A, Func<B, C>> f) =>
    (a, b) => f(a)(b);
}

Predicate Extensions

Next, lets look at Predicate extension methods. These are on similar lines to the ones found in Java. Again, all of them are Higher-Order functions.

public static class PredicateExtensions {
  public static Predicate<T> Not<T>(this Predicate<T> @this) {
    if (@this == null)
      throw new ArgumentNullException("Require non-null Predicate!");
    
    return t => !@this(t);
  }

  public static Predicate<T> And<T>(this Predicate<T> @this, Predicate<T> that) {
    if (@this == null || that == null)
      throw new ArgumentNullException("Require non-null Predicate!");
    
    return t => @this(t) && that(t);
  }

  public static Predicate<T> Or<T>(this Predicate<T> @this, Predicate<T> that) {
    if (@this == null || that == null)
      throw new ArgumentNullException("Require non-null Predicate!");
    
    return t => @this(t) || that(t);
  }
}

Dictionary Extensions

Next, lets look at IDictionary extension methods. It allows you to return a specified default value for a non-existent key in the dictionary. The two forms are:

  • Return a default value
  • Return a supplier function which then returns a default value

In case you don’t have a return value, the third form GetValueOrThrow allows you to throw an exception. Again, these are on similar lines to the ones found in Java and Scala.

public static class IDictionaryExtensions {
  public static V GetValueOrDefault<K, V>(this IDictionary<K, V> @this, K key, V defaultValue) {
    if (@this == null)
      throw new ArgumentNullException("Require non-null Dictionary!");
    
    if (@this.ContainsKey(key))
      return @this[key];
    
    return defaultValue;
  }

  public static V GetValueOrDefault<K, V>(this IDictionary<K, V> @this, K key, Func<V> defaultValueSupplier) {
    if (@this == null)
      throw new ArgumentNullException("Require non-null Dictionary!");
    
    if (@this.ContainsKey(key))
      return @this[key];

    return defaultValueSupplier();
  }
  
  public static V GetValueOrThrow<K, V, E>(this IDictionary<K, V> @this, K key, E exception) 
  where E : Exception {
    if (@this == null)
      throw new ArgumentNullException("Require non-null Dictionary!");
    
    if (@this.ContainsKey(key))
      return @this[key];

    throw exception;
  }
}

Hope you find these useful in your day-to-day work!

Why Workshops are not “trainings”?


As practiced today largely in the context of Information Technology companies, I have found it necessary to delineate these two words – Workshop and Training. Hence this post.

The word “training” as the dictionary expounds is – the action of teaching a person or animal a particular skill or type of behaviour“ and it is in same sense that everyone understands this word. Similarly, the word “workshop” as the dictionary expounds is – a meeting at which a group of people engage in intensive discussion and activity on a particular subject or project. Now herein lies the big difference – workshop’s multi-directional nature of engaging people in such a manner creates opportunities for deep reflection, realisations and learnings that stick, which other-wise would be difficult in trainings, largely due to its uni-directional or at best bi-directional nature.

Human evolution as it stands today – many experience that mind is not fully under its own control; many a times emotions hijack its operations or annul its decisions. Even if we were to bring about this control, cultivating it is like working on the hardest terrain on the earth – the rocks! So, how can I inspire you to work on this hardest terrain? Workshops! To bring about a mind-shift is what workshops have the potential to achieve. Mind-shift (inspiration) can easily trigger control and cultivation. In my view, trainings have a very limited scope of bringing about this mind-shift, as its primary focus is on developing particular skills.

Why workshops?

Activities and discussions in a workshop immerse and involve people intensely, learning happens as they experiment and build it themselves. As activities and guidance untie the knots and unblock it, the mind will interest itself in drawing inferences from the facts, tracing cause and effect. An adept facilitator can then lead the audience to notice successes and failures and the reasons behind them. This approach shows where the knowledge lies and how can it be habituated to rise to the surface, rather than knowledge being imparted as information being supplied from outside1 (a.k.a trainings). As Sri Aurobindo puts it in his Integral Education Principles that the first principle of teaching is that – “Nothing can be taught.” I’m also reminded of these words and have mapped those words to the tools2 we use –

Tell me and I Forget, => Talks, Slide-shows, Discussions etc…
Show me and I Remember, => Demos, Screencasts etc…
Involve me and I Learn. => Workshops, Pairing, Tutorials etc…

Workshops provide an environment where people find it enriching, stimulating and take back something with them. So, lets for once call a workshop a Workshop to convey its spirit without hiding or narrowing it by using the word “training”.

References

1. Integral EducationSri Aurobindo Center for Advanced Research (SACAR).
2. The Tao of Transformation – Dhaval Dalal.

Some Scala Code in Sanskrit

Tags

, ,


I’m doing function composition in Scala using Sanskrit as a language of representation.  The two functions वर्ग (square) and द्विवारम् (twice) are combined using compose (सम्भरति) and andThen (तदनन्तरम्), so that I can construct two Sanskrit sentences (please excuse my Sanskrit Grammar):

  • वर्ग तदनन्तरम् द्विवारम्
  • द्विवारम् सम्भरति वर्ग

In Scala, we can have aliases for types and static methods – for example one can do:

import java.util.{Map => JMap}
import System.out.{println => show}

However, I could not find a way to import method aliases in Scala, so I resorted to delegation using implicits.  I’ve used FunctionOps to achieve this:

// Alias println  
import System.out.{println => दर्शय}

// square
val वर्ग = (x: Double) => x * x
दर्शय(वर्ग(3.0))   // 9.0

// twice
val द्विवारम् = (x: Double) => 2 * x
दर्शय(द्विवारम्(2.0)) // 4.0

// Delegate
implicit class FunctionOps[-T, +R](f: T => R) {
  def सम्भरति[A](g: A => T): A => R = f.compose(g)
  def तदनन्तरम्[A](g: R => A): T => A = f.andThen(g)
}

import scala.language.implicitConversions
object FunctionOps {
  implicit def apply[T, R](f: T => R) = new FunctionOps[T, R](f)
}

import FunctionOps._

val वर्गचद्विवारम् = वर्ग तदनन्तरम् द्विवारम्
दर्शय(वर्गचद्विवारम्(3.0)) // 18.0

val द्विवारम्चवर्ग = द्विवारम् सम्भरति वर्ग
दर्शय(द्विवारम्चवर्ग(3.0)) // 18.0
 

Now, in Sanskrit the sentences are usually are Referentially Transparent (RT). For example, the sentences द्विवारम् सम्भरति वर्ग and वर्ग सम्भरति द्विवारम् are RT. Even though, the order of words have changed, the meaning of the sentences does not change. In programming, function composition is not commutative f ⨁ g != g ⨁ f and hence writing द्विवारम् सम्भरति वर्ग and वर्ग सम्भरति द्विवारम् will produce a different output. So we have dissonance between the spoken and the executable language.

However, not all sentences in Sanskrit are RT, lets take the sentence वर्ग तदनन्तरम् द्विवारम्, because of the use of the word तदनन्तरम् there is order in the sentence, so वर्ग तदनन्तरम् द्विवारम् and द्विवारम् तदनन्तरम् वर्ग mean different things and programmatically produce different outputs as well. So we have resonance between the spoken and the executable language.

So this brings me to a question – How can I write something that resonates in meaning and execution?

Exploring Concurrency CodeJugalbandi


This time at Functional Conf 2018, Morten Kromberg, CXO of Dyalog Ltd., Ravindra Jaju and myself presented CodeJugalbandi again. The theme was about exploring concurrency. Conversations between the three artists can be viewed by clicking the links below, or you can simple watch the embedded Youtube video herein.

Melody Name Languages Used Examples
Concurrency and Parallelism Java and APL
  • Concurrency – Echo TCP Server
  • Parallelism – Splitting I/O Task – Portfolio Networth
FP to the Rescue (Etymology of structure of code) Scala, C#, Clojure, APL and JavaScript Gathering Weather and Nearby Places Information
Everything is an Event (Pushing Multiple Values) Reactive Extensions (Java) and Clojure CSP (Core-Async) Portfolio networth using Streaming Stock prices

At the conference, we could demo only first two melodies (see below for the video), The Github Repo has all the melodies mentioned herein.

Slides are simply an index to the melodies.

Note: Further work is in progress on creating other melodies under the theme Exploring Concurrency Codejugalbandi – Mutability, STM and the Actor Model.