Как по мне, плохо не столько отсутствие move, сколько неявный copy по умолчанию.
Не всегда хватает указателя или ссылки, иногда надо сам объект переместить. Файловый дескриптор к примеру.
По языкам — наверное только Rust. В D есть RAII в какой-то форме, но насчёт мувов не уверен.
Мне кажется, основная причина в отсутствии destructive move, а не тривиальности перемещения. Но добиться "забывания" старых местоположений по сути невозможно, т.к. это сломает кучу существующего кода. Семантика конструкторов, деструкторов, перемещений, копий и т.п. накручена поверх value семантики из С.
Дополнительная проблема — все эти нововведения призваны ограничивать, а не освобождать. Т.е. чем правильней вы хотите описать поведение типа, тем больше писанины, правил 0-1-3-5-42, атрибутов и т.п. вам надо помнить. А по умолчанию получается POD.
Конечно, "вирусность" нетривиальных копирования и перемещения помогает. Но не сильно. Потому что действие по умолчанию — копирование, перемещение требует отдельного вызова обёртки. Базовых вещей вроде resource wrapper, finalizer в стандартной библиотеке нет до сих пор. Или пишите свой велосипед с риском ошибиться, или ищите в другом месте.
Касательно же Rust, один паттерн оттуда уж точно стоит взять на вооружение. Это copy method, когда создание копии происходит только через явный вызов отдельного метода.
Я видел обратные примеры, когда применение ООП вместо FSA превращало код в адскую лапшу из мутабельных состояний и флагов, когда непонятно, что куда относится и с чем взаимодействует.
Автор написал про YAML. И он кстати значительно сложнее.
Сравните JSON grammar и YAML grammar. Формат описания разный, но общее представление о разнице в сложности, думаю, даёт.
Исходя из п.4, вам оочень стоит рассмотреть SQLite как формат, убирающий большинство проблем с потерями. Поскольку при чтении-записи старые версии программы смогут работать со знакомыми им данными, не убивая старые при перезаписи части информации.
Не знаю как с JS, а питон встраивается довольно нетривиально. Причём основная лично для меня проблема — стандартный механизм импортов крайне тяжело взять под контроль. Последнее, что я находил — требуется руками редактировать исходники питона, иначе нет возможности к примеру ограничить доступ к стандартной библиотеке. Даже если вы её выпилите из вашего дистрибутива, клиентский код вполне сможет подгрузить свой модуль, к примеру неизменённую стандартную библиотеку. В отличие от него, Lua и встраивается, и изолируется не в пример проще.
Просто наука зиждется на фактах и проверяемости. Чтобы вас восприняли всерьёз, недостаточно неистово строчить в твиттер или ЖЖ — надо приложить выкладки, не противоречащие имеющимся фактам и дающие какие-то проверяемые предсказания. У "ниспровергателей" как правило проблемы или с выкладками в принципе, или они хорошо объясняют один факт, при этом противореча большинству оставшихся.
Просто у других моделей проблем ещё больше. По поводу вашего предположения — есть выкладки и опора на набоюдения? То, что имеем сейчас — результат выкидывания на помойку целой кучи гипотез — потому что они противоречили тем самым наблюдениям.
Тип — это просто какой-то идентификатор. Всё.
Далее на него каким-либо образом, прямо или косвенно — навешиваются всякие свойства.
С тем, что такое тип, определились.
Но тогда меня немного смущает ваша фраза из контекста выше:
При этом никакие сумтипы и прочее типами не являются и являться не могут.
Есть такая занятная штука как std::variant, которая позволяет хранить в одном и том же оъекте (?) какие-то значения одного из двух или более других типов. Т.е. это реализация тех самых типов-сумм для С++. Вы говорите выше, что это не тип. А потом даёте такое определение типа, под которое std::variant попадает на 100%. Так всё-таки, это тип или нет? Мне правда интересно.
А тут мы с вами должны дать определение объекту и процессу наследования. Может, пока остановимся на типах?
…
Почему? К тому же, опять же неверно. Объект никакого отношения к наследованию не имеет.
Ну давайте так. Определение давать надо, чтобы не путаться, кто что сказал. У меня в голове есть какие-то определения, но давать я их не буду — чтобы не запутывать дискуссию. Дайте пожалуйста ваше определение, чтобы мы с вами друг друга правильно понимали. И таки немного странно, что объект получает свойства от типа путём наследования, но никакого отношения к нему не имеет.
Если я понял вас правильно, то int вы типом считаете — исходя из вот этой вашей фразы:
…
Какая-то не внятная попытка. Я не совсем понял её смысл.
Попытка, простите, чего? Не понял.
Так всё-таки, чтобы наделять объект свойствами (?) типы не нужны?
…
Не нужны.
Тогда получается, что в языке (С/С++?) можно создать объект какого-либо типа (или вообще без типа) и наделить его какими-то свойствами по ходу дела? Получается та самая "скриптуха"? Или приведите пожалуйста пример, если я вас неправильно понял.
Опять какие-то невнятные попытки.
Ещё более невнятные попытки. Там всё понятно.
… и не пытаться меня поймать, что заранее обречено.
Так и не понял, попытки чего. Пока я только честно пытаюсь вас понять.
Надо просто мыслить не так узко
А вы объясните доступным языком. Может я как раз хочу расширить мышление, да знаний не хватает.
Давайте совсем для дошкольников. Есть свойство — sizeof. Это свойство типа, свойство привязанное к идентификатору. Допустим, в каком-то случае к int привязывается свойство sizeof == 4. Далее объект аннотируется типом и наследует(это не то наследование, о котором вы подумали) этот sizeof.
Ок. Пусть будет sizeof. Что это свойство для вас определяет? Почему оно равно именно 4? Если это не то наследование (уже спросил выше), то какое?
Всё остальное работает по тому же принципу. В тип так же может быть забинжены какие-нибудь операции над объектом данного типа. И не только.
Ведь не всякие же свойства. Или вообще любые? Или есть какие-то правила, какие свойства и операции могут быть ассоциированы с типом?
К тому же, выше вы говорили, что свойства и операции могут быть ассоциированы непосредственно с объектом. Можете показать? Я правда о таком не слышал.
Я бы не сказал, что тип вообще требует какого-либо определения в том плане, в котором его обычно определяют.
К сожалению, требует. Иначе будет непонятно, о чём мы с вами говорим. И непонятно, какие сущности языка считать типами, а какие — нет.
Тип — это просто какой-то идентификатор. Всё.
Согласно вашему определению, в выражении int foo = 0; типами можно назвать и int, и foo. Но это ведь не так, правда?
Далее на него каким-либо образом, прямо или косвенно — навешиваются всякие свойства.
Вот тут уже интересней. Что это за свойства, откуда они берутся?
Если я понял вас правильно, то int вы типом считаете — исходя из вот этой вашей фразы:
Ну примерно так. Хотя в том же си почти не было типов изначально. Просто везде по умолчанию инт, а потом уже к этому прикрутили аннотации типовые.
Какие у этого типа будут свойства? Или, если это не тип, что это тогда?
Далее каждый объект аннотируется этим идентификатором, тем самым объект наследует свойства типа.
А тут мы с вами должны дать определение объекту и процессу наследования. Может, пока остановимся на типах?
На самом деле каждый объект можно наделять свойствами отдельно, а сама типизация просто некое развитие.
Так всё-таки, чтобы наделять объект свойствами (?) типы не нужны?
Чуть выше вы сами пишете:
Поэтому типы именно как типы появились в статических языках в связи с необходимостью.
Пока не совсем понятно, какая необходимость заставила статические языки (С?) вводить типы. Если для наделения объекта свойствами типы не нужны.
Общие свойства множества объектов выносятся отдельно и им даётся имя/идентифактор. Это просто упрощает определение нового объекта с аналогичным набором свойств.
Т.е. если я правильно понял, для вас тип — какое-то соглашение?
А далее уже появляется какая-то логика работы с этими свойствами. Классификация и прочее.
Чтобы что-то классифицировать, и чтобы появлялась логика работы, надо определиться — с чем мы имеем дело. Давайте начнём с этого?
Статическая же типизация в статическом же ЯП предполагает обратное. Вся логика определяется типами, т.е. не существует такой ситуации, когда для какого-либо объекта не определён однозначно его тип. При этом никакие сумтипы и прочее типами не являются и являться не могут. Так же, здесь так же могут быть опциональные включения описательной типизации.
Уж простите что влезаю в ваш разговор. Но что тогда для вас тип? Можете дать определение со своей стороны?
Я может чего пропустил, но в статье как-то сложновато найти цифры выбросов углекислого газа на тонну груза или одного пассажира. И преимущество полного цикла биотоплива над классическим керосином. А то, извините, получается яхта Тунберг, слопавшая 10 билетов на самолёт вместо 4.
Как по мне, у меня вполне хватает информации для такого вывода — исходя из истории создания JS Бренданом Айхом, набора изначально вложенных в него концепций, набора "артефактов" вроде странностей слабой типизации. У меня есть с чем сравнить из динамики — я гораздо плотнее работал с Lua и Python.
Ну я же не уточнил, сколько таких кусков я могу вообще держать в голове :) Больше одного за раз не влазит, потом приходится голову проветривать. Плюс показатель сильно падает если он нарезан на несколько файлов… Короче сильно много "если". Рассматривайте эти 500 как идеальный случай несложного кода, мной же и написанного.
Я лично — ни одной. Я С++ник. Мне на ЖСе вообще некомфортно писать. Но видел пару раз вблизи довольно сложные проекты, которые ради поиска тривиальных проблем, проверяемых тайпчекером, обмазывали тестами по самое немогу.
Хороший тайпчекер требует вывода типов для хорошей эргономики.
Касательно простоты — для меня простой код, который я могу держать в голове, заканчивается строках на пятиста примерно. Дальше уже явно дискомфортно. Но я не показатель т.к. в динамику сунулся уже после статики.
Надо ещё рабочее тело откуда-то брать.
Как по мне, плохо не столько отсутствие move, сколько неявный copy по умолчанию.
Не всегда хватает указателя или ссылки, иногда надо сам объект переместить. Файловый дескриптор к примеру.
По языкам — наверное только Rust. В D есть RAII в какой-то форме, но насчёт мувов не уверен.
Мне кажется, основная причина в отсутствии destructive move, а не тривиальности перемещения. Но добиться "забывания" старых местоположений по сути невозможно, т.к. это сломает кучу существующего кода. Семантика конструкторов, деструкторов, перемещений, копий и т.п. накручена поверх value семантики из С.
Дополнительная проблема — все эти нововведения призваны ограничивать, а не освобождать. Т.е. чем правильней вы хотите описать поведение типа, тем больше писанины, правил 0-1-3-5-42, атрибутов и т.п. вам надо помнить. А по умолчанию получается POD.
Конечно, "вирусность" нетривиальных копирования и перемещения помогает. Но не сильно. Потому что действие по умолчанию — копирование, перемещение требует отдельного вызова обёртки. Базовых вещей вроде resource wrapper, finalizer в стандартной библиотеке нет до сих пор. Или пишите свой велосипед с риском ошибиться, или ищите в другом месте.
Касательно же Rust, один паттерн оттуда уж точно стоит взять на вооружение. Это copy method, когда создание копии происходит только через явный вызов отдельного метода.
Это сарказм? С ConEmu сравнивали?
Неясно чем это отличается от кастомизации палитры в обычном терминале.
Я видел обратные примеры, когда применение ООП вместо FSA превращало код в адскую лапшу из мутабельных состояний и флагов, когда непонятно, что куда относится и с чем взаимодействует.
Автор написал про YAML. И он кстати значительно сложнее.
Сравните JSON grammar и YAML grammar. Формат описания разный, но общее представление о разнице в сложности, думаю, даёт.
Исходя из п.4, вам оочень стоит рассмотреть SQLite как формат, убирающий большинство проблем с потерями. Поскольку при чтении-записи старые версии программы смогут работать со знакомыми им данными, не убивая старые при перезаписи части информации.
Не знаю как с JS, а питон встраивается довольно нетривиально. Причём основная лично для меня проблема — стандартный механизм импортов крайне тяжело взять под контроль. Последнее, что я находил — требуется руками редактировать исходники питона, иначе нет возможности к примеру ограничить доступ к стандартной библиотеке. Даже если вы её выпилите из вашего дистрибутива, клиентский код вполне сможет подгрузить свой модуль, к примеру неизменённую стандартную библиотеку. В отличие от него, Lua и встраивается, и изолируется не в пример проще.
Просто наука зиждется на фактах и проверяемости. Чтобы вас восприняли всерьёз, недостаточно неистово строчить в твиттер или ЖЖ — надо приложить выкладки, не противоречащие имеющимся фактам и дающие какие-то проверяемые предсказания. У "ниспровергателей" как правило проблемы или с выкладками в принципе, или они хорошо объясняют один факт, при этом противореча большинству оставшихся.
Просто у других моделей проблем ещё больше. По поводу вашего предположения — есть выкладки и опора на набоюдения? То, что имеем сейчас — результат выкидывания на помойку целой кучи гипотез — потому что они противоречили тем самым наблюдениям.
Предложите другую модель. ТЭ пока вроде как лучше всего описывает то, что видят астрофизики. И то с проблемами, о чём они в курсе.
К слову, ТЭ это всего лишь устоявшийся термин для неизвестного фактора, а не чОрные молнии как у фантастов. Выше уже несколько раз написали.
Ну хорошо, возьмём ваше определение.
С тем, что такое тип, определились.
Но тогда меня немного смущает ваша фраза из контекста выше:
Есть такая занятная штука как std::variant, которая позволяет хранить в одном и том же оъекте (?) какие-то значения одного из двух или более других типов. Т.е. это реализация тех самых типов-сумм для С++. Вы говорите выше, что это не тип. А потом даёте такое определение типа, под которое
std::variantпопадает на 100%. Так всё-таки, это тип или нет? Мне правда интересно.Ну давайте так. Определение давать надо, чтобы не путаться, кто что сказал. У меня в голове есть какие-то определения, но давать я их не буду — чтобы не запутывать дискуссию. Дайте пожалуйста ваше определение, чтобы мы с вами друг друга правильно понимали. И таки немного странно, что объект получает свойства от типа путём наследования, но никакого отношения к нему не имеет.
Попытка, простите, чего? Не понял.
Тогда получается, что в языке (С/С++?) можно создать объект какого-либо типа (или вообще без типа) и наделить его какими-то свойствами по ходу дела? Получается та самая "скриптуха"? Или приведите пожалуйста пример, если я вас неправильно понял.
Так и не понял, попытки чего. Пока я только честно пытаюсь вас понять.
А вы объясните доступным языком. Может я как раз хочу расширить мышление, да знаний не хватает.
Ок. Пусть будет sizeof. Что это свойство для вас определяет? Почему оно равно именно 4? Если это не то наследование (уже спросил выше), то какое?
Ведь не всякие же свойства. Или вообще любые? Или есть какие-то правила, какие свойства и операции могут быть ассоциированы с типом?
К тому же, выше вы говорили, что свойства и операции могут быть ассоциированы непосредственно с объектом. Можете показать? Я правда о таком не слышал.
К сожалению, требует. Иначе будет непонятно, о чём мы с вами говорим. И непонятно, какие сущности языка считать типами, а какие — нет.
Согласно вашему определению, в выражении
int foo = 0;типами можно назвать иint, иfoo. Но это ведь не так, правда?Вот тут уже интересней. Что это за свойства, откуда они берутся?
Если я понял вас правильно, то
intвы типом считаете — исходя из вот этой вашей фразы:Какие у этого типа будут свойства? Или, если это не тип, что это тогда?
А тут мы с вами должны дать определение объекту и процессу наследования. Может, пока остановимся на типах?
Так всё-таки, чтобы наделять объект свойствами (?) типы не нужны?
Чуть выше вы сами пишете:
Пока не совсем понятно, какая необходимость заставила статические языки (С?) вводить типы. Если для наделения объекта свойствами типы не нужны.
Т.е. если я правильно понял, для вас тип — какое-то соглашение?
Чтобы что-то классифицировать, и чтобы появлялась логика работы, надо определиться — с чем мы имеем дело. Давайте начнём с этого?
Уж простите что влезаю в ваш разговор. Но что тогда для вас тип? Можете дать определение со своей стороны?
Я может чего пропустил, но в статье как-то сложновато найти цифры выбросов углекислого газа на тонну груза или одного пассажира. И преимущество полного цикла биотоплива над классическим керосином. А то, извините, получается яхта Тунберг, слопавшая 10 билетов на самолёт вместо 4.
Как по мне, у меня вполне хватает информации для такого вывода — исходя из истории создания JS Бренданом Айхом, набора изначально вложенных в него концепций, набора "артефактов" вроде странностей слабой типизации. У меня есть с чем сравнить из динамики — я гораздо плотнее работал с Lua и Python.
Ну я же не уточнил, сколько таких кусков я могу вообще держать в голове :) Больше одного за раз не влазит, потом приходится голову проветривать. Плюс показатель сильно падает если он нарезан на несколько файлов… Короче сильно много "если". Рассматривайте эти 500 как идеальный случай несложного кода, мной же и написанного.
Да я в курсе. Но лучше такие волокуши чем совсем по грунту тащить.
Я лично — ни одной. Я С++ник. Мне на ЖСе вообще некомфортно писать. Но видел пару раз вблизи довольно сложные проекты, которые ради поиска тривиальных проблем, проверяемых тайпчекером, обмазывали тестами по самое немогу.
Хороший тайпчекер требует вывода типов для хорошей эргономики.
Касательно простоты — для меня простой код, который я могу держать в голове, заканчивается строках на пятиста примерно. Дальше уже явно дискомфортно. Но я не показатель т.к. в динамику сунулся уже после статики.