Комментарии 764
Если серьёзно — задача всего компьютерного — абстрагирование и уменьшение сложности. Каждый раз, когда сложность уменьшается, мы можем сделать больше (чем раньше) всего лишь восстановив уровень сложности. А потом ещё раз его уменьшить.
… Проблема начинается в тот момент, когда нижележащий уровень перестаёт прятать сложность и оно взрывается как пружина. Обычно люди просто стараются увернуться (включить/выключить, попробовать ещё раз), а не выяснять что именно там случилось.
Когда смотришь на готовый проект (что пример, что просто хороший чужой код) и всё очевидно. Начинаешь делать что-то сам — и упираешься в дикие ограничения, при решении которых натыкаешься либо на готовые сниппеты (магия!), либо городишь дикий код.
Потом начинаешь оборачивать дикий код в магию.
Тогда я это объяснил себе это спецификой декларативных языков, но в целом это свойственно для любой сложной системы — а код сейчас действительно сложный.
Замените рельсу на SQL — ничего не изменилось.
Потому что он заявляет «вам нужно просто описать информацию о предметной области в терминах предметной области, а Пролог-система даст ответ».
Но при этом достаточно в первой же нетривиальной программе из любого учебника по Прологу поменять две строки местами (а это, как понятно, «информацию о предметной области» не меняет) — и привет: программа зациклится и упадёт, сожрав предварительно всю память.
Блеск!
Как правило первая не тривиальная задача в учебниках — это набор фактов из Библии (пролог ещё до эпохи толерантности появился, там на Библию ещё можно ссылаться). Набор фактов вида «Исаак родил Иакова» и правила вывода (два):
1. Если A родитель B, то A — предок B.
2. Если A родитель B, а B — предок C, то A — предок C.
Так вот если эти правила поменять местами, то программа «рассыплется».
Восхитительная «декларативность».
Но с точки зрения человека последовательность этих правил — неважна. Такое определение: «предок твоего папы — это твой предок… ну и твой папа — тоже твой предок» — человек поймёт.
А с точки зрения Пролога — важна. «Предок твоего папы — это твой предок… ну и твой папа — тоже твой предок» — Пролог не поймёт. Зациклится. Где декларативность?
Как человек понимает эту фразу? Он считывает, входит в цикл, пытается найти определение предка, находит его, возвращается в цикл и разрешает его.
Так ведь это то же самое. Просто в прологе тебя просят «Чтобы снизить вычислительную сложность мы на уровне языка не будем реализовывать разрешение циклов и обратный поиск определений. Поэтому, будь так добр, записывай в порядке в котором машине будет легче понимать.»
Думаю можно сделать язык который все не явные противоречия разрешает, но возможно просто не достаточно вычислительных мощностей.
И да, то, что Пролог — не декларативен неделает его бесполезным. Но я не понимаю почему его все пытаются «продавать» как декларативный язык — притом что он таким ни разу не является.
Это пример практической некоммутативности связки ИЛИ.Извините, но это бред. Эти два правила для любой пары объектов дают ровно один ответ на вопрос «является ли Исаак предком Иакова» — независимо от порядка.
Например, выбор на дороге: 1) налево — потеряешь голову, 2) направо — получишь приз. От того какой путь выбрать первым зависит как пойдут дела. :)Это называется — императи́вное программи́рование
Проблема не в нем, а в природе логики.Нет — проблема в том, что некоторые люди не умеют отличать декларативное программирование от императивного.
Пролог просто является классической подменой понятий: вначале нам объясняется, что Prolog является декларативным языком программирования, а потом — объясняется как работает Prolog-машина и оказывается, что мы должны не писать декларативное описание этой задачи, а программировать вот эту вот, вполне императивную, машину…
В этой нашей теории типов A V B кодируется как ∀C: *. (A → C) → (B → C) → C. То есть, для любого действия, выполняемого и при походе налево, и при походе направо, разницы таки нет совсем.
Декларати́вное программи́рование — это парадигма программирования, в которой задаётся спецификация решения задачи, то есть описывается, что представляет собой проблема и ожидаемый результат.
Противоположностью декларативного является императивное программирование, описывающее на том или ином уровне детализации, как решить задачу и представить результат.
Так вот спецификация — не должна превращаться в тыкву при перестановке двух строк местами. Это уже не «описание проблемы», а бог-знает что.
Можно сколько угодно рассказывать про сложности работы со спецификациями, но практически — вы либо умеете с ними работать, либо нет. Пролог — не умеет. Он умеет работать только со специцикациями заточенными под Пролог-машину и учитывающими то, что у неё «под капотом». Какая тут, нафиг, декларативность?
Какая тут, нафиг, декларативность?Ответ — ограниченная. У пролога декларативность ограничена тем что у него под капотом. Но это не делает его не декларативным, это делает его «всего лишь» бесполезным на практике.
Вы похоже склоняетесь к точке зрения оппонента, что декларативность гарантирует поиск результата. Но это так только в случае действительно 100% точного описания задачи. Порядок дизъюнктов — это один из элементов такой точности.
Пролог или какое-то его удачное расширение — это будущее программированияОн может быть и будущее, но на данный момент он все равно бесполезен на практике. Одно никак не противоречит другому.
Вы похоже склоняетесь к точке зрения оппонента, что декларативность гарантирует поиск результата.Мой комментарий был вообще не об этом. Мой комментарий был о двух вещах — о том, что пролог крайне ограничен в множестве задач на которых его можно применять и, следовательно, не помогает в решении практических задач. Но при этом он остается декларативным, ограниченность принципу декларативности не мешает насколько я понимаю. Даже математически не мешает.
Он может быть и будущее, но на данный момент он все равно бесполезен на практике.
Не могу с таким согласиться. Существует достаточно много перспективных проектов вокруг пролога. Пролог — универсальный язык и на нём можно делать всё, что, например, на питоне. Может просто нужен кто-нибудь типа Гвидо, который сделает популярный вариант пролога. Скорость работы хороших прологов на уровне языков сценариев. Мне кажется полезность-перспективность и текущая массовая популярность — это разные вещи. Мое мнение — пролог это один из самых простых и близких к естественному языков программирования. К сожалению, приходится до сих пор больше работать сo скорее с потомками фортрана. :(
Существует достаточно много перспективных проектов вокруг пролога.Только перспективных или уже реально широко используемых? Если первое, то с его возрастом это диагноз на мой взгляд. Если второе, то интересно было бы посмотреть на пример.
Понимаете, это же достаточно объективно — если инструмент полезен и достаточно стар чтобы его успели попробовать, то на нем будут что-то делать. Если инструменту много лет, о нем много кто знает, но при этом ничего практического на нем нет — значит он бесполезен.
А чего Прологу не хватает, интересно? У меня есть ощущение, что как раз декларативности: современные системы многопоточны (а GPU — так сильно многопоточны), но как раз декларативно описанные задачи параллелятся «в лёгкую», а вся семантика Пролога завязана на его однопоточную машину…
Отличный язык для быстрого прототипирования) Просто фигачишь функции и они просто работают)
всё предельно быстро будет
Аллокатор, я надеюсь, у вас тоже не требует синхронизации между потоками? И программа работает на x84/x64/arm/aarch64 без компиляции? И векторизация инструкций тоже будет использоваться, да? И порядок инструкций поменяется на лету, ради скорости, да?
без задержек на GC
Аллокатор не фрагментарнтирует память, да? И free у Вас работает в отдельном потоке, как на Java, да?
не упадёт с OOM
Модель памяти у Вас простая, сама память не течёт, грязную память вы не используете, да?
Отличный язык для быстрого прототипирования)
А для боевого применения?
на клиентском устройстве
А отладку сможете делать на нем, если у Вас на рабочей машине другая ОС/архитектура процессора?
Если подытожить: Ваши аргументы крайне спорные. И далеко не так очевидно, что С быстрее, удобнее и т.д.
Аллокатор, я надеюсь, у вас тоже не требует синхронизации между потоками?Не требует.
И программа работает на x84/x64/arm/aarch64 без компиляции?Какая разница, +1 архитектура — всего лишь строчку в мейфайл добавить и поставить компилятор, что куда проще и симпатичнее, чем например, jvm под iOS запихнуть в дистрибутив приложения.
И векторизация инструкций тоже будет использоваться, да?Да, автовекторизация и прочие оптимизации весьма недурно производительность поднимают.
И порядок инструкций поменяется на лету, ради скорости, да?Если порядок меняет результат вычисления, и при этом нет грубых нарушений правил языка, ничего не поменяется.
Аллокатор не фрагментарнтирует память, да? И free у Вас работает в отдельном потоке, как на Java, да?На практике вклад malloc/free во время исполнения с лупой искать надо.
Модель памяти у Вас простая, сама память не течёт, грязную память вы не используете, да?Да вроде не течёт, тем более сама)
А для боевого применения?Проще 1 раз на 1 языке написать, чем писать на # под венду, java на андроид, swift на ios и js для веба. Для этого не так много языков годится.
А отладку сможете делать на нем, если у Вас на рабочей машине другая ОС/архитектура процессора?Для отладки компилятор зашивает в бинарник всё необходимое, при чём здесь ОС и процессор. В С я могу включить в отладочных целях проверки обращения к памяти например, как в той же Java, в релизе могу выключить и получить прирост производительности, а в Java — нет, не доверяет она разработчику.
всего лишь строчку в мейфайл добавить и поставить компиляторЭто так просто не работает.
gist.github.com/ph0b/69586260bc20c58136ef
Проще 1 раз на 1 языке написать, чем писать на # под венду, java на андроид, swift на ios и js для веба. Для этого не так много языков годится.
Покажите ваш проект на си, чтобы один раз, да сразу для iOS и для веба и для винды.
Схема «пишу под десктоп — иногда поглядываю, что там на андроид» уже работает, хотя конечно под андроид отдельная обёртка и шейдеры отличаются и OpenGL ES вместо обычного OpenGL, и отдельный проект в Android Studio, но сишное ядро приложения одно.
Получается не один раз, а под каждую платформу придётся писать что-то, а переиспользуется только какая-то небольшая часть? Я вам подскажу, таким занимается куча людей из устоявшихся технологий, и пока даже просто между iOS и Android настолько большая разница, что всё чаще возникают вопросы имеют ли смысл все эти Xamarin и React Native, если приложение больше пары простых скринов.
Получается не один раз, а под каждую платформу придётся писать что-то, а переиспользуется только какая-то небольшая часть?Переиспользуется как раз почти всё, написание чего требовало каких-то усилий. Обёртка под андриод — уровня хэлловорлда, причём даже не написанная, а тупо позаимствованная из NDKшных примеров.
Я вам подскажу, таким занимается куча людей из устоявшихся технологий, и пока даже просто между iOS и Android настолько большая разница, что всё чаще возникают вопросы имеют ли смысл все эти Xamarin и React Native, если приложение больше пары простых скринов.Ну если есть деньги на N команд разработки, то почему бы и не писать под каждую платформу отдельно. У меня нет)
Си как-то странно причислять к неустоявшимся технологиям, языку ~50 лет, инструментов и кейсов применения для него наработано огромное количество, множество платформ имеют официальную поддержку, есть стандарты, при соблюдении которых эта поддержка гарантирована.
Вот только использование Си для написания приложений сразу под веб и все остальные платформы — не устоявшийся кейс. Можете показать какие-то инструменты для этого, сравнимые с React Native?
Переиспользуется как раз почти всё, написание чего требовало каких-то усилий. Обёртка под андриод — уровня хэлловорлда, причём даже не написанная, а тупо позаимствованная из NDKшных примеров.
Пока вы не можете показать код — это просто слова. Я допускаю возможность каких-то частных случаев, когда это реально возможно с минимальным добавлением платформоспецифичного кода. Но вы писали о приложениях на Си под все платформы сразу.
Ну если есть деньги на N команд разработки, то почему бы и не писать под каждую платформу отдельно. У меня нет)
Я вам ещё раз повторю написанное: компании, использующие инструменты с огромным комьюнити, покрывающие гораздо более простые кейсы (iOS+Android), сомневаются в целесообразности этого. Именно с денежной точки зрения.
И есть простые примеры типа такого github.com/redblobgames/helloworld-sdl2-opengl-emscripten
Себе я запилил удобный фреймворк, на котором приятно работать, вот например разметка + внешний вид + добавление кнопки:
static LayoutsParams lbPersNew = {.width = 320, .height = 96, .gravity = CENTER_HORIZONTAL | TOP, .marginTop = 8, .marginTopPercent = .333};
static TextureParams tbPersNew = {.texLeft = 225, .texTop = 249, .texRight = 263, .texBottom = 287};
static NinePathParams nbPersNew = {.vertTop = 16, .vertBottom = 16, .horLeft = 16, .horRight = 16};
//...
void initGui() {
bPersNew = BUTTON(0, &onPersNewPressed, &lbPersNew, &tbPersNew, &nbPersNew, VISIBLE);
//…
Вы видите здесь что-то платформоспецифичное? Разметку и другие параметры я могу объявить в другом файле, если захочется разный вид приложения на разных платофрмах сделать, могу как есть оставить.
Зачем вам именно мой код, есть известные игровые движки Unreal Engine / Unity с большим сообществом, и некоторые другие, позволяющие собирать игры на Windows/Mac/Linux/Web/Android/iOS.
Во-первых, что под UE нужно писать на плюсах, под юнити на C# или UnityScript. Во-вторых, вы же в курсе что люди не только игры пишут, да?
В реальном мире даже просто нарисовать дизайн, который бы просто был удобен на всех платформах, это уже большая проблема. Не говоря уже о том, что он должен подходить под гайдлайны платоформ и быть привычным пользователям платформы.
.width = 320
320 чего?
320 чего?
Масштабируемых единиц, конечно же)
вы же в курсе что люди не только игры пишут, да?У меня приложение, и есть все нужные для него виджеты, аналоги андроидных ImageView, TextView, ListView с линейным списком и сеткой, скроббары, прогрессбар, кнопки. Всё, к чему привык на андроид, в облегченном варианте и кроссплатформенно.
Во-первых, что под UE нужно писать на плюсах, под юнити на C# или UnityScript.Я уже писал, что по моим ощущениям, С уменьшает сложность по сравнению с C++ или C#. На С++ код иногда без боли не взглянуть.
Масштабируемых единиц, конечно же)
Вы же в курсе, что в браузере их не существует?
У меня приложение, и есть все нужные для него виджеты, аналоги андроидных ImageView, TextView, ListView с линейным списком и сеткой, скроббары, прогрессбар, кнопки. Всё, к чему привык на андроид, в облегченном варианте и кроссплатформенно.
Как думаете, ваше приложение пройдёт ревью в App Store?
Вы же в курсе, что в браузере их не существует?выбор коэффициента масштабирования — задача платоформозависимой обёртки, можно положить =1, если лучшего решения не найдётся.
Что на Си можно написать на движке игру и она будет работать на всех платформах? Нет, нельзя. Зато можно сделать на C# или C++.
Что можно написать на Си кроссплатформенное приложение? Нет, нельзя. Как минимум, вам придётся создавать UI на OpenGL с нуля. Чем вы и занимаетесь.
Что вы можете написать велосипед и добавлять в него платформы со временем? Ну удачи. Наберёте когда сделаете 3-4. Как раз с точки зрения финансов это просто выброшенные на ветер деньги. Только какие тут преимущества у Си?
Только какие тут преимущества у Си?Вы видели эти божественные скобочки, которые я выше привёл? Я могу частично инициализировать структуру! Да это же как JSON! Я могу на си описывать UI с такой же лёгкостью, как JSON написать! В С++ такого нет, в джаве нет, в андроид блеклая эмуляция декларативного описания через XML, в iOS муки и матюки на StoryBoard или как там их инструмент разметки называется, несовместимый с git, в котлин чуть удобнее сделали, но всё равно не то.
Кроме того, Си на мой взгляд меньше всего ограничивает свободу, и при этом при помощи нехитрых макросов ему можно придать выразительность, не уступающую модным фишкам из С++, в т.ч. тем что только готовятся для включения в стандарт. for с ренжами например. Мне нравится его гибкость.
На Си можно писать в функциональном стиле, с функциями можно обращаться как с переменными, надеюсь вы не станете отказывать функциональному программированию в праве на существование? Си — это как Хаскель на минималках, достаточно функциональный для практического применения, но всё ещё с ручным контролем памяти.
Си замечательно дружит со многими другими языками. Я могу просто закинуть сишные файлы в проект на С++/objective-C/D, вроде Swift тоже, могу подключить к проекту на Java через jni, могу сишную либу слинковать с любым другим компилируемым языком. У С++ тут уже начинаются проблемы.
Далее, Си — простой для чтения и написания язык. Я могу показать код программисту на Java/C++/JS/C# и пр., и он гарантированно поймёт, что тут проиходит. Можно смотреть его в плейнтекст и не ломать голову, что это за auto.
Си программы быстро компилируются и быстро запускаются, за 1 секунду я могу собрать (инкрементально) проект и запустить приложение, полная пересборка всего ~4c, а в Java я успею попить кофе, пока всё соберётся, в С++ и подавно.
В С++ такого нетЧего нет? Designated initializers? Поддерживаются уже лет 10 clang'ом и GCC, включены в C++20. В MSVC, да, беда — ну так там их с в C нет, ибо C99 MSVC не поддерживает.
На Си можно писать в функциональном стиле, с функциями можно обращаться как с переменными, надеюсь вы не станете отказывать функциональному программированию в праве на существование?
Можете map
и foldr
на С написать?
Желательно, чтобы foldr
по ленивой структуре данных вычислялся лениво.
Си — это как Хаскель на минималках, достаточно функциональный для практического применения, но всё ещё с ручным контролем памяти.
Прелесть хаскеля не в том, что там с функциями можно обращаться как с переменными (кстати, нельзя), а в мощной системе типов.
Я вообще не понимаю этого восторга от функционального программирования как от банального STLC. В типах всё счастье-то, а не в том, что фукнции можно передавать в функции.

