5 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Функциональное программирование: в Java и C# слишком много церемоний

Функциональное программирование в C#

Функциональное программирование
Изучаю функции на python, необходима ваша помощь. Что не так в коде? Где? Почему? Зачем? Прошу.

Функциональное программирование
Суть моего задания: найти локальный максимум в вручную заданном массиве. Я написал код в.

Функциональное программирование
Читал или слышал, что те, кто выучил ООП, потом не могут изучить функциональное программирование.

Функциональное программирование
Написать функцию, которая запрашивает у пользователя ФИО студента группы (список группы составлен.

— На ваш взгляд, следует ли человеку, который долгое время занимается объектно-ориентированным программированием, знакомиться/переходить на функциональное?

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

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

Возникает такой аргумент: «а зачем мне изучать сами функциональные языки, если мы многое можем сделать и в C# с элементами функциональных языков?». По крайней мере один из ответов на это уходит в область изменяемости структур данных, поскольку и C#, и Java всегда останутся языками с мутациями. Когда данные, которые вы определяете по-умолчанию, доступны для изменении, то, какие бы элементы функционального программирования вы не вносили, принципиальной сущности этих языков это не изменит. В последних версиях C# вы можете «играться» с элементами ФП, но, конечно же, имеет смысл попробовать поработать с настоящим функциональным языком, таким как Erlang, Haskel или F#. Последний я бы особенно рекомендовал, поскольку это язык очень хорошо встраивается в .NET.

Из статьи на Хабре.
5 мая 2017
Функциональное программирование: в Java и C# слишком много церемоний

Функциональное программирование: в Java и C# слишком много церемоний

Администратор

Группа: Главные администраторы
Сообщений: 14349
Регистрация: 12.10.2007
Из: Twilight Zone
Пользователь №: 1

  • О применении функционального стиля программирования в языке Java.
  • О некоторых базовых паттернах для работы с коллекциями данных из функционального программирования в примерах на Java.
  • Немного о библиотеке Google Collections.

Если вы программируете на языках Java, C#, C++, PHP, или любом другом ОО языке, хотели бы познакомиться с функциональным программированием, но не имеет возможности/желания изучать Haskell/Scala/Lisp/Python, — эта статья специально для вас.

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

Вводим конструкцию «функция» в языке Java

Что такое функциональное программирование? Если в двух словах, то функциональное программирование — это программирование, в котором функции являются объектами, и их можно присваивать переменным, передавать в качестве аргументов другим функциям, возвращать в качестве результата от функций и т. п. Преимущества, которые раскрывает такая возможность, будут понятны чуть позже. Пока нам надо разобраться, как в Java можно использовать саму конструкцию «функция».

Как известно, в Java нету функций, там есть только классы, методы и объекты классов. Зато в Java есть анонимные классы, то есть классы без имени, которые можно объявлять прямо в коде любого метода. Этим мы и воспользуемся. Для начала объявим такой интерфейс:

public final interface Function <
T apply(F from);
>

Теперь в коде какого-нибудь метода мы можем объявить анонимную реализацию этого интерфейса:

public static void main() <
// Объявляем “функцию”, присваиваем ее переменной intToString.
Function intToString = new Function () <
@Override public String apply(Integer from) <
return from.toString();
>
>;

intToString.apply(9000); // Вызываем нашу функцию. Получаем строку “9000”.
>

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

Теперь можно перейти к изложению некоторых базовых паттернов функционального программирования.

Работа с коллекциями в функциональном стиле

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

Читать еще:  Ost и pst файлы в чем разница?

public String joinNumbers(Collection numbers) <
StringBuilder result = new StringBuilder();
boolean first = true;
for (Integer number : numbers) <
if (first)
first = false;
else
result.append(“, “);
result.append(number);
>
return result;
>

Для реализации функционального решения нам потребуется сперва подготовить несколько функций и методов. Будем объявлять их в качестве статических полей класса:

public static final Function INT_TO_STRING = . // Уже реализовали выше

// Берет поэлементно значения из коллекции from, преобразует их с помощью функции transformer
// и возвращает список результатов преобразования в том же порядке.
public static List map(Collection from, Function transformer) <
ArrayList result = new ArrayList ();
for (F element : from)
result.add(transformer.apply(element));
return result;
>

// Берет коллекцию произвольных элементов и конкатенирует их в строку
public static String join(Collection from, String separator) <
StringBuilder result = new StringBuilder();
boolean first = true;
for (T element : from) <
if (first)
first = false;
else
result.append(separator);
result.append(element);
>
return result.toString();
>

Теперь наш метод joinNumbers будет выглядить следующим образом:

public String joinNumbers(Collection numbers) <
return join(map(numbers, INT_TO_STRING), “, “);
>

Метод реализован ровно в одну простую строку.

Хотелось бы отметить несколько важных моментов:

  1. Методы map и join являются достаточно обобщенными, то есть их можно применять не только для решения данной задачи. Это значит, что их можно было бы выделить в некий утилитный класс, и использовать потом этот класс в разных частях проекта.
  2. Вместо класса Collection в методе map можно было бы передавать Iterable и возвращать новый Iterable, извлекая из переданной коллекции данные по мере обхода данных в возвращаемой коллекции, то есть извлекать элементы лениво, поэтапно, а не все сразу. Такая реализация, позволит, например, создавать цепочки преобразования данных, выделяя каждый этап преобразования в отдельную простую функцию, при этом эффективность алгоритма будет оставаться порядка O(n):

map(map(numbers, MULTIPLY_X_2), INT_TO_STRING); // каждый элемент умножаем на два и приводим к строке.

  • Создавая какой-нибудь класс, вы можете создавать для некоторых его методов статические поля, являющиеся функциями-обертками, делегирующими вызов apply на вызов соответствующего метода класса. Это позволит использовать «методы» объектов в функциональном стиле, например, в представленных выше конструкциях.
  • Работа с коллекциями с помощью Google Collections

    Ребята из Google как раз создали удобную библиотеку с утилитными классами, позволяющую работать с коллекциями в Java в функциональном стиле. Вот некоторые из возможностей, которые она предоставляет:

    • interface Function . Интерфейс, аналогичный приведенному мной выше.
    • Iterables.filter. Берет коллекцию и функцию-предикат(функцию, возвращающую булево значение). В ответ возвращает коллекцию, содержающую все элементы исходной, на которые указанная функция вернула true. Удобно, например, если мы хотим отсеить из коллекции все четные числа: Iterables.filter(numbers, IS_ODD);
    • Iterables.transform. Делает то же самое, что функция map в моем примере выше.
    • Functions.compose. Берет две функции. Возвращает новую функция — их композицию, то есть функцию, которая получает элемент, подает его во вторую функцию, результат подает в первую функцию, и полученный из первой функции результат возвращает пользователю. Композицию можно использовать, например, так: Iterables.transform(numbers, Functions.compose(INT_TO_STRING, MULTIPLY_X_2));

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

    Ссылки

    • Статья в Википедии о функциональном программировании.
    • Google Guava, проект, частью которого является Google Collections.
    • Видеопрезентация Google Collections с Joshua Bloch.
    • Apache Commons Collections. Решает схожие с Google Collections задачи, но был написан под Java 4, то есть без полиморфизма.

    О чем хотелось бы рассказать еще

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

    1. Мутабельные и иммутабельные замыкания.
    2. Pattern-matcher.
    3. Монады.
    4. Распараллеливание с использованием функционального подхода.
    5. Комбинаторы парсеров.

    5 языков, которые следует выучить после Java

    Вот 5 языков программирования, которые после Java произведут наименьший негативный эффект:

    C# — язык, с которым так или иначе сталкивался любой выпускник кафедры программирования (тем более опытный разработчик). Именно поэтому многие согласятся, что, не считая языков, транслируемых в JVM, это наиболее схожий представитель. Кроме того, C# востребован, а это важное условие, если вы собираетесь монетизировать свои знания.

    Что общего: очень сложно удержаться от цитирования статьи на Википедии, поэтому вот вам факты.

    Оба языка так или иначе являются развитием C++. Более того, создатели C# называют свой язык развитием Java. Кроме того, оба языка строго следуют принципам ООП.

    А еще у них похожий синтаксис:

    public class HelloWorld
    <
    public static void main(String[] args) <
    System.out.println(“Hello World!”);
    >
    >

    // HelloWorld.cs
    public class HelloWorld
    <
    public static void Main()
    <
    System.Console.WriteLine(“Hello World!”);
    >
    >

    И у Java, и у C# типизация строгая, что в известной степени способствует повышению безопасности в области использования памяти. Еще у языков похожие алгоритмы сборки мусора. Ещё один важный схожий момент, прекрасно характеризующий оба языка. Наконец, оба они кроссплатформенны. Изучение этого языка рекомендуем начать с нашего базового интенсива по Си Шарп.

    От чего захочется ругаться: Microsoft и естественная завязанность на их экосистему.

    Swift

    Если вы изучили Java для разработки мобильных приложений, то Swift станет логичным карьерным развитием. Более того, не так давно слухи упорно связывали будущее платформы Android со Swift, однако в итоге Google отстояло свое право на использование Java. Впрочем, кто поставит свой компьютер на то, что в дальнейшем Google не свернет с этого курса? В любом случае, умение писать “правильные” приложения для iOS лишним точно не будет.

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

    От чего хочется ругаться: подобно C#, экосистема Apple может вызывать отторжение.

    Kotlin

    Сахар для синтаксиса — распространенное мнение относительно Kotlin у разработчиков Java, ознакомившихся с ним лишь поверхностно. Куда более совершенный язык и наиболее очевидный преемник Java из существующих — утверждают люди, посвятившие изучению Kotlin чуть больше времени. В любом случае, как бы не сложилось ваше знакомство, равнодушным останитесь вряд ли.

    Что общего: создатели не скрывают, что Kotlin является доработкой Java с перспективой полного замещения. То есть фактически Kotlin сочетает всё то, за что вы полюбили Java, но при этом ещё удобнее, безопаснее и функциональнее. Работает с виртуальной машиной JVM.

    От чего хочется ругаться: и кому нужна Java, если есть Kotlin?

    Python

    Изучить Python после Java стоит хотя бы потому, что это просто. Во всех рейтингах, опросах и статьях, посвящённых выбору первого языка программирования, Python неизменно находится в топе.

    Что общего: практически ничего, кроме некоторых общих принципов ООП и кроссплатформености.

    От чего хочется ругаться: слишком далеко от привычного понимания о программировании.

    Возвращаясь к теме возможного отказа Google от Java в своем мобильном будущем, стоит всерьез рассмотреть вариант развития событий, при котором наследником станет Go. Пока что язык здорово проявляет себя в привычной среде Big Data, то есть сегодня, как минимум, Go может послужить полезным расширением для функциональности вашего приложения. Но если Go продолжит развиваться заданными темпами, а Google решится на внутреннюю революцию, то знание этого языка станет не бонусом, а практически необходимостью. Кстати, пару лет назад один из создателей Go, выложил в сеть интересную презентацию с названием “Go для Java-программистов”. Рекомендуется к просмотру.

    Что общего: формально общего здесь примерно столько же, сколько и в случае с C#: происхождение от языка C, строгая типизация, алгоритмы очистки памяти, схожие методы, интерфейсы и многое другое. Но, как язык, созданный почти через 15 лет после Java и через 10 после C#, Go он куда совершеннее, функциональнее и перспективнее.

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

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

    Вот 5 языков программирования, которые после Java произведут наименьший негативный эффект:

    C# — язык, с которым так или иначе сталкивался любой выпускник кафедры программирования (тем более опытный разработчик). Именно поэтому многие согласятся, что, не считая языков, транслируемых в JVM, это наиболее схожий представитель. Кроме того, C# востребован, а это важное условие, если вы собираетесь монетизировать свои знания.

    Что общего: очень сложно удержаться от цитирования статьи на Википедии, поэтому вот вам факты.

    Оба языка так или иначе являются развитием C++. Более того, создатели C# называют свой язык развитием Java. Кроме того, оба языка строго следуют принципам ООП.

    А еще у них похожий синтаксис:

    public class HelloWorld
    <
    public static void main(String[] args) <
    System.out.println(“Hello World!”);
    >
    >

    // HelloWorld.cs
    public class HelloWorld
    <
    public static void Main()
    <
    System.Console.WriteLine(“Hello World!”);
    >
    >

    И у Java, и у C# типизация строгая, что в известной степени способствует повышению безопасности в области использования памяти. Еще у языков похожие алгоритмы сборки мусора. Ещё один важный схожий момент, прекрасно характеризующий оба языка. Наконец, оба они кроссплатформенны. Изучение этого языка рекомендуем начать с нашего базового интенсива по Си Шарп.

    От чего захочется ругаться: Microsoft и естественная завязанность на их экосистему.

    Swift

    Если вы изучили Java для разработки мобильных приложений, то Swift станет логичным карьерным развитием. Более того, не так давно слухи упорно связывали будущее платформы Android со Swift, однако в итоге Google отстояло свое право на использование Java. Впрочем, кто поставит свой компьютер на то, что в дальнейшем Google не свернет с этого курса? В любом случае, умение писать “правильные” приложения для iOS лишним точно не будет.

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

    От чего хочется ругаться: подобно C#, экосистема Apple может вызывать отторжение.

    Kotlin

    Сахар для синтаксиса — распространенное мнение относительно Kotlin у разработчиков Java, ознакомившихся с ним лишь поверхностно. Куда более совершенный язык и наиболее очевидный преемник Java из существующих — утверждают люди, посвятившие изучению Kotlin чуть больше времени. В любом случае, как бы не сложилось ваше знакомство, равнодушным останитесь вряд ли.

    Что общего: создатели не скрывают, что Kotlin является доработкой Java с перспективой полного замещения. То есть фактически Kotlin сочетает всё то, за что вы полюбили Java, но при этом ещё удобнее, безопаснее и функциональнее. Работает с виртуальной машиной JVM.

    От чего хочется ругаться: и кому нужна Java, если есть Kotlin?

    Python

    Изучить Python после Java стоит хотя бы потому, что это просто. Во всех рейтингах, опросах и статьях, посвящённых выбору первого языка программирования, Python неизменно находится в топе.

    Что общего: практически ничего, кроме некоторых общих принципов ООП и кроссплатформености.

    От чего хочется ругаться: слишком далеко от привычного понимания о программировании.

    Возвращаясь к теме возможного отказа Google от Java в своем мобильном будущем, стоит всерьез рассмотреть вариант развития событий, при котором наследником станет Go. Пока что язык здорово проявляет себя в привычной среде Big Data, то есть сегодня, как минимум, Go может послужить полезным расширением для функциональности вашего приложения. Но если Go продолжит развиваться заданными темпами, а Google решится на внутреннюю революцию, то знание этого языка станет не бонусом, а практически необходимостью. Кстати, пару лет назад один из создателей Go, выложил в сеть интересную презентацию с названием “Go для Java-программистов”. Рекомендуется к просмотру.

    Что общего: формально общего здесь примерно столько же, сколько и в случае с C#: происхождение от языка C, строгая типизация, алгоритмы очистки памяти, схожие методы, интерфейсы и многое другое. Но, как язык, созданный почти через 15 лет после Java и через 10 после C#, Go он куда совершеннее, функциональнее и перспективнее.

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

    голоса
    Рейтинг статьи
    Ссылка на основную публикацию
    Статьи c упоминанием слов: