Обновить
4K+
7

Пользователь

7
Рейтинг
7
Подписчики
Отправить сообщение

Раз пошла такая пьянка, то картинку взял из тырнета и просто слегка перекроил под требования хабра. А кто первым обратил внимание на созвучие SCDU со “скыдыщ”, я не знаю. Это что-то пришедшее из народных толщ.

Всё так. Чем уже сфера ответственности, тем меньше шансов что-то сломать на широком фронте.

По хотрелоаду вполне возможно, что вы пытаетесь взять планку, которую F# не взял. У нас в REPL изменённый тип – это новый тип. С точки зрения компилятора он не эквивалентен старому, поэтому их нельзя просто так смешивать (за исключением случаев апкаста к общему предку). Часто приходится пересобирать зависимые модули и т.д. Кложуристы при столкновение с этим начинают выть, но после обретения некоторого опыта желания компилятора можно предвосхищать.

С рекордами приблизительно тоже самое происходит. Если добавить в некий тип поле B, то все конструкции вида { record with A = 42 } (новое поле не задействовано!) в зависимых dll начнут падать в рантайме, пока их не пересоберут с обновлённой либой. Код при этом останется идентичным. То есть проблему не решили by design, но существенных потерь от этого никто не понёс.

Применительно к F# ожидания надо скорректировать. Мы действительно до поры игнорируем обратную совместимость как несущественный фактор и не испытываем по этому поводу угрызений совести, так как эта схема работает на дистанциях значительно больших, чем это можно было представить по опыту C#. Лишь когда припрёт, мы начинаем танцы с бубнами. Причём этими танцами владеет очень ограниченный набор лиц/ Большинство из них явно выходят из аудитории, с которой работает Влашин как автор блога.

// Опыта общения с ним в роли консультанта не имею, и не знаю, что он говорит при личном общении.

Всё сильно зависит от проекта. У мя обычно речь идёт о десктопных/мобильных приложениях и в последнее время об играх. Тут по умолчанию нет команд, которые используют наши dll как либы в своём коде. Поэтому несмотря на приличный объём кодовой базы, мы очень легко идём на ломку типов.

Более того, я предпочитаю ломать обратную совместимость каждый раз, когда чувствую, что во всём зависимом коде надо среагировать на изменения логики. В этом случае я могу искусственно заменить .PropertyName на .PropertyName_42, после чего пойти каскадно править весь поломанный код и в ручном режиме решать, достаточно ли механической правки имени, или нужно что-то потяжелее. Это же решение будут вынуждены принять все разрабы, когда стянут изменения в свои ветки.

Сиё обсуждение происходит уже не в первый раз, и как я понял, для C#-еров такой подход выглядит экстремально, но тут просто необходимо учитывать устройство F#. Язык провоцирует нас создавать много типов с очень узкой сферой применения (<= домену в тдд). Если этому противиться, можно оказаться в ситуации, когда каждая правка будет сопровождаться философскими рассуждениями о том, каким эхом наши действия отразятся в вечности. Долго в режиме “симулятор тайп-астронавта: вид сбоку” существовать не получается, поэтому неизбежно начинается эрозия качества и прочий “реализьм”. Оба варианта мне не нравятся.

Понятно, что в случае библиотечных (ну или просто очень больших) решений у подхода ломай -> чини -> повтори будут трудности. Придётся изворачиваться, работать через type extrensions, быть может отказаться от алгебраических типов, чтобы не сталкиваться с перспективой неработающих конструкторов и т.д. Однако, во-первых, до проекта таких размеров надо ещё дожить, во-вторых, даже на больших кодовых базах большая часть кода существует в изолированных карманах, которым “библиотечный” уровень обязательств без надобности.

Поэтому рядовому разрабу достаточно чётко понимать, в каких условиях он находится и действовать соответствующим образом.

Я должен на серьёзных щах объяснять, почему F# используется в примерах статьи, которая является переводом главы из почти канонического цикла по F# с сайта fsharpforfunandprofit?

То, как C# видит мой код, меня не беспокоит, так как C#-ом мы лет 7+ фактически не пользуемся. В тех редких случаях, когда нужно скормить код C#-ерам или генератору кода, я могу добавить какую-то проекцию дружественную к C#, но вносить изменения в ядро я не буду.

