读书笔记Quick: An Introduction to Racket with Pictures

Quick: An Introduction to Racket with Pictures

1. 安装环境,DrRacket

2. 设置,选择语言

#lang slideshow

3. 开始

  • 表达式
    • 值:数字或者以双引号引用的字符串作为值直接输出
    • 函数调用:
      lisp
      (func arg1 arg2 ...)
    • 光标定位到函数上,按F1可打开浏览器查看帮助文档

4. 定义Definitions

(define ( ) )

5. 本地绑定Local Binding

  • 用define进行本地绑定
(define (four p)
  (define two-p (hc-append p p))
  (vc-append two-p two-p))

> (four (circle 10))
oo
oo
  • letlet*进行本地绑定
    • letlet*绑定优势在于,可以在表达式的任何位置进行绑定,并且一次可以绑定多个标识符。
    • let绑定不允许绑定标识符之间互相引用,而let*允许后面的绑定引用前面的绑定。

6. 函数即值Functions are Values

> circle
#
  • 因为函数就是值,所以可以定义函数为其他函数的参数
(define (series mk)
  (hc-append 4 (mk 5) (mk 10) (mk 20)))
> (series circle)
o O @
  • 当调用以函数作为参数的函数时,如果作为参数的函数不会用于其他地方,那么就不必用define在某个地方进行定义,只需使用lambda表达式来创建匿名函数:
> (series (lambda (size) (checkerboard (square size))))
  • 前面所述的define格式只不过是以下define格式的简写,一般用简写方式定义。
(define series
   (lambda (mk)
     (hc-append 4 (mk 5) (mk 10) (mk 20))))

7. 词法作用域Lexical Scope

8. 列表Lists

  • 列表函数可以有零或任意多个参数,并返回包含这些参数值的列表。
> (list "red" "green" "blue")
'("red" "green" "blue")
> (list (circle 10) (square 10))
'(O 口)

  由于圆括号既用于表达式也用于打印输出,为进行区别,加上单引号以示为输出

  • map函数用于将函数作用于list的每个元素,并返回以每个元素为参数的函数处理结果list
(define (rainbow p)
  (map (lambda (color)
         (colorize p color))
       (list "red" "orange" "yellow" "green" "blue" "purple")))

> (rainbow (square 5))
'(image image image image image image)
  • apply函数类似于map函数,也是将函数作用于list的每个元素,不同之处在于,map针对每个列表元素单独执行,而apply一次执行所有元素
> (apply vc-append (rainbow (square 5)))
image

  注意,这里(vc-append (rainbow (square 5)))是不能执行的,因为vc-append函数不接受list参数。apply函数在接受多个参数的函数和以这些参数作为一个整体的列表间起到了连接作用。

9.模块Modules

  • 由于程序在定义窗口以#lang slieshow开始,所以所有编写的代码都在这个module中,这个module中的所有东西在初始时被导入进来。要导入更多的类库,使用require格式。
(require pict/flash)
> (filled-flash 40 30)
image
  • 模块的命名和分发

    • 一些模块被打包进Racket或安装在层次集合。例如,命名为pict/flash模块就是位于pict集合中保存在flash.rkt文件中的模块实现。如果模块名不包括斜杠,表示对main.rkt文件的引用。
    • 一些模块的集合被打包分发。这些包可以被DrRacket中File菜单Install Package…安装,或者被命令行工具raco pkg命令安装。
    • 一些包与其他模块相关,不属于任何特定的集合或包。例如,上面所讲的函数定义可以保存在quick.rkt文件中,并在最后一行添加(provide rainbow square),这样就可以通过require来引用了:
      
      #lang racket
      
      (require "quick.rkt")
      (rainbow (square 5))

10.宏Macros

  • Libraries不仅仅输出值,例如函数;它们还可以定义新的语法形式。从这个意义上说,Racket不只是一种语言,更重要的是如何构造一种语言,这样你就可以扩展它或创造全新的语言。
  • 如下定义,通过define-syntaxsyntax-rules引入了一种新的语法格式,就是一个宏:
(define-syntax pict+code
  (syntax-rules ()
    [(pict+code expr)
     (hc-append 10
                expr
                (code expr))]))

> (pict+code (circle 10))

11.对象Objects

  • class系统本身由racket/class库实现,并且racket/gui/base库提供了GUI和绘图类。按照惯例,类名以百分号%结尾:
(require racket/class
         racket/gui/base)
(define f (new frame% [label "My Art"]
                      [width 300]
                      [height 300]
                      [alignment '(center center)]))

> (send f show #t)

  new创建了类的实例,send调用了对象fshow方法,传递参数#t

你可能感兴趣的:(Racket)