Все потоки
Поиск
Написать публикацию
Обновить
14.29

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

От Lisp до Haskell

Сначала показывать
Порог рейтинга
Уровень сложности

Ленивые функции в JavaScript

Время на прочтение3 мин
Количество просмотров12K

Привет!


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

Читать дальше →

Функциональная обработка ошибок в Kotlin с помощью Arrow

Время на прочтение4 мин
Количество просмотров10K
image

Привет, Хабр!

Все любят runtime exceptions. Нет лучшего способа узнать о том, что что-то не было учтено при написании кода. Особенно — если исключения обваливают приложение у миллионов пользователей, и эта новость приходит паническим email'ом с портала аналитики. В субботу утром. Когда ты в загородной поездке.

После подобного всерьез задумываешься о обработке ошибок — и какие же возможности предоставляет нам Kotlin?

Первым на ум приходит try-catch. По мне — отличный вариант, но у него есть две проблемы:

  1. Это как-никак лишний код (вынужденная обертка вокруг кода, не лучшим образом сказывается на читаемости).
  2. Не всегда (особенно при использовании сторонних библиотек) из блока catch возможно получить информативное сообщение о том, что конкретно вызвало ошибку.

Давайте посмотрим во что try-catch превращает код при попытке решения вышеозвученных проблем.
Читать дальше →

Принципы функционального программирования в JavaScript

Время на прочтение17 мин
Количество просмотров66K
Автор материала, перевод которого мы публикуем сегодня, говорит, что он, после того, как долго занимался объектно-ориентированным программированием, задумался о сложности систем. По словам Джона Оустерхаута, сложность (complexity) — это всё, что делает тяжелее понимание или модификацию программного обеспечения. Автор этой статьи, выполнив некоторые изыскания, обнаружил концепции функционального программирования наподобие иммутабельности и чистых функций. Применение таких концепций позволяет создавать функции, не имеющие побочных эффектов. Использование этих функций упрощает поддержку систем и даёт программисту некоторые другие преимущества.

image

Здесь мы поговорим о функциональном программировании и о некоторых его важных принципах. Всё это будет проиллюстрировано множеством примеров кода на JavaScript.
Читать дальше →

Квинтет как базовая сущность для описания предметной области

Время на прочтение10 мин
Количество просмотров6.6K
Квинтет — это способ записать атомарные фрагменты данных с указанием их роли в нашей жизни. Квинтетами можно описать любые данные, при этом каждый из них содержит исчерпывающую информацию о себе и о связях с другими квинтетами. Он представляет термины предметной области, независимо от используемой платформы. Его задача — упростить хранение данных и улучшить наглядность их представления.



Я расскажу о новом подходе к хранению и обработке информации и поделюсь мыслями о создании платформы разработки в этой новой парадигме.
Взглянуть по-новому на известные вещи

Как обрабатывать ошибки на JVM быстрее

Время на прочтение5 мин
Количество просмотров5.8K

Существуют различные способы обработки ошибок в языках программирования:


  • стандартные для многих языков исключения (Java, Scala и прочий JVM, python и многие другие)
  • коды статуса или флаги (Go, bash)
  • различные алгебраические структуры данных, значениями которых могут быть как успешные результаты так и описания ошибок (Scala, haskell и другие функциональные языки)

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


Последнее время я работаю со Scala, где в равной мере я могу использовать как исключения так и различные типы данных для обработки ошибок, поэтому интересно какой из подходов будет удобнее и быстрее.


Сразу отбросим использование кодов и флагов, так как этот подход не принят в JVM языках и по моему мнению слишком подвержен ошибкам (прошу прощения за каламбур). Поэтому будем сравнивать исключения и разные виды АТД. Кроме того АТД можно рассматривать как использование кодов ошибок в функциональном стиле.


UPDATE: к сравнению добавлены исключения без стек-трейсов

Читать дальше →

О композиции функций в JavaScript

Время на прочтение4 мин
Количество просмотров15K

Давайте пофантазируем на тему функциональной композиции, а так же проясним смысл оператора композиции/пайплайна.


TL;DR
Compose functions like a boss:
image
Популярные реализации compose — при вызове создают новые и новые функции на основе рекурсии, какие здесь минусы и как это обойти.

Читать дальше →

Проектирование типами: Как сделать некорректные состояния невыразимыми на C#

Время на прочтение9 мин
Количество просмотров7.2K

Как правило статьи, рассказывающие о проектировании типами, содержат примеры на функциональных языках — Haskell, F# и других. Может показаться, что эта концепция неприменима к объектно-ориентированным языкам, но это не так.


В этой статье я переведу примеры из статьи Скотта Власчина Проектирование типами: Как сделать некорректные состояния невыразимыми на идиоматический C#. Также я постараюсь показать, что этот подход применим не только в качестве эксперимента, но и в рабочем коде.

Читать дальше →

Голосование по второй бета-версии Revised 7 Report on Algorithmic Language Scheme (Large Language)

