@Fsharp_chat

Страница 306 из 772
Evgeniy
09.09.2017
07:44:27
@angmarr Я отписал. Подождем, что скажут. https://github.com/fsharp/fslang-suggestions/issues/594#issuecomment-328261268

Igor
09.09.2017
07:46:19
Спасибо

Evgeniy
09.09.2017
07:50:53
Прикольный пример про вывод типов. let x = List<_>() let c = x.Count // 0 x.Add(Unchecked.defaultof<_>) let c2 = x.Count // 1 printfn "%i" x.[0]

Google
Evgeniy
09.09.2017
08:54:06
Friedrich
09.09.2017
08:54:23
А, вот что, действительно.

А если убрать printf — тогда сломается?

Evgeniy
09.09.2017
08:55:49
Да.

kana
09.09.2017
09:33:55
https://www.youtube.com/watch?v=cxs7oLGrxQ4
Посмотрел, годно. Я уже использовал такой подход в хаскеле, когда писал бэкенд на servant. Идея в том, что какой-нибудь наивный веб-фреймворк типа синатры (scotty в хаскеле) отдает в хэндлеры некоторый объект request (в скотти это через монаду ридер или стейт, не аргумент), а мы потом в хэндлере из этого реквеста достаем всякие парамы, квери, хидеры, проверяем на их наличие, итд. Это все императивно как-то.

В серванте подход другой - мы декларативно описываем наш эндпоинт, типа что он начинается на /users/, далее имеет капчуру :id, значение которого типа UserID (алиас на Int), также есть квери-флаг ?force типа Bool, а на выходе у нас User. Все это декларативно описывается на уровне типов на такой тайплевел едсл, а потом в компайлтайме мы из этой спецификации генерируем типы для хэндлеров, клиенты, документацию. Так наш хэндлер перестанет иметь вид Req -> Res, а будет иметь тип UserID -> Bool -> Either Error User И хэндлер станет простой насколько это возможно функцией, которая ничего не знает про наш веб-фреймворк, она не зависит от него, это просто тупая функция, которая принимает тупые данные и тупые данные отдает

Все как на видео.

kana
09.09.2017
09:46:03
Только дополнительно еще и декларативно type GetUserAPI = "users" :> Capture "id" UserID :> FlagParam "force" :> Get '[JSON] User По этой спеке мы можем бесплатно сгенерировать во время компиляции функцию-клиент (она будет принимать UserId и Bool и делать запрос), документацию, бойлерплейт для фронта на жс для запросов, тип для хэндлера. И этот мини язык очень легко расширять своими комбинаторами (так я написал комбинатор RequiredQueryParam, который отдает 400, если парама нет, иначе отдает значение в хэндлер, обычный QueryParam отдает в хэндлер option/Maybe). И легко писать свои интерпретаторы этого языка, то есть вещи, которые по апи что-то генерируют. Считаю, что будущее веба за сервантом и таким декларативным подходом) Долой всякие getParam "id" response

Google
kana
09.09.2017
10:03:04
Сервант про апи (это роутинг-либа), поэтому этот кейс он не покрывает. Для базы можно использовать подход с доклада врутри хэндлера, тогда хэндлер станет чуть более импурным, а логику мы вынесем в другую функцию, как в докладе. Но я видел всякие servant-persistent с комбираторами для персистент-ормы. Я не знаю, как там что работает, не заглядывал внутрь, видел только название пакета на хакадже. Персистент имхо тоже довольно императивен, мне тут советовали посмотреть на какую-то либу на основе произведения профункторов для доступа к базе) - opaleye. Я ушел тогда осиливать эти произведения и так и забыл

Evgeniy
09.09.2017
10:56:05
Напоминает описание Freya отчасти.
А как в Freya? Я видел, что там довольно симпатичный синтаксис для роутинга, но потом идет машинерия с freyaMachine и оптикой, извлекающей значения из запросов.

Friedrich
09.09.2017
11:06:39
А как в Freya? Я видел, что там довольно симпатичный синтаксис для роутинга, но потом идет машинерия с freyaMachine и оптикой, извлекающей значения из запросов.
Ну да, типа того. На уровне типа немножко не хватает магии. Разбор урлов работает вот так: https://docs.freya.io/en/latest/recipes/routing/uri-templates.html

