и переменная «а» будет иметь целочисленное значение?
Да, именно так. Точнее, переменная a будет СОДЕРЖАТЬ целочисленное значение. Сама переменная типа не имеет, это только ящик.
Изложенная там философия явно не для школьника
Это ВАШ взгляд на исключения. В рамках Python, например, исключения используют гораздо чаще, чем в статических языках. В мире C++, например, исключения используют редко, т.к. они могут сильно ударить по производительности. Python не ставит целью высокую производительность, поэтому там это неактуально.
Да, это тонкая тема. Я не думал об этом серьёзно, но вот, пожалуй, идеологически правильно отделить результаты работы функций от обработки ошибок. В этом смысле исключения правильнее, даже если их сложнее объяснить (не факт, что сложнее...) Конечно, не всегда исключения лучше, но если выбирать что-то одно для первого знакомства, я бы всё же остановился на них.
Мне кажется, вы путаете тип переменной и тип значения, которое в переменную помещается. Переменная — это просто ящик, в который вы можете помещать любые значения. Меня может интересовать тип объекта в ящике, а сам ящик меня не интересует, лишь бы в нём можно было бы хранить вещи.
Никаких исключений и кодов ошибок тут не надо. Лишние они, когда вся программа на одном экране помещается.
Это, конечно, верно. Я просто думаю об обобщённых задачах вида «написать функцию, которая вычисляет квадратный корень» или «написать функцию, которая возвращает значение a / b». Вот их с кодами возврата написать красиво трудно, и, скорее всего, это будет довольно дурной стиль, которому бы я детей учить не хотел.
Если через весь курс вести идею о том, что нужно выдавать адекватные сообщения об ошибке даже при неадекватных данных, то исключения хорошо заходят сразу после того, как объясняешь методы.
Вот смотрите: мы тут обсуждаем вообще самых начинающих школьников, которые ещё почти ничего не умеют. Я не думаю, что для них код возврата «нагляднее» исключения. Исключение — это код вида «что-то пошло не так, мы это обрабатываем вот здесь». Я думаю, вполне наглядно. Вы же говорите сразу о том, чтобы «через весь курс вести идею...» — ну так если люди привыкли к кодам ошибок, конечно, для них исключения непривычны.
Я в данном случае опять-таки сошлюсь на опыт Python, где исключение считается стандартным способом реагировать на любую ошибку, даже такую, которая в большинстве других языков ошибкой бы не считалась. То есть мне самому (как человеку с классическим образованием) стандартная модель тоже привычнее, но я не хочу путать простоту и привычность. Ситуация, при которой функция «квадратный корень» возвращает какой-то «код ошибки» нелогична и не согласуется с предыдущим опытом. Напротив, попытались взять корень отрицательного числа, пришла учительница и сказала, что этого делать нельзя — это как раз модель выбрасывания исключения, когда работа над ошибкой происходит совсем в другом месте.
Ну а то, что C# или WinAPI так не поступает — это как раз следствие «классического» подхода, но мы же тут рассуждаем о логичности и наглядности, а не о том, что по факту чаще используется в реальных библиотеках.
В Python не надо писать int (и вообще никакого типа не надо), в C++ можно написать auto.
Честно говоря, вы прыгаете с языка на язык, поэтому мне трудно комментировать детально. Если мы обсуждаем динамические языки, там одна логика, если статические — другая. Мы вообще обсуждали, где лучше объявлять переменные. Если бы я знал, что речь зайдёт о типе, не написал бы «int a;» Вот считайте, что написал «auto a». А почему нужно ключевое слово «auto» в C++ и не нужно в Python — это тоже очень легко объяснить, в том числе и школьнику.
Обработка исключений — не самая простая для школьника тема.
Обоснуйте, сошлитесь на опыт. Исключения гораздо сложнее в языках типа C++, т.к. там ещё возникает задача управления ресурсами. В Python всё проще (как и в Visual Basic, например).
Вы так рассуждаете исключительно потому, что у вас голова «заточена» под языки со статической типизацией. Можно рассуждать об отличиях Паскаля от C или Java, но если вы хотите перепрыгнуть в динамический мир, там совсем иная логика.
Откуда вообще берётся понятие о типе переменной? Это достаточно технарская штука, которая мало соотносится с реальными алгоритмическими нуждами, да и просто с обыденным опытом. В динамическом языке переменная — это просто ящик. У ящика не может быть типа. Тип может быть только у содержимого. В Python вы можете класть что угодно в любой ящик, а если вам интересно, каков тип у хранимого значения — да, это можно сделать.
Таким образом, ничего запутанного тут нет: как раз динамические языки ведут себя абсолютно логично и соответственно нашему повседневному опыту. Как раз к логике статических языков надо привыкать. Заметьте, что ваши ожидания (нельзя присвоить, преобразование) — это чисто технарские ожидания, которыми вас явным образом обучили.
Да, создаётся. Ну, будет присвоено новое значение. Но это же не относится к вопросу «где объявлять», тут вы говорите о том, что у переменной нет строго сопоставленного типа. Это так.
Хотя в данном контексте разговора лучше сравнивать со статическими языками типа C++, в динамических вообще многое по-другому устроено. Но в данном случае не вижу проблем.
Кто сказал? Меня оба этих варианта очень даже беспокоят! Во-первых, как уже упомянуто, иногда переменную без инциализации создать нельзя вообще (нет конструктора по умолчанию). Во-вторых, эта конструкция не позволяет мне выразить ровно то, что я хочу. Я хочу сказать: «пусть А равно xyz», а меня язык заставляет сказать «пусть А равно нулю… а теперь A равно xyz».
Ровно поэтому хороший в моём понимании язык не заставляет объявлять переменную до того, как в неё будут записаны данные из файла, и результат работы функции в переменной тоже не хранит.
Повторюсь, я не возьмусь спорить. Есть люди, которые утверждают, что начинать учиться программировать вообще надо с функциональных языков, т.к. они правильно развивают мозг (!) А там синтаксис ещё покруче. Опять же, мой опыт начала с нуля показал, что можно уйти от номеров строк, хотя это ну настолько краеугольный камень всех Бейсиков восьмидесятых, что вообще было странно. как без них. Как же без GO TO, как же без READ...DATA.
Я правильно понял, что для наколенных поделок и одноразовых программ Питон наиболее удобен?
Я не знаю, что такое «по факту», по факту вы не можете обратиться к переменной до того, как она объявлена, так что она нигде заранее не «объявится». (Если мы не обсуждаем представление в машинном коде, где переменная в принципе может уйти вообще, т.к. её оптимизатор прибьёт за ненадобностью).
Я говорю о конкретной проблеме: вам приходится при объявлении переменных врать об их наполнении. А иногда это вообще невозможно (напр., если у вас нет конструктора без аргументов, то и присвоить переменной ничего разумного нельзя).
Ну вот я повторюсь, не сочтите за труд бегло посмотреть мои ссылки: ваша точка зрения крайне непопулярна и рассматривается как плохая практика почти единогласно. Даже дискуссии особенной нет.
Одну из важных технических причин я уже упоминал: переменной не всегда можно присвоить нормальное разумное значение в начале функции. Вы вот ссылались на театр: ну вот там сразу пишут, что такой-то играет роль такого-то. А тут получается «var a: Integer;», а чему оно равно — написать ещё нельзя. Семантический пробел.
Не знаю. Ну вот честно. Может, вы и правы. Мне скорее кажется, что это довольно мелкая деталь. Для меня, например, такая штука, как нумерация строк в Бейсике, казалась абсолютно неотъемлемой частью программы. Однако практика показала, что мозг достаточно гибок :)
Это слишком большой риск. Система образования должна выстраиваться на многие годы вперёд, и «завязывать» её на конкретную версию конкретного софта нельзя. Даже для обычной фирмы это плохая практика, а тут речь идёт о куда более широкой проблеме. Да и непонятно, ради чего всё это, если есть очевидные альтернативы.
Так в том и дело! Мы же живём не в «его времена», правда? Во всей дискуссии этой ветке меня больше всего удивляет произвольность критериев «простоты» и «сложности», которые поразительным образом совпадают со взглядами восьмидесятых годов.
В моём ментальном мире ассоциативный массив — это просто и понятно ребёнку. Набор пар вида «ключ-значение». Это кукла Маши, а это кукла Даши. Это куда понятнее и проще, чем «первая кукла», «вторая кукла» с нумерованными ящичками.
При этом когда «старый» Паскаль проваливается в сложности, никого это здесь не беспокоит. Например, ратуют за реализацию балансировки деревьев. Окей, но это означает динамическое выделение памяти, верно? Первое, чему учат школьника про память — это тому, что память представляет собой линейный блок. А тут говорят, что есть «куча», из которой можно брать что угодно и возвращать как угодно. Это же в голове не укладывается (по крайней мере, у меня в старшей школе был настоящий вывих мозга, когда мы это изучали). Ну а что, не объяснять же все сложные детали. Взяли память, отдали память, всего-то.
Я всё-таки за то, чтобы начало и конец блока обозначались явно. Как в Паскале, как в Си, — на худой конец, как в Бейсике.
Я тоже. Но ей-богу, этой проблеме Питона уделено неоправданно много времени. Это ещё один спор вида «tabs vs spaces» или «фигурную скобку открываем на строке с именем функции или на следующей».
Это интуитивно понятное правило. Аналогично, театральные пьесы начинаются списком действующих лиц, а кулинарные рецепты — списком необходимых продуктов.
Вообще мне странны такие аналогии. Честно говоря, мне казалось, что уже повсеместно давно определено, что переменные должны объявляться как можно ближе к контексту. Даже не знаю, где мне найти пример развёрнутой аргументации, потому что это абсолютно устоявшееся представление, common knowledge: раз, два, три, четыре.
Разумеется, можно сказать, что все эти люди слабо разбираются в программировании (в отличие от), но просто надо понимать, что ваша точка зрения крайне непопулярна.
Это ВАШ взгляд на исключения. В рамках Python, например, исключения используют гораздо чаще, чем в статических языках. В мире C++, например, исключения используют редко, т.к. они могут сильно ударить по производительности. Python не ставит целью высокую производительность, поэтому там это неактуально.
Это, конечно, верно. Я просто думаю об обобщённых задачах вида «написать функцию, которая вычисляет квадратный корень» или «написать функцию, которая возвращает значение a / b». Вот их с кодами возврата написать красиво трудно, и, скорее всего, это будет довольно дурной стиль, которому бы я детей учить не хотел.
Вот смотрите: мы тут обсуждаем вообще самых начинающих школьников, которые ещё почти ничего не умеют. Я не думаю, что для них код возврата «нагляднее» исключения. Исключение — это код вида «что-то пошло не так, мы это обрабатываем вот здесь». Я думаю, вполне наглядно. Вы же говорите сразу о том, чтобы «через весь курс вести идею...» — ну так если люди привыкли к кодам ошибок, конечно, для них исключения непривычны.
Я в данном случае опять-таки сошлюсь на опыт Python, где исключение считается стандартным способом реагировать на любую ошибку, даже такую, которая в большинстве других языков ошибкой бы не считалась. То есть мне самому (как человеку с классическим образованием) стандартная модель тоже привычнее, но я не хочу путать простоту и привычность. Ситуация, при которой функция «квадратный корень» возвращает какой-то «код ошибки» нелогична и не согласуется с предыдущим опытом. Напротив, попытались взять корень отрицательного числа, пришла учительница и сказала, что этого делать нельзя — это как раз модель выбрасывания исключения, когда работа над ошибкой происходит совсем в другом месте.
Ну а то, что C# или WinAPI так не поступает — это как раз следствие «классического» подхода, но мы же тут рассуждаем о логичности и наглядности, а не о том, что по факту чаще используется в реальных библиотеках.
Честно говоря, вы прыгаете с языка на язык, поэтому мне трудно комментировать детально. Если мы обсуждаем динамические языки, там одна логика, если статические — другая. Мы вообще обсуждали, где лучше объявлять переменные. Если бы я знал, что речь зайдёт о типе, не написал бы «int a;» Вот считайте, что написал «auto a». А почему нужно ключевое слово «auto» в C++ и не нужно в Python — это тоже очень легко объяснить, в том числе и школьнику.
Обоснуйте, сошлитесь на опыт. Исключения гораздо сложнее в языках типа C++, т.к. там ещё возникает задача управления ресурсами. В Python всё проще (как и в Visual Basic, например).
Откуда вообще берётся понятие о типе переменной? Это достаточно технарская штука, которая мало соотносится с реальными алгоритмическими нуждами, да и просто с обыденным опытом. В динамическом языке переменная — это просто ящик. У ящика не может быть типа. Тип может быть только у содержимого. В Python вы можете класть что угодно в любой ящик, а если вам интересно, каков тип у хранимого значения — да, это можно сделать.
Таким образом, ничего запутанного тут нет: как раз динамические языки ведут себя абсолютно логично и соответственно нашему повседневному опыту. Как раз к логике статических языков надо привыкать. Заметьте, что ваши ожидания (нельзя присвоить, преобразование) — это чисто технарские ожидания, которыми вас явным образом обучили.
Visual Studio точно умеет.
int a = readInt(f);
А если файл кончился, то просто выбрасывается исключение.
Хотя в данном контексте разговора лучше сравнивать со статическими языками типа C++, в динамических вообще многое по-другому устроено. Но в данном случае не вижу проблем.
Ровно поэтому хороший в моём понимании язык не заставляет объявлять переменную до того, как в неё будут записаны данные из файла, и результат работы функции в переменной тоже не хранит.
Не только для них, но думаю, что для них точно.
Я говорю о конкретной проблеме: вам приходится при объявлении переменных врать об их наполнении. А иногда это вообще невозможно (напр., если у вас нет конструктора без аргументов, то и присвоить переменной ничего разумного нельзя).
Одну из важных технических причин я уже упоминал: переменной не всегда можно присвоить нормальное разумное значение в начале функции. Вы вот ссылались на театр: ну вот там сразу пишут, что такой-то играет роль такого-то. А тут получается «var a: Integer;», а чему оно равно — написать ещё нельзя. Семантический пробел.
Так в том и дело! Мы же живём не в «его времена», правда? Во всей дискуссии этой ветке меня больше всего удивляет произвольность критериев «простоты» и «сложности», которые поразительным образом совпадают со взглядами восьмидесятых годов.
В моём ментальном мире ассоциативный массив — это просто и понятно ребёнку. Набор пар вида «ключ-значение». Это кукла Маши, а это кукла Даши. Это куда понятнее и проще, чем «первая кукла», «вторая кукла» с нумерованными ящичками.
При этом когда «старый» Паскаль проваливается в сложности, никого это здесь не беспокоит. Например, ратуют за реализацию балансировки деревьев. Окей, но это означает динамическое выделение памяти, верно? Первое, чему учат школьника про память — это тому, что память представляет собой линейный блок. А тут говорят, что есть «куча», из которой можно брать что угодно и возвращать как угодно. Это же в голове не укладывается (по крайней мере, у меня в старшей школе был настоящий вывих мозга, когда мы это изучали). Ну а что, не объяснять же все сложные детали. Взяли память, отдали память, всего-то.
Вообще мне странны такие аналогии. Честно говоря, мне казалось, что уже повсеместно давно определено, что переменные должны объявляться как можно ближе к контексту. Даже не знаю, где мне найти пример развёрнутой аргументации, потому что это абсолютно устоявшееся представление, common knowledge: раз, два, три, четыре.
Разумеется, можно сказать, что все эти люди слабо разбираются в программировании (в отличие от), но просто надо понимать, что ваша точка зрения крайне непопулярна.