Все ли языки в основном одинаковы?

39

Недавно мне пришлось понять дизайн небольшой программы, написанной на языке, о котором я понятия не имел ( ABAP , если вы должны знать). Я мог понять это без особых затруднений.

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

Это вообще правда? Все ли языки программирования состоят из одинаковых конструкций, таких как циклы, условные операторы и передача сообщений между функциями? Существуют ли неэзотерические языки, которые типичный программист на Java / Ruby / Haskell не сможет понять? Все ли языки имеют общее происхождение?

Anirudh
источник
4
Я направлю вас к победе над средними числами Пола Грэма. Вы можете или не можете хотеть прочитать всю вещь, но для соответствующей части ищите заголовок "Парадокс Клуба". Мистер Грэхем не может быть обеспокоен тем, чтобы поставить якоря в свою стену текста, поэтому я не могу напрямую ссылаться на него.
Кватфорд
4
Языки не имеют общего происхождения. Но все языки пытаются решить некоторые проблемы. Я думаю, что это несколько аналогично разговорной речи. Цель состоит в том, чтобы выразить себя. Я не могу сказать, что понятно понимать языки, основываясь на знании 1 процедуры / OO / функционала. Я этого не делал, но если бы мне пришлось задать этот вопрос, я бы посмотрел на perl или lisp с множеством скобок, и я бы не смог сказать, что достаточно знания одного языка всех типов.
Шахкалпеш
1
В этом случае: лямбда-исчисление. Возможно, не «настоящий» язык, но в определенном смысле он является матерью всех языков программирования. Однажды мне пришлось реализовать такой функциональный язык, чтобы он компилировался в лямбда-выражения (которые затем интерпретировались напрямую). Результаты были (по крайней мере для меня) нечитаемыми, несмотря на сохранение всех соответствующих идентификаторов. Особенно рекурсивные функции с использованием Y-комбинатора. Единственный практический способ выяснить, что сделали некоторые примеры выражений, - это оценить их вручную. Простые вещи, такие как fibonnaci и сортировка слиянием, были нечитаемыми.
Кватфорд
2
Если вы знаете функциональные языки, вы должны знать, что циклы не возможны на каждом языке.
Джалф
Пит совсем другой. :)

Ответы:

88

Основы большинства процедурных языков почти одинаковы.

Они предлагают:

  • Скалярные типы данных: обычно логические, целые числа, числа с плавающей запятой и символы
  • Составные типы данных: массивы (строки - особый случай) и структуры
  • Базовые конструкции кода: арифметика над скалярами, доступ к массиву / структуре, присваивания
  • Простые структуры управления: if-then, if-then-else, while, для циклов
  • Пакеты кодовых блоков: функции, процедуры с параметрами
  • Области применения: области, в которых идентификаторы имеют конкретные значения

Если вы понимаете это, вы хорошо понимаете 90% языков на планете. Что делает эти языки немного более сложными для понимания, так это невероятное разнообразие странного синтаксиса, который люди используют, чтобы говорить одни и те же базовые вещи. Некоторые используют краткие обозначения, включающие нечетную пунктуацию (APL - крайность). Некоторые используют много ключевых слов (COBOL - отличный представитель). Это не имеет большого значения. Важно то, что язык достаточно самодостаточен, чтобы выполнять сложные задачи, не заставляя вас рвать на себе волосы. (Попробуйте написать код серьезного взлома строк в сценарии оболочки Windows DOS: он способен на Тьюринга, но на самом деле плохо во всем).

Более интересные процедурные языки предлагают

  • Вложенные или лексические области, пространства имен
  • Указатели, позволяющие одному объекту обращаться к другому, с динамическим распределением памяти
  • Упаковка связанного кода: пакеты, объекты с методами, признаки
  • Более сложный контроль: рекурсия, продолжения, замыкания
  • Специализированные операторы: операции со строками и массивами, математические функции

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

Языки, которые труднее понять, являются непроцедурными:

  • Чисто функциональные языки, без заданий или побочных эффектов
  • Языки логики, такие как Пролог, в которых происходят символьные вычисления и унификация
  • Языки сопоставления с образцом, в которых вы указываете фигуры, которые соответствуют задаче, и часто действия инициируются совпадением
  • Языки ограничений, которые позволяют вам определять отношения и автоматически решать уравнения
  • Языки описания оборудования, на которых все выполняется параллельно
  • Специфичные для домена языки, такие как SQL, цветные сети Петри и т. Д.

Существует два основных стиля представления языков:

  • Основанный на тексте, в котором идентификаторы именуют объекты и информационные потоки неявно кодируются в формулах, которые используют идентификаторы для именования объектов (Java, APL, ...)
  • Графический, в котором сущности рисуются как узлы, а отношения между сущностями рисуются как явные дуги между этими узлами (UML, Simulink, LabView)

Графические языки часто допускают текстовые подъязыки как аннотации в узлах и дугах. Графические языки Odder рекурсивно позволяют графы (с текстом :) в узлах и на дугах. Действительно странные графические языки позволяют графам аннотаций указывать на аннотируемые графы.

Большинство из этих языков основаны на очень небольшом количестве моделей вычислений:

  • Лямбда-исчисление (основа для Lisp и всех функциональных языков)
  • Почтовые системы (или методы переписывания строк / деревьев / графиков)
  • Машины Тьюринга (изменение состояния и выбор новых ячеек памяти)

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