Может, этот слой даже можно как-то добавить.

Andrew
09.09.2017
11:17:43
Да, разрешилось по %i.
Крутая штука, но по-моему это проектировать нужно в обратную сторону. Все равно, что C# давал бы сначала написать код, а потом из того что получилось слепить интерфейс

Evgeniy
09.09.2017
11:28:30
Крутая штука, но по-моему это проектировать нужно в обратную сторону. Все равно, что C# давал бы сначала написать код, а потом из того что получилось слепить интерфейс
Угу. Просто демонстрация, как вывод типов работает. Такое поведение особенно новичкам может причинять пртблемы.

Vasily
09.09.2017
11:28:51
Ну такой вывод типов можно обойти

Evgeniy
09.09.2017
11:33:39
@impworks И вот ещё такой же пример с inline. https://repl.it/KsQo/0

Я тут с телефона пишу. Очень захотелось какой-нибудь F# редактор с компилятором под Android.

Пока искал что-то похожее, нашел TryFrege. .__.

Видимо, редактор для F# есть только под iOS. http://continuous.codes/

Летучая
09.09.2017
11:44:36
Видимо, редактор для F# есть только под iOS. http://continuous.codes/
Идея для пета! Наквасить на .NETStandard парсер (с тестами на неткоре); накидать гуй на Xamarin/Uwp/Avalonia.

Andrew
09.09.2017
11:45:35
Видимо, редактор для F# есть только под iOS. http://continuous.codes/
Ого, крутая штука. Но 750 рублей кусается

Да и вообще идея опасная. Специально беру в отпуск только айпад, чтобы не было соблазна ничего прогать

Evgeniy
09.09.2017
11:48:14
Идея для пета! Наквасить на .NETStandard парсер (с тестами на неткоре); накидать гуй на Xamarin/Uwp/Avalonia.
Мне было бы достаточно просто мобильного приложения для repl.it. С какой-нибудь дополнительной клавиатурой для символов.

Evgeniy
09.09.2017
11:48:59
Конечно!

Летучая
09.09.2017
11:49:30
И без Intellisence!?

Evgeniy
09.09.2017
11:51:18
И без Intellisence!?
Я во флудилке, кажется, рассказывал, что на втором курсе писал на плюсах в gedit. :) Ну, я шучу, конечно, просто реализация хорошего редактора может затянуться.

Google
Evgeniy
09.09.2017
11:52:30
Pauline
09.09.2017
11:52:42
@dotnettalks
спасибо))

Roman
09.09.2017
11:58:47
Evgeniy
09.09.2017
12:09:09
Для меня в своё время было открытием приложение для WolframAlpha с кастомной клавиатурой для математических символов.

Andrew
09.09.2017
15:37:18
Почему?
Нужно переключаться, полезно для здоровья и продуктивности

Evgeniy
09.09.2017
15:47:59
Берегите здоровье и помните, что нужно в двадцать тысяч раз больше кода!

У нас снова работают логи. http://telegrammy.net/group/Fsharp_chat/page1.htm

F# Weekly #37 – Is F# dead? https://sergeytihon.com/2017/09/09/f-weekly-37-is-f-dead/

Roman
09.09.2017
20:56:22
Evgeniy
09.09.2017
20:56:48
Два ответа.

@neftedollar Ну, и как же он умрет, если мы с тобой на нем пишем, друже?

Мы еще не написали свои "в двадцать тысяч раз больше кода"!

Ivan
09.09.2017
21:00:35
И умрет если мы не поддержим. Причем кодом. Причем в проекте FSharp.

Компилятор надо переписывать. Дон один не будет. А он устарел.

Если поддержите могу взять на себя семантический анализ AST с выводом типов. Есть опыт.

Google
Ivan
09.09.2017
21:16:00
to @gsomix даже не буду в монады лезть ?

Friedrich
10.09.2017
03:48:04
Компилятор надо переписывать. Дон один не будет. А он устарел.
На моей памяти ни один проект, который пытались «переписать», не взлетел. Нужен более-менее продуманный план постепенного рефакторинга и миграции. Нужно понимать, какие сейчас в компиляторе проблемы и кому/чему они мешают. Я думаю, нужен и опыт товарищей, которые намного больше нашего работают с компилятором (авторы Fable, fscx и пр.) В первую очередь тебе нужно со своими предложениями пойти в Slack (там есть канал про компилятор, где обсуждаются доработки и предложения).

