Решение одной задачи с помощью 16 языков программирования

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

Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!

Видеоблогер Конор Хекстра использовал разные языки программирования, чтобы решить одну и ту же задачу. Попутно выяснилось, что у Фортрана полно поклонников.

На YouTube-канале code_report, «посвященном соревновательному программированию», есть интересная работа Конора Хекстры, старшего инженера NVIDIA, работающего над пакетом RAPIDS для конвейеров обработки данных и аналитики. Хекстра увлекается просмотром решений с конкурсов по программированию (LeetCode, HackerRank, Topcoder и Codeforces), а также создаёт видеоролики на близкие к программированию темы, такие как структуры данных и алгоритмы.

У Фортрана оказалось много поклонников

Чтобы исследовать подходы к решению одной задачи на 16 разных языках программирования, Хекстра выбрал относительно простое задание с конкурса программирования LeetCode: определите наименьшее и наибольшее число из заданного списка, а затем найдите их наибольший общий делитель.

Языки, выбранные для решения:

  • C++

  • Rust

  • D

  • Clojure

  • Ruby

  • Elixir

  • Raku [Perl 6]

  • Haskell

  • Racket

  • Julia

  • Python

  • APL

  • J

  • BQN

  • Pharo Smalltalk

  • Fortran

(В видео поясняется, что последние два языка были добавлены по просьбам зрителей. «Я сделал опрос в Твиттере, и Fortran получил целых 27 лайков!», — объясняет Хекстра. Так что пришлось его тоже включить).

Кардинальные различия

Хотя исходная задача была простой, подходы к её решению в разных языках сильно отличаются. Особенно при переходе на язык массивов. Там подход будет принципиально отличаться от того же Python или Ruby.

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

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

И самое главное, поскольку Haskell использовал стиль программирования “Tacit” или point-free (стиль программирования без промежуточных переменных, предполагает использование конвейерных функций и комбинаторов), который не указывает аргументы в определениях функций, решение Haskell даже не нуждалось в упоминании массива чисел.

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

Хекстра жаловался, что в Rust и в C++ слишком много «формальностей». Обе функции, и min, и max, требуют использования iter() для прохождения итераций по каждому значению в списке чисел, и unwrap() для извлечения значения из более сложного модуля Result, который включает информацию об обработке ошибок.

И, как заметил Хекстра: «чтобы получить доступ к функции gcd приходится преодолеть кучу лишнего в пространстве имён num::integer:: . Но в остальном это очень хорошее решение».

Так как Хекстра является поклонником языков программирования массивов, в его исследовании нашлись и более существенные различия. Решение в APL (справа от розовой стрелки) состоит всего из пяти символов. (Первые два символа находят максимальное значение, последние два символа находят минимальное значение, а зеленая буква v в середине находит их наибольший общий делитель.)

Похожая структура есть и в языке программирования J (ещё один язык программирования массивов, но J является усовершенствованной версией APL, в которой используются диаграммы ASCII, а не символы Unicode»). Функция нахождения максимума представлена здесь ​​​​символом “>”, а функция поиска минимума — “<”.

Чем дальше, тем всё более экзотическими становились решения. BQN из семейства  APL (согласно APL Wiki) всё ещё является языком, управляемым массивами, но он использует свой уникальный набор символов. Поскольку в нём нет встроенной функции для нахождения наибольшего общего делителя, эта функция должна быть определена в отдельной строке кода.

Хекстра признался, что просто скопировал код из онлайн-источника. Как только функция стала определена в первой строке, появилась возможность вызвать её, как часть решения, во второй строке.

Соревнование со зрителями

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

“Некоторые интересовались решением для Cobol, так что я решил попробовать свои силы: https://t.co/Pi7OSCdeIl Всего-то 91 строка…

На данный момент видео получило сотни комментариев, в которых предлагались лучшие варианты решений. 

Решение на языке Julia был похоже на решение для Python, только с оператором «splat» (в данном случае троеточие), означающим, что будет проверено более одного значения:

