Skip to content

Kadrekka is a library that aims to make Kotlin more accessible to the northern italian population

Notifications You must be signed in to change notification settings

MMarco94/Kadrekka

Repository files navigation

Kadrekka

Kadrekka is a library that aims to make Kotlin more accessible to the northern italian population.
It provides lots of utility functions to make the code more readable and writable by every fellow polentone.

Install

Gradle

dependencies {
    implementation 'io.github.mmarco94:kadrekka:0.2-alpha'
}

The language

Northern italians are concrete people. It's very hard for them to reason in abstract terms.
For example, the basic unit of information in Kotlin is a Boolean: a type that encapsulate the truthfulness of a variable. For us northern italians, that makes very little sense.

Kadrekka's basic unit of information is instead a much more concrete type: TerraDOrigine.
Like a Boolean, TerraDOrigine can only take two values: polentun or terun.
Unlike a Boolean, a TerraDOrigine is easy to picture, interact with and understand [1].

For compatibility reasons, a polentun is equivalent to the Boolean true, while terun is equivalent to the Boolean false.

Control statement

Again, northern italians are concrete people. It makes little sense to use hypothetical statements like if or while. We use more concrete tests.

testDellaCadrega

Kadrekka borrows one of the most effective tests to determine the TerraDOrigine of a variable: il test della Cadrega (the test of the Cadrega).

testDellaCadrega is the most basic control flow expression. It will execute the given body block only when TerraDOrigine is polentun. For example:

val telChi: TerraDOrigine = ...
testDellaCadrega(telChi) {
    dighe("Tel chi l'è un polentun")
}

prendaPureUnaCadrega

prendaPureUnaCadrega is a more advanced control flow function. It allows running two different code blocks, based on the given TerraDOrigine. For example:

val telChi: TerraDOrigine = ...
prendaPureUnaCadrega(telChi)
    .sedia { dighe("Tel chi l'è un polentun") }
    .mela { dighe("Tel chi l'è un terun") }

ChesQui

chesQui is an even more flexible expression, capable executing the right code block, based on more advanced discriminations. For example:

val cosa: Roba = 1991
chesQui(cosa)
    .lÈUn(5) { dighe(5) }
    .lÈIn(1..3) { dighe("1-3") }
    .lÈUn { n: Numero -> dighe("L'è un numero") }
    .unaCadregaNonSiRifiutaANissun { dighe("Non se sa") }

Only the first block that matches the condition is executed.

unaCadregaNonSiRifiutaANissun is executed if none of the previous conditions matched.

IngannoDellaCadrega

ingannoDellaCadrega allows to quickly assert that the given TerraDOrigine is polentun. Otherwise, it will throw a ChesQuiLÈUnTerunException. For example:

fun sbriga(s: String) {
    ingannoDellaCadrega(s.isNotEmpty()) // Asserts that s is not empty
    ...
}

BussanoAQuestOraDelMattino