В тележном F#RU-чате есть любители миксовать языки, но я к ним не отношусь и последствия их движухи наблюдаю со стороны. Если хочешь помусолить эту тему, иди туда. На хабре этот лагерь фактически не представлен.

Тут два варианта. Если пример может быть локально адаптирован, то эту задачу может сделать нейронка. А если пример надо переписывать глобально, то придётся по всему тексту запускать ещё одно повествование. Это уйма работы. Думаю, что всем жаждующим лучше самостоятельно найти авторов, которые уже адаптировали идеи из этого цикла под свой язык.

По моему, в этой статье примеры ещё не позволяют себя улучшить посредством монад.

Исторически специализируюсь на десктопных приложениях. Остальное идёт как побочный результат. Плюс сейчас по фану начал заползать в геймдев. Отголоски этого процесса можно глянуть в хабе F#.

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

Однако точно могу сказать, что нет никакого смысла напирать на эффективность, контролируемость, тактильность, безопасность и так далее. Коллективной Раисе Максимовне важна только безответственность. Поход команды вверх по лестнице в режиме думгая её если и интересует, то явно не в том ключе. Так что собрать на своём планшете (в настольном смысле) самый лучший “движок” и пойти валить всех, кто посмел проявить слабину, вам никто не даст. Протаскивать придётся иными средствами, и в любом случае потребуется административный ресурс. Если конечно, мы не говорим о сопровождающих работу утилитах. Их можно пилить на F# явочным порядком.

C# методично забирает, но криво и, так сказать, с элементами не самой удачной отсебятины. Из-за этого исчерпывающе F# исходники на C# перекладывать не получается. Особенно в тех ситуациях, когда разработка проекта достигла стадии конвейера с распрыгами на гранатомёте. Однако до непосредственной попытки переноса это может быть незаметно. В результате межлагерная коммуникация местами даже ухудшилась, так как до этого C#-еры не знали, с чем имеют дело, и поэтому прилагали усилия к изучению, а сейчас лишь думают, что знают, и поэтому ничего не делают.

Есть фичи, которые C# уже не перенесёт (либо перенесёт с большими костылями). Например, computation expressions, так как они очевидно входят в конфликт с существующими IEnumerable и Task. Это важно, так как у нас до четверти кода на проекте может находиться в рамках кастомных CE.

Наконец, по поводу “мёртвости” языка. F# не бросили посреди крупной миграции, так что он находится в очень стабильном состоянии (за что мс таки можно сказать спасибо). И всё, что в него можно было быстро добавить, добавили почти в самом начале, а не через 15 лет. Почти всё, что хотят добавить теперь, потребует высадки космодесанта от мира программирования (он есть, но занят). В данный момент наибольшее влияние на код F# оказывают либы, которые пилят сами F#-исты (публично или приватно). Скажем, замена Hopac.Stream на что-то очень похожее, но чуть более сложное и совершенное на базе того же Hopac, сказалась на моём коде куда радикальнее, чем всё, что пережили C#-коллеги за последний десяток лет. Кейс, конечно, не рядовой, но с опытом в Erlang (у меня его нет) на F# можно и не так разгуляться.

Не очень понял, о чём вопрос.

Если о F# в целом, то это мой основной язык разработки. И так как у меня набита рука на десктопных приложениях и квазиакторных системах, в Godot я чувствую себя как дома. Разумеется, после проведения предварительных работ.

Если про статью или цикл, то с оригинальными тайловыми мирами я разобрался где-то в июле 2024, а сейчас всё ещё тяну резину с выпуском статей. Пишу нерегулярно, поэтому получается так медленно, но ввиду большого количества общих моментов, ценность написанного вряд ли потеряет силу.

Меня немного смущает, что я уже 13 раз публиковался в хабе Godot, а конца цикла всё нет, но у нас в F#-комьюнити есть проблемы с распространением опыта, и таким образом я потихоньку эти проблемы решаю. Плюс нахожу людей, которые по каким-то причинам в сообществе не представлены.

Ну и чисто для себя практикуюсь в дистанционном обучении. В моём окружении принято считать, что я могу объяснить, что угодно, кому угодно, при условии, что я понимаю о чём идёт речь, и оппонент не морозится и не саботирует передачу апелляциями к чуду, тайне и менталитету. Затык в том, что при односторонней передаче, типа тех же статей, когда собеседника не видно и не слышно, я не могу на него реагировать и мне приходится только предполагать. В минуты, когда я воспринимаю это как вызов, тексты пишутся, а когда -- как издевательство, процесс останавливается.

