programming-languages学习笔记–第5部分

*/-->

pre.src {background-color: #292b2e; color: #b2b2b2;}

programming-languages学习笔记–第5部分

1 Racket语法

Racket有非常简单的语法,term如下:

  • an atom, 例如#t, #f, 34, "hi", null, x,…
  • a special form, 例如define, lambda, if
    • 可以使用宏定义自己的特殊形式
  • 括号里的包含的term序列:(t1 t2 … tn)
    • 如果t1是一个特殊形式,序列的语义是特殊的
    • 否则是一个函数调用

使用括号把程序文本转换为程序的树形表示非常方便和清晰。

Racket中每个括号都是有意义的,不能随意添加或删除。
(e)表示无参数调用e, ((e))表示无参数调用e,并无参数调用其返回结果。

2 动态类型

Racket使用动态类型。

只有执行到错误代码的时候才能发现错误。

3 cond

只有#f是false,其余都是true

(define (sum3 xs)
(cond [(null? xs) ]
[(number? (car xs)) (+ (car xs) (sum3 (cdr xs)))]
[#t (+ (sum3 (car xs)) (sum3 (cdr xs)))])) (sum3 (list (list ) (list (list ))))

4 局部绑定

有4种方法:

  • let
  • let*
  • letrec
  • define

3种let表达式可以出现在任何地方.

let表达式在表达式之前就全部求值。

(define (silly-double x)
(let ([x (+ x )]
[y (+ x )]) ;这里的x为参数x
(+ x y -5))) ;等价于(+ x x)

let*表达式在每个之前的绑定环境中求值。

(define (silly-double x)
(let* ([x (+ x )]
[y (+ x )]) ;这里的x为+3的x,在上一个绑定的环境中
(+ x y -8)))

letrec表达式在包括所有绑定的环境中求值。用于相互递归,但是表达式还是按照顺序求值。

(define (silly-triplee x)
(letrec ([y (+ x )]
[f (lambda (z) (+ z y w x))]
[w (+ x )])
(f -9)))

在函数体的开头使用define,语义和letrec一样。

5 Toplevel Bindings

文件中的绑定和letrec类似:

  • 和ML一样,可以引用之前的绑定
  • 和ML不同,也可以引用之后的绑定
  • 但是只能在函数体中引用后面的绑定
    • 因为绑定是按顺序求值的
    • 使用未定义变量是一个错误
  • 和ML不同,不能在模块中定义相同的变量两次。

6 使用set!

绑定是可变的,改变绑定:
(set! x e)

(define b )
(define f (lambda (x) (* (+ x b))))
(define c (+ b ))
(set! b )
(define z (f ))
(define w c)

执行上面的程序,z绑定为9,因为set!改变了b绑定的值。c绑定为7,因为c绑定的值是在set! b前求值的。

如果不想让f中的b受可能会改变的影响,则在改变发生前制造一个copy.

(define f
(let ([b b])
(lambda (x) (* (+ x b)))))

racket中,绑定只能在定义的模块中使用set!修改它。

7 cons

cons制造一个pair,并不是list。以null结尾的嵌套pair是一个list.

cons的单元格是不可变的,mcons可以改变。

(define x (cons  null))
(define y x)
(set! x (cons null))
(define fourteen (car y))

set!并没有修改x指向的旧pair的内容。使用mcons和set-macr!和set-mcdr!可以修改pair内容。

8 延迟求值和Thunks

一个语言构造的关键语义问题是它的子表达式是何时求值的。比如在racket中:
(e1 e2 … en) 将在求值函数体之前求值函数参数e2, …, en. (lambda (…) …) 直到调用函数的时候才求值函数体。注意特殊形式的求值顺序有所不同,如if.

使用(lambda () e)达到延迟求值的目的,thunk the argument的意思就是使用(lambda () e)代替e.

9 使用Delay和Force进行惰性求值

惰性求值,按需调用,promises. 用于避免重复计算。

(define (my-delay th)
(mcons #f th)) (define (my-force p)
(if (mcar p)
(mcdr p)
(begin (set-mcar! p #t)
(set-mcdr! p ((mcdr p)))
(mcdr p))))

10 streams

流是无限序列值。实现流的方法有很多种,最简单的可以把流作为一个thunk,调用的时候产生一个pair,序列中的第一个元素,表示流的第二个到无限个元素的thunk。

(define ones (lambda () (cons  ones)))

(define nats
(letrec ([f (lambda (x) (cons x (lambda () (f (+ x )))))])
(lambda () (f ))))
(car (nats))
(car ((cdr (nats))))

11 Memoization

与惰性求值相关的惯用法,并且不直接使用thunks的是memoization.必须避免副作用,并且同样的参数返回同样的结果。

(define (fibonacci1 x)
(if (or (= x ) (= x )) (+ (fibonacci1 (- x ))
(fibonacci1 (- x ))))) ;; memo
(define fibonacci
(letrec ([memo null]
[f (lambda (x)
(let ([ans (assoc x memo)])
(if ans
(cdr ans)
(let ([new-ans (if (or (= x ) (= x )) (+ (f (- x ))
(f (- x ))))])
(begin
(set! memo (cons (cons x new-ans) memo))
new-ans)))))])
f))

12 Macros

宏定义为语言增加新的语法。它描述了如何把新语法转换为语言已有的不同的语法。宏系统是定义宏的语言。macro use只是使用一个之前定义的宏。macro use的语义是用宏定义的合适语法替换宏。这个过程经常叫作宏展开,因为它很常用,但并不需要语法转换产生大量代码。

关键点是宏展开在我们学过的任何东西之前:在类型检查之前,在编译之前,在求值之前。因此宏可以在任何地方展开,比如函数体内,条件分支内等。

宏系统用于添加语法糖,等同于用语法糖扩展现有语言。

宏定义,宏展开。

Tokenization

(define-syntax my-if
(syntax-rules (then else)
[(my-if e1 then e2 else e3)
(if e1 e2 e3)]))
(my-if then else )

卫生宏,宏展开后的变量名与展开位置的变量名不会混淆。靠词法作用域。

作者: ntestoc

Created: 2019-01-09 三 10:46

programming-languages学习笔记--第5部分的更多相关文章

  1. CUDA Programming Guide 学习笔记

    CUDA学习笔记 GPU架构 GPU围绕流式多处理器(SM)的可扩展阵列搭建,每个GPU有多个SM,每个SM支持数百个线程并发执行.目前Nvidia推出了6种GPU架构(按时间顺序,详见下图):Fer ...

  2. Programming Erlang 学习笔记(一)

    入门 启动Shell 在cmd中输入命令”erl”,百分号(%)表示一个注释的开始,从百分号开始到这行结束的所有文本都被看做是注释. 一个完整的命令需要以一个句点和一个回车结束. 退出erlang的命 ...

  3. UIView Programming Guide学习笔记

    |View |Creating and Configuring View Objects |Creating and Managing a View Hierarchy |Adjusting the ...

  4. The C++ Programming Language 学习笔记 第7章 函数

    1.关于内联函数(inline)      借用一下书中的例子. inline int fac(int n) { ) ? :n*fac(n-); }      inline描述符给编译器一个提示,要求 ...

  5. The C++ Programming Language 学习笔记 第6章 表达式和语句

    1.关于strcpy函数. 书中说c风格的字符串尽量少用,strcpy这样的函数应该也要少用.这里讲这个函数主要是要通过本章课后练习第十题来讲一下前面提及的要点.巩固一下前几章的知识.写了一段,本来感 ...

  6. The C++ Programming Language 学习笔记 第5章 指针、数组和结构

    1.关于输出指向字符的指针的值. 现在定义,char c='a',char* pc=&c.在C中,输出该值只需要printf("%p\n",pc);而在C++中,如果cou ...

  7. The C++ Programming Language 学习笔记 第四章 类型和声明

    1.关于main 函数中的 return 0 C99标准中,main 函数的返回值类型必须是 int ,这样返回值才能传递给程序的激活者(如操作系统).如果 main 函数的最后没有写 return ...

  8. 3D Game Programming withDX11 学习笔记(一) 数学知识总结

    在图形学中,数学是不可或缺的一部分,所以本书最开始的部分就是数学知识的复习.在图形学中,最常用的是矢量和矩阵,所以我根据前面三个章节的数学知识,总结一下数学知识. 一.矢量 数学中的矢量,拥有方向和长 ...

  9. Learning ROS for Robotics Programming Second Edition学习笔记(十) indigo Gazebo rviz slam navigation

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 moveit是书的最后一章,由于对机械臂完全不知,看不懂 ...

  10. Learning ROS forRobotics Programming Second Edition学习笔记(八)indigo rviz gazebo

    中文译著已经出版,详情请参考:http://blog.csdn.net/ZhangRelay/article/category/6506865 Learning ROS forRobotics Pro ...

随机推荐

  1. C# System.Timers.Timers的用法在工控设备上位中的用法

    这两天写设备的上位,由于要读取服务器上的数据库,通过WEBSERVICE访问数据库,我具体的做法是: 1.专门用Timer起线程执行,由于在用的时候报错,不能访问其他线程资源的错误,因此我用了委托的方 ...

  2. linux中find与rm实现查找并删除文件

    find命令: find . -name '*.log' #查找当前目录下的log文件 查找并删除: find . -name '*.log' -type f -print -exec rm -rf ...

  3. Cheatsheet: 2017 10.01 ~ 12.31

    Mobile Updating Your App for iOS 11 Get Started With Natural Language Processing in iOS 11 Getting S ...

  4. Linux下一个最简单的不依赖第三库的的C程序(1)

    如下代码是一段汇编代码,虽然标题中使用了C语言这个词语,但下面确实是一段汇编代码,弄清楚了这个代码,后续的知识点才会展开. simple_asm.s: #PURPOSE: Simple program ...

  5. 【SSH网上商城项目实战27】域名空间的申请和项目的部署及发布

     转自:https://blog.csdn.net/wwww_com/article/details/54405355 前面陆陆续续的完成了网上商城的一些基本功能,虽然还有很多地方有待完善,但是不影响 ...

  6. hdu 3415 Max Sum of Max-K-sub-sequence 单调队列。

    Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ...

  7. rocketmq Don't have SubscriptionGroup

    1. 问题描述 rocketmq 生产者发消息正常 mq后台也可以看到发出的消息 但是消费者一直没消费 好像订阅没成功 2. 问题排查 通过上图查看 确实没有检测到订阅者 3. 问题解决 线上环境是 ...

  8. Django实现验证码

    简单搞定生成验证码: 1.views.py from io import BytesIO import random from PIL import Image,ImageDraw,ImageFont ...

  9. Sql语句常用关键字

    --语 句 功 能--数据操作SELECT --从数据库表中检索数据行和列INSERT --向数据库表添加新数据行DELETE --从数据库表中删除数据行UPDATE --更新数据库表中的数据 --数 ...

  10. float浮动

    float是什么意思?float是浮动,翻译成中文也是浮动意思.进入对应css手册中float手册了解float基本信息. Float常跟属性值left.right.none Float:none 不 ...