Если ему кажется, что это время было «потрачено», и полученная программа сама по себе не стоила его — не нужно было и творить, всё честно. Или же браться только за написания программ по предварительным контрактам.
Но никто и не спрашивает его — хочет ли он получать за это деньги? А он хочет, уж поверьте.
Враньё. Free-as-beer open-source пишется, в первую очередь, для себя — ради интересы, обучения или просто чтобы создать удобную софтину под свои вкусы. Другие пользователи — побочный эффект того, что автор в лом напрягаться, и делать приличный интерфейс, нормальную конфигурацию, документацию и прочие необходимые атрибуты используемого продукта. 90% ( число с потолка ) open-source — наколенная поделка по определению и так и должно быть.
А вот если этот же продукт перерастает определённую стадию и появляется чёткая ориентация на конечного пользователя — вот тогда уже можно думать о том, что за это получать и как окупить затраты. И это совсем другая история.
А те, кто исходит из аксиоматики «каждый кто-то хочет за любой чих денег» — горите в аду, пожалуйста, из-за вас на этой планете жить тошно.
В Dragon Age 1 нет атмосферы? Х_х Ну-ну, имхо это самое олдовое и вообще труЪ что было сделано в жанре за эдак лет 5. В отличие от того же Fallout 3, который добрал пристойный уровень только стараниями тех самых Obisidian к New Vegas.
Прошу прощения за долгие ответы, надо дать себе зарок не ввязываться в дискуссии в разгаре дедлайна.
import std.stdio;
import std.file;
import std.parallelism;
// Синтаксический сахар, которого не нашёл в стандартной либе.
// Возможно стоить сделать pull request для phobos :)
auto launch(T)( T new_task )
{
struct Launched
{
private:
T task;
public:
this(T new_task)
{
task = new_task;
task.executeInNewThread();
}
auto result()
{
return task.yieldForce();
}
}
return Launched(new_task);
}
void main()
{
auto task1 = launch( task!readText("test1.txt") );
auto task2 = launch( task!readText("test2.txt") );
write( task1.result ~ task2.result );
}
Это сравнимый аналог вашего примера? Callback, конечно, неявно где-то все равно передается, но, подозреваю, в недрах имплементации Haskell тоже без них не обошлось.
Я исхожу из предпосылки, что чем меньше мы можем наложить контракта на функцию, тем больше вероятность ошибок.
… мало частных случаев и каких-то ситуаций, где только знание каких-то нюансов стандарта помогает понять, что происходит
Вот тут, боюсь, у нас сильное несовпадение взглядов. Я не вижу прямой связи между линейным увеличением числа контрактов и уменьшением вероятности ошибки. Контракт может быть полезным, может не быть. Каждый раз нужно отдавать себе отчёт в том, какое нежелательное поведение мы стараемся предотвратить каждым отдельным контрактом.
И хороший практичный язык, ИМХО, должен иметь множество частных случаев и нюансов стандарта. И сам стандарт на тысячи страниц. С тем лишь отличием от С++, что незнание этих нюансов не должно бить новичка по лицу, пока он с ними не знаком.
Ну ассемблер напрямую не вставить, ибо Haskell куда выше уровнем, да и компилироваться может через LLVM. Но звать сишные функции никто не запрещает
Я это к тому, что у Haskell и у D несколько разные дизайн-цели. И в D необходимым требованием является то, что встроенный ассемблер должен выглядеть так же естественно, как и функциональный стиль. Равноправное использование всех парадигм.
Если вы желаете услышать ответ на вопрос «Что может мотивировать вас проработать у нас как можно дольше?», то, возможно, стоит задавать именно этот вопрос и именно так, а не играть в игры? Я не собираюсь угадывать ваших намерений, даже если могу. А то ведь потом может оказаться, что техзадание мне так же придётся угадывать.
Я ведь не могу знать этого на момент собеседования. Могу спросить ( и спрошу, не сомневайтесь ), но едва ли поверю сказанному. Это то мнение, которое сформируется эдак через полгода, после пары дедлайнов и прочих прелестей. Вот тогда и можно будет задать вопрос, почему я хочу работать в вашей компании ( и хочу ли ). А сейчас — вы один из множества чёрных ящиков.
И нет, это я собеседую компанию, а не она меня. Если только вы не Google какой-нибудь, конечно. Об этом можно судить, как минимум, по количеству задаваемых вопросов с каждой стороны. Считаете это избытком гонора — без проблем, так и скажите, вежливо распрощаемся. Пока что рынок говорит о том, что я могу себе это позволить, и недостатка в предложениях не наблюдается, хотя, вроде бы, моложе некуда и по статусу не положено.
Дефицит с кадрами у нас в силу простой причины, что во всей стране нет ни одного места, где можно научиться специальности и все программисты хорошего уровня — в той или иной мере самоучки, а те, кто помоложе, предпочитает уезжать сразу, чтобы получить нормальное образование. Но это оффтопик :)
Жду комфортных условий работы — удобных офисных помещений, отсутствия лишней бюрократии, более либеральное отношение к рабочему графику, продуманную организацию рабочего процесса, эффективное распространение информации, близкий по отношению к работе коллектив. Всё вместе, конечно, едва ли бывает ( и в таких местах, не сомневаюсь, и впрямь обивают пороги в поисках вожделенного ), но это уже параметры, по которым можно реально что-то оценивать.
Это не то, что мало, я даже не заинтересуюсь таким предложением. Точнее — это вообще минимум, начиная с которого работодателя можно называть работодателем. Примерно как если бы я заявил, что «Умею написать „Hello world“, мало?».
Возможно, в России тысячи безработных компетентных программистов и обивают пороги компаний ( круто вам! ), а у нас как-то с квалифицированной рабочей силой дефицит. Мой текущий работодатель выплачивает наградные за каждого рекомендованного человека, который был принят на работу, не важно, какого он уровня и сколько на этом месте продержится. И знаете, как-то вот некого рекомендовать даже, не вижу тех самых тысяч программистов.
Потому что количество людей с достаточным уровнем наглости незначительно.
Что не отменяет того, что, по-хорошему, надо бы так. Я не «ищу работу», я предлагаю свои услуги как программиста. Это вы должны мне рассказать, что вы сделаете для того, чтобы мне захотелось работать здесь и год, и два года спустя. Я же, со своей стороны, готов подтвердить свои профессиональные навыки любым разумным способом, ответить на вопросы о предыдущем опыте, которые CV не затрагивает. Сочинение на тему «как я провёл лето?» написать не предлагаете?
– Почему ты хочешь у нас работать?
– Как ты думаешь, какое твое личное качество будет наиболее полезно в командной работе?
– Что ты по-настоящему любишь делать?
Верный сигнал, что нужно послать задающего такие вопросы прямым текстом и валить из этого всеми богами проклятого места.
А ФВП позволяет указать, что принимаемая ей функция pure и nothrow (и соот-но проверит ли это компилятор)?
Да.
void hof( int function() nothrow pure f ) { }
А асинхронный код как синхронный (плоско) там можно писать?
Этот вопрос не понял, мне незнаком термин «плоское написание асинхронного кода».
Касательно неявных преобразований, как минимум, привычной идиомы if(ptr) мне бы не хватало. Есть некоторое количество преобразований, которые на практике достаточно безопасны и удобны в неявном виде. Я это к тому, что цель языка программирования — быть удобным и практичным, а не предоставить строгую красивую модель.
Как насчёт вставки в ваш мутабельный пример inline assembler'a? Если уж он действительно такой императивно-мутабельный, а не просто имитирует стиль, взгромождая ещё одну абстракцию?
Вы исходите из предпосылки, что императивный код «грязнее» и хуже только потому, что он императивный. Кстати, императивный стиль не обязательно подразумевает мутабельность, что вполне показано в D2. До тех пор, пока эта предпосылка существует, нам очень трудно будет найти общий язык.
Отвечая на ваше сообщение, наткнулся на любопытное поведение компилятора dmd, которое явно стоит внимания. Пардон, нужно некоторое время, чтобы ответить точно.
Возможно, я недостаточно точно выразился.
Ручное управление памятью и gc — не противоречащие друг-другу понятия. Даже при включенном gc всегда доступны malloc, free и аллокация на стеке + можно пометить любые блоки памяти как недоступные gc для обхода. Или приостановить gc на какой-то момент для выполнения real-time блока. Это ничем не грозит.
Речь же в предыдущем комментарии шла о ситуации, когда gc отсутствует в принципе, не включен druntime на этапе компиляции. Это важно, в основном, только если вы хотите уместить программу на D на какую-нибудь очень embedded платформу, куда garbage collector просто не влезает.
Тогда, увы, не могу помочь. Я слежу, в основном, за развитием библиотек и всего, что касается серверных/сетевых технологий, в силу своего рода занятий. Касательно коммерческого — Adam'а я уже упоминал; несколько человек упоминали, что долгое время используют D для научных вычислений.
Сам я несколько раз использовал D для написания плагинов, которые в нормальных условиях предполагалось писать на С/С++, во вполне коммерческих проектах. Кодом поделиться не могу, ибо NDA. Могу победить лень и на основе оного написать статью, это максимум.
Что касается GUI — так оно в большей степени определяется GUI-библиотекой, нежели языком. Тот же GTK он и в D GTK.
1) Строгая типизация не ограничивает возможностей, она лишь заставляет описывать преобразования типов явно. Размен небольшого синтаксического сахара на предсказуемость поведения.
2) Статическая типизация ограничивает, предлагая взамен большую производительность и, в сочетании со строгой, возможность задавать некие контракты.
Я вижу непосредственную выгоды от подобной дисциплины. Несмотря на это, язык, предоставляющий _только_ строгую статическую типизацию ( никаких variant, никак неявных преобразований целых чисел ) явил бы собой пример бессмысленного ограничения и лишней сущности.
Всё ещё не вижу связи между обязательной строгой функциональностью и списком фич. В D2 тоже по типу функции можно определить некоторые аспекты, такие как pure, nothrow или safe. Обошлись как-то без ограничений.
Хочу заметить, что я нигде не упоминал «лишние сущности», только «бессмысленные ограничения». Это не имеет отношения к теме.
Насчёт android — как раз недавно появился к этому интерес, вот статья по тому, как можно собрать программу для Andoid, используя NDK + gdc. Но без полного портирования druntime и phobos это совсем не так круто, как хотелось бы, увы.
Враньё. Free-as-beer open-source пишется, в первую очередь, для себя — ради интересы, обучения или просто чтобы создать удобную софтину под свои вкусы. Другие пользователи — побочный эффект того, что автор в лом напрягаться, и делать приличный интерфейс, нормальную конфигурацию, документацию и прочие необходимые атрибуты используемого продукта. 90% ( число с потолка ) open-source — наколенная поделка по определению и так и должно быть.
А вот если этот же продукт перерастает определённую стадию и появляется чёткая ориентация на конечного пользователя — вот тогда уже можно думать о том, что за это получать и как окупить затраты. И это совсем другая история.
А те, кто исходит из аксиоматики «каждый кто-то хочет за любой чих денег» — горите в аду, пожалуйста, из-за вас на этой планете жить тошно.
Ан нет. Странно.
Как могло придти в голову перевести «thread» как «поток» — не представляю.
Это сравнимый аналог вашего примера? Callback, конечно, неявно где-то все равно передается, но, подозреваю, в недрах имплементации Haskell тоже без них не обошлось.
Я исхожу из предпосылки, что чем меньше мы можем наложить контракта на функцию, тем больше вероятность ошибок.
… мало частных случаев и каких-то ситуаций, где только знание каких-то нюансов стандарта помогает понять, что происходит
Вот тут, боюсь, у нас сильное несовпадение взглядов. Я не вижу прямой связи между линейным увеличением числа контрактов и уменьшением вероятности ошибки. Контракт может быть полезным, может не быть. Каждый раз нужно отдавать себе отчёт в том, какое нежелательное поведение мы стараемся предотвратить каждым отдельным контрактом.
И хороший практичный язык, ИМХО, должен иметь множество частных случаев и нюансов стандарта. И сам стандарт на тысячи страниц. С тем лишь отличием от С++, что незнание этих нюансов не должно бить новичка по лицу, пока он с ними не знаком.
Ну ассемблер напрямую не вставить, ибо Haskell куда выше уровнем, да и компилироваться может через LLVM. Но звать сишные функции никто не запрещает
Я это к тому, что у Haskell и у D несколько разные дизайн-цели. И в D необходимым требованием является то, что встроенный ассемблер должен выглядеть так же естественно, как и функциональный стиль. Равноправное использование всех парадигм.
Я ведь не могу знать этого на момент собеседования. Могу спросить ( и спрошу, не сомневайтесь ), но едва ли поверю сказанному. Это то мнение, которое сформируется эдак через полгода, после пары дедлайнов и прочих прелестей. Вот тогда и можно будет задать вопрос, почему я хочу работать в вашей компании ( и хочу ли ). А сейчас — вы один из множества чёрных ящиков.
И нет, это я собеседую компанию, а не она меня. Если только вы не Google какой-нибудь, конечно. Об этом можно судить, как минимум, по количеству задаваемых вопросов с каждой стороны. Считаете это избытком гонора — без проблем, так и скажите, вежливо распрощаемся. Пока что рынок говорит о том, что я могу себе это позволить, и недостатка в предложениях не наблюдается, хотя, вроде бы, моложе некуда и по статусу не положено.
Дефицит с кадрами у нас в силу простой причины, что во всей стране нет ни одного места, где можно научиться специальности и все программисты хорошего уровня — в той или иной мере самоучки, а те, кто помоложе, предпочитает уезжать сразу, чтобы получить нормальное образование. Но это оффтопик :)
Жду комфортных условий работы — удобных офисных помещений, отсутствия лишней бюрократии, более либеральное отношение к рабочему графику, продуманную организацию рабочего процесса, эффективное распространение информации, близкий по отношению к работе коллектив. Всё вместе, конечно, едва ли бывает ( и в таких местах, не сомневаюсь, и впрямь обивают пороги в поисках вожделенного ), но это уже параметры, по которым можно реально что-то оценивать.
Возможно, в России тысячи безработных компетентных программистов и обивают пороги компаний ( круто вам! ), а у нас как-то с квалифицированной рабочей силой дефицит. Мой текущий работодатель выплачивает наградные за каждого рекомендованного человека, который был принят на работу, не важно, какого он уровня и сколько на этом месте продержится. И знаете, как-то вот некого рекомендовать даже, не вижу тех самых тысяч программистов.
Что не отменяет того, что, по-хорошему, надо бы так. Я не «ищу работу», я предлагаю свои услуги как программиста. Это вы должны мне рассказать, что вы сделаете для того, чтобы мне захотелось работать здесь и год, и два года спустя. Я же, со своей стороны, готов подтвердить свои профессиональные навыки любым разумным способом, ответить на вопросы о предыдущем опыте, которые CV не затрагивает. Сочинение на тему «как я провёл лето?» написать не предлагаете?
– Как ты думаешь, какое твое личное качество будет наиболее полезно в командной работе?
– Что ты по-настоящему любишь делать?
Верный сигнал, что нужно послать задающего такие вопросы прямым текстом и валить из этого всеми богами проклятого места.
Да.
А асинхронный код как синхронный (плоско) там можно писать?
Этот вопрос не понял, мне незнаком термин «плоское написание асинхронного кода».
Касательно неявных преобразований, как минимум, привычной идиомы if(ptr) мне бы не хватало. Есть некоторое количество преобразований, которые на практике достаточно безопасны и удобны в неявном виде. Я это к тому, что цель языка программирования — быть удобным и практичным, а не предоставить строгую красивую модель.
Как насчёт вставки в ваш мутабельный пример inline assembler'a? Если уж он действительно такой императивно-мутабельный, а не просто имитирует стиль, взгромождая ещё одну абстракцию?
Вы исходите из предпосылки, что императивный код «грязнее» и хуже только потому, что он императивный. Кстати, императивный стиль не обязательно подразумевает мутабельность, что вполне показано в D2. До тех пор, пока эта предпосылка существует, нам очень трудно будет найти общий язык.
Ручное управление памятью и gc — не противоречащие друг-другу понятия. Даже при включенном gc всегда доступны malloc, free и аллокация на стеке + можно пометить любые блоки памяти как недоступные gc для обхода. Или приостановить gc на какой-то момент для выполнения real-time блока. Это ничем не грозит.
Речь же в предыдущем комментарии шла о ситуации, когда gc отсутствует в принципе, не включен druntime на этапе компиляции. Это важно, в основном, только если вы хотите уместить программу на D на какую-нибудь очень embedded платформу, куда garbage collector просто не влезает.
Сам я несколько раз использовал D для написания плагинов, которые в нормальных условиях предполагалось писать на С/С++, во вполне коммерческих проектах. Кодом поделиться не могу, ибо NDA. Могу победить лень и на основе оного написать статью, это максимум.
Что касается GUI — так оно в большей степени определяется GUI-библиотекой, нежели языком. Тот же GTK он и в D GTK.
Сам ни разу ещё не пробовал писать на D что-либо с GUI, не могу сказать.
Вы недооцениваете значение совместимости ABI.
2) Статическая типизация ограничивает, предлагая взамен большую производительность и, в сочетании со строгой, возможность задавать некие контракты.
Я вижу непосредственную выгоды от подобной дисциплины. Несмотря на это, язык, предоставляющий _только_ строгую статическую типизацию ( никаких variant, никак неявных преобразований целых чисел ) явил бы собой пример бессмысленного ограничения и лишней сущности.
Всё ещё не вижу связи между обязательной строгой функциональностью и списком фич. В D2 тоже по типу функции можно определить некоторые аспекты, такие как pure, nothrow или safe. Обошлись как-то без ограничений.
Хочу заметить, что я нигде не упоминал «лишние сущности», только «бессмысленные ограничения». Это не имеет отношения к теме.