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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): a19a0b
Download Telegram
duangsuse::Echo
#plt 回复 @幻の上帝 :原来你认识冰封和LH_Mouse[doge] 显然是做编译器喽, 我也做(kamet-dse),但只会前端。或许你应该试试讲科普,对概念理解得就会更具体。科普的语言简洁、顺序分明最重要,或许能遇到新东西[doge] 我这不就是遇到了吗​ 我对var的理解是 int i=1 这样显而易见的不必多打字,语言规范更多是种导向而非阻碍,如果类型足够含糊(如val x=a[i])大家是会标明的,规范不该太绝对;而且J11好像引入局部量推导了 抽象不该有什么目的,它是为实现目-易读易配置/扩展/移植的用的。…
类型和命名符号本来就不能分先后,硬要说,那有类型就是notype.checked,无类型就是多态的有类型,其实就是思想和汇编谁重要这种问题,公说公有理,我觉得都不如解法途径重要,所以我不讲理论的

你不觉得 C 的 int i,*p 类型记法,以及更难看的函数指针某种意义上是没有 __auto_type 导致的,初学者#define往往引起问题

%和<N 确实不该算一类,只是边界情况一样,Lua这样我也是很醉的,i=(0..<N)或(1..N) 其实不影响 N-1 这些修改的(若i!=N) ,考虑到它的table=ary|hashbucket 类JS混淆数组表,我觉得从1数反倒合理了-Lua只是为 a[i]这类元组引用的情况优化,反正其前身Sol是面向record的

因为区域取值不是集合类型论能检查的问题(甚至非负性都得看常量折叠),而且对暴露API的lib而言不动态检查无意义;程序和物理纸面是有区别的,程序会扩张和重复,故没法直观地严谨

N=随选数 的确很脏,Linus对这么选硬件地址的提交者严词批评,但oi算法比问题区间重要;不也有树状数组(堆排序,.)和kv状数组(状态机转移表),计算机毕竟是工程学科,AC就牛逼

至于位置,知乎上也没见啥有价值的讨论,C#CLR也是支持1起始,我觉得 iter-累计i=0 这可以说明时序和内存上0起始都更好,但现在有了函数协程,iter的出现也会越来越少,如 first(n) for(x of xs)if(n--)yield x else break
总之严谨点肯定是好,但也要看是为了什么,Lua牺牲严谨是为了石油采矿的统计,excel性质的,那1始数组也就有缘由了
#learn #cg 《OpenGL杂谈》 🔬
GL提供了特殊类型 vecN (xyzw/rgba/stpq 来引用/自由重组均可;可iub前缀表示类型)和matNxM (m[i<N][j<M])以及 texture(sampler2D,xy) ,支持严格 int/float percision ,支持struct和传统C的控制流及GL特有 cube/shadow,代码的特性由 compile 环境/GL驱动决定(比如GLES就不支持break,许多不能?:和%=mod,**=pow,不同类型?:)。SL能计算frag颜色和vert点-geom顶边,对应渲染和物理计算(一个很草的事实是,基于GL计算的渲染引擎在CG界遍地开花,各有各好 🤪)

SL是没helloworld却有计算力的语言,和CSS一样,明明print都写不了却能定义动画
尽管SL能保持个buffer-state,不要尝试只用SL完成一个功能机械的app,不然就太丑了。SL适合写动态壁纸和滤镜类的东西 #建议

除了社区不重视代码质量(冗长或空语义的极端,如uv=uniform=readonly graph-arg)、不善用struct、场景与渲染不切分、和复用/可配置力问题、shader含字符位图硬编码(GLSL不擅长的用途)等人的问题,也关于计算领域 🤔

为什么GLSL看起来和C很不同?不谈多out 函数和内部gl_物理变量,显卡的计算和CPU的单线模式差异很大。比如画个圆吧,g.arc(x,y,l, 0,2PI);g.fill() 后它就出现在画布(或用SDL/VGA)上了,因为这里有个“显示缓冲”位图的概念,所有图形存留在这里直到clear-SwapBuffers(一个冷知识,glFinish计数比FPS适合图形学跑分用),画圆可以迭代xy=(sint,cost) t=0~2PI 来累积圆上点,这个过程是线性的,多核CPU一次能画几个?尽管能LUT(查表)优化、能模拟Vec来复用同半径的结果,一次也只能画一个。对于几万个粒子来说就更鸡肋了,
因为执行顺序根本对时差更新/绘制结果毫无帮助,你逐个往画布叠对N叉 tree 好用,可对数学分形 还不如把“端点迭代”完全打散,越散越适合GPU计算。

显卡计算是没有顺序和“整体图像”的,几何都必须能按xy-颜色来“绘图”,因此着色器和 Painter 完全是两种东西,当然也有办法把arc(x,y,l)->float 峰值clamp 封装成函数,并且用数学方法mix()

#define v1 float
v1 circle(vec2 P, vec2 p, v1 l) {
v1 d = length(P - p) - l;
return 1.-clamp(d, 0.,1.);
}
void mainImage(out vec4 bg, vec2 P){vec2 L=iResolution.xy, p=P/L;
vec3 c = 0.5 + 0.5*cos(iTime+p.xyx+vec3(0,2,4));
bg=vec4(mix(c, vec3(.87,.37,.23), circle(P, L/2., L.y*.3 ) ) ,1);//试给圆半径 *mod(iTime,1.)
}
矩形xywh也可用类似手段。不过shader里这些形状不是必需品(paint里确实是)

数学(此为几何相关)应用相关命名随意已经是普遍现象了,
>“ s一般用来代表一个"scalar"(标量)。所以是一维数字。t是因为字母表s后面的字母。不能继续用u和v是因为uv已经被他们用来作计算用的坐标了。因此就用了向前的字母了。(strq)淡然,后来他们发现r与rgba的r冲突了,就用p替换了r。就是stpq了。
动画工具一般用t来表示时间的概念,所以就不用s和t来表示纹理的坐标了。因此,他们就用了u和v(UV贴图),因为他们根本不关心相关的计算。
s和t的命名来自于对平面的描述:r=r0+sv+tw (r0是平面任意一点,vw是定义向量,st随选)
uniform 意义也非常迷,它的意思是CPU和GPU间统一,许多人拿 uvec,uv 简写这ND座标/颜色/etc.,但SL里真有uvec2的类型-照传统编程早该改了,SL界硬是成了传统,想学图形先换术语,脑子里没对应表100%看不懂 😟

这是在GL(带一张 ShaderToy.com/new 贴图)显示 hello world ,带着注释里的问题阅读

float l=.06;
void mainImage(out vec4 bg, vec2 P) {
int[] t = int[](72,69,76,76,79,32, 87,79,82,76,68,33);//"Hello World"
P = P/iResolution.y - .3/*为什么能调x位置?全屏试试*/; P.y += .05*sin(3.*P.x+iTime) -.4;

for(int i=0; i<int(iMouse.x*.02)%12;i++,P.x-=.1)if (length(P-l)<l)
if(false)bg+=vec4(1)/*<能解释了吗? .5调成1.试试?>*/;else bg+= texture(iChannel0, P*.5 + fract(vec2(t[i],15-t[i]/16)/16.)).x;
}

答案:P的0值是确定点,for(i)if() 是为确定当前P对应的t[i] 。 P*.5 是因为原字体图太小了——那为啥P/2 呢?不该是有t[i]的位图yx偏移,就够在当前P画字了? 作为只懂g.fillText 的程序员不会考虑怎么从像素级别对应! P缩小了,同高区间就只含低 texture 视口,于是贴图放大了! 和数学函数缩放一样。类似写法在SL里很难规避,也没法文档

SL的逻辑不能用常规迭代/判断来解释,在进入图形学公式前,需要先习惯这种思维方式。许多程序员这辈子没机会,你看到了就是有本事。 所有平台,Web,Android,DX/Unity/Xorg 都支持OpenGL ,机器学习框架也开始GPU计算,不想黏合点特效装逼?看不出咋调参可不行!

你肯定会吐槽:逐点贴图?肯定很慢吧! 其实GL是最快的图形方法了。计算量大但都易优化,它是很低层的绘制API,和各种层次的painter不在一条赛道
在迈向并发的时代,一头什么都会的牛和一大群只会+-*/的鸡 硬件选择发展后者,应用层各有各好,但在图形上答案显然还是简单的-简单比线性好

#math 这是一个曼德博(朱丽亚)集的分形图,在SL上反而比在JS更合适,不需要手动迭代虚数P(x,y)

