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

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

От Lisp до Haskell

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

Лямбда-исчисление на JavaScript

Время на прочтение8 мин
Количество просмотров63K
Привет! В этой статье я хочу в очередной раз взглянуть на лямбда-исчисление. Теоретическую сторону вопроса на хабре обсуждали уже множество раз, поэтому взглянем на то, как лямбда-исчисление может выглядеть на практике, например, на языке JavaScript (чтобы примеры можно было выполнять прямо в браузере).

Итак, основная идея: всё есть функция. Поэтому мы ограничим себя очень узким кругом возможностей языка: любое выражение будет либо анонимной функцией с одним аргументом (x => expr), либо вызовом функции (f (x)). То есть весь код будет выглядеть похожим образом:

id = x => x
double = f => x => f (f (x))

Поскольку результатом работы функций будут другие функции, нам понадобится способ интерпретировать результат. Это единственное место, в котором пригодятся нетривиальные возможности JavaScript.
Читать дальше →

Монадные трансформеры для практикующих программистов

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

Прикладное введение в монадные трансформеры, от проблемы к решению


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


Всё как обычно: несколько лаконичных однострочных выражений (да, детка, это Scala!), несколько странных ошибок компилятора (о, нет, Scala, нет!), лёгкое сожаление о том, что вы написали такой запутанный код… И вдруг вы сталкиваетесь со странной проблемой: выражение for не компилируется. «Ничего страшного», — думаете вы: «сейчас гляну на StackOverflow», как вы это делаете ежедневно. Как все мы это делаем ежедневно.


Но сегодня, похоже, неудачный день.


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

Заклиная техническое интервью

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

Предлагаю читателям "Хабрахабра" перевод (возможно лучшей) статьи Kyle Kingsbury, a.k.a "Aphyr".


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


Видрун, зачатая от морских ветров в верхушках елей,
Видрун, зелень моих ветвей, радость и ноша моих дней,
Видрун, всех вдохновенней и умней, да станет мудрость нашего клана твоей:
Никогда не читай Hacker News
Читать дальше →

Пишем свои монады на Scala на примере CSV-парсера

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

За последнее время мы очень многое узнали о монадах. Мы уже разобрались что это такое и даже знаем как их можно нарисовать, видели доклады, объясняющие их предназначение. Вот и я решил заскочить в уходящий монадный поезд и написать по этой теме, пока это окончательно не стало мейнстримом. Но я зайду с немного другой стороны: здесь не будет выкладок из теории категорий, не будет вставок на самом-лучшем-языке, и даже не будет scalaz/shapeless и библиотеки parser-combinators. Как известно, лучший способ разобраться как что-то устроено — сделать это самому. Сегодня мы с вами будем писать свою монаду.


image


Задача


Возьмем для примера банальную задачу: парсинг CSV-файла. Допустим нам требуется распарсить строки файла в case classes, чтобы потом отправить их в базу, сериализовать в json/protobuf и так далее. Забудем про escaping и кавычки, для еще большей простоты, считаем что символ разделителя в полях встречаться не может. Думаю, если кто-то решит затащить это решение в свой проект, докрутить эту фичу будет не трудно.


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

«Да ты же просто робот, имитация. Разве может робот написать симфонию?» — интервью о ИИ с Дмитрием Сошниковым, Microsoft

Время на прочтение9 мин
Количество просмотров9.3K
Разработка элементов систем искусственного интеллекта активно развивается и становится трендом сегодняшнего времени, а умных ботов сейчас и вовсе не пишет только ленивый. Именно поэтому мы взяли интервью у Дмитрия shwars Сошникова, одного из лучших в стране экспертов по ИИ. Он является технологическим евангелистом Microsoft, автором книг, статей и учебных пособий, а также преподавателем и координатором студенческих программ, специалистом по функциональному программированию, нейросетям и искусственному интеллекту.


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

Онлайн-курсы весеннего семестра от Академического университета и CS центра

Время на прочтение2 мин
Количество просмотров6.1K
Коллекция онлайн-курсов, подготовленных преподавателями Академического университета (СПбАУ РАН) и Computer Science Center, насчитывает уже почти 20 бесплатных курсов по программированию и математике.

Все онлайн-курсы разработаны на платформе Stepik.org, их может проходить любой желающий. Количество курсов продолжает расти, и этой весной запускаются несколько новинок:



  • Алгоритмы: теория и практика. Структуры данных (А. С. Куликов)
  • Операционные системы (М.Ю. Кринкин)
  • Функциональное программирование на языке Haskell (часть 2) (Д. Н. Москвин)
Подробнее о курсах

