Clojure в Белорусском ГУ

    БГУ лого
    Clojure logo
    В этом семестре (осенью 2012) был проведён факультатив по языку Clojure в Белорусском ГУ. В посте будет описан факультатив: причины, программа, задания, результаты, впечатления.

    Начало


    Я студент 5 курса факультета прикладной математики и информатики в БГУ. Увлекаюсь функциональным программированием, но в курсе нашего обучения в университете ФП не рассматривается вообще, а из парадигм программирования проходили только ООП (java, c++). Я же считаю, что студенты, которые обучаются по специальности информатика, должны иметь хоть какое-то представление о ФП (а желательно и других парадигмах). Поэтому и решил попробовать хоть немного исправить ситуацию и провести факультатив. И т.к. опыта и знаний для проведения факультатива по ФП в целом у меня немного, то решил сосредоточиться на более прикладном и простом — на языке Clojure. Clojure — функциональный язык, современный диалект лиспа, исполняющийся в основном на JVM.

    В качестве картинок будут использованы скриншоты из задач, которые надо было решить в течение курса.

    Задача 2. Змейка.
    Змейка. Задача — написать бота.

    Программа курса


    1. Введение в Clojure. Описание синтаксиса. Функции. Анонимные функции. Простые арифметические и логические операции. Рекурсия.
    2. Работа с коллекциями. Различные виды коллекций: вектор, множество, ассоциативный массив (map). Функции для работы с ними: map, reduce, filter и т.д. Неизменяемость коллекций.
    3. Работа с коллекциями. Ленивые вычисления. Деструктуринг.
    4. Средства для работы с изменяемым состоянием. Атомы, агенты, рефы (ref). Транзакционная память.
    5. Макросы.
    6. Принцип работы неизменяемых структур данных. Разобрали реализацию PersistentVector и PersistentHashMap
    7. Мультиметоды.
    8. Протоколы, типы и записи (protocols, types, records).
    9. Немного λ-исчисления. Арифметика и логические значения в λ-исчислении.
    10. λ-исчисление. Рекурсия. Реализация списков в λ-исчислении. Пример типизированного λ-исчислении.


    Задача 3. Дурак.
    Игра «Дурак». Бот игрока — снизу.

    Задания


    После каждого занятия давалось домашнее задание. Домашние задания были 2 типов: решение задач на 4clojure и решение интерактивных задач. 4сlojure — сайт с набором небольших задачек от очень простых до весьма сложных и онлайн проверкой. На 4clojure есть удобная особенность — возможность смотреть решения других участников после того, как решил задачу. Я думаю это помогало, узнавать, как можно «более функционально» решить задачу.

    Интерактивные задачи — задачи, которые должны быть решены на Clojure, при этом решение большинства из них заранее визуализированы, т.е. можно было смотреть на результат решения. Для визуализации были использованы библиотеки Quil (обёртка над Processing'ом для кложура) и Incanter (использовалась для построения графиков).

    Список задач:
    • ПВО. Нужно сбить цель задавая угол выстрела. Было 2 варианта. Первый — без учёта гравитации, ракета летит по прямой, цель тоже летит по прямой. Второй вариант учитывал гравитацию (можно стрелять навесом), цель висит в воздухе не двигаясь.
    • Змейка. Реализовать бота для змейки. Бот должен учитывать наличие стен.
    • Дурак. Реализовать бота для карточной игры «Дурак». В основном реализовывали бота без запоминания предыдущих состояний. Но один человек всё же написал бота с запоминанием.
    • Клеточный автомат. Релизовать «фреймворк» для 2-мерного клеточного автомата: написать визуализацию, сделать возможным взаимодействие с программой (остановить, изменить состояния клеток) и самое главное — сделать возможность простого подключения произвольных правил (таких как Жизнь, Brian's Brain, Wireworld и другие).
    • k-means. Реализовать алгоритм k-means с фиксированным k. А также попробовать написать алгоритм, который будет подбирать наилучшее k.
    • Символьное дифференцирование. Написать функцию, которая на вход принимает кложурное выражение, например (* 2 x), на выход отдаёт производную: (+ (* 0 x) (* 2 1)). Упрощать полученный результат не требовалось. Визуализация — построения графиков функции и её первой, и второй производных.
    • λ-исчисление. Реализовать арифметические функции (+, -, *, ^). Написать рекурсивную функцию для вычисления суммы арифметической прогрессии чисел от 1 до n. Реализовать функции для работы со списками (head, tail, cons, empty?). Доп задание — написать map и reduce для таких списков.


    Задача 4. Клеточный автомат.
    Клеточный автомат Wireworld. Автомат реализует логический XOR.

    Процесс


    Занятия проводились по субботам, 1 раз в неделю. Для внеклассного общения использовалась гугло-группа. Задания по 4clojure естественно проверялись на самом сайте. Для решения интерактивных задач студенты форкали репозиторий на гитхабе и решали в форке. Проверять было весьма удобно, особенно учитывая то, что гитхаб позволяет оставлять комментарии к коммитам. Так что я мог указывать на неэффективные или не очень красивые места в решениях. У всех конечно вначале были императивные решения, использующие явные циклы, часто использовали изменяемые состояния и атомы там, где они на самом деле были лишними. К сожалению не могу точно оценить, насколько изменились решения к концу факультатива, насколько они стали более функциональными, но надеюсь, что стали.

    Проекты


    Была идея — чтобы все разбились на группы по 2-3 человека и каждая группа в течение семестра делала свой проект. Были предложены такие варианты: мультиплеерная змейка, простой физический движок, утилита для обработки текстовых документов (статистика, ещё что-нибудь), сделать аналог этого приложения. Ну и конечно можно было предлагать свои варианты. Но идея как-то не нашла отклика. Возможно домашних заданий и так хватало, учитывая, что мой факультатив был добровольным и к учёбе в университете никак не относился.

    Задача 6. Производные.
    Символьное дифференцирование. f = sin(2x). Изображены f, f', f''

    Мотивация и подарки


    В начале факультатива домашка никак не контролировалась. И она как-то слабо выполнялась, хотя судя по анонимному опросу «была интересной»… Тогда появилась идея награждать какими-то плюшками за решение домашек. После обсуждения с друзьями была предложена идея, которая мне очень понравилась: тот, кто выполнит больше 50% домашки, получит именную кружку со своим результатом. Так что был стимул выполнить на 100%, чтобы потом 90% глаза не мозолили. Для этого был создан рейтинг — табличка в гуглодоках, в которой вёлся учёт успехов студентов.

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

    Итоги


    По финальному опросу можно сделать вывод, что факультатив понравился. Я думаю он был полезен, если даже они и не будут использовать clojure или ФП в повседневной жизни. Что касается меня, то мне очень понравилось. Кстати идея о факультативе зародилась на парах педагогики, где мы все жаловались, что наше высшее образование плохое и нас учат никому не нужной ерунде. Тогда наш преподаватель и спросил, почему же мы сами ничего по этому поводу не пытаемся сделать.

    Спасибо моим друзьям за идеи с задачами, кружками и помощь в оплате кружек :)

    И напоследок немного фактов:
    • На факультатив ходило человек 10, в основном студенты 2 курса.
    • Было задано 65 задач с 4clojure. В среднем каждый решил 59.
    • Было задано 8 интерактивных задач. В среднем каждый решил 6.
    • Один из студентов нашёл 1 серьёзный баг в Quil.
    • 3 студента выполнили задания на 100%. Средний результат: 88%
    • Все, кто делал домашку и продержались до конца — получили кружку. Таких 8 человек. 2 человека посещали, но не выполняли задания.

    Кружки
    Именные кружки.

    Update
    Если кому-нибудь будет интересна генерация изображений для кружек, то скрипт доступен на гитхабе: http://nbeloglazov.github.com/clojure-mug-template/
    Поделиться публикацией
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 15
    • +1
      Ох как весело там у вас в БГУ :-)
      • +3
        Ну в БГУ не слишком весело. Поэтому и приходится веселье самим создавать :)
        • 0
          Мы в ПГУ развлекаемся тоже необычно. Попробую рассказать так, чтобы было понятно. Собираемся компанией на кафедре. Одеваем наушники с бодрым металлом и начинаем программировать задачи с codeforcess на скорость. При этом держа клавиатуру как гитару. (Отсылка к GuitarHero). Выглядит весьма эффектно. Быстрое такое, я бы сказал экстремальное программирование.
      • НЛО прилетело и опубликовало эту надпись здесь
        • +3
          Спасибо. Нет, не выкладывались. На самом деле материалов как таковых и не было. Перед лекциями старался делать небольшой план и придумать пару задачек уместных. А во время лекций рассказывал что знаю. Из материалов курса только что репозиторий с задачками, который, надеюсь, пригодится кому-нибудь.
          • НЛО прилетело и опубликовало эту надпись здесь
        • +1
          Хорошее начинание. Сам хочу в своём университете подобное провернуть…

          [мысли вслух]
          Хотя, когда курсы по программированию в университете организовывает студент факультета иностранных языков, это выглядит немного нелепо.
          [/мысли вслух]
          • 0
            Идея с кружками — отличная!
            Теперь было бы очень здорово сделать онлайн-курс ;)
            • 0
              Очень круто! А подскажите по такому вопросу: внешне кажется что задачки достаточно сложные. Они действительно сложные и студентам приходилось писать много кода, или в Clojure часть библиотек облегчающих работу есть?
              • +1
                Почти для всех задач требовалось знание только стандартных функций для работ с коллекциями. Только в клеточном автомате нужно было изучать библиотеку quil для визуализации. Так что задачи не очень сложные. Проблема была в том, что язык и парадигма совсем непривычные.
                • 0
                  Ну т.е если бы такую же задачу дать на Java, то сложность её была бы в разы выше?
                  • +1
                    На самом деле мне сложно оценить. Мне кажется задачи требуют знания основ алгоритмов и математики и все. Я бы сделал каждую задачу за вечер, но у меня больше опыта, да и я их придумал. На джаве было бы больше кода. И задача с дифференцированием на джаве не прошла бы так просто, потому что это фишка лиспов — оперировать с кодом, как с данными. И задача про лямбда-исчисления была бы куда ужасней, т.к. там надо было использовать тонну анонимных функций, а в джаве анонимные функции через анонимные классы смотрятся громоздко.
                    Мне кажется в основном решения укладывались строк в 100. А часто и в 50.
                    • 0
                      Кажется понял. Спасибо за ответы! ;)
              • 0
                Привет из Полоцкого ГУ.
                >>а из парадигм программирования проходили только ООП (java, c++)
                А ASM у вас разве не давали?
                • 0
                  Давали. Но мне сложно сказать к какой парадигме он относится.

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.