Category Archives: Programming

Regex Capture Groups with Java

The following java code extracts the group, artifact and version using regex capture groups:

import java.util.regex.Pattern;

public class Main {

    public static void main(String ... args) {
        //Text to extract the group, artifact and version
        var text = "org.junit.jupiter:junit-jupiter-api:5.7.0";

        //Regex capture groups for Group:Artifact:Version
        var pattern = "(.*):(.*):(.*)"; 

        var compiledPattern = Pattern.compile(pattern);
        var matcher = compiledPattern.matcher(text);
        if (matcher.find( )) {
            System.out.println("Whole text: " + matcher.group(0) );
            System.out.println("Group: " + matcher.group(1) );
            System.out.println("Artifact: " + matcher.group(2) );
            System.out.println("Version: " + matcher.group(3) );
        } else {
            System.out.println("NO MATCH");
        }
    }
}

Output

Whole text: org.junit.jupiter:junit-jupiter-api:5.7.0
Group: org.junit.jupiter
Artifact: junit-jupiter-api
Version: 5.7.0

Retrieving the Versions from maven-metadata.xml

Groovy Snippet

List<String> getMavenVersions(String metadataXmlURL) {
    def strVersions = new ArrayList<String>()
    def mvnData = new URL(metadataXmlURL)
    def mvnCN = mvnData.openConnection()
    mvnCN.requestMethod = 'GET'

    if (mvnCN.responseCode==200) {
        def rawResponse = mvnCN.inputStream.text
        def versionMatcher = rawResponse =~ '<version>(.*)</version>'
        while(versionMatcher.find()) {
            for (nVersion in versionMatcher) {
                strVersions.add(nVersion[1]);
            }
        }
    }

    strVersions.sort {v1, v2 ->
        v2.compareTo(v1)
    }

    return strVersions
}

Example Usage

def metatdataAddress = 'https://repo.maven.apache.org/maven2/xyz/ronella/casual/trivial-chunk/maven-metadata.xml'
def versions = getMavenVersions(metatdataAddress)
println versions

Functional Programming with Gosu

First Class Citizen

An entity that can be passed around as an argument, returned from a function, modified and assigned to a variable.

First Class Function

A function that is treated as first class citizen.

Higher-Order Functions (HOF)

A function which takes function as an argument and/or that return a function.

Closure

A function that remembers its lexical scope even when the function is executed outside that lexical scope.

function greeterFn() : block() {
  var name="World" //name is a local variable created by init
  var greet = \-> print("Hello ${name}") //greet is an inner function 
                                         //that uses the variable declared 
                                         //in parent function.
  return greet
}

var greeter = greeterFn()
greeter()

Currying

The process of converting a function that takes multiple arguments into a function that takes them one at a time.

var sum = \ a : int, b : int -> a + b
print(sum(1,2))

var curriedSum = \ a : int -> \ b : int -> a + b
print(curriedSum(1)(2))

Function Composition

The act of putting two functions together to form a third function where the output of one function is the input of the other.

uses java.lang.Integer
uses java.lang.Double
uses java.lang.Math

var compose = \ output : block(out : Integer) : String, func : block(param: Double) : Integer -> \ arg : Double -> func(output(arg)) //Definition

var floorToString = compose(\ out -> out.toString(), \ param -> Math.floor(param)) //Usage

print(floorToString(121.212121))

Continuation

The part of the code that's yet to be executed.

uses java.lang.Double

var printAsString = \ num : Double -> print("Given ${num}")

var addOneAndContinue = \ num: Double, cc : block(___num : Double) -> {
  var result = num + 1
  cc(result)
}

addOneAndContinue(2, printAsString)

Purity

A function is pure if the return value is only determined by its input values, and does not produce side effects.

var greet = \ name: String -> print("Hello ${name}")
greet("World")

The following is not pure since it modifies state outside of the function:

var greeting : String
var greet = \ name: String -> {greeting ="Hello ${name}"}
greet("World")
print(greeting)

Side Effects

A function or expression is said to have a side if apart from returning a value, it interacts with (reads from or writes to) external mutable state.

var currentDate = java.util.Date.CurrentDate //Retrieves the date from the system.
print(currentDate)

gw.api.util.Logger.forCategory("side-effect").info('IO is a side effect!')

Idempotent

A function is idempotent if reapplying it to its result does not produce a different result.

print(java.lang.Math.abs(java.lang.Math.abs(10)))

Point-Free Style (Tacit Programming)

Write functions where the definition does not explicitly identify the arguments used. This style usually requires currying or other higher order functions.

uses java.lang.Integer

// Given
var map = \ fn : block(item : int) : int -> \ list : List<Integer> -> list.map<Integer>(\ item -> fn(item))
var add = \ a : int -> \ b : int -> a + b
var nums : List<Integer> = (0..5).toList()

// Not points-free - 'numbers' is an explicit argument
var incrementAll = \ numbers : List<Integer> -> map(add(1))(numbers)

print(incrementAll(nums))

// Points-free - The list is an implicit argument
var incrementAll2 = map(add(1))

print(incrementAll2(nums))

Predicate

A function that returns true or false for a given value.

var predicate = \ a : int -> a > 2

print((1..4).where(\ a -> predicate(a)))

Lambda

An anonymous function that can be treated like a value.

(\ a : int -> a + 1)(1)

Lambda can be assigned to a variable

var add1 = \ a : int -> a + 1
print(add1(1))

Reference

https://github.com/hemanth/functional-programming-jargon
https://en.wiktionary.org/wiki/second-class_object#English
https://en.wiktionary.org/wiki/third-class_object#English

Gosu Collection Enhancements Functions

flatMap

Maps each element of the Collection to a Collection of values and then flattens them into a single List.

Syntax

flatMap<R>(mapper(item : Collection<?>) : Collection<R>) : List<R>

Example

var items = {{1},{2,2},{3,3,3},{4,4,4,4}}
print(items.flatMap(\ ___item -> ___item))
Output
[1, 2, 2, 3, 3, 3, 4, 4, 4, 4]

fold

Accumulates the values of an Collection into a single T.

Syntax

fold(aggregator(aggregate : T, item : T) : T) : T

Example

var items = {{1},{2,2},{3,3,3},{4,4,4,4}}
var flatItems = items.flatMap(\ ___item -> ___item)
print(flatItems.fold(\ ___aggr, ___item -> ___aggr + ___item))
Output
30

intersect

Returns a Set that is the intersection of the two Collection objects.

Syntax

intersect(that: Collection<T>) : Set<T>

Example

var items1 = {1,2,3,4,5,6}
var items2 = {4,5,6,7,8,9}
print(items1.intersect(items2))
Output
[4, 5, 6]

map

Returns a List of each element of the Collection mapped to a new value.

Syntax

map<Q>(mapper(item : <INPUT>) : <Q>) : List<Q>

Example

var numbers = {1,2,3}
var words = {"one","two","three"}
print(numbers.map(\ ___number -> words[___number-1]))
Output
[one, two, three]

partition

Partitions this Collection into a Map of keys to a list of elements in this Collection.

Syntax

partition<Q>(partitioner(item : R) : Q) : Map<Q, List<R>>

Example

var numbers = {1,2,3,4,5,6,8}
print(numbers.partition<String>(\ ___number -> ___number % 2 == 0 ? "even" : "odd"))
Output
{even=[2, 4, 6, 8], odd=[1, 3, 5]}

reduce

Accumulates the values of a Collection into a single V given an initial seed value

Syntax

reduce<T>(init : T, aggregrator(aggregate: T, item : ?) : T) : T

Example

var numbers = {1,2,3,4,5,6,8}
var sumOfNumbers = numbers.reduce(0, \ ___aggr, ___number -> ___aggr + ___number)
print(sumOfNumbers)
Output
29

union

Returns a new Set that is the union of the two Collections

Syntax

union(that : Collection<T>) : Set<T>

Example

var items1 = {1,2,3,4,5,6}
var items2 = {4,5,6,7,8,9}
print(items1.union(items2))
Output
[1, 2, 3, 4, 5, 6, 7, 8, 9]

disjunction

Returns a new Set that is the set disjunction of this collection and the other collection

Syntax

disjunction(that : Collection<T>) : Set<T>

Example

var items1 = {1,2,3,4,5,6}
var items2 = {4,5,6,7,8,9}
print(items1.disjunction(items2))
Output
[1, 2, 3, 7, 8, 9]

join

Joins all elements together as a string with a delimiter

Syntax

join(delim : String) : String

Example

var words = {"Hello", "World"}
print(words.join(" "))
Output
Hello World

Parallel Extensions

This extension calculates the most efficient way of dividing the task to the different cores available.

Note: Parallel extensions will block the calling thread.

Method Description
Parallel.For Executes for that may run in parallel.
Parallel.ForEach Executes foreach that may run in parallel.
Parallel.Invoke Executes actions that may run in parallel.

Asynchronous Programming Keywords

Async modifier

A modifier that indicates that the method can be run asynchornously.

Await keyword

Wait for a result of the asynchronous operation once the data is available without blocking the current thread. It also validates the success of the asynchronous operation. If everything is good, the execution will continue after the await keywords on its original thread.

Task.Run method

Run a task on a separate thread

ContinueWith Method

A task method that will be invoked after the running async task has returned a result.
The parameter TaskContinuationOption of this method can be use to control if the continue must be invoked if there are no exception or only with exception.

CancellationTokenSource

CancellationTokenSource is used to signal that you want to cancel an operation that utilize the token. This token be passed as a second parameter for the Task.Run method.

Dispatcher.Invoke() in WPF

Communicate with the thread that owns our UI.

ConcurrentBag Class

A thread safe collection.

Cyclomatic Complexity

Cyclomatic complexity is the count of linearly independent paths in a program's source code. With the help of control flow graph, we can use the following formula to calculate this:

CC = E - N + 2P

Variable Description
E The number of edges in the control flow graph.
N The number of nodes in the control flow graph.
P The number of connected components. This has a value of 1 if you are computing at the method (i.e. function or subroutine) level.

Related
Control Flow Graph