@scala_ru

Страница 1339 из 1499
Oleg
12.03.2018
14:22:19
а есть относительно крупный открытый проект, который построен с использованием таких штук?
Почему люди продолжают задавать этот вопрос, зная, что их пошлют... в ПОНВ

Юрий
12.03.2018
14:36:10
скажем, "в уме помнить" скорее работает, чем нет
Ключевая разница в том, что обычный подход, конечно, обычно работает. Но при этом потенциальная возможность допустить ошибку есть. Refined же в принципе исключает любую возможность ошибки. Это также как с типами - в диеамических языках обычно все норм, но все равно ошибки бывает пролезают. Добавляются типы - и компилятор бьет по рукам сразу.

Юрий
12.03.2018
14:39:08
Ну да, если ты правило неправильно написал - тут уж ничего не поделаешь. Но, скажем, какой-то пласт ошибок исключается

Google
Aleksey
12.03.2018
14:59:10
Ребята, я напоминаю что идет сбор заявок на доклады к ближайшей московской встрече Scala разработчиков. Писать мне или @optician_owl в личку.

Dmitry
12.03.2018
15:02:18
толстовато

Oleksandr
12.03.2018
15:06:06
что толстовато? мне, действительно, не очевидно абсолютное преимущество refined иногда оно приемлемо, конечно, но, ввиду отсутствия опыта работы с refined, я думаю, что абстракция или потечет, или сопровождающий её код будет монструозным

Oleg
12.03.2018
15:07:04
Вот там, где премлемо - всякие там парсинги, сваггеры

Там и ништяк

Oleksandr
12.03.2018
15:07:51
Интересно, несколько реплик назад ты интересовался, стоит ли пользоваться вообще. А теперь речь об абсолютном преимуществе.
"не уверен, что есть абсолютное преимущество" => "думаю, не всегда стоит юзать" => "когда, собсно, стоит юзать?"

Oleg
12.03.2018
15:10:28
Ну короче, не нужно думать, что ты там на рефайнменте что-то доказать сможешь. Сможешь навесить какие-то хинты, сгенерировать валидацию на базе этих хинтов. И соответственно, везде, где у тебя уместна валидация или публикация "требований к данным" они работают норм

Конфиги, АПИ сервисов, парсинг какой-то

Oleksandr
12.03.2018
15:10:57
Вот там, где премлемо - всякие там парсинги, сваггеры
а как это будет с бизнес логикой слинковано? скажем, если просто считать из парсера в кейс класс, то теряется кондишн а если продолжать держать кондишн, то, возможно, сильно усложнится эта самая бизнес логика, тк ей надо будет постоянно выковыривать значения

я как-то пытался на скаламетовских аннотациях похожие валидации сделать, и на этом этапе забил

Google
Oleg
12.03.2018
15:14:24
а как это будет с бизнес логикой слинковано? скажем, если просто считать из парсера в кейс класс, то теряется кондишн а если продолжать держать кондишн, то, возможно, сильно усложнится эта самая бизнес логика, тк ей надо будет постоянно выковыривать значения
Смотря как твой кейз-класс сделан. Вполне можно считать, что твой кейз-класс предполагает соответствующие требования к данным, или содержит структуру, пост-валидационной формы. Например на вход у тебя String Refined UUIDRegex а в кейз-классе ужу просто UUID

Alex
12.03.2018
15:15:40
пагадити а что мешает в кейскласс рафинад засунуть

Oleksandr
12.03.2018
15:15:59
пагадити а что мешает в кейскласс рафинад засунуть
возможно, сильно усложнится эта самая бизнес логика, тк ей надо будет постоянно выковыривать значения

я без понятия, не юзал не в песочнице, потому и спрашиваю

может, это необоснованный страх

пагадити а что мешает в кейскласс рафинад засунуть
тогда refined пролезет по всему проекту, и "либа валидации" становится весьма жесткой, трудновыпиливаемой зависимостью

может, есть какая умная теория, где рассказывается, как надо правильно

Alex
12.03.2018
15:18:13
а зачем выпиливать валидацию

Oleg
12.03.2018
15:18:47
вот есть у тебя RegisteredUser(..., age: Int Refined Adult, ...) или RegisteredUser(..., age: Int, ...) в первом случае ты можешь считать гарантию встроенной в тип во втором случае тебе нужно удостовериться, что все твои "смарт-конструкторы" не позволят сгенерировать некорректное значение И то и другое норм, и в том и в другом случае ты можешь считать, что гарантия age >= 18 присутствует

