@scala_ru

Страница 800 из 1499
Nick
06.07.2017
10:43:03
че ты несешь то? это нужно проверять для каждого конкретного кеиса, для каждой системы

static method != inline

Alexey
06.07.2017
10:43:30
как минимум, там оно в static генерится
а в скале делается синглтон, что примерно равно статик

и что

Google
KrivdaTheTriewe
06.07.2017
10:43:40
придумал более логичный способ
крутой у меня тут битва докера и artery

Oleksandr
06.07.2017
10:44:05
а в скале делается синглтон, что примерно равно статик
не синглтон на каждый юз генерится новый класс это смягчается AnyVal, но все же

Nick
06.07.2017
10:44:05
крутой у меня тут битва докера и artery
у меня теперь везде в таких зависимостях одна строчка)

Alexey
06.07.2017
10:44:20
я про AnyVal и говорю

а что же тогда генерится?

Nick
06.07.2017
10:45:20
Alexey
06.07.2017
10:45:25
лал

Nick
06.07.2017
10:46:33
какая
enablePlugins(ProtoSettings)

Nikita
06.07.2017
10:46:46
Nick
06.07.2017
10:47:10
@krivdatheliggen пришел к выводу, что паковать в джар протофайл и сгенеренный файл самое правильное

KrivdaTheTriewe
06.07.2017
10:47:20
enablePlugins(ProtoSettings)
я уж подумал libraryDependencies += "org.mongodb.scala" % "mongo-scala-driver_2.12" % "2.1.0"

Google
KrivdaTheTriewe
06.07.2017
10:48:09
А, ну у меня после того случая с протобафом всё вообще хорошо, ты как-то со своим плагином сильно извернулся, делалось всё проще

Nick
06.07.2017
10:48:12
@eld0727 вообще никогда не говори про синглтон, их не бывает

Oleksandr
06.07.2017
10:48:30
а что же тогда генерится?
примив + вызов метода vs вызов статического метода

Alexey
06.07.2017
10:49:20
примив?

Oleksandr
06.07.2017
10:49:46
AnyVal

Alexey
06.07.2017
10:49:59
штааа

Nick
06.07.2017
10:50:00
лол

пойду я поработаю)

Daniel
06.07.2017
10:51:11
да ну ладно взять те же экстеншн методы из котлина — их совершенно точно нужно инлайнить
кэш инструкций не бесконечный, всунул что-то большое, не влезло другое тонкий тюнинг делать нужно, только когда в этом есть необходимость, потому что там требуется использовать голову (сегодня пальцем в небо ткнул удачно, а при апдейте удача ушла)

Alexey
06.07.2017
10:54:16
примив + вызов метода vs вызов статического метода
http://docs.scala-lang.org/sips/completed/value-classes.html

Expansion of value classes.

Pavel
06.07.2017
11:15:29
вопрос) Вот те ребята у кого плей в проде, вы уже мигрировали на 2.6? Если нет, то когда планируете?

интереса ради

Oleksandr
06.07.2017
11:18:37
Expansion of value classes.
(kotlin) object T { fun Int.foo(): Int { return this * this } val x = 2.foo() } public final int foo(int); Code: 0: iload_1 1: iload_1 2: imul 3: ireturn public final int getX(); Code: 0: getstatic #15 // Field x:I 3: ireturn (scala) object T2 { implicit class IntOps(val i: Int) extends AnyVal { def foo = i * i } val x = 2.foo } public static int IntOps(int); Code: 0: getstatic #16 // Field T2$.MODULE$:LT2$; 3: iload_0 4: invokevirtual #22 // Method T2$.IntOps:(I)I 7: ireturn public static int x(); Code: 0: getstatic #16 // Field T2$.MODULE$:LT2$; 3: invokevirtual #18 // Method T2$.x:()I 6: ireturn окей, зачем в скале "лишние" invokevirtual? (мб я реально чего не понимаю)

Alexey
06.07.2017
11:20:23
Это листинг какого из двух классов?

Похоже на не тот

Oleksandr
06.07.2017
11:20:32
там оба листинга

или я не понял вопрос

Google
Alexey
06.07.2017
11:21:24
Jit заоптимизирует виртуал

Daniel
06.07.2017
11:21:49
Jit заоптимизирует виртуал
звучит как "бог поможет"

Alexey
06.07.2017
11:21:57
Ну типо того

Oleksandr
06.07.2017
11:22:10
это совсем другой вопрос, чего там jit сделает

итоговый байткод должен эмититься максимально параноидальным

имхо

