duangsues.is_a? SaltedFish
60 subscribers
609 photos
6 videos
91 files
562 links
🌶🐔🐟 duangsuse 的日常
尤其喜欢发些奇奇怪怪的东西
和转载别人的东西
Download Telegram
Forwarded from dnaugsuz
🌚和我想的一样,ktx序列化就是比反射多一个prim类型免装箱
为了这一碟醋包了一整个设计模式,啧啧

但kt区分T和TElement是我没想到的,有病程度堪比 ArrayInt vs IntArray
后面iseki又重造了x86调用栈的轮子不是。。
Forwarded from dnaugsuz
https://c3-lang.org/references/docs/macros
https://c3-lang.org/references/docs/compiletime/
所以我说的是业界共识啊,就是jawa垃圾所以不知道罢了

反射Field/Method invoke()本身就可以通过 https://t.iss.one/kotlin_cn/105710 强转代码的生成实现

硬要区分静态和动态,反射生成的表达式不能在编译期粘贴进Proxy().wtf这样的地方去
javapoet那种垃圾才有存活的空间
Forwarded from dnaugsuz
https://ruanyifeng.com/blog/2010/10/why_lisp_is_superior.html 🌚莫名其妙发现这个在阅读列表里

文尾提到 Counter=n> i>{return n+=i} 这个简单的事情在OOP里是设计模式,因此“所有C程序复杂到一定程度后,都是Lisp CLOS的一种实现”
emmm 其实yield也是

作者说, 主流语言都是图灵完全的,意味着其平台完全可以随便换

只是缺少的语言特性,往往只能由程序员「充当人肉编译器」! 要么就必须调用外语的lib,或者自己掌握元编程和解释器。

更多人只想选择接受Rust这样强大的语言,和它们的作者心里的“小九九”:例如不断复读Option,Result unwrap,or or_else这些冗长却空洞的术语。
看到后不禁感叹说的太对了
Forwarded from dnaugsuz
https://t.iss.one/dsuse/19184 这个内存对象范式叫行列算数(Rowcol typis),认为类型的本质是电子表格里 column set 间的混合, fn? 标记的表格可自由扩充新的列。

只要函数要求的列的Set能被变数或常数满足,调用就合法
赋值、 if for 只是普通调用,但含编译期计算
( - plus(An:Int, k:Int)Int 则是方法)

自带对序列化器(类型单实例的接口) 的支持,例如 typeof<Column2<Int,Str>>(JSON).loads()



好吧,有了一些小修改,主要是modifiers上的自动化
但大体上是把新class解释为对 Object这种的扩展,类似于 Haskell data C2=(A,B) 但是能够被外部扩展
Forwarded from dnaugsuz
🌚 我当然也可以把完整草稿发一下阿,甚至还有形式语法,但那有什么意思呢

行列算数的本质,就是把列模板、行集合算作整数,加入计算器,以及让GADT和其匹配的函数值变得可扩展、支持默认值、与实例解耦
从而替换掉struct,union sealed 那些东西

说点有实际意义的,它能彻底颠覆Kotlin的数据结构范式。

class are: Row<I> {
fun Num2(x:N, y:N){}
fun .. //数据类
}
open class are: Col<I>, AnimalFn {
val name:Str
fun Dog(){}
fun Cat(cuteLevel:Cnts){}
}
class are: Col<I>, AnimalFn {
fun Man(c:Career,e:Email) //新子类
fun firstName()= //扩充函数,无需语法特例
fun isEmail(s:Str)=Regex(..)(s)
//自带校验类型,inline class
}
enum Career_: iz{Dev,Teacher} //BitSet

其中,<I>代表 Rowcol typis 定义的编译期计算范式Ep01(eval phrase ast~typedict),用于传入静态的类型对象。加上cell(响应式/逻辑变量),它在各类数据绑定上都是自带电池的、跨语言的。

就像Col表格可以随便“打开与扩充”,基于cell多返回值的函数,除了能 showInt(res, "123");res.v 反计算
还据此支持 "trim_".as(u.txt/"wtf"){it.trim()} 这样的链式编解码与IO