Использование:

Да, препроцессор является частью С, но мы обсуждаем таки сишную часть. Ну или мне так казалось.
Ну если охота о препроцессоре думать — давайте всё равно рассуждать гомоиконно и делать map на препроцессоре, который принимает макру и список на препроцессоре и применяет макру к каждому элементу списка.
Если что, в Boost.PP такое есть. Получается, препроцессор годнее сишечки!
C:

time ./cppapplication_4
el = 1
el = 11
el = 21
el = 31
el = 41
el = 51
el = 61
el = 71
el = 81
el = 91
real 0m0,583s
user 0m0,486s
sys 0m0,097s
с++:

time ./cppapplication_3
foo contains: 11 21 31 41 51 61 71 81 91 101
real 0m3,828s
user 0m3,734s
sys 0m0,092s
Разница по времени не в пользу С++, да и читаемость так себе.
А давайте сравним с Rust:
vec.rs:
fn main() {
let vec = vec![0; 100000000];
vec.into_iter().enumerate()
.map(|(idx, _el)| idx * 10)
.map(|x| x + 1)
.take(10)
.for_each(|x| {
println!("el = {}", x);
});
}
Компиляция:
$ rustc vec.rs -O
$ time ./vec
el = 1
el = 11
el = 21
el = 31
el = 41
el = 51
el = 61
el = 71
el = 81
el = 91
real 0m0.003s
user 0m0.003s
sys 0m0.000s
Поиграться с кодом на playground
OMG пыщ-пыщ РАСТ БЫСТРЕЕ С в 200 раз и быстрее С++ в 1200 раз!!!111
Сомнительный бенчмарк, сэр. Тем не менее, этот сомнительный бенчмарк показывает, на что способен оптимизатор Раста =)
На самом деле это было на ленивых вычислениях. Тем не менее, без ленивых вычислений:
fn main() {
let vec = vec![0; 100000000];
let vec: Vec<_> = vec.into_iter().enumerate()
.map(|(idx, _el)| idx * 10)
.map(|x| x + 1).collect();
vec.into_iter()
.take(10)
.for_each(|x| {
println!("el = {}", x);
});
}
real 0m0.281s
user 0m0.072s
sys 0m0.208s
А в C++ версии вы сделали инициализацию массива из 100000000 элементов с помощью push_back, не удивительно, что оно так тормозит. Вы-то себе пачкой выделили память.
Читайте про амортизированную стоимость.
real 0m0,133sИ это я ещё OpenMP не подключил для автопараллелизации циклов)
user 0m0,072s
sys 0m0,061s
Раст прикольная конечно штука, но пока экзотика)
Вся смехота заключается в том, что мы одни бенчи запускаем на одном железе, а другие на другом. Вот таблица бенчей:
ArrayListTest.c:
real 0m0.497s
user 0m0.292s
sys 0m0.205s
cpp:
int op_increase(int i) { return ++i; }
int main() {
std::vector<int> foo;
foo.reserve(100000000);
for (int i=0; i<100000000; ++i) foo.push_back(i*10);
std::transform (foo.begin(), foo.end(), foo.begin(), op_increase);
for(size_t i = 0; i<10; ++i) {
std::cout << foo[i] << std::endl;
}
}
real 0m0.254s
user 0m0.148s
sys 0m0.108s
rust (вариант выше):
fn main() {
let vec = vec![0; 100000000];
let vec: Vec<_> = vec.into_iter().enumerate()
.map(|(idx, _el)| idx * 10)
.map(|x| x + 1).collect();
vec.into_iter()
.take(10)
.for_each(|x| {
println!("el = {}", x);
});
}
real 0m0.286s
user 0m0.097s
sys 0m0.189s
rust (параллельные итераторы):
use rayon::prelude::*;
fn main() {
let vec = vec![0; 100000000];
let vec: Vec<_> = vec.into_iter().enumerate()
.map(|(idx, _el)| idx * 10)
.map(|x| x + 1).collect();
vec.into_iter()
.take(10)
.for_each(|x| {
println!("el = {}", x);
});
}
real 0m0.112s
user 0m0.302s
sys 0m0.314s
Пока что лидирует Rust =)
И это я ещё OpenMP не подключил для автопараллелизации циклов)
Только код скиньте.
У меня нет ArrayList, поэтому не могу воспроизвести. С какими опциями вы собирали код?
Кроме того, это немножко читерство: в плюсах вы не выделили всё место сразу, а в С — выделили.
Ну и, кроме того, как-то мы резко сменили тему с написания сишного map
на микробенчмарки.
Сделал вариант бенчмарка с пушем в список по 1 элементу.
Вариант с пушем с -O3:
make && time ./a.out
real 0m0,394s
user 0m0,321s
sys 0m0,073s
С единоразовым выделением памяти gcc -O3:
make && time ./a.out
real 0m0,133s
user 0m0,072s
sys 0m0,061s
Проц i73630QM 2.2 ГГц
Ну и, кроме того, как-то мы резко сменили тему с написания сишного map на микробенчмаркиНу он написан же, что там ещё обсуждать. Перформанс вроде как важен для сишников.
void* add2ArrayList(ArrayList *list) работает несколько не так как в C++, он не добавляет элемент сам, а только увеличивает счётчик, если надо, реаллоцирует и возвращает указатель, по которому уже можно писать данные. Например, указатель на структуру.
Кроме того, это немножко читерство: в плюсах вы не выделили всё место сразу, а в С — выделили.На самом деле я скопипастил плюсовый код с какого-то сайта. Ну вот пишут они так.
github.com/yarston/ArrayListTest выложил сюда.
Спасибо. ХЗ, у меня сишка чего-то тормозит:
0.53 с для вашего варианта (только я ещё -march=native
добавил).
0.36 с для плюсового варианта с reserve + push_back.
0.31 с для плюсового варианта с resize + operator[], чтобы не проверять capacity на каждой вставке.
Если честно, я думал, разница между двумя последними вариантами будет не такой большой — по идее, бранч предиктор должен очень быстро научиться, что проверка на capacity всегда проходит. Интересно.
gcc 8.3.0, i7 3930k.
PS. Поигрался ещё.
Если убрать bar
и писать сразу в тот же foo
, то получаем 0.18 с.
Кроме того, заметил, что у вас там Slow
вместо Fast
. Заменил в вашем коде на getFast
— да, стало работать быстрее, та же 0.31 с, что и для плюсового кода.
Теперь можно сравнить, насколько универсальны std::transform
и этот ваш макрос соответственно.
Ну он написан же, что там ещё обсуждать.
Нет, там написан не он. Там написаны инструкции для кодогенератора (сишного препроцессора), как сделать сишный map для каждой конкретной функции (да и то в виде блока кода, а не произвольного указателя на функцию).
Так мы с вами дойдём и до того, что в Go дженерики есть, потому что их можно кодогенерировать.
у меня сишка чего-то тормозит:странно, у меня
gcc --versionПравда у меня ещё патчи против спектр отключены. Там getSlow() по умолчанию стоит, его можно закомментить и собрать с единоразовым выделением памяти.
gcc (SUSE Linux) 8.2.1 20190204 [gcc-8-branch revision 268513]
Нет, там написан не он.Звучит как повод для дискусси, но лень спорить) Да и ладно, списки крутятся, работа мутится.
Если убрать bar и писать сразу в тот же foo, то получаем 0.18 с.это уже другая задача.
Кстати, к слову о функциональщине — если вам будет охота, предлагаю написать две функции, map и foldr, и сделать по вашему списку, например, map с увеличением на единичку (как сейчас), а потом свертку с суммированием, и посмотреть, сколько времени это займёт. Потом можно будет сравнить с Ъ функциональщиной.
Но, в любом случае, важны не абсолютные цифры, а сравнение с плюсовой версией (которое я таки дал).
CONVERT_VEC_TYPE(unsigned, in, list, unsigned, out, list2) *out = *in + 1;
на FOR(unsigned, el, list) (*el++)++;
:make && time ./a.out
gcc -O3 list.c main.c
el = 1
el = 10
el = 21
el = 30
el = 41
el = 50
el = 61
el = 70
el = 81
el = 90
real 0m0,090s
user 0m0,070s
sys 0m0,020s
FOR(unsigned, el, list) (*el)++;
gcc -O3 list.c main.c
el = 1
el = 11
el = 21
el = 31
el = 41
el = 51
el = 61
el = 71
el = 81
el = 91
real 0m0,089s
user 0m0,060s
sys 0m0,028s
Тут, кстати, отлично видно, зачем на самом деле нужен map
. Все эти функциональные map
, filter
и foldr
нужны не для того, чтобы циклы на них переписывать, а для того, чтобы ограничить доступные вам действия. Хаскелевский мап не передаёт функции ничего, кроме текущего элемента — значит, у него нет никакого состояния, и преобразование действительно зависит только от текущего элемента (в отличие от foldr, например, для которого это не так, но через который можно выразить map). Плюсовый трансформ не передаёт указатель на элемент или итератор, а только сам элемент. Все эти функции хороши тем, что они связывают вам руки.
довольно большой кодовой базы которая была наработана и отлажена за всё время существования языкаКодовой базы которая наработана, но не отлажена в нем также больше. Поиски работающего кода для своей конкретной задачи — отдельная проблема которая далеко не всегда проще чем собственно написание своего решения. А уж поддержка кода который написали не вы…
Вы видите здесь что-то платформоспецифичное?
Да. 9-patch это андроидовская тема.
В чём у вас измеряются все магические константы — непонятно.
Да, автовекторизация и прочие оптимизации весьма недурно производительность поднимают.
И компиляторы уже такие умные стали, что автоматически векторизуют всё, что можно векторизовать?
Может, оно вам и AoS в SoA само конвертирует?
На практике вклад malloc/free во время исполнения с лупой искать надо.
Везёт вам там. У меня бывают проекты, где приходится писать свои аллокаторы, с аренами и вот этим всем.
И компиляторы уже такие умные стали, что автоматически векторизуют всё, что можно векторизовать?Ну у меня например, софтварный растеризатор треугольников на Си без интрисинков с опцией -O3 ~180мс на отрисовку сцены 8к полигонов в 4к (3840*2160) в 1поток на ноутбучном CPU, а с интрисинками (SSE4.2), оптимизацией размещения данных в структуре и выравниванием в памяти ~160мс. Пожалуй под неон забью на ручную векторизацию.
Может, оно вам и AoS в SoA само конвертирует?А зачем? Я сразу пишу как надо.
У меня бывают проекты, где приходится писать свои аллокаторы, с аренами и вот этим всем.В линуксовой libc аллокатор с аренами как раз. Если что, можно её статически линковать, не уверен правда, позволяет ли лицензия.
Ну у меня например, софтварный растеризатор треугольников на Си без интрисинков с опцией -O3 ~180мс на отрисовку сцены 8к полигонов в 4к (3840*2160) в 1поток на ноутбучном CPU, а с интрисинками (SSE4.2), оптимизацией размещения данных в структуре и выравниванием в памяти ~160мс.
А у меня есть код, у которого производительность отличается на порядок. И при этом я далеко не спец в SIMD, так, мимо проходил.
А про разницу всяких dlib'ов или eigen'ов с ручными операциями с матрицами против MKL я и говорить не хочу.
А зачем? Я сразу пишу как надо.
Ну а чего б и нет? В терминах AoS таки чуть удобнее размышлять.
В линуксовой libc аллокатор с аренами как раз. Если что, можно её статически линковать, не уверен правда, позволяет ли лицензия.
У меня как у программиста чуть больше информации о времени жизни объектов. Например, я знаю, что по условиям задачи я могу выделять память из арены, не освобождая её до окончания обработки запроса вообще никогда, и одним махом всё уничтожить в самом конце. Компиляторы пока не такие умные, к сожалению.
Языки с элементами субструктурных систем типов могут, например. Но да, не джава и не .NET.
Правда, и в этом случае будут проблемы — оптимизации во многом зависят от ожидаемых объёмов, времен жизни и тому подобного, которые непонятно как передать компилятору, кроме как через PGO.
Нет, потому что проблему из последнего абзаца они не решают.
С быстрее
Очевидно. Удобнее — уже очень сомнительно.
профилировать перформанс — и так ясно, что всё предельно быстро будет
А люди, дураки, зачем-то всё равно тяжёлый вычислительный код под профайлерами гоняют. А можно-то просто писать на сях, оказывается!
Отличный язык для быстрого прототипирования)
И код реюзабельный, и в языке все средства для этой реюзабельности есть, ага.
И да, это сарказм. И нет, это не про торжество ООП.
Обычно люди просто стараются увернуться (включить/выключить, попробовать ещё раз), а не выяснять что именно там случилось.
Так ещё Чарльз Беббидж говорил, что выгоднее (по времени) пересчитать заново всю ошибочную страницу, чем искать в ней ошибочные значения.
Вычитание из большого числа маленького может не приводить к изменению значения. И т.д.
Но стек абстракций уже слишком велик, чтобы кто-то мог его весь знать в подробностях.
Мы не чиним двигатель через выхлопную трубу. Мы едем на СТО и просим специалиста залезть пд капот.
задача всего компьютерного — абстрагирование и уменьшение сложности.
Иногда программисты старшего поколения, глядя на сегодняшние реалии начинают всерьез в этом сомневаться… Я вполне знавал людей, которые считали, что ассемблер гораздо ПРОЩЕ всех этих ваших «высокоуровневых» ЯП. И где-то они правы… Пока сложность собственно самого кода не выходит за определенный порог, когда без абстракция уже невозможно охватить сознанием логику решения в целом.
Но все равно — текущий уровень абстракции многих современных ЯП даже мне кажется слишком перегруженным! Ощущение такое, что уже пошли абстракции, ради абстракций, размывающие основы. Согласен во многом с автором.
Но я реально не понимаю, сколько строк кода на ассемблере нужно для того, чтобы скачать файл. tcp, DNSsec, TLS, http…
; Открыть интернет-соединение
invoke InternetOpen,user_agent,\
INTERNET_OPEN_TYPE_PRECONFIG,NULL,NULL,0
mov [hInet],eax
; Открыть FTP-соединение
invoke InternetConnect,[hInet],server,[port],login,password,\
INTERNET_SERVICE_FTP,INTERNET_FLAG_PASSIVE,0
mov [hConnection],eax
И тп…
Это был просто пример подхода к вопросу «скачать файл», если есть библиотека.
Так-то tls Гуглится на раз.
Я вполне знавал людей, которые считали, что ассемблер гораздо ПРОЩЕ всех этих ваших «высокоуровневых» ЯП.
"Сложность" в данном случае — это не сложность инструмента, а сложность решения задач при помощи этого инструмента. Экскаватор сложнее лопаты и требует более высокой квалификации от того, кто его использует, но копать котлованы при помощи экскаватора в итоге проще. Ассемблер — лопата, ЯП ВУ — экскаватор.
Например лопатой можно делать гораздо более точные и аккуратные вещи, в быту нужна лопата, а не экскаватор, порог вхождения у лопаты… Тонкий момент — у лопаты ниже, а ассемблера — не факт… ;)
Потом опять же — лопата, она и есть лопата, а сложность современных
Львиная доля усложнения самих ЯП (я имею ввиду не банальный синтаксис, а совокупность код/ide/продукт на выходе) идет на сокрытие реальной сложности от разработчика. А многократный запас по производительности позволяет не парится из избыточностью и не рациональностью в угоду универсальности.
Это, наверное неплохо, но… Иногда мне тоже кажется, что мы пройдем какую-то точку, после которой все это превратится в магию, потому, что никто не будет знать, как оно работает!
#include <GL/glut.h>
int main()
{
glutCreateWindow(«Small program»);
glutDisplayFunc([]{});
glutMainLoop();
}
Потом опять же — лопата, она и есть лопата, а сложность современных экскаваторов ЯП уже как-то слабо коррелирует со сложностью решаемых задач! Современный Hello world запросто может потянуть на пару десятков килобайт, и примерно никто 90% тех, кто его использует НЕ ЗНАЕТ, что там в этих килобайтах!
Экскаватор тоже тянет на несколько тонн. И 90% тех, кто им управляет, не знает, что там внутри :)
Львиная доля усложнения самих ЯП (я имею ввиду не банальный синтаксис, а совокупность код/ide/продукт на выходе) идет на сокрытие реальной сложности от разработчика.
Ну так да, уменьшение сложности. В этом смысл и состоит.
Иногда мне тоже кажется, что мы пройдем какую-то точку, после которой все это превратится в магию, потому, что никто не будет знать, как оно работает!
Почему никто?
Всегда останутся люди, которые делают процессоры и компиляторы под эти процессоры. Причем это будут разные люди, и разработчики компиляторов не всегда могут понимать, что творится внутри процессора (для них он предстает в виде набора команд, регистров, Errata и еще некоторого набора знаний, но никак не в виде конкретного сочетания транзисторов, обеспечивающего то, как процессор выглядит для разработчика компиляторов).
Срочно привозят на место происшествия: стоит экскаватор, на ковше вытянутый из земли высоковольтный кабель, изоляция уже лопнула и металл блестит. Экскаваторщик сидит в сторонке белый как бумага. В результате мы траншею копали лопатами.
Очень актуальная аналогия :)
Так и мысли в голове не настоящие. Это несвязной бормотание внутри головы — это только тень от того, что происходит за пределами сознания. В каком-то смысле, сознание и есть то, что мы можем сказать. Чтобы сделать тривиальное действие, например, выделить немного слюны — мы должны очень напрячься, воображая лимон.
И этот же подход мы перенесли на программирование. Чтобы отправлять тривиальные сигналы, мы создали какие-то абстракции, которые нашему сознанию более близки, которые проще вообразить. Мы, условно говоря, мыслим «лимонами», а наше тело и компьютер управляется условным электричеством. И наши ЯПы — тем для нас лучше, чем они ближе к «лимонам». А что они там под капотом делают — дело уже давно десятое. И в принципе, оно хорошо. Если завтра у нас компьютеры будут основаны на других принципах, то нам достаточно будет переписать наши интерпретаторы лимонов в это новое и оно будет как-то там работать. Это тоже контроль. Но другого типа.
Однако есть, условно, наука, а есть наукообразность. Есть области, где просто нельзя без усложнений, а есть люди крайне витиевато и сложно выражающие ЛЮБУЮ мысль — даже ту, которую можно донести трехлетнему ребенку десятком простых слов.
Есть канцеляризмы, есть сленг, арго и тп.
Вот и не понятно где усложнения были необходимы, а где кого-то просто перло от нагромождения абстракций!
А если серьёзно, то проблема построения абстракций над абстракциями (и так до бесконечности) очень-очень серьёзная. Хорошо, если хоть четверть веб-разработчиков знают и понимают, что под капотом у V8, сишарперы — у IL. И как только мы встречаемся с проблемой уровня ниже нашего предела понимания этих абстракций, мы бессильны.
Ещё Азимов в своей книжке "Основание" описал, а Артур Кларк сказал, что любая достаточно развитая технология неотличима от магии. А разве мы можем понять магию? Нет. Не можем. Значит рано или поздно, при появлении таких технологий, мы будем жить в мире компьютерной магии, и ни один человек не будет ей управлять.
А теперь представьте, если магия перестанет работать. Что будет? Полная разруха...
P.S. Машу табличкой «сарказм». Ссылка на рассказ Гарри Гаррисона.
Как жаль, с одной стороны, что нет инопланетян, и никакое НЛО не починит… Но с другой стороны, хорошо, что никто не может нас шантажировать в плане контроля и починки этой "магии".
Сколько мест в мире где скажем жесткие диски делают или еще чего там более продвинутого? А если их 1-2 таких мест на весь мир останется, глобализация экономики это же диктует, а потом какой локальный кабздец на это место свалится типа эпидемии или военного конфликта. Т.ч. специфичность условий тут скорее в локализации технологий, а не сами условия, о чем мне думается предыдущий оратор и говорил.
Сколько мест в мире где скажем жесткие диски делают или еще чего там более продвинутого?Жёсткие диски ладно. А вот сканеры для литографии — это штучная работа и всего три фирмы: ASML и Canon и Nikon их делают (вернее практически ASML только делает, Canon/Nikon всё грозятся победить EUV, но пока поставок нет).
Вы знаете, мне иногда кажется, что в современном мире достаточно уничтожить 15-20 тысяч человек, чтобы цивилизация встала в своём развитии. Пугает…
американцы вон уже список в санкциях начали заполнять=)) осталось ещё сотню таких составить, и заживём
Предположим некоторые рептилоиды с помощью наноботов взяли и уничтожили весь интел и амд. Ну и производственные их мощности заодно и складские запасы, так уж, чтобы наверняка. Что произойдёт?
Ну экономику поколбасит, да. Цены полезут вверх на железо как на дрожжах, стартапов поуменьшится.
Но
1) останутся сотни мелких производителей
2) Новые процессоры х86 выпустят в течение двух, максимум пяти лет
3) технологии на фабах откатятся ну скажем на десять лет назад
4) станут востребованны более быстрые стеки ПО
В целом эффект на прогресс это окажет не очень сильный.
возмут люди книжки и начнут изучать с азов, через пару лет появится группа специалистов которая будет востанавливать технологию…
СССРовсский x86 собственной разработки был или все же в основе интел лежал?
И сколько мелких производителей имеют культуру разработки и как изделий так и технологий, они уже всем готовым скорее пользуются чем собственное разрабатывают.
СССРовсский x86 собственной разработки был или все же в основе интел лежал?Он был копией — но это было политическое решение. Так же, как и пресловутый Ту-4.
Так же, как и пресловутый Ту-4.
Это Вы зря. Эта машина — самый настоящий реверс-инжиниринг.
Из чего не следует, что ничего своего создать не могут. В конце-концов и Ан-225 и E2K существуют и точно не являются копиями западных аналогов.
Кто то же эту «магию» должен поддерживать на всех уровнях )
Просто это будет совсем другой уровень. Сейчас уже есть неплохой разрыв между теми кто пишет ядро технологии и тех, кто ими пользуется ) Со временем он просто будет расти или количество слоёв будет увеличиваться.
Да, разрыв будет увеличиваться. И да, будут люди, поддерживающие всё это. Но рано или поздно это кончится. Либо это будет как в "Матрице", когда машины вытеснили людей и заставляют их жить по своим правилам, либо это будет, как тот случай с криптовалютной биржей и холодным кошельком, владелец которого умер.
Это всё к чему. Если (ну вдруг) происходит форс-мажор и людей-"богов" (продолжая образ магии = технологии), которые держали всё на своих двоих, не станет, то мы приедем в тупик цивилизации. Как только мы забудем, если отвлечься от темы технологий, рецепт Кока-Колы, которую знают единицы, то мы никогда не сможем её воспроизвести, лишь пользоваться уже настроенным оборудованием, пока его не придется заменить и забыть программу производства. Так и здесь, не стань пары ключевых людей в Intel, и архитектура процессора для нас — тайна. Тайна, правду о которой мы никогда не узнаем.
Но рано или поздно это кончится.Совсем не факт. Помимо людей, которые сейчас эту магию умеют есть масса учебных курсов. Из-за роста количества людей которым эту магию нужно чинить — людей владеющих магией тоже становится больше (количественно, не в процентах). Как они могут все внезапно куда-то деться, да еще и всю литературу по теме прихватить — непонятно совершенно. Разве что апокалипсис случится, но там проблемы побольше будут чем непонимание что там под капотом у V8.
Делается некая система, в нее вкладываются квалификация, знания и умения людей — чтобы делала все это за них. Потом люди уходят, оказавшись ненужными или потеряв интерес.
И через несколько лет имеем черный ящик, про который не только никто не знает, как он работает, но и никто не знает, что именно от ящика ожидается. Т.е. когда на постукивание в левом верхнем углу ящик выплевывает комок зеленых соплей — никто не может сказать, «это так и задумано и сделано для того-то и того-то крайнего случая», или «ящик сломался».
Ну хорошо, про «так и задумано» иногда сказать можно — на этот счет тест есть. А вот для чего оно так — это задокументировать забыли. Тут вот чуть выше про управление знаниями вспомнили. Но речь как раз про то и идет, что на самом деле этого самого управления практически никогда нет.
Апокалипсиса не надо. Оно встречается постоянноИ что — постоянно случаются катастрофы? Вроде бы нет, человечество как жило так и живет. Я к тому, что либо то, что вы описываете — апокалипсис и его скорее всего не случится, либо это достаточно незначительные события не играющие большой роли. Зависит от того, какой смысл вы вкладываете в слово «это».
Ну забросили в какой-то компании самодельную систему, ну и что? Да, компания что-то теряет из-за невозможности модификации и вынуждена будет потратить сколько-то денег на либо переделывание, либо покупку готового. Но это штатная ситуация, ничего страшного не произошло. Да, какие-то более глобальные решения забрасываются и есть люди которые остаются с магией. Но и это не происходит в один день и без появления альтернатив зачастую. Популярное решение не умрет если пропадет единственный его разработчик, потому что он не будет единственным. Ну а в таком случае те, кто остался на умершей системе в общем-то сами виноваты, могли бы и озаботится миграцией на что-то живое.
И через несколько лет имеем черный ящик, про который не только никто не знает, как он работает, но и никто не знает, что именно от ящика ожидается. Т.е. когда на постукивание в левом верхнем углу ящик выплевывает комок зеленых соплей — никто не может сказать, «это так и задумано и сделано для того-то и того-то крайнего случая», или «ящик сломался».
Это вы сейчас прям точно в саму природу человека и попали. Сколько тайн хранит не изученный потенциал человеческого мозга. Сколько интересных исследований я вчера почитал по раздвоению личности, после просмотра фильма «стекло». А не потеряли ли мы инструкцию к самим себе. И не это ли хотели нам сказать все предыдущие пророки. Но в силу скудности ума, мы так и не научились читать и слушать. И каждый народ интерпретировал или перевёл это на свой лад.
Вы скажете — а зачем это надо? Ну, к примеру, возобновление производства оружейного плутония. Там всё задокументированно и понятно, для химика, получившего образование в 40-х годах прошлого века. У современного специалиста, фраза " довести концентрацию вещества до 7" вызовет немой вопрос в глазах. Потому что кардинально поменялись методы анализа веществ.
Или совсем простой пример, лет 10 назад надо было слегка модернизировать крупный нефтеперерабатывающий завод в США. Есть некая документация, живы люди, которые её разрабатывали, и методы перегонки вроде не поменялись, вот только реальная схема завода СОВСЕМ не соответствует чертежам. И зачем так было сделано — никто не помнит. Причём видно, что сначала делали по чертежам, а потом переделывали. Результат — небольшая модернизация вылилась в полную перестройку, «с нуля».
Так что это дело не будущего, а настоящего. Мы уже не понимаем что, и почему именно так, делали наши родители.
И управление знаниями не панацея. Бумажная документация — считайте что её нет. Как показывает опыт, она не полная и перепутана. Да и выкидывают её с большим удовольствием. Особенно при банкротстве\ поглощении. Найти что либо в бумажных архивах можно при большой доле везения. Как с нефтеперегонным заводом. Понятно что была документация на все переделки. Вполне вероятно что она даже сохранилась. Вот только ГДЕ?
Так что это дело не будущего, а настоящего. Мы уже не понимаем что, и почему именно так, делали наши родители.Так а нам и не надо. Частный случай провала планирования не в счет — это провал планирования модернизации, а не необходимость восстановления никому больше не нужных тех процессов.
И возникает вопрос — если двигатель С ТАКИМИ ПАРАМЕТРАМИ был (сам двигатель в музее стоит) то почему его не использовали потом и не могут воссоздать сейчас?
если двигатель С ТАКИМИ ПАРАМЕТРАМИ был (сам двигатель в музее стоит) то почему его не использовали потомНе использовали потому, что по другим характеристикам не устраивал. В частности отношение тяги к весу лучше и у двигаталей, на которых Союз летает и у пресловутого Falcon-9.
А максимальная мощность одной камеры нужна только на очень тяжёлых ракетах и то не факт, что будет выигрыш: с учётом того, сколько ракете нужно везти топлива небольшой выигрыш по отношению «тяга к массе» может быть легко скомпенсирован проигрышем в экономичности…
Но вообще все эти самые-самые достижения «теряются» обычно потому, что ну очень дорого это: делать самую большую ракету, самый большой самолёт, самый большой экскаватор и прочее. Потому когда, через много лет, снова появляются потребности и деньги — всё с нуля приходится изобретать…
И возникает вопрос — если двигатель С ТАКИМИ ПАРАМЕТРАМИ был (сам двигатель в музее стоит) то почему его не использовали потом и не могут воссоздать сейчас?Потому что это не единственные его параметры. Есть еще цена и технологический стек у производителя как минимум. И с включением этих параметров создавать точно такой же двигатель не имеет смысла. А еще есть цель, то есть ее как раз нет. Такой же двигатель банально никому не нужен. Вообще спасибо, это прекрасная каноничная иллюстрация того о чем я говорю — появилась необходимость и сделали лучше на современных технологиях. Да, если бы этот двигатель модернизировали непрерывно с момента его создания, то сейчас не приишлось бы тратить столько времени на создание современного аналога. Но это просто вопрос цены — что нам жалко больше ресурсы на модернизацию того, что не нужно или время на создание более совершенного аналога когда таки станет нужно.
Они умерли потому что есть что-то более современное, что пришло им на заменуПричина не в этом. В случае с СССР после прекращения его существования, было до 800 технологий утрачено. Я не уверен в точности цифры. Но в официальном видео от РосАтома (или кто там главный у нас по реакторам) после развала с трудом нашли человека способного запустить какой-то тип ядерного реактора, и это у государства которое является одним из лидеров в ядерной энергетике. Знания размываются, связующие знания теряются. С ТУ-160 та же история, чуть не проимели титановую сварку в вакууме, но вроде нашлись знатоки. Что-то более современное иногда не приходит.
Что-то более современное иногда не приходит.Другие страны же это как-то делают. В РФ не так уж много технологий нужных кому-то еще и которых ни у кого больше нет. Ну может кроме военки, но я тут не силен. Или я ошибаюсь и весь мир страдает без титановой сварки в вакууме?
По поводу страданий всего мира без титановой сварки, я не в курсе.Ну то есть было не очень корректно на примере этого случая говорить что «Что-то более современное иногда не приходит.», так как вы просто не знаете пришло ли или нет. Конкретно в РФ — нет, потому что дешевле было не потерять технологию. Где-то еще — может быть и пришло. Либо где-то еще эта технология и не терялась даже. Я не говорю что вывод неверен, я тольо говорю что для такого вывода у вас не достаточно оснований. Он при этом вполне может быть и верен.
Потому называть процесс, из которого исключено что-то что в нём имеется и в нём это что-то случается — «естественным процессом» у меня не получается.Не надо смешивать катаклизм — гигантское изменение, катастрофу, с несчастным случаем — плохим, но в целом достаточно рядовым событием, как по эффекту, так и по частоте. Я из естественного процесса исключил только катастрофы. В данном случае — развал сверхдержавы. Можно поговорить о том, где провести границу, но в большинстве случаев это достаточно очевидно. Старый завод который забыл обновиться и у него что-то сломалось — несчастный случай. Развал сверхдержавы — катаклизм.
Ну, к примеру, возобновление производства оружейного плутония.
это вы сейчас так хитро тендер в хабр впихнули? или кто та там на верху забыл как плутоний обогащать=)) headhunter не
Это образно говоря. Но вполне возможно наткнутся на измерения уникальными приборами, с записью результатов в единицах шкал этих приборов. Или реакции которые тогда шли, а сейчас не идут, потому что степень очистки вещества поменялась, а примеси работали как катализаторы.
Невозможно сделать это ДЁШЕВО. Если это будет вопрос выживания — воспроизведут. Дорого, за десять тысяч человеко-лет, скажем, но воспроизведут. Да и пример ваш не очень — КНДР, вон, справилась с плутонием.
Пример с нефтезаводом тоже не очень. Построили же! Ну с нуля, но построили. Вот, скажем, в 18 веке не построили бы, вот никак, что с документацией, что без, потому что знаний в культуре не было, и весь завод был непонятная магия.
Здесь понимание магии как таковой не в том, что она для кого-то — фантастика, а для кого-то — реальность, а в том, что никто её не может объяснить толком. Вот лично я, разбираясь в достаточно простой (на первый взгляд) технологии — техниках рендеринга 3д игр, увяз в тоннах деталей, потонул как раз в той самой "магии" не потому, что это эпоха такая, или я плохой, а потому лишь, что тысячи последовательно возникавших идей создали многоуровневую сложность, пониманием (имею ввиду виду простоту и лёгкость осознания, Simple is better than complex — Python Zen) которой часто жертвуют ради других целей: эффективности, красочности и так далее.
Всё это приводит к тому, что если раньше, будучи энтузиастом, можно было легко покорять геймдев с минимальными знаниями, то сейчас есть шанс вообще не постигнуть этот дар богов.
Здесь понимание магии как таковой не в том, что она для кого-то — фантастика, а для кого-то — реальность, а в том, что никто её не может объяснить толком. Вот лично я, разбираясь в достаточно простой (на первый взгляд) технологии — техниках рендеринга 3д игр, увяз в тоннах деталей, потонул как раз в той самой «магии» не потому, что это эпоха такая, или я плохой, а потому лишь, что тысячи последовательно возникавших идей создали многоуровневую сложность, пониманием (имею ввиду виду простоту и лёгкость осознания, Simple is better than complex — Python Zen) которой часто жертвуют ради других целей: эффективности, красочности и так далее.С магией точно так же. Просто многое утрачено. инквизиций, церкви. Сколько литературы созжено. Люди боятся того что не понимают.
Всё это приводит к тому, что если раньше, будучи энтузиастом, можно было легко покорять геймдев с минимальными знаниями, то сейчас есть шанс вообще не постигнуть этот дар богов.
Техпроцесс основан на самопознаний, на силе разума и чем та там еще. Типа человек может контроливать на атомном уровне силой мысли.
если хоть четверть веб-разработчиков знают и понимают, что под капотом у V8
Если много знать о внутренностях V8, то и код получится заточенный под Google Chrome, а пользователи Firefox расстроятся. Поэтому лучше опираться на стандарт языка, а не на конкретную реализацию.
А тут вы идёте к мебельщику и начинается: нам нужно чтобы та штука, которая делает штуки, когда выполняет делание штуки делала другое делание делания штуки, которая штуку делает, а потом у неё есть функция контейнирования и она реаллоцируема.
Во во. В слове "тумбочка" на самом деле скрыт десяток лет воспитания и взросления человека, причем в определенном обществе. Ибо ваша тумбочка и тумбочка соседа таки может очень сильно отличаться :)
В данном случае само слово это всего лишь указатель на место объекта в памяти. А сам объект это дикая абстракция над абстракцией. И все еще неизвестно, где же в нашей голове предел сложности и финальные элементы декомпозиции "тумбочки".
Ок: тумбочка->спальня/гостиная/кабинет->комната->помещение->дом/завод/соц.объект->сооружение
И таки да, при задаче «нам надо спроектировать сооружение» — вероятность учета уместности тумбочки будет под вопросом.
Однако когда стоит задача "комната" — уже можно дать условные 90%, что все будет совместимо с любой условной тумбочкой.
Чем больше слоев абстракций, тем больше неопределенность в структуре нижних слоев.
Однако человечество справляется. По крайней мере на текущий момент.
UPD: Вспоминаю Sims — там как раз можно «пилить модулями-комнатами» (с тумбочками разумеется).
UPD №2: Смотрю на свою платформу для тестирования — у неё, как и любого сложного продукта есть много слоев абстракций.
На верхнем я просто пишу (утрирую конечно):
— система, вкл.
— система, авторизация
— система, проверить компонент Z
— система, проверить компонент F
— система, проверить компонент H
— система, выкл
Но под капотом,… разнокалиберные сервисы, динамическая балансировка нагрузки, автоматическое выявление неполадок (ага, тулл для тестирования сам себя тоже проверяет), их устранение (узкий спектр, но тем не менее), гибкое конфигурирование (частично на лету, самостоятельное). Система за собой даже тестовую среду может подчистить (убирать за собой, для возможности протестировать «продакшн»).
Т.е. в недрах крутится просто адская сущность, в которой без бутылки порой и не разберешься — блок-схемы в компе (или на бумаге) обязательны для возможности удержать в голове общую структуру.
Но это весьма надежная молотилка.
И все это управляет еще одним набором пластов абстракций, заключенных в webDriver.
выбрал PHP — слил жизнь в унитаз. Выбрал Go — стал тупицей.
Выбрал .net — не спишь по ночам, пытаясь восстановить связь с реальностью.
Шутка. Интересная публикация (y)
Кому нужен максимальный контроль — на asm.
Единственная полу-успешная попытка явно перестать отвечать за код умерла с архитектурой Intanium :)
А абстракции… То, что делают команды людей слишком сложно, чтоб обходиться без них — попробуйте себе представить, что происходит в каком-нибудь современном лайнере целиком или хотя бы в процессоре — в деталях и без абстракций?
Только машинные команды тоже жонглируются внутри процессора.
Выполнение 8086 команд это тоже абстракция с целью совместимости.
Даже на си и асме мы не знаем что же там внутри творится. Исключая разве некоторых непосредственных работников амд и интела
А теперь начинаем ме-е-едленно подниматься наверх. Свой ассемблер. Свой компилятор, который переставляет команды для оптимизации загрузки функциональных устройство стрррого по заданному алгоритму. Линукс порт. Busybox. Едва-едва дышащие (на тысячедолларовой FPGA) vi и mc. Текстовый браузер. И запоздалое понимание: на кой черт я безвозвратно потратил десять лет жизни — чтобы убедиться в том, что я точно понимаю, что под капотом?
Откуда вы такие беретесь? В Стандарте нет ни слова про debug/release, UB есть UB.
Достаточно вспомнить быстрый обратный квадратный корень Кармака и Silicon Graphics, который явно использовал трюк, который является UB, но как раз-таки из-за того, что автор хорошо понимал, каким оно получится на низком уровне в конкретном случае, оно работает.Тот трюк вызывал UB не из-за «непонимания чего-то на низком уровне», а тупо из-за каламбура типизации. Меняете его на bit_cast — и всё, никакого UB.
PS только сейчас подумал, что Глушковская ОГАС сейчас занимает 1 серверную стойку и стоит в каждом приличном банке, как минимум — 1.
Кому нужен много контроля и низкий уровень — пишут на С.
Кому нужен максимальный контроль — на asm.
<сарказм>… а кому нужно ещё больше контроля, пишут на Scala.</сарказм> Я, конечно, понимаю, что это просто DSL, но забавно всё-таки, что функциональный язык оказался в чём-то ближе к железу, чем asm (да, я знаю, что можно "писать процессоры" хоть на Python).
Или думаешь что команды выполняются в таком порядке, а на самом деле процессор выполнил их в другом.
Или думаешь что загрузил данные в конкретный регистр, а их там целый пул.
Уже давно asm это просто внешний интерфейс.
И чем абстрактнее становится язык, тем сильнее из твоего мышления вымывается его реальное назначение — контролировать электричество в железе. Все эти картинки у тебя на мониторе, циферки, библиотеки, анимации — они не настоящие. Настоящее только электричество. Только железо. Я не готов потерять над ним контроль.
Можно подумать у вас когда-то был этот контроль. Мне кажется, случай со specte должен был отлично показать, что вы не контролируете железо.
… До индикаторов был осцилограф, который точечками биты показывал.
www.youtube.com/watch?v=nc2q4OOK6K8
В 50х еще даже мои родители не родились. Я боюсь, что автор поста, скорее всего, тоже.
Я тоже из того времени и начинал писать на Урал-1, где все переменные должны были быть от -1 до 1, а в системе команд не было циклов и переходов с возвратом(вызов подпрограмм). Пришлось пройти весь путь от машинных команд через Алгамс, Кобол, PL/1, C, C++, Java к C#, WPF со множественными ответвлениями в разные стороны.
И ЯП не главное. Кроме языков есть методологии и технологии: модульность, структурное программирование, HIPO, Варнье, Джексон, ООП и др.
Пройденный путь помогает понять — почему и куда движется программирование.
3-4 слова в день — конечно перебор.
Есть БЭСМ -1, у которого всего ничего памяти, поэтому — программирование в машинных словах:
Которые да, руками забивались в машинку с 486 процессором и затем успешно исполнялись.
И полный цикл разработки-внедрения какого-нибудь метода Сименса занимал две сдвоенные пары.
А вот дебаг, это да, страшно было.
выбрал PHP — слил жизнь в унитаз. Выбрал Go — стал тупицей
Доктор, а если я выбрал HDL, я ещё не совсем безнадёжен?
1. Потеря контроля из-за делегирования и абстрагирования — основа человеческой цивилизации. Думаете, проектировщик корпуса нового спортивного автомобиля понимает, как работает его двигатель? Или всю глубину математического аппарата под моделированием аэродинамических характеристик? Думаете, врач знает, как работает МРТ, на основе которого он ставит диагнозы, определяющие чью-то жизнь? Мы все миримся с этим, потому что другого способа реализовывать сложные вещи и процессы у нас нет.
2. Увеличение толщины слоя абстракций в ЯП, как мне кажется, сильно преувеличено. Да поправят меня люди, чей опыт побольше моего и исчисляется десятилетиями, но по моим ощущениям за последние пару-тройку десятков лет толщина этого самого слоя не так чтобы особо выросла. Языки стали более зрелыми, да, инструменты стали более мощными. Но концептуально изменилось немного. Изучая устройство V8 я часто обнаруживал, что многие его ключевые фичи изобретены в 60-x – 80-x авторами какого-нибудь Lisp или Self. Выше упомянули Spectre — так и спекулятивному выполнению уже лет 30 как.
Но финальная идея, что язык значительно определяет сознание верная. Выход на мой взгляд простой — стараться изучать концепции, а не языки, смотреть шире. Тогда ставка на «неправильный» язык не будет критична.
- Увеличение толщины слоя абстракций в ЯП, как мне кажется, сильно преувеличено. Да поправят меня люди, чей опыт побольше моего и исчисляется десятилетиями, но по моим ощущениям за последние пару-тройку десятков лет толщина этого самого слоя не так чтобы особо выросла. Языки стали более зрелыми, да, инструменты стали более мощными. Но концептуально изменилось немного. Изучая устройство V8 я часто обнаруживал, что многие его ключевые фичи изобретены в 60-x – 80-x авторами какого-нибудь Lisp или Self. Выше упомянули Spectre — так и спекулятивному выполнению уже лет 30 как.
Самая большая победа, кмк, это реальная независимость от железа. Истории из 80-х полны рассказов о том, что как программы работали только на определенных видах процов, дисков, памяти и так далее. На данный момент банальное веб-приложение на python запускается почти везде.
Самая большая победа, кмк, это реальная независимость от железа. Истории из 80-х полны рассказов о том, что как программы работали только на определенных видах процов, дисков, памяти и так далее. На данный момент банальное веб-приложение на python запускается почти везде.Полностью согласен. Но не думаю, что это вопрос того, что тупо наклепали абстракций. Просто инструменты стали совершеннее.
Даже древнебородатый (не в обиду) C++ сегодня достаточно неплохо переносится между платформами. Понятно, что с перекомпиляцией; понятно, что нужно учитывать ряд ограничений (иначе и никак). Но тем не менее вы вполне можете писать кросс-платформенный код на С++ — имея при этом те самые «zero-cost abstractions».
Так с++ собирается под разные платформы, а пайтон и джаваскрипт запускаются на разных платформах.
вот такая вот «кросс-платформенность»…
А вот C#/Java (в меньшей степени Python/JS) — как раз ради этого и созданы: вам не нужно думать на каком CPU ваша программа запускается — если она работает у вас на десктопе, то и на телефоне запустится… разумеется такой подход ограничивается количество доступных платформ гораздо сильнее: вы не можете (как в C/C++) сказать «если ваша платформа это умеет — то и отлично, а если нет — то ошибка компиляции» и потом обложить это место #ifdef'ами. Вам нужно выбрать некоторое множество фич и обеспечить их работу на всех платформах…
Я это все к тому, что вместо стандартизации, мы продолжаем решать проблему не на той стороне, добавляя ненужные абстракции.
Мне кажется, что никогда такого не будет, потому что слишком много разных кейсов и для них нужны слишком разные стандарты. Даже тот же "стандартизированный" sql не очень то стандартизирован. Да что там, даже tcp/ip стек в каждом месте имеет свои приколы.
И чем абстрактнее становится язык, тем сильнее из твоего мышления вымывается его реальное назначение — контролировать электричество в железе.
Не-а. Реальное назначение — это решение задачи. Например, «показать пользователю иконку состояния ВПН соединения». Это — задача, а не манипуляция отдельными пикселями на экране. И если ты можешь решить эту задачу проще, то и чудно.
Всего-то количество пикселей увеличилось больше чем на порядок и утилита для просмотра картинок не стоит теперь 150 долларов как acdsee тогда. Если сейчас юзеоа за ту же делфи попросить тогдашнюю цену в несколько тысяч уе при тех зарплатах то современный софт и условия его использования покажутся раем.
Современный человек не задумывается, откуда у него на столе хлеб, в кране — вода, а на экране — сериальчики.
Безусловно, такой человек вряд ли самостоятельно сможет изготовить хлеб «с нуля».
Должен ли он знать, как это делается — наверно, да. Должен ли он сам это делать — наверно, нет.
Я точно ощущаю, что возможность решать задачи высокого порядка, не задумываясь о задачах порядков низких — это прекрасно и это в действительности ведет к прогрессу.
В реальности контроллировать электричество в железе никому не нужно
На самом деле это очень даже нужно.
Другой вопрос, что это нужно точно не программисту.
А нужно оно тому, кто это железо создает и порождает первые уровни абстракции — элементы логики для электрических схем (транзисторы, конденсаторы...), элементы более высокого уровня (ячейки памяти, триггеры...), элементы еще более высокого уровня (блок памяти, АЛУ...) и так до процессора.
Дальше программисты первого уровня абстракции уровня процессора (машинные команды) прячут под абстракции уровня компилятора (язык программирования), над которыми наворачивается стандартная библиотека, над которой наворачиваются фреймворки и так далее до абстракции уровня пользовательского интерфейса — кнопки, поля ввода.
Короче говоря, чтобы программисту было чем заняться, а у пользователя была кнопка в интерфейсе, которую он сможет нажать, нужны люди, которым приходится контролировать электричество в железе.
Я за то, что пользователи этого железа (а бытовые разработчики железо именно используют,
а не разрабатывают) не контроллируют электричество в железе. Оно на уровне абстрактных вещей формулирует другие, более высокоабстрактные вещи. И так далее. Все это в конечном итоге для того, чтобы кто-то смог действиями на экране заказать пиццу или посмотреть кино.
И это прекрасно — я вместо того, чтобы тратить время на приготовление пиццы, займусь теми вещами, которые умею делать. А пиццу пусть приготовят те, кому это выгоднее делать.
и это в действительности ведет к прогрессуПроблема только в том, что это прогресс для программиста, не для пользователя. Для пользователя, как уже здесь писали, с 90-2000х мало что принципиально поменялось. Да, кое-что стало слегка красивее. Но те же операционки с приблизительно XP для пользователя почти не поменялись. Браузеры тоже. Да, они стали обрабатывать огромные страницы по несколько мегабайт, но чем гмейл из двухтысячных хуже современного? дизайн слегка поменялся, он стал весить раз в 10 больше. по возможностям на фронтэнде всё примерно то же.
А персональные компьютеры обзавелись, например, поддержкой HDR и Hairworks. Процессор позволяет моделировать сложнейшие модели на ноутбуках в килограмм весом. Хорошую звуковую карту для проигрывания HI FI музыки можно уже не покупать — это все давно встроено в наушники.
Само собой, если не запускать ничего сложнее почтового клиента, блокнота, консоли и третьих героев, можно все это не заметить.
Но утверждать, что ничего не изменилось…
Мобильником примерно таким, как я пользуюсь сейчас (Samsung J1 16), я пользовался уже 10+ лет назад (Motorola A925).
по софту — вымирание любительской фототехники как класса (мобильник с ии фильтрами на борту), полноценные мобильные клиенты для соцсетей (покажите мне приложение с возможностями мобильного вКонтакте 10 лет назад), невероятно интуитивное и удобное яндекс такси, голосовое распознавание команд в мобильнике с набором текста — тоже было 10 лет назад?
Было такое. Причем в самом обычном кнопочнике, ни разу не смарте. Причем работало даже без обучения на пользователя (хотя с обучением лучше было).
Так что думаю, не придёт уровень «сделай вот такую хрень», потому как обязательно потребуется «сделай почти такую же хрень, но с перламутровыми пуговицами». И если разработчик абстракции не предусмотрел такой возможности, то целиком вся абстракция оказывается непригодной и придётся спускаться на уровень ниже.
Рад встретить человека, который общался с этим языком.
По поводу «через какое то время» — всё станет очень просто:
1. Сначала абстракция достигнет возможности не особо подготовленных пользователей писать «программы» — последовательности действий. Программа! Возьми рубли, преврати их в доллары и просуммируй за 100 лет по каждому клиенту. Или — подсоединись к Вконтакте и слей туда все мои фото по АПИ.
Программа ещё будет иметь достаточно много ограничений, но она будет уметь описывать в каких допустимых формах пользователь может ей сказать что хочет.
2. Пользователь сможет говорить своим языком в какой последовательности что и как надо сделать. Программа! Возьми вон тот столбец со значком Р и посчитай оборот за последний век.
3. Пользователь будет указывать что ему надо — программа сама построит алгоритм выполнения. Программа! Посчитай обороты для моего отчёта!
т.е. в итоге мы должны прийти (и придём) к тому, что бы машина понимала человека. Простого, неподготовленного человека. Именно к этому и ведёт увеличение уровня абстракций ЯП на мой взгляд и это неплохо.
другое дело, во что превратиться общество после такого перехода, как поддерживать такой «компилятор», что станет с легаси и АйТи итп-итп… но это совсем другая история.
Пока программист это часть компилятора по превращению желания заказчика в машинный код. Такие же как аналитик, компьютер, фреймворк, компилятор и все остальные уровни интерпретации данных поступивших от первого члена цепочки до последнего огонька на экране, показывающего то, что ему надо. И профдеформация у нас соответствующая части компилятора )
Не стоит бояться. Мы на стороне добра ) Системное мышление (чем бы оно нибыло развито) — это, на мой взгляд, уже само по себе очень хорошо.
… но наши дети точно будут уже совсем другими.
«Язык определяет сознание». (и к этому, до кучи, ещё фильм «Прибытие»).Если изучать языкознание не по фильмам, то внезапно всё оказывается совсем не так.
Вот тут лингвист кратко, но достаточно понятно разъясняет этот вопрос
Простого, неподготовленного человека.
Как показывает практика, простой, неподготовленный человек не умеет делать то, что вы описали в п. 1-3.
Думал, что ну вот теперь-то точно программирование станет доступным всем, но подумал и согласен с комментатором выше — здесь всё ещё есть декомпозиция задачи, а обычному человеку легче сказать «сделай мне Space Invaders», чем разобраться из чего состоит игра, чтобы командовать компьютеру «создай пулялку, создай пулю, назначь перемещение пулялки на стрелки, назначь перемещение пульки верх при нажатии стрелки верх и пусть она остановится на расстоянии в N пикселей...»
Так что похоже, что реально понадобится какой-нибудь ИИ или хотя бы нейросеть для типичных задач, а пока программисты будут требоваться.
Лично у меня (носителя русского языка с рождения), фраза «случилась херня» не вызывает ощущения что «херня виновата»; может, я как-то неправильно её понимаю?..
Новые языки программирования незаметно убивают нашу связь с реальностью