duangsues.is_a? SaltedFish
60 subscribers
609 photos
6 videos
91 files
562 links
🌶🐔🐟 duangsuse 的日常
尤其喜欢发些奇奇怪怪的东西
和转载别人的东西
Download Telegram
#js #code
ee.Videos=({Blank, it},my)=>(

my.Video=({url,title,desc, it})=>div(
Thumbnail(it),
a(url, h3(title), p(desc)),
BtnLike(it)
),

section(h2(it(a=> n(a)==0?Blank : n(a)>1?'Videos':'Video' )),
let(it, my.Video)
))

//
ee.SearchVideos=({it, vText})=>html(
input(wKV({type:"search", v:vText})),
Videos(
vText(k=>videos.filter(x=>x.title.has(k)))
.lets({Blank:`No ${k}`})
)
)

ee.Conference=({slug},my)=>(
my.Talks=({id})=>
let(
{load:()=>db.Talks.finds({confId:id})},
({video:v})=> SearchVideos(v))

$cnfs( //div(wSty``,
let({load:()=> db.Confs.find({slug}}, my.Talks, div('Not any')))
))
https://react.dev/blog/2023/03/16/introducing-react-dev 也写了

ee.Counter=({n=0})=>button(
wOp({tap(){ n.v++ }}),
Eq.fmt`pressed ${n}time$` //这样支持SSR或爬取
)

ee.Inp=({v="", isOk=$Y})=>html(
input(wKV({v}) )
p(Eq.fmt`You typed: ${v}`),
btn(Reset=>{v.v=""}),

sel(isOk),
p(Eq.fmt`You ${isOk(q=>q? 'liked':'did not like')} this.`)
)

is.i18n=`
isOk I liked this
incAge Get Elder
`

ee.Aged=({name='Taylor',age=18, vHelo})=>(
Eq.at(vHelo,{name,age}, _=>Eq.fmt`Hello, ${name}. You are ${age}.`),

html(
sel(name),
btn(incAge=>{age.v+=1}),
p(vHelo)
))

ee.body(
({u={},})=>ee.Aged(u),
div(p(`Hello, boy. You are 23.`))
)=={u: boy 23} 

ee.bodys(()=> detail(wKV({open:$N})) )
$("detail").attr("open",$N)

//https://www.solidjs.com/examples/context
ee.Themed=({ask:{color,title}})=>(
h1(wSty({color})), title,
sel(color)
)
is.i18n=`
color Change color theme
`

//Angular
ee.productList=({it})=>
html(
h2(`Products`),
lets(it, ({name,desc})=>
h3(
a([html`${name} details`,``], name)
),
p(wKV({if: desc}), html`Desc: ${desc}`),
btn(Share=>{})
)
)
duangsuse:
as? invoke provideDelegate 这些吧?
plusAssign 这些也挺魔怔的,和py一样

那种Compose DSL也算吧,虽然web前端里挺流行的

总之找不到比这段讨论 更多的,我是觉得语法的技巧,都比不上数据和操作模型的。 你应该拿语法去设计框架,而不是语法糖

measureTime {} 挺好的,虽然没 py Jupyter 和 %timeit 完善
obj::field, companion/string invoke 也罕见虽然没用