Курсы Computer Science клуба, весна 2017

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

Computer Science клуб вот уже 10 лет проводит открытые курсы по компьютерным наукам. Большинство лекций стараниями Лекториума записаны на видео и лежат в открытом доступе. В этом семестре выложены уже три новых курса, которые до этого не читались в клубе: «Программирование с зависимыми типами на языке Idris», «Вычисления на GPU. Основные подходы, архитектура, оптимизации», «Методы и системы обработки больших данных».
Читать дальше →

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

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

В данной статье будет рассмотрено функциональное программирование на примере скрипта поиска битых ссылок с использованием AnyEvent::HTTP. Будут рассмотрены следующие темы:


  • анонимные подпрограммы;
  • замыкания (closures);
  • функции обратного вызова (callbacks);
Читать дальше →

Программисты жизни

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

Скетч-шоу «Нереальная история»

С самого нашего первого крика при рождении и до последнего вздоха в конце жизни нас программируют. Родители, друзья, учителя и даже врачи. Нас окружают правила и законы, алгоритмы и различные руководства. Я хочу выделить один комментарий к моей последней публикации от пользователя Zoomerman:
Программист — человек, создающий программы.
Программист выстраивает цепочку событий, используя доступное множество ресурсов.
Программы бывают компьютерные, музыкальные, поведенческие, обучающие и т.д.
Программа начинает создаваться в тот момент, когда человек определяет начальную и конечную точки процесса.
И если менеджер говорит «у меня есть товар, хочу его поменять на деньги» — он превращается в программиста и строит алгоритм этого процесса.
Для меня программист — это не каста и не профессия. Программист — это состояние ума.
Читать дальше →

Scala: parser combinators на примере парсера формул

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

Время от времени у меня возникает желание придумать свой собственный маленький язык программирования и написать интерпретатор. В этот раз я начал писать на scala, узнал про библиотеку parser combinators, и был поражён: оказывается, можно писать парсеры легко и просто. Чтобы не превращать статью в пособие по "рисованию совы", ниже приведёна реализация разбора и вычисления выражений типа "1 + 2 * sin(pi / 2)".


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


Для сравнения:



Итак, если вам не терпится увидеть результат:


Ответственный за парсинг кусочек кода
object FormulaParser extends RegexParsers with PackratParsers {

    def id: Parser[Id] = "[a-zA-Z][a-zA-Z0-9_]*".r ^^ Id

    def number: Parser[Number] = "-" ~> number ^^ (n => Number(-n.value)) |
        ("[0-9]+\\.[0-9]*".r | "[0-9]+".r) ^^ (s => Number(s.toDouble))

    def funcCall: Parser[FuncCall] = id ~ ("(" ~> expression <~ ")") ^^ {case id ~ exp => FuncCall(id, exp)}

    def value: Parser[Expression] = number | funcCall | id | ("(" ~> expression <~ ")")

    lazy val term: PackratParser[Expression] = term ~ ("*" | "/") ~ value ^^ binOperation | value

    lazy val expression: PackratParser[Expression] = expression ~ ("+" | "-") ~ term ^^ binOperation | term
    ...
}

Посмотрите на следущую строчку:


def value: Parser[Expression] = number | funcCall | id | ("(" ~> expression <~ ")")

Она подозрительно похожа на описание грамматики, но это валидный код, в котором среда разработки может сразу же обнаружить и подсветить большинство ошибок.


Это возможно по следующим причинам:


  1. В scala разрешено давать методам замечательные названия типа "~", "~>", "<~", "|", "^^". Комбинация парсеров p и q записывается как p~q, а возможность выбрать один из них: p|q. Читается намного лучше, чем p.andThen(q) или p.or(q)
  2. Благодаря неявным преобразованиям (implicits) и строчка "abc" и регулярное выражение "[0-9]+".r при необходимости превращаются в парсеры.
  3. В языке мощная статическая система типов, которая позволяет ловить ошибки сразу.

Думаю, мне удалось Вас заинтересовать, поэтому дальше всё будет по порядку.


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

Вы знаете, что такое трансдьюсеры

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

Трансдьюсеры были анонсированы еще в далеком 2014, с тех пор по ним было написано немалое количество статей (раз, два), но ни после одной статьи я не мог сказать, что понимаю трансдьюсеры кристально ясно. После каждой статьи у меня возникало ощущение, что я приблизительно понимаю что-то сложное, но оно все равно оставалось сложным. А потом однажды в голове что-то щелкнуло: "я ведь уже видел этот паттерн, только он назывался иначе!"

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

Функциональный C#