单字符参数不好,所以它配套一个记着顺口的标准类型集"sixfane",这每个字符都对应一个类型
就不一一列举了,其实都是很简单的重构。
创建语言(新语法)很容易,但找出语意上的缺陷,并用新范式修补的话…… 这种人太少了。
Forwarded from Deleted Account
在Android中实现无障碍访问(Accessibility)时,可以使用 AccessibilityNodeInfo 类来操作 UI 元素。虽然在 JavaScript 中 ev.isTrusted 用于检查事件是否是由用户直接触发的,Android 的无障碍服务没有直接对应的机制,但可以通过其他方式实现类似的功能。

下面是一个简单的 Kotlin 示例,展示如何使用无障碍服务来模拟用户与界面的交互。

### Kotlin 示例代码

import android.accessibilityservice.AccessibilityService
import android.view.accessibility.AccessibilityNodeInfo
import android.accessibilityservice.AccessibilityServiceInfo
import android.view.accessibility.AccessibilityEvent

class MyAccessibilityService : AccessibilityService() {

override fun onAccessibilityEvent(event: AccessibilityEvent?) {
// 处理无障碍事件
}

override fun onInterrupt() {
// 服务被中断时的操作
}

private fun performAction() {
// 获取当前窗口的根视图
val nodeInfo = rootInActiveWindow
nodeInfo?.let {
// 查找特定的 UI 元素,例如按钮
val button: List<AccessibilityNodeInfo> = it.findAccessibilityNodeInfosByText("Button Text")
if (button.isNotEmpty()) {
// 模拟点击
button[0].performAction(AccessibilityNodeInfo.ACTION_CLICK)
}
}
}

override fun onServiceConnected() {
// 配置无障碍服务
super.onServiceConnected()
val info = AccessibilityServiceInfo().apply {
eventTypes = AccessibilityEvent.TYPE_VIEW_CLICKED
packageNames = null // 监听所有应用
feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC
flags = AccessibilityServiceInfo.FLAG_REPORT_VIEW_IDS
}
serviceInfo = info
}
}


### 说明

- **onAccessibilityEvent**: 用于处理无障碍事件。
- **performAction**: 定义了一个模拟点击的操作。
- **onServiceConnected**: 服务连接时配置所需的无障碍服务信息。

### 注意

- 确保在设置中启用了你的无障碍服务。
- 权限和配置需要在 AndroidManifest.xml 中定义。

<service
android:name=".MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="@xml/accessibility_service_config" />
</service>


上述代码为基本示例,具体需求可能需要进一步调整和扩展。希望这对你有帮助!🚀
Forwarded from Deleted Account
在 Android 中,虽然没有直接对应于 JavaScript 的 ev.isTrusted 属性,但你可以使用一些方法来判断事件是否由用户直接触发。在无障碍服务中,通常可以根据事件的来源来判断。

以下是一个基本的 Kotlin 示例,展示了如何在无障碍服务中检查点击事件是否来源于用户:

import android.accessibilityservice.AccessibilityService
import android.view.accessibility.AccessibilityEvent

class MyAccessibilityService : AccessibilityService() {

override fun onAccessibilityEvent(event: AccessibilityEvent?) {
event?.let {
when (event.eventType) {
AccessibilityEvent.TYPE_VIEW_CLICKED -> {
// 检查事件的源
val source = event.source
if (source != null && source.isFocusable) {
// 这里可以进行更多的检查
// 例如判断是否为用户操作
logEvent("用户点击事件: ${event.text}")
} else {
logEvent("非用户操作的点击事件")
}
}
}
}
}

override fun onInterrupt() {
// 处理服务中断
}

private fun logEvent(message: String) {
// 自定义日志处理
println(message)
}
}


### 解释:
1. **AccessibilityService**: 继承此类来创建无障碍服务。
2. **onAccessibilityEvent**: 重写此方法来处理收到的事件。
3. **类型检查**: 检查事件类型以识别用户点击。
4. **焦点检查**: 利用 source.isFocusable 检查事件是否与可聚焦视图相关联,帮助判断是否为用户直接操作。

虽然无法完全模拟 isTrusted 的行为,但通过这些方法可以近似实现用户交互的识别。希望能帮助你!😊
Forwarded from Deleted Account
当然可以!这里是 Haskell 和 Python 的最短实现最长公共子序列(LCS)算法。

### Haskell 实现

lcs :: Eq a => [a] -> [a] -> [a]
lcs xs [] = []
lcs [] ys = []
lcs (x:xs) (y:ys)
| x == y = x : lcs xs ys
| otherwise = max (lcs xs (y:ys)) (lcs (x:xs) ys)