Лично я сейчас вижу одну мажорную проблему, которая портит мне малину: неработающие тайппровайдеры под .NET Core.

Ivan
10.09.2017
06:20:14
Попробую обосновать. Сейчас компилятор FSharp: 1. Не является Roslyn компилятором - тяжело вписываеть в экосиситему. При этом не имеет сколько нибудь значимых расширений над обоими другимим Roslyn компиляторами, например компиляции в натив код. 2. Тяжелый. Медленно работает. 3. Высокий порог входа. Я не "осилил" до конца ?. Хотя рослиновский CSharp, Rust и Dotty осилил так, что могу контрибутить. Кстати авторы Fable не компиляторщики, у нас по моему их вообще по палцам рук и ног в мире персчитать можно. А между тем сам язык почти оптимален для обучения( как первый язык), для развития (есть заделы и в сторону высоких абстракций и в сторону низкоуровневости). Как например основа для импортозамещения ? - самое то

А насчет тайп провайдеров - проблема не в том, что Core не позволяет, а в совместимости с уже написанным кодом самих провайдеров. По моему мнению их не сделают. И самая убойная фича никогда не появится.

Friedrich
10.09.2017
06:48:44
А насчет тайп провайдеров - проблема не в том, что Core не позволяет, а в совместимости с уже написанным кодом самих провайдеров. По моему мнению их не сделают. И самая убойная фича никогда не появится.
Про провайдеры: насколько я понимаю, там в каждый провайдер нужно копипастить какой-то огромный кусок F#-кода, который и занимается кодогенерацией. Внутри провайдеров всё выглядит прилично, а вот этот копипастный код нужно переделывать, если мы хотим с Reflection.Emit переехать куда-либо.

Можно попробовать как-то заполифиллить старый API, например.