Я настоятельно рекомендую изучить Scheme, в частности, из действительно замечательной книги: Структура и интерпретация компьютерных программ . Это описывает все эти основные понятия. Если вы знаете это, другие языки покажутся довольно простыми, за исключением глупого синтаксиса.

Ира Бакстер
источник
3
Отличный ответ! В качестве продолжения (есть ли способ задать дополнительный вопрос в SO?), Есть ли один язык, на котором я мог бы освоить и утверждать, что понимает все концепции в программном обеспечении? Будет ли это Лисп (или диалект, такой как Схема)?
@Anirudh: Там нет официального механизма контроля, но вы могли бы открыть новый вопрос. Если он содержит обоснование и ссылку на этот вопрос, он может даже не закрыться. ;) Отвечая на ваши вопросы, я искренне верю, что не существует только одного языка, поскольку парадигмы слишком разные.
@Anirudh: Согласился с Джоном Y, не только один. Но если вы относительно новичок в этой области, вы должны потратить немало сил, чтобы овладеть процедурной парадигмой (я считаю ОО просто специализацией). Не мешало бы взглянуть на другие парадигмы (логика, ограничение, поток данных), чтобы понять, как они работают, но для большинства повседневных задач в промышленности процедурные языки в значительной степени король.
Ира Бакстер
1
Как и в случае с естественными языками, «труднее понять» субъективно и зависит от того, какой язык вы выучите.
NullUserException
1
@NullUserException: это предполагает, что вы должны тщательно выбирать свой первый язык, чтобы максимально облегчить понимание других. В этом суть Схемы, и в частности книги SICP.
Ира Бакстер
6

Языки описания оборудования являются языками программирования, но концептуально они очень разные. Попробуйте VHDL или Verilog для размера. Они являются общими для программирования ПЛИС. (Хорошо, значит, они не процессоры, но они являются вычислительными устройствами общего назначения. И такое должно считаться допустимым оборудованием для тем компьютерных наук.) Вы должны явным образом заставить вещи происходить последовательно. Это совершенно другая модель. Вы думаете о вещах, происходящих параллельно, как правило, а не как исключение. Ибо петли в verilog расширяются до параллельного оборудования. Таким образом, «ожидаемое» поведение может быть не тем, что вы ожидаете.

NoMoreZealots
источник
Неплохо подмечено. Я посмотрю, посмотрите вверх Verilog / VHDL.
Я всегда думал, что обычные языки программирования - это просто по-настоящему вялые способы кодировать программы, которые естественно параллельны, такие как VHDL. Когда вы начинаете как дизайнер оборудования, этот кусочек обо всем, что происходит в серийном стиле, кажется невероятно неуклюжим. (Мы преподаем неправильные языки программирования людям как их первый язык: это должен быть Verilog!).
Ира Бакстер
4

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

На низком уровне все они выполняют одинаковые последовательности операций, и все компоненты Windows, Linux и (недавно) OS X работают на Intel-совместимых процессорах с использованием одинаковых наборов команд. Таким образом, они также в основном одинаковы.

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

Дина
источник
3

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

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

Preet Sangha
источник
1
Джон фон Нейман И это НЕ произносится как «новичок», скорее как «нойман».
Спасибо за исправление - я произношу, как вы сказали, хотя.
Прит Сангха
Когда кто-то предлагает исправление, вы можете просто отредактировать свой пост, чтобы отразить его.
Фил Миллер
2

Языки программирования также являются инструментами для мышления. С другой точки зрения мышления некоторые проблемы исчезают или трансформируются в другой, более управляемый вид (например, многие шаблоны проектирования в стиле C ++ просто исчезают, когда вы думаете на Лиспе (см., Например, эту презентацию Питера Норвика ), и Эрланг освобождает вас от мышления некоторых низкоуровневых параллельных или распределенных вычислительных конструкций и позволяет вам просто сосредоточиться на логике приложения).

Обратите внимание, однако, что иногда «новые» парадигмы могут быть частично применены к «старым» языкам программирования, что объясняет, почему, например, у нас есть книги, обучающие функциональному программированию для Java-программистов . Но естественная поддержка и интеграция более мощной парадигмы на уровне языка обеспечивает более естественное применение этой парадигмы (и, следовательно, делает невозможным понимание программ на языке, поддерживающем незнакомую парадигму, на что намекают другие ответы - @Ira Baxter, перечисляющий непроцедурные языки и @kwatford со ссылкой на Пола Грэма ).

FOOF
источник
2
+++++++[>+++++++++++<-]>+.<+++++++++++[>+++<-]>.>>+++++++[>++++++<-]>++++.

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

asthasr
источник
1

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

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

Python стремится быть идеальным языком сценариев. Для этого он жертвует скоростью и проверяемостью ради производительности и портативности.

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

Эти жертвы и выгоды имеют огромное значение в языке. Да, большинство языков программирования можно использовать для всего, что может делать компьютер, но ни один из этих языков не должен использоваться для всего. Все вышеперечисленные языки - те, которые я выбрал бы для определенных задач, но не для других. Если бы я программировал операционную систему, я бы выбрал C. Если бы я писал бэкэнд для веб-сайта, я бы использовал Python. И если бы я писал финансовую систему, я бы использовал Haskell.

В конце концов, ваш выбор как программиста - это то, что нужно для работы.

имажинистов
источник