1欢迎使用Racket
Racket是
- 一种编程语言-一种lisp方言继承自Scheme
- 一系列的编程语言家族-各种Racket变体
- 一个工具集-为了使用一个系列的编程语言家族
Racket主要的工具包括 - racket,核心编译器,解释器,运行系统
- DrRecket 编程环境
- raco 命令行工具,可以用来执行Racket命令,比如安装包,构建库等等。
一般情况下,你可以使用DrRacket探索Racket语言,特别是刚开始的时候。你也可以使用命令行racket解释器和你最喜欢的文本编辑器。
如果你使用DrRacket,你需要选择合适的语言,因为DrRacket包含了各种Racket语言的变体,和其它语言。如果你从来没有使用过DrRacket,启动它,然后输入
#lang racket
到最上方的文本区域,然后点击上方的运行按钮。DrRacket就会运行在正常的Racket变体上。(你也可以运行在racket/base或者其它的语言上)
如果你已经使用过DrRacket运行以#lang开头的程序,DrRacket会记住你最后使用的语言,而不是通过#lang来推理。在这种情况下,使用语言选择菜单来告诉DrRacket使用#lang申明的语言类型。它仍然会吧#lang放在文本的第一行。
1.1和Racket交互
DrRacket底部的文本区域和racket命令行程序都像是一个计算器。输入一个racket表达式,敲入回车键,结果就会被打印出来。这种交互被叫做读取求值打印循环简称REPL。
数字是一个表达式,它求值的结果就是一个数字。
>5
5
字符串也是一个表达式并被求值成它自己。一个字符串以双引号开始和结束。
Racket使用括号来表示大型的表达式,几乎任何表达式或者简单的常量。比如,函数调用写成(函数名 参数···)。
1.2 定义和交互
你能使用define定义自己的函数。尽管你能在REPL里执行define,定义经常被保留并在之后使用。所以,在DrRacket里,你一般吧定义放在顶部区域-叫做定义区-并使用#lang作为前缀。
#lang racket
(define (extract str)
(substring str 4 7))
如果调用(extract "the boy")是主程序的一部分,那么应该放置在定义区。但是如果它只是一个例子表达式,用来探索exttact的用法,那么你他它留在定义区,点击运行,然后在repl里执行(extract "the boy")。
当使用命令行程序而不是在DrRacket里面运行,你可以使用你最喜欢的编辑器来保存上面的代码。如果你保存成"extract.rkt",然后在同一目录运行racket,你可以像下面这样执行
>(enter! "extract.rkt")
>(extract "the gal out of the city")
"gal"
enter!形式加载文件的代码并切换执行环境到模块内部,和DrRacket的运行按钮执行相同的操作。
1.3创建可执行文件
如果你的文件或者DrRacket的定义区域包含下列代码
#lang racket
(define (extract str)
(substring str 4 7))
(extract "the cat out of the bag")
它是一段完整的程序当执行时打印出“cat”,在DrRacket里面或者使用enter!形式在命令行里。但是如果程序被保存在<src-filename>的文件里,你可以在命令行里使用命令运行
racket <src-filename>
为了打包程序变成一个执行文件,你可以使用以下方法
- 在DrRacket里,你可以选择Racket|Create Executable菜单。
- 在命令行里,运行raco exe <src-filename>。查看raco exe: Creating Stand-Alone Executables 可以看到更多信息。
- 在unix或者mac os x里,你可以把程序文件转变成一个可执行的脚本只要插入
#! /user/bin/env racket
在文件开头的地方。当然,使用chmod +x <filename>改变文件的执行权限。
这种情况需要racket在用户的执行搜索路径上。你也可以指定一个全路径指向racket在#!之后,在这种情况下用户的执行搜索路径就没关系了。
1.4Lisp/Scheme的备注
如果你已经知道了Scheme或者Lisp,你可以把下面代码
(define (extract str)
(substring str 4 7))
放在"extract.rktl"里面并使用下面命令运行
>(load "extract.rktl")
>(extract "the dog out")
"dog"
这样也可以运行,因为racket会模仿传统的lisp环境,但是我们强烈建议不要使用load或者在一个模块外层运行代码。
定义运行在模块外部会产生很多问题。比如不好的错误信息,性能不好,不能很好整合。模块系统设计可以很好的避免问题。