duangsuse::Echo
717 subscribers
4.25K photos
130 videos
583 files
6.47K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
duangsuse::Echo
https://github.com/lice-lang/lice 冰封哥都退团了,emmm,之前听说实现 expr 是有啥问题来着
之前不知道是怎么回事搞混了 call-by-name 和 call-by-need,我以为 by-name 是惰性求值,by-need 是重复求值
肯定不是我自己记岔了!第一次看到 call-by-name 它好像被人拿来做是惰性求值的意思了……
duangsuse::Echo
关于 Reflex 这门语言,我这里已经有不少(本来不是为它设计) 的稿子了,但因为都是 JVM 语言所以都可以用,就来汇总一下 看了刚才的示例我感觉非常 excited,分分钟想弄出个大新闻 🐸 这是一门多范式 JVM 编程语言,支持特性包括: + 基本的值、计算、顺序、分支、循环、递归 + 支持高阶函数、Block (closure) + Java 没有太多值类型,所以都是按引用传递 + 支持语言层面的惰性求值(call-by-need),惰性求值是针对函数的返回值、参数,不支持列表等 Iterable…
这一段定义了和 Java 的 interop,

+ Reflex 是一门多范式、动态类型的 JVM 语言,它支持多态,在语法上支持类型标记。
+ 控制流,Reflex 支持顺序、分支、循环、递归。
+ Reflex 支持高阶函数和 Block (closure),函数参数都是按 java.lang.Object 引用传递

+ 语言层面支持(针对函数参数和返回值的)惰性求值和(针对返回值的)表达式作为值
+ 惰性求值使用标准库 lazy {} 函数创建,如果将惰性块保存到本地变量或者作为 Reflex 函数的参数、从函数返回,不求值。lazy 是软关键字
在 Java 的层面看来,收到的对象是 org.duangsuse.reflex.rhs.Lazily
+ 表达式使用 expr Name = Expr : Stmt 语法创建,表达式在每一个要求值的地方求值,表达式可以作为返回值,这种情况返回表达式而不计算,expr 是关键字。
在 Java 的层面看来,收到的对象是 org.duangsuse.reflex.rhs.Expression