Тут сорян. В мои задачи не входило рекламировать F# среди неинфицированных. Данный цикл для тех, кто ощущает личную предрасположенность к F#, но сталкивается с трудностями в виде необходимости откатываться к более "классическим" подходам из-за неопытности и/или неверно заданных максим. В некотором смысле это реакция на вал повторяющихся в F# Weekly текстов, которые раздают одни и те же советы и игнорируют одни и те же проблемы.

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

Что касается интеграции C#+F#, то она, что называется, "зависит". Что-то хавается бесшовно, что-то надо подкручивать. Тут надо смотреть конкретные случаи, но в целом я предпочитаю вовсе не использовать C#-проекты (не либы) в солюшене, так как в большинстве случаев они работают тормозом для всего солюшена. В Godot это формально невозможно, но на практике за C#-ом остаётся всего несколько единоразово добавляемых файлов. Я б сделал из них библиотеку, если бы до конца понимал механизм подхвата Godot, но сейчас мне проще закинуть пачку файлов руками.

По вакансиям ничего не скажу. Я как-то пришёл к выводу, что лучше всего наниматься к конкретному проверенному инженеру, иначе высок риск наткнуться на тотальный невменоз, а это предполагает несколько иной подход к поиску проектов. Плюс здесь идёт речь про геймдев, причём исключительно индигеймдев, так что я ориентируюсь на людей, которые пилят (ну или запилят в будущем) что-то своё.

Большинство их них оказываются перед угрозой не вывезти свой проект из-за его объёмов, и здесь F# может помочь за счёт большей скорости и меньшего количества архаики. За это придётся заплатить на старте, но есть люди, которые любят и (главное) умеют играть в долгую. Сим текстом я пытался им помочь.

---

Будет глава с подзаголовком "С# не нужен" (скорее всего №10), попробую заглянуть тогда. Если я ничего не перекину на потом, к тому моменту станет ясно, в каком ключе я веду разработку на Godot, и ты быть может поймёшь "зачем F#".

Ну и в целом, можешь с техническими вопросами в тележную личку писать. Пока что через Хабр идиотов ко мне не приходило будьте первыми!, так что я пусть и не сразу, но с интересом гляну, с чем возникли проблемы.

Да в целом норм. Если нет задачи интеропиться именно с API андроида, то разницы почти никакой. Отработал на компе, собрал, закинул на андроид, потыкал, быть может сделал пару поправок на другой экран и управление, идёшь дальше.

Правда, у мя нет и в ближайшее время не будет массовых приложений, так что я могу себе позволить не доделывать некоторые фичи. Я их просто не ковырял, но ввиду того, что движок не даёт доступа к Android-проекту, подводные камни определённо должны быть.

Я не думаю, что проблема в кодировке происходит от оси. Latin1 - не дефолтная. Автор пакета сохранил на неё указатель, так что скорее всего переключение было сознательным. Предположу, что он упёрся в корнер кейс при разборе консольного вывода и обошёл его данным хаком. То есть ситуация аналогично тому, как девопсы лочат локаль на en, чтобы не парсить сообщения об ошибках на других языках. Ход грязный, но достаточно надёжный.

// Промазал с ответом.

На похожий вопрос отвечал подробно выше https://habr.com/ru/companies/first/articles/865932/#comment_27667896

Добавить могу лишь то, что в абстрактной ситуации между скриптами на ОС и на F#, я выберу F#, ибо последний является моим основным инструментом. Весь свой девопс (отличный от готовых задач из маркета) держу в .fsx. Потребностей перейти на что-то другое как-то не возникало.

Что касается специального софта. то в его сторону даже не смотрел. С областью не знаком, так что раскуривать её мне придётся дольше, чем я решил свою проблему.

Аргументация верная, но в скрипт я полез из-за того, что у меня бомбило от несовершенства софта. Кроме того флешку не так-то просто вынуть и физически, и программно (там приложения стоят). По хронометражу может и быстрее, но точно не удобнее.

Не, конфликт кодировок на содержимое файлов не распространяется. Так что если бы я шарил в adb больше, я бы может так и сделал. Однако я иначе представлял себе её назначение, поэтому даже не предполагал наличие такой команды.