Я не понимаю, почему этим никто не занимается :(

Попробую обосновать. Сейчас компилятор FSharp: 1. Не является Roslyn компилятором - тяжело вписываеть в экосиситему. При этом не имеет сколько нибудь значимых расширений над обоими другимим Roslyn компиляторами, например компиляции в натив код. 2. Тяжелый. Медленно работает. 3. Высокий порог входа. Я не "осилил" до конца ?. Хотя рослиновский CSharp, Rust и Dotty осилил так, что могу контрибутить. Кстати авторы Fable не компиляторщики, у нас по моему их вообще по палцам рук и ног в мире персчитать можно. А между тем сам язык почти оптимален для обучения( как первый язык), для развития (есть заделы и в сторону высоких абстракций и в сторону низкоуровневости). Как например основа для импортозамещения ? - самое то
А, ну и про сложность кода компилятора: мне кажется, тут вопрос даже не в архитектуре, а в стиле кодирования. Я тоже разглядывал его код и писал небольшие патчи. И, конечно же, кучи однобуквенных переменных в бесконечных pattern-match выражениях просто убивают. Как и файлы по несколько тысяч строк с ровным слоем размазанными функциями (спасибо, хоть без рекурсивных модулей).

Ivan
10.09.2017
06:54:37
А просто некому. Один Дон не успевает. А полифилить надо на уровне компилятора или, скорее, рантайма. А то старье не взлетит. А пока не взлетит - никто прерписывать старье не будет. Проблема, как в WinPhone - сама по себе вещь хорошая, но без экосистемы не летает, а пока нет экосистемы - экосистему развивать некому.

Рослин родился, когда стало понятно, что старый компилятор сдох. А мы все тянем.

Nikolay
10.09.2017
07:00:39
Ну помоему F# сам по себе довольно сложен для компиляции, это в оправдание сложности и скорости fsc

Ivan
10.09.2017
07:02:38
Нет, не сложен. C# значительно сложнее. FSharp жутко логичен. Мало или почти нет оступлений от парадигмы. Единственное место - выводл типов, но как раз там алгоритм взят готовый, отработанный еще в ML.

Nikolay
10.09.2017
07:03:55
А чем сложен C#?

Ivan
10.09.2017
07:04:04
Как доказательство - посмотри на количество типов AST узлов в FSharp и CSharp

В CSharp по моему больше чуть ли не втрое

Friedrich
10.09.2017
07:05:01
Мне кажется, это говорит о том, что в C# эти узлы всегда имеют строго одну функцию, а у нас в F# узлы AST могут выступать в совершенно разных ролях в разных местах кода, и это должно увеличивать сложность компилятора, а не уменьшать.

Ivan
10.09.2017
07:06:04
Меньшее количество типов AST - значит меньше вариантов синтаксиса. Меньше вариантов синтаксиса - короче дерево анализа.

Google
Ivan
10.09.2017
07:06:58
Нет - узел AST безвариантно атомарно компилируемый. Всегда в один и тот же код до оптимизации.

Friedrich
10.09.2017
07:07:33
Хм, ну тогда ок.

Ivan
10.09.2017
07:12:42
Вот посмотри - самый, наверное сложный язык(Haskell), но AST у него очень простой. И компилятор потому так вылизан. https://hackage.haskell.org/package/haskell-tools-ast-0.9.0.0/docs/Language-Haskell-Tools-AST.html

Andrew
10.09.2017
07:40:26
Нет - узел AST безвариантно атомарно компилируемый. Всегда в один и тот же код до оптимизации.
Не совсем понял. Вот например: let a = 1 - код будет принципиально разным в зависимости от того, замыкается эта переменная дальше или нет

Ivan
10.09.2017
08:02:27
Нет не будет. Кода не будет. Именование не создает код ?

Будет что то типа Scope.AddNamed 1 "a"

kana
10.09.2017
09:04:34
Ну так действительно, какая разница, в рутовый скоуп или вложенный какой. Разве лет не замыкается в глобальном скоупе, он же виден всем остальным функциям в нем

Ivan
10.09.2017
09:20:07
Принцип другой. Скоп имеет парента. Смотрит в себе потом в паренте. Когда идет замыкание - происходит инкапсуляция парент скопа. Обычно не совсем корректная. В csharp например некорректная. Он замыкает скоп целиком. А мог бы определить потребности вложенного и замкнуть частично.

При компиляции доступ к скопу делегируется на компиляцию самому скопу. И именно он определяет, как вставить доступ к имени - как статичный по адресу или относительный по таблице.

Enhed
10.09.2017
09:57:12
Ребят, приветствую. Подскажите, пожалуйста, можно ли при наследовании интерфейса реализовать его частично, а некоторые методы так и оставить абстрактными для следующих наследников?

Andrew
10.09.2017
10:11:21
Можно. Раз в c# можно, то и в f# тоже. Это будет абстрактный класс

Klei
10.09.2017
10:12:27
Хм, хотя лично с проблемой не сталкивался. Но ограничения на частичную реализацию точно были.

Igor
10.09.2017
12:28:20
Как правильно сконкатенировать два списка записей, так что бы из второго списка заигнорились записи которые уже есть в первом при этом сравнивать надо только по одному полю id ?

Пока сделал так firstList |> List.append secondList |> List.distinctBy (fun x -> x.id)

kana
10.09.2017
12:42:16
Задача подразумевает множество, но у нас тут уникальность не по объекту, а по полю объекта. Я не знаю, как в сабже, но в хаскеле сет работает только с сравниваемыми типами (Ord тайпкласс, там внутри бинарное дерево (RB) скорее всего, раз Ord, а не Eq). Если на типе объекта определить класс Ord, который будет сравнивать айдишники, но множество будет работать как нужно. Полагаю, что-то такое можно сделать и на фшарпе

В идрисе это сделано еще лучше, там можно делать не один инстанс интерфейса (тайпклассы), а много, каждый можно проименовать. Можно сделать именной инстанс Ord @[byId] и не замусоривать тип лишним интансом (насколько я знаю, именной не применяется по дефолту).

Igor
10.09.2017
13:04:20
К сожалению пока в F# нет тайпклассов ? У модуля List очень мало функций которые принимаю компоратор даже в виде отдельной функции. Меня в принципе текущий вариант устраивает.

А вот как написать коротко вычитание одного списка из друго (сравнивая по id) - что-то пока не соображу.

Страница 306 из 772