#define cxmul(a,b) vec2(a.x*b.x - a.y*b.y,  a.x*b.y+a.y*b.x)
#define R iResolution
//#define JulC vec2(.383,.13)
void mainImage(out vec4 bg, vec2 P){
vec2 z,c = P/R.xy *4.-2.; c.x=c.x* R.x/R.y +(.2-iMouse.x/R.x)*15.; c/=1.2+iMouse.y/R.y*20.; z=c;
#ifdef JulC
c=JulC; //v 猜猜看,怎么调参数.
#endif
float i=.0,N=abs(sin(iTime/32.0))*64.0, v;
for(; length(z)<2. && i<N;i++)z =true? vec2(z.x*z.x-z.y*z.y, 2.*z.x*z.y)+c : cxmul(z,z) + c;
v=i/N;
bg = vec4(v,v,v,1);
}

这是一个”老相片“视频滤镜,展示了GL无所不能的inputs... ,猜猜它是怎么处理颜色的

void mainImage(out vec4 bg, vec2 P){
vec2 p = P.xy / iResolution.xy;
//p.y = 1.0 - p.y; // invert
//p.x = 1.0 - p.x; // flip
vec4 c = texture(iChannel0,p);
float c0 = (c.r + c.g + c.b) / 3.0; // grayscale
c.rgb *= abs(vec3(cos(c0),sin(c0),atan(c0) * sin(c0)) );
bg = c;
}

以上三个示例里,大家都能感受到GLSL对向量(元组)计算 帮助是很大的
应该也能感受到数学计算里不需要太多边界判断,靠sin,mod 等就能展示复杂的图形。比如这个 fireworks. fascinating graphics, made eazy, 类似的有效作品120多个
OpenGL着色器杂谈今天就到这里

ref:
https://zhuanlan.zhihu.com/p/32788146 Py julC
https://blog.csdn.net/cuckoo1/article/details/108083508 js分形
https://www.shadertoy.com/view/Wtt3Wl OTF bezier
https://www.shadertoy.com/view/XsyXzw 音乐粒子
https://www.shadertoy.com/view/7dKGDK 基础着色
https://www.cnblogs.com/chen9510/p/11447292.html UBuffer 跨着色器传递
duangsuse::Echo
#learn #cg 《OpenGL杂谈》 🔬 GL提供了特殊类型 vecN (xyzw/rgba/stpq 来引用/自由重组均可;可iub前缀表示类型)和matNxM (m[i<N][j<M])以及 texture(sampler2D,xy) ,支持严格 int/float percision ,支持struct和传统C的控制流及GL特有 cube/shadow,代码的特性由 compile 环境/GL驱动决定(比如GLES就不支持break,许多不能?:和%=mod,**=pow,不同类型?:)。SL能计算frag颜色和vert点…
#cg 也是非常有创意的领域,而且也有技术
第一个烟花就只这点代码(都不够按行算了):
#define N(h) fract(sin(vec4(6,9,1,0)*h) * 9e2)
void mainImage(out vec4 o, vec2 P) { //fireworks[SH17a]
vec2 u = P/iResolution.y;
float e, d, i=-2.;
for(vec4 p; i++<9.; d = floor(e = i*9.1+iTime),p = N(d)+.3, e -= d)
for(d=0.; d++<50.;)
o += p*(1.-e) / 1e3 / length(u-(p-e*(N(d*i)-.5)).xy);
u.y<N(ceil(u.x*i+d+e)).x*.4 ? o-=o*u.y : o;}
第二个也只有20行稀疏的代码 https://www.shadertoy.com/view/4sjBWR
这就是几何学的魅力

对于我们普通程序员,也是很值得思考🤔的- 仅仅使用一个数字,多写点算式就能实现复杂控制流的功能,仿佛变量都不必存在一样
也好像是禁语游戏-不使用常规绘制法,如何绘图

这也是函数式编程的特征啊
所以是顺序执行,还是怎样怎样,有许多代码可以实现一个程序,只要思想不滑坡,你就永远是菜鸡-只是菜的清醒罢了😂
#algorithm UnionFind、三角分形(精简版)

如果要实现 Set 你会怎么做?每次 add(x) 时去重遍历 uniq() 吗?
现在按数组Array(N).fill(0).map((x,i)=>i) 实现 Set<Int> 。每位与一个索引关联,初始是和自己
当加一对 a-b ,把它们的位置赋上彼此,就能知道在不在同集合内——不行,如果还有a-b-c 咋赋值?
答案是 a->b 关联 b->c 再关联,因此 find() 变成链表遍历后最终同一。然后 add(a,c) 先找这个"b",把它->c
最终这个 Map<Int,Parent=Int> 会变成树状数组,只是不被遍历。UF集也有a-b小size侧优先-> 权重,和max()时顺便合并快查法

UF=(N,up=Array(N).fill(0).map((x,i)=>i) )=>(a,b,eq=true)=>{
let max=i=>{for(;i!= (i=up[i]);); return i}, iA=max(a),iB=max(b)
if(eq&&iA!=iB)up[iA]=iB; return eq||iA==iB //不上obj,写不好..
}
let o=UF(3); o(0,1);o(1,2)
o(0,2, false)==true


//给不懂的同学:N是(Map状数组)项个数,up是“父数字” ,eq代表不仅查询还建立a-b 连接关系。 UF算法与up[] 是1:1 ,所以随便起了个o=UF() 数据来功能test
这个相当于List<Set<Int>>
另外 UF,BFS 都是在节点图上判断两点是否联通,如果需要路径则用 DFS ,如从节点 2 的[+3,*3]边怎么走到 "9":
dfs=(link,flink,out,chk=(e,e1)=>{let k,k1;if(e==e1)return[]; if(!out(e)) for(k of link){k1=chk/*找!*/(flink(e,k),e1); if(k1)return k1.concat(k) } })=>chk
ten=dfs(["+3","*3"], (a,k)=>eval(a+k), a=>a>10)
ten(2,9)
->+3*3 (chk完还应reverse下.)
//当然比较hack,如果是专门讲我就会用正经let函数
然后最短路径可以用Dij狄图算法(也可优化权重边),也有A*啥的寻路法。 pip,apt 等依赖工具就是简单BFS可达搜索搞定;我不搞OI懂的不多
#inm 比较喜欢的数字论证生成器可以是这样 11 = 11*-4+51+4

我找了两个与算法解读比 较差的博文:
https://blog.csdn.net/dm_vincent/article/details/7655764
https://www.cnblogs.com/SeaSky0606/p/4752941.html
还有正经算法解读: https://zhuanlan.zhihu.com/p/63123489
大家可以比比它们的信息量。
—
你要咋画 Xecades大佬的三角分形 (三角内接倒三角,其三边与我顶点继续如此)?
本来是要在中线拿3点(shift遍重组,或者手写配对)和带深度递归的,可看起来只需要
#js #code
document.write`<canvas id=eg>`
{
let sq=Math.sqrt, dim=(e,[w,h])=>{e.width=w,e.height=h}
y = Math.min(innerHeight, innerWidth * sq(3) / 2)
g = eg.getContext("2d");
g.fillStyle = "blue";

let P=[[0,y],[y / sq(3),0], [2*y / sq(3),y]],p=[...P[0]] //左顶右
dim(eg,P[2]);dim(eg.style,["100%","100%"])

setInterval(() => {
let j=0,i = Math.random() * 3 >>0
for(;j<2;j++) p[j]=(p[j]+P[i][j])/2 //随机选方向游走
g.fillRect(...p,1,1)
})
}
//g;画布,dim:宽高wh ,sq:三角(点->点)xy距离的计算, j:仿造向量的计算同时应用于xy

就够了。GLSL 里画三角
#define v1 float
v1 PI=3.14;
v1 ply(int N,vec2 p){
//多边形. 三角[0,y],[y / sq(3),0], [2*y / sq(3),y] 都没了..
v1 d, TURN=2.*PI;
// space to -1~1.
p = p *2.-1.;

// Angle and radius from the current pixel
v1 r = TURN/float(N);
v1 l = atan(p.x,p.y)+PI;
d = cos(floor(.5+l/r)*r -l)* length(p);//distance-shape

return 1.0-step(.4,d);//也可smoothstep(a,b,v)模糊锐边
}
void mainImage(out vec4 bg, vec2 P){P/=iResolution.xy;
P.x *= iResolution.x/iResolution.y;
bg=vec4(0,0, ply(3,P), 1.);//左中 蓝三角
}
// 这个我没法注释,因为SL图形和数学几何关系大。有的时候看不懂也不是因为故弄玄虚,而是那个领域本身难懂。比如我define v1=float 和rld仨变量变 degRee(不用a因为编程有数组要命名),length,distance 后对第三块代码难度影响不大,因为核心不是浮点有几个字

(不过要画三角分形就会难许多了,而且Xe的游走三角是靠边点累积来的,SL不支持累积..)
可以看出,物理的矢量是非常高明的代码复用,少做了很多结构性的事,却照样实现图形效果,而且更可调参——例如靠点集计算就做不到 ply() 边缘模糊的效果
duangsuse::Echo
#plt 呃,这几天眼睛有点疼,那个网页重构也接近尾声了(目的就是交个PR),马上把雄狮扭眼的”热度蹭完“,我就能开始二进制pybind了 ……但是到2月我就必须开始制作一个H5动画礼物,以现在这个效率…… (而且之前说的 Java 入门又鸽子了,尽管对话框和离线javac的问题解决,其他内容还是需费精力 说真的我没一次蹭上国内热度,因为每次都是我趁机学了些”没用的“(比如彩字符画、粒子动画、MBR程序、C指针和数组啦),然后数据不好看 😂 这次也是一样,我用shift重映射圆心距l=1~len 环上像…
谈谈命名问题。圆座标系(POLar)上,角度和距离一般称 theta-rho , angle/arc-radius 即a-r,这是物理采用较少的几个希腊字
我的物理命名法则用 rl:rotation-length 表示这个,因为编程上a理应代表数组..而一些人也会用r标记角度a记面积 真混乱

对同一个像素图,可用直角(xy)和圆座标(rl)自00点等效描述其上每点位置(座标系的意义就是编码位置),这样就容易进行变换,例如圆翘曲和拧转
->rl=(atan2(x,y), sqrt(xx+yy))
<-rl=(lsinr,lcosr)