Oleksandr
06.07.2017
11:24:19
Oleg
06.07.2017
11:24:52
он вызывает IntOps из компаньона

это конструктор для value class а, как видишь, он берёт Int и возвращает Int

Oleksandr
06.07.2017
11:26:55
это ясно, я не понимаю, почему такой сложный (и потенциально неоптимизируемый) выхлоп в IntOps: public int foo(); Code: 0: getstatic #19 // Field T2$IntOps$.MODULE$:LT2$IntOps$; 3: aload_0 4: invokevirtual #21 // Method i:()I 7: invokevirtual #25 // Method T2$IntOps$.foo$extension:(I)I 10: ireturn и уже аж в T2$IntOps$ public final int foo$extension(int); Code: 0: iload_1 1: iload_1 2: imul 3: ireturn

Alexey
06.07.2017
11:27:30
Ну вообще я не могу в байт коде увидеть методов из сгенерированого object

Oleksandr
06.07.2017
11:27:49
могу, чуть выше листинг

Oleg
06.07.2017
11:28:54
это ясно, я не понимаю, почему такой сложный (и потенциально неоптимизируемый) выхлоп в IntOps: public int foo(); Code: 0: getstatic #19 // Field T2$IntOps$.MODULE$:LT2$IntOps$; 3: aload_0 4: invokevirtual #21 // Method i:()I 7: invokevirtual #25 // Method T2$IntOps$.foo$extension:(I)I 10: ireturn и уже аж в T2$IntOps$ public final int foo$extension(int); Code: 0: iload_1 1: iload_1 2: imul 3: ireturn
Ну потому что твой класс объявлен в объекте, даже если он и будет анбоксед версию вызвать, он всё-равно может полагаться на инициализацию этого объекта, использовать его методы\поля

Поэтому статический метод ссылается на метод компаньона

Oleg
06.07.2017
11:29:42
Естественно, такой код пишется из предположения, что первый проход нетрассирующего оптимизатора в ЖВМ всё заинлайнит

Oleksandr
06.07.2017
11:30:49
вот jmh мне сейчас лениво писать, дома проверю, если не забуду (хотя 99% ты прав)

D
06.07.2017
11:30:56
на должность скала-гуглера?
скаластэковерфлоущика

Google
Oleksandr
06.07.2017
11:31:13
anyway, подход котлина для задачи "вызвать 2.foo" на мой взгляд чище

хотя вот импорт этих экстеншн методов раздражает

но это слегка другое

Oleg
06.07.2017
11:32:17
anyway, подход котлина для задачи "вызвать 2.foo" на мой взгляд чище
Да, но, как уже обсуждали беднее. Представь, что твой метод использует какие-то имплисит инстансы, которые генерятся в твоём объекте

Скаловский всё корректно инициализирует и подставит

А в котлине такого просто нет

Mikhail
06.07.2017
11:35:50
anyway, подход котлина для задачи "вызвать 2.foo" на мой взгляд чище
так ведь принцип то у них совсем разный. у котлина обычный шугаринг на костылях со школота-синтаксис притянутый за уши. а тут полноценные классы со всеми вытекающими возмностями, но дополнительно поверх этого реализовано немного оптимизирующей логики. никто не мешает эту логику слегка усложнить и генерировать более оптимальный байткод, но это потребует дополнительных проверок и этим кому-то придется заниматься. но поскольку это врятли можно назвать приоритетным направлением, то и получаем текущие энивалы больше как некий poc)

Mikhail
06.07.2017
11:38:01
ну там шугаринг на костылях ещё с C#
мелкософты никогда не отличались хорошим дизайном

Admin
ERROR: S client not available

Oleg
06.07.2017
11:39:12
В общем, да. Котлиновский выхлоп проще. Так же, как тайпскриптовый выхлоп проще пьюрскриптового. Но ведь это значит жить без фриманаток

И не просто "жить", как например если ты гражданин Берляндии и вчера парламент Берляндии выяснил, что весь террористический софт написан с ФП, и запретил фриманатки в первом чтении. Это просто ты говоришь "мне без фриманаток, с простым плоским шугаром жить проще, а ещё писать софт для андроида" и по собственной воле такой начинаешь котить на котлине без пропаганды и ринуждения

Mikhail
06.07.2017
11:45:26
прежде чем работать дальше над энивалами, я бы лучше сделал плагин к компилятору, который бы сделал довольно простую и в то же время такую нужную( с моей колокольни) в скале штуку - оптимизация сгенерированных доказательств, которая бы могла вполне себе генерировать фантомные методы без мертворожденных имплиситов и в байткоде генерировать вызов к фантомному методу(после стадии вывода типов, имплиситов - на последних этапах когда все проверки уже пройдены и можно со спокойно душой оптимизировать) . в простых случаях жит хорошо все чистит, но чуть что сложнее - там сразу начинается чехарда и жит справляется уже не так хорошо.

Daniel
06.07.2017
11:46:38
> довольно простую o.O

KrivdaTheTriewe
06.07.2017
11:51:56
Теперь официально https://rambler-co-e-org.timepad.ru/event/533749/ Приходите сами, зовите друзей и коллег! Ждем всех!

Mikhail
06.07.2017
11:52:15
> довольно простую o.O
да, там немного правил для этого требуется проверить и алгоритм довольно линейный. я уже в голове все расписал примерно, хотел под скаланатив поц собрать - там проще .ll файл переписать программно, чем вникать во все модельки, которые скалац внутри использует. но пока времени не хватает закончить(

Nikita
06.07.2017
12:56:59
Может кто-нибудь объяснить как работает def foo[Bar["a" :: "b" :: HNil]]? Взял отсюда http://www.cakesolutions.net/teamblogs/what-if-i-told-you-scala-compiler-can-understand-sql-queries

Конкретно интересует тип "a" :: "b" :: HNil

Oleg
06.07.2017
12:57:24
прежде чем работать дальше над энивалами, я бы лучше сделал плагин к компилятору, который бы сделал довольно простую и в то же время такую нужную( с моей колокольни) в скале штуку - оптимизация сгенерированных доказательств, которая бы могла вполне себе генерировать фантомные методы без мертворожденных имплиситов и в байткоде генерировать вызов к фантомному методу(после стадии вывода типов, имплиситов - на последних этапах когда все проверки уже пройдены и можно со спокойно душой оптимизировать) . в простых случаях жит хорошо все чистит, но чуть что сложнее - там сразу начинается чехарда и жит справляется уже не так хорошо.
Всё очень просто, если имплисит фантомный, он не используетс в коде. Если он не используется в коде, доказательство неконструктивное Если доказательство неконструктивное, ЖРИ СВОЙ ЖВМ МУСОР ХАХА

Конкретно интересует тип "a" :: "b" :: HNil
Что ты хочешь знать про этот тип?

Google
Nikita
06.07.2017
12:59:05
Никогда не видел, когда в типах строку можно писать. Поэтому интересуюсь как это работает

Oleg
06.07.2017
12:59:16
есть case class shapeless.::[A, B <: HList](head: A, tail: B) extends HList

есть в скала-компиляторе infix - синтаксис для типов

т.е. ты можешь написать не Either[A, B] а A Either B

Denis
06.07.2017
13:00:21
и есть даже pretty print для таких целей в TLS

Oleg
06.07.2017
13:00:32
Есть в тайплевельном форке скаловского компилятора специальные синглтон типы

Т.е. type String("a") <: String

Т.е. типы есть и в простом компиляторе, но в тайплевельном форке, ты их можешь записать в коде

В итоге получается такой тип Bar[::[String("a"), ::[String("b"), HNil]]]

тип String("a") - это специальный подтип строчки, который имеет ровно одного представителя "a"

Nikita
06.07.2017
13:03:31
Яснопонятно, спасибо

Oleg
06.07.2017
13:03:49
И в shapeless есть специальный тайпкласс Witness, который может в другую сторону - доставить тебе значение по типу

Для вот таких singleton типов

Nikita
06.07.2017
13:05:57
С Witness получилось что-то похожее import shapeless._ case class Foo[HList]() val wa = Witness("a") type A = wa.T println(Foo[A :: HNil])

Oleg
06.07.2017
13:06:39
С Witness получилось что-то похожее import shapeless._ case class Foo[HList]() val wa = Witness("a") type A = wa.T println(Foo[A :: HNil])
да, ещё можешь написать Witness.`"a"`.T прямо в нужном месте без val и type алиасов

Nikita
06.07.2017
13:07:17
Так гораздо удобней, спасибо

Oleg
06.07.2017
13:07:38
Ну ещё удобнее писать "a" :: HNil

для этого нужно просто scalaOrganization := "org.typelevel"

ну и -bin-typelevel-4 к версии скалы, если 2.12.2

Mikhail
06.07.2017
13:09:46
для этого нужно просто scalaOrganization := "org.typelevel"
а есть у них список плюшек которые в комплекте идут?

Oleg
06.07.2017
13:09:57
https://github.com/typelevel/scala/blob/typelevel-readme/notes/typelevel-4.md

Страница 800 из 1499