
Alexey
04.09.2018
13:23:21
Тогда моя не понимать

Andrey
04.09.2018
13:24:01

Alexey
04.09.2018
13:24:59

Quantum Harmonizer
04.09.2018
13:25:20
ну вот есть класс/объект/функция:
object Wtf {
fun <T> id(obj: T): T =
obj
}
и нельзя просто так взять и Wtf::id, функциональный тип неспособен это выразить. Это функция с другой сигнатурой, у функционального типа 0 тафп-параметров, а тут один.

Google

Andrey
04.09.2018
13:26:26

Quantum Harmonizer
04.09.2018
13:28:16
Эт не ковариантность не даёт, а здравый смысл)

Alexey
04.09.2018
13:28:28
Пока что я могу хотя бы википедией кинутся
https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%BB%D0%B8%D0%BC%D0%BE%D1%80%D1%84%D0%B8%D0%B7%D0%BC_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)

Quantum Harmonizer
04.09.2018
13:29:00
...ковариантность же позволяет List<Nothing> использовать в качестве List<Number> или List<String>.

Alexey
04.09.2018
13:29:00
И там всё довольно однозначно

Andrey
04.09.2018
13:32:52
И там всё довольно однозначно
Да, в рамках теории типов, где всё есть лямбда, аннотированная некоторым типом, полиморфизм оно и есть, так как там значения тоже лямбды (объекты). Так и в Котлин все значения - объекты.
Между лямбдами и объектами есть простой изоморфизм, который я выше писал, так что вполне можно считать, что всё в языке есть лямбда.

Alexey
04.09.2018
13:34:31
Эмммм

Quantum Harmonizer
04.09.2018
13:34:31
погодите-ка, для меня как джависта-котлиниста лямбда — это один из десятков типов выражений, который существует только в исходниках

Alexey
04.09.2018
13:34:41
Как через лямбду выразить мутабельный список?
Какой тут будет изоморфизм?
Иммутабельный список можно выразить через гетерагенный список, а вот что с мутабельным?

Google

Alexey
04.09.2018
13:36:28
Я конечно довольно слаб в теории типов, но что то мне кажется что никак

Nikita
04.09.2018
13:39:06
я так понимаю речь про то, что любую функцию можно посчитать анонимной в пределах ограниченного контекста ее вызова, а значит любая функция является анонимной, после того как именование станет неактуальным, а вызов будет совершаться по ключу в роли которого выступает реф на функцию

Andrey
04.09.2018
13:39:48
Как через лямбду выразить мутабельный список?
Ну состояние в лямбда исчислении можно выразить через продолжения в превом приближении.
Более красиво через State монаду, которая следит за тем, как к State применяются операции.
Собсна, на State монаде можно выразить изменяемый список, правда работать с ним можно будет только в контесте монады.

Alexey
04.09.2018
13:41:00
Ну это же всё равно не будет мутабельным состоянием, это будет снапшотами иммутабельных состояний

Andrey
04.09.2018
13:41:37
Так что получится нечто, что ходит как мутабельный список, крякает как мутабельный список => его вполне можно считать мутабельным списком.

Alexey
04.09.2018
13:44:43
Параллелые != асинхронные
Хотя это уже наверное про эффекты и в контексте монад некоректно про это рассуждать ?

Andrey
04.09.2018
13:47:35

Alexey
04.09.2018
13:48:30
Ну вот тогда в этом кейсе стейт монада уже не будет крякать как мутабельный список
Ну и есть Parallel, который вовсе не обязан быть concurent

Andrey
04.09.2018
13:49:39
В контексте State монады не получится в параллельные вычисления, она для этого не предназначена.
Ну и в Котлине для подобных операций список небезопасно использовать. Нужен thread safe вариант и плюс куча ограничения на опреации.

Alexey
04.09.2018
13:50:24
Речь просто про два последовательных обособленных вычисления

Andrey
04.09.2018
13:51:14

Alexey
04.09.2018
13:51:46
Русский язык не справляется с выражением мысли
Нужно рисовать

Google

Andrey
04.09.2018
13:53:15

Alexey
04.09.2018
13:53:41
Ну короч все эти рассуждения все равно не дают права в котлине написать val <A> a :)

Andrey
04.09.2018
13:54:42

Alexey
04.09.2018
13:55:52
Ну почему нет, например вот есть такое выражение: val <A> a: A= ???
Что можно написать вместо ??? кроме throw new Exception

dimiii
04.09.2018
13:56:03
И уж точно нет ограничений на значения - функциональные объекты, или как их обзывают - я уже запутался в ограничениях

Andrey
04.09.2018
13:56:08
Хотя можно ещё в бесконечную рекурсию уйти в поисках значения :)

Alexey
04.09.2018
13:57:45
Ну это уже опять будет функция, которая вызывает саму себя
короч нужна функция :)

