10 «однострочников» на Racket, которые произведут впечатление на ваших друзей

Хочу вернуться к подзабытой теме о «10 однострочниках» на любимом языке. Бурное обсуждение на Хабре было несколько месяцев назад. К сожалению, не многие приводили действительно однострочники и не многие из них были читабельны. Хочу предложить версию на Racket, которая по этим параметрам местами даже превосходит изначальный пример на Scala.


1. Удваиваем каждый элемент списка

Можно делать так:
(for/list ((i (in-range 10))) (* 2 i))

Либо так:
(map (curry * 2) (build-list 10 (λ (x) x)))


2. Суммируем все числа в списке

(apply + (build-list 10000 (λ (x) x)))


3. Проверяем вхождение подстроки

(define wordlist '("Racket" "akka" "play framework" "sbt" "curring")) ; искомые строки
(define tweet "This is an example tweet talking about Racket and curring") ; проверяемая строка

Находит первое вхождение (если не находит, возвращает #f):
(findf (curryr regexp-match? tweet) wordlist)

Выбирает из wordlist подстроки, присутствующие в tweet:
(filter (curryr regexp-match? tweet) wordlist)


4. Чтение из файла

(file->string "file.txt") ; в одну строку
(file->lines "file.txt") ; в список строк


5. Печать песни «Happy Birthday»


Раз вариант
(for-each (λ (x) (display (string-append "Happy Birthday" (if x ", dear John" " to You") "\n"))) '(#f #f #t #f))

Два вариант
(for ((x (in-range 4))) (display (string-append "Happy Birthday" (if (= x 2) ", dear John" " to You") "\n")))

Три вариант
(display-lines (build-list 4 (λ (x) (string-append "Happy Birthday" (if (= x 2) ", dear John" " to You")))))


6. Фильтрация списка чисел

(partition (curry > 60) '(49 58 76 82 88 90))

Возвращает два списка — отвечающий условию и не отвечающий.

7. Получение и разбор XML от веб-сервиса

Загружаем стандартные библиотеки:
(require net/url xml)

Следующее действие помещает полученный xml в структуру типа document
(define doc (read-xml (get-pure-port (string->url "http://search.twitter.com/search.atom?&q=racket"))))

При желании, можно распарсить полученный документ в дерево — родной формат лиспа, коим Racket и является:
(xml->xexpr (document-element doc))


8. Поиск минимума (или максимума) в списке

Не сложнее, чем сложение чисел:
(apply max '(14 35 -7 46 98))
(apply min '(14 35 -7 46 98))


9. Параллельная обработка

Пусть есть какие-то данные. В качестве теста приведём обычный список:
(define data-list '(A B C D E F G H))

И есть какая-то процедура. Для наглядности выберем многократную печать символа:
(define (process sym) (for ((n (in-range 10))) (display sym)))

Запускается параллельная обработка так:
(for ((x data-list)) (thread (λ () (process x))))


10. Решето Эратосфена

Задача скорее алгоритмическая. Есть множество способов её решения.
Вот генерация списка чисел от 2 до max
(define (eratosphen max)
  (let er ([lst null] [cur 2])
    (cond
      [(> cur max) (reverse lst)]
      [(ormap (λ (x) (= (remainder cur x) 0)) lst)
       (er lst (add1 cur))]
      [else (er (cons cur lst) (add1 cur))])))

Это в одну строчку записывать не стоит.
А если нужна только проверка числа на простоту методом решета Эратосфена, то код и правда может уместиться в строку (на месте 113 должно стоять проверяемое число).
(let check ([cur 2] [n 113]) (cond [(= (remainder n cur) 0) #f] [(> (sqr cur) n) #t] [else (check (add1 cur) n)]))

Но я бы такое всё же разбивал «на лесенки», как и все остальные решения этой задачи.
AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 38

    –18
    Чего? Друзья такого не поймут! Хоть это и не однострочник, но вот это их удивит точно 99-bottles-of-beer.net/language-perl-737.html

    А вот этот пожалуй способен разозлить.
    cat "test... test... test..." | perl -e '$??s:;s:s;;$?::s;;=]=>%-{<-|}<&|`{;;y; -/:-@[-`{-};`-{/" -;;s;;$_;see'

    А то что привели Вы…
      +3
      Почему без sudo?
        +3
        Патч Бармина?
        Уже давным давно любой непонятный код на перле по умолчанию считается именно им.
          +15
          а на перле можно написать понятный код?
        +10
        Не вижу ничего очень крутого. То что реально коротко — просто функции из стандартной библиотеки, а то что немного подлиннее на том же javascript'е будет примерно так же выглядеть.
          0
          В любом случае плюсую, функциональные языки — наше всё!
          • UFO just landed and posted this here
            • UFO just landed and posted this here
                +1
                а зачем в a = list([i * 2 for i in a]) вызывать list?
                [i * 2 for i in a] — уже сам по себе дает на выходе список
                • UFO just landed and posted this here
                  +1
                  a = list([i * 2 for i in a])

                  А зачем здесь list? Генератор списка и так возвращает список.

                  a = [i * 2 for i in a]
                    +1
                    Прошу прощение за повтор, даже обновление комментов мне не помогло. :(
                +7
                Что реально выделяет схему из большинства других языков, так это очень изящная макросистема и call/cc
                А то что описано здесь — баловство, доступное первокурснику с LINQ. Никакого особенно «впечатления» не производит
                  0
                  > изящная макросистема

                  И бесполезная. Последний раз провозившись с ней два часа, сделал (require mzlib/defmacro) и написал макрос за десять минут.

                  Зато изящная, да. Схема вообще изящная.
                    0
                    > И бесполезная
                    А вот ни фига. Я вообще смутно понимаю любовь к закату солнца вручную как самоцель. Ну вот low level разработчики гоняют байты для того, чтоб было быстрее/меньше по размеру. А зачем гонять вручную s-выражения в стиле define-macro/defmacro? Зачем ручная гигиена, если она нужна в подавляющем большинстве случаев и удобнее как раз ее вручную нарушать при необходимости? Какие преимущства это дает?

                    Как по мне, люди, предпочитающие defmacro-style макросы просто расписываются в своей неспособности понимать/создавать абстракции (в данном случае синтаксические).

                    С другой стороны, как же уже хочется нормальных макросов в мейнстриме (желательно нативном). Хотя бы и с ручным закатыванием солнца.
                      0
                      Люди, предпочитающие схемовые макросы просто расписываются в непонимании принципов дизайна ЯП. Встретилась задача где необходима другая система макросов — используйте другую систему макросов, например, с гигеной по-умолчанию. (В LoL есть пример реализации) В чём проблема? Высокоуровневая система однозначно хороша только если она не прячет от разработчика никакие возможности, как Java, или схемовые макросы. Более мощным языком является не тот в котором больше абстракций из коробки, а который позволяет проще и эффективнее реализовывать новые.
                  0
                  Что то да… Не впечатлило… Я привык к такому ходу мыслей на ruby
                    +1
                    Все, конечно, поняли, что Racket — это некоторый диалект Lisp… но, имхо, стоило об этом написать до ката, нет?
                    По сути: все уже поняли, что диалекты Lisp, ML-языки и вообще ЯФП могут быть очень выразительными в некоторых задачах.

                    Ну и хотелось бы до ката узнавать, что за язык/среда такой — Racket? (грубо говоря — стоит за ним в википедию идти или нет).
                      0
                      Как-то грустно совсем… Даже сравнивать не хочется с теми решениями, что были на других языках. Явно не гольфить против perl и ruby.(golfscript не считаю интересным)
                        +11
                        А как вот это ваше λ с клавиатуры набирать?
                          +2
                          Обычно так «\»
                            0
                            А лучше λ или ALT+NUM(0+9+5+5).
                              0
                              Ну… это только в виндоус будет работать.
                            0
                            Можно набирать lambda. Если редактор поддерживает юникод, то можно на хоткей повесить. Я исходники редактирую из под DrRacket, в нём этот хоткей определён изначально: ctrl + \
                            +3
                            В APL подобные выражения выглядят эзотеричнее:

                            максимум — ⌈/ 3 5 88
                            фильтрация — d←5 6 7 8 9 ⋄ (d>6)/d
                            и т.п.
                              0
                              Ага, мне тоже сразу APL вспомнился после увиденной λ, ну как вспомнился, не программил конечно на нём, так книжку в детстве прочитал о нём — язык адский.
                                0
                                Обычный функциональный язык. Значки запоминаются гораздо лучше названий функций, которые зависят от пожеланий разработчика. Например максимум — max, maxof, maximum или ещё как нибудь. Да и порог вхождения у APL ооочень низкий. Мне хватило 20 рабочих дней, чтобы научиться разбирать готовый код.
                                  +2
                                  > порог вхождения у APL ооочень низкий.

                                  > Мне хватило 20 рабочих дней, чтобы научиться разбирать готовый код.

                                  взаимоисключающие параграфы детектед.
                                    –1
                                    реквестирую пояснения. Сколько нужно дней, чтобы изучить, например, пайтон в объеме, достаточном для поддержки/разработки крупного проекта?
                                      0
                                      Erlang — 2 недели. Максимум. Если есть готовая инфраструктура и не надо принимать архитектурные решения самому.
                                        –1
                                        Разница всего в 2 раза. Поэтому буду продолжать считать, что у APL низкий порог вхождения.
                              +2
                              Что-то никак, не то что на друзей, даже на меня не произвело впечатления.
                              Когда я вижу какие-нибудь bash или perl однострочники, вот это да думаю, впечатления, а тут нет.
                                0
                                ну, по идее — любую программу на Lisp и подобных ему языках можно написать в одну строку.
                                вопрос в том что в 99% случаев не стоит этого делать
                                  0
                                  На С и еще многих языках тоже можно написать в одну строку.
                                  +6
                                  Хех, вспомнилась цитата с башорга про установку генту тремя строчками.
                                    0
                                    На меня эти строчки не произвели абсолютно никакого впечатления кроме WTF относительно синтаксиса.
                                      0
                                      На меня эти строчки не произвели вообще никакого впечатления. А вот строчки на Scala и Python (были раньше) — WTF синтаксис.
                                    • UFO just landed and posted this here

                                      Only users with full accounts can post comments. Log in, please.