【Scheme】编程学习(一) —— 概述

简介: Scheme 是一种编程语言,为 Lisp 的一种变体,本文概述 Scheme 语言

概述

Scheme 是一种编程语言是 Lisp 语言一种变体。在 1975 年由 Guy Steele 与 Gerry Sussman 在 麻省理工的 (Artificial Intelligence lab) 人工智能实验室中发明。 它是 Lisp 的第一个要求其实现使用尾调用优化,并着重于函数式编程和递归算法的方言。

Scheme 编程语言采用极简主义的设计理念,指定一个小的标准核心,并提供强大的语言扩展工具。它广泛用于教育和科学组织,尤其是在人工智能领域。编写 Scheme 的程序员被非正式地称为“Schemers”。

与 Lisp 一样,Scheme 使用 lambda 关键字来表示匿名函数。例如,语句

(lambda (x y) (+ x y))

表示将两个数字相加的匿名函数。

总体来说 scheme 语言有三个特点

  • Simple 语法简洁
  • Weird 有些奇怪
  • Cool 很酷

    I - 语法简洁

代码由括号,符号和空格组成,示例

(operator operand1 operand2 ...)

此行代码由 一个操作符,多个操作数组成,操作符在最前面,操作数在后面。

1.1 - 算数运算 (arithmetic)

看几个具体的例子

(+ 3 4)

结果为 7, 3 + 4 = 7

(* 3 4)

结果为 12 ,3 * 4 = 12

(+ 5 (* 2 2))

结果为 9 , 首先计算 (* 2 2) 的结果为 4,然后计算
5 + 4 , 结果为 9。

1.2 - 定义值

我们可以定义符号,类似于其他语言里的声明变量,示例

(define foo 3)

定义 foo 为 3,我们也可以使用这个符号

(* foo 4)

结果为 12 , foo * 4 等价于 3 * 4 = 12

1.3 - 定义函数

(define (square x) (* x x))

表示函数需要一个入参数,函数体为

(* x x)

调用函数的方法

(square 4)

根据之前的内容,显而易见结果为 16

我们也可以将这个函数用于复合的表达式,例如

(+ (square 2) (square 3))

将两个平方相加,4 + 9 = 13 。

1.4 - 流程控制 (flow control)

(define (abs x)
        (if (< x 0)
            (- x)
            x))

根据条件不同,执行不同的运算。

(abs -3) ; 结果为 3
(abs 3)  ; 结果为 3

注: ';' 为 scheme 语言中的注释

这个函数体为简单的 if 表达式,如果 x 小于 0 ,则调用 减号函数,可近似写成 C 语言:

if (x < 0)
    return -x;
else 
    return x;

1.5 - 数据结构

一种数据结构,例如要写出 value1, value2, value3 ... 则需要使用 list 函数,

(list value1 value2 value3 ...)

比如 排序

(sort (list 4 6 5))

我们将 (4 6 5) 作为一个实参传入 sort 函数,得到结果为:

(4 5 6)

再如 获取长度

(length (list 1 2)) ; 结果为 2

II - 奇怪 Weird

  • Functional (sort of) 函数式编程
  • Dynamic typing 动态输入
  • Functions are values 函数可以被视作值
  • Code is data, data is code 代码可以视作数据,数据也可以被视作代码

2.1 - 函数式 list 操作

(define my-list (list 1 2 3 4 5))

符号定义可以使用 - 符号

(car my-list)

car 函数用于从 list 中获取第一个元素 即 1

(cdr my-list)

cdr 函数用于从 list 中获取除了第一个元素之外的所有元素即 (2 3 4 5)

2.2 - 函数式 递归 (recursion)

(define (sum list-of-values)
        (if (= 1 (length list-of-values))
            (car list-of-values)
            (+ (car list-of-values)
               (sum (cdr list-of-values)))))

第一行定义了函数,最后一行调用了同一个函数,但是不同的实参,之后详细解释

调用:

(sum (list 5 6 7)) ; 结果为 18

2.3 - 动态输入

(define (improved-code q) (* q 2))
(define code-quality 4)
(improved-code code-quality) 
; 结果为 8
(define code-quality "poor")
; expects type as 1st argument,

2.4 - 函数可被视作值

(define (double value) (* 2 value))
(define (apply-twice fn value) (fn (fn value)))
(apply-twice double 2)

结果为 8

2.5 - 数据或代码

(define (swap-2-3 x)
        (list (car x)
              (caddr x)
              (cadr x)))

(swap-2-3 (list 1 2 3))
; (1 3 2)
(swap-2-3 (list "a" "b" "c"))
; ("a" "c" "b")

caddr 首先执行 cdr 再执行 cdr 最后执行 car

(define four-over-two (list '/ 4 2)); '/ 表示为符号不为操作符

four-over-two 
; (/ 4 2),此处将代码视作数据

(eval four-over-two)
; 2, 此处将代码视作代码

我们定义个新的符号

(define switched (swap-2-3 four-over-two))
(eval switched)
; 1/2

首先对 four-over-two 应用 swap-2-3 函数,然后其结果为 ('/ 2 4) ,然后 eval 此 list 为 2 \/ 4 = 1/2

switched
; (/ 2 4)

仅仅打印 switched 其结果为 list ('/ 2 4)

III - 酷 Cool

  • Generics without all that syntax 泛型编程不需要关心很多语法,比如类型在 java, c, c++ 中等等。
  • Generating code is easy 相对其他编程语言生成代码相对简单很多
  • Metaprogramming is just ... programming 元编程在 Scheme 中与正常编程无异
  • Macros are (almost) just more code 宏是一种元编程,在 Scheme 中只是更多的代码
  • There are a lot of brackets 在 Scheme 代码中有很多括号

有一个笑话,当时美国有些先进的设备使用的是 Scheme ,有间谍去偷代码,但是只偷到了最后一部分,打开之后全是括号 :D

3.1 - Everything is generic 一切皆是泛型

(sort (list 5 4 3 2 1) <)
; (1 2 3 4 5)
(sort (list "abc" "a" "ab") string<?)
; ("a" "ab" "abc")

3.2 - 生成代码相对简单

(define (d-zero name)
        (list 'define (string->symbol name) 0))

(d-zero "a")
; (define a 0)

(define (d-zero-list names) (map d-zero names))
(define mycode (d-zero-list (list "a" "b" "c")))

mycode
;((define a 0) (define b 0) (define c 0))

map 为对 list 中的每一项应用方法,现在 mycode 为是数据不是代码。

(for-each eval mycode); 对 mycode 进行代码化执行
a
; 检查 a 得到 0
b
; 检查 b 得到 0
c
; 检查 c 得到 0
d
; 检查 d 得到 reference to undefined identifier : d 
; 引用了未定义的标识符 : d

3.3 - 元编程 Metaprogramming

(define (double x) (* x 2))
(define (square x) (* x x))

(define (apply-twice fn x)
        (fn (fn x)))

(define (quadruple x) (apply-twice double x))
(define (pow-4 x)     (apply-twice square x))

定义如上几个函数

(quadruple 3)
; 12 
(pow-4 3)
; 81

quadruple 为 4 倍的意思
pow-4 为 4 次方的意思

3.4 - 非常好的点

  • Macros - write your own language 宏即是定义自己的语言
  • You must acknowledge the power of the brackets 你必须承认括号的强大

IV - 讨论

安装 Scheme 的方法

$ sudo apt-get install plt-scheme
$ mzscheme
Welcome to MzScheme v4.2.1 [3m], Copyright (c) 2004-2024
>

Windows 电脑也可以下载 Racket
https://download.racket-lang.org/

参考链接:

目录
相关文章
|
7月前
|
缓存 自然语言处理 前端开发
第一章 引言-HTTP协议基础概念和前后端分离架构请求交互概述
第一章 引言-HTTP协议基础概念和前后端分离架构请求交互概述
157 0
|
6月前
|
安全 网络协议 算法
Android网络基础面试题之HTTPS的工作流程和原理
HTTPS简述 HTTPS基于TCP 443端口,通过CA证书确保服务器身份,使用DH算法协商对称密钥进行加密通信。流程包括TCP握手、证书验证(公钥解密,哈希对比)和数据加密传输(随机数加密,预主密钥,对称加密)。特点是安全但慢,易受特定攻击,且依赖可信的CA。每次请求可能复用Session ID以减少握手。
67 2
|
7月前
|
安全 搜索推荐 数据安全/隐私保护
深入探讨HTTPS协议的原理和工作流程
【2月更文挑战第10天】
302 4
深入探讨HTTPS协议的原理和工作流程
|
Linux API C语言
由浅入深C系列五:使用libcurl进行基于http get/post模式的C语言交互应用开发
由浅入深C系列五:使用libcurl进行基于http get/post模式的C语言交互应用开发
|
自然语言处理 C语言 C++
【Scheme】编程学习 (二) —— 基础
Scheme 编程语言学习第二节基础
134 0
|
域名解析 网络协议 大数据
小白必须掌握的几点HTTP协议的基础知识,建议收藏
1.TCP/IP的分层管理 TCP/IP协议族里重要的一点就是分层。TCP/IP协议族按层次分别分为以下4层:应用层、传输层、网络层和数据链路层 应用层: 应用层决定了向用户提供应用服务时通信的活动。 TCP/IP协议族内预存了各类通用的应用服务。比如,FTP(文件传输协议)和DNS(域名系统)服务就是其中两类。HTTP协议也处于该层。
152 1
小白必须掌握的几点HTTP协议的基础知识,建议收藏
|
JavaScript
WebApi入门第五章(attribute语法学习 )
WebApi入门第五章(attribute语法学习 )
116 0
WebApi入门第五章(attribute语法学习 )
|
安全 网络协议 应用服务中间件
HTTP协议基本概念简介
HTTP协议基本概念简介
152 0
HTTP协议基本概念简介
|
SQL 缓存 安全
《图解 HTTP》 阅读摘要(下)
这本 HTTP 方面的小册子还蛮不错,已经二刷了 😜 这次做了一些笔记,方便自己和其他人翻阅和复习,因为这本书是 2014 年出的初版,所以有一些不怎么常用的技术,笔记中就省略了,只记一些比较常用的 ~ 如果希望获取本书的 PDF 资源,可以关注文末二维码加微信群找群主要~
《图解 HTTP》 阅读摘要(下)
|
Web App开发 缓存 JavaScript
《HTTP/2 基础教程》 阅读摘要(上)
最近粗线了不少 HTTP2 相关的帖子和讨论,感觉新一轮的潮流在形成,所以最近找了本 HTTP2 相关书籍做知识储备,刚好记成笔记以备后询 ~ 如果希望获取本书的 PDF 资源,可以关注文末二维码加微信群找群主要~ 这本书本身不错,缺点就是翻译的有点蹩脚,另外因为是 2017 年出的书,所以有些内容时效性不太好,比如关于 Chrome 的部分,所以我根据 Chrome 的官方文档增加了点内容 😅
《HTTP/2 基础教程》 阅读摘要(上)