Andrey
04.09.2018
13:58:28
val <A> a: A = a
Как-то так

Alexey
04.09.2018
14:00:42
Хм, а как котлин развернёт вообще val a: Any = a ?

Andrey
04.09.2018
14:00:57
короч нужна функция :)
Ну и функция - тоже. Кто-то же должен объект создавать.
Вот как вариант:
tailrec fun <A> bottom(): A = bottom()
val <A> a: A = bottom()

Quantum Harmonizer
04.09.2018
14:01:03

Alexey
04.09.2018
14:02:17
эм, нет
Всмысле компилятор нахер пошлёт?

Quantum Harmonizer
04.09.2018
14:02:40

Mikhail
04.09.2018
14:03:11

Alexey
04.09.2018
14:03:51
чисто теоритические изыскания

Andrey
04.09.2018
14:04:05
А зачем такое?
Да так, теоретические рассуждения об ограничениях выразительных средств языка.

Google

Mikhail
04.09.2018
14:04:56

Andrey
04.09.2018
14:05:31

Mikhail
04.09.2018
14:06:25

Andrey
04.09.2018
14:06:27
Его не существует. bottom type не населён. Но сам тип должен быть с точки зрения полноты системы типов (он наследник всех типов).

Mikhail
04.09.2018
14:07:22
И тогда можно сделать val a = TODO()

Alexey
04.09.2018
14:07:26
Ну Nothing - это точно бросок исключения

Mikhail
04.09.2018
14:07:50

Quantum Harmonizer
04.09.2018
14:08:07
переменной должно быть присвоено значение, а у Nothing множество значений пустое

Admin
ERROR: S client not available

Alexey
04.09.2018
14:08:22
null же в соседней от Nothing иерархии

Andrey
04.09.2018
14:08:46

Alexey
04.09.2018
14:08:46
то есть у него по сути тип Null с единственным значением

Mikhail
04.09.2018
14:10:14
Да, все верно и val a = TODO() просто бросит исключение
Ок

Andrey
04.09.2018
14:10:17

Mikhail
04.09.2018
14:10:37
Но вообще, есть ли смысл пытаться выразить значения типа, у которого нет значений?
Есть пример языка, который такое может?

Andrey
04.09.2018
14:12:42

Quantum Harmonizer
04.09.2018
14:13:02
не полиморфное, просто подтип всего

Google

Andrey
04.09.2018
14:13:37
Ну а вообще реально вернуть значение подтипа всего не получится, так как его не существует. Можно или упасть, или уйти в бесконечную рекурсию.

Mikhail
04.09.2018
14:13:48

Alexey
04.09.2018
14:14:15
Ну в скалке - это ок, и будет просто рекурсия

Andrey
04.09.2018
14:14:29
Я про пример val a = a
Ну это вариант с бесконечной рекурсией, если бы можно было обращаться к значению на этапе его инициализации.
То есть, чтобы узнать чему равно а, сходи в а, где написано, что чтобы узнать, чему равно а, сходи в а, где написано ...

Alexey
04.09.2018
14:16:40

Andrey
04.09.2018
14:17:20
неа
Хмм... Странно. Я всегда думал, что это Haskell для JVM ?

Alexey
04.09.2018
14:17:53
В scala 3 вроде порывались сделать, не помню точно что решили

Andrey
04.09.2018
14:19:11
Вот bottom type на Haskell:
Prelude> let a = a
Prelude> :t a
a :: t
Если попросить вывести a - уйдёт в рекурсию.

Quantum Harmonizer
04.09.2018
14:19:49
фига себе язык с безопасной системой типов)

Andrey
04.09.2018
14:19:55

Alexey
04.09.2018
14:20:07
Ну типо никто не мешает тебе написать val a = a

Andrey
04.09.2018
14:21:03

Alexey
04.09.2018
14:21:10

Quantum Harmonizer
04.09.2018
14:21:39
ну и позволять заводить значения таких типов тогда бессмысленно

Andrey
04.09.2018
14:22:41

Ivan
04.09.2018
14:23:13
подскажите. Вот есть у меня класс
class TopEntryRowMapper<T> (val valueClass: Class<T>) : RowMapper<TopEntry<T>> {
override fun mapRow(res: ResultSet, rowNum: Int): TopEntry<T> {
return TopEntry(res.getString("username"), res.getObject("topvalue", valueClass))
}
}
Я могу его передать туда, где ждут RowMapper<TopEntry<Int>> вот такое - TopEntryRowMapper(Int::class.java)
Можно это переделать на функцию типа
private inline fun <reified T : Any> mapTopEntry(res: ResultSet, rowNum: Int): TopEntry<T> =
TopEntry(
res.getString("username"),
res.getObject("topvalue", T::class.java)
)
и передавать ссылку на неё как-то?

Alexey
04.09.2018
14:25:39
inline функции по сути нет

Andrey
04.09.2018
14:26:44