Время на прочтение5 мин
Количество просмотров25K
C# — язык мультипарадигмальный. В последнее время крен наметился в сторону функциональщины. Можно пойти дальше и добавить еще немного методов-расширений, позволяющих писать меньше кода, не «залезая» при этом на территорию F#.
Читать дальше →

Модульные приложения на Java. Как?

Время на прочтение6 мин
Количество просмотров19K
То, что в Java не поддерживается модульность, известно всем. Проблема существует давно, и было немало попыток исправить ситуацию. Этой цели посвящен проект Jigsaw. В 2011 планировалось добавить поддержку модульности в Java 7, в 2014 – в Java 8, наконец, было анонсировано, что в конце июля 2017 выйдет Java 9 с возможностью модуляризации. Но что же делать в ожидании этого прекрасного мига?

OSGi спешит на помощь


Для создания по-настоящему модульной архитектуры на языке Java можно воспользоваться OSGi (Open Services Gateway Initiative) – спецификацией динамической модульной системы и сервисной платформы для Java-приложений (разработчик OSGi Alliance). Она описывает модель разработки ПО, при которой компоненты обладают тремя основными признаками модульного приложения. Речь об инкапсуляции (каждый модуль скрывает свою реализацию от внешнего окружения), слабой связности (модули взаимодействуют только с помощью заранее оговоренных контрактов) и динамичности (компоненты можно замещать на лету, без остановки всего приложения). Основой концепции OSGi являются 2 сущности: наборы (Bundles) и сервисы (Services).
Читать дальше →

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

Как я стал лучше программировать

Время на прочтение6 мин
Количество просмотров48K
Автор статьи — Джеймс Лонг, один из создателей Firefox Developer Tools

Несколько человек на React Conf спросили у меня совета, как программировать лучше. По какой-то причине люди видят во мне продвинутого программиста, к советам которого стоит прислушаться. Я подумал, стоит записать «ментальную модель» того, как я подходил к программированию на протяжении всех лет.

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

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

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

Время на прочтение8 мин
Количество просмотров27K
Функциональное программирование (далее ФП) нынче в моде. Статьи, книги, блоги. На каждой конференции обязательно присутствуют выступления, где люди рассказывают о красоте и удобстве функционального подхода. Я долгое время смотрел в его сторону издалека, но пришла пора попробовать применить его на практике. Прочитав достаточное количество теории и сложив в голове общую картину я решил написать небольшое приложение в функциональном стиле. Так как в данный момент я c++ программист, то буду использовать этот замечательный язык. За основу я возьму код из моей предыдущей статьи, т.е. моим примером будет упрощенная 2Д симуляция физических тел.

Разработка R&D-проектов продолжается: запуск Wolfram Language 11.1

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

Перевод поста Стивена Вольфрама (Stephen Wolfram) "The R&D Pipeline Continues: Launching Version 11.1".
Выражаю огромную благодарность Полине Сологуб за помощь в переводе и подготовке публикации


Содержание


Небольшой релиз — тоже неплохо
Визуальные изменения
Множество новых функций
Нейросети
Машинное обучение
Аудио
Изображения и визуализация
Больше данных
Интегрированные внешние сервисы
Больше математики, больше алгоритмов
Детализация дат
Настройка языка
Язык хранения
Программирование на низком уровне
Укрепление инфраструктуры
И еще кое-что


Небольшой релиз — тоже неплохо


Я рад сообщить о том, что сегодня вышла версия 11.1 языка Wolfram Language (и системы Wolfram Mathematica). На данный момент, версия 11.1 уже работает в Wolfram Cloud, а Desktop-версии уже доступны для загрузки для Mac, Windows и Linux.

Что нового в версии 11.1? На самом деле много чего. Если кратко:



В ней очень много нового. Можно подумать, что релиз .1 спустя почти 29 лет после выхода версии 1.0 вряд ли удивит. Однако в случае с нашей компанией дела обстоят иначе. С тех пор, как мы построили весь стек доступных сейчас технологий, мы лишь ускоряемся в своем развитии. И теперь даже в версии 11.1 представлено множество новых функциональных возможностей.
Читать дальше →

Немного о функторах и функциях высшего порядка в Swift

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

Коллекции


Разработчики, перешедшие на Swift с Objective-C, не могли не заметить удобнейший функционал, который предоставляет Swift для работы с коллекциями. Использование диапазонов в индексах
let slice = array[1..<10]
удобный синтаксис инициализации и добавления элемента в коллекцию, расширяемость, и, конечно функции высшего порядка

Filter