-- 示例
main :: IO ()
main = print $ lcs "AGGTAB" "GXTXAYB"


### Python 实现

def lcs(x, y):
if not x or not y:
return ""
if x[0] == y[0]:
return x[0] + lcs(x[1:], y[1:])
return max(lcs(x[1:], y), lcs(x, y[1:]), key=len)

# 示例
print(lcs("AGGTAB", "GXTXAYB"))


这两段代码都实现了基础的递归 LCS 算法,当然对于长字符串来说,效率较低,可以进一步优化。希望对你有帮助!😊
Forwarded from Deleted Account
要在 Android 项目的 build.gradle.kts 文件中配置 .kts 源码的编译和引用,可以按照以下步骤操作:

1. **确保项目结构**:将你的 .kts 文件放在项目的 src/main/kotlin 目录下(或你希望的位置),例如 src/main/kotlin/com/example/myfile.kts

2. **修改 build.gradle.kts 文件**:在你的 build.gradle.kts 文件中,添加如下配置:

   import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

plugins {
id("com.android.application")
kotlin("android")
}

android {
compileSdk = 33 // 或你希望的 SDK 版本

defaultConfig {
applicationId = "com.example.app"
minSdk = 21
targetSdk = 33
versionCode = 1
versionName = "1.0"
}

buildFeatures {
compose = true // 如果使用 Compose,设置为 true
}

compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}

kotlinOptions {
jvmTarget = "1.8"
}
}

dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.8.10") // Kotlin 依赖
// 添加其他依赖
}

tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs += "-Xscript" // 添加编译选项以支持 .kts 文件
}
}


3. **在 Main 中引用**:在主活动或任何 Kotlin 文件中,你可以这样引用 .kts 文件:

   // 示例: 引用 myfile.kts
val result = eval("src/main/kotlin/com/example/myfile.kts")


确保在运行时可以找到并执行该 .kts 脚本。如果有任何问题,可以查看运行日志,以确保一切配置无误 😊

按照这些步骤,你就能够在 Android 项目中成功使用 .kts 文件了!如果你有任何具体问题或错误,请随时告诉我!🚀
Forwarded from Deleted Account
要在 Kotlin 中编译 .kts 文件并将其生成为 fun,你可以使用 Kotlin Scripting API。以下是一个基本示例,展示如何实现这个过程:

### 步骤 1: 创建一个 .kts 文件

首先,创建一个 .kts 文件,例如 script.kts,内容如下:

fun greet(name: String): String {
return "Hello, $name!"
}


### 步骤 2: 使用 Kotlin Scripting API

接下来,在你的 Kotlin 应用中,使用 Kotlin Scripting API 来加载和执行这个脚本。示例代码如下:

import kotlin.script.experimental.api.*
import kotlin.script.experimental.host.*
import kotlin.script.experimental.jvm.*
import kotlin.script.experimental.kotlin.*

fun main() {
val scriptFile = File("script.kts")

val compilationConfiguration = ScriptCompilationConfiguration {
jvm {
dependencies("path/to/kotlin-stdlib.jar") // 添加必需的依赖
}
}

val evaluationConfiguration = ScriptEvaluationConfiguration {
// 可以在此处配置和添加额外的环境
}

val script = KotlinScriptEngine().eval(scriptFile, compilationConfiguration, evaluationConfiguration)

// 调用脚本中的方法
val greetFunc = script.scriptInstance::class.members.find { it.name == "greet" }
val greeting = greetFunc?.call(script.scriptInstance, "World") // 调用 greet 函数
println(greeting) // 输出: Hello, World!
}


### 步骤 3: 运行代码

确保你的环境中配置好 Kotlin 和所需的库。运行这段代码,它将读取 script.kts 文件并调用 greet 函数。

### 小结

通过这种方式,你可以在 Kotlin 中动态加载和调用 .kts 文件中的函数!🎉 如果有任何问题或者需要进一步的帮助,请告诉我!😊
#bash
alias DEB='cu sudo dpkg -i --force-all'
cu(){ eval $(node -p 'gc={"?d1":"--depth=1","?dn":"--recurse-submodules","":""}; process.argv.slice(1).map(s=>{try{u=new URL(s),s=/^git/.test(u.host)?
`git clone ${gc[u.search]} git@${u.host}:${u.pathname.slice(1)}.git&&ls -td */`:
`wgetHL ${u}`;s=`$(${s}|head -n1)`}catch{}return s}).join(" ")' $*);}