画半径=3圆就可用点迭代式(参数方程) lsinr,lcosr (r=0~2pi, l=3) ,这等同于在pol系生成一堆点再映射到xy系。当然位图上不好确认dr=rStep ,所以可用 length(p-p0)<l, r=atan2(yx) 处理圆内点。这个yx是配合 (lcosr,lsinr) 顺序的,具体为啥正弦反在余(co-)弦后我不清楚(补: 因为数学把 正右作0点, sin,cos 的00是正上

比如,笛卡尔心 rho=1-sin(theta) .极座标式 r=a*(1-(sint)) 直座标式 (asint,acost)-(.5sin(2t),.5cos(2t)) t=0~2pi

#define pol(f) float r=atan(p.y,p.x),l=length(p);f;p = l * vec2(cos(r), sin(r));
void mainImage(out vec4 bg, vec2 P){
vec2 p = P.xy/iResolution.xy - .5;
p-=.1;pol(float d=(1.-sin(r))/3.9 -l) bg = vec4(1.,step(d,.001) ,1.,1.);
//pol(l=l*l*1.5)bg=texture(iChannel0, p + .5);
}

为啥笛卡尔能画出心呢?在 funcplot.com 画 1-sinx (即-sinx+1)和 x=2pi 和y=1,对照 r=1-sint 你就能找到答案. 注意数学pol系是从正右逆时针算弧度..天哪 难怪 r=1-cost 是向左的

附带物理命名法表/补上次的:
Array B-paired Config Distance Element Func/File-path Graph
h w y x/item i j-i内i n m-n内n Key/比率 Value Length
Object Predicate条件 Question真假 Rotation弧度 Str/stream Text/template模板
u-二进制 z-深度

记忆法:26字母背一遍,把符号配对就行了: hwyx (h)ijnm (ij)kvl (uvwxy)z,你会发现 for(y in 0..<h)for(x i 0..<w) 正好和 y=i, x=j 对应
duangsuse::Echo
#math 上面 ai.Xecades.xyz 的数字识别用了卷积网络:(另外 #life 我恢复了。明天交了页面就又继续修补JS最简解释器了,添加更多数据类型、解构、?句和表达式宏、中缀式 其中有一句 ab点积(移动做内点积就是卷积): let c = MatZeros(a.row, b.col),i,j,k; for (i = 0; i < a.row; i++) for (j = 0; j < b.col; j++) for (k = 0; k < a.col; k++) c.data[i][j]…
呃,我觉得这位和顶楼的工程式讲法比较好:
在输入信号的每个位置,叠加一个单位响应,就得到了输出信号。
卷积的重要的物理意义是:一个函数(如:单位响应)在另一个函数(如:输入信号)上的加权叠加。
^”书上先反褶再平移,把输入信号当作一个整体(去翻转平移相乘积分),一次算出一个时间点的响应值;而楼主把信号拆开,一次算出一个信号在所有时间的响应值,再把各个信号相加。两者本质上是相同的。

顶楼:
令f(t=1) 衰减是种卷积,如t=1敲锣,锣面震幅随 tNow-1 衰减。接下来 1.2 ,1.4s 也有同样的敲锣。将它们叠起来就成了系统的输出
无论多么复杂的输入信号,我们都可以将其分解为一个个连续的冲激信号

用符号'*'表示卷积,关系式:输入*系统=输出。上面的图2在t=0.4s时的数值,是由图1中蓝、红、绿分别对应的3个单位冲激响应相加得来,
蓝、红、绿3个信号进入系统的时间分别为:t=0s,t=0.2s,t=0.4s,仔细观察,在图1中3个冲激信号对应系统响应的值分别为
系统响应在t=0.4s,t=0.2s,t=0s的值,对应的时间顺序刚好相反(因为.4s时0s 的还没消失),所以要翻转

😅不过有件好事:在计算机图形学 #cg 上 Sobel 边缘检测和各种锐化/平滑 都是无关方向的,如果只是 dot 乘积(各位之和) 其实就是普通列表处理;需要处理声音和图像不需要理解信号处理 #sp 学的术语概念

我想起了滑动平均拨弦声
https://tinyrave.com/tracks/67/remix
#js #code audio
kPluck = 470.0 ,
a = Array(44100 / kPluck >>0).fill(0);//FIFO frequency
a.forEach((x,i)=>a[i] = Math.random() * 2 - 1)//white noise
cyc=(a,i)=>i%a.length,
runAvg=f=>T=>{
let i=cyc(a,T*SAMPLE_RATE>>0); return a[i] = f(a[i], a[cyc(a,i+1)])
}

buildSample=runAvg((a,b)=>(a+b)/2)

当然音质差也可:
kPluck = 470.0 ,
a = Array(44100 / kPluck >>0).fill(0);
a.forEach((x,i)=>a[i] = Math.random() * 2 - 1)

buildSample=T=>{//没平均相邻
let i=T*SAMPLE_RATE %a.length >>0; return a[i] = a[i]/1.01
}

卷积核就是权重,#AI 学习的正好是权重,把权叠到每片像素,所以图片分类器能学习出核的特征,对识别项求和后判断归类
在每个xy 叠加卷积核,就得到输出颜色/灰度 等信号

应用于位图参考 https://zhuanlan.zhihu.com/p/76606892
shadertoy.com/new #GLSL #code
#define v1 float
v1 lumAt(vec2 p){
return dot(vec3(.2126, .7152, .0722),//亮度
texture(iChannel0, p.xy / iResolution.xy).rgb);
}

void mainImage(out vec4 bg, vec2 P){
vec4 c = texture(iChannel0, P / iResolution.xy);
v1 gx,gy, d = sin(iTime * 5.0)*0.5 + 1.5; // kernel offset

// Sobel Kernel
//x
// -1 -2 -1
// 0 0 0
// 1 2 1
//y
// -1 0 -1
// -2 0 -2
// -1 0 -1
#define k(x,y,P,a) v1(a)*lumAt(P+vec2(v1(x)*d,v1(y)*d))
gx=k(-1,-1, P,1) + k( 0,-1, P,2)
+k( 1,-1, P,1) + k(-1, 1, P,-1)
+k( 0, 1, P,-2) + k( 1, 1, P,-1);
gy=k(-1,-1, P,1) + k(-1, 0, P,2)
+k(-1, 1, P,1) + k( 1,-1, P,-1)
+k( 1, 0, P,-2) + k( 1, 1, P,-1);

v1 g = gx*gx + gy*gy;// denoise in the video
v1 g2 = g * (sin(iTime) / 2.0 + 0.5);
bg = c+ vec4(0.0, g, g2, 1.0);
}

lum滤镜 . 这次让我学会了位图擦拭渐变外 的边缘和模糊 以及边角画扭曲 💭视频粒子特效可能需要
我这里还有个中心模糊的:
#GLSL #code https://www.shadertoy.com/view/4ts3Ws
float amount = 5.9;

vec3 shadow(vec2 P){
return texture( iChannel0, .5*(sin(1.)+P) ).rgb;
}

void mainImage( out vec4 bg, vec2 P){
vec2 pC = -1.0 + 2.0 * P.xy / iResolution.xy, p = pC;
vec2 dCopy = (iMouse.xy/iResolution.xy - pC ) / amount;

vec3 g = vec3( 0.0 );
for(int i = 0; i < int( amount ); i++ ){
vec3 c = shadow(p);
g += smoothstep( 0.0, 1.0, c);
p += dCopy;
}

bg = vec4(g/ amount, 1.0 );
}
#code #cpp 🌚👍 应该进疫情贡献博物馆陪着支付宝健康码?!
#define FOREVER 0 (exit值) 这人估计是个反串黑
return NEVER 可以理解为永远跟党走,但 return forever 就是一直倒车的意思 👌🏼🤡

中国很悲伤的地方,就是反串黑和无脑挺分辨不出来,「清风不识字,何必乱翻书」呢。
https://t.me/dsuset/10243

原來暖心小粉紅們的自信,是需要靠別人歧視他們体会出來的。❤
--https://m.youtube.com/watch?v=3VqT-uxt2Ec
“公開場合有權利拍任何想拍的人‘’跟“罵人是我的言論自由‘’一樣暖心。
不是说了sorry we have a break...個人有權要求不被拍攝。

到底有誰嗆人的時侯會說,我是哪裡人啊?
用其他種族的名義 侮辱別人,然後又要所有亞洲人站他們那邊,中國在給全世界製造仇恨真的是第一名欸。
duangsuse::Echo
#blog #meme 看到易语言还在VB++ 的范式旁徘徊 😅,并且觉得编程语言 是种必须特色和备案的「核心技术」… 我想复刻下这2007年文章的口吻: “绝句.ju”十分钟入门教程 作者:转载必须注明出处 亲爱的朋友,您愿意花十分钟的时间,来了解一门全新的编程语言“绝句.未公开”吗?(搞笑向 btw. 很难想象标准库与ES7接轨,拥有函续、不/可变数据集、流/叠加、双主语的绝句,还能用“合规”的记法支持VB7时代的“正统中文编程”👀 - 起点 将123写到屏幕 100.123:[x] …
#zhihu #PLT 又看到有趣的中文编程设计 ,做些科普。 👀

1.打这些太极 还不如就叫真假,另外,加语法糖并不是以混淆基本语法,以编程的一致性为代价. PHP,Ruby,Py2 和VB已经玩烂过这套“大小混写”了(你怎么不用神奇GPT编译呢?)

2.子类型对应的是强制兼容,而非隐式数值转换。 进制只是表示法,SQL那种类型只是验证位数
你说的不需要看(隐式新建类型变量)、运行时可见,Haskell、Kotlin也支持,但你对连 List<T>,T->R 都还没懂的人弱化类型,就利于他们学用新接口了?别把隐类型当成无类型

3.其实,只要编码统一,最常见的bytes.replace和非空split都OK多字节字符。即便你想像Perl那样囊括万物,得出的语言可能就是一个Str运算的节点图
4.GC引用和Str/Builder的隔离不就是? 你还混淆了编译期和int*两期变量绑定 (x86 ABI -O0 就是用esp-4-8栈指针传参的, vararg 就是靠这个)

5.JVM每天都在跨线程 (volatile Object)vars=新引用 ,C#还支持并行For,numpy 则支持GPU,SIMD ,为什么要把废话说得像真理一样啊啊啊..

6. #define str char* 后 str a,b; 你就会发现C的类型运算符本身有问题
另外,int(int,int) add 不适合写类型推导
7. 文字游戏。 add(a,b,&c) 的汇编叫无副作用?
C有函数指针啊,而且Linux还用它“实现OOP驱动”了
只是没 a=>new(b=>a+b) 闭包对象而已,C的落后并不是只在写法上,是GC,API,types,memsafe 的全面不足,但是把C的错误当宝就是程序员的问题了

另外 看见贺老锐评#js 函数式提案,发现很多都被现在的EQ设计过了…

Iterator helpers
[1,2,5,1].Q.firsts(x=>x<3) //基于waitFun,故同时兼容 [],func*,async

Record&Tuple
when(class{
User(name){表单验证}
})

Stage0:ADT Enum, tail calls
when(class Either{ //EQ继承很多绝句里的语法
A(v){} B(v){}
})
noOp=(a,b=0)=>nest(b=>{
if(a!=0)loop(a-1,b+1)
})


Stage1:Observable、Emitter, Extensions, Partial application,Pipeline operator,Memo
前两个是 obj.it.xx 的核心特性
user.to(_=>{name="Jack"})
Str.it({
cap:_=> _[0].toUpper+slice(1)
})

compose管道也是

num=(a,b)=>a+b
it.n([num.it(+1), x=>x+'%'])
is.ST({num}) //memo


模式匹配,不就是EQ的基石嘛
when(res,
[{status:200,body}, body!="", fn(bodyVar)],
[Some(x), x],
[None, 0]
)

「前人造过的轮子就有点像是数轴上的有理数点:稠密,有序,无穷无尽。但是真当你用的时候,你会发现,你的实际需求有着几乎100%的概率落在有理数的缝隙里。」
duangsuse::Echo
#math #web 看来想完成EqvJS的设计,还要简化自己之前的许多作品里的技术 (图: easing 曲线, Svelte ease-out 代表先快后慢 #apple #tool Epic Easing - easings.net - animejs.com #dalao https://lisyarus.github.io/blog/programming/2023/02/21/exponential-smoothing.html#:~:text=speeds%20up%20naturall…
This media is not supported in your browser
VIEW IN TELEGRAM
看到个有意思的, #android 夜间切换特效
>GLSL https://www.shadertoy.com/view/4sBfRd
#define circ distance(P,iMouse.xy)
#define swing(x) cos(.5*(1.-x)*radians(180.))
//混成AB两版的main, 对B版用圆选区, transition: --len_vw 4s ease-out
void mainImage(out vec4 bg, vec2 P) {
_mainImage(bg,P);
bg=(circ< swing(iTime/4.)*iResolution.x? bg:1.-bg);
}
背景也可以是波浪。忘记 sine scroller 的关键词了 🥰

用HTML-SVG 做的话,在clone出的 #app.dark 上剪裁 clip-path:circle(var) 很方便,但如果想用更灵活的mask:radial-gradient(var) 就只能靠自定义filter了
但无论如何 都比canvas或paint的方法好移植且快

Android上,深色主题如果是靠bg/fgcolor 切换,除了 transition: 不是一等公民,需要自己填Animator

还有复杂的自定义“复用”Recycler.View失效问题 🥰 而 clusterize.js.org 呢?往table调一个函数就能优化,安卓那种复杂度,对它够支持瀑布流了

可能,还需要手动setAttrValue 什么的

H5里做排版的XML,安卓做style
H5里做交互的JS,安卓做排版.. Compose 等于是简化下HTML的语法,却硬是让View框架被“重新定义”了
H5里自带的Web平台API,安卓靠Gradle.. 依赖地狱什么的这不就来了?
duangsuse::Echo
#cg #code 国产剧《点燃我,温暖你》/110w 里面的一个桥段,天才程序员男主李峋期中考试中完成的爱心代码 效仿评论区就自己写了个…… 另外GL里字体/for循环是较难的 float heart(vec2 P) { float t= mix(.3,.8, mod(iTime,1.2)),//心跳 r=pow(P.y-pow(abs(P.x),t), 2.)+pow(P.x,2.) -1.;//灰度函数 return r<.3? mix(1.,4.,-r) : r; //黑心换白心…
#cg 用了半天AI都不能创建一个shader
纯frag shader 要想画粒子特效,只能用vec4图片编码vec2 来模拟gl vertex (本质是全局数组 https://stackoverflow.com/questions/48384564/webgl-glsl-time-variable-similar-to-shadertoy)
https://www.shadertoy.com/view/Nty3D3
GPU 每个线程只1个rgba矩阵可变,禁止手动for(;;)全局变量。 GLSL设计的这么僵化,还不如numpy和taichi呢
GL人都是作品靠试错就摆好了,即性粘贴型画师,比jspy还复用白痴 😅可见编译太快联动性会变差
包括Unity等有建工程的
其实是不配称程序员的,和gpt一样 代码没有复用度,全是脚本 用完即弃
但是数学家和物理学家就是这样,不重视自顶向下 复用

https://developer.mozilla.org/zh-CN/docs/Web/API/WebGPU_API#:~:text=像素的颜色
pacaur -S intel-media-driver libva-utils
后访问chrome://flags/ 查看支持度

>编程用 frag Shader 绘制爱心跳动, 心形的内部是白色, 背景是白噪声
>create a 2d ball particles collision demo in ShaderToy
> update BufferA & mainImage separately; note: shaders won't save state
它只会用 matplotlib画..
不过,圆角矩形什么简单图像,AI依然是有可能写出的。需要几个宏

#define time iTime
#define resolution iResolution
#define main mainImage( out vec4 gl_FragColor, in vec2 gl_FragCoord )


> 用 re.sub 去除 "www.bilibili.com/?" 这样链接的 query参数
qwen 实在是太逆天了正则 match group 连AI都不会弄
脑残 我是说全文替换 该死的垃圾AI被双引号骗了
"http://baidu.com\n".repeat(2).replace(/http:\/\/(.*)/g, "ftp:\/$1");
#code #cg #apple 等待光标 🍬 https://www.shadertoy.com/view/XljXzV

#define hsv(c)  ( (c).z * ( 1. + (c).y* ( .6 * cos( 6.3*(c).x  + vec3(0,23,21)  ) -.4 ) ) ) // golfed

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
// Position normalised into (0, 1)
vec2 P = fragCoord.xy/iResolution.xy, M=iMouse.xy/iResolution.xy, d = 1.0 - (P * 2.0);
// Rotation
float L=length(d), r = acos(d.x / L) / M_PI, lv=M.y*50.;
if (d.y < 0.0) { r = M_PI-(r + M_PI); } // Sort out the bottom half (y=-1)
r+=sin(smoothstep(-M.y,M.x*2., .9*L));
r = floor( (r)*lv)/lv;
fragColor = vec4(2.*hsv( vec3(r/2., 1.0, 0.5)), 1.);
}


带夹层
// Position normalised into (0, 1)
vec2 P = fragCoord.xy/iResolution.xy, d = 1.0 - (P * 2.0);

float r = length(d), a = atan(d.y,d.x)/ 2./M_PI;
a+=cos(.6*r);
fragColor = vec4(hsv(vec3(a, 0.5 + 0.25*sin(iTime*a), 1.0)), 0.5);
duangsuse::Echo
补一句,为什么我那么在乎readXX() 首先,当然是它余缀了,Reader模式、Visitor模式需要加固定前缀是哪群大师教的?? Qt,luaY_parse 都没有这种文明 至少对 enum Op{Add(Op,Op); N(i32)} 写 visitAdd 的人绝对是py ast看多了,overloads不会用。 Java比C最主要的优势就是Type2namespace,居然有人主动添加余缀? 然后,是对编程界毫无进步的无奈。 我最初学编程时(8,9年前吧)改了一些c#小游戏,当时有 https…
duangsuse: #读写线 #bin #FP #algorithm
1.所以我认为这种partial是错的,比如lexer吧,至少把Node的wsPre 保留下来-比如对注释文档,这样rust fmt/doc也会好写很多。

2.你举得例子太tricky了,而且JSON就不是一种minimal dynKV- 它有一大堆无效的;, 需要过滤

3.内存buf问题应该交给linux swap处理,而且用 fit(inoutT参数) 替代read():T 并不会阻止windowing

4.所以只要在pull的回调里注册onmut,就能免费定义出writeback(),当然实践起来确实没那么简单

duangsuse:
冷知识: int** 可以被scanf读取

C是存在静态数组的,i=0..sizeof a/sizeof int
https://blog.csdn.net/GGN_2015/article/details/119902369

我们可以确定一个共识: readXX() 的本质,是通过ret和赋值stack var把file的一部分加载到mem的KV乃至于[]里,这也是为何libc的tcp和inode都是 iostream API --以及为何会jspy的人不懂C移植

因此,虽然它叫IO,却被框在call-return并赋值、 forEach-call并write 的枷锁里,明明只是asn.1那样的databind手段,却被递归下降的样板代码给框住了

但这种模式在C里,就是struct,set_type和set_size的递归下降,可以靠os的vm功能缓存、1次读完 mmap():bytes,当然任何新语言都没有直观对应出这个

如果有些struct var 是不需要读的,完全可以用 isDbg: 来mock自己读到了,然后不实际赋值,反正JS是动态的

对了,你觉得为啥js版bytes(blob,abuf) 都不提供流API

难道它是想让用户手写py structs那样的封装?

py有cString,jvm有Reader,js没有byte流接口;那就是只想read一个二进制header喽?

TextDecoder那个啊,感觉java味大
尤其是async*() ,不得不用State(var)取代吧

https://developer.mozilla.org/en-US/docs/Web/API/Streams_API

最大的功能就是补丁fetch()和onrequest ,其他和WebSocket重叠了

duangsuse:
额。。就是讲用回调的人为何被coro不明觉厉到了,呗

Object的本质就是可扩展的fn.bind()
打包好避免难传递

用回调的人根本没有错,错就错在coro.then为什么那么间接,还没人解读

不同的OOP还是有区别的,虽然大家的实质都是在提供参数N->1和if typeof 这些CLOS都懂的函数式风格的技术

但Java对closureArg 样板化的支持(通过重写和重载)更好,这也是为什么MBPC classdef比lisp的defclass有意义
往大了说语法差异都是没有意义的,无非就是alloca和malloc、递归下降、流水线这些算法嘛

另外,这还有个魔怔的中英emoji双语嵌入式编程支持原型链 def T.class(vars):ret{}

https://gitee.com/chen-chaochen/lpk#https://gitee.com/link?target=https%3A%2F%2Flosu.tech%2Fplayground
Forwarded from dnaugsuz
哎,没有心情看 #kt #book
看了下codegen技法,只能说近十例子里anko的风格相对优越,和html一样是用twig(类似erb)模板,然后作者函数复用还行,但也没有到90分的程度。

例如“贯穿全文”的DeepCopy(x:T)吧
js里相当于x就是T的反射,又一切皆可变,可以直接读写{...x}[ID], 只需
mapEachMember{if(it.isPrim) it else DeepCopy(it)}

kt里需要用构造器复制,先拿到 T.vars[ID].get(x)而非 x[ID],但依旧是 mapEachArg{getattr(x,it).primOrCopy} 的模式,这个至少适用于 Tuple$N的toMut和url参数绑定
这就是个小学算法,反射和List API 的良莠不齐却让它很难看。

重要的是独宠XXpoet 真的无力吐槽,和那个 https://t.me/dsuse/17514 一样,就一个不用导包,然后自带formatter。简直可以说是一碟醋级别的算法,甚至应该叫搞错重点

和我的tkgui https://t.me/dsuse/19768(py基于getattr等元编程,运行期生成等效调用赋值图代码)
都没法比,何况最近我在设计表达式级(fun{}内计算图)都能建模的跨语言、带裸类型推理、动静合一OOP元编程范式了,这种拙劣的"xml模板"实在写不起来

java确实是“病态类型”,而非什么静态检查。 连数据树的验证和walkDeep都要靠魔法,有什么资格谈类型签名的那些好处?
靠被默认值参数替掉的重载吗?

只能说,如果手头有电脑,我应该去吧那个sql dsl写了😒 而不是在这看java人像手写sql或xml那样拼接字符串
不知道 unquote(ast) 这种函数式代码生成,起码吧 quote(litOrID)做一下,免得被注入弄出无效代码啊

再说说全书结构,首先就没有谈元编程是什么,而是java老三套:环境配置、难题、抄代码

好吧,可是一个优秀的老师应该选循序渐进,但却对知识体系至关重要的例题: #learn #plt

- 为什么是靠C的#define 自主研发出易语言?预处理比str.replace多了哪些? 高亮分词后,灵活解释“常量字面”吧
> eval("[1,$x]") 是一种JSON解析器,可是x="][0]"时似乎有bug。 修好它,然后把js爆改为你希望的“易”语言(复用猜数游戏的REPL)。 完成后类似的bug应该仍然存在!
其实,js源码也有它的JSON.parse,它就是反射的原型。
- 比较下SQL的'?'、C printf、ERB/ES6模板,kt元编程最缺少的语法为什么反而是"$str"? 控制变量,就能明白pwsh和ts为何比bash和js有长期编程时的优越性

- if os==nt6: class: 与#ifdef _WIN7 凭什么是同构的? 动态类型,依旧是Java式的类型。宏,并不需要魔法
- 为什么Java8让 invokedynamic负责创建lambda,getMethod不也能.invoke吗
- 局部fun 一定要 ::引用的背后,藏着一种元编程,T.(A)与(T,A)->、(T?)!!的强转背后也是! 原来除了消除重复,她还让语言提供更有价值的“值类型”
- 为什么“闭包是穷人的对象”? C语言里回调函数去哪了?SAM接口又为何比到处new.object{}流行? 原来返回函数、重写接口也能费内存啊

- 为什么pyjs里很少人研究元编程,但却又有 python-future.org 与vue,babel这样的全民应用。 二者有何区别
- Proxy(obj)掉包属性,是动态类型元编程的专利吗? reflect.Proxy 能生成函数,还不止于DSL或AOP!
- 能不能通过函数重命名,用py风格的反射API实现KAPT的 @decorator ?哪怕只是封装Reflect?这能让你学习跨平台移植,收获超越本次需求的心智模型和视野
- Kotlin对dynamic类型表达式链条的“零修改”生成规则可以怎么实现,numpy里也可以吗? 这能帮你理解DSL和编译优化的本质

- “优秀的程序与其读写数据的结构直观对应”。纯函数式编程(例如rust的enum和if let) 做对了什么? 为什么你仍然选择不够纯的Kotlin? 这种enum能表示JSON乃至HTML的序列化结构。
- bash风格的参数有3种,其中一种如 ls -ar(all reverse) 传入enum:BitSet。用fun demo()出完整函数签名
- 以上问题和codegen无关,也没有教你具体怎么生成url/json/sql绑定类或函数,却给你了设计相关框架的能力!这次由我来回答,为什么javapoet是对pyjs里闭包list/dict的拙劣模仿,以及反射调用为什么就是在codegen!

所以。。 虽然《Ruby元编程》教你的只是一些OOP特性的“工作原理”,而案例较少,但我更喜欢它 --它让读者真正建立起了对"class"这个dict的理解,加上dyn(*arg,**kw) 本就可以用名字动态查,让读者对“把def和class 视为一种constObj去查询、实现复制粘贴、...”有了把握

而不是一个看似什么搞法和IR,ASM都贴出来了
实际上对你没有用,只是让工作失去焦点的troublemaker🌚🌝
👍1
duangsuse::Echo
#rust #go #algorithm UmbraString 是对带长度指针(py.bytes, rs.slice) 的(免链接inline),而 SwissTable 是对Hash预分组查表的免链接! 我们知道,Java 存在(装箱boxing) 一说,也就是int,char等字面值的堆分配 (这是泛型擦除 vs template<>化新建的编译期细节),因此JDK8用class Stream.OfInt{}缓解了reified泛型的缺失 那么,(拆箱unwrap) 其实就是在值的内存上内联,像C++栈分配。…
#algorithm #防自学 🤓 让我来示范一下怎么概括算法思路
要介绍的是在stdlib里,用于组织集合类、JSON的3个重要结构: b"ytesPtr", {K:V}, sorted([0 2 1])=[0 1 2]
它们对各种app和其他算法性能效能的重要性,好比json(cbor.me)之于REST、zip之于jvm和pip。 因为是涉及SDK实现的内容,也主观评价下语法设计

下面用胖指针(x64上void*是8b, 胖指16b)、链表、快速排序简单的实现3者 #code
#define Col(...) typedef struct{__VA_ARGS__;} T;

#define T Str
Col(size_t n; char* buf) //C的类型本应默认为指针, *胖指针,像kt那样对Int等类型免链接化。简洁的UNIX里,Type* 快成为public那样的形式主义啦

#define T_Link(E,T) struct T{E x; T* xs;}
T_Link(int,Nums) //template<T> 允许类型推理,即一致化调用和返回处的<T>。可怜gcc/clang无论对宏还是模板的报错皆如内容农场,不具有可读性

https://colobu.com/2023/06/29/replace-std-map-faster/chunk-index-memory.jpg
用例和 #haskell #code https://gist.github.com/duangsuse/26b80c39e1d8f7549b9cf244d8de1ce4
题外话,闭包值和 x.interface_cast(T) 的双指针&dyn 随结构传入T的函数表
qsort :: (Ord a) => [a] -> [a]
qsort [] = []
qsort (x:xs) =
let smallerSorted = qsort [a | a <- xs, a <= x]
largerSorted = qsort [a | a <- xs, a > x]
in smallerSorted ++ [x] ++ largerSorted


UmbraString 和上文Str{n,buf}胖指针一样是16b,但它的.n和jvm一样只寻址[4b:int]的长度,其后最少随4b的免链接char 用于比大小
对于n>12的buf,剩下8b换成指针,指针的高2位用于标记GC信息: 持久pin、临时ref、用后即焚val

很明显!这是一种灵活利用了x86内存布局的b"length"实现,和x32压缩指针一样,节省了sort解指针的时间

SwissTable 是对Hash预分组查表的免链接。我们知道, dict/HashMap/lua.Table 这样的{K:V, K1:V} 单映射常被用于查找和缓存,在C++里更是会区分 unordered_map, rb_map(以排序radix,SortedSet,而非hash作为预分组线索)
它的最简实现是lisp里的链表 T_Link(struct {int A,B;}, int_LnKV) :没留任何线索来减枝!

即便8b hashCode,也是一定会冲突的,哪怕是int.hash也会因 buck[hash%nBuck] 有限而退化为线性查找,负载因子(kv/nBuck 过大),这时就要扩容。Go的扩容基于一种空间换时间的优化(图1, 为了减少求余数的冲突,除数都会采用2的指数)
扩容后的冲突集,可以用链表(UnionFind)或数组(slot), 从那往右找
Swiss 更聪明,它对每slot对应1b的元数据,最高位0x80=无效项 ,0xFF=null结尾 ,低7位用于存储hashcode的高7位,这么摘要是为了SIMD128bit 1次对比8个KV
不仅仅只是CPU CACHE友好,这样的结构配合原子操作,相信很容易做出一个并发版本的hash table

快速求余(x,n)= uint32((uint64(x) * uint64(n)) >> 32)
#dalao https://init.blog/fast-newton-sqrt/
float InvSqrt(float x) {
float xhalf = 0.5f*x;
int i = *(int*)&x;
i = 0x5f3759df - (i >> 1);
x = *(float*)&i;
x = x*(1.5f - xhalf*x*x);
return x;
}


最近的一种基于partition(区间而非idx)的快排也很有趣: less than pivotL | between pivotL and pivotR | greater than pivotR
duangsuse::Echo
看最近几条逆天,我要聊哲学 #CS 操作系统不就是4片3口虚拟化么 时间内存存储程序,网口线口板口 #os #plt #embed #recommend win,*nix,mac, aosp ios ;哪个不是只有这么点API和差异化 🦄?为了音视频和回应事件弄那么多框架外链新语法,不如3行 #web js。 像 bellard.org 那样的通才终究少数,搞出\0结尾无长度字串,连{}[]{type:}都没建模的libc算什么API啊?在位运算位flag上都被人打败 也配教人数据结构算法? 。 为这…
#FP #c https://github.com/hirrolot/datatype99/blob/master/datatype99.h macro
https://halfrost.com/reactivecocoa_macro/

tag union: enum { A(int) B(str) } in C 😨 无需任何编译器插件
implemented upon Boost/Preprocessor
冷知识: gcc 宏是可以通过CPS延长递归展开 到1024步的,而宏又包含 if defined/eq 等常规流控与##-concat等运算,意味着即便没有 template<> 魔法, for if 甚至 eval() 也可以 static_assert
// 9, 2, 5
static int lesser_than_10[] = {
ML99_LIST_EVAL_COMMA_SEP(
ML99_listFilter(ML99_appl(v(ML99_greater), v(10)), ML99_list(v(9, 2, 11, 13, 5)))),
};
// 用例: 1+(2+3)
datatype(
BinaryTree,
(Leaf, int),
(Node, BinaryTree *, int, BinaryTree *)
);
int sum(const BinaryTree *tree) {
match(*tree) {
of(Leaf, x) return *x;
of(Node, lhs, x, rhs) return sum(*lhs) + *x + sum(*rhs);
}
}


ML99 是一门在 C99 预处理器运行的lisp https://metalang99.readthedocs.io/en/latest/list.html
尽管如此,有大佬说「元编程」要三思 https://lotabout.me/2018/think-twice-before-utilizing-meta-programming/
btw. 看到文心一言禁止F12, 有人贴了个反制 很有意思😂
for (var i = setTimeout(";"); i-->0; clearTimeout(i)); 


利用宏展开和递归实现貌似不可能的链表处理,其实也只是手段巧妙,利用f.nArg这样的const拼接代码, 效果并不会比过程宏甚至简单的codegen好
#define AND(X, Y) AND_##X##_##Y
#define AND_0_0 0
#define AND_1_1 1

#define IF_ELSE(C, T, E) JOIN(IF_ELSE_, C)(T, E)
#define IF_ELSE_0(T, E) E
#define IF_ELSE_1(T, E) T

#define IF(C, T) IF_ELSE(C, T, )


我还是觉得,如果不限制工具链,编译期反射或运行期记忆化eval 比模板巧妙的多。 体操只是被编译器驯化的结果而已,比递归+模式匹配巧妙的算法有很多。

https://github.com/hirrolot/datatype99/tree/master/examples/derive
https://github.com/orangeduck/CPP_COMPLETE
https://netcan.github.io/2020/11/06/C-Rust元编程之BrainFuck编译器(constexpr-过程宏解法)/

n=a=>a.length
add=(A,B)=>A+B
curry=(f, N=n(f)-1, ARG=Array(N).fill('').map((x,i)=>'_'+i) )=>eval(`p0=>(${ARG})=> ${f.name}(p0,${ARG})`)

curry(add)
p0=>(_0)=> add(p0,_0)

完全有能力生成任意的vararg,并且可以加泛型
另外,我刚又又设计了一种新的元编程方式: QuineQuoted (馈硬是一种 eval(s)==s 的测试,它和FP系的ast宏还有点区别: qq需要编译器支持, QQ自己就是编译器) #plt #kt
https://github.com/mame/quine-relay

我几年前用这类技术弄了Tk的DSL,forin展开 https://github.com/duangsuse-valid-projects/TkGUI ,但没有意识到值:名替换 是把运算符重载变成编译器的要点 : 首先 kstSel=Fn(2, ([A,B])=> KST? A:B ) 就可以用read自源码+值名替换 生成出 "(A,B)=>{" "A" "}"

想必是比XML魔法优雅不少吧……

这样Kt的循环展开可以这么写:

val [T Array].constFor = F.PASTE { op: (T)->pass/*[T pass F.n1]*/ ->
indices { i -> quote { op(`$`(this).get(i)) } }
//(this as KtScope).quote "op(x1.get(1))"
//(this as KtScope).quote "op(x1.get(2.. ))"
// str += " inlineOp(${arr}.get(${2})) " 是否和 quote { op($this[i]) } 雷同? Java STR|SQL. 提案的真正面貌来了。
//也可以来return repr(字面量均可序列化), inline("bin/file")... 宿主有多强,宏就有多强。不在五行之中,却不会生成非法结构
}


看起来相当简单,而且和Proxy({}, {get:genFn}), 和lang.invoke属于同款! 但是,因为能处理左值,创建函数、修改class{}字典也是可能的。 运行时反射,编译时留字面,运行即编译,但比起JIT所有不知名的「编译优化」,eval后留字面可不是魔法,只是元循环函数而已,就像numpy和taichi 的"C DSL"
Quine比之poet等EL就像SpringBoot比SpringXML一样, 不需要切出本语言的思维,就可以突破 o.key() o."key"() 的隔离, 避免了人们关于「静态类型」一直以来的一个很大的误会
但我就从来没见「最佳实践」们用过…… kt 在用仅能自动import而且个性贼大的poet。 lombok 甚至重造javac的轮子,就为了显得自己懂栈字节码了
和我那个拟态类型不谋而合,相信再强化下反射API,很快就能替代TS了!? 🤔
val $T_Array.constFor = F.PASTE(n=1) { op:any -> when(var T,){ this typ([T Array]) && op typ([T pass F.n1]) -> pass
else -> TypeError("某些人觉得很厉害的编译原理和OOP,唉,还是比eval和原型链棋差一着")
//把for/if 这些函数的语意,重载成只执行1遍/2侧都执行就够了, 这是Lisp说的道理:语言们没什么语法,只有传参法、求值序、回调或栈的区别罢了。 类型检查和webpack什么的,何必呢,直接在编译期黑盒测试:TDDtc调试运行即编译!
//Kt 不太能按inferDFS(T)分重载,你 val=::print 就一目了然,方程的形式就只有 {T:?0, R:?1} 这样的解构匹配而已,却卡的要死,真不懂是JVM拖了K2的后腿吗? 还是某些预制人比起为用户着想,更爱虚伪的代数呢?
//因此以上代码已经是JB级别的 type inference 了,Prolog数据库的helloworld而已。 F(n1,T,pass). v(this,T,array):-is(T,any?),F(n1,T,pass). >>> v(变量名,...模板参数)

//btw. Kt 没 match{case+} 也不是大问题,如果支持真正纯函数式的解构匹配,怕是val和var语法和那高开低走的@Compose都要退役了。 Svelte的rune、C的返回到指针都不会抄,还真是仅此一家别的不看了
}}


Lisp也有类似的能力,Haskell系的 quasi-quote 准引用 ,包括Rust!()也是这个意思,不过它们都是简单的eval(comptime eval 又怎样?不成熟),甚至搞一些因为反射API不稳定、母语语法空洞而贫瘠,而使用的模式匹配重新造parser,还有递归限制
C++ template<T> 扩充的#define呢,类型体操(比如printf的静态检查)呢,也是这个意思,但它们非常丑陋,它们总是让上下游在 💩味的代码和代码味的💩间二选一,明明试图用解构匹配重新实现调包和# define就能解决的任务,还自我感觉良好,仿佛一眼概况程序的能力已输给AI,但只要Tab补齐的类型写对了,就能强化自己的正确率似的。 丑陋的黑魔法只会诞生丑陋,没有例外。

Quine就不一样了。它揭示了函数的本质只是复用了几个变量的计算树,和JSON一样是跨平台的, 借此允许我们审视和消灭重复的类型签名,创造更好的SWIG、rustdoc、lint、minify等工具,甚至是[拟态评判lityping]这样更直观的检查与推理
这一切都不需要魔法,它和Proxy+getMethod一样是自举的,可以在任何编程语言-尤其是在缺乏this支持(并且傲慢地唯独不支持this隐写)的pyjs里发生。 这是最重要的点,我的跨语言RPC新JSON需要这种codegen框架。 解决一种问题,肯定要把所有上游复杂性全消灭掉,对不对?
duangsuse::Echo
1752279094668.png
更令人作呕的是弥漫在圈内的“和事佬”癌变! 动不动就搬出“XXX没有绝对的对错”、“大家都有道理”这种散发着恶臭的伪辩证法。在文科领域,这话大概率只是空洞的屁话;但在以逻辑、精确、客观事实为根基的理工科,尤其是在编程这种非黑即白(UB就是错,概念混淆就是错,逻辑漏洞就是错)的领域,说这种话无异于当众排泄!理工科没有对错?那你还学个毛线?你写的代码是薛定谔的对错吗?运行时靠意念决定结果?

这种“和稀泥”的本质,就是用虚假的“包容”和“多元”来掩盖技术上的无知、懒惰和不求甚解,是对严谨精神的彻底背叛!“态度至上”的矫情 + “和事佬”式的无原则包容 = 国内技术圈最恶劣的双生毒瘤! 它们联手绞杀严肃的技术讨论:纵容错误: 为技术谬误提供了“免死金牌”——反正“没有绝对对错”,错也理直气壮。打击求真者: 让 mq白 这样敢于直言、追求精确性的人被扣上“激进”、“高傲”、“揪字眼”的帽子,承受道德绑架。培养巨婴: 让学习者永远沉浸在“我弱我有理”、“你说我错就是你态度差”的舒适区,拒绝成长。劣币驱逐良币: 最终导致认真讨论技术、坚持标准的人心灰意冷,沉默或离开,留下满地鸡毛和自嗨的“差不多先生”。这就是一场彻头彻尾的、针对技术尊严的慢性谋杀! 在这种环境下,追求正确、精确和深入理解,反而成了“异类”和“原罪”。

https://www.fxzhihu.com/question/582463239/answer/1921899702628103298


我在 https://t .me/dsuse/21408 吐槽了你最近那事

然后 int a[3]; 是不是指针?当然是,除了没人用的sizeof a!=int ,用起来不就是指针,☝️🤓一点也不好玩。
你要问我为何不是指针,我说,从语意上讲是「双指针」,slice ,因为读写时的性质如此,sprintf_s 也是如此。
两边都有解释,范式不同而已。

你被人喷时可以考虑改一下自己批评的方向, 正确不等于对,你要为C/cpp用户需求的功能点着想一下, 你讨厌谭学,那你自己批UB的时候就不谭学了吗? 你的文章也有脱离App谈C++的私货的

我不是说你的开源和工程师精神不值得respect,但你必须学着从科普的角度入手,而不是一直纠结语法特性X何时是UB, 你批判的问题点,你要给出working的最佳实践再比较, 没人听你干巴巴普法
>strict alias,你要问语言律师,什么是sa,他能给你讲得头头是道,以肉眼parser分析出你的代码有没有违反规则,如果违反了,会嘲笑你不知道乌贼有十条腿。
但是全网没有一个人讲清楚这玩意到底有什么用 😅,我们能从中得到什么益处,以及,我需要强制类型转换以及指针偏移时该怎么办——按照标准,linux内核链表是ub的。
按照律师们的说法,所有在2020年前,把int32转成float都只能用memcpy,所有2011年之前想用while(running)判断线程结束(volatile) 的都是错误。至于在此之前怎么写正确的代码,语言律师不会给你答案,仿佛在此之前从未有过多线程App。
—
你又不可能突破函数模型来组合程序,只要不是 #define / static T[], 你都不能用C sizeof 实现 forEach(a, print_D) 功能,所以a[]就是指针,API如此
“引用就是指针” 引用不可空,不可调整,是更好的指针,能在swap(A,B)上替代宏
我看见有人说 int a[2] 是 int a, a1; (int a**2); 他们是这么理解栈变量+指针的,这当然不规范,但C就没有operator[]和集合库,你说它是个二进制offset绑定语言,无关编程,也完全正确。 不要在一个错误的地方比较对错了,50年不变了

>你凭啥说我说错了?书上就是这么写的,数组名是指针,你比书懂?老师也是这么教的,你是啥啊?比我老师牛逼?我老师是还说看汇编,你看的懂吗?我老师可是教授。这书的作者可是清华教授,你有资格质疑吗?(一般不会一句话说完这些,这里只是全加在一起)
>一个18岁的人,能指望他懂什么?可以看出,他学东西“满满的高中生思维”,恨不得把整个cppref背下来,其实用处不大。
>热衷于当语言律师主要是因为没有能力当架构律师
>震惊,王垠还有低配版?我当初学编程,也是一堆语言律师教我在那边怎么写,就一个void main和int main能争论好几年
>那个个小圈子有点太抽象了,自称loser,确实了也是。我搞不明白,真正搞技术的谁没事整这么个b群,一个个整个loser的身份。感觉都是一群心智不成熟的高中生商业互吹。不如买几本经典书看收获大。
https://zhuanlan.zhihu.com/p/659407017


想到 #cpp SFINAE 和UB的关系也是 实在难崩, 确实需要正常人的编程语言整治一下C++字节和心脏只有一个能跳的碎片化狂欢了

代数确实就是非黑即白的, 但它的下场,就是几百年没人开发了,也就是领域死了。 还死的很有尊严呢~ 主不在乎。
SFINAE最开始不就是UB么, C++真是一个从bug和UB里构建出来的SDK,和py小而美的路子完全相反
邮电确实好啊…… 我大专
Please open Telegram to view this post
VIEW IN TELEGRAM
#day https://x.com/i/grok/share/AVGVB1PH41EhXnGuO8zPXZ9Jz 😃
>哈哈,真是很有意思呢。易语言也没有这么文绉绉的

这种代码的「既视感」就像是把编程主播念的代码转写到纸上,和算法的心智模型隔着两层, 并且是七成中文编程栏目的水平
我们不谈这些奇怪的代码。 编程语言的设计从来不是#define几个替换,而是心智模型的转换

例如
- 分号和let是不是噪音?print有必要成为语法吗?花括号、缩进、end 哪个更合适?
- 循环 i 从 2 到 n{} 不容易复用,也较难与 2<input<n 对仗,应该外提为运行时数据, for in (2..n)?
- 数组长度只在类型里足够吗?
- 是if else if; if elif,还是when{}?


你会发现,C++,Java,Ruby,Lua,Rust这些语言都给出了不同的答案,而「中文编程语言」比如muLang,本质上给的答案如出一辙,而且没有变化
#ai对比 https://chat.librechat.ai/share/LZvxePcLNiym1w4vg6xl- 🤪
Please open Telegram to view this post
VIEW IN TELEGRAM
#vibe 今日挑战:牛顿分形 (Newton Fractals)
lines 266, 3hrs (重构前317行), 包含 8 种目标函数选择和 5 种配色算法选择 😝
https://codepen.io/duangsuz/full/MYezJVP

分形包含混沌边缘,展现出无限精细的朱利亚集(Julia Set)结构,像素级并行计算。

使用 lil-gui 极大提升交互体验,hammer.js 能完美支持触控和鼠标拖拽,而利用 #define 宏或字符串注入来处理 GLSL 公式,能让代码结构更清晰。👍
#math http://www.shuxueji.com/w/48457
https://paulbourke.net/fractals/ 分形 world!

从 CPU Canvas2D 逐像素计算迁移至 GPU SwissGL (基于 WebGL 2.0),性能提升数百倍,支持实时 60fps 渲染。
https://google.github.io/swissgl/#Springs

实现了复数运算库(包括复数乘法、除法、正弦、双曲余弦等),包含js平滑的鼠标拖拽(Pan)和滚轮缩放(Zoom)。

牛顿迭代公式:代码中的 iter 循环执行复数操作。div 函数处理复数除法,F.f 和 F.df 分别计算函数值和导数值。迭代 zn+1​=zn​−f(zn​)/f′(zn​) 寻找函数收敛域

HSV 平滑着色逻辑:可视化方程 p(z)=0 的根。Hue (色相) 取决于根的相位(角度),Value/亮度取决于收敛速度(迭代次数),不仅区分了不同的根的区域颜色,还能看到平滑的边缘细节。


使用了 Inigo Quilez 的经典 Cosine Gradient 算法,并调整了参数,让颜色过渡更加细腻(更有“梯度感”)。👍

已加入 https://duangsuse.github.io/NebulaRemix #疯狂星期二 套餐
发誓11点后再不熬夜 #vibez.. 😅
Please open Telegram to view this post
VIEW IN TELEGRAM
春东西 dumb box
https://x.com/solanamummy/status/2044808122997284963?s=46
#PLT

我想吐槽 #Haskell 根生的可用性问题。f(1+1) 里int(2)的懒求值是蛤丝的“特点”,而 add=(\a \b a+b) 的强制“解耦合”是纯FP风俗,异曲同工

这是在制造“熵增”。

我们都知道 @autoclosure,即 f(1+1) 等效 f(lambda:1+1) 是Lazy<T>的必须(时间换空间,这是混淆求值阶段的代价),懒有什么好处呢?

允许自定义 if(Q,A,B) 和 and(A_or_break, B) “函数”?单子宏?这是在乱搞。

((1)+1)==(1+1) 吗?哲学上来说,PL把自己当成“递等式”,过程和答案是等价且相等的。但“熵增”就是丢垃圾,蛤丝喜欢垃圾! 这是为啥呢?


对于上面的“递等式”,显然有比 2==2 更高性能的证法,但符号的好处正如列表字典之于JSON——有得必有失。在Lisp继Fortran诞生后,这个【失】就是GC。

Thunk就是另一个“GC”,只是它屁用没有。GC至少能用“链表状图”帮你算出“字节数”状图在某天有多大,

Thunk(0参函数)知道“1天”是什么维度的值吗?

栏目答演算的本质是什么?字面量替换。这也是为什么ML99能用 #define (配合 if_##A##B 式模式匹配)的写出一个无编译期插件的DSL,所以无论是SKI、栈语言、Prolog(DFS)的替换都是同阶的,不存在哪种“血统”更高

Church老祖在写自然数 N=Z|N+1 和“神奇”的,不用struct{}写程序的组合子时,他只是把tuple放进了(*arg,)闭包里,通过.then(续延)的“链表线程栈”的方法,以及从arg里选续延。纯函数是另一种OOP编程而已。

所以“懒人”是和自己过不去:如果说 (add 0)=(\b 0+b) 无法被压缩(即更接近停机/靠近main的帧),是因为 b :: Int 值还有“极大”的潜在空间,无法在“Runtime”之前剪枝,(add 0 1) 或 0+1 凭什么不是字节(=0x1)呢?

Currying 是因为int(x)所示所有x的空间,4GB也装不下,Thunk,比如 Monad “解释器”和Haskell蛤丝引以为傲的 do(>>=) notation 的情况不同! 🤔💭