Oleksandr
12.03.2018
15:18:58
а зачем выпиливать валидацию
например, баг или надоели аллокации это не так важно, нельзя делать либу валидации косяком проекта

Oleksandr
12.03.2018
15:21:22
Oleg
12.03.2018
15:21:25
case class RegisteredUser(age: Int) { assert(age > 18) }
да, именно этого г-на и не хотелось бы видеть

Dmitry
12.03.2018
15:21:25
зачем ты так?

Alexander
12.03.2018
15:21:51
У нас на соседнем проекте было где-то.

Google
Oleksandr
12.03.2018
15:23:05
Это же просто типы, хм.
кмк, бизнес логика не должна вообще знать про какую-либо обертку-валидацию

Alexander
12.03.2018
15:23:50
кмк, бизнес логика не должна вообще знать про какую-либо обертку-валидацию
А если у тебя в "бизнес логике" написано, что контент можно отдавать только пользователям 18+?

Oleksandr
12.03.2018
15:24:34
А если у тебя в "бизнес логике" написано, что контент можно отдавать только пользователям 18+?
то ей на вход должны уже поступать данные, чтобы на начало работы этой самое бизнес логики все было ништяк

Oleksandr
12.03.2018
15:27:09
почему?
ну такой пример — на вход (Int > 23), а по "бизнес логике" надо > 18 и я вижу только два варианта: либо проверки оберток руками в начале метода, и смысл тогда всех этих рефайндов (минус исчезает, если либа сама поймет, что 23 > 18, в чем сомневаюсь) либо то, что я писал

Oleg
12.03.2018
15:29:34
ну такой пример — на вход (Int > 23), а по "бизнес логике" надо > 18 и я вижу только два варианта: либо проверки оберток руками в начале метода, и смысл тогда всех этих рефайндов (минус исчезает, если либа сама поймет, что 23 > 18, в чем сомневаюсь) либо то, что я писал
ну смотри, твой метод в бизнес логике может принимать на вход Int Refined GT18 и этим он выражает свои prerequisites Благодаря этому методу нужно меньше думать, как сообщать об ошибке, что входные данные соотвествуют требованиям.

Теперь ты со стороны пользователя метода - у тебя есть просто Int, и ты вынужден верифицировать условие, т.е. тебе заранее придётся подумать - а что делать, если мой инпут не подходит

Либо у тебя откуда-то. Может вообще прямиком из реквеста есть уже Int Refined GT23 и ты можешь явно сконвертить его

Grigory
12.03.2018
15:31:01
да ладно рибята о чем вы спорите вообще надо ток как в анси си и переменные по одной букве и типы везде писать да и вообще можно указателями уобойтись не надо знать тому кто читает код что там за типы и обфускация доп

Grigory
12.03.2018
15:31:58
Александр
12.03.2018
15:32:44
чет протекает обильно очень флудилка

Oleksandr
12.03.2018
15:33:15
Теперь ты со стороны пользователя метода - у тебя есть просто Int, и ты вынужден верифицировать условие, т.е. тебе заранее придётся подумать - а что делать, если мой инпут не подходит
вот тут самое интересное правда ли, что, на текущий момент в скале, нельзя автоматически заиметь пруф того, что GT23 соответствует GT18 ?

Alex
12.03.2018
15:33:16
всмысли? обсуждаем сугубо скальную либу

Grigory
12.03.2018
15:33:41
Oleg
12.03.2018
15:34:02
Но я правда не уверен, что можно в той самой либе сконвертить T Refined Greater[23] в T Refined Greater[18] Можно?

По-идее где-то были такие макросы

это не очень сложно

Oleksandr
12.03.2018
15:37:03
гм, если это можно, и можно оперировать с T Refined G как с просто T (само чтобы конвертило), то было бы супер круто

Google
Oleksandr
12.03.2018
15:38:11
ладно, последнее, думаю, можно как-то на уровне компайлер плагина подкрутить, чтобы дописывал строчку конверсии