1 shouldBe 2 简直是毒瘤,直接用重载写成 assert { 1==2 } 不香吗(kt1.4 又支持了 context(T1,T2) 多this捕获,但用处鸡肋

对,这个极好
还有 groupBy.eachCount 什么的,比较自然

Science Yuan:
发明操作符简直是毒瘤 全都搞成函数不香吗

duangsuse:
反正都会被AI取代的,无所谓了

我知道py里 x==None 是错的,但坚持不用 x is None ,就是因为没道理做出两个意义相同,或者电脑外不存在的概念

py是好在开箱即用、浅嵌套、不折腾

for 循环在 numpy 里就是喳

isinstance(x,T) 都落后了,应该用 match x: case T:

isekiのChannel:
1 == 2,嵌套了lambda咋办

duangsuse:
所以说职责本来就要单一啊

不单一你连现代 DSL 都没法用

很难想象在 @Test fun 里使用== 来判断测试环境的配置,应该用独立函数,区分特定配置下的测试,而不是写if。

isekiのChannel:
那你看SQL,完全为了贴合人类语言

duangsuse:
那都是骗人的, SQsu 都比它更“人类”

select id from 狗 where (月龄>6 and 高>40);
aka 取狗(月龄>6 and 高>40)

正宗的关系式写法是:

狗(id,高,月龄), 月龄>6, 高>40

一个被专门做出AI生成的语言,那肯定是垃圾

是啊,所以我觉得 private 就直接改成 fun xx(): @our Int = 0 好了,也统一了很多

public protected internal private
直接改成
ourapi ourtype ourpkg our, 都是our
(因为写明public的人是闲的, 就要把语法做得很丑,让他们不敢用)

那大家都用sql好了,要ORM和GPT干什么? 既然你只能用别人给的接口,开发框架有啥意义

isekiのChannel:
那什么,我看了一遍你这文章,没看懂你这语法怎么用

duangsuse:
欸,我有说必须是中文吗, 如果给 Prolog 的语法添加个返回值和隐式this ,可能就没ORM什么事了;因为直接写逻辑式会比 filter{} map{} 还容易

还不是这些语言设计时太狭隘导致被取代的问题,然后取代者又带来一堆问题。

「有新取 create insert select 」是唯一的三条实用指令

有表、有库 都是按这三个字分组的

甚至 新建、新删(into..values drop) 都是这样,根本不需要学语法

区别就是你不用问AI 查询怎么写,而是即便你让AI来写,都不会比SQsu更简单;或者说这个语言真的能给学习带来辅助,而不是空耗精力去思考简单的解谜

当然我觉得它也不够好, 我想设计的是SQL的翻译器 而不是“预处理器”

没有问题也不会被NoSQL淘汰了,可惜了它本来最符合Excel和生活现实

面向列的数据库、Geo GIS 和向量数据库,不也是这样, 所以说这些取代者也没有好好想过「这整个领域」的基础表达式,应该怎么设计

只是顾忌那一亩三分地,和他们“改革”了什么旧写法

Science Yuan:
NoSQL那些民科级查询DSL

还是先想想怎么别被SQL淘汰吧
duangsuse:
所以之前我被冰封骂“胡乱加功能导致可维护性崩坏” 的时候,我就觉得我很冤啊。 我是最重视优雅性的,甚至为此了搁置了实践

SQL 和ORM(Repo, Mapper 那些的)现在就是绝对的基本功, 根本没有淘汰一说, 但未来会有更多利用新数据库的需求,甚至pg 最近也支持了向量类型。SQL凭什么淘汰别人的新功能呢?

其实这个主要是修正了语序、 where 子句冗长的问题,然后是本土化了「序大 序小(升降序) 页每」

有用表T 是用来给 取; 做简写的,现在我觉得应该直接把上次查询的表设为 T ,就像 IPython 的_变量;主打一个避免Tab补齐

isekiのChannel:
where 子句的冗长,你是指 且 或 这样的连接词吗

duangsuse:
呃.. 当时没有,但现在觉得是

当时连 left join 都不知道是啥(当然现在也不知道)。。
不过发现 SQL 能查询出 Madelbrot 集(把xy值插进去 select +递归) 也是很震惊

SQL 既然是关系式语言,就要遵守 Pair(a,b), a=1, b=2 | b=3 这样的逻辑写法;虽然看起来没有隐式 this ,查询会有冗余变量

当时就觉得是 filterMap 那一套呗

根本不科学,因为程序员是没日没夜在说这些 select ,正常人怎么会?

如果一切都能用 UI 解决,那现在许多后端直接变成带验证公式的 Excel 好了;但是还是有人 既要可读 又要可用

Science Yuan:
所以你到底哪里超越了SQL

ORM的好处显然就是它是嵌入宿主语言的

duangsuse:
行了吧,我没想过超越谁,你就当那是玩具好了。 俺不是程序员照样活得开心

大学时第一次应聘一个连锁药店,就看到 1000+行的存储过程SQL

感觉也是.. 隔行如隔山?

我觉得 OpenResty 也是栽在Lua没有IDE上

ties 是指 sorted list[N] 里,第N项后相同的项 ,这有什么用,是数 NULL 的?

应该是 group by 的单分组形式?
ties 第N项后相同的项.. 没见过这种处理

所以我不太会SQL ,因为一堆无法情景实例化的语法

Haskell 里的 takeWhile (==) ,或者说 [1,1,2,3].firsts(1) 可以做到 ties ,不过有点难;所以说 SQL tie 比 Kotlin 那30+列表处理 fun 还先进(

其实在我眼中,有这么多 List/Iter 函数,说明标准库对多态和type 的归类和利用是失败的。就只差步 Ruby 的后尘了,rb 的 str.replace 是单参的。

Ruby 的时代开发出了 GitHub 欸,现在许多 DSL, Compose 也并不是从 Py 学来的,Ruby 是把内嵌DSL发扬光大了,比如它的 def 里可以嵌套 class..

一个语言失败,并不是坏事。反正工程师又不挑…… 而且垃圾语言,说不定高逼格大牛多、薪水会高

Go 的有些地方真的挺好,比如内建的 template 和 go func, 以及最好的 encoding/xml,json,protobuf,. 封装

在 UNIX 编程上,算是成功的吧

现在 protobuf 可以转为 json, 也能输出 Schema ,写起来有补齐

还是 Kotlin 协程好, 直接把调度器和 Continuation(return的函数化)放一块了,能在指定线程回调,能yieldAll,能支持结构化并发,同生同灭;JS就没有

可惜就是对框架开发者不好理解, 而且有点难记 launch, with啥的

八重 狐子:
压根没用过kt的async

直接整个函数变suspend

duangsuse:
=async {}不是可以用推导吗

Scope 上不会不兼容吗? 虽然 async 里应该能调 suspend

协程就是把 return的函数化 传给被调方,从而在堆里维持调用栈,也就是受try,while等流控支持的回调

js 里用 await Promise((ok)=> 就能拿到这个函续值了
但是 kt 里函续会在特定的 Dispatcher 上文被调用

那样是建立新线程等待?

对了,那async{} 都不会卡在主调度器上? jvm好像没有单纯要回调,但不会卡线程的http,timer 啥的

nio.Unsafe 里的键盘 Signal 是不需要,也不会打断mainloop

八重 狐子:
因为我把那个function 直接suspend了

kt的async还真没怎么用过

duangsuse:
#bing
async{} 会返回一个 Deferred<T> 对象,表示协程的结果,可以通过调用 await() 方法
async{} 可以用来实现并发,即在同一个协程作用域中同时运行多个协程,并且等待它们的结果。
launch{} 则只是用来实现异步,即在后台运行协程,不需要等待它的结果1。

协程需要返回结果或并发,那么 async 可能更合适。 所以 async 只是用来延迟执行分组协程的?

延迟且有结果的 launch? 那和 ES6 async()=> 不一样啊, es6 没有说async是否并发吧..

好吧,是我理解有误 😅

isekiのChannel:
我这边写出的操蛋代码都长这样了: input.map{ async{ handle(it) } }.awaitAll()

duangsuse:
Promise.all(a.map()) 是正常操作
py asyncio.gather(x for a) 也一样

DOM 简直是UI UX 的天堂,我都不知道 Java 里还要手动定义阻塞线程(Disptacher)的 async 操作里

无所谓,反正标准库不会带,AI也不会写..
在 JavaScript 中,你可以使用 GPUBuffer.mapAsync() 方法来映射 GPUBuffer 的一部分,并且返回一个 Promise1。
在 Akka Streams 中,你可以使用 Source.mapAsync 或 Flow.mapAsync 来并发地运行多个 Future,并且保持元素的顺序2。
在 Python 中,你可以使用 multiprocessing.Pool.map_async 来非阻塞地运行多个进程,并且返回一个 AsyncResult3。

我误会 Python 了,虽然 asyncio 臭名远扬,
gather,wait,as_completed 在理论上比 Promise.all,race,any 准确

但是这种准确.. 真的不如js,至少有两个是保底记得住的
py可能还是败在箭头函数不好写,以及没有 libuv.org 那么异步的系统IO可攀,虽然 yield 是和js一样方便的,没有DOM那种免线程框架还是做不起来

Koshin:
平常写Android 业务的来说,基本这种就够了,我只在处理比较长的初始化流程用的上async

Yumeko:
在学dsl,是每创建一个方法都要存一个属性吗,不然好像没法用

Jason5Lee:
我甚至希望 HTML 本身就长这样(

duangsuse:
不过我最近打草稿的 JS 框架就是这样
Forwarded from dnaugsuz
#bing #py 移植到 scipy 和 cv2:

# wav2rawpng.sh
infile=$1
sox -r 44100 -b 16 -c 2 $infile -e unsigned -b 16 -c 2 test.raw
file=test.rgb
mv test.raw $file
# find out size in bytes
size=$(du -b $file)
echo size in bytes is $size
# calculate padding needed to ensure square image
# I don't even know what's going on with the 6's...
pad=$(awk -v size="$size" 'function quad(x){return(x*x)} function ceil(x, y){y=int(x); return(x>y?y+1:y)} BEGIN{ print quad(6*ceil(sqrt(size/6)))/6-size }')
echo padding in bytes is $pad
cp test.rgb test-pad.rgb
truncate -s +$pad test-pad.rgb

# oh yeah we need the resolution too
newedge=$(awk -v size="$size" 'function ceil(x, y){y=int(x); return(x>y?y+1:y)} BEGIN{ print ceil(sqrt(size/6)) }')
echo edge size is $newedge
magick convert -size ${newedge}x${newedge} -depth 16 test-pad.rgb ${infile%.wav}-rawpng.png

—失败
from scipy.io import wavfile
from PIL import Image
import numpy as np

rate, aud = wavfile.read('a.wav')

# Compute the minimum square dimension
l = int(np.ceil(np.sqrt(aud.size / 6)))
pad = int((l ** 2) * 6 - aud.size)

# Reshape the aud array into a square image
img = np.pad(aud, (0, pad), constant_values=0)
img = Image.fromarray(img.reshape(l, l, -1),'RGB')
img

import IPython.display as say

aud = np.array(img).reshape(-1)
aud = aud[:aud.size - pad]

wavfile.write('a1.wav', rate, aud)

say.Audio('a.wav')
#py #code #FP w2png diff
from PIL import \
Image ,\
ImageFilter as Filt
import \
librosa as sa, soundfile ,\
numpy as np ,\
functools as Fns

pipe=lambda*eq:Fns.reduce(lambda a,b:\
(lambda x:b[0](a[0](x)), lambda y:a[1](b[1](y))), eq)

def main():
cat,cut=w2bmp('a.wav') #v use blur(3px) on audio?
a=cat('out_'); cut(a)
b=cat('fi_').filter(Filt.GaussianBlur(radius=3)); cut(b)
display(a,b)

w2bmp=lambda fp:pipe(wav(fp), ft, (svA,svB), (np.flipud,np.flipud), bmp('HSV') )

def wav(f,sr=48000,ver=''):
def to(v): nonlocal ver;ver=v; return sa.load(f, sr=sr)[0]
return to, lambda y: soundfile.write(ver+f,y, sr,'PCM_16')

# A:w2bmp, B:bmp2w
bmp=lambda rgb: (
lambda A:Image.fromarray(A, mode=rgb).convert("RGB"),
lambda B:np.array(B.convert(rgb))
)

yMax,yPad=300,lambda x:np.pad(x, [(0, 1025-yMax)], 'constant')

ft=(lambda A:(F:=sa.stft(A)[:yMax], (np.abs(F),np.angle(F)) )[-1] ,\
lambda B:(lambda V,S:sa.istft(V * np.exp(1j * S)) )(*map(yPad,B)) )

def svA(A):
V,S=A; H=np.full(V.shape,0) # 0, power, phase
return np.dstack((H, S, V)).astype(np.uint8)
def svB(B):
H,S,V=(px[...,0] for px in np.dsplit(B,3))
return V,S


def main():
cat,cut=w2bmp, bmp2w
a=cat(); cut('out_',a)
b=a.filter(Filt.GaussianBlur(radius=3)); cut('fi_',b)
display(a,b)

# A:w2bmp, B:bmp2w
fp='a.wav'
sr=48000
yMax,yPad=300,lambda x:np.pad(x, [(0, 1025-yMax)], 'constant')

def w2bmp(): # 所以,你要在两个函数里涉及文件 read-write
A=sa.load(fp, sr=sr)[0]
F=sa.stft(A)[:yMax]
A=svA((np.abs(F),np.angle(F)))
A=Image.fromarray(A, mode="HSV").convert("RGB")
return A

def bmp2w(ver, B):
B=np.array(B.convert("HSV"))
V,S=map(yPad,svB(B))
B=sa.istft(V * np.exp(1j * S))
soundfile.write(ver+fp,B, sr,'PCM_16')
duangsues.is_a? SaltedFish
https://react.dev/blog/2023/03/16/introducing-react-dev 也写了 ee.Counter=({n=0})=>button( wOp({tap(){ n.v++ }}), Eq.fmt`pressed ${n}time$` //这样支持SSR或爬取 ) ee.Inp=({v="", isOk=$Y})=>html( input(wKV({v}) ) p(Eq.fmt`You typed: ${v}`), btn(Reset=>{v.v=""})…
ee.main=({name='world'})=>
h1(html`Hello ${name}!`)

ee.main=({src='rick.gif', name='Rick Astley'})=>
img(wKV({src, alt:html`${name} dancing`}))

ee.main=({n:0, hov})=>
button(
wSty({ $wtf: hov })
wOp({
tap(){ n.v+=1 }, hov
}, 'only'), //preventDefault
html`Clicked ${n}time$`
)

ee.main=({a=rn(0,10), b=a, c})=>(
Eq.at(c,{a,b}, _=>a+b),
div(
sel(a), sel(b),
p(html`${a}+${b}=${c}`)
)
)

ee.main=({n=0, n2,n4,sec}, my)=>(
Eq.at(n2, {n}, _=>n*2),
my.stop=CSS.s(0.5).rate(()=> n.v+=1),
div(
button(
wOp({tap: my.stop})
),
p(html`${n}*2=${n2}`),
p(html`${n2}*2=${n2(x=>x*2)}`)
)
)

ee.main=({n=0})=>(
Eq.at(n,{n}, _=>{
if(n>=10){ say(`count too high!`); return 9 }
})
button(
wOp({
click(ev){ n.v++ }
}),
html`Clicked ${n}time$`
)
)

ee.main=({t=0.})=>
html(
efx(t, {dur:400, ease:'k3'}),
progress(wKV({value: t})),
...rn(0,1, 1/4).lets(t=>button(
wOp({tap(){t.v=t}}),
html`${t}%`
))
)

ee.main=({vis=$Y})=>
html(
sel(vis),
p(efx(vis, {erase:{fly:{y:200,dur:2..s}, fade:{dt:.1} }}),
`in:fly out:fade`)
)

// 组件化
ee.main=()=>p(`Styled~`)
Nd.unit(CSS=>{
wSty("app")
wSty.p={
color: purple,
font: {
family: ['Comic Sans MS', cursive],
size: 2..em
}
}
})

ee.main=({it})=>(
wSty(it, "app"),
p(`These styles`, Nested())
)
ee.Nested=()=>
p(`...don't affect me `, html(`<u>here ULine</u>`))

ee.main=({})=>NeedKV(wKV({answer:42}))
ee.NeedKV=({ask:{answer}})=>
p(html`Universe is ${answer||'a mystery'}`)

const pkgs=[
{
name: 'svelte', ver: 3,
href: 'https://svelte.dev'
speed: 'blazing fast',
}
]

ee.main=()=>lets(pkgs, Info)
ee.Info=({name,ver,href,speed})=>p(html`
The ${code(name)} is ${speed}.
Get v${ver} from ${a(['',html`http:${name}`], `npm`)}
and ${a(['',href], `learn more here`)}
`)

//逻辑
ee.main=({
login=NO
})=>
when(login, {
$Y: btn(LogOut=>{ login.v^=1 }),
$N: btn(LogIn =>{ login.v^=1 }),
})

ee.main=({
x=7
})=>div(wOp({edit:$Y}),
when(x (x=>[x>10, x<5, $Y] ), [
p(html`${x} > 10`),
p(html`${x} < 5`),
p(html`${x} in rn(6,9)`),
]),
mark(wOp({edit:NO}), 'Truth: ',x, error)
)

let cats = [
{ id: 'J---aiyznGQ', name: 'Keyboard Cat' },
{ id: 'z_AbfPXTKms', name: 'Maru' },
{ id: 'OUtn3pvWmpg', name: 'Henri The Existential Cat' }
];

ee.main=()=>$app(
h1(`The Famous Cats of YouTube`),
lets(cats, ({id,name},i)=>
li(a(['',html`yt:${id}`,'_blank'], html`${i(Eq.num(+1))}: ${name}` ))
, ul(`empty?`))
)

let things = is.w`darkblue indigo deeppink salmon gold`.lets(
(x,id)=>({id,color:x}))

ee.main=()=>
html(
btn(Pop0=>{ things.splice(0,1) }),
grid({of:'1fr,2', gap:'1em'},
...['id',NO].lets(k=>
div(h2(`Key ${k}`),
lets(things.let({sort: k}), Thing)
)
)
)
)
duangsues.is_a? SaltedFish
ee.main=({name='world'})=> h1(html`Hello ${name}!`) ee.main=({src='rick.gif', name='Rick Astley'})=> img(wKV({src, alt:html`${name} dancing`})) ee.main=({n:0, hov})=> button( wSty({ $wtf: hov }) wOp({ tap(){ n.v+=1 }, hov }, 'only'), //preventDefault…
//Events, no forwarding indeed
ee.main=()=>html(
wOp({msg(ev) {ee.say(ev.text)} })
Inner({})
)
ee.Inner=({it})=>(
wOp(it.super={msg:1 }),
btn(sayHello=>{ it.super.msg({text:'morning!'}) })
)

ee.main=({d,time})=>(
Eq.at([d,time], [1..s.rate], ([t])=>[new Date, t]),
h1(html`Time is ${d}h24,${[,,,0,2,2]}`)
)

ee.main=({P=N2(0,0)})=>$full(
N2.ptr(P),
html`mouse @ ${P.x}y${P.y}`
)
ee.main=({x=0,y=0, k='client'})=>$full(
wOp({mousemove(ev) { x.v=ev[k.v+'X']; y.v=ev[k.v+'Y'] } }),
wOp({tap(){ee.say('Only once') } }, 'once'),
html`mouse @ ${x}y${y}`
)


api=ee.HI('tutorial/', {
'*':({text,ok})=> ok? text : Error(text)
})
ee.main=({F5})=>
html(
button(wOp({tap:F5}), `load Num`),
Reload({},
lets({load:[F5,api.random_number]}, x=>html`Rand num is: ${x}`)
)
ee.main=({F5})=>html(
button(wOp({tap:F5}), `load Num`),
Reload(
{load:p(`..Wait`),fail:p(wSty({fg:'red'}), error)},
lets({async*load() {
for(;; await F5) yield api.random_number()
}},
x=>html`Rand num is: ${x}`)
)
)

api=ee.HI('https://jsonplaceholder.typicode.com/', {
photos(x,{_limit}){}
})
ee.Photos=()=>
html(
h1(`Photos`),
grid({of: '5,1fr', gap:8}, wSty`full`,
lets({load:()=> api.photos(20) },
({thumbnailUrl:src, title:alt})=>figure(
img(wKV({src,alt})), figcaption(alt)
))
)
)

ee.main=({size=42, text='god', L})=>
html(
sel(size), sel(text),
p(html`size: ${L.x} h ${L.y}`),
div(
wKV({ xy:[0,L, 'absolute!'] }),
span(wSty({font:{size} }), text)
)
)

//Form
let active=a=>a.only({done:$N})
ee.main=({
todos=is.wdoc`
rewrite Svelte
build TODO app
adopt AI
`.split('\n').lets(x=> ({done:$N, text:x}))
})=>
html(
h1(`Todos`),
lets(todos, x=>div(wKV({show:x.done(q=>!q) })
sel(x.done), sel(x.text, {tip:`Do what?`})
)),
p(html`${todos([active,n])} remaining`),
btn(Add=>{ todos.add({done:$N,text:''}) }, Clear=>{ todos.let(active) ) })
)

ee.main=({pin=''})=>
html(
h1(wSty({ fg:pin(q=>q? '#333':'#ccc') }),
pin(x=>x? x.replace(/.(?!$)/g, '•') : 'pls enter' )),
Keypad({pin}, {submit:alert})
)

ee.Keypad=({pin}, my,
btr=(tap)=>button(wKV({show:pin(x=>!x)}), wOp({tap}))
)=>
grid({of:'3,5em 4,3em', gap:'.5em'},
wOp({of: 'button',
tap(){ pin.v+=this.innerText }
})
...rn(1,9).lets(x=>button(x)),
btr(()=> pin.v=''),
button(0),
btr(my.submit)
)

ee.main=({
name='',
ten=rn(0,10),
a=[1,ten],b=[2,ten],c,
yes=$N,
flavors=[['Mint choc chip'], menu],
scoops=[0, is.w`One Two Three`.lets(x=>x+' scoops')],
order='',
text='my **dear** Python'
})=>(
Eq.at(c, {a,b},_=>a+b),
Eq.at(order, {flavors,scoops},_=>
n(flavors)==0? 'need more!'
:n(flavors)>scoops? 'more scoops!'
:html`Ordered ${scoops}scoop$ of ${flavors}`.v
),
html(
sel(name,{tip:`enter your name`}), p(html`Helo ${name (x=>x||'stranger') }`),
sel(a, {chk:1}), sel(a),
sel(b, {chk:1}), sel(b),
p(html`${a}+${b} = ${c}`),
sel(yes),
when(yes,
{$Y: p(`Good boy!`),
$N: p(`Bad !! must be checked`) })
button(wKV({show:yes}), `Get Food`),

h2(`Size`), sel(scoops)
h2(`Flavors`), sel(flavors, {of:'many',chk:1}), // of:'' = select[multiple?]
order,

textarea(wKV({value: text}), wSty({width:'100%', height:200 })),
html(text(marked))
)

)
is.use`marked elizabot.Eliza`
let menu = [
'Cookies and cream',
'Mint choc chip',
'Raspberry ripple'
]

Rn.ptr
await 0..s
String.it({
swapcase(_) {
/[a-z]/.test(_)? toUpperCase():toLowerCase()
}
})



删掉了my参数,允许用 ee.fork 定义私有组件、直接添加原型链扩展。爽了,减少了UI设计的噪音

ee.Demo=({n=0, ptr,P}, fmt=({x,y})=>html`(${x},${y})` )=>
div(
wOp({ mousemove:ev=>ptr }), N2.ptr(P), ()=>其他初始化绑定,

btn(n, [html`++ ${n.to(x=>x+1)}time$`])
, b(wOp({tap:n.to(Eq.num(-1))}), `n--`)
p(ptr(fmt)),
li(P(fmt))
)

let localUI=ee.fork
ee.Demo.it({
__n1:_=> _.n+1,
n: Eq(x=>x+1)
})
我把文章的 #ts #Rust 代码重写了下

when- as
Automobile'wheels seats manufacturer'(:Cnt1, manu_:Str)

- main
Automobile(4,4,"X"):
say("My car has ${wheels} wheels and ${seats} seats, and it was made by ${manufacturer}.")

when- MyCar
Wheels Seats Manfus

- main
at car=[4 4 "X"].Ary
car[MyCar.Seats.id].as<Int>

“没什么语法把名字给编号,和类型对应,但 T() Send 可以实现T,Ln<Any>转换”
-! main
PairN<Cnt1 Cnt1 Str>([4 4 X]):[[Wheels Seats Manfus]]
Wheels

pkg @RowAsData
“tag和强转的就不写了,太智障。
struct True,False 的也算了,编译期计算没必要写成类型匹配”
when- Expr
Const(:Int)
Op(:Opk, A:Expr, B:Expr)
when- Opk
+ - * /

- +(e:Expr) = when e:
Const(x):x
Op(k,A,B): (+A to +B):
when k:
+: A+B

- main
at e: Expr = (+, (53), (-, (1), (0) ))
say(+e)

'AB'(get)when- Either
A(:A) B(:B)

at xx: Either.A<Int>
xx.as<Either<Int Any?>>

“data Nat = Z | S Nat deriving Eq ”

when- Nat
Z S(:Nat)
- +(:Nat) = when nat:
Z: this
S(x): S(this)+x
- + 'ab'(:Nat) = when a to b:
Z to n: n
S(x) to n: x+S(n)

- main
at:
one S(Z)
three (1~3) (Nat: Sum(Z,S))
one+three

-! printf(fmt:Str) = Fn1<Arg<Any>>{}.as<Fn>
^now
-! Fn = Type: “constexpr, TypeFamilies”
FnN(fmt('\\d'):Int )

动|静|绝句
Array 具名?元组,组 when-as,Ln<Str>
Tree union-和类型 when- HtmlNode
Value 具名?泛型 'T'type Ln, Any
for和递归 类型的归纳 'this'type Num
if和匹配 trait重写 - Str as() Int
签名 trait Fn<R> (编译期计算)
实现 impl Fn forT
调用 T as F<>::Out
#ts #PLT 每次看Py花猫的周刊,都能帮助自己改良设计…… 谈到 typed printf, 又不知绝句类型上什么写法最好了。 这些内容,可以理解为用“声明式“的方法 生成要eval() 的代码

- htmlTag("div", attrs..) 如何查到元素类型,和限制attr{k:v}
- int[10] 的 get(i), +int[5] 如何只在标准库实现
- pipe(num=Eq<Str Int>, aList=Eq<Int Any>) 如何得到 Eq<Str Any>, 或者提供 aList=Fn1:a[it] 的类型信息

绝句不会用上文里 C++,Rust 用的那种编译期模板,甚至比 Nim 的编译期计算走的更远。 -! evalFun(:Arg<*>)=arg[1] 本就是分段求值的

也就是通过监听已知参数上的执行,来推测「变量」的类型, at! kv=[:"a" 1 "b" 2.0] 这些“字典类型”也不需要专门做支持,因为'!'就是编译期内联的意思,只会在与变量同算式 或自身非:Send时,真正保留

这样看, -! printf(fmt:Str, :Arg<*>) = fmt('\\d').Ln:[regexSpan i] arg[i] 是不需要额外标注类型(函数)的,反正用了依赖类型,也只是把函数体 按「变量」而非「值」再复述一遍

高端在哪呢? 不过是 Box<T>,or:T, Fn1<T R> 的R既能从Box里推导,也能是抽象的<T>被listOf()组装 ,再查个重载。关系式编程并没有很难。
那么 int[10] 可表达为 'T'AryN(N:Cnt,:Ary) , fn(:AryN<Int>{N=10}), 构造和解构时检查下就好了,功能和纯函数式一样,还避免直接写 check() require()。

一些语言把递归匹配和类型运算符混在一起写 (都用上递归了,还不好做“反向查询”..),显得类型体操是个又难、又有用的技巧,但各个击破的话,这些强类型的魔法其实是没事找事…… 语言贫瘠造成的逻辑炸弹

但这样有问题,不能给 String.format() 标注类型;如果要的话,要组合出 Type: Fn1(Int, Str) 这种动态泛型 ,我不喜欢这种手动算类型的 ,但如何优化掉呢??
duangsues.is_a? SaltedFish
我把文章的 #ts #Rust 代码重写了下 when- as Automobile'wheels seats manufacturer'(:Cnt1, manu_:Str) - main Automobile(4,4,"X"): say("My car has ${wheels} wheels and ${seats} seats, and it was made by ${manufacturer}.") when- MyCar Wheels Seats Manfus …
#design 刚才审核绝句 句级跳转&主语域时,意识到 break continue 这些必须和 if 搭配使用,以及
- 因为使用 (0~9):[i] break i==5 的语法函数化, break n 必须=return^n*2+1^ ,就像 this=you^0
- tailrec 是 at xxx=let: return^0^ any 里的(ret赋值&break) 的平替

fun IntRan.forEach(fn:(Int)->Unit) {
var i=first
do { fn(i);i+=1 } while(i<=last)
}

- Rn<Int>.`|`(:Fn1<Int>)
at now: i A
let:
fn(i)
loop(i+1): i!>B //i<=B

// AI的编程效率高于补齐,阅读速度上还在用 map-forEach, let-apply 这些的话是不够的
((0~9) : +1) == (1~10)
(1~10)|: [x]
say(x-1)

at now: i 0
loop $Y:
breaks i<10
break i==100
say(i)
when i:
5: 这里才允许; break
else{}

太棒了,终于摆脱流控了!
但,正在考虑应该强制带上“跳过 跳出^0^” 以防止在单层循环体滥用

不少人在用 if continue 实现filter,但绝句会歧视过程式编程.. (0~9){>5}: say(this) 是绝句里单项和列表通用的搞法
"a arm bar ada".Sep.firsts{it[0]=='a': if !this{say("End")} } 则关于break

if break 可以视为 while(cond) 的扩充,但考虑CLI程序:
let:
at str=input("> ")
str:
in('(\d+)'):[[d]] say(d.Int+1)
loop(): str!="q"

二层循环(本该用函数跳转)

- Str find(sub:Str) Idx
at N=sub.Cnt
(0~Cnt-N):[i] //N=1,则 i=0~iLast
(0~~N):[iS]
break^0^ this[i+iS]!=sub[iS] //也可以每次iS=i 然后blabla..
return i
return -1

- 文 找(:文) 针
在N=文的计
(0~计-N):[i]
首否(文、i) 去路,回i。
回-1

呃,这个是命题 all, any 的才能提前break

- Ln<Ln<Int>> firstZero
at now: i; j
this:[i a] a:[j x]
break^1^ x==0
say([i j])

应当把鸡肋的流控和过度return,扔进历史的垃圾桶了。 向物理公式看齐,而且没有数学的那些希腊字符,没有 __dunder__,但 +-*/ 都可由用户定义
比Py更激进,只有文件和(主语)函数域,不可以无缘无故加{}号分号

- move'ab'(:Int) = let:
loop(a-1,b+1): a!=0
b

'T'data Linked(x:T, xs:Linked?)
-'T' last(a:Linked) = a:
loop(xs): xs!=NO
x

fun move(a,b) = if(a!=0)move(a-1,b+1) else b

data class Linked<T>(val x:T,val xs:Linked<T>?)
fun<T> last(a:Linked<T>) = a.run { if(xs!=NO)last(xs) else x }
#blog 看到易语言还在VB++ 的范式旁徘徊,并且觉得编程语言是种必须特色和备案的「核心技术」… 我想复刻下这2007年文章的口吻:

“绝句.ju”十分钟入门教程
作者:转载必须注明出处

亲爱的朋友,您愿意花十分钟的时间,来了解一门全新的编程语言“绝句.未公开”吗?

#1
只有十分钟,时间紧迫,让我们立刻开始,不多说一句废话(这一句话本身算不算废话?哈哈)。
请去拜读易语言官方提供的《“易语言.飞扬”白皮书》——这本书写的很好,文笔比我强多了!本文大量参考该白皮书。

#2
绝句的大概:
- 物类面向对象,具有名词动词、同名例的概念(忘掉函数式编程吧
- 支持宿主语言的GC(Str Int 都是 Any 指针,能自动优化,轻松多了
- 源代码将被编译为全面西化的语言(当然还是比不上“仓颉”“木兰”了
- 用 data- JVM as 接口 跨平台编译为多个操作系统(微信OS/Homo/郭继承...)的可执行
- 可将源代码压缩为AST类库,以达到代码复用。
- 将会有一个包括“可视化函数设计”的集成开发环境(IDE),其将用js编写

我想有必要再强调一遍:“绝句”跟原来的Kotlin(1.x - 1.4.x)是完全不同的两个编程语言(如果非要找出相同点话,它们都能够用英文编程,作者都不是吴涛)

#3
物 启动类
同名例
- 起点
说("祖国您好!")

juc hello.ju_zh .java

启动类.class 的执行结果是在屏幕上输出:祖国您好!

还记得吗?吴涛教给我们的第一个易语言(旧版)程序不过是一句淡淡的问候而已,哪象“祖国您好!”这样饱含深情?
中国永远不缺少国际🇹🇼主义者,但我们急需的是 民族主义者🇨🇳

#5
类 游戏
- 猜

- 起点(猜:游戏=猜数字()) @JVM
猜去猜

物 猜数字 私下(内定数字 = 66) 游戏
|- 猜
重复 非(猜数字(“不可”)),。

- 猜数字()@私下 真假
在n=获取数()
说(n、 NL="")
回 判n去较(内定数字),
首中,说("猜对了,恭喜");真。
首大,说("太大了");假。
首小,说("太小了");假。

- 获取数 @可定 = 听("请猜1-100中的一个数:")去数

物 全自动猜数字 私下(可变_n=1) 猜数字()
|- 获取数 @终定 = n移右

#6
- 类是指接口,公开是一种注解
- 起点 启动 入口 主要 面 可以是文件函数
- 造于 私下(内定数字) 指明构造量
- 循环、如果 换成重复非、若判(表达式)了
- 继承和 Go 一样,写括号后面就好

#7
起点(全自动猜数字()) 自动用线性查找 内定数字
也可以改为 读:函0<数> 参数

#8
友好名称——用类自然语言格式书写程序:

'T'物 `将`(:T) “名记平权”
- 将<文>`写到屏幕` = 说(它)

- 起点
将123写到屏幕
100.123,[x]
(将x)写到屏幕

没想到吧,绝句记法还可以这么用😅
就是照着能解析Typst和bash设计的

三联判断式:

若x存于0~10, “如果(0 <= x <= 10)”
若x存于(0的右~10的左), “如果(0 < x < 10)”

多自然呀,为什么其它编程语言就是不支持呢?我想所有程序员学数学都早于学编程,(后面的太矫情,怕被喷就不复制了)

不知道 Python 是否后悔同时支持 range(A,B)和A<x<B ,那么在支持UI框架时, A<x<B 是等于两个滑条吗?

双向赋值运算符“<=>”:

在此刻,a 1;b 2
可变去换(a、b)
必,a是2 & b是1 “既然有解构 a,b=b,a 不就好了.. 绝句是有可变引用”

方法多返回值:

''名龄=俩项<文 计>
- 华夏=("中国"到5_000)

华夏(),[名到龄]
名去作<合法名>“require”
  FIXME "揣摩上意,是更喜欢讲中国台湾,还是给台湾打码"
必"🐭","🦆"!
FIXME "这不是国产OS吗? 上面为什么报错?"

/* FIXME(请领导指示): 台独检查的中文翻译 却有搞台独的风险 *///
''合法名=Str{ "台湾"!in this : "但这个没备案的境外苏联app搞台独啊"}


#9
有了Kotlin,为什么还要重新搞“绝句”?

Kt1.4 已经渐趋成熟和Java化,恢复正常的空间已经很小了。

……有哪些本质改进?

完全面向对象、自动垃圾回收、可自行开发类库、纯文本源代码(?)、多文件工程、与C/C++等语言水乳交(?)融。

已经有很多编程语言了,我们还需要一个全新的编程语言吗?

确实,汇编语言诞生时,C语言诞生时,C++诞生时,Pascal诞生时,Java诞生时,C#诞生时,都有人问这类问题

#10
改自全公网唯一剩下的易语言入门
404官方论坛:https://dywt.com.cn/vbs/

pkg
sys; random:rand
cmd:Cmd

- main=猜数字().cmdloop
data 猜数字(x=rand(1_000)/10)Cmd
made now:
数 0; 最接近 100
历史 [数 ]()
- `#$default`(ln)
ln.Int?{数=this}or: say()
历史 add 数; on(数)
- on(num)
num==x: say(); exit()
or:
say("太${(num>x).way("大","小")}了")
接近了(): say("不过接近咯")
- 接近了=历史(Sum: abs(x-it)).min:
Var.swap(最接近,this): return $Y
$N
静态解析外语的“jvm”函数签名 到 #TS
让GPT3 压行翻译到Prolog ,省掉了等号和infer
但参数是含变量的值,不是单变量,依然看起来很魔法

arg('', []) :- !. %前缀转列表前
arg('i'||'d'|Xs, [number|R]) :- arg(Xs, R).
arg('s'||'w'|Xs, [string|R]) :- arg(Xs, R).
arg('v'|Xs, ["ArrayBuffer"|R]) :- arg(Xs, R).
arg('b'|Xs, [bigint|R]) :- arg(Xs, R).
arg('p'|Xs, [bigint|R]) :- arg(Xs, R).

% 明明是样板代码,但AI仍然会写错
argF('', []) :- !.
argF('['||part||']'|Xs, [fnT<part>|R]) :- argF(Xs, R).
argF('i'||'d', [number|R]) :- argF(Xs, R).
argF('s'||'w', [string|R]) :- argF(Xs, R).
argF('v'|Xs, ["ArrayBuffer"|R]) :- argF(Xs, R).
argF('b'|Xs, [bigint|R]) :- argF(Xs, R).
argF('p'|Xs, [bigint|R]) :- argF(Xs, R).

resT('i'||'d', number) :- !.
resT('b'||'p', bigint) :- !.
resT('_', void) :- !.

fnT(args, (Xs, number | void)) :- arg(args, Xs).

fnKV(args||'!'||res, Args, R) :- argF(args, Args), resT(res, R).
fnKV(args, Args, void) :- argF(args, Args).

relocated需要{}类型,GPT不会用Prolog查表
duangsues.is_a? SaltedFish
静态解析外语的“jvm”函数签名 到 #TS 让GPT3 压行翻译到Prolog ,省掉了等号和infer 但参数是含变量的值,不是单变量,依然看起来很魔法 arg('', []) :- !. %前缀转列表前 arg('i'||'d'|Xs, [number|R]) :- arg(Xs, R). arg('s'||'w'|Xs, [string|R]) :- arg(Xs, R). arg('v'|Xs, ["ArrayBuffer"|R]) :- arg(Xs, R). arg('b'|Xs, [bigint|R])…
duangsuse:
#js #web #Svelte 还没用熟 TypeScript 社区已经开始抛弃了 - 零点CoCo的文章 - 知乎
https://zhuanlan.zhihu.com/p/626237877

看起来他们比我还激进? (虽然我也是观望,不会为TS专门改设计

我是这么看的,前端也就只有123和abc, [{}] 三个类型

标注太占地方,还不如直接用 {a=0} 或者清晰的名字, EQ 简化了UI部分,让JS函数绑定到一种XML模板,消除了很多人眼障碍
如果编程习惯好的话,没有检查应该不会怎么样

本来以为Svelte这个作者算有两把刷子的,没想到和我的观念相似……

无虚拟 DOM 版 Vue 进行到哪一步了? - 手撕红黑树的文章 - 知乎
https://zhuanlan.zhihu.com/p/644340806

为什么React一年不发新版了? - 魔术师卡颂的文章 - 知乎
https://zhuanlan.zhihu.com/p/642766301

(现在AI的智商感觉越来越低了,不知还能不能用来给项目加类型)

JS的常量级类型check是很弱的, 比C好一点

DOM能有什么复杂的API ,都是RPC级别的类型复杂度, TS除了做点{}[] 的类型函数 好像也不需要计算很多


#FP 纯函数: 数据皆静止,调用皆惰性:(ok? print : noOp) 的if只是函数, if 必须有 else 。不可以用匹配&重构外的方式计算, 用"单子" "幺元" 结构来做流控
if let 解构,只要”值可以含可变<T>“ 👀,就变成简单的构造器&异常=跳过
可理解为”只能添加(调用) 不能反查“的关系式
子类型接口:
#haskell 使用解耦的 class (Num t) -instance (Num Int) 实现调用按类型,就像 #kt fun T.run(:重载)=按T单分派 ,会比 when-is 好
Visitor 可以把”覆写“隔离成配置对象 map({Int x: x+1, Str:}, 语法树), 连”配置“也是可继承&扩充的

反射:在弱类型里元编程才算直观, Object.values(AnyType) 在 Java就是所谓反射了。
Str的同名例TYPE,包含 f(_隐式this)(arg); _.x; _["x"]=1 的”语法“的实现。 KV<Str Int>.typedArg[0] 同是类型
Str 除了属于Type,还可遍历成员做 toJSON, 0参创建,依赖注入(=按类型.ini) 等接口
@定义() 如果只能生成为传参,就等效于在构造器调用 get("/http") {} 或继承钩子
#ai 也不会用现在的微分编程 #ml 框架
import sklearn.neural_network as ML, numpy as np

XOR = ML.MLPClassifier(
activation='relu' if 'ok' else 'logistic', max_iter=10000, hidden_layer_sizes=(4,2))

csv=np.array([[*x]for x in "000,101,011,110".split(',')])
#csv=np.vectorize(int)(csv)
XOR.fit(X:=csv[:,:2], csv[:,2])
.predict(X) #成功

import torch
import torch.nn as nn
import torch.optim as optim

# 定义 XOR 网络类
class XORNet(nn.Module):
def __init__(self):
super(XORNet, self).__init__()
self.fc1 = nn.Linear(2, 4) # 输入层到隐藏层
self.fc2 = nn.Linear(4, 1) # 隐藏层到输出层
self.activation = nn.Sigmoid() # 隐藏层使用 Sigmoid 激活函数

def forward(self, x):
x = self.fc1(x)
x = self.activation(x)
x = self.fc2(x)
x = self.activation(x)
return x

# 创建 XOR 网络实例
net = XORNet()

# 定义损失函数和优化器
criterion = nn.MSELoss()
optimizer = optim.SGD(net.parameters(), lr=0.1)

# 输入数据和期望输出
X = torch.tensor([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=torch.float32)
y = torch.tensor([[0], [1], [1], [0]], dtype=torch.float32)

# 训练模型
for epoch in range(1000):
optimizer.zero_grad()
output = net(X)
loss = criterion(output, y)
loss.backward()
optimizer.step()

# 预测
predictions = torch.round(net(X))

# 输出预测结果
print(predictions)
duangsues.is_a? SaltedFish
//Events, no forwarding indeed ee.main=()=>html( wOp({msg(ev) {ee.say(ev.text)} }) Inner({}) ) ee.Inner=({it})=>( wOp(it.super={msg:1 }), btn(sayHello=>{ it.super.msg({text:'morning!'}) }) ) ee.main=({d,time})=>( Eq.at([d,time], [1..s.rate], ([t])=>[new…
https://www.youtube.com/watch?v=MnpuK0MK4yo

ee.main=({count=0}, txt,
_=()=>txt.as(x=>x*2) (x=>doc.title=x)
)=>
button(
wOp({tap:count(x=>x+1)}),
txt=html`count is ${count}`,
when(count.as(x=>x%2), p(`even`),p(`odd`) ),
when(count.as(x=>[x>1000, x>500, $Y]),
[p(`big`),p(`medium`), mark(`small`)])
)

ee.Tops=({items=is.w`foo bar baz`})=>
as(items, x=>
p(x.name)
,a=>html())

ee.Await=({}, num=Promise.resolve(10))=>
Reload(F5=>
as({F5,load:num}, x=>
p(html`It is ${num}!`))
,{
load:div(`Loading..`), err:ex=>ErrPage(ex)
})

ee.Navbar=({},es)=>
nav(...es)
#HR - 做过哪些项目,用过哪些 Android 开发相关的东西
没有,H5赛高


- 「大学生活质量指北」是什么
不过VS Alt-S 同行数多光标可以列粘贴, 但含换行的要 s/(^- .*)\n(.*?)/$1-NL-$2/g


- Java 里 LinkedList 和 ArrayList 的区别

链表不需要resize (1 (2 null))
+ LinkedList 和 ArrayList 是 Java 中两种常见的 List 实现方式。ArrayList 是基于数组实现的,它的随机访问速度很快,但插入、删除元素比较慢;LinkedList 是基于链表实现的,它的插入、删除速度比较快,但随机访问比较慢。

- 栈和队列的区别,如何用栈实现队列,Android 里哪些地方用到队列

Queue.add-pollFirst 队列 add-poll 栈。Looper Handler.post Stk.poll()=len==1? pop() : (x=pop(),r=递归,add(x),r) 。转换的话,LIFO两次==FIFO
+ 栈和队列都是数据结构。栈是一种后进先出(LIFO)的数据结构,只允许在栈顶进行插入和删除操作;队列是一种先进先出(FIFO)的数据结构,允许在队尾进行插入操作,在队头进行删除操作。可以使用两个栈实现一个队列,在队尾插入元素时,将所有元素都压入栈1中,在队头删除元素时,将栈1中所有元素依次弹出并压入栈2中,然后从栈2中弹出队头元素。在 Android 中,队列常用于消息队列、任务队列等场景。

- 上面我提到了 LRU 缓存,所以什么是 LRU 缓存

eg.已满100项{arg:ret}则删掉最早1项
+ LRU(Least Recently Used) 缓存是一种缓存淘汰策略,根据最近使用时间淘汰长时间未使用的缓存。常见的实现方式是使用哈希表和双向链表实现。

- HTTP 和 HTTPS 的区别

HTTP(SSL(connect(IP:port) )) 公钥加密的有无
+ HTTP(HyperText Transfer Protocol)和 HTTPS(HTTP Secure)都是用于在客户端和服务器之间传输数据的协议。HTTP 是明文传输,安全性不高,HTTPS 通过使用 SSL/TLS 协议对数据进行加密、签名和鉴别来保证传输安全。

- 进程和线程的区别

有无内存,fd资源隔离
+ 进程和线程都是程序执行的基本单位。进程是资源分配的最小单位,包括代码、数据、内存空间、文件和设备资源等。线程是程序运行的最小单位,每个进程至少包含一个线程。线程共享进程的资源,但各自有独立的栈空间和程序计数器,因此线程之间的切换比进程之间的切换更快。

- 有哪些方式保证线程安全

原子和锁,或者向量化 各自隔离
+ 保证线程安全的方式有很多,常见的包括用 synchronized 和 ReentrantLock 实现同步,使用 volatile 关键字保证可见性,使用原子类和并发集合等数据结构,避免使用共享资源等。

- 堆内存和栈内存的区别

堆new的对象不会在return时删除、栈很小(Linux 8M)
+ 堆内存和栈内存都是程序运行时的内存空间,不同之处在于堆内存由 JVM 进行管理,用于存储对象和数组等动态分配的内存空间,而栈内存用于保存方法执行时的局部变量、方法参数和返回地址等信息。

- StackOverflow 和 OOM 分别会在什么时候发生,如何避免


-Xms:8G -Xss:1G(划掉) 栈爆只会在DFS的输入太大或无基线,类似的OOM是BFS没有记忆而无限回环
+ StackOverflow(栈溢出)通常发生在方法递归调用层数过深或者死循环等情况下,导致栈空间不足,程序无法继续执行。OOM(OutOfMemoryError)通常发生在程序申请内存空间过多、频繁分配内存导致堆内存不足时,导致无法继续进行内存分配,程序出现异常退出。避免 StackOverflow 可以使用迭代或其他方式代替递归,避免无限循环。避免 OOM 可以通过优化程序算法、降低内存消耗、调整 JVM 堆内存大小等方式解决。

- 算 6&5 和 6|5

4+2+1, 0b111&|0b110, 5,6
+ 算 6&5 得到的结果是 4,6|5 得到的结果是 7。

- Activity 里什么时候会保存状态、恢复状态

onRestore/SaveInstanceState(强类型KV), 请AI实现 V:Parcelable
+ Activity 保存状态、恢复状态和屏幕旋转的生命周期都跟 Activity 生命周期有关。当 Activity 被意外销毁(如系统内存不足)或者用户主动退出时,系统会调用 onSaveInstanceState() 方法保存 Activity 的状态;当 Activity 重新创建或者从后台恢复到前台时,系统会先调用 onRestoreInstanceState() 方法恢复状态,再调用 onCreate() 方法重新创建 Activity。

- Activity 屏幕旋转的时候会经过哪些生命周期

请正读-反读 pause-resume stop-start destory-create
+ 在屏幕旋转的时候,Activity 会先调用 onSaveInstanceState() 保存状态,然后接着走生命周期的 onPause()、onStop()、onDestroy(),接着创建一个新的 Activity,最后调用 onRestoreInstanceState() 恢复状态。

- 如何计算一个图片会占用多少内存

nByte=w*h*单像素bit/8
+ 计算图片占用的内存可以使用以下公式:图片占用的内存 = 宽度 x 高度 x 每个像素占用的字节数。其中,每个像素占用的字节数跟图片的格式有关,如 ARGB_8888 格式的图片每个像素占用 4 个字节。可以使用 BitmapFactory.Options 对象的 inJustDecodeBounds 属性计算图片的宽度和高度。

- 项目中用过哪些第三方库,能否分别给出介绍

没有,安卓生态冗得像罚抄
jueju:刚开始,我们有个功能
say(1+1, end="\n")

^汇编(带数值类型,参数宏)

创建变量
-- pressF2(x)
say(x, end="\n")
明确类型
- sayNum(x:Int)
say(x, end="\n")

用类型里词汇去思考,乃至组合
- sayNum(x:Int)
(x!=0):
say(x)
at opts=[1 2 3]
opts:
(this==x): say("small")

- as(ln:You<Ln<Int>>, :Fun1<Int>)
at now: i 0; N ln.n
N!=0:
fn(ln[i]); loop(i!=N, i=i+1)

type 'T'Ln
at n: Cnt
- get(:Idx)T

^结构化(带list,GC,方法封装)

但是,如何复用at变量?先复用函数吧

- sayNum(x:Int)
say(x)
[1 2 3]{this==x}: say("small")
^now
- 'T'Ln as(:Test, :Fn0)
this:[x] test(x): fn()

然后把私下的^now 简化并公开!
data- SayNum(at, x:Int) Filters
say(x)
[1 2 3].only: say("small")
^now
- 'T'Ln only(do:Fn0)
this:[it] (it==x): do()

增加一点细节,为调用侧。
type 'T'Filters
- Ln only(do:Fn0)@ourpkg impl??

- main=SayNumFilters(0)|: “!读作 to:”
this()
x=3; this()

^面向对象(仅接口多态)

又或者,你的需求太简单,懒得去继承框架呢?
- main
“demo, list filters”
ask(at now Int: num)
at onlyIf=Test{it==num} “覆写”
num:[x] TODO"sayNum"

酷酷地可变量、伪递归
-- Var<Int>++=this|: v=v+1
-- ++(:Var<Int>)=as: v=v+1; v

- noop'ab'(:Int,b=0)=as:
loop(a!=0, a-1,b+1)
b

^函数式(非纯)

类型可以随意扩展
- SayNum odds(max=100)
(0~max by 2):[x]
this.x=x; this()

物类的类型,是一个单例'T'(T Type)。单例自己就是类型,就像 pkg 命名空间
data 'AB'Pair(A:A,B:B)
^named T
at mjs=Pair("Michael","Jackson")

--'AB' A`|`(:B)=Pair(A,B)
at Pair.T.jsm="Jasmine"|"Flower"

T提供了值域,而 T.Def==(name,[T0],{}) 反射其定义域。如果继承自Send,就能让序列化/注入器看到 T.cols,T.conds
- main=Pair: ([mjs jsm]):[A|B]
say("name:${A} family:${B}")

^面向对象

有数据的单例,要保存Enum,Is 等接口,就像Data
when- as
Pair(A:A,B:B)
when- Color
R;G;B
Bad
- Str=error("")

也可以模式匹配
when- 'AB'Way3
A(:A); B(:B); NO

接口随便扩充
- Int8|Int4=this.Int
data- Str|Sorts
^now
at sort=Fn1: it[0]

-'N'(N Num) Half=N.Rn: (A+B)/2.
type 'this'Num
^named T() .Const
type 'this'Const
at Rn:Rn<this>

^定义式编程(ADT)
#kt #FP #PLT duangsuse, [2023/9/27 15:56]
还是H5 <meta name="viewport" 好,就只有基于dpr的 px vw wh, 然后 sp=rem, @media(device-pixel-ratio:1)
不会因为放大到200% 就蹦出一个更新的单位。SVG里都一样

一个毫无意义的区别,让设计师拿来作为特色竞争力,妙呀

duangsuse, [2023/9/27 15:59]
你可以自己常量外提啊,JVM应该会优化

duangsuse, [2023/9/27 16:00]
不要管性能, 能被AI转写的那都是虚的,主要是好写耐看

duangsuse, [2023/9/27 16:00]
我也觉得把两个Int放在堆上很弱智…… 应该直接内联成参数,可是这就是 Java

duangsuse, [2023/9/27 16:02]
Kotlin 的 inline class 已经是种typealias了,你想怎么加? 我看他们不觉得这是问题

duangsuse, [2023/9/27 16:05]
Kt range 对int,long 都有不同的(模板)重载 ,连(Java8 stream 里也有的)去除装箱都没推广到语言层面,你还指望他们考虑这个。 最多就碎片地优化下惯用法

duangsuse, [2023/9/27 16:06]
不过JS里是有 forEach 比for of 快的一个见解。Kt里这也不失为一种统一风格,可惜如果性能有问题……

duangsuse, [2023/9/27 16:08]
你要理解它们,人家可是重造了LLVM的轮子, 是专业的中间优化层 😁

总之不重造轮子,就不算懂计算呗

duangsuse, [2023/9/27 16:10]
性能不会是我选择工具时的考量,但和你们交流时,我也会被带着跑…… 毕竟代码是要跑的,唉

duangsuse, [2023/9/27 16:10]
inline fun 不就是只针对lam的,包括 forEach 可以跳出两层也是因为有优化

duangsuse, [2023/9/27 16:14]
如果不可变,被捕获的外部var 就不必被绑定为Ref()

duangsuse, [2023/9/27 16:15]
真的有人会在用lambda时注意性能吗…… 不都是类似宏的用途,真要 onclick 那种是绝对无法缓存的

duangsuse, [2023/9/27 16:17]
全局的怎么能叫捕获呢…… 外层函数的栈变量,转堆变量,那才叫捕获

Kt 的fn is Any 应该是种误解,这方面反而是Rust.. 每个函数类型独立,要明确

duangsuse, [2023/9/27 16:19]
没想到 crossinline 竟然被Kt做成了特性,而Kt对这个特性什么教程都没有…… 让人摸不着魔法

duangsuse, [2023/9/27 16:21]
就不应该指明,JS 的闭包就是这样。闭包并不是Any,包括也没有toStr

你甚至不能看到调用栈里,受调用click等闭包的捕获变量。只有JS DevTools能看到那些

duangsuse, [2023/9/27 16:27]
我也想啊,比如协程是挂起,那“休眠”就是在退出重进时保留任务栈了,多香啊
一个语言都能实现操作系统了

可惜kt 里Coroutine和回调闭包是不同的

val hibernate = withContext(Dispatchers.IO) {
delay(10_000L); print("")
}

val hB = ByteArrayOutputStream().apply {
ObjectOutputStream(this).use{writeObject(hibernate)}
}.toByteArray()

val data = ByteArrayInputStream(hB).use {
val input = ObjectInputStream(it)
input.readObject() as Continuation<*>
}

// Resume the coroutine
data.resumeWith(Result.success(Unit))

duangsuse, [2023/9/27 16:35]
这个接口其实是 Promise+then时调度器 ,只是不需要yield而直接把自己给delay(),中规中矩。没有写可以序列化
(但其实换调度队列不需要coroCtx, 只有catch要它模拟调用栈+给函数值加名字, 以及让1个fun有两个等待scope..)

如果闭包都不能跨越会话重复调用,Coro就更不可能了

感觉有点可惜,如果可以的话,一门语言就足够支撑起操作系统内核那种复杂的多任务了

duangsuse, [2023/9/27 17:28]
函数序列化还有个好处, 就是若C/S端使用同一份代码(同构),
login(uid,hash) () 可以直接发到另一个全局环境去执行

就是不知道异步seq 是怎么执行的。但至少能用响应式{k:var}来监听

duangsuse, [2023/9/27 22:28]
找到了 ,和Python inspect 一样信息齐全
ObjectOutputStream 是通过这个支持:
(SerializedLambda)  fn.getDeclaredMethod("writeReplace")(fn)  //-readResolve
duangsuse, [2023/9/27 22:27]
对啊,感觉奇奇怪怪的。 我说的是那种两边都有,基于Hash和闭包变量分派的序列化

RPC和RCE真的一字之差啊…… RPC多少还有点接口规范可循吧, 但HTTP,REST,GraphQL 就稍微复杂点了

我说 login(uid,hash) () 可以直接发到另一个全局环境去执行 优点是在语言内部支持RPC,但protobuf这些也是可能的
duangsuse
, [2023/9/28 10:54]
你写了一个 T(x).f(arg): T 的链,并试图标明还未f()的T

你可以把灵感给GPT让它来写

duangsuse, [2023/9/28 10:55]
说到 reduce{A+B} 这类函数,我倒是有个 [0].as(Sum(it, (A,B)=>A+B)) 的封装,用于支持分组过滤

duangsuse, [2023/9/28 10:57]
在没有this的语言里调用链挺好玩的,但java里都有 new ArrayList(){{add(1,2); add(3)}} 这种用法

- add_v1'ab'=a+b
D=add_v1(1,2) “dbg print”

data Adder'ab'(:Int)
- add()=a+b

say(Adder(1,2).add)

data Adder(list:Ln<Int>)
- add()=list(Sum).sum

(1~4):
say(this,Adder(this.Ln).add)

[ALL(1~4)]:
at val=Adder(this){add}
say(val())
add 5; say(val())

type 'T'Gets
- get()T
type 'this T'Adds
- add(:T)this

data 'T'CanAdd(at,a:@our T)@impl?? Gets Adds
^now
- get=a

data I(a:Int)CanAdd()
- add(b)=a+b
data S(a:Str)CanAdd()
- add(b)=a.as<Str>+b

data 'T'Adder(list:Ln<CanAdd>)
‘测试’ Adder([I(1),I(2)]).add.get
- add()=(list isEmpty){ CanAdd.None }:
at now: x list[0]
1~list.iLast:[i] x=x.add(list[i])
x

type 'T'CanAddZ CanAdd
^named .Consts
type Consts
at zero:T
data I(a:Int) I()CanAddZ
^named
at zero=0

‘TODO’ (CanAddZ: Adder<I>()).get