Рубрика «функциональное программирование» - 48

Внимание: перед тем как читать текст ниже, вы уже должны иметь представление о том, что такое монады. Если это не так, то прежде прочитайте вот этот пост!

Перед нами функция half:
Тройка полезных монад

И мы можем применить её несколько раз:

half . half $ 8
=> 2

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

half x = (x `div` 2, "Я только что располовинил  " ++ (show x) ++ "!")

Что ж, отлично. Но что будет если вы теперь захотите применить half несколько раз?

half . half $ 8

Вот то, что мы хотели бы, чтобы происходило:
Тройка полезных монад

Спойлер: автоматически так не сделается. Придётся всё расписывать ручками:

finalValue = (val2, log1 ++ log2)
    where (val1, log1) = half 8
          (val2, log2) = half val1

Фу! Это ни капли не похоже на лаконичное

half . half $ 8

А что, если у вас есть ещё функции, имеющие лог? Напрашивается такая схема: для каждой функции, возвращающей вместе со значением лог, мы бы хотели объединять эти логи. Это побочный эффект, а никто не силён в побочных эффектах так, как монады!
Читать полностью »

Предисловие

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

В первый раз время наступило после второго курса. Я был уверен, что полученных знаний языка C мне хватит, чтобы в одиночку написать и компилятор, и виртуальную машину, и всю стандартную библиотеку к нему. Задумка была элегантна и дышала романтикой юношеского максимализма, но вместо этого результатом двух лет прилежной работы стало монструозное нечто. Даже несмотря на то, что виртуальная машина подала признаки жизни и смогла исполнить довольно несложные скрипты на псевдоассемблере, который помог написать боевой товарищ fornever, проект был вскоре заброшен. Вместо этого было решено написать язык для платформы .NET, чтобы нахаляву получить автоматическую сборку мусора, jit-компилятор и все прелести огромнейшей библиотеки классов. Компилятор был реализован всего за полгода, исходный код выложен на CodePlex, и с ним я успешно защитил диплом.

Однако чего-то по-прежнему не хватало. При всех своих преимуществах, разработанный для диплома язык требовал явного объявления всех типов и функций, не имел никакой поддержки generic'ов, не умел создавать анонимные функции, да и вообще область его применения была неясна. Решение изобрести еще один велосипед пришло спустя год, когда мне написал знакомый, учившийся на моей же кафедре на два года младше. Он предложил «помочь» ему в написании дипломной работы, и я согласился. К новому языку были поставлены следующие требования:

  • Взаимодействие с любыми доступными типами .NET без явного импорта
  • Поддержка generic'ов
  • Поддержка анонимных функций и замыканий
  • Наличие хоть какой-нибудь практической ценности

Вышеупомянутый fornever изъявил желание поучаствовать, и работа закипела. Он принимал активное участие в создании дизайна языка и написал парсер на F#, а я занялся описанием синтаксического дерева и внутренней инфраструктуры.

На днях знакомый защитил-таки свой диплом, поэтому репозиторий проекта на Github теперь открыт для всех желающих. Дальше в статье я расскажу о том, что в результате получилось, какие подводные камни встретились на пути, и почему у статьи такой желтый заголовок.Читать полностью »

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

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

Пользователи хотели иметь возможность составлять данные так, как они сами того хотят. Хотели, хотят, и наверняка будут хотеть. Всё больше, всё разнообразней и сильнее.
Именно поэтому полезно проследить за развитием пользовательских типов данных в программах и языках программирования.
Читать полностью »

В статье приведено решение и описано его использование. Заказывайте темы для следующих статей в ЛС.

Тут можно получить информацию

  • примеры использования CoffeeScript
  • “классовое” ООП с CoffeeScript
  • примеры удачных решений структуры алгоритма
  • jQuery вместе с CoffeeScript
  • микрошаблонизатор на CoffeeScript

Читать полностью »

Во времена, когда я писал на Лиспе и совсем не был знаком с ООП, я пытался найти паттерны проектирования, которые мог бы применить у себя в коде. И всё время натыкался на какие-то жуткие схемы классов. В итоге сделал вывод, что эти паттерны в функциональном программировании не применимы.

Теперь я пишу на Питоне и с ООП знаком. И паттерны мне теперь намного понятней. Но меня по-прежнему воротит от развесистых схем классов. Многие паттерны прекрасно работают в функциональной парадигме. Опишу несколько примеров.Читать полностью »

Язык InterSystems Caché ObjectScript (COS) развивается с каждым годом (в версии 2013.1 появилась команда return, в 2012.2регулярные выражения), и в него добавляются новые команды и операторы. К сожалению, в настоящий момент подпрограммы в COS не являются объектами первого класса, то есть подпрограмму (функцию, метод) нельзя передать как параметр в подпрограмму или вернуть из подпрограммы.

Тем не менее, существуют способы смягчить эти ограничения.

Под катом рассмотрим несколько вариантов передачи кода как аргумента подпрограммы.
Читать полностью »

Немного интересного из мира CoffeeScript

Читать полностью »

Вот некое простое значение:
Функторы, аппликативные функторы и монады в картинках

И мы знаем, как к нему можно применить функцию:
Функторы, аппликативные функторы и монады в картинках

Элементарно. Так что теперь усложним задание — пусть наше значение имеет контекст. Пока что вы можете думать о контексте просто как о ящике, куда можно положить значение:
Функторы, аппликативные функторы и монады в картинках

Теперь, когда вы примените функцию к этому значению, результаты вы будете получать разные — в зависимости от контекста. Это основная идея, на которой базируются функторы, аппликативные функторы, монады, стрелки и т.п. Тип данных Maybe определяет два связанных контекста:
Функторы, аппликативные функторы и монады в картинках

data Maybe a = Nothing | Just a

Позже мы увидим разницу в поведении функции для Just a против Nothing. Но сначала поговорим о функторах!
Читать полностью »

Доказательство упрощением

Итак, в предыдущих частях мы определили новые типы данных и функции над ними. Настало время обратиться к вопросу о том, как сформулировать и доказать их свойства и поведение. В некотором смысле мы уже начали делать это – в первой части мы написали своего рода юнит-тест, используя ключевое слово Example, который содержал некоторые утверждения о поведении некоторой функции, применяемой к определенному набору аргументов. Используя определение функции, Coq упрощает выражение и проверяет на равенство его левую и правую часть.Читать полностью »

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

Ранее я сказал, что в Coq нет батареек. На самом деле я слукавил — в Coq есть стандартная библиотека, которая содержит множество полезных определений. Помимо стандартной библиотеки существуют и более специфические вещи, на которых мы пока не будем останавливаться.
Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js