Здравствуйте, WolfHound, Вы писали:
L>>Аргументы? WH>Уже много раз написал. WH>Но ты проигнорировал.
Нет, это не так. Фраза про "глубоко фиолетово" прозвучала 2 поста назад, много раз ты на нее ответить чисто физически не мог.
L>>Что именно для макроязыков не так? Для макроязыков так просто спроектировать фичу языка, что они хорошо ляжет на целевой язык? Благодаря чему? WH>Благодаря тому что этой задачи нет вообще. WH>Я тебе тут давно об этом говорю. WH>А ты все понять не можешь. WH>Если макра кривая она просто умрет и все. WH>Точно также как умирают кривые библиотеки.
Ты знаешь, я не верю в то, что путем естественного отбора может получиться хороший язык. Путем естественного отбора может получиться только шлак. Хорошие вещи изначально качественно и вдумчиво проектируются (хотя и это не панацея) и языки тут не исключение.
L>>Внимание, вопрос. Что делать с унаследованным кодом? А ну да, "настояшие" программисты от такого нос воротят. WH>Тоже что делают с унаследованным кодом, в котором используется мертвая и кривая библиотека. WH>Разницы нет никакой. WH>Совсем.
Нет, разница есть и она очень велика. Если проводить аналогию с естественным языком: язык — это способ мышления, а библиотеки — это всего лишь слова языка. Слова ежедневно приходят и уходят, а глубинная структура языка остается преждней.
Я знаю, что аналогия не является доказательством, но чем богаты.
Здравствуйте, WolfHound, Вы писали:
Q>>А что, было бы неплохо. И уже для имитации императивных конструкций добавлять сахар, который позволит вместо вложенной структуры байндингов использовать линейную последовательность «инструкций» с «присваиваниями»... Постойте-ка, где-то я это уже видел! WH>В немерле?
Здравствуйте, Qbit86, Вы писали:
Q>Здравствуйте, Lloyd, Вы писали:
L>>Каким образом statement может что-то возвращать?
Q>a return что, не statement?
Тут под "statement" я имел в виду statement-ы из твоего примера. Раз ты отдельно выделил return, я решил, что в других statement-ах return-ов нет.
Q>>>Ты просто скрыл недостижимую константность внутри. Снаружи всё константное, но внутри по прежнему программист может «вклиниться» в момент, где какая-то переменная уже создана, но ещё не инициализирована.
L>>Каким образом?
Q>Да вот тем, который ты же показал
Q>Внутренняя «double y» у тебя не константа, и какое-то время пребывает в неинициализированном состоянии.
Этот код не должен скомпилироваться. Если он компилируется, это ошибка. Но в самой концепции ошибки нет.
Q>Во, ещё один эксплоит придумал, даже без исключений. Предположим, у тебя рассчёт производится в сторонней библиотеке: Q>
Q>И всё бы ничего, но в один прекрасный день разработчики сторонней библиотеки изменили код: Q>
Q>void compute(double sin_φ, double& y)
Q>{
Q> if (0.0 < y) // Использование потенциально неинициализированной переменной.
Q> y = 0.5 * ::log((1.0 + sin_φ) / (1.0 - sin_φ));
Q>}
Q>
Q>И всё! Даже исключения об использовании неинициализированной переменной не будет! Компилятор в общем случае не в состоянии понять, что во внешней функции с переданной ссылкой творится.
Тут мы отдаем контроль в руки программиста. По правильному — надо различать ref и out-параметры, как это сделано в том же шарпе.
Q>>>Просто вбей в редактор и проверь (именно так я и сделал). Только синтаксис C++0x-замыканий используй: «[=]() -> double { ...; return ...; }». L>>Нет у меня редактора, я говорю о гипотетическом языке.
Q>Я так понял, ты говоришь о гипотетическом языке, который будет расширять сахаром существующий язык (или аналог), заменяя существующий подход более простым синтаксически. Очевидно, C++ таким образом не расширишь. В него и лямбды-то со скрипом всунули, да и то получилось не ахти.
Да я на C++ и не покушался.
L>>Предложенный let работает только в выражениях. Ты предлагаешт выбросить все императивные конструкции?
Q>А что, было бы неплохо. И уже для имитации императивных конструкций добавлять сахар, который позволит вместо вложенной структуры байндингов использовать линейную последовательность «инструкций» с «присваиваниями»... Постойте-ка, где-то я это уже видел!
Ох, не начинай.
Q>>>В заключение хочу сказать вот что. Так как в наших широтах сейчас стоит прелестнейшая погода, предлагаю засчитать мне технических слив, а я отправлюсь бегать кросс. L>>Ну уж нет, рано или позно ты вернешься.
Q>
1. Инструментарий: медленная компиляция в сочетании с глючной инкрементальной компиляцией и пока ещё убогими и сырыми IDE.
2. Отсутствие хорошей документации по некоторыми нетривиальным вещам (combinator parsers; actors — с механикой остановки актора не разобрался, времени не хватило).
3. Ограничение на максимальное количество полей (22) у case-классов; для классов данных с большим количеством полей приходится вручную писать все те же методы, что case-классы дают автоматом.
4. Как ни странно, отсутствие метапрограммирования (макросов как в Nemerle) — некоторые вещи напрашиваются на обобщение (entity-классы; в lib.web forms многовато рефлексии и т.п.).
5. Вывод типов мог бы быть куда мощнее. Ладно ещё обязательное указание типов для параметров функций — я типы указываю частенько даже там, где необязательно, чтобы логику свою контролировать. Но очень часто она требует типы в параметрах анонимных функций (в частности внутри generic-контекста), хотя запросто могла бы и сама вывести. Блин, точно надо на немерл переходить.
Здравствуйте, Lloyd, Вы писали:
L>По правильному — надо различать ref и out-параметры, как это сделано в том же шарпе.
Всё верно. Оба патологических случая (ловля исключения до завершения инициализации и передача неинициализированной переменной в метод по ссылке), видимо, не удалось бы воспроизвести в СиШарпе или Джаве. Правда, может, есть другие контрпримеры — «отсутствие доказательства не означает доказательства отсутствия» :)
L>Но в самой концепции ошибки нет.
Всё равно math-like синтаксис «where» в Хаскель мне нравится больше, чем дурацкое разнесение объявления и определения переменной по разным углам. В нём иерархическая структура выражения чётче просматривается.
Здравствуйте, Qbit86, Вы писали:
L>>Но в самой концепции ошибки нет.
Q>Всё равно math-like синтаксис «where» в Хаскель мне нравится больше, чем дурацкое разнесение объявления и определения переменной по разным углам. В нём иерархическая структура выражения чётче просматривается.
да я не против. вопрос лишь в том, как это ляжет на императивные блоки кода.
Здравствуйте, Qbit86, Вы писали:
Q>Я название исказил. В «FDG» это называется Tester-Doer Pattern. Это когда к методу Parse, бросающему исключение, добавляют метод TryParse с мерзкими out-параметрами и возвращаемым bool'ом.
Ох, щи! Там 100500 комментариев, «tl;dr», извините.
U>Out, конечно, не идеальное решение, но Option еще хуже.
Это что; есть мнение, что стандартные итераторы вместо «MoveNext():bool»/«Current:T» надо было на опционах делать. Но если что, я этого не говорил. Десятистраничного холивара не осилю.
1. Много синтаксических конструкций ради "галочки", одну вещь можно сделать разными способами.
2. Много завязок на java. Не хватает простых обёрток и библиотек (большой оверхед). Местами требуется, чтобы код был более java-подобный, т.е. приходится думать почти на 2х языках.
3. Дефолтная фича для конфигов является наполовину кодом, но не валидным, а потому неисполняема. Зато очень хорошо путает.
4. Крайне медленная работа.
5. Невнятный и неудобный рефлекшн.
6. Безумные стек-трейсы, которые могут в своём безумстве посоревноваться с эрланговскими.
7. В некоторых случаях не все ошибки расскажет (и это в рантайме!).
...coding for chaos...
Re[17]: C#: const для переменных, pattern-matching, ...
Здравствуйте, WolfHound, Вы писали:
L>>Что именно для макроязыков не так? Для макроязыков так просто спроектировать фичу языка, что они хорошо ляжет на целевой язык? Благодаря чему? WH>Благодаря тому что этой задачи нет вообще. WH>Я тебе тут давно об этом говорю. WH>А ты все понять не можешь. WH>Если макра кривая она просто умрет и все. WH>Точно также как умирают кривые библиотеки.
Т.е. долго и мучительно, по пути съедая мозг всем поддерживающим код программистам.
Re[18]: C#: const для переменных, pattern-matching, ...
Здравствуйте, VoidEx, Вы писали:
VE>Т.е. долго и мучительно, по пути съедая мозг всем поддерживающим код программистам.
Да. Но разницы с обычными библиотеками совершенно никакой.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[19]: C#: const для переменных, pattern-matching, ...
Здравствуйте, WolfHound, Вы писали:
VE>>Т.е. долго и мучительно, по пути съедая мозг всем поддерживающим код программистам. WH>Да. Но разницы с обычными библиотеками совершенно никакой.
Главное в это верить.
Re[20]: C#: const для переменных, pattern-matching, ...
Здравствуйте, Lloyd, Вы писали:
L>Главное в это верить.
В отличие от тебя я это знаю.
А у тебя только вера в какие-то страшные бедствия, которые никто из практиков не видел.
... << RSDN@Home 1.2.0 alpha 4 rev. 1472>>
Пусть это будет просто:
просто, как только можно,
но не проще.
(C) А. Эйнштейн
Re[21]: C#: const для переменных, pattern-matching, ...
Здравствуйте, WolfHound, Вы писали:
L>>Главное в это верить. WH>В отличие от тебя я это знаю.
И часто-часто повторять. И ни в коем случае не сомневаться.
WH>А у тебя только вера в какие-то страшные бедствия, которые никто из практиков не видел.
Практиков, говоришь? Я с год назад спрашивал про практику использования, кроме самого компилятора никто особо серьезного примера использования привести не смог. За год что-то изменилось или это и есть ваша "практика"?
Поскольку никто про жаву не пишет, придётся мне. Давно уже не юзал, но кое-что помнится.
1. Многабукаф. Нупростодоужасамногабукаф.
2. Не люблю, когда злоупотребляют аннотациями: они хуже проверяются типизатором. В жаве почти все фреймворки работают на аннотациях. Это вот отчаянное желание превратить всё на свете в POJO с аннотациями бесит. Взять тот же Spring MVC. Я хз чем плохо запихать обработчик каждого URL в отдельный класс-функтор (Page.service: Request -> Response), а свойства обработчика сделать дополнительными свойствами / виртуальными методами этого класса. (Не, правда, если кто пробовал и знает, чем плохо, очень прошу поделиться.) Нет, мы разрешим использовать POJO, обращать любой метод в обработчик запроса путём навешивания на него тонны аннотаций — на сам метод и на каждый параметр. Итого: типизация пролетает, как фанера над парижем; нетривиальную валидацию параметров, как и нетривиальную обработку ошибок, хрен прикрутишь; отладить эту AOP-хрень практически невозможно; IDE никаких подсказок не возможностям не даёт (базового класса нет, виртуальные методы подсмотреть негде, а аннотации я хз какие в каком случае применимы), приходится долго читать доки на каждую мелочь. Аналогичные претензии к Tapestry, а вот Wicket рулит.
3. После знакомства с ФП стало резко не хватать методов map(), filter() и т.п. на коллекциях. Плодить циклы на каждое элементарное функциональное преобразование — ну просто тоска смертная. Были какие-то Google collections, но у меня с зависимостями что-то не срослось. Разбираться забил, т.к. в этот период уже от жавы отошёл и не был особо заинтересован (иначе на крайняк сам бы классы-утилиты написал).