课程内容复习
Lec5 函数式语言
-
急求值:急求值是严格求值(Strict),完全求值;急求值对应值调用,最安全
-
正规求值:函数中的形参每次出现均用实参替换(相当于传名调用)。要做多次实参计算。可能有副作用。
-
懒求值:是正规求值的特例。
-
它只到用到被结合的形参变量 的值时才对实参变元表达式求值(第一次出现),求值后将结果 值束定于形参变量,以后形参变量再次出现就不用求值了。
-
对于复杂的表达式如果子表达式求值对整个表达式求值没有影 响就不再求它。
-
短路(short circuit)求值,一般用作条件表达式,也叫短路条件。
E = Exp1 and Exp2 and …Expn 若Exp1求值为false,则E值已定为false。
再如: E = Exp1 or Exp2 or …Expn 若Exp1为true,则E值为true不论其它表达式取何值。
C、Ada及近代函数式语言均采用懒求值。
-
λ演算参考
并发——go语言
并发编程练习题:
假设存在一个生产者,依次产生数字0到9。存在一个奇数消费者,一个偶数消费者分别使用奇数和偶数,使用Go语言通道实现这个生产者消费者模型。使得数字按从小到大的顺序输出。
思路:新添加一个Channel,用以两个Consumer之间通信,传递一个flag。拿到flag的Consumer进行输出,没有拿到flag的Consumer阻塞。因为从0开始输出,所以flag最初在偶数消费者手中。
package main
import (
"fmt"
"sync"
)
// wg 用来等待程序结束
var wg sync.WaitGroup
func main() {
oddChannel := make(chan int)
evenChannel := make(chan int)
//排序标志,必须获取到这个量才能输出,false表示输出偶数,true表示输出奇数
flagChannel := make(chan bool)
// 计数加 3,表示要等待3个goroutine
wg.Add(3)
go producer(oddChannel, evenChannel)
go oddConsumer(oddChannel, flagChannel)
go evenConsumer(evenChannel, flagChannel)
//初始是偶数
flagChannel <- false
// 等待结束
wg.Wait()
}
func producer(odd chan int, even chan int) {
// 在函数退出时调用Done 来通知main 函数工作已经完成
defer wg.Done()
for i := 0; i < 10; i++ {
if i%2 == 0 {
even <- i
} else {
odd <- i
}
}
close(odd)
close(even)
}
func oddConsumer(odd chan int, flag chan bool) {
defer wg.Done()
for {
value, ok := <-odd
if !ok {
fmt.Printf("Consumer odd, work done\n")
return
}
outFlag := <-flag
if outFlag {
fmt.Printf("Consumer odd, get value %d\n", value)
}
flag <- false
}
}
func evenConsumer(even chan int, flag