diff --git a/README.md b/README.md index 880b20c..3e26330 100644 --- a/README.md +++ b/README.md @@ -18,8 +18,8 @@ 16. Стоит ли использовать scope функции везде, где это возможно. 17. Чем отличается arrayListOf()` от `mutableListOf()`? 18. List в Kotlin всегда реализует List в Java при интеропе? -19. Можно ли сделать собствен карту get и set при помощи квадратных скобок? -20. В чем отличие forEach в стандартной библиотеке Котлин и Java? +19. Можно ли сделать собственную реализацию карты с get и set при помощи квадратных скобок? +20. В чем отличие forEach на карте в стандартной библиотеке Котлин и Java? 21. Как работают функции componentN? 22. Почему в Котлин нет диапазонов для чисел с плавающей точкой? 23. Какой оператор должен быть реализован типе для того, чтобы он стал делегатом? diff --git a/notebooks/Idioms.ipynb b/notebooks/Idioms.ipynb index f710f6b..c1ac804 100644 --- a/notebooks/Idioms.ipynb +++ b/notebooks/Idioms.ipynb @@ -76,9 +76,7 @@ }, { "cell_type": "code", - "source": [ - "println(\"This is a plain string\")" - ], + "source": "println(\"This is a plain string\")", "metadata": { "datalore": { "node_id": "FFW0GaV6uhemvZxlpnjpFL", @@ -140,9 +138,7 @@ }, { "cell_type": "code", - "source": [ - "println(\"This is a string with \\$\")" - ], + "source": "println(\"This is a string with \\$\")", "metadata": { "datalore": { "node_id": "hm9iYlWj1B2S0469GtxDrf", @@ -418,12 +414,12 @@ { "cell_type": "code", "source": [ - "fun returnFunction(): (String) -> Unit{\n", + "fun returnFunction(): (String) -> Unit {\n", " fun printStringWithPrefix(str: String){\n", " println(\"Prefixed: $str\")\n", " }\n", " return ::printStringWithPrefix\n", - " // return { printStringWithPrefix(it) }\n", + " //return { printStringWithPrefix(it) }\n", " // return { println(\"Prefixed: $it\") }\n", "}\n", "\n", @@ -467,7 +463,7 @@ "cell_type": "code", "source": [ "\n", - "fun returnUnit(): Unit{\n", + "fun returnUnit(): Unit {\n", " // no return statement `Unit` is returned implicitly\n", " val b = Unit\n", "}" @@ -487,6 +483,20 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "fun doNothing(){\n", + " \n", + "}\n", + "\n", + "val a = doNothing()\n", + "a::class" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "markdown", "source": [ @@ -554,8 +564,11 @@ " x * x + 2 * x + 1\n", "}\n", "integrate(0.0, PI) { sin(it) }\n", + "// integrate(0.0, PI) //error\n", "integrate(0.0, step = 0.02, to = PI) { sin(it) }\n", - "//integrate(0.0, step = 0.02, PI) { sin(it) }" + "//integrate(0.0, step = 0.02, PI) { sin(it) }\n", + "\n", + "integrate(0.0, step = 0.02, function = { sin(it) }, to = PI)" ], "metadata": { "datalore": { @@ -568,6 +581,25 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "fun functionWithParameters(){\n", + " println(\"without default\")\n", + "}\n", + "\n", + "//@JvmOverloads\n", + "@JvmName(\"functionWithDefaultParameters\")\n", + "fun functionWithParameters(a: Int = 2){\n", + " println(\"with default\")\n", + "}\n", + "\n", + "functionWithParameters()" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "markdown", "source": [ @@ -631,7 +663,7 @@ "source": [ "data class BuildResult internal constructor(val str: String, val int: Int, val optional: Double?){\n", " init{\n", - " require(optional!= null){\"null!\"}\n", + " require(optional!= null){ \"null!\" }\n", " }\n", "}\n", "\n", @@ -644,13 +676,15 @@ " fun build() = BuildResult(str, int, optional)\n", "}\n", "\n", - "fun doWithBuilder(defaultInt: Int, block: Builder.() -> Unit): BuildResult = \n", + "fun BuildResult(defaultInt: Int, block: Builder.() -> Unit): BuildResult = \n", " Builder(int = defaultInt).apply(block).build()\n", "\n", - "doWithBuilder(2){\n", + "val res = BuildResult(2){\n", " str = \"ff\"\n", " optional = 1.0\n", - "}" + "}\n", + "\n", + "res" ], "metadata": { "datalore": { @@ -736,7 +770,7 @@ " fun doSomething(): Unit = TODO()\n", "}\n", "\n", - "//voldemort.doSomething()" + "// voldemort.doSomething()" ], "metadata": { "datalore": { @@ -749,6 +783,31 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "fun interface Float64Function: (Double) -> Double {\n", + " override operator fun invoke(arg: Double): Double\n", + " \n", + " operator fun invoke(doubles: DoubleArray): DoubleArray = DoubleArray(doubles.size){ invoke( doubles[it]) }\n", + "}\n", + "\n", + "val sin = object : Float64Function{\n", + " override fun invoke(p1: Double): Double = sin(p1)\n", + "}\n", + "\n", + "val cos = Float64Function{ kotlin.math.cos(it) }\n", + "\n", + "val tg = Float64Function(::tan)\n", + "\n", + "sin(PI/2)\n", + "\n", + "sin(doubleArrayOf(0.0, PI/2))" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "markdown", "source": [ @@ -775,6 +834,10 @@ "\n", "interface Consumer{\n", " fun consume(value: T)\n", + "}\n", + "\n", + "interface Doer: Producer, Consumer {\n", + "\n", "}" ], "metadata": { @@ -825,6 +888,13 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": "fun transformIf(flag: Boolean): Int = if (flag) 1 else 0 ", + "outputs": [], + "execution_count": null + }, { "cell_type": "markdown", "source": [ @@ -850,7 +920,7 @@ "/**\n", " * Matching by type\n", " */\n", - "fun checkType(arg: Any): Unit = when(arg){\n", + "fun checkType(arg: Any): Unit = when (arg) {\n", " is String -> println(\"I am a String. Length is ${arg.length}\")\n", " is Int -> println(\"I am an Int.\")\n", " is Double -> println(\"I am a Double\")\n", @@ -858,11 +928,11 @@ " else -> println(\"I don't know who am I?\")\n", "}\n", "\n", - "fun checkType2(arg: Any): Unit = when{\n", + "fun checkType2(arg: Any): Unit = when {\n", " arg is String -> println(\"I am a String\")\n", " arg is Int -> println(\"I am an Int\")\n", " arg is Double -> println(\"I am a Double\")\n", - " 2==2 -> println(\"Wat?\")\n", + " 2 == 2 -> println(\"Wat?\")\n", " else -> println(\"I don't know who am I?\")\n", "}\n", "\n", @@ -899,11 +969,11 @@ "cell_type": "code", "source": [ "fun tryCatch() {\n", - " val result = try {\n", + " val result: Int = try {\n", " 22\n", " } catch (e: ArithmeticException) {\n", " throw IllegalStateException(e)\n", - " } finally{\n", + " } finally {\n", " println(\"finally\")\n", " }\n", "\n", @@ -930,6 +1000,7 @@ " 4\n", "}\n", "\n", + "println(res.exceptionOrNull())\n", "(res.getOrNull() ?: 0) + 1" ], "metadata": { @@ -946,18 +1017,18 @@ { "cell_type": "code", "source": [ - "val dataFlow = sequence{\n", + "val dataFlow = sequence {\n", " var i = 0\n", - " while(true){\n", + " while (true) {\n", " yield(i++)\n", " }\n", "}\n", "\n", - "dataFlow.map { \n", - " runCatching { \n", - " if(it%2 ==0) error(\"Even: $it\") else it\n", + "dataFlow.map {\n", + " runCatching {\n", + " if (it % 2 == 0) error(\"Even: $it\") else it\n", " }\n", - "}.take(10).toList()" + "}.take(10).toList().joinToString(separator = \"\\n\")" ], "metadata": { "datalore": { @@ -999,6 +1070,12 @@ " return found + 2\n", "}\n", "\n", + "//FIXME don't do that\n", + "fun dontDoThat() {\n", + " if (true) return\n", + " println(false)\n", + "}\n", + "\n", "fun checkCondition(): Int {\n", " fun conditionSatisfied() = false\n", "\n", @@ -1045,7 +1122,7 @@ "}\n", "\n", "\n", - "data class DataClass(val a: Int, val b: Double) {\n", + "data class DataClass(val a: Int, var b: Double /*, d: Double */) {\n", " val c get() = b + 1\n", "}\n", "\n", @@ -1086,7 +1163,6 @@ { "cell_type": "code", "source": [ - "\n", "/**\n", " * Nullable truth.\n", " */\n", @@ -1122,6 +1198,27 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "import java.util.Optional\n", + "import kotlin.reflect.typeOf\n", + "\n", + "println(typeOf>() == typeOf>>())\n", + "\n", + "println( typeOf() == typeOf()) " + ], + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "code", + "source": "mapOf().get(\"f\")!!", + "outputs": [], + "execution_count": null + }, { "cell_type": "markdown", "source": [ @@ -1169,7 +1266,7 @@ "// printNotNull(null) does not work\n", "\n", "val value: Int? = 2\n", - "//val value: Int? by lazy{ 2 }\n", + "//val value: Int? by lazy { 2 }\n", "\n", "//printNotNull(value) // Error\n", "if (value != null) {\n", @@ -1305,6 +1402,13 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": "", + "outputs": [], + "execution_count": null + }, { "cell_type": "code", "source": [ @@ -1323,6 +1427,26 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": "", + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "val functionWithReciever: List.(arg: Int) -> Unit = {arg->\n", + " println(get(arg))\n", + "}\n", + "\n", + "listOf(\"1\", \"2\", \"3\").functionWithReciever(1)" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "markdown", "source": [ @@ -1458,7 +1582,7 @@ "// Using `with`\n", "val res = with(AClass){\n", " // AClass type is the receiver in this scope\n", - " println(\"a = $a, b = $b, c = $c\")\n", + " println(\"a = ${this.a}, b = $b, c = $c\")\n", " /*return@with*/ \"some value\"\n", "}\n", "\n", @@ -1475,17 +1599,36 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "object AContext{\n", + " fun AClass.abc() = a + b + c // warning additional concatenation\n", + "}\n", + "\n", + "fun printAbc(aClass: AClass) = with(AContext){\n", + " aClass.abc()\n", + "}" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "code", "source": [ "\n", "//using `run`\n", - "getAClass()?.run {\n", + "getAClass()?.takeIf { it.a.isNotEmpty() }?.run {\n", " // the same as above\n", " println(\"a = $a, b= $b, c = $c\")\n", " 2\n", "}\n", "\n", + "val runResult: Int = run {\n", + " \n", + "}\n", + "\n", "//Using `let` to compose result. Not recommended using without a need\n", "val letResult = getAClass()?.let { arg ->\n", " arg.c + arg.a\n", @@ -1502,6 +1645,16 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "//Don't do that\n", + "fun scopeAbuse(str: String?) = str.takeIf { it?.isNotEmpty() == true }?.let { it.substring(0..4) }?.let { it.matches(\".*\".toRegex())}" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "markdown", "source": [ @@ -1615,12 +1768,13 @@ "/**\n", " * This method creates a read-only list of strings. One should note that the type of the list is not specified\n", " */\n", - "val list = listOf(\"a\", \"b\", \"c\")\n", + "val list: List = listOf(\"a\", \"b\", \"c\")\n", "\n", "println(list[0])\n", "println(list.get(1))\n", "//println(list.get(4))\n", - "println(list.getOrNull(4) ?: \"nothing\")" + "println(list.getOrNull(4) ?: \"nothing\")\n", + "list::class" ], "metadata": { "datalore": { @@ -1657,6 +1811,19 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "\n", + "//don't do that ever\n", + "fun doBadThingWithList(list: List): List = (list as MutableList).apply { add(\"something\") }\n", + "\n", + "doBadThingWithList(listOf(\"a\", \"b\", \"c\"))" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "code", "source": [ @@ -1673,6 +1840,29 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "val mutableList = mutableListOf(1,2,3)\n", + "\n", + "fun consumeList(list: List){\n", + " println(list.joinToString())\n", + "}\n", + "consumeList(mutableList)\n", + "mutableList.add(4)\n", + "consumeList(mutableList)" + ], + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "code", + "source": "listOf(1,2) + listOf(3,4)", + "outputs": [], + "execution_count": null + }, { "cell_type": "code", "source": [ @@ -1691,20 +1881,33 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "val writableList = mutableListOf(\"a\", \"b\") // Warning!\n", + "writableList += setOf(\"c\")\n", + "writableList" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "code", "source": [ "\n", "/**\n", - " * This one creates a mutable ArrayList.\n", - " */\n", + " * This one creates a mutable ArrayList.\n", + " */\n", "val arrayList: ArrayList = arrayListOf(\"a\", \"b\", \"c\")\n", "\n", + "//ArrayList()\n", + "\n", "//Danger zone\n", - "\n", - "val newList: List = list + \"f\" + mutableList\n", - "\n", - "println(newList)" + "//\n", + "//val newList: List = list + \"f\" + mutableList\n", + "//\n", + "//println(newList)" ], "metadata": { "datalore": { @@ -1726,8 +1929,7 @@ "val lambdaList = List(3){ it.toString() }\n", "println(lambdaList)\n", "\n", - "\n", - "val builderList: List = buildList{\n", + "val builderList: List = buildList {\n", " add(2)\n", " add(8)\n", " remove(8)\n", @@ -1802,6 +2004,13 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": "", + "outputs": [], + "execution_count": null + }, { "cell_type": "markdown", "source": [ @@ -1826,6 +2035,7 @@ ")\n", "\n", "//The map could be accessed via indexing operation\n", + "println(map::class)\n", "println(map[\"key\"])\n", "map[\"key\"] = \"fff\"\n", "println(map[\"key\"])\n", @@ -1848,10 +2058,12 @@ "\n", "//val entry: MutableMap.MutableEntry = map.iterator().next()\n", "\n", + "//map.entries.first().component2()\n", + "\n", "/**\n", " * The destructuring declaration for maps and other objects that support `operator fun componentN`\n", " */\n", - "for ((k, v) in map) {\n", + "for ((k: String, v) in map) {\n", "//val (k, v) = entry\n", "// val k = entry.component1()\n", "// val v = entry.component2()\n", @@ -1871,9 +2083,7 @@ }, { "cell_type": "code", - "source": [ - "map.forEach { (k, v) -> println(\"$k -> $v\")}" - ], + "source": "map.forEach { (k, v) -> println(\"$k -> $v\")}", "metadata": { "datalore": { "node_id": "s1Q65aNWb9YNBZOgxmjotW", @@ -1897,7 +2107,7 @@ "\n", "data class Coordinate(val x: Double, val y: Int)\n", "\n", - "val (x1, y1) = Coordinate(1.0,2)" + "val (x1, y1) = Coordinate(1.0, 2)" ], "metadata": { "datalore": { @@ -1940,6 +2150,11 @@ "\n", " private val _list: MutableList = ArrayList()\n", " val list: List get() = _list\n", + " \n", + " fun add(int: Int){\n", + " require(int>0)\n", + " _list.add(int)\n", + " }\n", "}\n", "\n", "\n", @@ -1947,6 +2162,7 @@ "val obj = AClassWithList()\n", "\n", "// obj.b = 10.0 //error\n", + "obj.add(42)\n", "obj.list.add(43)" ], "metadata": { @@ -1960,199 +2176,6 @@ "outputs": [], "execution_count": null }, - { - "cell_type": "markdown", - "source": [ - "## Contains operator and ranges" - ], - "attachments": {}, - "metadata": { - "datalore": { - "node_id": "GKoCVcgdnSYPjsNCAJIkBB", - "type": "MD", - "hide_input_from_viewers": true, - "hide_output_from_viewers": true - } - } - }, - { - "cell_type": "code", - "source": [ - "\n", - "val emailsList = emptyList()\n", - "\n", - "// When used directly infix in operator checks if the element is contained in a collection\n", - "//using `operator fun contains`\n", - "\n", - "if (\"john@example.com\" in emailsList) {\n", - " println(\"is in list\")\n", - "}\n", - "\n", - "if (\"jane@example.com\" !in emailsList) {\n", - " println(\"not in list\")\n", - "}" - ], - "metadata": { - "datalore": { - "node_id": "4mh1Lg6g8OWEIC1Qjgp9tN", - "type": "CODE", - "hide_input_from_viewers": true, - "hide_output_from_viewers": true - } - }, - "outputs": [], - "execution_count": null - }, - { - "cell_type": "code", - "source": [ - "\n", - "\n", - "class DateRange(val start: Instant, val end: Instant)\n", - "\n", - "operator fun DateRange.contains(value: Instant): Boolean = value > start && value < end\n", - "\n", - "\n", - "println(Instant.now() in DateRange(Instant.EPOCH, Instant.MAX))" - ], - "metadata": { - "datalore": { - "node_id": "1N4A00CAksn2nVg57DRKnp", - "type": "CODE", - "hide_input_from_viewers": true, - "hide_output_from_viewers": true - } - }, - "outputs": [], - "execution_count": null - }, - { - "cell_type": "code", - "source": [ - "\n", - "// Another (different) use of `in` is iteration over range or collection using\n", - "// using `operator fun iterator`\n", - "\n", - "for (i in 1..100) {\n", - " println(i)\n", - "} // closed range: includes 100\n", - "\n", - "(1..100).forEach { i ->\n", - " println(i)\n", - "} //the same, but with boxing\n", - "\n", - "for (i in 1..<100) {\n", - " println(i)\n", - "} // half-open range: does not include 100\n", - "\n", - "for (x in 2..10 step 2) {\n", - " println(x)\n", - "}\n", - "for (x in 10 downTo 1) {\n", - " println(x)\n", - "}\n", - "\n", - "infix fun ClosedRange.step(step: Double): Sequence {\n", - " //TODO check arguments\n", - " var current = start\n", - " return sequence {\n", - " do {\n", - " yield(current)\n", - " current += step\n", - " } while (current <= endInclusive)\n", - " }\n", - "}\n", - "\n", - "for (x in 0.0..10.0 step 0.5){\n", - " println(x)\n", - "}" - ], - "metadata": { - "datalore": { - "node_id": "hwJfUD7H5mDtjStAsGppk7", - "type": "CODE", - "hide_input_from_viewers": true, - "hide_output_from_viewers": true - } - }, - "outputs": [], - "execution_count": null - }, - { - "cell_type": "markdown", - "source": [ - "## Map-reduce" - ], - "attachments": {}, - "metadata": { - "datalore": { - "node_id": "IsJiqd43JpY7BnZTeHNU4M", - "type": "MD", - "hide_input_from_viewers": true, - "hide_output_from_viewers": true - } - } - }, - { - "cell_type": "code", - "source": [ - "val list: List = listOf(1, 2, 3, 4, 5, 6)\n", - "\n", - "val result = list\n", - " //.stream().parallel()\n", - " //.asSequence()\n", - " .filter { it % 2 == 0 } //select even numbers\n", - " .map { it * it } // get square of each element\n", - " //.onEach { println(it) }\n", - " .sumOf { it } //use one of reduce operations\n", - " //.reduce { acc: Int, i: Int -> acc + i }\n", - "\n", - "result" - ], - "metadata": { - "datalore": { - "node_id": "KKT62bidVYF8I147heptAS", - "type": "CODE", - "hide_input_from_viewers": true, - "hide_output_from_viewers": true - } - }, - "outputs": [], - "execution_count": null - }, - { - "cell_type": "code", - "source": [ - "val sequence = sequence {\n", - " var counter = 1\n", - " while(true){\n", - " yield(counter++)\n", - " yield(counter++)\n", - " // println(counter)\n", - " }\n", - "}\n", - "\n", - "val result = sequence\n", - " .take(6)\n", - " .filter { it % 2 == 0 } //select even numbers\n", - " .map { it * it } // get square of each element\n", - " //.onEach { println(it) }\n", - " //.sumOf { it } //use one of reduce operations\n", - " .reduce { acc: Int, i: Int -> acc + i }\n", - "\n", - "result" - ], - "metadata": { - "datalore": { - "node_id": "9qcw7ejFSF8QnAGdf1bAI0", - "type": "CODE", - "hide_input_from_viewers": true, - "hide_output_from_viewers": true - } - }, - "outputs": [], - "execution_count": null - }, { "cell_type": "markdown", "source": [ @@ -2176,7 +2199,7 @@ " add(it)\n", " }\n", "}\n", - "println(list)\n" + "println(list)" ], "metadata": { "datalore": { @@ -2189,6 +2212,218 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "data class ImmutableObject(val a: String, val b: String, val c: Int)\n", + "\n", + "class ImmutableObjectBuilder(a: String) {\n", + " var a: String = a\n", + " var b: String = \"\"\n", + " var c = 0\n", + " \n", + " fun build() = ImmutableObject(a, b, c)\n", + "}\n", + "\n", + "fun ImmutableObject(a: String, block: ImmutableObjectBuilder.() -> Unit): ImmutableObject =\n", + " ImmutableObjectBuilder(a).apply(block).build()\n", + "\n", + "ImmutableObject(\"aValue\") {\n", + " c = 99\n", + "}" + ], + "outputs": [], + "execution_count": null + }, + { + "metadata": { + "datalore": { + "node_id": "GKoCVcgdnSYPjsNCAJIkBB", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "cell_type": "markdown", + "source": "## Contains operator and ranges" + }, + { + "metadata": { + "datalore": { + "node_id": "4mh1Lg6g8OWEIC1Qjgp9tN", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "cell_type": "code", + "source": [ + "\n", + "val emailsList = emptyList()\n", + "\n", + "// When used directly infix in operator checks if the element is contained in a collection\n", + "//using `operator fun contains`\n", + "\n", + "if (\"john@example.com\" in emailsList) {\n", + " println(\"is in list\")\n", + "}\n", + "\n", + "if (\"jane@example.com\" !in emailsList) {\n", + " println(\"not in list\")\n", + "}" + ], + "outputs": [], + "execution_count": null + }, + { + "metadata": { + "datalore": { + "node_id": "1N4A00CAksn2nVg57DRKnp", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "cell_type": "code", + "source": [ + "import java.time.*\n", + "\n", + "class DateRange(val start: Instant, val end: Instant)\n", + "\n", + "operator fun DateRange.contains(value: Instant): Boolean = value > start && value < end\n", + "\n", + "\n", + "println(Instant.now() in DateRange(Instant.EPOCH, Instant.MAX))" + ], + "outputs": [], + "execution_count": null + }, + { + "metadata": { + "datalore": { + "node_id": "hwJfUD7H5mDtjStAsGppk7", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "cell_type": "code", + "source": [ + "\n", + "// Another (different) use of `in` is iteration over range or collection using\n", + "// using `operator fun iterator`\n", + "\n", + "for (i in 1..100) {\n", + " println(i)\n", + "} // closed range: includes 100\n", + "\n", + "(1..100).forEach { i ->\n", + " println(i)\n", + "} //the same, but with boxing\n", + "\n", + "for (i in 1..<100) {\n", + " println(i)\n", + "} // half-open range: does not include 100\n", + "\n", + "for (x in 2..10 step 2) {\n", + " println(x)\n", + "}\n", + "\n", + "for (x in 10 downTo 1) {\n", + " println(x)\n", + "}\n", + "\n", + "infix fun ClosedRange.step(step: Double): Sequence {\n", + " //TODO check arguments\n", + " var current = start\n", + " return sequence {\n", + " do {\n", + " yield(current)\n", + " current += step\n", + " } while (current <= endInclusive)\n", + " }\n", + "}\n", + "\n", + "for (x in 0.0..10.0 step 0.5){\n", + " println(x)\n", + "}" + ], + "outputs": [], + "execution_count": null + }, + { + "metadata": { + "datalore": { + "node_id": "IsJiqd43JpY7BnZTeHNU4M", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "cell_type": "markdown", + "source": "## Map-reduce" + }, + { + "metadata": { + "datalore": { + "node_id": "KKT62bidVYF8I147heptAS", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "cell_type": "code", + "source": [ + "val list: List = listOf(1, 2, 3, 4, 5, 6)\n", + "\n", + "val result = list\n", + " //.stream().parallel()\n", + " //.asSequence()\n", + " .filter { it % 2 == 0 } //select even numbers\n", + " .map { it * it } // get square of each element\n", + " //.onEach { println(it) }\n", + " //.sumOf { it } //use one of reduce operations\n", + " .reduce { acc: Int, i: Int -> acc + i }\n", + "\n", + "result" + ], + "outputs": [], + "execution_count": null + }, + { + "metadata": { + "datalore": { + "node_id": "9qcw7ejFSF8QnAGdf1bAI0", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "cell_type": "code", + "source": [ + "val sequence = sequence {\n", + " var counter = 1\n", + " while(true){\n", + " yield(counter++)\n", + " yield(counter++)\n", + " // println(counter)\n", + " }\n", + "}\n", + "\n", + "val result = sequence\n", + " .take(6)\n", + " .filter { it % 2 == 0 } //select even numbers\n", + " .map { it * it } // get square of each element\n", + " //.onEach { println(it) }\n", + " //.sumOf { it } //use one of reduce operations\n", + " .reduce { acc: Int, i: Int -> acc + i }\n", + "\n", + "result" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "markdown", "source": [ @@ -2207,6 +2442,9 @@ { "cell_type": "code", "source": [ + "import java.nio.file.*\n", + "\n", + "\n", "val stream = Files.newInputStream(Paths.get(\"file.txt\"))\n", "// The resource is automatically closed when leaving the scope\n", "stream.bufferedReader().use { reader ->\n", @@ -2298,11 +2536,7 @@ "source": [ "\n", "open class Bad{\n", - " val value: Int\n", - "\n", - " init {\n", - " value = requestValue()\n", - " }\n", + " val value: Int = requestValue()\n", "\n", " open fun requestValue(): Int {\n", " doSomethingElse()\n", @@ -2327,6 +2561,28 @@ "outputs": [], "execution_count": null }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "class BadString{\n", + " val value: String = requestValue()\n", + "\n", + " fun requestValue(): String {\n", + " doSomethingElse()\n", + " return \"2\"\n", + " }\n", + "\n", + " private fun doSomethingElse(){\n", + " println(value)\n", + " }\n", + "}\n", + "\n", + "BadString()" + ], + "outputs": [], + "execution_count": null + }, { "cell_type": "code", "source": [ @@ -2470,7 +2726,7 @@ " * The demonstration of use of inline [forEach] function with non-local return\n", " */\n", "fun foo(): Int {\n", - " listOf(1, 2, 3, 4, 5).forEach {\n", + " listOf(1, 2, 3, 4, 5).forEachOdd {\n", " if (it == 3) return it // non-local return directly to the caller of foo()\n", " print(\"$it, \")\n", " }\n", diff --git a/notebooks/Kotlin design patterns.ipynb b/notebooks/Kotlin design patterns.ipynb index ef68f24..b2e9d8c 100644 --- a/notebooks/Kotlin design patterns.ipynb +++ b/notebooks/Kotlin design patterns.ipynb @@ -1,39 +1,39 @@ { - "cells":[ + "cells": [ { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Sheet" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"Sheet", - "type":"MD", - "hide_input_from_viewers":false, - "hide_output_from_viewers":false, - "sheet_delimiter":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "Sheet", + "type": "MD", + "hide_input_from_viewers": false, + "hide_output_from_viewers": false, + "sheet_delimiter": true } } }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Factories" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"kfka3l54zO2cbMlMjZser7", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "kfka3l54zO2cbMlMjZser7", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "interface A{\n", " val body: String\n", "}\n", @@ -50,44 +50,36 @@ " println(obj)\n", "}" ], - "execution_count":9, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"w3yuNLSDBka2TYCaWojtxM", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "w3yuNLSDBka2TYCaWojtxM", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "print(C(\"My body\"))" ], - "execution_count":10, - "outputs":[ - { - "name":"stdout", - "text":[ - "My body C\n" - ], - "output_type":"stream" + "metadata": { + "datalore": { + "node_id": "uBjdJBVkelSda73M9M9KVt", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"uBjdJBVkelSda73M9M9KVt", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "interface AFactory{\n", " fun create(body: String): T\n", "}\n", @@ -98,129 +90,99 @@ "\n", "fun createWithAWord(word: String, factory: AFactory) = factory.create(\"Word: $word\")" ], - "execution_count":14, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"bOHAAqwHwERE2KjWbCpYnR", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "bOHAAqwHwERE2KjWbCpYnR", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "createWithAWord(\"Hello\", BFactory)" ], - "execution_count":15, - "outputs":[ - { - "data":{ - "text\/plain":[ - "Word: Hello B" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "FQCZ6JUVsv30zSrNgFusW9", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"FQCZ6JUVsv30zSrNgFusW9", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "fun createWithAWord(word: String, factoryFunction: (String) -> T) = factoryFunction(\"Word: $word\")" ], - "execution_count":17, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"A60omBLPluLVcheSHMCwbO", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "A60omBLPluLVcheSHMCwbO", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "createWithAWord(\"Hello\", ::B)" ], - "execution_count":19, - "outputs":[ - { - "data":{ - "text\/plain":[ - "Word: Hello B" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "NjSa4JlkOMYs1wcUFMkxqb", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"NjSa4JlkOMYs1wcUFMkxqb", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "createWithAWord(\"Hello\"){body -> B(\">\\t$body\")}" ], - "execution_count":21, - "outputs":[ - { - "data":{ - "text\/plain":[ - ">\tWord: Hello B" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "TvX8qzziDGxZWf044iqHO3", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"TvX8qzziDGxZWf044iqHO3", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Factory functions" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"3iPAMgURNX1IdwhklIXETa", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "3iPAMgURNX1IdwhklIXETa", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "data class Client(val url: String)\n", "\n", "interface Request{\n", @@ -228,108 +190,88 @@ "}\n", "\n", "data class RequestImpl(override val client: Client): Request{\n", - "\/\/ constructor(url: String): this(Client(url))\n", + "// constructor(url: String): this(Client(url))\n", "}" ], - "execution_count":2, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"yVwMw3CpejJHhnEQDCab6g", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "yVwMw3CpejJHhnEQDCab6g", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "fun Request(url: String): Request{\n", " return RequestImpl(Client(url))\n", "}" ], - "execution_count":4, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"72D1rEcXVM7hutTX65ouiE", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "72D1rEcXVM7hutTX65ouiE", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "Request(\"DDD\")" ], - "execution_count":5, - "outputs":[ - { - "data":{ - "text\/plain":[ - "RequestImpl(client=Client(url=DDD))" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "9Y1icG6BtLX5P0uF879Baq", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"9Y1icG6BtLX5P0uF879Baq", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "listOf(1,2,3)" ], - "execution_count":33, - "outputs":[ - { - "data":{ - "text\/plain":[ - "[1, 2, 3]" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "3yvFzSrCRK7m3o90gysDVm", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"3yvFzSrCRK7m3o90gysDVm", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Lazy" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"IttR7MZNzaf78FGtuNcLEx", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "IttR7MZNzaf78FGtuNcLEx", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class WithLazy{\n", " val prop = 2\n", " get(){\n", @@ -343,123 +285,87 @@ " }\n", "}" ], - "execution_count":12, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"h0jgOzZDe8PiryzcHnNdBG", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "h0jgOzZDe8PiryzcHnNdBG", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "val withLazy = WithLazy()" ], - "execution_count":13, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"5lXgZjAPOpwswgQpZIC0NO", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "5lXgZjAPOpwswgQpZIC0NO", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "withLazy.prop\n", "withLazy.prop\n", "withLazy.prop" ], - "execution_count":14, - "outputs":[ - { - "name":"stdout", - "text":[ - "Hit 2\n", - "Hit 2\n", - "Hit 2\n" - ], - "output_type":"stream" - }, - { - "data":{ - "text\/plain":[ - "2" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "C6VAvJWSYieH6LGfrgNvQ5", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"C6VAvJWSYieH6LGfrgNvQ5", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "withLazy.lazyProp\n", "withLazy.lazyProp\n", "withLazy.lazyProp" ], - "execution_count":15, - "outputs":[ - { - "name":"stdout", - "text":[ - "Hit lazy\n" - ], - "output_type":"stream" - }, - { - "data":{ - "text\/plain":[ - "2" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "rJLM2Kv6yvJQf9bNMpcsB9", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"rJLM2Kv6yvJQf9bNMpcsB9", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Builder" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"XYoUXQu8GD51C080v5thFD", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "XYoUXQu8GD51C080v5thFD", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "data class Buildable(\n", " var a: Int = 1,\n", " var b: Int = 2,\n", @@ -472,82 +378,62 @@ " }\n", "}\n", "\n", - "\/\/ Buildable.builder()\n", - "\/\/ .setA(1)\n", - "\/\/ .setB(2)\n", - "\/\/ .setC(3)\n", - "\/\/ .setABC(1)\n", - "\/\/ .build()" + "// Buildable.builder()\n", + "// .setA(1)\n", + "// .setB(2)\n", + "// .setC(3)\n", + "// .setABC(1)\n", + "// .build()" ], - "execution_count":7, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"nlm610q2oEsKlSDE1pXtkG", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "nlm610q2oEsKlSDE1pXtkG", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "Buildable(b = 5)" ], - "execution_count":8, - "outputs":[ - { - "data":{ - "text\/plain":[ - "Buildable(a=1, b=5, c=3)" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "EQoUX3r984KJvt9tkpy3Wd", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"EQoUX3r984KJvt9tkpy3Wd", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "Buildable().apply { \n", " a = 1\n", " setABC(a + b + c)\n", "}" ], - "execution_count":9, - "outputs":[ - { - "data":{ - "text\/plain":[ - "Buildable(a=6, b=6, c=6)" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "hJnD2AzKDTgYkrZoyf31Hd", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"hJnD2AzKDTgYkrZoyf31Hd", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "fun Buildable(block: Buildable.()-> Unit): Buildable = Buildable().apply(block)\n", "\n", "Buildable{ \n", @@ -555,45 +441,35 @@ " setABC(a + b + c)\n", "}" ], - "execution_count":11, - "outputs":[ - { - "data":{ - "text\/plain":[ - "Buildable(a=6, b=6, c=6)" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "eybgzzEc7H4Px2nL7CKvvt", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"eybgzzEc7H4Px2nL7CKvvt", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Multiton" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"g33v0kYJUYOULVwSfxeGhB", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "g33v0kYJUYOULVwSfxeGhB", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class Multiton private constructor(val name: String){\n", " init{\n", " println(\"Multiton $name created\")\n", @@ -606,91 +482,55 @@ " }\n", "}" ], - "execution_count":16, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"jWHHMghzB2djqbkxMUA6Tx", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "jWHHMghzB2djqbkxMUA6Tx", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "Multiton.resolve(\"a\")\n", "Multiton.resolve(\"a\")\n", "Multiton.resolve(\"b\")\n", "Multiton.resolve(\"a\")" ], - "execution_count":17, - "outputs":[ - { - "name":"stdout", - "text":[ - "Multiton a created\n", - "Multiton b created\n" - ], - "output_type":"stream" - }, - { - "data":{ - "text\/plain":[ - "Line_61_jupyter$Multiton@5271dd0f" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "lc75iGLEUf7H0uXMTaIXHx", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"lc75iGLEUf7H0uXMTaIXHx", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "Multiton(\"v\")" ], - "execution_count":18, - "outputs":[ - { - "name":"stderr", - "text":[ - "Line_67.jupyter.kts (1:1 - 9) Cannot access '': it is private in 'Multiton'" - ], - "output_type":"stream" - }, - { - "ename":"Syntax Error", - "evalue":"Syntax Error: Cannot access '': it is private in 'Multiton'", - "traceback":[ - "\u001b[0;31m---------------------------------------------------------------------------", - "Traceback (most recent call last)", - "Syntax Error: Cannot access '': it is private in 'Multiton'" - ], - "output_type":"error" + "metadata": { + "datalore": { + "node_id": "q7uzHnibwUrfQT3IbMmcce", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"q7uzHnibwUrfQT3IbMmcce", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "sealed interface SealedMultiton{\n", " object A: SealedMultiton\n", " object B: SealedMultiton\n", @@ -703,35 +543,35 @@ " is SealedMultiton.Custom -> println(sealed.body)\n", "}" ], - "execution_count":24, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"6GgWOmtJcF5yzCoPf7PbRE", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "6GgWOmtJcF5yzCoPf7PbRE", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Adapter" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"YfxaLKY0BwQjCnS48Fkh3z", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "YfxaLKY0BwQjCnS48Fkh3z", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "val array = doubleArrayOf(1.0,2.0)\n", "val list = listOf(1.0,2.0)\n", "\n", @@ -740,47 +580,39 @@ " println(l)\n", "}\n", "\n", - "fun convertArrayToList(array: DoubleArray): List = array.asList()\/\/List(array.size){i -> array[i]}\n", + "fun convertArrayToList(array: DoubleArray): List = array.asList()//List(array.size){i -> array[i]}\n", "\n", "consumeList(convertArrayToList(array))" ], - "execution_count":25, - "outputs":[ - { - "name":"stdout", - "text":[ - "[1.0, 2.0]\n" - ], - "output_type":"stream" + "metadata": { + "datalore": { + "node_id": "0r5gCS5ICD5utC3vtYhbOb", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"0r5gCS5ICD5utC3vtYhbOb", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Decorator?" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"jsc3UoWftQEDJuUInDWIpe", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "jsc3UoWftQEDJuUInDWIpe", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "@JvmInline\n", "value class EMail(val address: String)\n", "\n", @@ -788,35 +620,35 @@ "\n", "val EMail.server get() = address.substringAfter(\"@\")" ], - "execution_count":27, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"cML7IAfXcFt8Aab6PWZ0z0", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "cML7IAfXcFt8Aab6PWZ0z0", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Delegate" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"ibtt47bWffgOF3rAIxNuLO", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "ibtt47bWffgOF3rAIxNuLO", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class ValueHolder{\n", " var value = 2\n", "\n", @@ -827,43 +659,35 @@ "\n", "ValueHolder().apply { value = 6 }.printValue()" ], - "execution_count":28, - "outputs":[ - { - "name":"stdout", - "text":[ - "6\n" - ], - "output_type":"stream" + "metadata": { + "datalore": { + "node_id": "yvjapJUSD8MaI46U8mmlF4", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"yvjapJUSD8MaI46U8mmlF4", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "Bad example" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"IGYgOEliyB7xhgQex6rTRS", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "IGYgOEliyB7xhgQex6rTRS", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class ModifiedValueHolder: ValueHolder(){\n", " override fun printValue(){\n", " print(\"value = \")\n", @@ -873,41 +697,20 @@ "\n", "ModifiedValueHolder().apply { value = 6 }.printValue()" ], - "execution_count":29, - "outputs":[ - { - "name":"stderr", - "text":[ - "Line_141.jupyter.kts (1:28 - 39) This type is final, so it cannot be inherited from\n", - "Line_141.jupyter.kts (2:5 - 13) 'printValue' in 'ValueHolder' is final and cannot be overridden\n", - "Line_141.jupyter.kts (8:31 - 36) Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: \n", - "public final var value: Int defined in Line_141_jupyter.ModifiedValueHolder" - ], - "output_type":"stream" - }, - { - "ename":"Syntax Error", - "evalue":"Syntax Error: This type is final, so it cannot be inherited from", - "traceback":[ - "\u001b[0;31m---------------------------------------------------------------------------", - "Traceback (most recent call last)", - "Syntax Error: This type is final, so it cannot be inherited from" - ], - "output_type":"error" + "metadata": { + "datalore": { + "node_id": "m27RUUy8qf5jZllZknp5o3", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"m27RUUy8qf5jZllZknp5o3", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class GoodValueHolder(val valueHolder: ValueHolder = ValueHolder()){\n", "\n", " var value by valueHolder::value\n", @@ -919,28 +722,20 @@ "}\n", "GoodValueHolder().apply { value = 6 }.printValue()" ], - "execution_count":27, - "outputs":[ - { - "name":"stdout", - "text":[ - "value = 6\n" - ], - "output_type":"stream" + "metadata": { + "datalore": { + "node_id": "OHLrIGtjkN2XQjYacDM8ut", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"OHLrIGtjkN2XQjYacDM8ut", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class CompositeValueHolder(\n", " val a: ValueHolder,\n", " val b: ValueHolder\n", @@ -955,174 +750,137 @@ " }\n", "}" ], - "execution_count":null, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"fdNq2E5bTa6zarGwDDqQFj", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "fdNq2E5bTa6zarGwDDqQFj", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class Id(val value: String)" ], - "execution_count":43, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"3OCnDlksXhltJds6fY0L7v", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "3OCnDlksXhltJds6fY0L7v", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "Id(\"d3d\").value" ], - "execution_count":44, - "outputs":[ - { - "data":{ - "text\/plain":[ - "d3d" - ] - }, - "metadata":{}, - "output_type":"display_data" + "metadata": { + "datalore": { + "node_id": "MjDAABWvcpMQLzBFN4x91C", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"MjDAABWvcpMQLzBFN4x91C", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "Id(\"fff\").length" ], - "execution_count":41, - "outputs":[ - { - "name":"stderr", - "text":[ - "Line_154.jupyter-kts (1:11 - 17) Unresolved reference: length" - ], - "output_type":"stream" - }, - { - "ename":"Syntax Error", - "evalue":"Syntax Error: Unresolved reference: length", - "traceback":[ - "\u001b[0;31m---------------------------------------------------------------------------", - "Traceback (most recent call last)", - "Syntax Error: Unresolved reference: length" - ], - "output_type":"error" + "metadata": { + "datalore": { + "node_id": "525C4u3URrTwsBeZ2sTLud", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"525C4u3URrTwsBeZ2sTLud", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Proxy" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"NwAoDBrhHGOMQkkInhobM1", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "NwAoDBrhHGOMQkkInhobM1", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class StringProxy(val string: String): CharSequence by string{\n", " override fun get(index: Int): Char{\n", " return if(index < 0) '!' else string[index]\n", " }\n", "}" ], - "execution_count":30, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"x3XnwlrqMLxwzwughZSmqw", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "x3XnwlrqMLxwzwughZSmqw", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "val proxy = StringProxy(\"dddd\")\n", "\n", "println(proxy[0])\n", "println(proxy[-1])" ], - "execution_count":31, - "outputs":[ - { - "name":"stdout", - "text":[ - "d\n", - "!\n" - ], - "output_type":"stream" + "metadata": { + "datalore": { + "node_id": "ZAprJIO0gNiM69lJSMgPVt", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"ZAprJIO0gNiM69lJSMgPVt", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Observer" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"xF2sXItrdeH2pbwchAI8UQ", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "xF2sXItrdeH2pbwchAI8UQ", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class ObservableValueHolder(defaultValue: Int, val callback: (Int) -> Unit){\n", " var value: Int = defaultValue\n", " set(value){\n", @@ -1131,79 +889,70 @@ " }\n", "}" ], - "execution_count":1, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"wLHHws3VLVqGyjA3YIdnaa", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "wLHHws3VLVqGyjA3YIdnaa", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "val holder = ObservableValueHolder(1){\n", " println(\"Changed value = $it\")\n", "}\n", "holder.value = 6\n", "holder.value = 7" ], - "execution_count":2, - "outputs":[ - { - "name":"stdout", - "text":[ - "Changed value = 6\n", - "Changed value = 7\n" - ], - "output_type":"stream" + "metadata": { + "datalore": { + "node_id": "pAG4a8kqIeaClaAtAOOkwJ", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"pAG4a8kqIeaClaAtAOOkwJ", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Visitor" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"0dpe5zY5a0RQW1ueDfxV4W", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "0dpe5zY5a0RQW1ueDfxV4W", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "### Classic visitor" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"nePxZT9HQTU2lEhESlhVly", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "nePxZT9HQTU2lEhESlhVly", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "interface Structure\n", "\n", "class StringStructure(val string: String): Structure\n", @@ -1212,20 +961,20 @@ "\n", "class StructureList(val content: List): Structure" ], - "execution_count":13, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"Wo26AfHjCt8mlaZ2yIMcOm", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "Wo26AfHjCt8mlaZ2yIMcOm", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "fun interface StructureVisitor{\n", " fun visit(structure: Structure): Unit\n", "}\n", @@ -1245,20 +994,20 @@ " visitor.visit(this)\n", "}" ], - "execution_count":17, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"7ga1xsthc8oovIBmcC8Cg9", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "7ga1xsthc8oovIBmcC8Cg9", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "fun List.asStructure() = StructureList(this)\n", "\n", "@JvmName(\"stringsAsStruct\")\n", @@ -1275,85 +1024,73 @@ "\n", "structureList.visit(myStructureVisitor)" ], - "execution_count":24, - "outputs":[ - { - "name":"stdout", - "text":[ - "It is a StringStructure with value ddd\n", - "It is a IntStructure with value 2\n", - "It is a IntStructure with value 7\n", - "It is a StringStructure with value aaa\n", - "It is a StringStructure with value bbb\n" - ], - "output_type":"stream" + "metadata": { + "datalore": { + "node_id": "lAzMMN1L3TmQl2cVxi36ED", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"lAzMMN1L3TmQl2cVxi36ED", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "### Kotlin idiomatic visiting" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"wvN4YCDwzYUDQfXA7IoRUr", - "type":"MD", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "wvN4YCDwzYUDQfXA7IoRUr", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "sealed interface SealedStructure\n", "\n", "class StringSealedStructure(val string: String): SealedStructure\n", "\n", "class IntSealedStructure(val int: Int): SealedStructure" ], - "execution_count":27, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"GjXhhTAsHL0AUcEzmuypK1", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "GjXhhTAsHL0AUcEzmuypK1", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "fun List.visit(visitor: (SealedStructure) -> Unit){\n", " forEach(visitor)\n", "}" ], - "execution_count":28, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"p58da7MiEz4NeXbk2ZUyiz", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "p58da7MiEz4NeXbk2ZUyiz", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "val sealedStructureList = listOf(\n", " StringSealedStructure(\"ddd\"),\n", " IntSealedStructure(2), \n", @@ -1364,72 +1101,54 @@ " when(structure){\n", " is StringSealedStructure -> println(\"It is a StringSealedStructure with value ${structure.string}\")\n", " is IntSealedStructure -> println(\"It is a IntSealedStructure with value ${structure.int}\")\n", - " else -> {} \/\/ why is that?\n", + " else -> {} // why is that?\n", " }\n", "}" ], - "execution_count":30, - "outputs":[ - { - "name":"stderr", - "text":[ - "Line_206.jupyter.kts (8:5 - 9) 'when' expression must be exhaustive, add necessary 'else' branch" - ], - "output_type":"stream" - }, - { - "ename":"Syntax Error", - "evalue":"Syntax Error: 'when' expression must be exhaustive, add necessary 'else' branch", - "traceback":[ - "\u001b[0;31m---------------------------------------------------------------------------", - "Traceback (most recent call last)", - "Syntax Error: 'when' expression must be exhaustive, add necessary 'else' branch" - ], - "output_type":"error" + "metadata": { + "datalore": { + "node_id": "aCfKGNanITfEocl3N0T0Ce", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"aCfKGNanITfEocl3N0T0Ce", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[], - "execution_count":null, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"EmfBYCTjDyjeCP4LqTIyFg", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "cell_type": "code", + "source": [], + "metadata": { + "datalore": { + "node_id": "EmfBYCTjDyjeCP4LqTIyFg", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"markdown", - "source":[ + "cell_type": "markdown", + "source": [ "# Observer" ], - "attachments":{}, - "metadata":{ - "datalore":{ - "node_id":"Observer", - "type":"MD", - "hide_input_from_viewers":false, - "hide_output_from_viewers":false, - "sheet_delimiter":true + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "Observer", + "type": "MD", + "hide_input_from_viewers": false, + "hide_output_from_viewers": false, + "sheet_delimiter": true } } }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "import kotlin.properties.Delegates\n", "\n", "class ObservableHolder{\n", @@ -1438,46 +1157,38 @@ " }\n", "}" ], - "execution_count":8, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"h2OYBThfWjdp7hhteNH2Lt", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "metadata": { + "datalore": { + "node_id": "h2OYBThfWjdp7hhteNH2Lt", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "val holder = ObservableHolder()\n", "\n", "holder.observable = 5" ], - "execution_count":9, - "outputs":[ - { - "name":"stdout", - "text":[ - "observable 5\n" - ], - "output_type":"stream" + "metadata": { + "datalore": { + "node_id": "pAzvJyJubYwBrzqNmGLAMj", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"pAzvJyJubYwBrzqNmGLAMj", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[ + "cell_type": "code", + "source": [ "class Response(val header: String, val body: () -> String ){\n", " fun onRead(callback: (String) -> Unit){\n", " callback(body())\n", @@ -1497,56 +1208,47 @@ " }\n", "}.start()" ], - "execution_count":12, - "outputs":[ - { - "name":"stdout", - "text":[ - "header\n", - "body\n" - ], - "output_type":"stream" + "metadata": { + "datalore": { + "node_id": "z4D2hzOyzy2Dmpi1QbKMqf", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - ], - "metadata":{ - "datalore":{ - "node_id":"z4D2hzOyzy2Dmpi1QbKMqf", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true - } - } + }, + "outputs": [], + "execution_count": null }, { - "cell_type":"code", - "source":[], - "execution_count":null, - "outputs":[], - "metadata":{ - "datalore":{ - "node_id":"QlpqRBkqqUHN2CUAm2hP3H", - "type":"CODE", - "hide_input_from_viewers":true, - "hide_output_from_viewers":true + "cell_type": "code", + "source": [], + "metadata": { + "datalore": { + "node_id": "QlpqRBkqqUHN2CUAm2hP3H", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true } - } + }, + "outputs": [], + "execution_count": null } ], - "metadata":{ - "kernelspec":{ - "display_name":"Kotlin", - "language":"kotlin", - "name":"kotlin" + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" }, - "datalore":{ - "computation_mode":"JUPYTER", - "package_manager":"pip", - "base_environment":"default", - "packages":[], - "report_row_ids":[], - "version":3 + "datalore": { + "computation_mode": "JUPYTER", + "package_manager": "pip", + "base_environment": "default", + "packages": [], + "report_row_ids": [], + "version": 3 } }, - "nbformat":4, - "nbformat_minor":4 -} \ No newline at end of file + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/notebooks/Multitasking.ipynb b/notebooks/Multitasking.ipynb new file mode 100644 index 0000000..5c85e84 --- /dev/null +++ b/notebooks/Multitasking.ipynb @@ -0,0 +1,791 @@ +{ + "cells": [ + { + "cell_type": "code", + "source": [ + "%use coroutines" + ], + "metadata": { + "datalore": { + "node_id": "Al3t64xqN0DN3JmLKHOVn2", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "# Три оси многозадачности" + }, + { + "cell_type": "markdown", + "source": "### Синхронный х однопоточный х неконкурентный ", + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "TawmM9V8by8RGHfhNv7D3m", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "repeat(10){\n", + " println(\"Line number $it\")\n", + "}" + ], + "metadata": { + "datalore": { + "node_id": "XzjwoelmODMg8pmaJRe1KK", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": [ + "import java.util.stream.*\n", + "\n", + "IntStream.range(0, 100).sum()" + ], + "metadata": { + "datalore": { + "node_id": "UuTmCNAMCpUAHaAwWVYJPy", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Синхронный х однопоточный х конкурентный", + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "f6DGHwBOIRvKuYjtxVRn0W", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "val list = (0..100).toMutableList()\n", + "\n", + "list.forEach{\n", + " if(it % 2 == 0) list.remove(it)\n", + "}" + ], + "metadata": { + "datalore": { + "node_id": "O1DPfMSAedOChaqU5JWXrU", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "datalore": { + "node_id": "N3QIwvANEngnvMgsCVJatN", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Синхронный х многопоточный х неконкурентный", + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "x9nGAXOgOlWxd4cu6Smio8", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "val sum = IntStream.range(0, 100).parallel().sum()\n", + "\n", + "println(sum)" + ], + "metadata": { + "datalore": { + "node_id": "lRJGB0cHhpjQTdRdGynG0G", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "datalore": { + "node_id": "1lLEGWWbB6qnFr1qjfSGpo", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Асинхронный х однопоточный х неконкурентный", + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "OTRLxfWLADkMoc9ViJfeEq", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "fun runLongTask(result: Int = 8): Int {\n", + " Thread.sleep(100)\n", + " println(\"Task complete: $result\")\n", + " return result\n", + "}" + ], + "metadata": { + "datalore": { + "node_id": "r1yVVtgMhexxzx7gGVmeIg", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": [ + "import java.util.concurrent.*\n", + "\n", + "val executor = Executors.newSingleThreadExecutor()\n", + "\n", + "val future = executor.submit {\n", + " val result = runLongTask()\n", + " println(result)\n", + " result\n", + "}\n", + "\n", + "future.get()" + ], + "metadata": { + "datalore": { + "node_id": "8YvIKfD1I7cfbiPRMpk0DC", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Асинхронный х однопоточный х конкурентный ", + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "nyjKPayaltq8gBzq2bIP1c", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "interface Observable{\n", + " fun onChange(callback: (Int) -> Unit)\n", + "}\n", + "\n", + "val observable: Observable by lazy{ TODO() }" + ], + "metadata": { + "datalore": { + "node_id": "UreOIHJpXQYfkjeHOvf1Bq", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": [ + "val list: MutableList = mutableListOf()\n", + "\n", + "observable.onChange { \n", + " list.add(it)\n", + "}" + ], + "metadata": { + "datalore": { + "node_id": "1in8iE7mL9m895XWUNh0Sl", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Асинхронный х многопоточный х неконкурентный", + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "TczpOZrkCKogcT7x7XWAUT", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "datalore": { + "node_id": "YvgL8fFuneP9USjjnsfiQj", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": [ + "val executor: ExecutorService = Executors.newFixedThreadPool(4)\n", + "\n", + "repeat(8){\n", + " executor.submit{\n", + " runLongTask(it)\n", + " }\n", + "}" + ], + "metadata": { + "datalore": { + "node_id": "9NS1h5b5lJ0BEzieUt6xrr", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Синхронный х многопоточный х конкурентный", + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "REBgToVc8iKIrODCWXPdZj", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "import kotlin.io.path.Path\n", + "import kotlin.io.path.writeText\n", + "\n", + "val file = Path(\"someFile.txt\")\n", + "\n", + "val data: List = emptyList()\n", + "\n", + "data.stream()\n", + " .parallel()\n", + " .forEach { \n", + " file.writeText(it)\n", + " }" + ], + "metadata": { + "datalore": { + "node_id": "3AjItM8WtjFE9qJo9JvZFW", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": "### Асинхронный х многопоточный х конкурентный", + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "XDCp5EjIq8v6ABeo5q2K6S", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "val cache = mutableMapOf\n", + "\n", + "val consumer: (Int) -> Unit = TODO()\n", + "\n", + "\n", + "repeat(8){ i->\n", + " executor.submit{\n", + " val result = cache.getOrPut(i){\n", + " runLongTask(i)\n", + " }\n", + " consumer(result)\n", + " }\n", + "}" + ], + "metadata": { + "datalore": { + "node_id": "taOKUd5Gc9U6TuGVFZJvew", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "## Инструменты" + ], + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "bSK4aInljsXYinbOTNSLdc", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "markdown", + "source": [ + "#### Thread" + ], + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "qjWpglMy3eSM475ozgnDPA", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "import kotlin.concurrent.*\n", + "\n", + "val t = thread {\n", + " runLongTask()\n", + "}\n", + "t.join()" + ], + "metadata": { + "datalore": { + "node_id": "nEZ6jKJhVHhsjMvptTQ3rU", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "datalore": { + "node_id": "k35GcE4VUIMtrznZ0C3BmC", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "#### Future" + ], + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "bX0GaqyAH6q7Max0Tky7DW", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "val future = executor.submit{\n", + " runLongTask()\n", + "}\n", + "\n", + "future.get()\n", + "future.cancel(true)" + ], + "metadata": { + "datalore": { + "node_id": "TVhCm0JtWiYFFqWYORxuya", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "#### CompletableFuture" + ], + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "a5BY9U8m9OeZSSsS0yGRSZ", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "import java.util.concurrent.*\n", + "\n", + "val cf = CompletableFuture.supplyAsync{\n", + " runLongTask()\n", + "}\n", + "\n", + "val cf2 = cf.whenComplete{ res, _ ->\n", + " runLongTask(res - 1)\n", + "}\n", + "\n", + "val cf3 = cf.whenComplete{ res, _ ->\n", + " runLongTask(res + 1)\n", + "}\n", + "\n", + "cf2.join()\n", + "cf3.join()" + ], + "metadata": { + "datalore": { + "node_id": "2rchFZt5trGqzOCuU3aPvz", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "#### Lock" + ], + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "izHWuE5ZZo1hphjMmc7BHj", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "import java.util.concurrent.locks.*\n", + "\n", + "val list = mutableListOf()\n", + "val lock = ReentrantLock()\n", + "\n", + "val cf4 = CompletableFuture.supplyAsync{\n", + " val res = runLongTask(4)\n", + " lock.withLock { \n", + " list.add(res)\n", + " }\n", + "}\n", + "\n", + "val cf5 = CompletableFuture.supplyAsync{\n", + " val res = runLongTask(5)\n", + " lock.withLock { \n", + " list.add(res)\n", + " }\n", + "}\n", + "\n", + "cf4.join()\n", + "cf5.join()\n", + "\n", + "list" + ], + "metadata": { + "datalore": { + "node_id": "JTXxcGnvTS36OVX6GkJfkK", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Reactive streams" + }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "class A(val value: Int)\n", + "class B(val value: Int)\n", + "\n", + "val aFlow = flowOf()\n", + "val bFlow = flowOf()\n", + "\n", + "val combined = aFlow.zip(bFlow){ a, b->\n", + " a.value + b.value\n", + "}.debounce(2.seconds)" + ], + "outputs": [], + "execution_count": null + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Actor" + }, + { + "metadata": {}, + "cell_type": "code", + "source": [ + "sealed class Event {\n", + " class Open(val transactionId: Int): Event()\n", + " class Close(val tranactionId: Int): Event()\n", + "}\n", + "\n", + "fun interface Actor {\n", + " suspend fun receive(event: Event)\n", + "}\n", + "\n", + "val actor = object : Actor {\n", + " private var transaction: Int? = null\n", + " override suspend fun receive(event: Event) {\n", + " when (event) {\n", + " is Event.Open -> if (transaction != null) {\n", + " error(\"Transaction already open\")\n", + " } else {\n", + " transaction = event.transactionId\n", + " }\n", + " is Event.Close ->if (transaction != event.tranactionId) {\n", + " error(\"Wrong transaction id: ${event.tranactionId}\")\n", + " } else {\n", + " transaction = null\n", + " }\n", + " }\n", + " }\n", + "\n", + "}" + ], + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "## Сорта асинхронности" + ], + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "YDqoXAD2XEED9MSPRuMMzL", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "markdown", + "source": [ + "#### Callback" + ], + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "kb1ccsTMIZX3aacLF6gPrJ", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [ + "import java.net.*\n", + "import java.net.http.*\n", + "import java.net.http.HttpResponse.*\n", + "\n", + "val client: HttpClient = HttpClient.newHttpClient()\n", + "\n", + "val request : HttpRequest = HttpRequest.newBuilder()\n", + " .uri(URI.create(\"https://sciprog.center\"))\n", + " .GET().build()\n", + "\n", + "val regex = \"\"\"href=\\\"(.+\\.png)\\\"\"\"\".toRegex()\n", + "\n", + "client.sendAsync(request, BodyHandlers.ofString())\n", + " .thenApply{ it.body() }\n", + " .thenApply{ \n", + " val resources = regex.findAll(it).map{it.groupValues[1]}\n", + "\n", + " resources.forEach { resourceName->\n", + " val resourceRequest : HttpRequest = HttpRequest.newBuilder()\n", + " .uri(URI.create(\"https://sciprog.center$resourceName\"))\n", + " .GET().build()\n", + " client.sendAsync(resourceRequest, BodyHandlers.ofByteArray()).thenAccept{ resourceResponse ->\n", + " val bodyBytes = resourceResponse.body()\n", + " //do something with the body\n", + " }\n", + " }\n", + " resources\n", + " }\n", + " .thenAccept{ println(it.toList()) }\n", + " .join()" + ], + "metadata": { + "datalore": { + "node_id": "jZrkouEiPJnMCCpxTFlgVP", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + }, + { + "cell_type": "markdown", + "source": [ + "#### Реактивные потоки" + ], + "attachments": {}, + "metadata": { + "datalore": { + "node_id": "7zwURNaHnaTgOTAZumDDcd", + "type": "MD", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + } + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "datalore": { + "node_id": "lPXl5Gkvu7CuhlhUV7YJab", + "type": "CODE", + "hide_input_from_viewers": true, + "hide_output_from_viewers": true + } + }, + "outputs": [], + "execution_count": null + } + ], + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" + }, + "datalore": { + "computation_mode": "JUPYTER", + "package_manager": "pip", + "base_environment": "default", + "packages": [], + "report_row_ids": [], + "version": 3 + } + }, + "nbformat": 4, + "nbformat_minor": 4 +}