типа из def foo(x: Int Refined Greater[23]) { ... получить def foo(_x: Int Refined Greater[23] { val x: Int = _x.getHiddenValue ...

с автоматическими пруфами таки сложнее, "23 > 18" — самое простое вероятно, прийдется руками их писать в каждом месте вызова

Oleg
12.03.2018
15:42:03
Ну у автора рефайнеда есть соотв. репозиторий

https://github.com/fthomas/singleton-ops

Alex
12.03.2018
15:44:50
чел боится либу в проект втащить, а ты такой for Typelevel Scala with SIP-23

Admin
ERROR: S client not available

Oleg
12.03.2018
15:46:28
кто-то ещё не на тайплевеле?

Oleksandr
12.03.2018
15:47:06
99%

https://github.com/fthomas/singleton-ops
попробую прикрутить на пете, авось понравится

Oleg
12.03.2018
15:51:51
Глянул насчёт аллокаций

Вот такое определение case class AdultUser( nameP: String, name: String Refined Regex, age: Int Refined Greater[18], ageP: Int)

Вот такой javap конструктора

public AdultUser(java.lang.String, java.lang.String, int, int); Code: 0: aload_0 1: aload_1 2: putfield #48 // Field nameP:Ljava/lang/String; 5: aload_0 6: aload_2 7: putfield #52 // Field name:Ljava/lang/String; 10: aload_0 11: aload_3 12: putfield #55 // Field age:Ljava/lang/Integer; 15: aload_0 16: iload 4 18: putfield #58 // Field ageP:I 21: aload_0 22: invokespecial #145 // Method java/lang/Object."<init>":()V 25: aload_0 26: invokestatic #149 // InterfaceMethod scala/Product.$init$:(Lscala/Product;)V 29: return

т.е. в параметрах этот энивэловый рефайнмент ничем не отличается от исходного типа В хранимых полях будет примитивы боксить

Alex
12.03.2018
15:54:16
ну у него в ридми так и написано тащемта

Oleg
12.03.2018
15:55:07
ну у него в ридми так и написано тащемта
Подумал, что раз уж я не долистал ридми до конца и всё равно уже залепил конкретный javap, почему б не поделиться

Эхх, когда там ньютайпы

Daniel
12.03.2018
16:23:51
зачем вообще opaue types когда для jvm пилят value types (valhalla)?

Google
Юрий
12.03.2018
16:26:34
Daniel
12.03.2018
16:29:44
вот, расскажите, в чём разница? opaque types все затираются на фронтэнде, а value types не имеют header ов, то есть объект Point представляется в памяти в виде двух значений x и y.

в массиве они хранятся в виде последовательностей x ов и y ков.

Oleg
12.03.2018
16:31:27
вот, расскажите, в чём разница? opaque types все затираются на фронтэнде, а value types не имеют header ов, то есть объект Point представляется в памяти в виде двух значений x и y.
Короче разница в том, что opaque types все затираются на фронтэнде, а value types не имеют header ов, то есть объект Point представляется в памяти в виде двух значений x и y. в массиве они хранятся в виде последовательностей x ов и y ков.

Daniel
12.03.2018
16:31:56
это не одно и тоже?

Oleg
12.03.2018
16:32:13
нет

Daniel
12.03.2018
16:33:19
я не утверждаю, а пишу, что понял из докладов, если что :))

Oleg
12.03.2018
16:34:02
ньютайп - это семантический контейнер, который имеет тот же рантайм, что и содержимое

ты можешь налепить 100 ньютайпов поверх инта, в рантайме - это будет 32 бита

все "методы" opaque types как в случае правильно сделанных AnyVal превратятся в статические вызовы, jvm\js вообще не узнает, что у тебя там было что-то под обёрткой

opaque types могут быть полиморфными и содержать любое количество фантомных параметров

и каких-то - относящихся к его содержимому

с вальгаллой ты можешь построить любой класс, и запихнуть туда кучу байт, соответствующих заэмбеденным классам, но верхний класс всё равно останется остальным И насколько я понимаю, заэмбеддить без статического представления для jvm что эмбеддить ты не сможешь Т.е. вряд ли у тебя будет class Sum<T> где T можно заэмбеддить, а с opaque нет проблем

Короче, весь этот понос о том, что opaque разруливаются за счёт компилятора, у которого гораздо больше инфы о структуре кода

Daniel
12.03.2018
16:43:43
беглый просмотр вики openjdk говорит, что вальгалла это два пункта 1) специализированные дженерики (что и так уже есть) 2) принятие сердцем рантайма иммутабельности и уменьшение излишних копирований и прочих гардов ради перформанса

про типы только "дженерики"

Daniel
12.03.2018
16:45:42
http://www.oracle.com/technetwork/java/jvmls2016-goetz-3126134.pdf

как минимум, это типы данных с одим указателем, то есть они ведут себя как int, double и т.д.

да, это твой пункт 2))

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