<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
    <channel>
        <title>NicoLabs</title>
        <link>http://blog.hellonico.info/zh/</link>
        <description>NicoLabs</description>
        <generator>Hugo -- gohugo.io</generator><language>zh</language><lastBuildDate>Thu, 02 Jul 2026 12:00:00 &#43;0900</lastBuildDate>
            <atom:link href="http://blog.hellonico.info/zh/index.xml" rel="self" type="application/rss+xml" />
        <item>
    <title>Coni中的程序化音频与WebGL WebAssembly体验</title>
    <link>http://blog.hellonico.info/zh/posts/coni/procedural-audiovisual-wasm/</link>
    <pubDate>Thu, 02 Jul 2026 12:00:00 &#43;0900</pubDate>
    <author>Author</author>
    <guid>http://blog.hellonico.info/zh/posts/coni/procedural-audiovisual-wasm/</guid>
    <description><![CDATA[<p>仅在过去的24小时内，我们就突破了<strong>Coni WebAssembly</strong>生态系统的边界，制作了整套程序化视听网络体验。通过将Coni宏系统与原始WebGL及WebAudio API相结合，我们成功地在浏览器中原生搭建、编译和部署了复杂的图形和音乐系统，并且绝对零外部资产依赖。</p>
<p>让我们来看看我们构建的这五个新应用。您可以在<a href="https://coni-lang.org/wasm-apps/" target="_blank" rel="noopener noreffer ">Coni WASM Gallery</a>的浏览器中原生体验它们。</p>
<h3 id="1-极简techno视觉化工具-minimal-techno-visualizer">1. 极简Techno视觉化工具 (Minimal Techno Visualizer)</h3>
<p><strong>主题:</strong> 黑暗、充满驱动力的算法俱乐部能量。
<em>链接:</em> <a href="https://coni-lang.org/wasm-apps/apps/minimal-techno/" target="_blank" rel="noopener noreffer ">Minimal Techno App</a></p>
<p>我们想要证明Coni能够编排实时的程序化音乐生成，并将其与繁重的3D几何渲染完美同步。</p>
<ul>
<li><strong>音频引擎:</strong> 定制的140 BPM时间线引擎在16分音符的弱拍上触发模拟风格的锯齿波低音线，搭配808风格的合成底鼓，并在高潮段（Drop）引入清脆的基于噪声的军鼓/拍手声。</li>
<li><strong>WebGL细节:</strong> 我们映射了5,000个在16小节“Breakdown”期间反转重力的下落雨粒，以及一个致密脉动的3D几何核心，它在每次底鼓敲击时猛烈绽放，并根据音序器状态从冷青色转变为火橙色。</li>
</ul>
<h3 id="2-999hz-神圣无限-divine-infinity-999hz">2. 999Hz 神圣无限 (Divine Infinity 999Hz)</h3>
<p><strong>主题:</strong> 空灵的数学疗愈。
<em>链接:</em> <a href="https://coni-lang.org/wasm-apps/apps/infinity-999hz/" target="_blank" rel="noopener noreffer ">Divine Infinity 999Hz</a></p>
<p>这个应用以神圣频率疗愈的概念为核心，是纯粹数学与环境音频的完美结合。</p>
<ul>
<li><strong>音频引擎:</strong> 它生成999Hz的“天使频率”正弦波，并辅以微妙的8Hz Theta双耳节拍，以诱导深度放松。</li>
<li><strong>WebGL细节:</strong> 我们在GLSL顶点着色器中使用纯三角函数，将500,000个粒子映射到“伯努利双纽线”（无限大符号）上。它在3D空间中完美渲染，带有微妙的环境光晕和基于深度的不透明度渐隐。</li>
</ul>
<h3 id="3-清除脑雾-40hz-clear-brain-fog-40hz">3. 清除脑雾 40Hz (Clear Brain Fog 40Hz)</h3>
<p><strong>主题:</strong> 几何的清晰与专注。
<em>链接:</em> <a href="https://coni-lang.org/wasm-apps/apps/brain-fog-40hz/" target="_blank" rel="noopener noreffer ">Clear Brain Fog 40Hz</a></p>
<p>旨在驱散精神杂念，此应用使用令人着迷的几何图形搭配接地频率。</p>
<ul>
<li><strong>音频引擎:</strong> 通过微调两个振荡器（左耳432Hz，右耳472Hz）创建的纯40Hz双耳节拍。</li>
<li><strong>WebGL细节:</strong> 我们在顶点着色器中编程了一个拥有5片旋转花瓣的3D繁花曲线。复杂的重叠曲线产生了一种不断向前运动的错觉，而摄像机实际上根本没有移动，使眼睛陷入一种心流状态。</li>
</ul>
<h3 id="4-webgl呼吸引导应用-webgl-guided-breathing-app">4. WebGL呼吸引导应用 (WebGL Guided Breathing App)</h3>
<p><strong>主题:</strong> 控制下的节奏感冥想。
<em>链接:</em> <a href="https://coni-lang.org/wasm-apps/apps/breathing-app/" target="_blank" rel="noopener noreffer ">Breathing App</a></p>]]></description>
</item>
<item>
    <title>WebGL呼吸引导: 6-2-6的交互式体验</title>
    <link>http://blog.hellonico.info/zh/posts/coni/breathing-app-webgl/</link>
    <pubDate>Mon, 29 Jun 2026 23:35:00 &#43;0900</pubDate>
    <author>Author</author>
    <guid>http://blog.hellonico.info/zh/posts/coni/breathing-app-webgl/</guid>
    <description><![CDATA[<p>在当今快节奏的数字世界中，心理健康和专注力至关重要。继我们的脑波同步应用取得成功后，我们决定解决幸福感的另一个方面：<strong>有意识的呼吸</strong>。</p>
<p>我们很高兴揭晓我们最新的Coni WASM应用程序：<strong>WebGL呼吸应用 (WebGL Breathing App)</strong>。这是一个从零开始构建的视听体验，旨在引导您完成一段平静的6-2-6呼吸练习（吸气6秒，屏息2秒，呼气6秒）。</p>
<h3 id="打造栩栩如生的ui">打造栩栩如生的UI</h3>
<p>与仅仅显示一个不断变大圆圈的传统呼吸计时器不同，我们希望构建一些让人感觉有生命力的东西。我们设计了一个交互式菜单，您可以在其中设置您的<strong>心境 (Mood)</strong>——从<em>平静 Calm</em>（青色）、<em>温暖 Warm</em>（橙色）或<em>专注 Focus</em>（紫色）中选择。</p>
<p></p>
<p>当您开始练习时，背景环境噪音和程序生成的铃声开始播放。这些声音完全由Web Audio API驱动，并由原生Coni函数无缝调度。通过将逻辑与标准JS运行时的卡顿隔离开来，音频保持完美的连贯性且没有抖动。</p>
<h3 id="gpu的力量">GPU的力量</h3>
<p>在底层，应用程序生成一个由<strong>30,000个几何粒子</strong>组成的簇，这些粒子在WebAssembly中原生计算和缓存。我们将这些点连同您选择的心境颜色以及一个连续的 <code>u_breath_factor</code> 传递给WebGL着色器。</p>
<p>当您吸气时，球体膨胀，其半径动态缩放，同时其顶点通过直接在顶点着色器中应用的三角正弦和余弦操作而轻柔起伏。颜色强度也会增加，模拟能量的扩张。</p>
<p>当您呼气时，球体收缩成一个紧凑的核心。</p>
<p></p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-clojure" data-lang="clojure"><span style="display:flex;"><span><span style="color:#75715e">;; 我们完全在WASM中计算阶段</span>
</span></span><span style="display:flex;"><span>(<span style="color:#66d9ef">defn </span>update-phase [t phase-text]
</span></span><span style="display:flex;"><span>  (<span style="color:#66d9ef">let </span>[cycle-time (<span style="color:#a6e22e">fmod</span> t <span style="color:#ae81ff">14000.0</span>)
</span></span><span style="display:flex;"><span>        inhale-time <span style="color:#ae81ff">6000.0</span>
</span></span><span style="display:flex;"><span>        hold-time <span style="color:#ae81ff">2000.0</span>
</span></span><span style="display:flex;"><span>        exhale-time <span style="color:#ae81ff">6000.0</span>]
</span></span><span style="display:flex;"><span>    (<span style="color:#66d9ef">if </span>(&lt; cycle-time inhale-time)
</span></span><span style="display:flex;"><span>      <span style="color:#75715e">;; ... 平滑扩展的数学逻辑</span>
</span></span></code></pre></div><p>通过将视觉变换卸载到GPU，并在WASM中原生保持严格的状态同步，我们实现了如丝般顺滑的60fps体验，感觉非常自然，而不是机械生硬的。</p>]]></description>
</item>
<item>
    <title>使用Conimo框架构建最小化CMS</title>
    <link>http://blog.hellonico.info/zh/posts/coni/getting-started-conimo/</link>
    <pubDate>Mon, 29 Jun 2026 12:00:00 &#43;0900</pubDate>
    <author>Author</author>
    <guid>http://blog.hellonico.info/zh/posts/coni/getting-started-conimo/</guid>
    <description><![CDATA[<p>Conimo是Coni的官方全栈Web框架。它将极其快速的WASM前端功能与健壮的后端服务器环境结合在一起，形成了一个具有凝聚力且精简的开发者体验。</p>
<p>最近，我们通过将核心的Conimo CLI脚本直接嵌入到 <code>conimo</code> 库的 <code>bin</code> 目录中，极大地改善了开发者体验。这意味着您不需要外部的设置脚本——一切都由原生的Coni代码驱动。</p>
<p>在本指南中，我们将带您完成新应用程序的脚手架搭建、运行本地开发服务器，并利用强大的 <code>patom</code> 数据库快速构建一个极简的内容管理系统 (CMS)。</p>
<h3 id="1-使用-create-搭建脚手架">1. 使用 <code>create</code> 搭建脚手架</h3>
<p>要开始使用，我们使用内置的 <code>conimo create</code> 命令。Conimo提供了各种内置模板，从最小的SSR设置到完整的实时WebSocket架构，甚至是原生的AI聊天应用程序。</p>
<p>对于CMS，我们需要持久化。<code>csv-store</code> 模板非常适合这个需求，因为它通过 <code>patom</code> 利用了健壮的CSV文件数据库。</p>
<p>运行以下命令来搭建您的项目脚手架：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>coni conimo create my-cms --template csv-store
</span></span></code></pre></div><p>脚手架脚本将瞬间生成一个全栈目录结构：</p>
<ul>
<li><code>backend/</code>: 您的后端HTTP/WebSocket服务器。</li>
<li><code>frontend/</code>: 您的WASM编译前端代码。</li>
<li><code>coni.edn</code>: 项目配置，会自动注入当前的编译器路径，以确保原生WASM构建无缝工作。</li>
</ul>
<h3 id="2-运行开发服务器">2. 运行开发服务器</h3>
<p>创建项目后，启动开发环境就像运行 <code>conimo dev</code> 命令一样简单。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>cd my-cms
</span></span><span style="display:flex;"><span>coni conimo dev
</span></span></code></pre></div><p>在底层，Conimo开发服务器：</p>
<ol>
<li>为您的 <code>frontend/</code> 代码生成一个后台WASM编译进程。</li>
<li>等待直到 <code>main.wasm</code> 和必要的JS桥接完全编译完毕。</li>
<li>自动启动您的 <code>backend/main.coni</code> 服务器。</li>
</ol>
<p>您现在拥有了一个实时的全栈环境，在这里您的后端服务器和WASM前端无缝连接。</p>
<h3 id="3-编写cms">3. 编写CMS</h3>
<p></p>]]></description>
</item>
<item>
    <title>针对Coni原生Float32数组的硬核混沌测试</title>
    <link>http://blog.hellonico.info/zh/posts/coni/float32-chaos-testing/</link>
    <pubDate>Sun, 28 Jun 2026 11:30:00 &#43;0900</pubDate>
    <author>Author</author>
    <guid>http://blog.hellonico.info/zh/posts/coni/float32-chaos-testing/</guid>
    <description><![CDATA[<p>当您在浏览器中构建高性能应用程序时，JavaScript通用的 <code>Number</code> 类型通常是不够的。您需要原始的、连续的内存数组。在Coni WASM中，我们在计算最密集的应用程序上严重依赖原生的WebAssembly <code>float32</code> 数组。</p>
<h3 id="float32在coni中到底用在哪里">Float32在Coni中到底用在哪里？</h3>
<p>原生 <code>float32</code> 数组（<code>make-float32-array</code>、<code>f32-set!</code>、<code>f32-get</code>）是Coni性能层的绝对主干。您会发现它们驱动着：</p>
<ol>
<li><strong>WebGL几何体:</strong> 在我们的 <a href="https://coni-lang.org/wasm-apps/apps/deep-focus-webgl/" target="_blank" rel="noopener noreffer "><code>deep-focus-webgl</code></a> 应用中，我们使用 <code>float32</code> 数组在原生层面通过数学方式塑造一个拥有80,000个顶点的大脑矩阵（240,000个浮点数！），然后通过 <code>js/float32-buffer</code> 将其一次性发送给GPU。</li>
<li><strong>游戏引擎粒子系统:</strong> 对于像 <code>flappy-bird</code> 或 <code>neon-boids</code> 这样的游戏，并行的 <code>float32</code> 数组无需垃圾回收的停顿，即可跟踪数以千计的X/Y坐标、速度和生命周期。</li>
<li><strong>原始DSP音频:</strong> 我们的 <code>sound-nodes</code> 合成器在将复杂的脉冲响应和噪声波形映射到WebAudio通道之前，使用 <code>float32</code> 数组在原生层面计算它们。</li>
</ol>
<h3 id="错误所在类型强制转换与-f64reinterpret_i64">错误所在：类型强制转换与 <code>f64.reinterpret_i64</code></h3>
<p>因为这些数组极其关键，它们中的任何错误都将是灾难性的。最近，我们发现了一个问题：将一个精确的整数（如 <code>150</code>）传入 <code>f32-set!</code> 时，会莫名其妙地产生 <code>0.0</code>。</p>
<p>到底发生了什么？在较早版本的WASM编译器中，将整数传递给浮点数setter会导致编译器错误地使用 <code>f64.reinterpret_i64</code> 来解释这些位，从而完全扰乱了底层的值。</p>
<h3 id="解决方案float32混沌测试-chaos-testing">解决方案：Float32混沌测试 (Chaos Testing)</h3>
<p>我们修补了编译器，以便在插入内存之前将整数正确地强制转换为浮点数，但我们需要一个保证，确保它永远不会再次退化。于是，<strong>混沌测试</strong>登场了。</p>
<p>在新的 <code>float32_coercion_test.coni</code> 测试套件中，我们构建了一个硬核的混沌测试。我们不是仅仅测试几个顺利通过的数字，而是分配了一个巨大的数组，并用确定性的、伪随机的循环来猛烈敲击它。</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-clojure" data-lang="clojure"><span style="display:flex;"><span>(<span style="color:#a6e22e">deftest</span> test-f32-chaos
</span></span><span style="display:flex;"><span>  <span style="color:#e6db74">&#34;针对float32数组边界和类型转换的硬核混沌测试。&#34;</span>
</span></span><span style="display:flex;"><span>  (<span style="color:#66d9ef">let </span>[size <span style="color:#ae81ff">1000</span>
</span></span><span style="display:flex;"><span>        arr (<span style="color:#a6e22e">make-float32-array</span> size)]
</span></span><span style="display:flex;"><span>    (<span style="color:#66d9ef">loop </span>[i <span style="color:#ae81ff">0</span>]
</span></span><span style="display:flex;"><span>      (<span style="color:#66d9ef">if </span>(&lt; i size)
</span></span><span style="display:flex;"><span>        (<span style="color:#66d9ef">let </span>[
</span></span><span style="display:flex;"><span>          <span style="color:#75715e">;; 混合生成极端边缘用例：</span>
</span></span><span style="display:flex;"><span>          val (<span style="color:#66d9ef">if </span>(= (<span style="color:#a6e22e">mod</span> i <span style="color:#ae81ff">4</span>) <span style="color:#ae81ff">0</span>) (- <span style="color:#ae81ff">0</span> i)                   <span style="color:#75715e">;; 负整数</span>
</span></span><span style="display:flex;"><span>                (<span style="color:#66d9ef">if </span>(= (<span style="color:#a6e22e">mod</span> i <span style="color:#ae81ff">4</span>) <span style="color:#ae81ff">1</span>) (* i <span style="color:#ae81ff">10000</span>)             <span style="color:#75715e">;; 大正整数</span>
</span></span><span style="display:flex;"><span>                  (<span style="color:#66d9ef">if </span>(= (<span style="color:#a6e22e">mod</span> i <span style="color:#ae81ff">4</span>) <span style="color:#ae81ff">2</span>) (+ i <span style="color:#ae81ff">0.5</span>)             <span style="color:#75715e">;; 精确的float32小数</span>
</span></span><span style="display:flex;"><span>                    <span style="color:#ae81ff">0</span>)))                                    <span style="color:#75715e">;; 零（整数）</span>
</span></span><span style="display:flex;"><span>        ]
</span></span><span style="display:flex;"><span>          (<span style="color:#a6e22e">f32-set!</span> arr i val)
</span></span><span style="display:flex;"><span>          (<span style="color:#a6e22e">recur</span> (+ i <span style="color:#ae81ff">1</span>)))
</span></span><span style="display:flex;"><span>        nil))
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">;; ... 验证循环 ...</span>
</span></span></code></pre></div><p>通过故意将极端正整数、负边界值、纯零和带有小数的浮点数这种残酷的混合物向 <code>f32-set!</code> 函数抛出1,000次，我们保证了能避免WASM陷阱（traps），并且类型强制转换变得坚不可摧。</p>]]></description>
</item>
<item>
    <title>用纯Coni Lisp编写WebGL着色器！</title>
    <link>http://blog.hellonico.info/zh/posts/coni/coni-webgl-shaders/</link>
    <pubDate>Sun, 28 Jun 2026 07:30:00 &#43;0900</pubDate>
    <author>Author</author>
    <guid>http://blog.hellonico.info/zh/posts/coni/coni-webgl-shaders/</guid>
    <description><![CDATA[<p>在上一篇文章中，我们通过编排一个由80,000个粒子组成的WebGL矩阵展示了Coni WASM的原始威力。但在WebGL流水线中，始终存在一个挥之不去的烦恼：<strong>着色器本身</strong>。</p>
<p>如果您写过WebGL代码，您一定深有体会。您最终会将顶点着色器和片段着色器写成庞大、混乱的字符串字面量，散布在整个代码库中。您失去了语法高亮、格式化，而且——对于Lisp黑客来说最悲惨的是——您失去了结构化编辑（Paredit/Slurp/Barf）。</p>
<p>今天，我们非常高兴地宣布，我们通过新的 <code>libs/webgl/src/glsl.coni</code> 库征服了最后的这个前沿阵地。</p>
<p><strong>您现在完全可以使用Coni的原生Lisp语法编写您的GLSL着色器了。</strong></p>
<h3 id="defshader-登场"><code>defshader</code> 登场</h3>
<p>通过利用Coni强大的AST（抽象语法树）和宏系统，我们构建了 <code>defshader</code>。它接受标准的Lisp形式、类型和数学运算，并在它们到达GPU之前，自动将它们转译为严格的GLSL。</p>
<p>看看为我们的Amplifocus粒子引擎编写的这个片段着色器是多么优雅：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-clojure" data-lang="clojure"><span style="display:flex;"><span>(<span style="color:#a6e22e">require</span> <span style="color:#e6db74">&#34;libs/webgl/src/glsl.coni&#34;</span> <span style="color:#e6db74">:all</span>)
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>(<span style="color:#a6e22e">defshader</span> fs-src
</span></span><span style="display:flex;"><span>  (<span style="color:#a6e22e">precision</span> mediump float)
</span></span><span style="display:flex;"><span>  (<span style="color:#a6e22e">varying</span> vec4 v_color)
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span>  (<span style="color:#66d9ef">defn </span>void main []
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">;; 原生数学运算与坐标映射！</span>
</span></span><span style="display:flex;"><span>    (set vec2 coord (- gl_PointCoord (<span style="color:#a6e22e">vec2</span> <span style="color:#ae81ff">0.5</span> <span style="color:#ae81ff">0.5</span>)))
</span></span><span style="display:flex;"><span>    (set float dist (<span style="color:#a6e22e">length</span> coord))
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    (<span style="color:#66d9ef">if </span>(&gt; dist <span style="color:#ae81ff">0.5</span>)
</span></span><span style="display:flex;"><span>      (<span style="color:#a6e22e">discard</span>))
</span></span><span style="display:flex;"><span>    
</span></span><span style="display:flex;"><span>    <span style="color:#75715e">;; 使用Lisp S-表达式进行发光（Glow）计算</span>
</span></span><span style="display:flex;"><span>    (set float glow (- <span style="color:#ae81ff">1.0</span> (* dist <span style="color:#ae81ff">2.0</span>)))
</span></span><span style="display:flex;"><span>    (set vec4 final_color (* v_color glow))
</span></span><span style="display:flex;"><span>    (set gl_FragColor final_color)))
</span></span></code></pre></div><h3 id="为什么这能颠覆游戏规则">为什么这能颠覆游戏规则？</h3>
<ol>
<li><strong>不再有字符串字面量:</strong> 您的着色器是一等代码。它们与应用程序的其余部分格式完美统一。</li>
<li><strong>AST级别的验证:</strong> Coni编译器可以在它尝试于浏览器中编译WebGL程序之前，就解析并验证您的着色器结构。</li>
<li><strong>结构化编辑:</strong> 您可以使用标准的Lisp结构化编辑工具来slurp、barf和操作复杂的GPU数学计算。试着用C风格的GLSL字符串做这些试试！</li>
<li><strong>无缝集成:</strong> 将其编译成可用的WebGL着色器极其简单，只需调用我们的 <code>core-gl/gl-shader</code> 函数即可：<code>(core-gl/gl-shader gl (.-FRAGMENT_SHADER gl) fs-src)</code>。</li>
</ol>
<h3 id="专为浏览器打造的全栈lisp">专为浏览器打造的全栈Lisp</h3>
<p>有了这次更新，整个流水线终于完整了。从使用 <code>reframe</code> 的DOM操作，到WebAudio合成，到WASM浮点缓冲，再到现在实际的GPU顶点变换——100%都是Coni。</p>]]></description>
</item>
<item>
    <title>在Coni WASM中构建40Hz认知专注应用</title>
    <link>http://blog.hellonico.info/zh/posts/coni/brain-waves-wasm/</link>
    <pubDate>Sun, 28 Jun 2026 07:30:00 &#43;0900</pubDate>
    <author>Author</author>
    <guid>http://blog.hellonico.info/zh/posts/coni/brain-waves-wasm/</guid>
    <description><![CDATA[<p>浏览器中的WebAssembly一直承诺提供令人难以置信的性能，但将其与WebAudio和WebGL等Web API顺畅连接有时感觉像是在解谜。今天，我们非常高兴地展示Coni生态系统如何通过引入两个专为认知专注而设计的全新Web应用来优雅地解决这个问题。</p>
<p>这两个应用程序使用双耳节拍生成<strong>40Hz伽马频率</strong>——一种与深度专注、记忆唤起和认知提升相关的特定脑波频率。但真正的魔力在底层：它们完全是用<strong>Coni WASM</strong>编写的。</p>
<h3 id="40hz伽马波的科学">40Hz伽马波的科学</h3>
<p>在深入探讨技术之前，为什么选择40Hz？伽马波是脑波频率中最快的。研究表明，当大脑在40Hz范围内运作时，它与敏锐的感知、问题解决能力和巅峰的注意力相关联。</p>
<p>通过在左耳播放60Hz的正弦波，在右耳播放100Hz的正弦波，大脑会感知到恰好40Hz的频率差“节拍”。这个过程被称为脑波同步（brainwave entrainment），它会温和地将您的认知状态推入伽马频率。</p>
<p>为了展示Coni架构在提供这种体验方面的灵活性，我们构建了该应用的两个截然不同的版本：</p>
<h3 id="1-canvas版本-deep-focus-40hz">1. Canvas版本: <a href="https://coni-lang.org/wasm-apps/apps/deep-focus-40hz/" target="_blank" rel="noopener noreffer "><code>deep-focus-40hz</code></a></h3>
<p></p>
<p>我们的第一个应用程序依赖于传统的2D Canvas和DOM API。我们利用自定义的<code>reframe_wasm</code>库，直接通过WebAssembly以Hiccup风格的DOM生成来处理UI状态和渲染。</p>
<p>音频引擎完全以接近原生的速度细致地管理振荡器。我们甚至构建了一个自动生成铃声系统，它可以实时调制包络——完全避免了JS的开销：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-clojure" data-lang="clojure"><span style="display:flex;"><span><span style="color:#75715e">;; 无需JS绑定的富有表现力的WebAudio包络！</span>
</span></span><span style="display:flex;"><span>(doto (<span style="color:#a6e22e">.-gain</span> gain)
</span></span><span style="display:flex;"><span>  (<span style="color:#a6e22e">.linearRampToValueAtTime</span> <span style="color:#ae81ff">0.15</span> (+ now <span style="color:#ae81ff">2.0</span>))
</span></span><span style="display:flex;"><span>  (<span style="color:#a6e22e">.exponentialRampToValueAtTime</span> <span style="color:#ae81ff">0.001</span> (+ now <span style="color:#ae81ff">8.0</span>)))
</span></span></code></pre></div><p>这是在纯Coni中构建一个响应式、高性能音频引擎的完美例子。</p>
<h3 id="2-webgl性能怪兽-deep-focus-webgl">2. WebGL性能怪兽: <a href="https://coni-lang.org/wasm-apps/apps/deep-focus-webgl/" target="_blank" rel="noopener noreffer "><code>deep-focus-webgl</code></a></h3>
<p></p>
<p>虽然Canvas版本很棒，但我们想看看我们能将Coni的原生处理能力推到多远。于是<code>deep-focus-webgl</code>（内部代号为Amplifocus）诞生了。</p>
<p>这个版本不再依赖2D Canvas，而是使用纯WebGL渲染一个由<strong>80,000个粒子组成的脑矩阵</strong>。
是什么让这真正令人兴奋？</p>
<ul>
<li><strong>100%纯Coni:</strong> GPU加速的顶点变换和海量粒子数组逻辑都在Coni WASM中原生处理。</li>
<li><strong>零JS数学开销:</strong> 通过使用Coni的数学库（<code>libs/math</code>），我们计算了数万个顶点的复杂三角函数变换，而无需跨越昂贵的JS-WASM桥梁。</li>
</ul>
<p>下面看看我们在原生浮点缓冲中塑造3D几何体并将其发送给GPU是多么毫不费力：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-clojure" data-lang="clojure"><span style="display:flex;"><span><span style="color:#75715e">;; 在WASM内存中处理8万个顶点，一次性发送给GPU！</span>
</span></span><span style="display:flex;"><span>(<span style="color:#a6e22e">f32-set!</span> *base-points* idx final-x)
</span></span><span style="display:flex;"><span>(<span style="color:#a6e22e">f32-set!</span> *base-points* (+ idx <span style="color:#ae81ff">1</span>) final-sy)
</span></span><span style="display:flex;"><span>(<span style="color:#a6e22e">f32-set!</span> *base-points* (+ idx <span style="color:#ae81ff">2</span>) (* z <span style="color:#ae81ff">1.1</span>))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span><span style="color:#75715e">;; 一次性上传静态几何体</span>
</span></span><span style="display:flex;"><span>(<span style="color:#a6e22e">gl/upload-static-data</span> <span style="color:#f92672">@</span>*gl-state* (<span style="color:#a6e22e">js/float32-buffer</span> *base-points*))
</span></span></code></pre></div><p>我们只需分配一次浮点数组，原生处理几何数据，然后通过单一缓冲操作将其瞬间送至GPU。</p>]]></description>
</item>
<item>
    <title>使用嵌入式子命令为Coni CLI提供超级加速</title>
    <link>http://blog.hellonico.info/zh/posts/coni/embedded-subcommands/</link>
    <pubDate>Sat, 27 Jun 2026 00:00:00 &#43;0000</pubDate>
    <author>Author</author>
    <guid>http://blog.hellonico.info/zh/posts/coni/embedded-subcommands/</guid>
    <description><![CDATA[<p>Coni语言最大的优势之一是其便携性。我们的设计使得核心解释器和标准库作为单一的静态二进制文件发布。您不需要臃肿的安装过程；只需下载可执行文件即可开始使用。</p>
<p>然而，随着生态系统的不断发展（例如添加了我们的Android构建流水线），我们发现工作流中出现了一个小烦恼。要调用Android APK构建器，您必须通过其绝对路径运行脚本：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>coni libs/android/bin/build-apk.coni ./my-app
</span></span></code></pre></div><p>虽然它能用，但感觉不够原生。我们希望提供一种极致的开发者体验，让开发者可以简单地运行：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-bash" data-lang="bash"><span style="display:flex;"><span>coni android build-apk ./my-app
</span></span></code></pre></div><p>今天，我们非常高兴地宣布，我们通过实现由Go的 <code>embed</code> 文件系统驱动的<strong>动态子命令路由 (Dynamic Subcommand Routing)</strong>，成功填补了这一空白！</p>
<h2 id="它是如何工作的">它是如何工作的</h2>
<p>我们对Go编译器进行了三个关键的架构级修改：</p>
<h3 id="1-嵌入二进制文件">1. 嵌入二进制文件</h3>
<p>我们扩展了Go编译器内部的 <code>//go:embed</code> 指令，以自动打包所有模块中的所有 <code>bin/</code> 目录：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#75715e">//go:embed libs/*/src libs/*/bin</span>
</span></span><span style="display:flex;"><span><span style="color:#66d9ef">var</span> <span style="color:#a6e22e">embeddedLibs</span> <span style="color:#a6e22e">embed</span>.<span style="color:#a6e22e">FS</span>
</span></span></code></pre></div><p>这个简单的改变保证了辅助脚本（如 <code>build-apk.coni</code>）被永久地“烧录”到可执行文件中。</p>
<h3 id="2-子命令拦截器">2. 子命令拦截器</h3>
<p>我们在CLI参数解析逻辑中引入了一个巧妙的拦截器。现在，如果您运行一个无法识别的命令，比如 <code>coni android build-apk</code>，解析器会拦截它并动态构建一个路径查询：<code>libs/android/bin/build-apk.coni</code>。</p>
<p>它会检查嵌入的文件系统，如果该脚本存在，它会动态地将执行直接重新路由到嵌入的有效载荷！</p>
<h3 id="3-参数掩码屏蔽">3. 参数掩码屏蔽</h3>
<p>最后一个拼图是保持脚本自身的“错觉”。<code>build-apk.coni</code> 脚本使用 <code>cli/parse-opts</code> 来读取标志（如 <code>-p camera</code>）。如果我们盲目地将参数传递给评估器，脚本会被前面的 <code>android</code> 和 <code>build-apk</code> 令牌搞糊涂。</p>
<p>为了解决这个问题，Go路由器在幕后重写了全局的 <code>os.Args</code> 切片：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-go" data-lang="go"><span style="display:flex;"><span><span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Args</span> = append([]<span style="color:#66d9ef">string</span>{<span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Args</span>[<span style="color:#ae81ff">0</span>], <span style="color:#a6e22e">embeddedPath</span>}, <span style="color:#a6e22e">os</span>.<span style="color:#a6e22e">Args</span>[<span style="color:#ae81ff">3</span>:]<span style="color:#f92672">...</span>)
</span></span></code></pre></div><p>从脚本的角度来看，它认为自己是被直接调用的！</p>
<h2 id="结果">结果</h2>
<p>其结果就是获得了闪电般快速、无缝的CLI体验。所有的工具和辅助脚本都有机地打包在Coni二进制文件中，通过自然、感觉像原生的子命令即可瞬间访问。</p>
<p>没有额外的下载，没有路径配置。只有纯粹、不受干扰的生产力！</p>]]></description>
</item>
<item>
    <title>在Coni中构建原生并行下载</title>
    <link>http://blog.hellonico.info/zh/posts/coni/parallel-downloads/</link>
    <pubDate>Sat, 27 Jun 2026 00:00:00 &#43;0000</pubDate>
    <author>Author</author>
    <guid>http://blog.hellonico.info/zh/posts/coni/parallel-downloads/</guid>
    <description><![CDATA[<p>构建自己的语言和工具的绝佳之处之一，是能够重新思考操作的执行方式。在最近的提交中，我们决定解决构建过程中的一个主要瓶颈：下载Maven依赖项。</p>
<h2 id="特定平台脚本存在的问题">特定平台脚本存在的问题</h2>
<p>以前，Coni中的 <code>download-url-to-file</code> 函数依赖于调用特定平台的外部工具：</p>
<ul>
<li>在Linux/macOS上，它会生成一个 <code>curl</code> 进程。</li>
<li>在Windows上，它会调用一个使用 <code>System.Net.WebClient</code> 的庞大 <code>powershell</code> 命令。</li>
</ul>
<p>虽然这种方法可行，但它有几个缺点。首先，调用外部进程既缓慢又消耗资源。其次，依赖外部工具意味着 <code>curl</code> 版本的微妙差异或Windows安全协议可能会导致意想不到的失败。最重要的是，使用这些shell命令顺序下载工件意味着解析大型Maven项目会花费太长时间。</p>
<h2 id="原生解决方案">原生解决方案</h2>
<p>在提交 <code>9ac76d12</code> 中，我们引入了 <code>sys-http-download</code>，这是一个直接在Go评估器中实现的原生内置函数。这个新的内置函数使用了Go标准的 <code>net/http</code> 客户端。</p>
<p>因为它原生内置在评估器中，所以我们完全避免了进程创建的开销。我们甚至在Go实现中直接加入了一些健壮的重试逻辑，以处理来自Maven Central的速率限制（如果您在没有可识别的User-Agent的情况下请求过快，它经常会抛出429 Too Many Requests错误）。</p>
<h2 id="使用goroutine进行超级加速">使用Goroutine进行超级加速</h2>
<p>在原生内置函数准备就绪后，真正的魔力发生在我们应用Coni的并发原语时。Coni使用 <code>go</code>、<code>chan</code>、<code>&lt;!</code>（从通道读取）和 <code>&gt;!</code>（写入通道）原生支持Go风格的并发。</p>
<p>我们没有逐个下载工件，而是直接在标准库中设置了一个工作池 (worker pool)：</p>
<div class="highlight"><pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"><code class="language-clojure" data-lang="clojure"><span style="display:flex;"><span>(<span style="color:#66d9ef">let </span>[total-count (count missing)
</span></span><span style="display:flex;"><span>      result-ch (<span style="color:#a6e22e">chan</span> total-count)
</span></span><span style="display:flex;"><span>      task-ch (<span style="color:#a6e22e">chan</span> total-count)]
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">;; 将所有任务推送到任务通道</span>
</span></span><span style="display:flex;"><span>  (<span style="color:#66d9ef">loop </span>[rem missing]
</span></span><span style="display:flex;"><span>    (<span style="color:#66d9ef">if </span>(not (<span style="color:#a6e22e">empty?</span> rem))
</span></span><span style="display:flex;"><span>      (<span style="color:#66d9ef">do </span>
</span></span><span style="display:flex;"><span>        (<span style="color:#a6e22e">&gt;!</span> task-ch (first rem))
</span></span><span style="display:flex;"><span>        (<span style="color:#a6e22e">recur</span> (rest rem)))))
</span></span><span style="display:flex;"><span>  (<span style="color:#a6e22e">close!</span> task-ch)
</span></span><span style="display:flex;"><span>  
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">;; 生成8个工作goroutine并发处理任务</span>
</span></span><span style="display:flex;"><span>  (<span style="color:#66d9ef">loop </span>[i <span style="color:#ae81ff">0</span>]
</span></span><span style="display:flex;"><span>    (<span style="color:#66d9ef">if </span>(&lt; i <span style="color:#ae81ff">8</span>)
</span></span><span style="display:flex;"><span>      (<span style="color:#a6e22e">do</span>
</span></span><span style="display:flex;"><span>        (<span style="color:#a6e22e">go</span> 
</span></span><span style="display:flex;"><span>          (<span style="color:#66d9ef">loop </span>[]
</span></span><span style="display:flex;"><span>            (<span style="color:#66d9ef">let </span>[item (<span style="color:#a6e22e">&lt;!</span> task-ch)]
</span></span><span style="display:flex;"><span>              (<span style="color:#66d9ef">if </span>(not (nil? item))
</span></span><span style="display:flex;"><span>                (<span style="color:#a6e22e">do</span>
</span></span><span style="display:flex;"><span>                  (<span style="color:#a6e22e">&gt;!</span> result-ch (<span style="color:#a6e22e">download-file-single</span> item repos))
</span></span><span style="display:flex;"><span>                  (<span style="color:#a6e22e">recur</span>))))))
</span></span><span style="display:flex;"><span>        (<span style="color:#a6e22e">recur</span> (+ i <span style="color:#ae81ff">1</span>)))))
</span></span><span style="display:flex;"><span>
</span></span><span style="display:flex;"><span>  <span style="color:#75715e">;; 等待结果并显示进度</span>
</span></span><span style="display:flex;"><span>  ...)
</span></span></code></pre></div><p>我们将工作池的上限限制为8个goroutine，以防止网络不堪重负或触发激进的速率限制。</p>]]></description>
</item>
</channel>
</rss>