+ 允许使用反射访问任何 Java API,内部语法 (.) (::)、标准库 (.$ #) (::$ #) (?.$ #) (?::$ #)
+ o.method 不可以使用,这个语法只能用来表示索引属性 Val / Var
public final o.XXX, public o.XXX 字段、public o.getXXX(), public o.setXXX() 方法
如果属性以 is, has 开头,则查找方法时不添加 get/set 前缀
+ o.method(_) 进行 Partial application (WIP,目前先 reserve 这个 _
+ o::method 来引用某个 receiver 上的方法
+ 所有带 $ 的语法,表示访问非公开属性/字段/方法,都由标准库提供(import std.reflect

创建的所有函数,都由 java.lang.Runnable, org.duangsuse.reflex.fn.Function[0-7] 提供
Function0<R>, Function1<T0, R>, ...
对象上面的方法,内部使用 Method0<A>: Consumer<A>, Method1<A1>, ... Method7 实现

函数或方法(不包含 this)的参数个数不能大于 7,vararg 关键字可以支持变长参数,内部支持 SAM(Single Abstract Method) 自动代理实现

ExprOrBlock = (EQ Expr | Block)
+ 可以使用 val Type.Name[: Type] get(L R) ExprOrBlock [ set(L Name R) ExprOrBlock ] 扩展 getter
+ 可以使用 fun Type.Name ArgList[: Type] ExprOrBlock 扩展方法

+ 内部支持 (is) (as?) (as) 操作符
+ 对于 Nullable type 支持 (?:) (!!) 操作符
需要注意的一点是,T?T 的差别在于 T? 可能是 null
+ 标准库还扩展了
infix fun Any?.in(container: Any?) = container.contains(this)
infix fun Any?.`!in`(container: Any?) = container.contains(this)
方法
+ infix operator 定义类似这样:
(infixl | infixr) LitInt (L ... R)
infix fun 默认 precedence 和 (.) 相当
如果 infix operator 的名字两侧包含空白,代表它需要左/右侧有一定数量的空白字符
如果 infix operator 的最右侧是 #,代表它接受一个标识符作为参数,对应 fun 将被传入 org.duangsuse.reflex.data.Name 实例
duangsuse::Echo
这一段定义了和 Java 的 interop, + Reflex 是一门多范式、动态类型的 JVM 语言,它支持多态,在语法上支持类型标记。 + 控制流,Reflex 支持顺序、分支、循环、递归。 + Reflex 支持高阶函数和 Block (closure),函数参数都是按 java.lang.Object 引用传递 + 语言层面支持(针对函数参数和返回值的)惰性求值和(针对返回值的)表达式作为值 + 惰性求值使用标准库 lazy {} 函数创建,如果将惰性块保存到本地变量或者作为 Reflex…
然后是在操作和内部值的层面:

typedef Name EQ Type
const Name EQ Expr

fun Name (L ArgList R)[: Type] [LSQ LocalList RSQ] BlockOrExpr2D : Stmt
do (I ArgList I) | (ArgList.) BlockOrExprNoEQ2D : Expr

loop(L Name R) [(while | until) Expr] Block : Stmt
break(L Name R) : Expr
continue(L Name R) : Expr

WhenBr = when LB { Expr => Expr } [else => Expr] RB
| when NL l:Layout Expr (l Expr)*
WhenInfix = when Expr LB {infix Expr => Expr} [else => Expr] RB | {- 2D part -}
WhenEq = when Expr LB { Expr => Expr } [else => Expr] | {- 2D part -}
When: Expr = WhenBr, WhenInfix, WhenEQ

Var = var Name : Expr
Call = Name (L Args R) [ Block ] : Expr
Infix = Expr infix Expr : Expr {- 大意,因为分 infixl/infixr - }

其中,EQ 的判断方法是 eval(branch).equals(subject), 方便支持模式匹配

2D 表示不需要 where 语法,就可以判定使用基于缩进的块

(=) (+) (-) (*) (/) (mod)
(>) (>=) (<) (<=) (==) (!=)

我们不把负数当数,所以没有类似 Kotlin 的 unaryMinus 语法,但有一个 neg 一元操作符(还是 std.prelude 里面的)
inv 操作没有对应语法

Literal:
Bool true false
Int 0xAF 1_23 0b10 0xFFl
其中,下划线不能连续出现
Real 0.1 0.1f 1.0e10
Str "abc" "User($name)" "${1+1}" "\t\v\a\b\n\r\f" "\x00" "\u0000" "\U0000_0000" (<<heredoc ...)
注意这里 \U 中间的划线是必须写上的

Name (任何在 Java 中有效的标识符,除了包含 $ 的部分) `name` (建模的时候我把标识符也考虑进去了,虽然它表示对存储的引用,我觉得必要时它也是值……)
上面那两条消息就是 #Reflex 的基本设计了,那 numpreety.js 也不是多好写,我先写点看看 🤔
JavaScript 真是辣鸡,我去找点 ES6 to 5 的翻译器,结果我只找到 Babel 和 traceur 两个,而且 traceur 的那个还一年没更了
Babel 的那个根本不能即装即用,亏得它还弄的花里胡哨的彩色啊…… 还啥啥啥定律,我看以后不如用 Kotlin.js 写好了

ES6 都麻烦的要死,为毛现在还是 Next,明明是必品啊,TMD 我写单文件就麻烦,node 本来已经只是包装了还包装不好,看看人家 Ruby
还是巨硬的 TS 好,没被 JavaScript 的辣鸡社区带坏
虽然不如 Kotlin,还是 TS 更可心。
虽然类型推导很差,和 Kotlin 也还算是 VSCode 和 IntelliJ IDEA 比啦,设计上类型系统的确是强大,不过使用起来效果不好,我为啥要给类型签名写参数的名字???
已经足够把 babel 那一些不方便的 ES6 换掉了,虽然不如 Kotlin 好用
Google 不知道是怎么搞的,难道 Google 的前端都是吃干饭的?怎么才弄出那一点东西还不维护了,NPM 上都是几年前更新
numpreety.ts
3.6 KB
numpreety.ts
3.6 KB
等等我发 Gist…… 💭
numpreety.es6
4.5 KB
tsc numpreety.ts --out numpreety.es6 欸不错啊,体积这么小
duangsuse::Echo
numpreety.es6
我写了很多流 operator,不过还是不吼 emmm,没写出我开始想的那个算法,有点麻烦了
算法果然还是脑袋清晰的时候写纸上方便,要不然很容易糊涂的 😭
#GitHub #mobile +1, 之前看过 #Desktop 的,但不知道这个,他们好像没推广
#Ruby Dir.glob('.*').let { |fs| fs.zip(fs.map { |name| name.gsub(//){$1} }).each { |c| o,n=c; File.rename(o, n) } }
Forwarded from Justf News (Justf | 盲人)
#News 微软的小工具 PowerToys 新增了一个新功能:PowerRename。可以批量修改文件名了,支持正则表达式。
下载传送门
duangsuse::Echo
#Ruby Dir.glob('.*').let { |fs| fs.zip(fs.map { |name| name.gsub(//){$1} }).each { |c| o,n=c; File.rename(o, n) } }
def bulkRename(re_src = /.*/, re_ext, fmt_dst)
src = Dir.glob(re_src)
new_names = src.map { |name| name.gsub(re_dst, fmt_dst) }
for old, new in src.zip(new_names)
File.rename(old, new)
end
end
#bulk.rb

def bulkRename(re_src, pat_dst, fmt_dst)
re_dst = Regexp.new(pat_dst)
selected = Dir.glob(re_src)
for name in selected
newnam = name.gsub(re_dst, fmt_dst)
puts("mv #{name} #{newnam}")
File.rename(name, newnam)
end
end

case ARGV.size # Just br size is OK
when 0 then warn("Usage: #{$0} [select] re_dst fmt_dst")
when 1 then puts(Dir.glob($*[0]))
when 2 then bulkRename('*', $*[0], $*[1])
when 3 then bulkRename($*[0], $*[1], $*[2])
end

#move_back.rb
for ln in $<.each_line do
next unless ln.start_with?('mv')
_mv, src, dst = ln.split
puts("mv #{dst} #{src}")
end