Время на прочтение2 мин
Количество просмотров2K


Открыто голосование по содержанию второй (из восьми) бета-редакции алгоритмического языка Scheme R7RS-large (Tangerine Edition), а также сбор предложений по третьей бета-редакции (Orange Edition).
Читать дальше →

Учим поросёнка на моноидах верить в себя и летать

Время на прочтение14 мин
Количество просмотров11K

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



Я провёл простое тестирование и убедился в том, что на простых задачах, использующих только стек, виртуальная машина работает шустро, а при использовании "памяти" — массива со случайным доступом — начинаются большие проблемы. О том, как удалось их решить, не меняя базовых принципов архитектуры программы и достичь тысячекратного ускорения работы программы, и пойдёт речь в предлагаемой вашему вниманию статье.

Читать дальше →

Стековая машина на моноидах

Время на прочтение32 мин
Количество просмотров15K

Не так давно на Хабре появилась отличная и вдохновляющая статья про компиляторы и стековые машины. В ней показывается путь от простой реализации исполнителя байт-кода ко всё более и более эффективным версиям. Мне захотелось показать на примере разработки стековой машины, как это можно сделать Haskell-way.


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


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

Читать дальше →

Данные высокого рода

Время на прочтение8 мин
Количество просмотров7.1K
Да-да, вам не привиделось и вы не ослышались — именно высокого рода. Род (kind) — это термин теории типов, означающий по сути тип типа [данных].

Но вначале немного лирики.

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

Эта статься — мои пять копеек в этот хайп. Мы рассмотрим валидацию данных в Хаскеле.

Валидация типом


Ранее было рассмотрен пример методики валидации при помощи валидации типом:

type EmailContactInfo  = String
type PostalContactInfo = String

data ContactInfo = EmailOnly EmailContactInfo | 
                   PostOnly PostalContactInfo | 
                   EmailAndPost (EmailContactInfo, PostalContactInfo)

data Person = Person 
  { pName :: String,
  , pContactInfo :: ContactInfo,
  }

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

Валидация данными высокого рода




В этой статье мы посмотрим иной метод валидации — при помощи данных высокого рода.

Пусть у нас есть тип данных:

data Person = Person
  { pName :: String
  , pAge  :: Int
  }

И мы будем валидировать данные лишь в том случае, когда валидны все поля записи.
Поскольку Хаскель по функциональным возможностям на голову превосходит большинство функциональных языков, на нём можно легко избавится от большинства рутины.

Тут можно и поэтому данный метод широко используется среди авторов библиотек на Хаскеле.
Читать дальше →

Красота НЕ-безымянных функций в JavaScript

Время на прочтение3 мин
Количество просмотров12K

image


Анонимные стрелочные функции в JavaScript, согласно некоторым опросам — самая популярная фича ES-2015, что также подчеркнуто исчерпывающим числом туториалов в интернете. Они бесспорно очень полезны, но в этой небольшой статье мы рассмотрим примеры использования обделенных вниманием не менее замечательных выражений с именованными функциями — NFE.

Читать дальше →

Самое краткое введение в Reactive Programming

Время на прочтение3 мин
Количество просмотров22K

Цель данной статьи – показать на примере зачем нужно reactive programming, как оно связано с функциональным программированием, и как с его помощью можно писать декларативный код, который легко адаптировать к новым требованиям. Кроме того, хочется сделать это максимально кратко и просто на примере приближенном к реальному.


Возьмем такую задачу:
Есть некий сервис c REST API и endpointом /people. При POST-запросе на этот endpoint'a создается новая сущность. Написать функцию которая принимает массив объектов вида { name: 'Max' } и создают набор сущностей посредством API(по-английски, это называется batch-операция).


Давайте решим эту задачу в императивном стиле:


const request = require('superagent')

function batchCreate(bodies) {
  const calls = []
  for (let body of bodies) {
    calls.push(
      request
        .post('/people')
        .send(body)
        .then(r => r.status)
    )
  }
  return Promise.all(calls)
}

Давайте, для сравнения, перепишем этот кусочек кода в функциональном стиле. Для простоты, под функциональным стилем мы будем понимать:


  1. Применение функциональных примитивов(.map, .filter, .reduce) вместо императивных циклов(for, while)
  2. Код организован в "чистые" функции – они зависят только от своих аргументов и не зависят от состояния системы
Читать дальше →

Ближайшие события

Парсим X12 «на коленке»

Время на прочтение13 мин
Количество просмотров2.6K
imageПри создании приложения, активно взаимодействующего со сторонними сервисами и системами, часто требуется обеспечить обмен информацией с ними, односторонний или двусторонний

При этом зачастую сторонний сервис предоставляет единственный формат и структуры данных для такого взаимодействия.

Одним из таких форматов электронного документооборота является EDI ANSI ASC X12, достаточно подробное описание которого приведено по ссылке.

КДПВ была взята с этого сайта