cnf-x() {
[[ ! "$@" =~ ' /' && "$@" =~ / ]]&&cd "$(mkdir -p $@;echo $1)" ||([[ $1 =~ ^[0-9,]+$ ]] &&cut -d' ' -f $1|sed -nE "$2p" ) ||
([[ $1 =~ ^\. ]] &&jc ${@:2}|tee e.json|jq -rcM "$1"|sed '1s/^/(/; $s/$/)/'|node -p) ||(ev=CNF$1;[ -n "${!ev}" ] &&${!ev} "${@:2}") ||
([ -z $(command -v $1) ] &&command-not-found $1) ||(
for opt in "--help" "-h"; do $@ $opt 2>&1|cnfx-HL &&break; done
sleepHL 2 &&for doc in "tldr" "man" "man -k"; do $doc $1 &&break; done
)
}
alias ?=cnf-x grepp='grep --color=always -P'
CNFimport='pip install -U'; CNFjs='sudo npm -g i'; CNFdoc='docker pull'
CNF_fmt='[[/(?<=\s-[\w-.]+)(( | ?[=<\x27[])[^\s:,,]+)/g, 33],[/,? ?(\s-[\w-.]+)/g, 32],[/([A-Z][A-Z0-9_]{2,})/g,34]]'
command-not-found() { sudo pacman -S --noconfirm --needed $@ ||pacman -Ql $@|grepp '/etc|lib/'; pkgcSel $1; return 0;}
cnfx-HL(){ node -p "$CNF_fmt.reduce((str, [A, B]) => str.replace(A,\`\x1b[1;\${B}m\$1\x1b[0m\`), process.argv[1])" -- "$(cat)"; }