К тому же я не знал точный путь к директории. Я был уверен, что меня ждёт отдельный диск D, а не подпапка. Благодаря SharpAdbClient и SyncService у меня была готовая структура данных, которой я мог оперировать в привычной мне манере, так что поиск не занял много времени.

Кроме того, структура папок моего фото-архива устроена сложнее, чем исходная папка на телефоне. На F# я могу легко написать предикат, который установит наличие копии в фото-архиве, но сделать это через консольный скрипт я сходу не смогу. Соответственно надо копировать либо всё, либо дёргать файлы по одному, а мне это проще делать через скрипт.

И наконец, мне надо было удалить файлы на телефоне, но не все. Некоторые моменты мне хотелось иметь и там, и там. Это подразумевает поштучное удаление, а в моём случае ещё и перенос файлов с внутреннего хранилища телефона на sd-карту.

Если бы я столкнулся с непреодолимым препятствием, я быть может допёр до adb pull, но всё удавалось слишком быстро и легко, чтобы я успел остановиться и подумать об альтернативах. Правда и сейчас я не вижу в этом смысла, так как мои скрипты проворачивают все необходимые мне операции с предельной точностью. Причём они могут делать это в автоматическом режиме, просто обнаруживая телефон в своей зоне действия.

Чистые функции хорошо взаимодействуют с пайпами, но всё же я акцентировал внимание на отсутствии шума от промежуточных переменных и т.п. Это разные плюшки, хоть они зачастую и идут пакетом. Существуют DSL, адаптированные под пайпы, где каждая строка обладает неслабым сайд-эффектом. В Godot без этого не обойтись из-за устройства API некоторых сервисов.

  1. Да, функции тоже можно. Так работает кодоген по Swagger и т.п. Однако по моему опыту в F# на основе внешнего источника данных чаще генерируются структуры данных, а не функции. Для последних характерно использование рефлексии по существующим библиотекам, то есть источник данных скорее внутренний.

  2. Лет 6-7 назад в C# уже был рослин, которые позволял ворочить AST непосредственно в VS. Я практически не пробовал вытаскивать его наружу, но не думаю, что это вызовит серьёзные сложности. Кроме того в C# есть сорсгены, но они обычно подразумевают более общие задачи без серьёзной кастомизации.

  3. partial в неумелых руках может превратить проект в кашу, но в случае с Godot разрабы накидали своих фишек.

В Godot всё описывается через ноды, которые могут вкладываться друг в друга без ограничений, за счёт чего получаются очень раскидистые деревья. Это напоминает UI-фреймворки, но в качестве ноды может быть объект, который отвечает только за логику и вообще никак не взаимодействует с UI. У этих нод есть свойства и события, но они полностью не закрывают всех фич, часть из которых доступна только через переопределение методов. Проблема в том, что просто переопределить метод недостаточно, ещё важно сделать это в нужном месте проекта.

Для того, чтобы Godot узнал о override в типе, этот тип должен лежать в C#-проекте и быть partial. Если я просто закину анонимную ноду в глубине сцены:

{ new Node() with
    override this._Process delta =
        if Input.IsKeyPressed Key.Shift then
            GD.print "Shift pressed!!!"
}

То Godot никогда не вызовет метод _Process, потому что будет считать, что он не был изменён. Я пока не понял, почему они сделали именно так, но проблему приходится решать через создание прослойки вида:

public partial class InCSharp : InFSharp
{
    public override void _Process(double delta) => base._Process(delta);
}

На каждый тип вида:

type InFSharp () =
    override this._Process delta = 
        ()

Получается, что я:

  • Не могу избавиться от C#-проекта.

  • Вынужден дублировать все ключевые типы с переопределениями.

  • Вынужден создавать их через фабрики, так как вместо InFSharp() мне надо неявно вызвать InCSharp().

Кроме того есть проблемы с экспортируемыми свойстваи и сигналами, которые также надо протаскивать через C#.

Я постепенно закатываю весь этот шум в асфальт и уже явно вышел в плюс, но мне не понятно, зачем этот комплекс проблем вообще был создан. В 3 версии Godot такой проблемы не было.

1

Информация

В рейтинге
907-й
Зарегистрирован
Активность