#daily #tech #cs #pl 又是一周的 duangsuse 随机瞎想集合
今天的格言是
+ #Rust 奇怪的
对 Rust 宏稍微有一点了解的人(比如我)(但我只限于·一点·了解)(我还会学)知道宏可以按标记类型匹配(其实是我搞错了... Rust 这个宏处理过程有点奇葩弄得我糊涂了)
\+ block: 区块(即由花括号包起的一些语句加上/或是一项表达式)。
但是 模式(Rust 支持模式匹配如
+ #functional Haskell: 面向 Currying 编程和
Haskell 的确是一门比较复杂的语言... 比 Java 难学多了(毕竟 declarative),其名称是取自计算机科学家、逻辑学家 Haskell B. Curry 的 "Haskell" 名字 https://www.haskell.org
其实嘛... Haskell 在语言上还是很简洁的,但是函数式老是递归、集合处理 currying 什么的小白们就只能望 declaration 兴叹了(233 我下面给大家一下 Haskell 语法的资料)
\+ antlr/grammars-v4#210 btw. InScript 也不是 Context-free grammar 的,因为我们的语言结构是基于 indentation 缩进的... 虽说我们的分词器能够自动插入内部的
\+ https://www.haskell.org/onlinereport/haskell2010/haskellch10.html (Haskell 2010 的报告,语法部分)
稍微对 Haskell 函数定义有点了解的人会知道(初学者难度),假设我们有一个这样的函数
同时我们也知道了,Haskell 类型声明里
而 Ruby 里
+ #cs duangsuse 的九条命
曾经 duangsuse 很菜的时候(其实也就是六七个月前)认识了 @ice1000 等(好吧其实大体只有他一个)(现在都认识我了,当然第一印象全是负面的...)
这个标题是说什么呢... 就是说已经被很多 CS 讨论 (QQ)群给踢出去了(因为开始的时候技术很菜... 然后我又喜欢到处参与技术讨论... 然后说的全 TM 是错的... 大佬群容不得小白)
好吧,现在只剩下一个编译原理群了... 且行且珍惜,里面基本都是讨论编译原理、有时也有热点话题和操作系统、线程池什么的 😭
所以说吃瓜群众一定不要插话神仙打架:
一定不要参与自己 *完全* 不了解的讨论
一定不要参与自己 *完全* 不了解的讨论
一定不要参与自己 *完全* 不了解的讨论
今天的格言是
想给你一个拥抱,让全世界知道。 ——微微一笑很倾城 via 一言 API (闲的了)+ #Rust 奇怪的
ty 标记类型名称对 Rust 宏稍微有一点了解的人(比如我)(但我只限于·一点·了解)(我还会学)知道宏可以按标记类型匹配(其实是我搞错了... Rust 这个宏处理过程有点奇葩弄得我糊涂了)
宏模式中还可以包含捕获。这允许输入匹配在某种通用语法基础上进行,并使得结果被捕获进某个变量中。此变量可在输出中被替换使用。
\+ item: 条目,比如函数、结构体、模组等。\+ block: 区块(即由花括号包起的一些语句加上/或是一项表达式)。
但是 模式(Rust 支持模式匹配如
(_, 1))、类型、标记树的类型被称为是 pat、ty、tt 怎么说呢... 感觉还是称为 pattern、type、tree 好一些... (其实我也可以写一个宏修改 rust 的 macro_rules! 语法,但是现在太菜了写不了...)+ #functional Haskell: 面向 Currying 编程和
right precedence "二元运算符右优先级"Haskell 的确是一门比较复杂的语言... 比 Java 难学多了(毕竟 declarative),其名称是取自计算机科学家、逻辑学家 Haskell B. Curry 的 "Haskell" 名字 https://www.haskell.org
其实嘛... Haskell 在语言上还是很简洁的,但是函数式老是递归、集合处理 currying 什么的小白们就只能望 declaration 兴叹了(233 我下面给大家一下 Haskell 语法的资料)
\+ antlr/grammars-v4#210 btw. InScript 也不是 Context-free grammar 的,因为我们的语言结构是基于 indentation 缩进的... 虽说我们的分词器能够自动插入内部的
end 关键字以使它(狭义解析器层面的)变成 CFG\+ https://www.haskell.org/onlinereport/haskell2010/haskellch10.html (Haskell 2010 的报告,语法部分)
稍微对 Haskell 函数定义有点了解的人会知道(初学者难度),假设我们有一个这样的函数
square x = x * x它(符号
square)的类型是 Int -> Int 然后我们可以在 Haskell 里静态写明它的类型: square :: Int -> Int
大家可能和我一样菜到不行所以连 Haskell 的 -> (函数类型)声明都看不懂... 非常简单嘛,函数式 value -> value 态射(morphism)「在集合论中,态射就是函数」,简单的模式就是arg1_type -> result_type
现在你别问是多参函数那怎么办,接下来才是重点,如果我们要定义一个有两个参数的函数 compose,在 Python 里等价(其实并不,区别易见平凡读者自己领悟)的代码:def bcompose(f, g): # b means 'back'Haskell(我们这里自动推导类型)(其实是我不了解 Haskell HM 类型系统所以... 没法显式写类型)(抄的,生而为码农我很抱歉...):
return lambda x: g(f(x))
def add2(x):
return x + 2
def mul10(x):
return x * 10
add2mul10 = bcompose(add2, mul10)
print(add2mul10(2)) # prints 40: (2 + 2) * 10
compose :: (b -> c) -> (a -> b) -> (a -> c) -- 貌似 REPL 会出问题,你们看定义就好了...我们来看看类型:
compose f g = \x -> f(g(x))
-- 我使用 do let add2 = (+2) in let mul10 = (*10) 的时候出问题了... 只能这样
add2 = (+2)
mul10 = (*10)
add2mul10 = compose mul10 add2
print(add2mul10 2)
add2 :: Integer -> Integer首先你已经知道了(并不) why
mul10 :: Integer -> Integer
add2mul10 :: Integer -> Integer
compose :: (b -> c) -> (a -> b) -> (a -> c)
add2mul10 = compose mul10 {- which 类型是 Int -> Int -} add2 {- 同左 -}
compose {- add2mul10 -} :: (b:Int -> c:Int) -> (a:Int -> b:Int) -> (a:Int c:Int)
-- 简单点来说
print add2mul10(1:type of a) -- 先计算的是 add2 which add2mul10 = compose(a->c) -> mul10(b -> c) add2(a -> b) (括号: 类型提示)
compose 函数的类型是 (b->c) -> (a->b) -> (a->c) 因为我会告诉你下面这些代码 which Python 原 compose 函数根本写不出来print' = compose print
print' (+1) 1
-- 2
printAddOne = print' (+1)
printAddOne 3
-- 4
那么现在我们终于知道了... 首先 Haskell 的 Currying 函数类型写法... 不是什么「最后一个是返回值」(实际上的确是,但容易误解为 Haskell 是为了「好看」而这么做的),而是天然的 Currying 导致每「填写」「填充」一个函数参数(假设函数是 a -> b -> c,你只给了 a),Haskell 再返回给你一个函数(b -> c,a 的值已经拿到了),which 参数列表长度少了你已经填充完毕的那一项,直到最后返回 arg1 -> result 的时候,给你的才是真正的返回值(c)...(这就是 Currying,柯里化,btw. 其实它不是柯里本人发明的技巧,是 Moses Schönfinkel 发明的,但 Haskell 本人做了很大贡献)同时我们也知道了,Haskell 类型声明里
-> 的右优先级(right precedence)比左优先级高,正如 Ruby 里的 :: 一样,因为我们知道 a -> b -> c 其实是 a -> (b -> c) which (b -> c) 是一个函数,就是说它返回一个函数。高阶函数(higer-order function)。而 Ruby 里
Object::ObjectSpace::WeakMap (其实等于 ObejctSpace::WeakMap 为啥你自己猜)显然我们要先求值(假设没有优化,或者说不管有没有优化语义都不该发生变化) Object 然后 Object::ObjectSpace 最后才是获得常量 WeakMap 的引用,那也就是说 :: 的右优先级比左优先级高喽+ #cs duangsuse 的九条命
曾经 duangsuse 很菜的时候(其实也就是六七个月前)认识了 @ice1000 等(好吧其实大体只有他一个)(现在都认识我了,当然第一印象全是负面的...)
这个标题是说什么呢... 就是说已经被很多 CS 讨论 (QQ)群给踢出去了(因为开始的时候技术很菜... 然后我又喜欢到处参与技术讨论... 然后说的全 TM 是错的... 大佬群容不得小白)
好吧,现在只剩下一个编译原理群了... 且行且珍惜,里面基本都是讨论编译原理、有时也有热点话题和操作系统、线程池什么的 😭
所以说吃瓜群众一定不要插话神仙打架:
一定不要参与自己 *完全* 不了解的讨论
一定不要参与自己 *完全* 不了解的讨论
一定不要参与自己 *完全* 不了解的讨论
www.haskell.org
Haskell Language
The Haskell purely functional programming language home page.
duangsuse::Echo
#daily #tech #cs #pl 又是一周的 duangsuse 随机瞎想集合 今天的格言是 想给你一个拥抱,让全世界知道。 ——微微一笑很倾城 via 一言 API (闲的了) + #Rust 奇怪的 ty 标记类型名称 对 Rust 宏稍微有一点了解的人(比如我)(但我只限于·一点·了解)(我还会学)知道宏可以按标记类型匹配(其实是我搞错了... Rust 这个宏处理过程有点奇葩弄得我糊涂了) 宏模式中还可以包含捕获。这允许输入匹配在某种通用语法基础上进行,并使得结果被捕获进某个变量中。此变量可在输出中被替换使用。…
+ #oop 垃圾 duangsuse 才知道为什么 #Java 子类转型基类是类型安全的
简单点来说(我不讲什么面向对象的 is_a(class) 什么 can_do(interface)无关的):
我们知道,有一种类型理论叫做「Duck Typing(动态类型)」「一个动物走起来像鸭子、叫起来像鸭子,那它就是鸭子」
鸭子的叫声是 Quack,并且它叫唤的时候,我们假设能够获得它的名字 — 并且知道它是只鸭(肯定的)
现在我们有个函数,它接受一只动物(Animal)并且会先确保它醒着(如果已经睡着就把它弄醒),让它叫。然后会再让它睡着,再让它叫(打呼噜 233)
我们再回到「Duck Typing」动态类型的理论上来,因为 Animal 类「派生」到的对象,他们都拥有的
因为我们只知道可以在
而反观
我们反过来看,
我们都知道了,
+ #emmm 菜鸡要啃草才能... 变成肉鸡
duangsuse 比较菜呢... 好好学习吧,菜鸡虽然菜... 多吃点总会变成... 肉鸡(删除)战斗鸡的吧 当然也要注意身体啊(现在我明显没有...)
+ #cs #pl 读 Lice 动态作用域实现后我才知道 Lime 主动实现的是动态作用域...
动态作用域... 就是那种只是在特殊操作的时候维护作用域「Environment」栈的方法吧,比如在进行函数调用的时候,至于作用域嵌不嵌套是另一回事
冰冰这篇博文说的是
于是就这么做:我在进入新嵌套作用域时已经知道了那个作用域有哪些符号,然后我检查冲突并且把冲突的符号(包含符号的名字和值)给备份一下(集合类型引用备份到栈上),然后再进入作用域,这样就可以简单的 put() 和 get() 了(不过你依然得记录新产生的键值对,等到离开这层作用域时删除他们,不能让符号「泄漏」到作用域外面)
就是说它看重时序,而不是「定义域」
我看完博客后自己又草稿了几种不同的作用域实现,我感觉帅炸了:
\+ PrefillScope
\+ PrefixScope (NamespaceMap)
\+ IndexedScope
\+ ArrayOrHashScope (AutoArrayOrHashMap)
\+ CollisionScope (CollisionMap, ByPlaceCollisionMap)
+ #android #tech #dev Android 的保护(反 crack)技术
六个我还记得(真的有六个?)
1. 手动验证 OkHttp SSL 证书以 filter 掉系统 CA 证书信任「bypass 绕过检验」问题
2. Mess 混淆 XML
3. Proguard 混淆 repackage
4. 核心代码用 native 语言写
5. JNI_OnLoad 验证环境
6. 忘记了一个... 哦是用第三方库加密 assets 运行时解密,这个也很常见
+ #pl #cs 常见的程序语言实现优化技术,扫盲
1. 常量传播
2. 常量折叠
3. 函数内联
4. 指令顺序调整
5. 公共子表达式消除
6. 逃逸分析
7. 循环常量外提
8. 循环展开
9. 死代码消除
10. 表达式重组
啊啊啊懒得写了
简单点来说(我不讲什么面向对象的 is_a(class) 什么 can_do(interface)无关的):
我们知道,有一种类型理论叫做「Duck Typing(动态类型)」「一个动物走起来像鸭子、叫起来像鸭子,那它就是鸭子」
abstract class Animal {
boolean is_sleeping = false;
public Animal() {}
public void sleep() { is_sleeping = true; }
public void wakeUp() { is_sleeping = false; }
public boolean isSleeping() { return is_sleeping; }
public void makeNoise() {
if (!is_sleeping)
System.out.println("Animal making noise");
else
System.out.println("Sleeping animal making noise");
}
}
这是我们对「动物」的定义:可以睡觉、可以发声,同时这个封装保存了 boolean is_sleeping 状态,允许 Animal 的子类实现根据情况(动物是否醒着) makeNoise
class Duck extends Animal {
final String name;
public Duck(String name) { this.name = name; }
public String getName() { return name; }
@Override public void makeNoise() {
System.out.print("[Duck ");
System.out.print(name);
System.out.print("] ");
if (!is_sleeping) System.out.println("Quack!");
else System.out.println();
}
}
这是我们对鸭子(Duck)的定义:它定义为依赖 Animal 类(从此类派生(Derived)),并且有一个扩展字段:name 以允许我们给鸭子命名鸭子的叫声是 Quack,并且它叫唤的时候,我们假设能够获得它的名字 — 并且知道它是只鸭(肯定的)
现在我们有个函数,它接受一只动物(Animal)并且会先确保它醒着(如果已经睡着就把它弄醒),让它叫。然后会再让它睡着,再让它叫(打呼噜 233)
public static void playWithAnimal(final Animal animal) {
if (animal.isSleeping()) animal.wakeUp();
animal.makeNoise();
animal.sleep();
animal.makeNoise();
}
我们来测试一下(假设下面的代码是 Groovy 写的)animal = new Duck("Doddle")
animal.makeNoise()
// [Duck Doddle] Quack!
animal.sleep()
animal.makeNoise()
// [Duck Doddle]
playWithAnimal(animal)
// [Duck Doddle] Quack!
// [Duck Doddle]
... 好吧,我承认我的例子举得比较失败,但有上面的例子我想你已经知道为啥这种类型转换(type casting)是安全的了playWithAnimal 接受一个 Animal 作为它的参数,而 Duck 是 Animal 的子类却也可以被传递进去,为什么呢?我智商比较低一直不明白因为 Duck 「继承」了 Animal 的所有公开方法和公共属性,将 Duck 转换为 Animal 会让对象不能 getName()(Animal 类没有这个方法),而不管怎么样,都不会让 Animal 类原有的 sleep() wakeUp() 方法被 *删除* 而无法调用
Duck *是*(is_a) 一个 Animal,只不过它有自己额外的特性(name)而已!所以将它隐式转型为 Animal 是完全可以的
Duck is JUST an Animal AND MORE!我们再回到「Duck Typing」动态类型的理论上来,因为 Animal 类「派生」到的对象,他们都拥有的
Animal 所拥有行为(睡觉、发出叫声),所以他们都 *是* Animal因为我们只知道可以在
Animal 对象上做这些操作:sleep、wakeUp、isSleeping、makeNoise,而这个类的实例对象实现了所有这些 *行为*,就说它 *是* Animal而反观
Duck 呢?它从 Animal 那里继承到了所有这些操作,所以它当然是一只 Animal我们反过来看,
Duck 比 Animal 多了一项操作:getName,而 Animal *没有* 实现此操作,所以 Animal 不是一个 Duck我们都知道了,
Animal 并不是一个 Duck,所以在运行时将它(一个相对的基类)转型为 Duck(相对的子类)自然是不可能实现的。同时这也不是类型安全的行为+ #emmm 菜鸡要啃草才能... 变成肉鸡
duangsuse 比较菜呢... 好好学习吧,菜鸡虽然菜... 多吃点总会变成... 肉鸡(删除)战斗鸡的吧 当然也要注意身体啊(现在我明显没有...)
+ #cs #pl 读 Lice 动态作用域实现后我才知道 Lime 主动实现的是动态作用域...
动态作用域... 就是那种只是在特殊操作的时候维护作用域「Environment」栈的方法吧,比如在进行函数调用的时候,至于作用域嵌不嵌套是另一回事
冰冰这篇博文说的是
let var = valExpr 这种作用域优化。就是说在求值的时候可以只在全局放一个 Hashtable 因为一旦放多(每层 scope 一个 hashtable,*访问(read/write)* 还是带锁的(这是他原话我也不知道是写带锁还是全都带锁))了他会很心疼(Hashtable 这种空间换时间的数据结构... allocate 一大堆 bins 会爆炸的)于是就这么做:我在进入新嵌套作用域时已经知道了那个作用域有哪些符号,然后我检查冲突并且把冲突的符号(包含符号的名字和值)给备份一下(集合类型引用备份到栈上),然后再进入作用域,这样就可以简单的 put() 和 get() 了(不过你依然得记录新产生的键值对,等到离开这层作用域时删除他们,不能让符号「泄漏」到作用域外面)
就是说它看重时序,而不是「定义域」
我看完博客后自己又草稿了几种不同的作用域实现,我感觉帅炸了:
\+ PrefillScope
\+ PrefixScope (NamespaceMap)
\+ IndexedScope
\+ ArrayOrHashScope (AutoArrayOrHashMap)
\+ CollisionScope (CollisionMap, ByPlaceCollisionMap)
+ #android #tech #dev Android 的保护(反 crack)技术
六个我还记得(真的有六个?)
1. 手动验证 OkHttp SSL 证书以 filter 掉系统 CA 证书信任「bypass 绕过检验」问题
2. Mess 混淆 XML
3. Proguard 混淆 repackage
4. 核心代码用 native 语言写
5. JNI_OnLoad 验证环境
6. 忘记了一个... 哦是用第三方库加密 assets 运行时解密,这个也很常见
+ #pl #cs 常见的程序语言实现优化技术,扫盲
1. 常量传播
2. 常量折叠
3. 函数内联
4. 指令顺序调整
5. 公共子表达式消除
6. 逃逸分析
7. 循环常量外提
8. 循环展开
9. 死代码消除
10. 表达式重组
啊啊啊懒得写了
duangsuse::Echo
#Kotlin Don't block, Keep moving! 不要阻塞,持续执行!
This media is not supported in your browser
VIEW IN TELEGRAM
你们看看我又双写了多少个字... 都是干货吧?尤其是上面 Haskell 和 Java 的,我作为 Java 开发者一直是知其然(howTo)不知其所以然(why),现在想必都非常清楚了
Java 里没有损失的类型转换貌似都可以是 implicit(隐式)的,而有损失的则必须是显式(explicit)的
Java 的 primitive (aka. valueType 但不一定是真的值类型,我不清楚他们到底是 pass-by-quantity 传值调用还是 pass-by-reference 传引用调用也不清楚是分配 allocated 在栈(Java Stack)上还是在堆(Java Heap)上)按位长度排其实有些「不分上下」的类型,所以我们按「精度」排是
现代的电子计算机架构,32 位 IEEE754 浮点和 64 位的其实 overhead(开销)基本都一样,所以默认基本都是
将一个类(e.g.
实际上你只能把一个对象在运行时转换到它实际的类型,不能随便转换,否则运行时就会抛出异常。很多人分不清编译期和运行期类型检查的联系,不过我也分不清就算了...
现代电子计算机本来就是用一大堆二进制数位(bits)堆起了你的数据,而类型系统所做的就是负责「解释」这些数据和「检查」你的代码是否「类型安全」,即满足类型检查的「约束条件」,比如不能拿
如果真的是我太蠢了一直不理解那 Haskell 的一点资料也是有价值的... 大概吧 😶
Java 里没有损失的类型转换貌似都可以是 implicit(隐式)的,而有损失的则必须是显式(explicit)的
Java 的 primitive (aka. valueType 但不一定是真的值类型,我不清楚他们到底是 pass-by-quantity 传值调用还是 pass-by-reference 传引用调用也不清楚是分配 allocated 在栈(Java Stack)上还是在堆(Java Heap)上)按位长度排其实有些「不分上下」的类型,所以我们按「精度」排是
byte(8) short(16) int(32) long(64) float(32) double(64) (都是数值型,额外还有个叫 char 的 utf-16 (Unicode)字符是 16 位)(其实嘛,boolean 和 void 也算,但 void 不算正式的类型)现代的电子计算机架构,32 位 IEEE754 浮点和 64 位的其实 overhead(开销)基本都一样,所以默认基本都是
f64(double)
一般一个 byte 被叫做一个「字节(8)」,两个被称为一个「半字(16)」,四个被称为一个「字(32)」,八个被称为一个「双字(64)」(括号:二进制位长度)将一个类(e.g.
Object)的对象 cast 到它的子类(e.g. String)是不安全的。所以需要显式转型,在那之前最好还 <reified T>.cast(Object obj) (删除,其实是 T Class<T>.cast(Object obj))方法 check 一下,抛出异常就不要再 runtime cast,很多人包括之前的我不知道如何 不 supress explicit 类型转换的 IDEA inspection 而修复问题,其实你应该显式检查能否强制转型。这样看来其实很多人都并不了解 OOP 动态类型系统呢。都不知道「why」你要显式地把一个对象显式转换为它当前类型的子类实际上你只能把一个对象在运行时转换到它实际的类型,不能随便转换,否则运行时就会抛出异常。很多人分不清编译期和运行期类型检查的联系,不过我也分不清就算了...
现代电子计算机本来就是用一大堆二进制数位(bits)堆起了你的数据,而类型系统所做的就是负责「解释」这些数据和「检查」你的代码是否「类型安全」,即满足类型检查的「约束条件」,比如不能拿
String 去调用 System.exit(int) 那样会引发未定义行为 UB(Undefined Beavior)如果真的是我太蠢了一直不理解那 Haskell 的一点资料也是有价值的... 大概吧 😶
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse::Echo
🐱 Sticker
所以说能自己开发 web 应用也是幸福嘛... 本来可以往 Stiack Note 上记的然后利用机器人同步更新 2333
This media is not supported in your browser
VIEW IN TELEGRAM
我觉得这人(就这篇文章的各种例子而言)有点 low... 😶
有时候感觉知其然并且知其所以然是一种幸福,在别人都只看到表象的时候你能看到本质,所以你不会被各种清奇的问题迷惑也不会被花里胡哨的技巧蒙蔽双眼,总是选择最合适的,而这是只知道 how to 所不能做到的
看到这篇文章突然感觉 Ruby 之类掺了函数式理念的 OOP 真是对工业界帮助好大啊... 区区一个 block 表达能力和自然性(符合直觉、容易理解)吊炸天
别说现在
Java 这种稳如老狗并且老到不行而且从来不加新特性的语言都在添加这种语法和 API,业界主流了。我大多范式(multi-paradigm)威武!
有时候感觉知其然并且知其所以然是一种幸福,在别人都只看到表象的时候你能看到本质,所以你不会被各种清奇的问题迷惑也不会被花里胡哨的技巧蒙蔽双眼,总是选择最合适的,而这是只知道 how to 所不能做到的
看到这篇文章突然感觉 Ruby 之类掺了函数式理念的 OOP 真是对工业界帮助好大啊... 区区一个 block 表达能力和自然性(符合直觉、容易理解)吊炸天
别说现在
Enumerable 的集合处理方法了... 接受一个 lambda、block 或者之类的代码块 "Invokable",从此写码不求人... 太自然了Java 这种稳如老狗并且老到不行而且从来不加新特性的语言都在添加这种语法和 API,业界主流了。我大多范式(multi-paradigm)威武!
Forwarded from 羽毛的小白板
博客园首页发现一篇奇怪的文章,然后发现这个人还真是脑洞清奇。所以说,奇怪的问题只因为奇怪的人用奇怪的方法产生出来
js.es5 map循环一大坑:循环遍历竟然出现逗号!
https://www.cnblogs.com/soyxiaobi/p/9898762.html
js.es5 map循环一大坑:循环遍历竟然出现逗号!
https://www.cnblogs.com/soyxiaobi/p/9898762.html
羽毛的小白板
博客园首页发现一篇奇怪的文章,然后发现这个人还真是脑洞清奇。所以说,奇怪的问题只因为奇怪的人用奇怪的方法产生出来 js.es5 map循环一大坑:循环遍历竟然出现逗号! https://www.cnblogs.com/soyxiaobi/p/9898762.html
最奇怪的是他写了这种代码,好吧是
array.map 不是类似 Ruby 里的 Array#map! 所以优化后可以说是基本等价于 forEach 的/********* ES6 **********/
//一行代码可以省略return
array.map( item => console.log(item))
=>
array.map( item => {
return console.log(item)
})
//多行代码需要{}
array.map( item => {
//do someting 花括号一般是处理某些逻辑
})
//返回组件
array.mao( item => (
<div>{item}</div> //这种比较常出现在react的jsx
))
duangsuse::Echo
我觉得这人(就这篇文章的各种例子而言)有点 low... 😶 有时候感觉知其然并且知其所以然是一种幸福,在别人都只看到表象的时候你能看到本质,所以你不会被各种清奇的问题迷惑也不会被花里胡哨的技巧蒙蔽双眼,总是选择最合适的,而这是只知道 how to 所不能做到的 看到这篇文章突然感觉 Ruby 之类掺了函数式理念的 OOP 真是对工业界帮助好大啊... 区区一个 block 表达能力和自然性(符合直觉、容易理解)吊炸天 别说现在 Enumerable 的集合处理方法了... 接受一个 lambda、block…
现在 OOP 把 PP(面向数据结构 aka. 指令式) 和 FP(函数式) 都给吞了... 就差一个逻辑式了?啊啊啊(其实还有很多)(但大的「范」只有这几个...)
羽毛的小白板
博客园首页发现一篇奇怪的文章,然后发现这个人还真是脑洞清奇。所以说,奇怪的问题只因为奇怪的人用奇怪的方法产生出来 js.es5 map循环一大坑:循环遍历竟然出现逗号! https://www.cnblogs.com/soyxiaobi/p/9898762.html
我跟你们总结一下他是在讲什么:
+ 如何使用
如果你不知道这怎么用,我教你怎么用:
+ 如何使用
String Iterable<String>.join(seprator: String) ...如果你不知道这怎么用,我教你怎么用:
['apple', 'orange', 'pear'].join(" vs. ") //=> "apple vs. orange vs. pear "
如果你是开发者并且发现 pear 后面多了一个空格,我告诉你怎么去除,除非是性能敏感否则这样写已经很好了['a', 'b', 'c'].join(" vs. ").trimRight() //=> "a vs. b vs. c"
如果你好奇它(Array.prototype.join,限于 Array of String)是怎么实现的,我给你一个实现function joinString(strs, seprator = '') {
let buf = [];
strs.forEach(s => { buf.push(s); buf.push(seprator); });
return buf.join('');
}
如果你不止想在集合项之间使用连接(contact)操作,你可以使用 reduce
['a', 'b', 'c'].reduce(console.log)没错,就是这一个姿势点,他居然能写一页... 而且前端还没做好... 而且例子举得居然不是最简用例... 而且废话贼多,我当时还以为他是讲 ES6 里数组的空位
[1,,3] 问题呢(实际上虽然这个是反智的,但 forEach 和 for let 没有这个问题...)
duangsuse::Echo
我跟你们总结一下他是在讲什么: + 如何使用 String Iterable<String>.join(seprator: String) ... 如果你不知道这怎么用,我教你怎么用: ['apple', 'orange', 'pear'].join(" vs. ") //=> "apple vs. orange vs. pear " 如果你是开发者并且发现 pear 后面多了一个空格,我告诉你怎么去除,除非是性能敏感否则这样写已经很好了 ['a', 'b', 'c'].join(" vs. ").trimRight()…
如今的前端啊... too young... sometimes naive 🐸... 算了,因为我的确有点失望,这位前端小哥教的例子到底是最佳实践呢还是半懂不懂的技巧滥用代码呢...
羽毛的小白板
博客园首页发现一篇奇怪的文章,然后发现这个人还真是脑洞清奇。所以说,奇怪的问题只因为奇怪的人用奇怪的方法产生出来 js.es5 map循环一大坑:循环遍历竟然出现逗号! https://www.cnblogs.com/soyxiaobi/p/9898762.html
现在看来其实也没有什么好奇怪的呢... 毕竟尤其是中国,开发者水平差异是巨大。而再重灾区一点的就是 web 前端... 因为他们真的是可以做到干一辈子前端当一辈子码农的 — 你可能看不到他们的技术较 n 年前有什么变化 — 可能都是差不多的,或者说他们对自己代码的「理解层次」根本不会有变化,都只知其一不知其二。
duangsuse::Echo
所以说啊成天写了那么多字在自己的频道上,如果哪天 Telegram 爆炸了,王八蛋 leader durov 跑路了,然后我的数据写了这么多个月的东西全部爆炸 lost 了我都可以进抢救室了... 还是备份一下吧 #telegram #emmm #life #tech
然后我回忆当时 @drakeet 删频道的时候我真的很惊讶啊,他闭源项目和博客也就算了因为数据没有丢失,但如果他没有备份而频道数据丢失了呢... 那自己这么多年积攒的广播都没有了... 他不会珍惜这些东西吗...
This media is not supported in your browser
VIEW IN TELEGRAM
duangsuse 不会 coroutine 呢... 其实我接触 #lua 也是很早之前(十几个月)的事情了,但当时 coro 对我来说只不过是技术名词而已。现在好像也是... 我只知道
Fiber 这种 coro...