Самой часто используемой функцией для коллекций, пожалуй, является filter
let alex = Person(name: "Alex", age: 23)
let jenny = Person(name: "Jenny", age: 20)
let jason = Person(name: "Jason", age: 35)
let persons = [alex, jenny, jason]
let jNamedPersons = persons.filter { $0.name.hasPrefix("J") } // [jenny, jason]


Reduce


Реже используемой, но при этом крайне выразительной и удобной является функция reduce

let ages = persons.map{ Float($0.age) }
let average = ages.reduce(0, +) / Float(persons.count)


Можно писать свои функции высшего порядка и это довольно увлекательно:
func divisible(by numbers: Int...) -> (Int) -> Bool {
    return { input -> Bool in
        return numbers.reduce(true) { divisible, number in
            divisible && input % number == 0
        }
    }
}

let items = [6, 12, 24, 13]
let result = items.filter(divisible(by: 2, 3, 4)) // [12, 24]


Map


Функциональные понятия функторов и монад пришли к нам из языка Haskell. Говорят, невозможно просто взять и понять, что такое монада, а уж тем более невозможно это объяснить. Тем не менее мы можем временно отбросить все сложности и объяснить себе только то, что действительно необходимо, а те, кто захочет закопаться поглубже, могут начать с изучения Haskell.

Итак, для простоты мы можем считать, что функтор это контейнер, к которому применима функция map, а монада это функтор, к которому применима функция flatMap.

Поскольку коллекции это контейнеры, и в Swift для них определена функция map, они могут выступать в роли функторов:
для того, чтобы трансформировать коллекцию одного типа в коллекцию другого типа, возьмем наш массив persons и получим из него массив возрастов типа [Int]
let ages = array.map{ $0.age } // [23, 20, 35]


FlatMap


И в роли монад:
для того, чтобы из массива oprtional типов вернуть массив не опциональных значений
let optionalStrings: [String?] = ["a", nil, "b", "c", nil]
let strings = optionalStrings.flatMap { $0 } // ["a", "b", "c"]

для того, чтобы расширить первоначальную коллекцию
let odds = [1,3,5,7,9]
let evensAndOdds = odds.flatMap { [$0, $0 + 1] } // [1,2,3,4,5,6,7,8,9,10]

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

Haskell: об одном методе реализации функций с переменным числом параметров

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

– А видела ты Черепаху «Как бы»?
– Нет, – сказала Алиса. – Я даже не знаю, кто это такой.
– Как же, – сказала Королева. – Это то, из чего делают «Как бы черепаший суп».

                  Льюис Кэрролл, 
                           «Алиса в Стране чудес»

— Судя по твоим речам, ты хорошо знаешь Фангорн? — спросил в ответ Арагорн.
— Какое там! — отозвался старик. — На это ста жизней не хватит. Но я сюда иной раз захаживаю.

                 Джон Р. Р. Толкиен, 
                          «Властелин Колец» — к слову о моём знании Haskell ;)


Homines dum docent, discunt. (Объясни другим — сам поймёшь.)
                 народная латинская поговорка


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

Казалось бы о каком переменном числе параметров может идти речь при таком раскладе? Однако поразмыслив, посмотрев исходники printf или просто почитав wiki.haskell становится очевидным, что как раз ФП даёт ключ к достаточно красивому, хотя и несколько «казуистическому» решению этой задачи.

В настоящей публикации я рассмотрю один из способов реализации такого механизма на простых примерах, а также предложу некоторое обобщённое решение на базе Template Haskell, для превращения семейства обычных функций с последним параметром типа список в функцию с «как бы с переменным числом параметром» (далее по тексту просто «с переменным числом параметром»).
Читать дальше →

О функциональном программировании в фронтенде

Время на прочтение4 мин
Количество просмотров34K
Заинтересовался темой функционального программирования, увидел здесь статью, и решил перевести, статья вышла небольшая, но интересная. Ссылка на оригинал. Далее сам перевод.
Читать дальше →

Liscript — REPL боты онлайн

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


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

Недавно я добавил возможность широкой аудитории познакомиться с данным языком — написал REPL-ботов для следующих мессенжеров: IRC, Telegram, Slack, Gitter. Боты располагаются на специально созданных для них каналах, но в большинстве случаев их можно добавлять/приглашать на другие каналы и вести с ними личную переписку. Такой формат позволяет проводить текстовые онлайн-доклады на тему основ функционального программирования, сопровождая их демонстрацией интерпретатора в реальном времени.

Конечно, графические окна с анимацией можно создавать только в десктопном варианте приложения. Поэтому для большего раскрытия возможностей языка и РЕПЛа я написал текстовую реализацию игры Лабиринт, в которую могут играть с ботом любое количество человек. Подробности и немного лирики под катом.
Читать дальше →