原来显示屏还分 PWM(Pulse Width Moderation,脉冲宽度调制) 和 DC(Direct Current) 两种
还有 频闪、OLED、Amoled、拖影、偏色、(PWM)占空闭、刷新率、垂直更新、逐行刷新、隔行更新、果冻效应、运动模糊、灰阶、刷新频率矫正 什么的
显示相关的参数有对比度、亮度、色域、亮/暗处的显示效果、色准 等
https://t.me/c/1076357496/1734632 #hardware #CG
还有 频闪、OLED、Amoled、拖影、偏色、(PWM)占空闭、刷新率、垂直更新、逐行刷新、隔行更新、果冻效应、运动模糊、灰阶、刷新频率矫正 什么的
显示相关的参数有对比度、亮度、色域、亮/暗处的显示效果、色准 等
https://t.me/c/1076357496/1734632 #hardware #CG
#life #statement 《莫言谈教养》(杂志上看到,没找到源头)
假如有人在谈论李白,
此时一个人出来问了一句,『李白是谁?』,这是最初级的没有教养,因为他不读书。
又有一个人出来哈哈大笑,『你连李白是谁都不知道啊!』,这是中级的没有教养,因为他不懂得尊重人。
另外一个人立刻开始就着李白的出生经历高谈阔论,这是最高级别的没有教养,因为他炫耀自己的知识。
假如有人在谈论李白,
此时一个人出来问了一句,『李白是谁?』,这是最初级的没有教养,因为他不读书。
又有一个人出来哈哈大笑,『你连李白是谁都不知道啊!』,这是中级的没有教养,因为他不懂得尊重人。
另外一个人立刻开始就着李白的出生经历高谈阔论,这是最高级别的没有教养,因为他炫耀自己的知识。
Forwarded from Deleted Account
重要的不是学语言,是你先把 JavaScript 和 Java 里那一些基本的数据类型 primitives、控制结构给背下来,然后再去学「疯子」封装、抽象、继承、多态的面向对象,把这个抽象能力和编程经验给提上来,然后再怎么样自己想喽。
那个基本数据比如 boolean, byte, short, int, long, float, double, char, string 吧,加上 array, reference, function, error,基本数据结构比如 list, set, map 什么的,都记下来,以后整理认知用得到。
控制结构比如 seq, branch, repeat 吧,换成 Java 就是 {} 组合语句、if + if else + switch + ? : ternary、while, for, do while、break continue,然后再多看点高级语言虚拟机(HLLVM) 的指令流的学习一点编译原理的知识,认识一下老冯(Von Newmann) 那一套存储、运算、控制、输入输出的,自己写个解释器出来不就会好很多了么?多了解一下,学处理树形结构,写点子类型的 Evaluator 和 visitor pattern 的 tree walker 什么的。
对象和消息那个极其类似 UML(Unified Model Language) 术语的『给某 obj 发信号』就理解为『一群对象互相驱使』好了。
面向对象多态就是子类型、参数化类型,特殊多态函数 overload 和 C++ 那个类型转换貌似就是。
子程序的 vararg 了解和 C、C++ 用 stdarg.h 和 initializer_list、template 特化递归和 ... 展开的可以去学学,毕竟元编程。
算法就不用学太多了,先认识一下 BFS 广度优先搜索、常递归实现的 DFS 深度优先搜索就好了,当然狄克斯特拉算法、二分查找、并查集(UnionFind) 快速查找的传递关系优化、那个『树状数组』的权重优化也是可以参考一下的,关系式(relational programming) 的 unification 算法也可以学习一下,六个基本元素 variable, state, introduce(fresh), eq, both, either,不就是求解相等么,以后写点类型推导算法用得上,逆波兰记法
纯函数式编程完全可以不学,范畴论直接以你们家的族谱开始枚举可选的箭头就可以了,然后传统函数式数据 Maybe Either 相当常用,Haskell 写解释器学下 GADTs 和 TypeFamilies 小姐的博客是个不错的选择。
重要的是学模式,那个
那个基本数据比如 boolean, byte, short, int, long, float, double, char, string 吧,加上 array, reference, function, error,基本数据结构比如 list, set, map 什么的,都记下来,以后整理认知用得到。
控制结构比如 seq, branch, repeat 吧,换成 Java 就是 {} 组合语句、if + if else + switch + ? : ternary、while, for, do while、break continue,然后再多看点高级语言虚拟机(HLLVM) 的指令流的学习一点编译原理的知识,认识一下老冯(Von Newmann) 那一套存储、运算、控制、输入输出的,自己写个解释器出来不就会好很多了么?多了解一下,学处理树形结构,写点子类型的 Evaluator 和 visitor pattern 的 tree walker 什么的。
对象和消息那个极其类似 UML(Unified Model Language) 术语的『给某 obj 发信号』就理解为『一群对象互相驱使』好了。
面向对象多态就是子类型、参数化类型,特殊多态函数 overload 和 C++ 那个类型转换貌似就是。
(1 2 +) 也必须了解下,数值化字符串再化回来的也可以写写啊。可以试试写字典树(trie tree) 和弄个二分查找的 RangeMap 什么的。纯函数式编程完全可以不学,范畴论直接以你们家的族谱开始枚举可选的箭头就可以了,然后传统函数式数据 Maybe Either 相当常用,Haskell 写解释器学下 GADTs 和 TypeFamilies 小姐的博客是个不错的选择。
重要的是学模式,那个
x >= first && x <= last 和 x >= begin && x < stop 的左开右(闭/开) 式区间必须会用,状态机 列表处理 栈 队列什么的必须明白,然后是写点提供 callback 的程序 正确理解回调和异步、不用处理数据同步的那种多线程、SIMD 也可以考虑一下,Forwarded from Deleted Account
计算机科学不能光嘴上说说,所以现在就去拿 Turtle 画画。
多整点应用啊,状态机、线形结构、树形结构、映射是相当重要的抽象模式,纸上编程用起来,当一个快乐的空想工程师。
关键是要买书看啊…… 还能怎么样,我说的又 要 素 过 多,没有结构。
大佬多的是,一年后你有没有长进看自己。
多整点应用啊,状态机、线形结构、树形结构、映射是相当重要的抽象模式,纸上编程用起来,当一个快乐的空想工程师。
关键是要买书看啊…… 还能怎么样,我说的又 要 素 过 多,没有结构。
大佬多的是,一年后你有没有长进看自己。
本苏打算去看看盗版《天气之子》之类的动漫电影什么的,
在此之前,本苏不得不先谈谈解释器实现时的作用域实现 #CS #PLT
下文,我们涉及到主要术语:子程序(subroutine)、参数(argument)、局部变量(local variable)、上值(up-value)、闭包(closure)、词法作用域(lexical scoping)、动态作用域(dynamic scoping)
我们要处理的,就是实现局部变量,此外作为子程序参数的局部变量也包含在内。
此外,还有闭包——对闭包的创建有点像面向对象的架构器调用,我们需要包住 UpValue——也就是外部函数(outter function) 的局部变量,之后闭包被展开(调用,或者说求值)的时候可以用到包好的值。
你和 Ada 通过 SICP 和龙书了解了有这么两种作用域方案(划掉,怎么可能这么简单)
(-1). (大脑降级方案)使用全局作用域
0. (不全实现方案)使用 Map<String, Perfixed<String>>,给变量加函数名前缀。
1. 使用时序作用域,也即动态作用域。 你们用 Stack<Map<String, Object>> 存储变量,每一层都是
2. 使用 Map<String, StackOrSingle<Object>> 优化方案
3. 使用 pre-bind 预先指定使用到的变量,然后在进入可能修改变量的子程序前把老变量备份在系统栈的 Map 上,速度更快。
但是 Ada 同学很快否定了这些做法,理由是,那样容易造成混淆。
咱知道,子程序可以是递归的,也就是说,属从它的参数可能在同一时间有很多个,上面也说了。
但关于子程序
但除了参数,局部变量也是要有的,怎么办?
如果程序自己调用自己也是可能的,怎么办?
调用栈最深的时候,just 的参数是这样的:
所以,为了保证递归可能性,作用域的实现必须和栈有关。
那么局部变量怎么办呢?也在栈上分配嘛。
变量是什么?最关键却不太容易感知到的一点是,变量就是针对某个存储空间的,名字,或者标记符而已,它后面藏着『一个』——有且只有一个 存储空间。
就好像
也就是 lambda 演算的世界观,不过这里才不会提太多术语呢!上面的
我们从
而从
这整个动作,则被称为『施用 Apply』,整个程序表达呢?就叫『应用Application』。
所以参数、局部变量、闭包该如何实现呢?(当然也有全局变量)
Lua呢,因为是手动递归下降解析器,所以直接在解析的时候,做好这个问题就完了。不就是一个名字对应一个存储空间,冲突按嵌套次序深者优先么。
这个问题怎么解决呢?每一层解析器,都得知道当前有什么参数,方便统一这个存储位置。
最根本的需要就是一个
局部变量呢?当然,参数就是局部变量,不过是可以暴露出来给调用者提供的那种而已。
局部变量,定义的时候直接在栈帧上分配好了存储空间。至于都放在栈上如何不冲突呢?
这就涉及到调用约定的问题,调用者知道如何操纵咱共同的存储——系统栈,不会破坏要执行的子程序的取参行为。
名字冲突呢?不存在的事情,字符串的名字可能冲突,存储空间是不可能冲突的。
名字如何在内部的闭包中共享呢?
让解析器知道,闭包里的
不过这有点区别——其实也可以作为引用实现,假设某函数把一个包着自己变量的闭包递了出去,就有可能在变量还『活着』的时候,被自己调用的函数修改,我们这里不考虑这种情况。
Lua 的实现是,UpValue(也就是上面我们说的 someVar,某个闭包包住的外层函数变量)
有两个状态:open/close,我忘记它们代表什么了,好像和 GC 有关。
于是一个闭包长这样:
调用者知道的事情,就是按顺序把它们压到栈上,一般是后参先压(我是指传统 CDEF 的,Lua、JVM 里可能不是这样)。
然后子程序知道的事情,就是现在 (a,b) => a+b 里的 a,我们到栈的第一个位置取,这就保证了 a 指代同一个位置,并且符合参数传递的预期。
局部变量也是一样,都商议好分配位置,如知道
于是,我们的参数可以传递,并且有名字、局部变量可以读写,并且也有名字。现在闭包对 UpValue 的引用怎么办?
我们觉得,既然闭包不可避免地是一种数据对象,那就给它安排一个数组,来存放其 capture 住的部分,其他的和普通函数无二,也有自己的代码、参数和局部变量。
创建闭包时,检查闭包的 captures 列表,分配一个数组把 capture 住变量的实际值都存到里面去,合并入闭包对象的状态里,这样运行时就能拿到 UpValue 的信息了。
—
实现注记:
1. Subst 和 Variable 都是 Local,但 Subst 没有 setValueIn。
2. Upvalue 和 Local 都是 Resolvable,能够关于一个栈取到值
3. Function 和 Closure 都是 Subroutine,可以被提供参数调用也可以有局部变量
4. 在 Lua 里,函数是有 maxlocals 的,换句话说,Subroutine 就有使用的局部存储空间大小这一说,可以在运行前确定。
5. 解析器可以选择低内存优化和低计算优化
如果要为低内存优化,可以使用 ArrayMap,再加上 base map, shadowed map 先往局部遮盖的符号(可能没有)里找,再往上一层的遮盖找,这个数据和算法可以封装为一个 class,一般情况都不用。
6. 查找顺序:局部变量、参数、外部函数的 UpValue,否则就是全局变量。
在此之前,本苏不得不先谈谈解释器实现时的作用域实现 #CS #PLT
下文,我们涉及到主要术语:子程序(subroutine)、参数(argument)、局部变量(local variable)、上值(up-value)、闭包(closure)、词法作用域(lexical scoping)、动态作用域(dynamic scoping)
在编程中,我们经常……算喽,简略点。
我们要处理的,就是实现局部变量,此外作为子程序参数的局部变量也包含在内。
此外,还有闭包——对闭包的创建有点像面向对象的架构器调用,我们需要包住 UpValue——也就是外部函数(outter function) 的局部变量,之后闭包被展开(调用,或者说求值)的时候可以用到包好的值。
function makeCounter() {
var count = 0;
return () => { count++; };
}
var counter = makeCounter()
counter() //: 0
counter() //: 1
假如你是李华,你的朋友 Ada 想要创建一门编程语言,但她不知道如何提供作用域,以使得程序表达更模块化。你和 Ada 通过 SICP 和龙书了解了有这么两种作用域方案(划掉,怎么可能这么简单)
(-1). (大脑降级方案)使用全局作用域
0. (不全实现方案)使用 Map<String, Perfixed<String>>,给变量加函数名前缀。
1. 使用时序作用域,也即动态作用域。 你们用 Stack<Map<String, Object>> 存储变量,每一层都是
Map<String,Object>,然后每次取值时用名字往外找,第一个匹配的就是值,注意,如果你们用 String 作为名字(标识符),不同函数如果名字一样会导致产生可跨层引用,对返回函数指针的处理也可能遭致问题,因为子程序和变量值是完全分开的。2. 使用 Map<String, StackOrSingle<Object>> 优化方案
3. 使用 pre-bind 预先指定使用到的变量,然后在进入可能修改变量的子程序前把老变量备份在系统栈的 Map 上,速度更快。
但是 Ada 同学很快否定了这些做法,理由是,那样容易造成混淆。
one = 1 # "one" in add1那么咱来看 C++ 的 caputre:
def add1(n):
return one + 1
def each_people(people, fn):
for one in people: # most recent definition of "one"
return fn(one)
def print_grow1(person):
name, age = person
print(name + " aged " + add1(age)) # here
each_people([('Jack' 22), ('Rose', 19)], print_grow1)
[some_upvalue](int arg1) { return arg1+some_upvalue; } 咱知道,子程序可以是递归的,也就是说,属从它的参数可能在同一时间有很多个,上面也说了。
但关于子程序
(x) => x + 1 最关键的其实是,我们知道 (x+1) 里的 x 是这个东西的第一个参数。但除了参数,局部变量也是要有的,怎么办?
如果程序自己调用自己也是可能的,怎么办?
def just(n):
if n == 0: return 0
else return just(n-1)+1
just(2) //= just(1) +1 //= just(0) + 1 + 1 调用栈最深的时候,just 的参数是这样的:
[(2), (1), (0)] Top 所以,为了保证递归可能性,作用域的实现必须和栈有关。
那么局部变量怎么办呢?也在栈上分配嘛。
变量是什么?最关键却不太容易感知到的一点是,变量就是针对某个存储空间的,名字,或者标记符而已,它后面藏着『一个』——有且只有一个 存储空间。
就好像
f= (x, y) => x+y 里的 x, y 在生存周期上是『局部变量』,实际上是『参数』,再细化一点,x 代表第一个形式化参数、y 则是第二个。f(1, 2) 最终就代表着 (1+2),这才是正常一点的世界观。也就是 lambda 演算的世界观,不过这里才不会提太多术语呢!上面的
(x, y) 被称为 formals,形式参数、 (x+y) 被称为 body,体。我们从
(x, y) => x+y 的『抽象 Abstraction』,给定两个实际参数 (1,2),填充到 (1+2) 的过程被称为『替换 Substitute』,这 x, y 就被叫做『代词 Substitution』(我自己翻译的……)而从
(1+2) 算出最终的结果 3 的过程,被称为『收束 Reduce』(也是我自己翻译的…… 好像也叫『归约』)这整个动作,则被称为『施用 Apply』,整个程序表达呢?就叫『应用Application』。
所以参数、局部变量、闭包该如何实现呢?(当然也有全局变量)
Lua呢,因为是手动递归下降解析器,所以直接在解析的时候,做好这个问题就完了。不就是一个名字对应一个存储空间,冲突按嵌套次序深者优先么。
这个问题怎么解决呢?每一层解析器,都得知道当前有什么参数,方便统一这个存储位置。
最根本的需要就是一个
Map<Symbol, Local> 符号表,代表本层的词法作用域信息(之前所有外层嵌套的参数和局部变量)局部变量呢?当然,参数就是局部变量,不过是可以暴露出来给调用者提供的那种而已。
局部变量,定义的时候直接在栈帧上分配好了存储空间。至于都放在栈上如何不冲突呢?
这就涉及到调用约定的问题,调用者知道如何操纵咱共同的存储——系统栈,不会破坏要执行的子程序的取参行为。
function solve(a, b, c)(注:Lua 包含常量折叠,也就是说 d 这个数值常量可能不会作为局部变量,这里忽略这种可能)
d = 233
return a, b, c, d -- (arg0, arg1, arg2, var0)
end
名字冲突呢?不存在的事情,字符串的名字可能冲突,存储空间是不可能冲突的。
名字如何在内部的闭包中共享呢?
让解析器知道,闭包里的
someVar 实际上代表着外部 someVar 的值,就对了。不过这有点区别——其实也可以作为引用实现,假设某函数把一个包着自己变量的闭包递了出去,就有可能在变量还『活着』的时候,被自己调用的函数修改,我们这里不考虑这种情况。
Lua 的实现是,UpValue(也就是上面我们说的 someVar,某个闭包包住的外层函数变量)
有两个状态:open/close,我忘记它们代表什么了,好像和 GC 有关。
于是一个闭包长这样:
[captures](formals) {body}
我们怎么创建它呢?考虑一下实现的细节——每个参数都是 Subst(val idx: FrameIdx, val name: String)、每个局部变量都是 Variable(同上),区别主要是参数不可被赋值,而这个存储(编号)分配的过程在解析阶段完成。调用者知道的事情,就是按顺序把它们压到栈上,一般是后参先压(我是指传统 CDEF 的,Lua、JVM 里可能不是这样)。
然后子程序知道的事情,就是现在 (a,b) => a+b 里的 a,我们到栈的第一个位置取,这就保证了 a 指代同一个位置,并且符合参数传递的预期。
局部变量也是一样,都商议好分配位置,如知道
x 是在当前栈顶 -1,取/置都按照这个位置来即可。于是,我们的参数可以传递,并且有名字、局部变量可以读写,并且也有名字。现在闭包对 UpValue 的引用怎么办?
我们觉得,既然闭包不可避免地是一种数据对象,那就给它安排一个数组,来存放其 capture 住的部分,其他的和普通函数无二,也有自己的代码、参数和局部变量。
UpValue(val idx: Idx, val name: String)解析闭包时,记住外层函数的局部变量表,如果知道闭包引用了外层的东西,就把这个被引用的东西往 captures 列表一放,再对应地把对它的引用视为
UpValue(idx, name)。创建闭包时,检查闭包的 captures 列表,分配一个数组把 capture 住变量的实际值都存到里面去,合并入闭包对象的状态里,这样运行时就能拿到 UpValue 的信息了。
—
实现注记:
1. Subst 和 Variable 都是 Local,但 Subst 没有 setValueIn。
2. Upvalue 和 Local 都是 Resolvable,能够关于一个栈取到值
3. Function 和 Closure 都是 Subroutine,可以被提供参数调用也可以有局部变量
4. 在 Lua 里,函数是有 maxlocals 的,换句话说,Subroutine 就有使用的局部存储空间大小这一说,可以在运行前确定。
5. 解析器可以选择低内存优化和低计算优化
如果要为低内存优化,可以使用 ArrayMap,再加上 base map, shadowed map 先往局部遮盖的符号(可能没有)里找,再往上一层的遮盖找,这个数据和算法可以封装为一个 class,一般情况都不用。
6. 查找顺序:局部变量、参数、外部函数的 UpValue,否则就是全局变量。
Forwarded from Mr. Bug | Wild Pointer
Twitter
Michael Anti
青岛警方第一天抓造谣者,然后青岛政府凌晨把谣言官方再宣布下。现在疫情如此严重,各地警方能否少点二逼作孽,多按中央政府的命令救人?
Forwarded from Deleted Account
Wave.kt
728 B
#Kotlin 你说的好有道理啊,虽然花了很长时间我才知道 index/44100.0 再 %1.0 是什么意思,(time/ratio)*2*Pi*Short.MAX_VALUE 嘛,我之前也听说过 PWM,不过只知道能用来做 LED 的闪烁走马灯