Под катом приведен простой алгоритм парсера X12 и код на Clojure, реализующий парсер и пример обработки распарсенных данных.
Читать дальше →

Книга «App from scratch»

Время на прочтение2 мин
Количество просмотров4.6K

Я написал книгу, предварительный релиз, о создании веб-приложений с нуля.


Я прочитал много книг по программированию, но, часто, после прочтения у меня оставался только один вопрос — Как мне применить эти знания на практике?


Предположим, вы разработчик системы автоматизации, портала или интернет-магазина.
Добавление новой функциональности осложняется наслоениями кода. Запуск тестов занимает полчаса, а релиз — час. Идея о переходе на новую версию фреймворка вызывает нервные подергивания. Вы узнаёте, что PostgreSQL имеет поддержку массивов, jsonb, полнотекстового поиска и lateral join, но ORM не позволяет использовать их в полную силу. Вы прочитали про TDD, но как писать в таком стиле, когда аналитик описывает сценарии, а фреймворк требует создания модели, контроллера и представления?


Как применить SOLID, если сущности наследуют от ORM?


Как избавиться от боли?


Постепенно, по мере изучения Clojure, и, наконец после прочтения Clean Architecture, я понял, как без боли написать приложение, где на первом месте стоит предметная область, а не фреймворк, где я принимаю решения, а не создатели фреймворков навязывают свои.


В какой-то степени книгу можно рассматривать как практический самоучитель по Clojure,
так что знание этого языка не требуется.

Читать дальше →

Великая сила newtypes

Время на прочтение7 мин
Количество просмотров4.9K
НовыйТип (newtype) — это специализированное объявление типа данных. Такое, что содержит лишь один конструктор и поле.

newtype Foo a = Bar a
newtype Id = MkId Word


Типичные вопросы новичка


В чём же отличие от data типа данных?

data Foo a = Bar a
data Id = MkId Word

Главная специфика newtype состоит в том, что он состоит из тех же частей, что и его единственное поле. Более точно — отличаясь от оригинала на уровне типа, но имеет такое же представление в памяти, да и вычисляется строго (не лениво).
Если вкратце — newtype более эффективны благодаря своему представлению.

Да это ничего не значит для меня… Буду использовать data
Не, ну в конце-концов, всегда можно включить расширение -funpack-strict-fields :) для строгих(не ленивых) полей или указать прямо

data Id = MkId !Word

Всё же сила newtype не ограничивается лишь эффективностью вычислений. Они значительно сильнее!
Читать дальше →

Как сделать функции на Python еще лучше

Время на прочтение12 мин
Количество просмотров52K
Собственно, заголовок этой замечательной статьи от Джеффа Кнаппа (Jeff Knupp), автора книги "Writing Idiomatic Python" полностью отражает ее суть. Читайте внимательно и не стесняйтесь комментировать.

Поскольку очень не хотелось оставлять в тексте важный термин латиницей, мы позволили себе перевести слово «docstring» как «докстрока», обнаружив этот термин в нескольких русскоязычных источниках.
Читать дальше →

Списки в Kotlin. Haskell подход

Время на прочтение10 мин
Количество просмотров12K
Haskell является полностью функциональным и чрезвычайно лаконичным языком. Любой, кто когда-нибудь пробовал писать код на Haskell, замечает, насколько он получается более кратким и изящным, чем написать то же самое на императивном языке. Добиться такого же на Java, на мой взгляд, невозможно, но Kotlin позволяет продвинуться в этом направлении и примерить на себе полностью функциональный стиль. Мы можем вывести все сложные функции, которые нам могут понадобится из стартового базиса 3-х наиболее известных функций: map, filter, reduce. Кроме этого я создал репозиторий, который вы можете изучить и посмотреть тесты.
Читать дальше →

Секреты невозможных вычислений на GPU

Время на прочтение9 мин
Количество просмотров29K
Наш опыт использования вычислительного кластера из 480 GPU AMD RX 480 при решении математических задач. В качестве задачи мы взяли доказательство теоремы из статьи профессора Чуднова А.М. “Циклические разложения множеств, разделяющие орграфы и циклические классы игр с гарантированным выигрышем“. Задача заключается в поиске минимального числа участников одной коалиции в коалиционных играх Ним-типа, гарантирующее выигрыш одной из сторон.


Читать дальше →

Функциональное программирование: семь раз отмерь, один раз отрежь

Время на прочтение4 мин
Количество просмотров9.2K
Добрый день! Последнее время я очень часто слышу о том, что пришел закат ООП. Сегодня все больше людей переходят на функциональную парадигму. Скоро людей, которые пишут на C++/C#/Java, вообще не останется. Так ли это? Не думаю. На мой взгляд, бездумное использование ФП (функциональное программирование) может стать затратной по времени и лишней головной болью, которая совершенно не сочетается с текущими проектными решениями. Давайте убедимся в этом!

image
Читать дальше →