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

    • Tutorial

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


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


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

    Читать дальше →
  • Данные высокого рода

      Да-да, вам не привиделось и вы не ослышались — именно высокого рода. Род (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
        }

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

      Тут можно и поэтому данный метод широко используется среди авторов библиотек на Хаскеле.
      Читать дальше →
      • +16
      • 2,7k
      • 7
    • Как сделать ещё больше некорректных состояний ещё более невыразимыми

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

        Читать дальше →
      • Красота НЕ-безымянных функций в JavaScript

          image


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

          Читать дальше →
          • +23
          • 8,4k
          • 7
        • Самое краткое введение в Reactive Programming

            Цель данной статьи – показать на примере зачем нужно 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 «на коленке»

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

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

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

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


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

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


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


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


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


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


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


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

                Читать дальше →
              • Великая сила newtypes

                  НовыйТип (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 не ограничивается лишь эффективностью вычислений. Они значительно сильнее!
                  Читать дальше →
                  • +13
                  • 2,7k
                  • 2
                • Как сделать функции на Python еще лучше

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

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

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

                  Самое читаемое