Но зрители предложили более простой синтаксис. В Julia есть две встроенные функции поиска минимума и максимума, которые не требуют многоточия. Также есть одна функция, которая возвращает оба значения “extrema”. А затем решение стало еще проще, когда Хекстра взял оператор склеивания функций для создания point-free решения (с функцией сбора, преобразующей два значения в формат списка, который можно передать в gcd).

«На мой взгляд, это самое красивое решение из всех, — добавил Хекстра — отчасти потому, что оно демонстрирует элегантность point-free решений.»

Затем зрители предложили ещё несколько изящных улучшений для решения Хекстры на Raku (язык, ранее известный как Perl 6). В Raku gcd — это «инфиксная» функция, которую можно поместить между двумя значениями  аналогично математическим операторам (например, плюс или минус). И тогда два значения, между которых его поместили, могут быть результатами методов объектного стиля, вызываемых массивом чисел. 

По иронии судьбы, решение Pharo Smalltalk оказалось похожим на решение Raku (со своей собственной функцией gcd:, которая появлялась как «инфиксный» оператор между двумя функциями, возвращающими минимум и максимум).

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

Хекстра счёл такое решение предпочтительным.

По фану с Фортраном

В первом видео Хекстра посчитал решение, написанное на Fortran, худшим, потому что оно тоже было заполнено кучей формальностей и усложнений. Но он уточнил, что «это первый кусок кода на Фортране, который я написал в своей жизни, так что, скорее всего, есть лучшие решения… После 40 минут отладки и запуска этого кода я решил, что пора закругляться».

Но в последующем видео Хекстра признался, что получил потрясающий ответ от сообщества Fortran. Джейкоб Уильямс, программист Фортрана и орбитальный механик в Космическом центре НАСА имени Джонсона, ответил, что ему потребовалось для решения задачи потребовалось около 5 минут (с gcd из кода rosetta). 

Также видео Хекстры вызвало отклик у Милана Курчича, давнего программиста на Фортране и автора книги «Современный Фортран». Курик поблагодарил Хекстру за включение Фортрана в свой обзор и предложил альтернативное решение, которое включает функцию наибольшего общего знаменателя:

Оказалось, что временная переменная res не нужна, так как результат можно просто вернуть, не присваивая ему отдельного значения. И некоторые обновления синтаксиса в Фортране теперь позволяют указывать длину списка с помощью одного лишь двоеточия вместо громоздкой переменной numsSize. Это позволяет избавиться от целой строки кода. Итого вместо огромного кода можно прийти к всего двум строкам в теле функции!

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


Что ещё интересного есть в блоге Cloud4Y

→ Как открыть сейф с помощью ручки

→ OpenCat — создай своего робокотика

→ Как распечатать цветной механический телевизор на 3D-принтере

→ WD-40: средство, которое может почти всё

→ Изобретатели, о которых забыли

Подписывайтесь на наш Telegram-канал, чтобы не пропустить очередную статью. Пишем только по делу. А ещё напоминаем про второй сезон нашего сериала ITить-колотить. Его можно посмотреть на YouTube и ВКонтакте.

Источник: https://habr.com/ru/company/cloud4y/blog/691602/


Интересные статьи

Интересные статьи

Недавно перед командой аналитики подбора преподавателей встала задача усовершенствования модели матчинга учеников преподавателей. Перед вами статья о том, как мы это делали.
По профессии я режиссер монтажа, а прикладное программирование как увлечение в свободное время.В какой то момент пришла идея совместить работу с хобби, прочитал статью на...
Часто требуемое для вывода результатов расчетов преобразование числа с «плавающей точкой» из формата IEEE-754 в текстовую строку в «научной» нотации (т.е. с показателем с...
В статье рассмотрена проблематика очистки образов, которые накапливаются в реестрах контейнеров (Docker Registry и его аналогах) в реалиях современных CI/CD-пайплайнов для cloud n...
Те, кто собираются открывать интернет-магазин, предварительно начитавшись в интернете о важности уникального контента, о фильтрах, накладываемых поисковиками за копирование материалов с других ресурсо...