zoukankan      html  css  js  c++  java
  • 99种用Racket说I love you的方式

    99种用Racket说I love you的方式

    来源 https://www.tuicool.com/articles/qiyeAz

    原文  http://www.soimort.org/posts/145/

    今天是3月14日,也就是传说中的 白色情人节 (据说是个被表白一方向表白方回赠礼物以表示心意的好日子,蕴含着人们对天下有情人终成眷属的 良好祝愿 )。

    作为一个技术宅,应该在这一天准备什么样的礼物给妹子捏?99朵玫瑰?还是巧克力?可不要被这些 商家营销手段 给骗了——就像Sheldon家Amy说的一样,Nerds们过一个真正属于自己的“No dinner, no romance, no gifts”的情人节才是正道啊;这种时候,只要像往常那样写写代码,用代码来说出“I love you”就好了。当然,为了表示诚意,我们要用99种——没错,是用99种不同的方式来写同一句话。

    用什么语言写好捏?当然是 满满的都是爱 的 Racket 咯ヽ(♡´ω`♡)ノ

    (先放上一段忘了从哪偷来的代码……在DrRacket里运行,就能看到一颗doki~doki跳动的红心哦)

    #lang racket
    
    (require 2htdp/universe 2htdp/image)
    
    (define scale-factor 10)
    (define window-size (* scale-factor 20))
    
    (define (lobe shape size) (shape (* size scale-factor) 'solid 'red))
    (define (lobe circle 4))
    (define •• (overlay/offset (* 7 scale-factor) 0 ))
    (define (rotate 180 (lobe triangle 14)))
    (define (overlay/offset •• 0 (* 8 scale-factor) ))
    
    (define amplitude 1/10)
    (define speed 1/2)
    
    (define (☺♥ n)
      (overlay (scale (add1 (* (sin (* n speed)) amplitude)) )
             (empty-scene window-size window-size)))
    (animate ☺♥) 
    

    下面开始,进入正题。

    以前,穷屌丝书生喜欢发问,茴香豆的茴字有几种写法?而高富帅则会问,I love you里面的love有几种make法?不管做任何一件事情,方法上的选择总是很重要——对于敲代码的程序猿来说也一样。

    在Python里,做任何事,通常有且仅有一种正确的方法;Pythonic教的传教士说:只有一种姿势最优雅,其他的体位都是邪恶的。但是Rubyists们却不以为然。他们是一群奉行自由主义的嬉皮,不需要Python里面那种类似 哲♂学 一样的教条束缚;在解决同一个最基本的问题上有时也会跟随feeling写出新奇而孑然不同的代码。

    记得刚开始接触Ruby那会,试着 用Ruby解过 那套经典的 P-99(99个Prolog问题) 。前面好几十个问题差不多都是关于list的操作:做过一遍之后立刻就感觉到,Ruby单从表达问题的灵活性上来说,的确不是现有的其他主流语言所能够比拟的——显然,作为Perl的继任者,Ruby很好地发扬光大了这一点。

    嘛,当然,要说到表达能力,基于 抖S前入式 、把数据和代码结构高度统一起来的Lisp才是编程语言中真正的总攻(虽然这也让一部分Lisper养成了光说空话不干实事+吹嘘自己造车轮造得多么的好+不合作不贡献社区的 坏毛病 )。话说回来,在Lisp里,哪怕是做最简单的一件事情——构造一个list,也能凭空造出千般万般变化。不信?继续看下去。

    为了帮助童鞋们更好地理解Racket语言中的核心概念,Univ of Utah的CS系教授Matthew Might写了这篇 《99 ways to say '(I love you) 》 。你不仅能够从中领略到Lisp那无与伦比的表达能力,还能借此复习一下Scheme/Racket中的那些基础知识点:lambdas,higher-order function,pattern matching,delayed evaluation,macros,等等——当然,后者才是此文的主要目的。

    下面奉上原文翻译。(其实文字部分也就几句话)

    Original Article: 99 ways to say '(I love you) by Matthew Might 
    (Chinese Translation by Mort Yao )

    99 ways to say '(I love you)

    虽说其具有本质上的简单性,有关list的那些事儿仍然会常常让Racket程序员们困惑不已。

    除开list结构本身之外,Racket程序中各种运算的表达方式更需要花上不少时间来发掘和掌握。

    为了更好地强调这些重点,我写了99个不超过一条推长度的Racket表达式,它们求值的结果均得到同样的一个list: '(I love you) 。

    这些表达式中大约有一半用来展示构建或操作list的方法,剩下来的则展示了Racket中表述计算的各色方式。

    所涉及到的关键知识点包括:

    • 用cons连接单元(cons cells)
    • 字面list记号(literal list notation)
    • 加点list记号(dotted list notation)
    • 反引号表示list(quasiquoted lists)
    • let绑定形式(let-binding forms)
    • vector和stream(vectors and streams)
    • 匿名函数(anonymous functions)
    • 高阶list操作(higher-order list operations)
    • 条件式(conditionals)
    • 结构化模式匹配(structural pattern-matching)
    • 哈希表(hash maps)
    • 续延(continuations)
    • 异常(exceptions)
    • 诺言(promises)
    • 变更(mutation)
    • 宏(macros)
    • 端口(ports)
    • 未来(futures)
    • 参数(parameters)

    以下是具体的99种方式。

    如果读到任何一条不能理解的话,不妨在DrRacket的REPL里面尝试摸索一番,直到你彻底弄懂它。

    99种方式

    下面的每一枚Racket表达式,求值的结果均得到一个list '(I love you) :

    (原文里面没有给这99条归类,小标题是翻译君擅自加的,看的时候请注意鉴别……)

    1. 构造list的基本手段: quote 和 list

    ;;;
    '(I love you)
    
    ;;;
    (quote (I love you))
    
    ;;;
    (list 'I 'love 'you)
    
    ;;;
    (list (quote I) (quote love) (quote you))
    

    2. 用 cons 连接单元

    ;;;
    (cons 'I (cons 'love (cons 'you '())))
    
    ;;;
    (cons 'I (cons 'love (list 'you)))
    
    ;;;
    (cons 'I (list 'love 'you))
    
    ;;;
    (cons 'I '(love you))
    

    3. 加点list记号(Dotted list notation)

    ;;;
    '(I love . (you))
    
    ;;;
    '(I . (love . (you)))
    
    ;;;
    '(I . (love . (you . ())))
    
    ;;;
    '(I . (love you))
    

    4. 反引号表示list(Quasiquoted lists)

    ;;;
    `(I love you)
    
    ;;;
    `(I ,'love you)
    
    ;;
    (quasiquote (I ,'love  you))
    
    ;;
    (quasiquote (I (unquote 'love) you))
    
    ;;;
    `(I ,`love you)
    
    ;;;
    (let ([verb 'love])
      `(I ,verb you))
    
    ;;;
    `(I ,(string->symbol "love") you)
    
    ;;;
    `(I ,(string->symbol (list->string '(#l #o #v #e))) you)
    
    ;;;
    `(I love . (you))
    
    ;;;
    `(I love . ,(list 'you))
    
    ;;;
    `(I love ,@'(you))
    
    ;;;
    `(I love (unquote-splicing '(you)))
    
    ;;;
    `(I ,@(list 'love 'you))
    
    ;;;
    `(,@(list 'I 'love) you)
    
    ;;;
    `(,@'(I love you))
    
    ;;;
    `,'(I love you)
    
    ;;;
    `(I love you . ,'())
    

    5. car 和 cdr

    ;;;
    (car (list '(I love you)))
    
    ;;;
    (cdr '(Hark! I love you))
    

    6. let 绑定形式( let -binding forms)

    ;;;
    (let ([words '(love you I)])
      (list (car (cdr (cdr words)))
            (car words)
            (car (cdr words))))
    
    ;;;
    (let ([words '(love you I)])
      (list (caddr words)
            (car words)
            (cadr words)))
    
    ;;;
    (let* ([c '(you)]
           [b (cons 'love c)]
           [a (cons 'I b)])
      a)
    
    ;;;
    (let ()
      '(I love you not)
      '(I love you))
    

    7. vector

    ;;;
    (vector->list (vector 'I 'love 'you))
    
    ;;;
    (vector->list #(I love you))
    

    8. stream

    ;;;
    (stream->list (stream 'I 'love 'you))
    

    9. 匿名函数(Anonymous functions)

    ;;;
    ((lambda args args) 'I 'love 'you)
    
    ;;;
    ((lambda (one two . rest) rest) 'You 'believe 'I 'love 'you)
    
    ;;;
    ((lambda (a c b) (list a b c)) 'I 'you 'love)
    
    ;;;
    (apply (lambda (a c b) (list a b c)) 
           (list 'I 'you 'love))
    
    ;;;
    ((lambda (a b [c 'you]) (list a b c)) 'I 'love)
    
    ;;;
    ((lambda (#:foo b #:bar c #:baz a)
       (list a b c))
     #:baz 'I #:bar 'you #:foo 'love)
    
    ;;;
    ((lambda (a b #:key [c 'me]) (list a b c)) #:key 'you 'I 'love)
    

    10. 柯里化(Currying)

    ;;;
    (let ([f (λ (x)
               (λ (y)
                 (λ (z)
                   (list x y z))))])
      (((f 'I) 'love) 'you))
    

    11. case-lambda

    ;;;
    (let ([f (case-lambda 
               [() 'I]
               [(x) 'love]
               [(x y) 'you])])
      (list (f) (f 1) (f 1 2)))
    

    12. 基础list操作

    ;;;
    (append '(I love) '(you))
    
    ;;;
    (append '(I) '(love) '(you))
    
    ;;;
    (flatten '((I) (love you)))
    
    ;;;
    (flatten '((I) (love) (you) ()))
    
    ;;;
    (reverse '(you love I))
    
    ;;;
    (remove 'cannot '(I cannot love you))
    
    ;;;
    (remove-duplicates '(I love love love you))
    
    ;;;
    (take '(I love you not) 3)
    
    ;;
    (take-right '(I think I love you) 3)
    
    ;;;
    (drop '(She knows I love you) 2)
    
    ;;;
    (drop-right '(I love you no more) 2)
    

    13. 高阶list操作(map、filter和reduce)

    ;;;
    (map (lambda (x) (if (eq? x 'hate) 'love x))
         '(I hate you))
    
    ;;;
    (map (λ (i) (vector-ref #(love you I) i))
         '(2 0 1))
    
    ;;;
    (map (λ (k) (hash-ref #hash(("foo" . I) 
                                ("baz" . you)
                                ("bar" . love)) k))
         '("foo" "bar" "baz"))
    
    ;;;
    (map string->symbol (sort (list "love" "you" "I") string<?))
    
    ;;;
    (map string->symbol (string-split "I-love-you" "-"))
    
    ;;;
    (flatten (map (λ (a b) (cons a b))
                  '(I love you)
                  '(() () ())))
    
    ;;;
    (filter (lambda (x) (not (eq? x 'cannot))) 
            '(I cannot love you))
    
    ;;;
    (foldr cons '() '(I love you))
    
    ;;;
    (foldl cons '() '(you love I))
    

    14. 迭代(Iterations)

    ;;;
    (for/list ([word #(I love you)])
      word)
    

    15. 条件式(Conditionals)

    ;;;
    (cond
      [(even? 3) '(Not me)]
      [(odd?  3) '(I love you)])
    
    ;;;
    (cond
      [(even? 3) '(Not me)]
      [(odd?  2) '(Nor I)]
      [else      '(I love you)])
    
    ;;;
    (case 1
      [(a b c) '(Not me)]
      [(3 2 1) '(I love you)])
    

    16. 结构化模式匹配(Structural pattern-matching)

    ;;;
    (match #t
      [#f '(Not me)]
      [#t '(I love you)])
    
    ;;;
    (match #t
      [#f '(Not me)]
      [_  '(I love you)])
    
    ;;;
    (match 'you
      ['me '(Not me)]
      [x   `(I love ,x)])
    
    ;;;
    (match '(foo bar)
      ['(foo bar) '(I love you)])
    
    ;;;
    (match '(I cannot lift you)
      [(list 'I 'cannot _ c) `(I love ,c)])
    
    ;;;
    (match '(2 3 1)
      [(list-no-order 3 1 2)
       '(I love you)])
    
    ;;;
    (match '(love you I)
      [(list-no-order 'I 'love foo)
       `(I love ,foo)])
    
    ;;;
    (match '(3 . 4)
      [(cons 3 4)
       '(I love you)])
    
    ;;;
    (match '(3 love 1)
      [(cons 3 (cons x (cons 1 '())))
       `(I ,x you)])
    
    ;;;
    (match '(3 love 1)
      [(cons 3 (cons x (cons 1 '())))
       `(I (unquote x) you)])
    
    ;;;
    (match 3
      [(? symbol?) '(Not me)]
      [(? string?) '(Me neither)]
      [(? number?) '(I love you)])
    
    ;;;
    (match 3
      [(not 4)   '(I love you)]
      [3         'unreachable])
    
    ;;;
    (match '(you love I)
      [`(,c love ,a)
       `(,a love ,c)])
    
    ;;;
    (match '(We love you)
      [`(,_ . ,rest)
       `(I . ,rest)])
    
    ;;;
    (match '(We love you)
      [`(,_ ,rest ...)
       `(I ,@rest)])
    
    ;;;
    (match '(We love you)
      [(list _ rest ...)
       `(I ,@rest)])
    
    ;;;
    (match #(1 love 3)
      [(vector (? number?) b (? number?))
       `(I ,b you)])
    
    ;;;
    (match #hash((1 . I) (3 . you) (5 . love))
      [(hash-table (1 a) (5 b) (3 c))
       (list a b c)])
    
    ;;;
    (match 'you
      [(and x (? symbol?)) `(I love ,x)])
    
    ;;;
    (match '100
      [(app (λ (n) (- n 1)) 99)
       '(I love you)])
    

    17. 续延(Continuation)

    ;;;
    (list 'I 
          (call/cc (λ (cc)
                     (error (cc 'love))))
          'you)
    

    18. 异常(Exceptions)

    ;;;
    (with-handlers ([symbol? (lambda (p)
                                 `(I ,p you))])
        (raise 'love))
    

    19. 延迟求值(Delayed evaluation)

    ;;;
    (let ([problem (delay (car '()))])
      '(I love you))
    
    ;;;
    `(I ,(force (delay 'love)) you)
    
    ;;;
    (letrec ([x (delay (list a b c))]
             [a 'I]
             [c 'you]
             [b 'love])
      (force x))
    

    20. 变更(Mutation)

    ;;;
    (let ([word 'know])
      (set! word 'love)
      `(I ,word you))
    
    ;;;
    (let ([word-box (box 'know)])
      (set-box! word-box 'love)
      `(I ,(unbox word-box) you))
    

    21. 宏(Macros)

    ;;;
    (let-syntax ([un-yoda-list
                  (syntax-rules ()
                    [(_ c a b) (list 'a 'b 'c)])])
      (un-yoda-list you I love))
    

    22. 端口(Ports)

    ;;;
    (let ((in (open-input-string "I love you")))
      (cons (read in)
            (cons (read in)
                  (cons (read in) '()))))
    

    23. 未来(Futures)

    ;;;
    (list (touch (future (λ () 'I))) 'love 'you)
    

    24. 参数化(Parameterization)

    ;;;
    (let ([a (make-parameter "a")] 
          [b (make-parameter "b")]
          [c (make-parameter "c")])
      (parameterize ([a 'i] [b 'love] [c 'you])
        (list (a) 
              ((parameterize ([b 'dislike])
                 (λ () (b))))
              (c))))
    

    来自其他人的贡献

    由 David Van Horn 提供:

    (define `λ (λ 'love 'I 'you)) 
    ((λ λ λ) 
      `(λ (λ ) λ) 
       `(λ (λ ) λ)
       `(λ (λ) λ))
    

    由Bruce Bolick提供:

    (define (stream-take s n)
      (if (= n 0)
          '()
          (cons (stream-first s)
                (stream-take (stream-rest s) (- n 1)))))
    (define U 3)
    (define I stream-take)
    (define (stream  'I 'love 'you))
    (I U)
    

    (原文完)

    (我表示诸位看官到这里可以直接无视以下内容了……看可以,请一笑了之。)

    因为文章里提到的99种方式都没有涉及到logic programming,我觉得很有必要写一个自己的版本。用谓词逻辑来推导出“I love you”这种设定会很有趣的不是么……

    于是就有了下面这段蛋疼的产物(用到了 Racklog ,一个仿Prolog的逻辑式编程扩展),最终的结果也是一样一样的 '(I love you) :

    我要做一只合格的脑残偶像厨WOTA \(^o^)/

    #lang racket
    (require racklog)
    
    (define %love
      (%rel ()
        [('I 'AKB48)]
        [('I 'you)]
        [('you 'I)]))
    
    (define first-love
      (%which (who)
        (%and (%is who 'AKB48)
              (%love 'I who)
              (%love who 'I))))
    
    (define not-that-much-but-still-love
      (%which (who)
        (%and (%love 'I who)
              (%love who 'I))))
    
    (define (♡˙︶˙♡)
      `(I love, (cdr (car not-that-much-but-still-love))))
    
    (♡˙︶˙♡)
    

    ====================== End

  • 相关阅读:
    Linux工具-curl
    常用工具-Postman
    HTTP头部信息
    HTTP状态码
    HTTP/HTTP2协议
    HTTP协议
    常用的服务端口
    三次握手,四次挥手和抓包工具
    路由表
    TCP/IP协议详解
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/10155529.html
Copyright © 2011-2022 走看看