Здравствуйте, AlexRK, Вы писали:
ARK>Здравствуйте, netch80, Вы писали:
N>>Пусть по одной ветке тип получает значение complex<float>, по другой double, по третьей — string. N>>Какой тип будем дедуцировать?
ARK>Вопрос не ко мне, но очевидно же, что compile error.
То есть надо все ветки привести явно к одному типу значения (или к совместимым с минимальными различиями).
Ну вот после этого и видно, что явное задание типа целевой переменной — проще и эффективнее, как минимум в заметной части случаев.
Здравствуйте, kov_serg, Вы писали:
_>Я же об этом и говорю должно быть с auto и выглядеть так: _> CGBuilderTy &Builder = CGF.Builder; _> auto Eq, And, Or, LPtr, RPtr, PtrEq, Zero, EqZero LAdj, RAdj, AdjEq, One, OrAdj, OrAdjAnd1, OrAdjAnd1EqZero, Result;
Это уже карго-культ какой-то. Объявления должны быть потому, что должны быть.
Здравствуйте, kov_serg, Вы писали:
M>>А в начале появляется шум. Даже не шум, а куча г. _>Это не шум это объявление ограничений. В рамках которых описывается дальнейшая программа.
Это даже не шум, это просто мусор.
M>>Кстати, про RAII слышал? _>Если вам говорили что RAII вершина управления ресурсами то от вас многое утаили.
Лучше только Rust с borrow checker'ом.
_>Незнаю но многие упорно хотят видеть где переменная впервые использеутся. С этим спокойно спраиться IDE просто подсвечивая имя под курсором по всему тексту.
Ну и зачем тогда объявления в начале?
M>>Опять же. Определение переменной по месту экономит стек. Сейчас это не большая проблема на современных компиляторах, но раньше с этим было хуже _>Вы серьёзно считаете что компилятор не способен определить когда и где создавать переменные.
Когда-то так и было. Первые компиляторы Паскаля были однопроходными, что и требовало объявлять переменные в начале. В результате поклонники секты Свидетелей Вирта эту багофичу вознесли в ранг Евангелия.
Здравствуйте, Mr.Delphist, Вы писали:
C>>Не подходит. После Паскаля приходится потом долго вправлять моск в правильную сторону. MD>Простите, а что за "неправильная" такая сторона у Паскаля?
Куча вредных идей типа "выход из функции только один", непонимание системных концепций (указатели) и в то же время незнакомство с более высокоуровневыми понятиями (векторы, хэш-карты, объекты, управление зависимостями, ...)
В общем, идеальный язык для выполнения программ по подсчёту количества простых чисел в массиве, и ничего более.
C>>В "зарубежных курсах" Паскаль давно похоронили. В качестве первого языка чаще всего берут Питон, затем С/С++/Java. MD>Но берут-то почему?
Кого где берут?
Здравствуйте, scf, Вы писали:
scf>НО — для начального обучениния избыток парадигм вреден. К примеру, вот что входило в мою школьную программу: scf>- понятие алгоритма scf>- операторы, переменные, типы, условия, циклы scf>- процедуры, функции scf>- структуры данных: массивы, строки, списки, деревья
Вот тут начинаются проблемы со списков. В школьной программе их нет.
scf>- алгоритмы: поиск элементов в масивах, обход списков, обход деревьев, двоичный поиск, решение уравнений методом деления пополам
И на йух это не надо.
scf>- ascii графика (типа распечатать таблицу умножения) scf>- цветная графика — нарисовать пейзаж, анимация, графики, графики трехмерных функций по алгоритму художника
В вариане TurboPascal — это нормально не получится.
scf>Этого списка достаточно, чтобы загрузить школьников до 11 класса включительно. Надеюсь, никто не будет спорить, что а) всё перечисленное нужно и б) никакие парадигмы и библиотеки для этого не нужны.
Ещё их можно загрузить уроками по строевому шагу. Речь идёт не о "загрузить", а об обучении.
scf>- программы не требуют ни `public static void main`, ни хитрого кода инициализации консоли/окна/графики scf>- простой удобный интерактивный отладчик, мнгновенная компиляция
Python.
scf>- строгий структурированный синтаксис на английском языке, без лишних сокращений типа фигурных скобок и навязанных идиом типа значимых отступов
Синтаксис не строгий.
scf>- строгая типизация
Не строгая.
scf>- достаточно низкоуровневый, чтобы рассказывать школьникам про байты, биты, непрерывные многомерные массивы и организацию памяти
А зачем?
Здравствуйте, netch80, Вы писали:
C>>В С есть удобный разыменователь: ptr->x, в Паскале его нет. N>C: obj.x, ptr->x N>Pascal: obj.x, ptr^.x N>тебя "^." настолько смущает синтаксически? Форма стрелки направо критична?
Да, так как разыменователь отличается от всего остального в Паскале.
C>>Да, но только это всё скрыто магией. Совершенно непонятно причём там указатели. N>Как это зачем? Указатель на выделенную динамическую область. Или ты о чём?
Динамические массивы в Паскале работают через setlength. Не очень понятно как.
N>>>Фокус в виде a[i] == i[a] == *(a+i) там не одобряют в чистом виде. Но в борландовской линии, по-моему, писать явно (a+i)^ было можно и нужно, если тебе в явном виде передали unsafe-указатель (хоть он так и не назывался). C>>Ну вот потому С как раз очень помогает понять указатели, в отличие от Паскаля. N>Я бы не сказал, что возможность a[i] === i[a] тут как-то существенно помогает
Это как раз неважно. Важно то, что в С очень очевидная связь между массивами и памятью. Массив — это просто набор элементов, которые идут один за другим. С арифметикой указателей на них, работающей очевидным образом.
C>> С точки зрения промышленного программирования с указателями в С — полная катастрофа с безопасностью, но для обучения как раз идеально. N>Не-а. Чтобы понять простую идею "указатель это адрес", это всё не нужно. N>Чтобы понять арифметику указателей — тоже. Её по любому надо явно объяснить, и этого достаточно.
Мне из личного опыта — было нужно. Я слышал и другие подобные истории.
Здравствуйте, Cyberax, Вы писали:
C>Когда-то так и было. Первые компиляторы Паскаля были однопроходными, что и требовало объявлять переменные в начале. В результате поклонники секты Свидетелей Вирта эту багофичу вознесли в ранг Евангелия.
Дело скорее не в однопроходности самой по себе, а в том, что в Паскале есть вложенные функции, и объявление переменных после них приведет не только к необходимости не однопроходного компилятора, но и логичным вопросам "что за ... ?"
Понимаю разумеется, что не будь этих вложенных функций Вирт все равно бы принудил объявлять переменные в отдельном разделе, но он точно так же принудил это делать, если бы изначально компилятор пришлось сделать не однопроходным. Хотя он все равно равно бы его сделал однопроходным
Здравствуйте, Cyberax, Вы писали:
C>А зачем?
А зачем в школе предмет — информатика? Может и не нужен но если нужен, то как минимум про байты с битами придется рассказать, про организацию памяти, в простейшем виде, с линейной адресацией наверно тоже. Можно конечно предполагать, что библиотекарше и секретарше достаточно будет знать почти человеческий SQLExcel Питон. Но он точно школьку нужен больше, чем байт с битом?
MAG>>Вот только за это Паскаль надо выкидывать и забывать как страшный сон. Только виртовские детища, емнип, на ровном месте создают из одной сужности (функция), две. Иди, попробуй объясни ее ... да хоть кому бы то ни было.
ARK>Отчего ж, не только виртовские создают из одной сущности две. Страуструповские, ричекернигановские, хейлсберговские, гослинговские детища
В каком месте в C, C++, Java и т.п. есть разделение на процедуры и функции?
ARK>- они все тоже туда же. Иди попробуй объясни, зачем в сикраше Action и Func ... да хоть кому бы то ни было. Выкинуть и забыть этот весь шлак как страшный сон!
Это скорее из-за ущербности системы типов и дизайна. Потому что сигнатура `Func` вот такая:
TResult Func<in T,out TResult>(T arg);
понятно, что нельзя иметь
out void
Но да. Лажа в какой-то мере такая же, что и function/procedure в Паскале. Другое дело, что в Паскале с ними сталкиваешься сразу, а в C# можно долго не знать ни про Action ни про Func
Здравствуйте, MamutArGud, Вы писали:
MAG>В каком месте в C, C++, Java и т.п. есть разделение на процедуры и функции?
Ну как же. Так называемый "тип" void — это вот оно и есть.
ARK>>- они все тоже туда же. Иди попробуй объясни, зачем в сикраше Action и Func ... да хоть кому бы то ни было. Выкинуть и забыть этот весь шлак как страшный сон! MAG>Это скорее из-за ущербности системы типов и дизайна.
Безусловно. Но по факту это и есть деление на процедуры и функции.
MAG>понятно, что нельзя иметь
out void
Да много чего нельзя. Переменную типа void нельзя объявить. Нельзя вот так сделать (слегка обобщенный псевдокод):
function Combine<T...>(a: function() T..., b: function(T...)) // принимает две функции, которые можно скомбинировать - вторая принимает то же, что возвращает первая
{
var result: T...; // кортеж! может быть одна переменная, несколько переменных или НОЛЬ переменных!
result := a();
b(result);
}
function A1() result: int // ничего не принимает, возвращает целое число
{
Print("A1 ");
return 33;
}
function B1(param: int) // принимает целое число, ничего не возвращает
{
Print("B1 ");
Print(param);
}
function A2() // ничего не принимает и не возвращает (как будто принимает и возвращает "ничего")
{
Print("A2 ");
}
function B2() // ничего не принимает и не возвращает (как будто принимает и возвращает "ничего")
{
Print("B2 ");
}
function Main()
{
Combine(A1, B1); // печатает "A1 B1 33"
Combine(A2, B2); // И ЭТО ТОЖЕ РАБОТАЕТ!!! печатает "A2 B2 "
}
Вот такого — нету, а это и есть самое главное. "void" — это не тип, а заглушка. Это и есть "procedure", только записывается короче.
MAG>Но да. Лажа в какой-то мере такая же, что и function/procedure в Паскале. Другое дело, что в Паскале с ними сталкиваешься сразу, а в C# можно долго не знать ни про Action ни про Func
Так и с void и его особенностями тоже сразу сталкиваешься.
Здравствуйте, netch80, Вы писали:
S>>Иметь и использовать типы данных — это прекрасно. Не прекрасно засирать этим голову школьникам (и, кстати, школьницам) в обязательном порядке.
N>Что именно засирательного тут я предложил?
Хештаблицы и прочие структуры данных сложнее, чем переменная в смысле integer или double.
N>Серьёзно? Даже массивы — лишнее?
Да.
S>> Сумму чётных элементов последователности, или предел последовательности, или что-то такое.
N>Ну если в языке будет абстрактная последовательность, то он станет чем-то вроде Хаскеля.
Никаких абстрактных последовательностей, а просто циклом вычислить сумму элементов ряда, типа a(n)=1/n
N>А это и не обязательно на таком уровне давать. Достаточно принципа "вот ключи, а вот значения при них".
Так же не будет. Обязательно потащится всякая алгоритмическая сложность и прочее.
Здравствуйте, netch80, Вы писали:
N>OK, определились. Но всё равно в этом случае будет заметная часть специфических "дети, это невозможно понять, это надо запомнить".
N>- а условия i <= 9 и i < 10 это одно и то же? (в спокойной обстановке они сами это скажут и посмеются, что кто-то не понимает, но когда сам начинаешь писать, нервы всё сбивают)
от 0 до 9 — это включая 9, или нет? ) Самое смешное, что семантически "до" допускает гораздо более неоднозначную трактовку, чем <, или <=. И как раз в Паскале это надо "просто запомнить", так как понять невозможно.
На самом деле в любом языке есть куча вещей, которые понять либо невозможно и надо тупо запоминать, либо можно, но только уже постигнув дзен этого языка. Но проблема в том, что сейчас подавляющее большинство языков С-подобные. Т.е. абстрактному студенту сперва надо запомнить специфику синтаксиса одного языка, а потом оперативно переключаться на другой. И выбор, к сожалению, не выглядит как: "учить на Паскале", или "учить на С-подобном языке". Он выглядит так: "Учить на С-подобном языке сразу" или "Учить на Паскале, а потом тут же переучивать на С-подобное".
Да, глупо отрицать, что Паскаль лучше подходит для обучения (он, в конце концов, для этого и задумывался). Проблема в том, что пара-тройка проблемных мест С-подобного синтаксиса, с которыми может столкнуться новичок, не перекрывают необходимости учить заново новый язык, практически полностью пуская на свалку знания по старому.
"Пишите код так, как будто сопровождать его будет склонный к насилию психопат, который знает, где вы живете". (с) Макконнелл, "Совершенный код".
Здравствуйте, Sharowarsheg, Вы писали:
S>>>Иметь и использовать типы данных — это прекрасно. Не прекрасно засирать этим голову школьникам (и, кстати, школьницам) в обязательном порядке. N>>Что именно засирательного тут я предложил? S>Хештаблицы и прочие структуры данных сложнее, чем переменная в смысле integer или double.
Зато это принципиальная возможность, которая всегда будет использована на практике и полезна для задач.
N>>Серьёзно? Даже массивы — лишнее? S>Да.
И что тогда останется от всей тематики? Будет ли там на чём вообще делать реальное обучение?
S>>> Сумму чётных элементов последователности, или предел последовательности, или что-то такое. N>>Ну если в языке будет абстрактная последовательность, то он станет чем-то вроде Хаскеля. S>Никаких абстрактных последовательностей, а просто циклом вычислить сумму элементов ряда, типа a(n)=1/n
Вы намеренно дали пример на расходящийся ряд?
N>>А это и не обязательно на таком уровне давать. Достаточно принципа "вот ключи, а вот значения при них". S>Так же не будет. Обязательно потащится всякая алгоритмическая сложность и прочее.
Почему? Это как раз можно на базовом уровне не вспоминать. Только на первом из продвинутых.
Здравствуйте, Александр Кузнецов, Вы писали:
N>>OK, определились. Но всё равно в этом случае будет заметная часть специфических "дети, это невозможно понять, это надо запомнить". N>>- а условия i <= 9 и i < 10 это одно и то же? (в спокойной обстановке они сами это скажут и посмеются, что кто-то не понимает, но когда сам начинаешь писать, нервы всё сбивают) АК>от 0 до 9 — это включая 9, или нет? ) Самое смешное, что семантически "до" допускает гораздо более неоднозначную трактовку, чем <, или <=. И как раз в Паскале это надо "просто запомнить", так как понять невозможно.
Ну потому и есть "до" "включая" и "не включая".
АК>На самом деле в любом языке есть куча вещей, которые понять либо невозможно и надо тупо запоминать, либо можно, но только уже постигнув дзен этого языка. Но проблема в том, что сейчас подавляющее большинство языков С-подобные. Т.е. абстрактному студенту сперва надо запомнить специфику синтаксиса одного языка, а потом оперативно переключаться на другой. И выбор, к сожалению, не выглядит как: "учить на Паскале", или "учить на С-подобном языке". Он выглядит так: "Учить на С-подобном языке сразу" или "Учить на Паскале, а потом тут же переучивать на С-подобное".
Да.
АК>Да, глупо отрицать, что Паскаль лучше подходит для обучения (он, в конце концов, для этого и задумывался).
Нет. Потому что задумка оказалась кривой по куче моментов.
Но так как в IT побеждает не лучшее, а первое из того, что минимально приемлемо и раскручено, то Pascal пошёл, а обновления в виде Modula — нет, они опоздали.
AK> Проблема в том, что пара-тройка проблемных мест С-подобного синтаксиса, с которыми может столкнуться новичок, не перекрывают необходимости учить заново новый язык, практически полностью пуская на свалку знания по старому.
Здравствуйте, netch80, Вы писали:
S>>Хештаблицы и прочие структуры данных сложнее, чем переменная в смысле integer или double.
N>Зато это принципиальная возможность, которая всегда будет использована на практике и полезна для задач.
Теми, кто пойдет в хирурги, эта возможность не будет использована никогда.
N>>>Серьёзно? Даже массивы — лишнее? S>>Да.
N>И что тогда останется от всей тематики? Будет ли там на чём вообще делать реальное обучение?
Ворд-эксель, и паскаль в объёме чуть большем hello world. Даже ворд с экселем в нормальном объеме я не уверен, что можно успеть.
S>>>> Сумму чётных элементов последователности, или предел последовательности, или что-то такое. N>>>Ну если в языке будет абстрактная последовательность, то он станет чем-то вроде Хаскеля. S>>Никаких абстрактных последовательностей, а просто циклом вычислить сумму элементов ряда, типа a(n)=1/n
N>Вы намеренно дали пример на расходящийся ряд?
Да. Не будем же мы выбрасывать из школьной программы арифметическое переполнение? Или выбросить?
N>>>А это и не обязательно на таком уровне давать. Достаточно принципа "вот ключи, а вот значения при них". S>>Так же не будет. Обязательно потащится всякая алгоритмическая сложность и прочее.
N>Почему? Это как раз можно на базовом уровне не вспоминать. Только на первом из продвинутых.
Нет. Не верю я в то, что это остановится на каких-то разумных пределах. Только резать, резать, и резать.
Здравствуйте, AlexRK, Вы писали:
ARK>Здравствуйте, MamutArGud, Вы писали:
MAG>>В каком месте в C, C++, Java и т.п. есть разделение на процедуры и функции?
ARK>Ну как же. Так называемый "тип" void — это вот оно и есть.
Не так. В исходном Pascal у функции, кроме возвращаемого значения, ещё одно свойство: отсутствие побочных эффектов — нельзя присваивать ничего за пределами, нет var-параметров. Сейчас это принято называть, что функция чистая (pure).
В Turbo версии и вслед за ней во всех реальных это, насколько помню, похерили. С этого момента (и особенно с появлением var-параметров у функций) и получилось, что procedure f === void f(), а function f: type === type f, и больше принципиальной разницы нет.
Но вначале оно было жёстко принципиальное.
ARK>>>- они все тоже туда же. Иди попробуй объясни, зачем в сикраше Action и Func ... да хоть кому бы то ни было. Выкинуть и забыть этот весь шлак как страшный сон! MAG>>Это скорее из-за ущербности системы типов и дизайна. ARK>Безусловно. Но по факту это и есть деление на процедуры и функции.
В C/C++, по описанному, его никогда не было.
Сейчас вроде бы где-то можно объявить, что функция является pure, как полезный хинт анализатору (где-то отклонение — он пожалуется).
ARK>Вот такого — нету, а это и есть самое главное. "void" — это не тип, а заглушка. Это и есть "procedure", только записывается короче.
1. См. выше.
2. Если уже говорить про подобные возможности, то надо вспоминать и возврат не одного значения из функции, а многих. В C++, считаем, есть (хоть и криво — ни один ABI это ещё не позволяет напрямую; std::pair, std::tuple приводят к возврату структуры через скрытый параметр — указатель), и можно использовать (да хоть монады на нём строить). В Паскале нет и не ожидается.
Здравствуйте, Cyberax, Вы писали:
C>>>В С есть удобный разыменователь: ptr->x, в Паскале его нет. N>>C: obj.x, ptr->x N>>Pascal: obj.x, ptr^.x N>>тебя "^." настолько смущает синтаксически? Форма стрелки направо критична? C>Да, так как разыменователь отличается от всего остального в Паскале.
Постфиксностью? И что в этом плохого?
C>>>Да, но только это всё скрыто магией. Совершенно непонятно причём там указатели. N>>Как это зачем? Указатель на выделенную динамическую область. Или ты о чём? C>Динамические массивы в Паскале работают через setlength. Не очень понятно как.
std::vector::reserve и аналоги. Что непонятного-то?
Ну да, реализовано в языке, а не библиотеке.
N>>>>Фокус в виде a[i] == i[a] == *(a+i) там не одобряют в чистом виде. Но в борландовской линии, по-моему, писать явно (a+i)^ было можно и нужно, если тебе в явном виде передали unsafe-указатель (хоть он так и не назывался). C>>>Ну вот потому С как раз очень помогает понять указатели, в отличие от Паскаля. N>>Я бы не сказал, что возможность a[i] === i[a] тут как-то существенно помогает C>Это как раз неважно. Важно то, что в С очень очевидная связь между массивами и памятью. Массив — это просто набор элементов, которые идут один за другим. С арифметикой указателей на них, работающей очевидным образом.
Так тут то же самое. Только не всегда дают сам указатель.
C>>> С точки зрения промышленного программирования с указателями в С — полная катастрофа с безопасностью, но для обучения как раз идеально. N>>Не-а. Чтобы понять простую идею "указатель это адрес", это всё не нужно. N>>Чтобы понять арифметику указателей — тоже. Её по любому надо явно объяснить, и этого достаточно. C>Мне из личного опыта — было нужно. Я слышал и другие подобные истории.
Здравствуйте, netch80, Вы писали:
N>Не так. В исходном Pascal у функции, кроме возвращаемого значения, ещё одно свойство: отсутствие побочных эффектов — нельзя присваивать ничего за пределами, нет var-параметров. Сейчас это принято называть, что функция чистая (pure). N>В Turbo версии и вслед за ней во всех реальных это, насколько помню, похерили. С этого момента (и особенно с появлением var-параметров у функций) и получилось, что procedure f === void f(), а function f: type === type f, и больше принципиальной разницы нет. N>Но вначале оно было жёстко принципиальное.
Это тоже верно, но я сейчас говорю про текущую ситуацию — с чистотой функций никто не заморачивается (очень зря), но деление все равно есть из-за псевдотипа void, не позволяющего работать однотипно с произвольными функциями.
N>2. Если уже говорить про подобные возможности, то надо вспоминать и возврат не одного значения из функции, а многих. В C++, считаем, есть (хоть и криво — ни один ABI это ещё не позволяет напрямую; std::pair, std::tuple приводят к возврату структуры через скрытый параметр — указатель), и можно использовать (да хоть монады на нём строить). В Паскале нет и не ожидается.
Я не большой знаток C++ , но не помню, что в нем это "есть". Чтобы использовать пары и туплы для комбинирования, надо, чтобы их не только возвращали, но и принимали входными параметрами, разве нет? Или можно НАПРЯМУЮ сунуть тупл (2, "test") в функцию "void Func(int a, string b)", т.е. вызвать как "Func(myTuple);"? Если нельзя, то все эти пары с туплами нельзя считать за что-то особенное. Такое и в паскале есть — возвращай да принимай любые структуры, строй из них монады.
N>Не так. В исходном Pascal у функции, кроме возвращаемого значения, ещё одно свойство: отсутствие побочных эффектов — нельзя присваивать ничего за пределами, нет var-параметров. Сейчас это принято называть, что функция чистая (pure).
Что-то сомневаюсь, паскалевские и функции и процедуры могли быть вложенными, а им доступны все переменные описанные "выше" и если мне не изменяет мой склероз никаких ограничений на из изменение в Паскале нет.
N>2. Если уже говорить про подобные возможности, то надо вспоминать и возврат не одного значения из функции, а многих. В C++, считаем, есть (хоть и криво — ни один ABI это ещё не позволяет напрямую; std::pair, std::tuple приводят к возврату структуры через скрытый параметр — указатель), и можно использовать (да хоть монады на нём строить). В Паскале нет и не ожидается.
Возвращай запись (record) или их нельзя было возвращать? вот это точно не помню.