Элементы функционального программирования появились в Java сравнительно недавно, но приобретает все большую популярность. Особенно в части stream API – наверное нет Java разработчика, который бы не слышал/читал/применял этот API для работы с коллекциями. К сожалению, большинство и не идет дальше использования Stream API, тогда как функциональный подход позволяет значительно упростить жизнь разработчикам автотестов. Ниже я расскажу про два примера такого упрощения – словари проверок и специализированные матчеры
Рубрика «functional programming» - 7
Автотесты в функциональном стиле
2016-05-19 в 20:19, admin, рубрики: automation testing, functional programming, java, java 8, Тестирование IT-системРазбавляем асинхронное программирование функциональным на Scala
2016-04-11 в 10:38, admin, рубрики: asynchronous, functional programming, scala, scalaz, tutorial, параллельное программирование, функциональное программированиеПриветствую! В этой статье будет показано, как, имея на руках обычные Future-ы, сделать в scala подобие корутин и асинхронные stream-ы. Этакий небольшой туториал по функциональному программированию.
Что это и зачем
К сожалению, простое последовательное комбинирование 2х и более асинхронных операций (загрузить конфиг, а потом картинку по адресу из конфига как пример) — это все, на что способны обычные Future-ы в качестве монад. Они не позволяют ни сохранять состояние, ни делать циклы из асинхронных операций, ни выдавать несколько (или бесконечно много) значений. Вот этими недостатками мы сейчас и займемся.
Давайте для определенности представим некий виджет. Он ждет конфиг, который обновляется с определенной периодичностью, загружает по адресу из конфига значение (например, температуру), и рисует на экране текущее значение, минимум, максимум, среднее и так далее. И все это делает в цикле, да еще и асинхронно.
Применив знания из этой статьи, мы сможем этот процесс описать примерно так:
// Про 'FState' - далее, пока же просто примем, что это - такая необычная Future
def getNextConfig: FState[Config]
def getTemperature(from: String): FState[Int]
case class State(temperature: Int, sumTemp: Long, count: Int) {
def isGood = ...
}
// Как видим, получается единый асинхронный алгоритм с состоянием,
// которое извне этого алгоритма не видно
val handle =
while_ ( _.isGood)
{ for (
config <- getNextConfig();
if (config.isDefined); // пустой конфиг - прекращаем выполнение
nextValue <- getTemperature(config().source); // грузим значение температуры
state <- gets[State]; // тут мы берем текущее состояние
newState = State(nextValue, state.sumTemp + nextValue, state.count + 1);
_ <- puts(newState); // .. и меняем его
_ <- runInUiThread { drawOnScreen(newState) }
) yield() }
Или вот так:
val configs: AsyncStream[Config] = ... // получаем откуда-то stream конфигов
def getTemperature(from: String): FState[Int]
case class State(temperature: Int, sumTemp: Long, count: Int)
// Получается то же самое, только вместо зависимости 'getNextConfig'
// мы, по сути, передаем сами данные - stream из конфигов
val handle =
foreach(configs) {
config => for (
nextValue <- getTemperature(config().source); // грузим значение температуры
state <- gets[State]; // тут мы берем текущее состояние
newState = State(nextValue, state.sumTemp + nextValue, state.count + 1);
_ <- puts(newState); // .. и меняем его
_ <- runInUiThread { drawOnScreen(newState) }
) yield()
}
Всех, кто заинтересовался, прошу под кат.
Читать полностью »
Лямбда-выражения Java 8 — это замыкания?
2016-04-06 в 7:10, admin, рубрики: functional programming, java, lambdas, Блог компании Издательский дом «Питер», книги, Профессиональная литература, функциональное программированиеРазвернутый ответ на вопрос, вынесенный в заглавие поста, приводится в статье Брюса Эккеля в редакции от 25 ноября 2015 года. Мы решили разместить здесь перевод этой статьи и поинтересоваться, что вы думаете о функциональном программировании в Java, а также об актуальности такой книги:

Приятного чтения!
Второй митап функциональных программистов в Москве (Erlang, Clojure и другие функциональные штуки)
2016-02-24 в 13:31, admin, рубрики: closure, erlang, Erlang/OTP, functional language, functional programming, functional thinking, javascript, Node, ruby, функциональное программирование 
Что будет: доклады, пицца, общение, отличный вечер четверга.
Список заявленных докладчиков и тем под катом.
Читать полностью »
Чисто-функциональный REST API на Finagle-Finch
2015-02-16 в 4:55, admin, рубрики: api, finagle, finch, functional programming, rest api, RESTful, scala
История библиотеки Finch началась около года назад «в подвалах» Конфеттина, где мы пытались сделать REST API на Finagle. Не смотря на то, что finagle-http сам по себе очень хороший инструмент, мы стали ощущать острую нехватку более богатых абстракциий. Кроме того, у нас были особые требования к этим самым абстракциям. Они должны были быть неизменяемыми (immutable), легко композируемыми (composable) и в тоже время очень простыми. Простыми как функции. Так появилась библиотека Finch, которая представляет собой очень тонкий слой функций и типов поверх finagle-http, который делает разработку HTTP (micro|nano)-сервисов на finagle-http более приятной и простой.
Шесть месяцев назад вышла первая стабильная версия библиотеки, а буквально на днях вышла версия 0.5.0, которую я лично считаю pre-alpha 1.0.0. За это время 6 компаний (три из них еще не в официальном списке: Mesosphere, Shponic и Globo.com) начали использовать Finch в production, а некоторые из них даже стали активными контрибьюторами.
Этот пост рассказывает о трех китах на которых построен Finch: Router, RequestReader и ResponseBuilder.
Читать полностью »
Эффективный JSON с функциональными концепциями и generics в Swift
2014-12-08 в 10:08, admin, рубрики: functional programming, generics, ios 8, mobile development, swift, вывод типов, Программирование, разработка под iOS, функциональное программированиеЭто перевод статьи Tony DiPasquale «Efficient JSON in Swift with Functional Concepts».
Предисловие переводчика.
Передо мной была поставлена задача: закачать данные в формате JSON с Flickr.com о 100 топ местах, в которых сделаны фотографии на данный момент, в массив моделей:
//------ Массив моделей Places
struct Places {
var places : [Place]
}
//-----Модель Place
struct Place {
let placeURL: NSURL
let timeZone: String
let photoCount : Int
let content : String
}
Кроме чисто прагматической задачи, мне хотелось посмотреть как в Swift работает «вывод типа из контекста» (type Inference), какие возможности Swift в функциональном программировании, и я выбрала для парсинга JSON алгоритмы из статьи Tony DiPasquale «Efficient JSON in Swift with Functional Concepts and Generics», в которой он «протягивает» generic тип Result<A> для обработки ошибок по всей цепочке преобразований: от запроса в сеть до размещения данных в массив Моделей для последующего представления в UITableViewController.
Чтобы посмотреть как Swift работает «в связке» с Objective-C, для считывания данных с Flickr.com использовался Flickr API, представленный в курсе Стэнфордского Университета «Stanford CS 193P iOS 7», написанный на Objective-C.
В результате помимо небольшого расширения Моделей:
extension Place: JSONDecodable {
static func create(placeURL: String)(timeZone: String)(photoCount: String)(content: String) -> Place {
return Place(placeURL: toURL(placeURL), timeZone: timeZone, photoCount: photoCount.toInt() ?? 0, content: content)
}
static func decode(json: JSON) -> Place? {
return _JSONParse(json) >>> { d in
Place.create
<^> d <| "place_url"
<*> d <| "timezone"
<*> d <| "photo_count"
<*> d <| "_content"
}
}
}
extension Places: JSONDecodable {
static func create(places: [Place]) -> Places {
return Places(places: places)
}
static func decode(json: JSON) -> Places? {
return _JSONParse(json) >>> { d in
Places.create
<^> d <| "places" <| "place"
}
}
}
мне самостоятельно пришлось написать только три строчки кода:
Читать полностью »
Функциональное программирование на coffeescript с библиотекой f_context
2014-12-08 в 6:35, admin, рубрики: coffeescript, functional programming, javascript, pattern matching, функциональное программированиеТем, кто сталкивался с функциональными языками программирования наверняка знакома такая конструкция:
fact(0) -> 1
fact(N) -> N * fact(N - 1)
Это один из классических примеров ФП — вычисление факториала.
Теперь это можно делать и на coffeescript'е с библиотекой f_context, просто добавляя «f_context ->» и немного табов, например:
f_context ->
fact(0) -> 1
fact(N) -> N * fact(N - 1)
F# адвент календарь по английски на 2014
2014-12-03 в 8:22, admin, рубрики: .net, .net frameowrk, functional programming, функциональное программированиеУ наших друзей из Японии есть замечательное событие, называемое F#-ский адвентский календарь. Каждый день, начиная с первого декабря по 31 декабря, один класный чел-доброволец пишет новую статью о F#. Это же просто замечательный подход для празднования Рождества, не правда ли?
Давайте же поддержим эту инициативу и сделаем английскую версию такого календаря. Две блог статьи в день лучше одного, неправда ли? Нам нужен 31 доброволец, готовый подготовить и опубликовать статью о F# в назначенный день.
Читать полностью »
Как я завел дружбу с асинхронностью в JavaScript
2014-10-21 в 18:14, admin, рубрики: event-driven programming, functional programming, javascript, асинхронное программирование
JavaScript встречает разработчиков асинхронностью можно сказать чуть ли не с порога. Начинается все с DOM-событий, ajax, таймерами и библиотечными методами, связанными с анимацией (например jQuery-методы fadeIn/fadeOut, slideUp/slideDown). В целом, это все не очень сложно и разобраться с асинхронностью на этом этапе не представляет проблем. Однако, как только мы переходим к написанию более или менее сложных приложений, в которых комбинируется все вышеуказанное, асинхронный поток может сильно затруднить понимание происходящего в коде. Цепочки асинхронных действий, например, анимация > ajax-запрос > инициализация -> анимация, создают достаточно сложную архитектуру, которая не подчиняется строгому направлению «снизу верх». В этой статье я намерен рассказать про свой опыт преодоления трудностей связанных с асинхронным JS.
Читать полностью »
Трансдьюсеры в JavaScript. Часть вторая
2014-09-23 в 14:00, admin, рубрики: clojure, clojurescript, FRP, functional programming, javascript, transducer, transducers, Программирование, реактивное программирование, функциональное программирование В первой части мы остановились на следующей спецификации: Трансдьюсер — это функция принимающая функцию step, и возвращающая новую функцию step.
step⁰ → step¹
Функция step, в свою очередь, принимает текущий результат и следующий элемент, и должна вернуть новый текущий результат. При этом тип данных текущего результата не уточняется.
result⁰, item → result¹
Чтобы получить новый текущий результат в функции step¹, нужно вызвать функцию step⁰, передав в нее старый текущий результат и новое значение, которое мы хотим добавить. Если мы не хотим добавлять значение, то просто возвращем старый результат. Если хотим добавить одно значение, то вызываем step⁰, и то что он вернет возвращаем как новый результат. Если хотим добавить несколько значений, то вызываем step⁰ несколько раз по цепочке, это проще показать на примере реализации трансдьюсера flatten:
function flatten() {
return function(step) {
return function(result, item) {
for (var i = 0; i < item.length; i++) {
result = step(result, item[i]);
}
return result;
}
}
}
var flattenT = flatten();
_.reduce([[1, 2], [], [3]], flattenT(append), []); // => [1, 2, 3]
Т.е. нужно вызывать step несколько раз, каждый раз сохраняя текущий результат в переменную, и передавая его при следующем вызове, а в конце вернуть уже окончательный.
В итоге получается, что при обработке каждого элемента, одна функция step, вызывает другую, а та следующую, и так до последней служебной функции step, которая уже сохраняет результат в коллекцию (append из первой части).
Итак, сейчас мы можем:
- Изменять элементы (прим. map)
- Пропускать элементы (прим. filter)
- Выдавать для одного элемента несколько новых (прим. flatten)