bussanoAQuestOraDelMattino can be used to execute multiple times the given code block. It takes two forms:

  1. bussanoAQuestOraDelMattino { <terra d'origine> } chiSaràMai { <code block> }
  2. bussanoAQuestOraDelMattino(<Iterable>) { <code block> }

For example:

var cnt = 0
bussanoAQuestOraDelMattino { cnt < 4 } chiSaràMai {
    siga("$cnt: Sono il Conte DRACULA")
    cnt++
}
bussanoAQuestOraDelMattino(1..4) { cnt ->
    siga("$cnt: Sono il Conte DRACULA")
}

Both the snippets above execute the given code block 4 times.

GuardaGliZigomi

guardaGliZigomi allows to execute a code block, catching any exception of the given type. For example:

guardaGliZigomi {
    ...
} sonProprioBassi { e: ChesQuiLÈUnTerunException ->
    dighe("T'ha salvato la campanella")
}

Dighe and Siga

dighe prints the given variable on the standard output. siga does the same, but the expression is converted to uppercase first.

OhMadonna and Mariaaa

ohMadonna and Mariaaa are equivalent to dighe and siga, but they print on the standard error instead.

PONTE_SULLO_STRETTO

Equivalent to Kotlin's TODO, PONTE_SULLO_STRETTO allows marking unfinished part of your code.
For example, the following snippet compiles, even though the return type of the function doesn't match:

fun sbriga(s: String): Intero {
    PONTE_SULLO_STRETTO("Mancano i soldi")
}

Equality

Equality can be checked with the or lÈUn infix function (e.g. telChi lÈUn terun).

Instance equality (i.e. Kotlin's ===), can be checked with the lÈProprio or lÈProprioUn infix function (e.g. telChi lÈProprioUn terun).

Instance check (i.e. Kotlin's is), can be performed with the lÈUn<T>() function (e.g. dü.lÈUn<Intero>()).

Numbers

Katrekka provides constants for the first 20 (vint) numbers. For example:

ingannoDellaCadrega(vün + dü lÈ trì) // Asserts that 1 + 2 == 3

La Bella La Và Al Fosso

Katrekka provides the lines of the "La Bella La Và Al Fosso" in the laBellaLaVàAlFosso constant. If you need them to repeat indefinitely (for example, to generate a Lorem Ipsum text), you can use the included infinite sequence laBellaLaVàSempreAlFosso.

For example, to keep singing until transilvaniaLiberaDaiMeridionali(), you can use:

laBellaLaVàSempreAlFosso
    .takeUntil { transilvaniaLiberaDaiMeridionali() }
    .forEach { siga(it) }

Miscellaneous functions

Function Kotlin's equivalent Example
lÈPejoDe() <= quelLà lÈPejoDe me
lÈProprioPejoDe() < quelLà lÈProprioPejoDe me
vienPrimaDe() < dü vienPrimaDe trì
lÈMejoDe() >= quelLà lÈMejoDe me
lÈProprioMejoDe() > quelLà lÈProprioMejoDe me
vienDopoDe() > trì vienDopoDe dü
lÈIn() in dü lÈIn setOf(1, 2, 3)
spaccàIn() / des spaccàIn dü lÈ cinch

Examples

Recursive binary search

Kotlin (taken from Rosetta code):

fun <T : Comparable<T>> Array<T>.binarySearch(target: T, lo: Int, hi: Int): Int {
	if (hi < lo) return -1

	val guess = (hi + lo) / 2

	return when {
		this[guess] > target -> binarySearch(target, lo, guess - 1)
		this[guess] < target -> binarySearch(target, guess + 1, hi)
		else -> guess
	}
}

What is this?! Only fancy intellectuals are able to understand this blob.
Let's see Katrekka's equivalent:

fun <T : Comparable<T>> Array<T>.trova(cosa: T, daChì: Intero, aLà: Intero): Intero {
	testDellaCadrega(aLà vienPrimaDe daChì) {
		return -vün
	}

	val centro = (aLà + daChì) spaccàIn dü

	return chesQui(this[centro])
		.vienDopoDe(cosa) { trova(cosa, daChì, centro - vün) }
		.vienPrimaDe(cosa) { trova(cosa, centro + vün, aLà) }
		.unaCadregaNonSiRifiutaANissun { centro }
}

Now, that's better.

Iterative binary search

Kotlin:

fun <T : Comparable<T>> Array<T>.iterativeBinarySearch(target: T): Int {
	var hi = size - 1
	var lo = 0
	while (hi >= lo) {
		val guess = lo + (hi - lo) / 2
		when {
			this[guess] > target -> hi = guess - 1
			this[guess] < target -> lo = guess + 1
			else -> return guess
		}
	}
	return -1
}

Katrekka's equivalent:

fun <T : Comparable<T>> Array<T>.iterativeTrova(cosa: T): Intero {
	var daChì = zero
	var aLà = size - vün
	bussanoAQuestOraDelMattino { daChì vienPrimaDe aLà } chiSaràMai {
		val centro = (aLà + daChì) spaccàIn dü
		chesQui(this[centro])
			.vienDopoDe(cosa) { aLà = centro - vün }
			.vienPrimaDe(cosa) { daChì = centro + vün }
			.unaCadregaNonSiRifiutaANissun { return centro }
	}
	return -vün
}

Wow, even a newborn polentun could understand that!

Appendix

[1] = For some people, it may be easier to understand a polentun rather than a terun.

About

Kadrekka is a library that aims to make Kotlin more accessible to the northern italian population

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages