Oкей, Google, переведи print("Hello, World!") на Pascal
Существует ли Google Translate для языков программирования? Разбираемся в транспайлерах.
tesla / youtube
Глядя на приложения и платформы, которые переводят иностранные языки, невольно задаёшься вопросом: «А можно ли так же перевести код с Java на Python?»
Если ответить коротко — можно. Если же вдаваться в подробности — то вроде как тоже да, но… нет. Давайте разбираться.
I, Robot: почему переводить языки программирования не так просто, как кажется
Google Translate и «Яндекс.Переводчик» вполне сносно справляются с простыми фразами и даже клишированными коммерческими статьями. Да, текст выходит немного кривым и теряет стилистическую окраску, но из него легко выхватить основную суть. То есть, несмотря на все шероховатости, автоматические переводчики отлично выполняют фундаментальную задачу перевода — передают смысл.
Логично, что раз компьютеры справляются с обычными языками, то с языками программирования должно быть ещё легче — они строже, структурированнее, проще в плане синтаксиса и не двусмысленны. Но на деле именно эти простота и строгость усложняют автоматический перевод программ с одного языка на другой.
Человек легко додумывает или мысленно исправляет косяки «Google Переводчика». А вот компьютер — нет. Даже самая мелкая неточность приводит к тому, что программу невозможно запустить. Иначе говоря, перевод языков программирования должен быть идеальным, чтобы от него был хоть какой-то толк. И это при том, что программирование не стоит на месте — появляются новые библиотеки, фреймворки и языки, дополняются и изменяются старые.
Не спасают ситуацию и автокорректоры — это те же программы, которые пишут люди. Легко запрограммировать компьютер и указать ему, что слово «корова» пишется именно так. А вот понять намерения программиста, если он ошибся, машине трудно — требуется слишком много сценариев.
Языки программирования строже и не прощают даже самые мелкие неточности. При этом они меняются и дополняются так же быстро, как и естественные языки.
Ну и что? Just Do It!
Действительно. Языки программирования всё же возможно переводить автоматически. Для этого есть специальные программы — транспайлеры. Они переводят исходный код в рамках одного и того же уровня или абстракции — например, Python в JS (оба языка высокоуровневые) или JS ES2015 в JS ES5.
Одним из первых транспайлеров можно считать Ratfor — язык программирования, который расширяет возможности Fortran 66 — в частности, предоставляет операторы if-else и while. Он появился в середине 1970-х и, по сути, переводил программы, написанные на Fortran 66, на более современные стандарты языка.
Однако автоматические переводчики с разных языков стали создавать в конце 1980-х. Тогда появился Fortran-to-C Converter (F2C) — программа, которая переводит код с Fortran на C. Другой яркий пример — Pascal to C Translator (P2C), который транслирует Pascal в C.
Правда, F2C и P2C создавали под конкретную задачу — портирование приложений между разным железом и операционными системами. Первый переводил важные программы с уже мёртвого языка программирования на живой. Второй — портировал их на ПО Unix, созданное на Pascal: для этого программу также было необходимо перевести на C. То есть ни один из транспайлеров не делался именно для того, чтобы легко переводить любую программу с одного языка на другой.
Как работают транспайлеры
Компиляция большинства языков программирования включает шаг «взять текст программы и преобразовать его в синтаксическое дерево».
Всё, что необходимо сделать транспайлеру, — это получить такое дерево (компиляторы большинства языков уже научились отдавать его другим программам) и для каждого узла подобрать похожую конструкцию из целевого языка. В самом примитивном случае если есть компилятор целевого языка и ему можно передать синтаксическое дерево, то вся задача сводится к преобразованию одного дерева в другое.
Но чаще всего траспайлер преобразует текст программы на другом языке, так что программисту нужно для каждого узла синтаксического дерева подобрать нужный текст на целевом языке. К примеру, если компилятор Python увидел код:
if foo:
print (foo)
то он построит из него синтаксическое дерево с корнем if, от которого идут ветки «условие» и «тушка». Преобразуя это в JavaScript, разработчик транспайлера пишет код, который для ветки if создаст следующий текст:
if () {
}
Далее внутрь круглых скобок устанавливается транспилированное условие, а внутрь фигурных — транспилированная «туша».
Ну и так далее. Всего будет примерно сотня разных узлов. Плюс преобразования для ситуаций, когда в исходном языке есть что-то, чего нет в целевом. Тогда генерируется код, который делает то же по смыслу, но в форме, которая доступна целевому языку.
Григорий Петров
Генералист, нейрофизиолог-любитель. Организует разработку, конференции, хакатоны. Участвовал в создании Radmin и Advanced IP Scanner, продвигал интерактивное телевидение NPTV и программируемую телефонию Voximplant. Сейчас — head of developer relations в Evrone.
«Твоя моя не понимать»: почему транспайлеры почти никому не нужны
Итак, есть транспайлеры, которые автоматически переводят программу с одного языка программирования на другой. Почему же тогда нет популярных приложений, которые легко делают такие переводы?
Большинство программ и так изначально пишут на том, что решает эти задачи лучше всего. Вряд ли кто-то будет писать сайт на C#, когда есть JS, PHP и прочие инструменты веб-разработки. Переводить потом этот сайт на Swift или Perl — такое же бесполезное и даже глупое занятие.
С другой стороны, гораздо чаще разработчики просто работают с тем, что умеют и знают лучше всего. Но даже в этом случае команда, в которой есть крутые спецы по JS, Python и С++, вряд ли будет использовать транспайлеры, если надо сделать мобильное приложение на iOS.
Никто в здравом уме не будет писать приложение на Python, чтобы потом перевести его на Swift. Ведь тогда пришлось бы использовать все библиотеки, которые написаны для Swift и документированы на Swift, из Python. Гораздо проще будет нанять ещё одного спеца или просто выучить Swift.
P. S. Кстати, в 2016 году Google выпустил специальный инструмент для портирования программ с Android на iOS. Эффекта волшебной палочки от него ждать не стоит, но если вы предпочитаете портировать Android на iOS, а не наоборот, то есть смысл протестировать.
Мнение эксперта
Задача сделать транспайлер по сложности тянет на уровень для курсовой работы студента-первокурсника. Есть одно но: сам язык программирования — это очень маленькая часть того, что нужно для разработки программы. Гораздо более сложная и объёмная часть — это фреймворки с библиотеками. И если сделать транспайлер для самого языка — не слишком сложная задача, то вот с фреймворками и библиотеками всё уже не так радужно.
Они создаются для конкретного языка и намертво заточены на его идиомы и синтаксис. Делать перевод на другой язык теоретически можно, но практически использование библиотек из неродного языка превращается в ад. Это уже несколько раз проходили, когда пытались сделать языки для экосистемы Java. Самый болезненный опыт получился у Apple, когда они заменили Objective-C на Swift, оставив большую часть библиотек от Objective-C. Разработчики до сих пор, мягко говоря, в шоке.
Вообще, самое популярное в этом направлении — транспайлеры для JavaScript. На этом их применение по большей части и заканчивается. Почему именно JS? Потому что часто возникает ситуация, когда веб-сайт на стороне сервера реализован на Python, Ruby или PHP, а нужно добавить чуть-чуть кода в браузер. И чтобы разработчикам не использовать сразу два языка, часто применяют транспайлер, который позволяет, к примеру, писать всё на Python, а часть кода на Python превращать в код на JS. JS в этом плане, кстати, удобен ещё и тем, что у него удивительно бедная стандартная библиотека. Ну и стоит упомянуть про TypeScript: надстройку на JavaScript от Microsoft. Эта «тушка» уже превосходит сам JavaScript по популярности, но при этом не является самостоятельным языком: исходный код на TypeScript транспилируется в JavaScript.
А вот большинство транспайлеров для других языков — просто поделки без какой-либо реальной практической значимости. Поэтому в интернете очень сложно найти качественный переводчик других языков — всерьёз ими никто не занимается. Получается такой замкнутый цикл:
никому не нужно и плохо работает → никто их не улучшает и не делает → поэтому они продолжают плохо работать → и поэтому они никому и не нужны.
Григорий Петров
Генералист, нейрофизиолог-любитель. Организует разработку, конференции, хакатоны. Участвовал в создании Radmin и Advanced IP Scanner, продвигал интерактивное телевидение NPTV и программируемую телефонию Voximplant. Сейчас — head of developer relations в Evrone.
Вывод
Автоматические переводчики языков программирования существуют — это транспайлеры. Однако навороченных приложений вроде Google Translate для программирования нет. Обычно транспайлеры делают для конкретных задач и удобства в веб-разработке — под JavaScript.
Всё остальное не имеет особого смысла — не потому, что сложно, а потому, что это бессмысленные поделки, в которых нет никакой практической пользы. В самом деле — кому вообще в голову может прийти переводить Python в Pascal? :)