sleepHL(){ python -c "$HL_0
dt=$1*10;t0=time.time()
try: goPB(dt,delay(iter('?'*dt),.1))
except: print(f'{time.time()-t0}s :) cancel'); sys.exit(1)";}
wgetHL(){ python -c "$HL_0
for sh in hear(f'LANG=C {sys.argv[1]} 2>&1', vp:=[*map(re.compile,sys.argv[2:])]):
time.sleep(1); f=iter( F.partial(open(vp[1],"rb").read,1), b"")
print(vp[1]); sys.stdout=sys.stderr; goPB(int(vp[0]),f)
sh.wait()
" "wget -dc $1" 'Length: (\d+)' "Converted file name.*-> '(.*)'";}
cliHL(){ ls;}

HL_0='import pip._internal.cli.progress_bars as PB, time,sys, re,subprocess as P, functools as F
goPB=lambda n,su: [*PB._rich_progress_bar(su, bar_type="on",size=n)]
def hear(sh,vp):
nvp=len(vp)
for s in (po:=P.Popen(sh, stdout=-1,text=True,shell=True)).stdout:
for k,v in enumerate(vp):
if nvp==0:yield po
if not isinstance(v,str)and (m:=v.match(s)): vp[k]=m.group(1); nvp-=1
def delay(xs,dt):
for x in xs:yield x;time.sleep(dt)
'
xfor() { for x in `sed 's/\n/ /g'`; do $@ "$x"; done ;}
zenity-sel(){ s=`cat`; test -n "$s"&&zenity<<<$s --title "$1" --list $(eval echo --column={$2}) $3;}

pkgcSel(){ k=$(pkgconf --list-all | grep -P $(sed 's/lib/(lib)?/' <<<$1) |sed 's/ \s*/\n/'|zenity-sel "Debug package $1" cffi,usage)||return
for fp in $k $1/$1 $1 $k/lib$1/$1; do cpp -undef $(pkgconf $k --cflags-only-I) <<<"#include <${fp}.h>"|grep -v '^#' >sel.h &&break; done
(sleep 5&&sed -E 's/__attribute__[^;]*//g;s/__(inline|restrict)//g;s/typedef .*va_list.*//g;s/\w*va_list/.../g' -i sel.h)&
echo "import cffi; ffi=cffi.FFI();ffi.cdef(open('sel.h').read()); C=ffi.dlopen('$(pkgconf $k --libs)'[2:])"
#fuck u cffi, what <cdata>? Is strconv&cdef(errItem=ignore) that hard?
}
# 'isatty[]=0;; readdir[_,"/"]=0'; export GTK_DEBUG=interactive LD_DEBUG=all
frida-cffi(){ ls;}
ytdl-spi() { python -c 'import yt_dlp,sys
u=yt_dlp.YoutubeDL({"cookies-from-browser":True}); del u._ies["Generic"]

for x in sys.stdin:
try:print(u.extract_info(download=False, url=x))
except: print()
'
}
#f5 %.pyc; f5 /usb /clip


BAT() {
i=0;eval `cat /sys/class/power_supply/BAT$i/!(*/) 2>/dev/null|grep POW`
st=$([[ "$POWER_SUPPLY_STATUS" == C* ]] &&echo ⚡️)
tput setaf 6 bold;
echo "$(quote $POWER_SUPPLY_MODEL_NAME) $POWER_SUPPLY_TYPE by $POWER_SUPPLY_MANUFACTURER#$POWER_SUPPLY_SERIAL_NUMBER $st"
echo "IU=${POWER_SUPPLY_POWER_NOW} mW"
echo "C0=.${POWER_SUPPLY_CAPACITY}C=${POWER_SUPPLY_ENERGY_NOW} mWh"
tput setaf 1;echo "C=$(echo "scale=2;(${POWER_SUPPLY_ENERGY_FULL}/${POWER_SUPPLY_ENERGY_FULL_DESIGN})" | bc)design=${POWER_SUPPLY_ENERGY_FULL} mWh"
echo "U=${POWER_SUPPLY_VOLTAGE_NOW} mV > ${POWER_SUPPLY_VOLTAGE_MIN_DESIGN} mV"
tput sgr0;
echo Lm=$(echo `cat /sys/class/backlight/*/{,max_}brightness` 10/ /p|dc)0% 💡
echo "nCyc=${POWER_SUPPLY_CYCLE_COUNT}🔋"
echo "CpW=$(echo "scale=3;(${POWER_SUPPLY_ENERGY_NOW}/${POWER_SUPPLY_POWER_NOW})" | bc)h"
}
unit() { node -p 'process.argv[1].replace(/(\d+) m(Wh?|Ah?|V)/g, (m,n,k)=>n/1e6+" "+k)' "`cat`" ;}


bili-m4s() {
[ -f ls ]||for f in */c_*/entry.json; do jq -r '$U+.bvid+".png",.title,.owner_name,.bvid,(.downloaded_bytes/1024e2),.cover' --arg U $PWD/ <$f
ffmpeg -loglevel quiet -n -i $(dirname $f)/*/video.m4s -ss ${1:-1} -vframes 1 $(jq -r '.bvid+".png"'<$f); done >ls
zenity-sel 您要提取的缓存 thumb,标题,up,BV,MB,cover --multiple <ls #--imagelist
}
Forwarded from dnaugsuz
De Bruijn 索引。 https://magic.huohuo.moe/html/DBI.html

PLT人起名字也真是乱起,那么多抽象玩意(譬如Sum/Prod来表示 union{int tag; struct{}} 的,你是 Prolog 能DFS出所有BoolPair也就罢了, 没那个功能还硬套嘛。。)
DBI居然还是参考卡牌游戏的魔术

UUID,在ES6里叫 Symbol(),等价 new Obj。不过bash那种 $1 是不会冲突的,看了下,你大概把符号的"文本形式" 视为值了

(z.x. (z.x)) z 里(z.x), x本就是(_=> _.upval[1]) 的语意,而型参z.并不是"z"。
哪怕没有用嵌套KV做把ID解析到ValRef,至少也该知道替换不是对argName这些反射数据进行的。
可以说此问题的前提就是没有尊重AST scoping,[Str 的括号树]并不是lambda的本质, lisp本就缺少用于复用节点构成计算图的let (他们说用函数..),搞成递归数组就更空洞了

入.的自由变量,其实就是this变量, A.B. A+B 即 \2 $1+$0
DBI在apply(f,x)时 f变浅,x变深, (A. [A B.A]) 0 即 \ [$0 \ $1] 到 \ [0 \ $2]

确实不好讲,因为$2明明可以在代换时就替换为0,为啥既要重命名,又不绑定到闭包数据结构呢?

最后,解释器要100行…… 而且就是单replace()功能
好吧这就是java
duangsuse, [2024/8/13 23:33]
https://magic.huohuo.moe/html/EvalStrategy.html 这篇说 call-by-lazyName 也忽略了一个重点

()=> 的本质是对象,它完全能有非局部引用。 你为了实现 if(, print..) 这些越DSL的俎代庖的“优越性”,不遵循x86 ABI 这些规范传值,结果只能是更慢,而非少求值了几次。

设计一种东西总得谈概率吧? a||b||c 确实能节省,但autoclosure这种,有必要给人讲明白,而不是为了解决而解决

duangsuse, [2024/8/13 23:45]
https://magic.huohuo.moe/html/Algeff.html

也没必要写成 catch{e.resume} 这么奇怪的形式。Eff 就是静态的把catch{} 依赖注入给throw()而已
那么,如果不需要cont,直接throw again 就行

只是把java的组件级依赖注入改成语句级,然后yield给一个根本不需要new函续体的handler。

Exception 之所以不叫Error,就是因为它是一种可以默认传入的函数值参数,就像 open fun
非局部返回只是一种愉快的副作用,至于Retry和替代Promise什么的, Algebiac Effect 显得高射炮打蚊子。 异常+协程 仍然是最优解

>发生记录日志的作用,可以预先写一个输出到标准流的的执行器(Handler)一个输出到文件的执行器然后在调用函数的时候按需组合。这也就是它是代数的(Algebiac)的原因

这理由也够扯的。 「代数」?线性代数够普世吧? 它和编程界的组合compose可一点儿关系也没有,丑陋的矩阵处理
挪用Java界的依赖注入文化就算了。 Effect 根本不能区分longjmp() 和真正要切换有栈协程的优化情况
哪怕是C++和Linux 引入的协程/进程上文切换/fork,往往也比(多发)函续体、CPS 这些所谓理论强多了。一个自动传回调讲成啥了。

duangsuse, [2024/8/14 00:18]
https://magic.huohuo.moe/html/Parsec.html
嗯,又是一个被复杂化的简单问题。 就像某些CS课,“能够写编译器的编译器呢!”

不过是重造了x86调用栈和forif的轮子,和那些把链表当列表处理的人一样。并不重视语意,只是用他们的“特色”捆绑一些最基础的工具。
parser只是编译器的第0步,而且是完全能省略的;然而有人觉得那才是最重要的。

在谈parser是什么前,你的第一页要说明输入输出是什么格式,比如本文用正则来对照就很好
“简单是可靠代码的先决条件,而非可靠的牺牲品——Dijkstra, 发明递归的人”
“优雅的程序与它对应的数据,在读写前直观绑定——Daniel Friedman, 箭头函数的先驱”
“业界有两个设计软件的方法,一种简单大方,明确没有堆砌缺陷,一种繁琐抽象,连缺陷都难以写明确——Hoare, 快速排序之父”

https://t.iss.one/dsuse/18717
Forwarded from dnaugsuz
> 计算机发展的历史就是人类尝试控制复杂度的历史,运行时有时间复杂度空间复杂度,编写时有代码复杂度和逻辑复杂度。封装抽象出的黑盒系统可以把复杂度分离到不同部分,而每一个部分的复杂度都能控制住人脑能接受的范围。模块化使我们能在不同项目间共享复杂度。而良好的编程习惯可以让代码变得有序,减少代码层面的复杂度。运行时的调度、垃圾收集利用算力分担手工管理的复杂度。
https://iota.huohuo.moe/OO-in-C.html#:~:text=Java%20不支持像

噗,原来你们(例如龙书封面)也知道复杂度是个坏事啊

可你们起的术语、写的文章,在我看来根本是在违背自己的哲学啊。
import this 用凯撒密码加密了源码,但Pythonic是真实的。包括中文PLT却很少强调「编程的理论是为了消灭复杂度」这点

其实 magic.huohuo.moe 的许多文章,例如 F-Bounded Polymorphism(Self type) 都可以有一句话提纲,让用户有个前置印象再去看
再比如 HKT<List,Int>, Java泛型本质上是繁多类型(List literal as type)而不是常量函数, 不过 Higher Kinds 最终的价值也是把'*'填完生成一个Matcher去检查字面变量, 那就是用HKT1<P,T>强转了

不过介于我看的这几篇都不得要领,在某种理论上甚至不如Lua这些工业糖精聪明,我也没时间去读剩下的了
比方说吧,JS Bool, Error, List, 这些明明都能用 [12,3].As(x=>).or("empty"); fetch.As(e=>"fail", x=>x.body) 的"箭头"去处理

这就是FP的category,而且不需要引入任何新概念("compose?") 或"不准确的类比"。它们都有零元(x=>x, false, []..)和join(e.g. x=>[x]) ,而且当然能 A=> B=>curry(A+B)
结果是语言的forif,filter map可以被逻辑查询替代,而且是符合4定律的: 哪怕 Functor[A] 变成 A,Any也不能变回Any 。js自带结合与组合律

而FP呢? 除了空壳还是空壳。 如果说Functor只是和C指针一样拙劣而且用途更小(无所不包,但缺斤少两,因此才被淘汰) 的抽象,你们也不肯改编吧

我不知道CS有什么理由向癖好「未定义先使用」的数学书们学习。他们根本不知道明确与严谨该怎么写,他们甚至没有与几百个人合作写过1本书("交流" 可不是件简单的事!),可以拍脑门地使用各种希腊符号(现代物理已经减少了rho这种歪七扭八的东西)。
Forwarded from dnaugsuz
https://magic.huohuo.moe/html/ADT.html
想起行列算数(RowCol TypIs)了
类型是一张表格。横列是A,B..或具名的值,纵行是它的构造样板,也就是校验函数
用??语法打开或新建表格,添加函数列或构造样板。只要参数覆盖了类型签名对应的列,就能调用操作

?? Col
Student -name-id(Str Int)
#共有str*int种可能性,也叫乘积类型
Vec2(N N)
Date(Int Int)

- say -An(Student) "{name}({id})"

?? SchoolPerson
-name Str
Student -id(Int)
Teacher -office(Str)
#共有(学生+老师)种可能性,也叫求和类型

?? Bool
YY; NN
?? Nat
O
十1 -An(Nat) #peano,链表长度数
two O.十1.十1

?? [T Link]
Cons -x-?xs(T Link)

?? Json fn # 以允许继承,即便已有构造器
Lit -?val(Bool) #YY,NN,NO

?? Json
Lits -a([Json Ln])
KLit -k([Str Json KV])

GADT(泛型adt)好歹把 Tagless和Final讲一下啊
btw. Tagless是指用virtual虚表取代 type tag 做union的意思
最开始年轻的牛和猴,俩一起反天,基本没有对手,但是牛有老婆,有牵挂,天庭想阴招坑了铁扇让她怀孕骗老牛半路跑路,结果剩下一个猴被如来搞了,牛发现娃不是自己的种,认为铁扇骗自己,坑了自己兄弟,跟铁扇闹翻了,铁扇解释自己也是被逼的,也接受不了就跟牛分居了,牛也一怒之下跑去找玉面狐狸不跟铁扇玩了。
猴子被搞过了几百年开始西游认为反天可能不是好办法,觉得可能进编制才是正道,火焰山又碰上牛,用尽手段逼牛进编制,牛本来也认命了,猪跳出来说你老婆我杀了还扒光看干净了,牛又怒了,结果一个没干赢一群又跪了,进编制干活去了。
最后猴进了编制发现不是自己想的那回事,该被人搞还得被人搞,又开始闹了,这时候牛也是成熟的编制人员了,就跟着二郎神把猴子搞了分尸了。
然后红孩儿发现了自己不是牛的种,自己差不多被人灭门了,找牛要猴的尸体牛不给,反手把牛给搞了,牛不愿意真弄死红孩儿也不敢真给他尸体就干脆不反抗让红孩儿囚禁,然后天明人来搞事了。
牛一辈子全选错是说
猴和牛反天的时候顾及老婆怀孕选择半路跑路,他不跑难说成了,选错了第一次。
猴逼着牛归顺的时候为了老婆被杀选择反抗,他忍了就没后面的事了,选错第二次。
牛跟着天庭搞死猴的时候为了讲兄弟义气不肯下死手,真玩命把猴弄个形神俱灭,给天庭当狗也就没后面啥事了。选错第三次。
结果就是家破人亡,妻离子散​

看看你吃的加生命的延寿仙丹是用什么材料做的,玲珑内丹,有修为的妖怪才能结出的内丹,天庭众神想长生不老除了九千年的蟠桃会,就只有延寿仙丹,仙丹是妖怪内丹做的,你仔细想想​
大圣戴上金箍,箍住的不但是大圣的自由身,更是大圣逍遥自在,不服强权,敢一棍子打上凌霄宝殿的侠肝义胆;唐三藏几逐悟空,逐的是悟空嫉恶如仇,要将魑魅魍魉全都打的魂飞魄散的血性,从花果山回来的是悟空,但是是没有心的悟空;灵山一释,摘下的是孙猴子的金箍,换回去的却不是孙猴子的自由身,早在船上褪去凡胎之时,那金箍就随着沉没的肉体,一起沉入了孙猴子的心,九九八十一难,难的是唐三藏?难的是不会斗战的猴子,没有佛心的圣佛,这本书成书的年代,正是佛道鼎盛之时,可见南朝四百八十寺的盛景,无论皇帝尊道灭佛,还是尊佛灭道,为了皇权而服务的佛道都已经变了味道,它们不是祈福的咒语,不是慈悲的心怀,而是天王老子禁锢万民的无形金箍,所以做书之时,其心中必是怀着对神佛害国的厌恶,怀着对被箍着的百姓的怜悯所做的。​

那些神仙需要的永远只是弼马温,弼马温永远只能管理马匹,想要升迁绝无可能。神位就是金箍。猴子说他能摘了金箍,二郎神杨戬也想摘了自己的金箍所以他暗中帮了猴子一把

其实可以简单看作,各种超能力者打架,而这些超能力者大多数都是蔑视人命的,不管是佛教的自生自灭,还是道教的清净无为,本质上就是超能力者(神仙佛魔妖)对普通人类(人界)的剥削,
佛道里面也不是铁板一块,像是弥勒和须菩提,就像个中立单位。但其实神仙佛和普通人是一样的,也有七情六欲,只是自诩为神仙佛高人一等,所以仗势欺人,不管是天庭还是灵山。​

要搞这套阴谋论是吧,那好你们tm神仙妖怪都是一帮什么货色?你孙悟空又是什么货色?反抗?斗争?革命?革个几把毛!你悟空天生就是灵猴妖王,地方豪强,目的就只有一个摆脱朝廷掌控,想自由发展。跟人类有什么关系,人类纯给这帮神仙妖怪艹的,真要反抗就该人类荡平了这些什么神仙妖魔,包括你孙悟空,什么玩意儿?争来争取谁坐皇位有什么区别,更何况猴子就是像打破现有秩序,自己仗着自己的资本去逍遥自在。独留给世间一片混沌,要革命第一个杀悟空。你还想着自己是孙悟空呢?还是先挑挑自己用那种方式被烹调吧。​
Forwarded from Rachel 碎碎念 (Rachel 🐨)
最近才发现 ffmpeg 提供了 Android 设备的 MediaCodec 支持,可以调用底层硬件加速编解码,兴冲冲地用手上的小米 13 压缩 Big Buck Bunny,结果发现高通提供的 h264 编码单元质量就是一坨…

如果各位想试试看的话,可以在 Termux 里安装 ffmpeg,使用 ffmpeg -codecs | grep mediacodec 看 ffmpeg 支持的编解码器,然后将视频的 codec 换成对应 mediacodec 的版本即可,例如一个 libx264 的视频可能是这样:

ffmpeg -i input.mp4 -c:v libx264 -vf "format=yuv420p" output.mp4

使用 h264_mediacodec 编码的话,就写成这样:

ffmpeg -i input.mp4 -c:v h264_mediacodec -vf "format=yuv420p" output.mp4

它应该会自动调用最合适的硬件编码器,如果需要手动指定,也可以下载一个 Codec info ,或使用 Device Info HW 这类工具查看设备的编解码器信息,例如我希望指定图 2 中高通提供的 avc 编码器 c2.qti.avc.encoder ,那么:

ffmpeg -i input.mp4 -c:v h264_mediacodec -codec_name c2.qti.avc.encoder -vf "format=yuv420p" output.mp4

上述工具还可以查看编码器具体支持的参数等,例如高通这个就支持恒定/可变比特率,但不支持 CQ/CRF;当然,不同厂商甚至同厂商不同芯片的硬件编解码器,都可能有巨大的差异,欢迎各位尝试后分享在评论区!

视频来源: https://bbb3d.renderfarming.net/download.html ,感谢群友提供
Codec wiki 中关于 MediaCodec 的文档: https://wiki.x266.mov/docs/encoders_hw/mediacodec
Android 官方的 MediaCodec 文档: https://developer.android.com/reference/android/media/MediaCodec