Переход с Java (C++, ..) на Scala (Clojure, Haskell, Erlang ..) как повышение абстракции программирования

в 21:32, , рубрики: java, scala, абстракция, коллекции, функциональное программирование, метки: , , , ,

А что такого можно написать на Scala, чего нельзя на Java?
(из разговора с одним моим знакомым другом, человеком и программистом)

The best reason to learn a new programming language is to learn to think differently.
Chad Fowler

Переход с Java (C++, ..) на Scala (Clojure, Haskell, Erlang ..) как повышение абстракции программирования
Хочу рассказать не о простоте конструкций Scala по сравнению с Java и не о том, что в 1 строчку Scala я могу уместить 20 строк Java. А наоборот, копнуть поглубже, уронить устои ООП и посмотреть на реакцию благородной публики.

Буквально 1,5- 2 месяца назад я сам себе задавал абсолютно тот же вопрос, что стоит под заголовком. И вот недавно наконец замахнулся я на Ульяма нашего Шекспира Мартина Одерски. На этом месте суровые Scala программеры со стажем могут снисходительно улыбнуться- дескать без году неделя- а уже Scala статьи писать. Да еще в Сам Хабр.И тем не не менее, позвольте продолжить- возможно и Вам будет небезинтересно.
Начну издалека: с риторического вопроса-на чем основан прогресс человечества? Ну или хотя бы ограничимся языками программирования. Если отвлечся от синтаксиса, пунктуации и узреть корень? Ну да, конечно — на повышении уровня абстракции.
Когда с машинных кодов перешли на ассемблер- писать стало лучше, писать стало веселее.
А что такое asm супротив basic? Это все равно что плотник супротив столяра собака супротив человека. Программисту перестал знать устройство регистров, он стал мыслить переменными! Оставим в стороне нерпиятный побочный эффект профанации этой высокой профессии, когда каждый индус школьник мог назвать себя программистом.
Дальше- больше. Появился Fortran- процедурное программирование, формальные и фактические переменные, библиотеки процедур! Кто ездил на трамвае за 3 копейки возможно помнит сплошной листинг из спагетти кода и goto.
Следующий шаг- структуры данных. Хватит мыслить переменными! Даешь структуры-объекты! Если вы пишете в стиле ООП и в каком то месте скатываетесь к примитивам- например в кэше или в концифурации — несколько раз мне приходилось встречать такое — задумайтесь. Находитесь ли вы на одном уровне абстракции с вашим языком? ООП позволяет мыслить бизнес моделью вашей задачи- объектами. Не нужно говорить: скопируй автора А в автора Б, дату А в дату Б и коментарий А в коментарий Б и т.д. Скажите- скопируй документа А в документ Б. Даже если внизу будет копирование полей, мыслить то програмист уже документами, а не его полями.
На сем позвольте закончить затянувшееся вступление и перейти к завязке:

что же это за такая абстракция в этих функциональных языках, чего нет в императивных?

Возьмем простой пример простой задачи: является ли число N простым, перевод из цикла переведенных статей на IBM про функциональное программирование где, на мой взгляд, преимущество функционального подхода прозвучало неубедительно. Перефразирую задачу на язык программиста:

Определить, есть ли в поcледовательности от 2 до sqrt(N) такое число, чтобы деление N на него нацело было бы без остатка.

Фф, скажет джавист и правильно сделает:

    int sqrt=sqrt(N);   // вычисляем только раз, а не при каждой итерации цикла
    for(int i=2; i<=sqrt; i++){
        if( N % i ==0){
           return false;
        }
        return true;
    }

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

    !(2 to math.sqrt(N).toInt).exists(N % _ == 0)

Красиво? Да, безусловоно, но… Может кого-то это убедит, конечно… Что ж, для сомневающихся попробую забить последний гвоздь в их голову крышку их устоев непокобе непоколебимости ООП: операция par над коллекцией. Одним ма-аленьким словом из 3-х букв программист Scala может послать java распаралелить вычисления над любой коллекцией. Например так:

!(2 to math.sqrt(N).toInt).par.exists(N % _ == 0)

На сложных задачах и 8 процессарах например- прирост скорости конечно не в 8 раз, но около того. А все потому что Scala мыслим не элементами коллекции, а ей всей целиком. Далее можно было бы объявит конкурс на минимальный код на джава, который повторит этот трюк. Но если вы не бросились пытаться повторить это на java, значит мои усилия не пропали даром.
Ну и наконец, после счастливой развязки, позвольте внести еще и интригу: следующая абстракция Scala пока зреет в моей голове и, надеюсь, выплеснется следующей статьей.
Спасибо за внимание.


Автор: gkislin

Источник

Поделиться