LINUX.ORG.RU

ЛОР, помоги выбрать ЯП для обучения

 , , , ,


1

3

Часто слышу просьбу научить программированию. Хотя пока я этим не занимаюсь, мне стало интересно, какой ЯП выбрать для введения в программирование.

Вот к каким мыслям я пришёл:

Язык должен наиболее чисто демонстрировать самые основы написания кода.

Не Си и не современные коммерческие языки (Java, C#, Go). Си, хотя примитивный в основе, усложнён из-за окружения, в котором используется. Современные коммерческие языки были созданы для решения проблем индустрии. Проблема общая: я хочу преподавать материал по мере нарастания сложности. Если в языке неизбежно приходится использовать классы или printf, то это затруднит объяснение (не хотелось бы слишком часто говорить «потом узнаешь для чего это нужно»), напугает студента (ему придётся писать код, используя возможности, которые он плохо понимает), создаст неправильное восприятие основ (как будто printf — это какая-то важная часть компьютера или ОС).

В целом, я хочу постепенно наращивать сложность и, если задачу можно решить более простым методом, то выбрать этот метод.

Языки, между которыми я выбираю: Pascal и Python.

Pascal устарел и денег не принесёт (обидно), но это и не является основной целью. Целью является программирование, а не современное окружение.

В частности, я не собираюсь задрачивать студента на Delphi или любой «продвинутый» диалект языка. Это противоречит цели. Я рассчитываю на то, что после должной тренировки “bare bones” нужно перейти на современный язык и это будет легко.

Важно упомянуть, что спека языка Oberon (Виртовский язык, тот же Паскаль, только упрощённый и доработанный) составляет 17 страниц.

Питон мне сложнее оценить, потому что я избегал работы с ним.

Если ограничиться императивным подмножеством, без ассоциативных массивов, классов и мета-классов, list comprehensions, HOF, исключений, то выглядит как альтернатива Паскалю. Хотя меня беспокоит динамическая типизация. Типы — очень важная вещь, хотелось бы чтобы язык помог это донести, а не быть типа «ну да, это важно, но ты забей».

Это все мои мысли.

Что касается практики, то я имел несчастье наблюдать как человек впервые знакомился с программированием, изучая Java на javarush. На это было больно смотреть.

Edit: дальнейшие пояснения по теме:

  • Подробнее про то, почему я считаю, что изучение основ и Паскаль хорошо сочетаются: 1
  • Почему не Си и не ассемблер: 1 2
  • Почему Паскаль: 1 2
  • Почему не Питон: 1
  • Целевая аудитория: 1
  • Почему такая размытая аудитория: 1 2
  • Про важность иерархии: 1


Последнее исправление: kaldeon (всего исправлений: 10)

Странный вопрос. Если ученик школьник, то Python, сейчас все задачи в ЕГЭ по программированию для школьников решаются и объясняются с помощью Python (см. https://kompege.ru/task) не редко используются даже и его библиотеки. Если ученик не учащийся школы и хочет чтобы ты был его учителем, то тот который лучше всего знаешь ты (ну кроме pascal, delphi и т.п. - причина сильно устарели) У меня был ученик - студент вуза там изучали c#, другой просил помощи по visual c++.

fesey
()
Ответ на: комментарий от ya-betmen

однозначно один из трёх невозможно

Вполне возможно, если не быть (и, главное, не стремиться стать) погонщиком сферических коней в вакууме, множество которых заполонило этот тред.

rebforce
()
Ответ на: комментарий от CrX

А смысл всё равно ускользает…

Для меня это выглядит следующим образом. Он так шифрует свою бессмыслицу - бессмыслицей. Знает много интересных слов и хочет поделится этими интересными словами, похвастаться своей эрудицией

anonymous
()
Ответ на: комментарий от alysnix

как можно двусвязный список сделать без указателей? и не надо там списки заменять массивами. это совершенно разные структуры

Ээээ… легко?

#!/usr/bin/env python3

class Node:
    def __init__(self, next=None, prev=None, data=None):
        self.next = next
        self.prev = prev
        self.data = data

    def add(self, new):
        self.next = new
        new.prev = self


n1 = Node(data=1)
n2 = Node(data=2)
n3 = Node(data=3)

n1.add(n2)
n2.add(n3)

print('forward:')
c = n1
while c:
    print(c.data)
    c = c.next

print('backwards:')
c = n3
while c:
    print(c.data)
    c = c.prev
anonymous
()
Ответ на: комментарий от dataman

Были бы проблемы со здоровьем, это бы случалось и в других ситуациях, а ускользает он только в постах одного конкретного юзера. И, я так понимаю, я не один такой. Но находятся и те, кто понимает. Ну или думают, что понимают, или делают вид — по крайней мере какие-то диалоги в итоге получаются.

CrX ★★★★★
()
Ответ на: комментарий от CrX

иногда сам факт усилия при понимании приносит пользу усилявшему

а уж инициирующее зерно может и не быть сутью

qulinxao3 ★★
()
Ответ на: комментарий от alysnix

в пытоне кстати нет идеи. вот в с++, яве, шарпе идея есть. а пытон просто рядовой интерпретируемый язык с отступами вместо явного указания блока. что, кстати, вредно и для читабельности и понимания, где какой блок кончился в сложном коде.

И духовности, ага. А технические аргументы будут?

anonymous
()
Ответ на: комментарий от alysnix

значит в пытоне есть указатели. просто называются они ссылками, и им можно присвоить None.

Ссылки и указатели это очень разные вещи. Но не суть. Суть в том, что на питоне ты можешь показать принци работы любой структуры данных и нормально будет. И эти знания будут применимы. Дрочевание с тараканами ФП принесет много лишних усложнений, а применить эти знания будет сложно.

anonymous
()
Ответ на: комментарий от monk

там сами «поля» - ссылки, потому поле и может принимать значения разных типов. а None - ссылка на предопределенный обьект None. по сути это указатели, без возможности адресной арифметики, так по классике избавляются от указателей, и питон тут ничего нового не открыл.

но это порождает и проблемы - низкая эффективность, все на куче, активная мусоросборка и так далее.

alysnix ★★★
()
Последнее исправление: alysnix (всего исправлений: 1)
Ответ на: комментарий от CrX

Переменные в третьем классе есть.

Неизвестные

vM ★★
()
Ответ на: комментарий от alysnix

по сути это указатели, без возможности адресной арифметики, так по классике избавляются от указателей, и питон тут ничего нового не открыл.

А кто-то утверждал что питон что-то новое открыл? Ссылки на объекты есть вообще везде, где есть объекты.

anonymous
()
Ответ на: комментарий от CrX

русский вроде с детства знаю в качестве родного, то есть должен всё понимать.

Есть язык, а есть индивидуальная речь.

vM ★★
()
Ответ на: комментарий от anonymous

проблема пытона в бестиповости ссылки и что она может указывать куда угодно. все выяснение типа и выбор операции осуществляется в рантайме (ну в общем случае), и чтобы сложить два числе одной командой процессора, надо перемолоть кучу кода, выясняя, каким же кодом все это сложить.

в языках с типизацией, все просто складывается одной командой и возможны наворочанные статические оптимизации кода.

alysnix ★★★
()
Ответ на: комментарий от monk

В питоне есть структуры. И поле может принимать значения разных типов. Указатели там излишни.

Структуры передаются по значению, через копирование?

ya-betmen ★★★★★
()
Ответ на: комментарий от anonymous

Там написано что A это результат сложения B и C.

Осталось разобраться что такое результат сложения в данном случае. А то, есть подозрение, третьеклассник может понять это совершенно неправильно. И не понять этого. А это ещё хуже, чем сразу совсем не понять.

ugoday ★★★★★
()
Ответ на: комментарий от rebforce

Вполне возможно

Я даже таких встречал.

- почему ты написал тут статик?

- если я не напишу статик, то код не копилируется.

ya-betmen ★★★★★
()
Ответ на: комментарий от alysnix

как можно двусвязный список сделать без указателей? и не надо там списки заменять массивами. это совершенно разные структуры

Ну нельзя же быть таким зашоренным. Двусвязный список — это всё, что реализует интерфейс двусвязного списка. А какие там массивы указателей в реализации используются — дело десятое.

ugoday ★★★★★
()
Ответ на: комментарий от CrX

Переменные в третьем классе есть. И даже смысл по сути тот же.

Т.е. теперь в третьем классе переменные обладают типом и могут менять свои значения во времени? Чудны дела твои, Господи!

ugoday ★★★★★
()
Ответ на: комментарий от alysnix

проблема пытона в бестиповости ссылки и что она может указывать куда угодно. все выяснение типа и выбор операции осуществляется в рантайме (ну в общем случае), и чтобы сложить два числе одной командой процессора, надо перемолоть кучу кода, выясняя, каким же кодом все это сложить.

Для обучения вообще насрать. Надо чтобы была видна разница между O(1) и O(N), например. Она будет видна. Что ещё надо-то?

в языках с типизацией, все просто складывается одной командой и возможны наворочанные статические оптимизации кода.

Это все только мешается, когда ты учишься код писать. Питон (perl, php, whatever), позволяет творить любую дичь и любоваться происходящим. Скорость тут ваще не при делах.

anonymous
()
Ответ на: комментарий от ugoday

Т.е. теперь в третьем классе переменные обладают типом и могут менять свои значения во времени? Чудны дела твои, Господи!

Ты опять усложняешь на ровном месте. Этот код понятен любому человеку, знакомому с простейшей математикой. Про третий класс ввернули для красного словца, но нельзя исключать, что таки да, дети тоже поймут о чем речь. Дети вообще хорошо ищут паттерны.

anonymous
()
Ответ на: комментарий от alysnix

проблема пытона в бестиповости ссылки и что она может указывать куда угодно. все выяснение типа и выбор операции осуществляется в рантайме (ну в общем случае), и чтобы сложить два числе одной командой процессора, надо перемолоть кучу кода, выясняя, каким же кодом все это сложить.

Компилятор вполне может вывести необходимый тип.

в языках с типизацией, все просто складывается одной командой и возможны наворочанные статические оптимизации кода.

Зато приходится на каждую комбинацию типов аргументов делать по реализации функции. Много-много копипасты. Упомянутый выше my_list на Си может иметь дюжину почти идентичных реализаций, отличающихся только типами.

monk ★★★★★
()
Ответ на: комментарий от Stanson

Ассемблер даёт представление о том, что может процессор в реальности, а что нет.

Об этом можно узнать в справочном руководстве по архитектурному семейству и в справочниках по отдельным моделям.

Работа инструкций процессора описывается для программиста по-английски(по-китайски и т.д.) в сочетании с (псевдо)кодом на некотором алгоритмическом языке.

Например:

ADCS

Add with carry, setting flags

This instruction adds two register values and the Carry flag value, and writes the result to the destination register. It updates the condition flags based on the result.

После описания кодирования инструкции и операндов, и асмовских обозначений показывается то, что делает инструкция, как её выполнение изменяет состояние машины:

https://developer.arm.com/documentation/ddi0602/2024-09/Shared-Pseudocode/shared-functions-integer?lang=en#impl-shared.AddWithCarry.3

// AddWithCarry()
// ==============
// Integer addition with carry input, returning result and NZCV flags

(bits(N), bits(4)) AddWithCarry(bits(N) x, bits(N) y, bit carry_in)
    constant integer unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
    constant integer signed_sum = SInt(x) + SInt(y) + UInt(carry_in);
    constant bits(N) result = unsigned_sum<N-1:0>; // same value as signed_sum<N-1:0>
    constant bit n = result<N-1>;
    constant bit z = if IsZero(result) then '1' else '0';
    constant bit c = if UInt(result) == unsigned_sum then '0' else '1';
    constant bit v = if SInt(result) == signed_sum then '0' else '1';
    return (result, n:z:c:v);

https://developer.arm.com/documentation/ddi0602/2024-09/Base-Instructions/ADCS--Add-with-carry--setting-flags-?lang=en

constant integer d = UInt(Rd);
constant integer n = UInt(Rn);
constant integer m = UInt(Rm);
constant integer datasize = 32 << UInt(sf);
constant bits(datasize) operand1 = X[n, datasize];
constant bits(datasize) operand2 = X[m, datasize];
bits(datasize) result;
bits(4) nzcv;

(result, nzcv) = AddWithCarry(operand1, operand2, PSTATE.C);

X[d, datasize] = result;
PSTATE.<N,Z,C,V> = nzcv;

Асма тут 2-3 строчки, исключительно в качестве текстовой нотации, а не объяснения того, как инструкция «работает». Безусловно, знать принятую для платформы систему обозначений полезно, но это не даёт само по себе понимания принципов работы процессора.

В руководствах по AMD64 и интеловских по x86 аналогичная манера.

Сами разработчики процессоров логическое моделирование тоже выполняют с помощью высокоуровневых инструментов.

vM ★★
()
Ответ на: комментарий от ugoday

Т.е. теперь в третьем классе переменные обладают типом

В третьем — нет, но что-то похожее всё же появляется в школьной математике чуть позже, когда в условиях задачи требуют решения только в действительных числах, или только в целых, ну или в любых, включая комплексные. Насколько это соответствует именно типу в программировании — вопрос во многом философский. Тут будет зависеть от того, насколько абстрактно мы к этому подходим, а насколько углубляемся в реализацию, в используемую память, и вот это всё.

и могут менять свои значения во времени?

Ну про это я уже упомянул. И да, это основная проблема для понимания третьеклассником этой записи: он не воспринимает знак равенства как присваивание.

CrX ★★★★★
()
Ответ на: комментарий от ya-betmen
  • если я не напишу статик, то код не копилируется.

Намекну: те ЯП, которые позволяют писать неговнокод спустя всего неделю изучения, всяких статиков не требуют.

rebforce
()
Ответ на: комментарий от ugoday

Осталось разобраться что такое результат сложения в данном случае. А то, есть подозрение, третьеклассник может понять это совершенно неправильно. И не понять этого. А это ещё хуже, чем сразу совсем не понять.

А ещё есть гипотеза что ты настолько сильно ударился в буквоедство, что перестал иметь хоть какую-то связь с реальностью.

anonymous
()
Ответ на: комментарий от ugoday

Двусвязный список — это всё, что реализует интерфейс двусвязного списка.

«интерфейс двусвязного списка» реализует много что. например внутри может быть динамический массив

alysnix ★★★
()
Ответ на: комментарий от praseodim

При том, что в твоём посте очевидная проекция.

Pwner
()
Ответ на: комментарий от AntonI

Ну попробуйте на латыни в Таджикистане купить себе еды;-)

Латинский: является обязательным в ряде университетов для получения диплома юриста / врача по крайней мере в США. Делает доступным огромный пласт до сих пор полезной литературы, написанной в 19м-начале 20го века, когда ещё не делали адаптацию текста под идиотов. Увеличивает вокабуляр, даёт понимание этимологии, повышает баллы на SAT/LSAT. Это всё, что касается элементарного уровня. Продвинутый позволит читать произведения в подлиннике, чай язык науки до 18го века.

Таджикский: можно купить еду в Таджикистане.

Сложный выбор, однако.

Но массово начинать учить латынь как первый иностранный язык это очень плохая идея.

Не знаю, что такое «массово начинать учить», но свои выводы ты выдаёшь за аргументы совершенно напрасно.

Pwner
()
Ответ на: комментарий от CrX

основная проблема для понимания третьеклассником этой записи: он не воспринимает знак равенства как присваивание.

В исходном ASCII был знак ←:

A ← B + C
vM ★★
()
Ответ на: комментарий от Pwner

Таджикский: можно купить еду в Таджикистане.

Если освоить традиционную (на арабской, а не клинописной основе) персидскую графику, можно попытаться разобрать классическую поэзию.

vM ★★
()
Ответ на: комментарий от rebforce

Напишу явно, после недельного освоения с любым языком будут аналогичные проблемы независимо от наличия в нём статиков. Код запускает и код делает то что нужно это две большие разницы.

ya-betmen ★★★★★
()
Ответ на: комментарий от vM

классическую поэзию

поэззию персов и арабов 12го века что-ли? а оно нам надо. у нас своих поэззий через край

alysnix ★★★
()
Ответ на: комментарий от Pwner

Не знаю, что такое «массово начинать учить»

Это заметно.

но свои выводы ты выдаёшь за аргументы совершенно напрасно.

Прежде чем оценивать чужие аргументы научитесь внимательно читать и понимать написанное. На русском написанное, не на латыни…

AntonI ★★★★★
()
Ответ на: комментарий от ya-betmen

Да, представь себе, так бывает, когда быстро изучаешь базу и код уже делает то, что нужно, потому что ЯП имеет достаточный уровень абстракции, позволяющий сфокусироваться на задаче вместо борьбы с «особенностями» самого ЯП или, того хуже, среды исполнения.

rebforce
()
Ответ на: комментарий от Pwner

Сложный выбор, однако.

Таджикский дает возможность общаться с таджиками (основной строительной силой в РФ). Латынь позволяет эстетствовать, читая давно переведенные на все нужные языки тексты. Очевидно что таджикский куда полезнее для извлечения гешефта.

anonymous
()
Ответ на: комментарий от rebforce

Да, согласен, отличный бы был язык и люди его изучившие за неделю.

К сожалению к нашей реальности это отношения не имеет.

ya-betmen ★★★★★
()
Ответ на: комментарий от rebforce

Но ведь попыгать жопой по клаве чтобы получить запускающийся код на питоне и написать код, который будет решать поставленную задачу это не одно и то же.

Первое за неделю вполне, второе (в зависимости от человека) может быть никогда.

ya-betmen ★★★★★
()
Ответ на: комментарий от ya-betmen

А при чём здесь одно к другому? ТС спрашивал ЯП для обучения программированию. Разумеется, в процессе обучения программированию обучение собственно ЯП должно занимать минимальное время. Если ЯП своей кривизной, костылями и неочевидностью мешает обучаться всему остальному в программировании, то, в общем-то, нахер такой ЯП нужен как на этапе обучения, так и на всех последующих.

rebforce
()
Ответ на: комментарий от rebforce

Нет, когда человека учат математике ему подбирают не те примеры, которые он быстро решит, а те которые помогут ему освоить нужные знания и получть нужные умения.

С изучением программирования так же, задачи и яп должны помогать в изучении материала, а не быть "легкими".

ya-betmen ★★★★★
()
Ответ на: комментарий от alysnix

«интерфейс двусвязного списка» реализует много что. например внутри может быть динамический массив

На динамическом массиве можно сделать операцию cons со сложностью O(1)?

monk ★★★★★
()
Ограничение на отправку комментариев: