<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Hacker News: ianthehenry</title><link>https://news.ycombinator.com/user?id=ianthehenry</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Mon, 07 Sep 2026 14:25:13 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=ianthehenry" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by ianthehenry in "Terpstra Keyboard"]]></title><description><![CDATA[
<p>Well the only moving part in a typing keyboards is a mass-produced switch that you slot into a PCB. There are mass-produced hall effect switches that can provide velocity sensitivity, but it's a pretty distant comparison. The keys on a lumatone aren't anything like buttons; they're weighted mechanical arms with significant travel -- much more like a piano key than a keyboard key. And it has 280 of these! The degree of mechanical hardware in this thing makes it seem not really comparable to a PCB with some switches slotted into it.<p>That said! There are people making DIY isomorphic keyboards using hall-effect keyboard switches. None are commercially available right now, but see e.g. the MidiHex at <a href="https://gullsonix.co.uk/" rel="nofollow">https://gullsonix.co.uk/</a>. You could make one for a fraction of the cost of a lumatone -- but of course it would be a very different instrument.</p>
]]></description><pubDate>Sat, 05 Sep 2026 17:46:37 +0000</pubDate><link>https://news.ycombinator.com/item?id=49578873</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=49578873</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49578873</guid></item><item><title><![CDATA[New comment by ianthehenry in "Tuxedo No. 2 – Cocktail recipes"]]></title><description><![CDATA[
<p>I like this website a lot and used it as the base recipe book for a program that will tell you what cocktails you can make with the ingredients you have, but also what cocktails you are “one ingredient away from.” <a href="https://github.com/ianthehenry/mixologician" rel="nofollow">https://github.com/ianthehenry/mixologician</a><p>It’s a little datalog script - input is a text file, output is a text file. I’ve used it a few times to decide what to pick up at the store!</p>
]]></description><pubDate>Mon, 10 Aug 2026 02:22:13 +0000</pubDate><link>https://news.ycombinator.com/item?id=49238552</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=49238552</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49238552</guid></item><item><title><![CDATA[New comment by ianthehenry in "Why Janet? (2023)"]]></title><description><![CDATA[
<p><a href="https://github.com/ianthehenry/janet-module/blob/master/init.janet" rel="nofollow">https://github.com/ianthehenry/janet-module/blob/master/init...</a><p>This is a very very barebones version of this, but it’s not too hard to construct environment tables dynamically</p>
]]></description><pubDate>Sat, 06 Jun 2026 16:55:48 +0000</pubDate><link>https://news.ycombinator.com/item?id=48426775</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=48426775</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48426775</guid></item><item><title><![CDATA[New comment by ianthehenry in "Why Janet? (2023)"]]></title><description><![CDATA[
<p>The `import` macro extends the current environment with prefixed symbols from another environment. But the environment is a first-class object that you can hold and manipulate and use in arbitrary ways — `require` is the lower level primitive that `import` is built on.</p>
]]></description><pubDate>Sat, 06 Jun 2026 16:54:14 +0000</pubDate><link>https://news.ycombinator.com/item?id=48426757</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=48426757</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48426757</guid></item><item><title><![CDATA[New comment by ianthehenry in "New method turns ocean water into drinking water, without waste"]]></title><description><![CDATA[
<p>And a Blue Planet II video of a brine pool, stronger content warning for much more horrifying death: <a href="https://www.youtube.com/watch?v=ZwuVpNYrKPY" rel="nofollow">https://www.youtube.com/watch?v=ZwuVpNYrKPY</a></p>
]]></description><pubDate>Sat, 06 Jun 2026 04:10:36 +0000</pubDate><link>https://news.ycombinator.com/item?id=48421301</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=48421301</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48421301</guid></item><item><title><![CDATA[New comment by ianthehenry in "Shaders: How to draw high fidelity graphics with just x and y coordinates"]]></title><description><![CDATA[
<p>The next chapter is about SDFs, but it is not available yet.<p><a href="https://www.makingsoftware.com/chapters/rays-and-sdfs" rel="nofollow">https://www.makingsoftware.com/chapters/rays-and-sdfs</a></p>
]]></description><pubDate>Sun, 23 Nov 2025 15:32:19 +0000</pubDate><link>https://news.ycombinator.com/item?id=46024293</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=46024293</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=46024293</guid></item><item><title><![CDATA[New comment by ianthehenry in "How functional programming shaped and twisted front end development"]]></title><description><![CDATA[
<p>Bonsai is a frontend framework that models data as an explicit graph, separate from any “component hierarchy” or DOM structure. State can live anywhere in the application graph, whether or not it’s associated with DOM nodes, and you eliminate all of the “move this state to the parent to share it” ceremony by just having “components” return their views and “outputs” at the same time (if they want).<p>It’s pretty great and hard to imagine going back to a React-like component hierarchy.</p>
]]></description><pubDate>Sat, 04 Oct 2025 14:47:40 +0000</pubDate><link>https://news.ycombinator.com/item?id=45473683</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=45473683</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45473683</guid></item><item><title><![CDATA[New comment by ianthehenry in "Ask HN: What are you working on? (March 2025)"]]></title><description><![CDATA[
<p>I'm working on adding something like <a href="https://graphtoy.com/" rel="nofollow">https://graphtoy.com/</a> to my lisp-based 3D art tool <a href="https://bauble.studio/" rel="nofollow">https://bauble.studio/</a>. It's really useful to visualize functions like this, especially when writing animation curves that vary over time.<p>It's easy to add it as a plain overlay over the screen if you're graphing a function, but I really want it to be able to plot arbitrary expressions with free variables where it just infers the axes, so you can just see values overload in the orthographic view (press alt-q to see that). That way you can just write something like (ss p.x 0 10 | graph) on any expression and visualize it as you go. I haven't quite figured out how to make it seamless though...</p>
]]></description><pubDate>Sun, 30 Mar 2025 21:04:10 +0000</pubDate><link>https://news.ycombinator.com/item?id=43527620</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=43527620</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43527620</guid></item><item><title><![CDATA[New comment by ianthehenry in "Mountains, Cliffs, and Caves: A Guide to Using Perlin Noise for Procedural Gen"]]></title><description><![CDATA[
<p>If this kinda thing piqued your interest and you want to play around with this idea, paste the following code into <a href="https://bauble.studio/" rel="nofollow">https://bauble.studio/</a>:<p><pre><code>    (def octaves 4)
    (def lacunarity 2.00)
    (def persistence 0.50)
    (def period 100)
    (def height 40)
    (plane y (fbm octaves :f lacunarity :gain persistence perlin p.xz period * height)
    # try s/color/shade on the line below
    | color (ss p.y -20 0 blue (ss p.y 0 20 green white))
    | slow (20 / height)
    | intersect (sphere 200))
</code></pre>
(Using the terms from the article.) You can right-click and drag those numbers to see how the parameters affect the result in realtime. Also an easy way to compare perlin and simplex noise. Procedural terrain is fun!<p>Also while this uses 2D perlin noise -- you're just changing the height of a plane -- you can create some pretty detailed neat "rocky" terrain effects by using 3D perlin noise instead. Change "p.xz" to "p.xyz" to see what that looks like.</p>
]]></description><pubDate>Sat, 08 Mar 2025 06:33:04 +0000</pubDate><link>https://news.ycombinator.com/item?id=43298014</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=43298014</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=43298014</guid></item><item><title><![CDATA[New comment by ianthehenry in "Building Bauble"]]></title><description><![CDATA[
<p>okay, that's helpful. the "undefined is not an object" bit is definitely a function of the "failed to create webgl2 context" error -- it tries to reference it unconditionally. no idea why it can't create the graphics context in the first place, though (and not much to do without one)</p>
]]></description><pubDate>Sat, 11 Jan 2025 17:51:03 +0000</pubDate><link>https://news.ycombinator.com/item?id=42667552</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=42667552</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42667552</guid></item><item><title><![CDATA[New comment by ianthehenry in "Building Bauble"]]></title><description><![CDATA[
<p>huh, that's no good. it works fine for me on safari 18.1. would you share the line that it's raising on? no other errors before that one?</p>
]]></description><pubDate>Sat, 11 Jan 2025 16:45:59 +0000</pubDate><link>https://news.ycombinator.com/item?id=42667029</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=42667029</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42667029</guid></item><item><title><![CDATA[New comment by ianthehenry in "Building Bauble"]]></title><description><![CDATA[
<p>I ordered them from sculpteo — the only service I could find that would do it. Very happy with everything I’ve gotten from them. It is very very expensive if you want to make anything large, but for small jewelry-scale stuff it’s not too crazy. The balloon is seven custom parts so that was pricey ($250 total?), but the other two models were around $50 each.</p>
]]></description><pubDate>Sat, 11 Jan 2025 14:41:59 +0000</pubDate><link>https://news.ycombinator.com/item?id=42666190</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=42666190</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42666190</guid></item><item><title><![CDATA[Building Bauble]]></title><description><![CDATA[
<p>Article URL: <a href="https://ianthehenry.com/posts/bauble/building-bauble/">https://ianthehenry.com/posts/bauble/building-bauble/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=42660942">https://news.ycombinator.com/item?id=42660942</a></p>
<p>Points: 205</p>
<p># Comments: 26</p>
]]></description><pubDate>Fri, 10 Jan 2025 22:22:15 +0000</pubDate><link>https://ianthehenry.com/posts/bauble/building-bauble/</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=42660942</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42660942</guid></item><item><title><![CDATA[New comment by ianthehenry in "Janet for Mortals (2023)"]]></title><description><![CDATA[
<p>It's complicated; Calvin Rose was the original creator of Fennel ("fnl"), but I understand it was just a little side project that he made over the course of a week or so in college. Phil Hagelberg found the project years later and thought it was cool, took over as its maintainer, and basically turned it into the Fennel you know today. So it's like, kind of, I dunno, both things are kinda true.</p>
]]></description><pubDate>Wed, 27 Nov 2024 16:55:48 +0000</pubDate><link>https://news.ycombinator.com/item?id=42257545</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=42257545</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42257545</guid></item><item><title><![CDATA[New comment by ianthehenry in "Janet for Mortals (2023)"]]></title><description><![CDATA[
<p>hi, i am the author of this book and i agree with you. it's not a good connotation. i chose it because: 1. it is kinda memorable (look there are so many programming books with exactly the same name) 2. the language is named after an immortal being who guides mortals through the afterlife in the fictional property <i>the good place</i>, so there's some kinda connection. but i agree the implication that janet is somehow "hard" to learn or that the author is somehow "on a higher plane" is bad. i waffled on this a lot but never came up with another title i could stand and ultimately just pulled the trigger. (but note that i left myself some wiggle room with a neutral domain name.) i hope the tone of the book itself helps to counteract the title, but ya know who knows</p>
]]></description><pubDate>Wed, 27 Nov 2024 16:44:08 +0000</pubDate><link>https://news.ycombinator.com/item?id=42257430</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=42257430</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42257430</guid></item><item><title><![CDATA[New comment by ianthehenry in "Janet for Mortals (2023)"]]></title><description><![CDATA[
<p>delete the contents of the script and then refresh — you’ve loaded an old version of bauble before and have the old tutorial cached in localStorage :/</p>
]]></description><pubDate>Wed, 27 Nov 2024 15:09:04 +0000</pubDate><link>https://news.ycombinator.com/item?id=42256662</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=42256662</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=42256662</guid></item><item><title><![CDATA[New comment by ianthehenry in "Ask HN: What are you working on (September 2024)?"]]></title><description><![CDATA[
<p>hey thanks!</p>
]]></description><pubDate>Mon, 30 Sep 2024 21:27:08 +0000</pubDate><link>https://news.ycombinator.com/item?id=41702333</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=41702333</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41702333</guid></item><item><title><![CDATA[New comment by ianthehenry in "Ask HN: What are you working on (September 2024)?"]]></title><description><![CDATA[
<p>Thanks! Here's the source:<p><pre><code>    (color r2 (vec3
      (fbm 8 :f (fn [q] (rotate (q * 2) (pi * sin (t / 100)) + [t 0]))
        (fn [q] (cos q.x + sin q.y /)) q (osc t 30 30 10) | remap+)))
</code></pre>
Basically taking the function (1 / (cos(x) + sin(y))) and adding it to itself 8 times, each time scaling and rotating the input a little more (:f).<p>I'm curious if it looks the same on all GPUs because it kinda relies on floating point precision errors to give it that film-grainy textured effect. And it definitely divides by zero sometimes.</p>
]]></description><pubDate>Mon, 30 Sep 2024 16:59:46 +0000</pubDate><link>https://news.ycombinator.com/item?id=41699427</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=41699427</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41699427</guid></item><item><title><![CDATA[New comment by ianthehenry in "Ask HN: What are you working on (September 2024)?"]]></title><description><![CDATA[
<p>Oh yeah if you clear localStorage like from dev tools, Bauble will re-save the script before refresh, putting it right back where it was. But if you like cmd-a backspace to empty the contents of the script and then refresh it’ll load the default.</p>
]]></description><pubDate>Mon, 30 Sep 2024 13:30:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=41696873</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=41696873</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41696873</guid></item><item><title><![CDATA[New comment by ianthehenry in "Ask HN: What are you working on (September 2024)?"]]></title><description><![CDATA[
<p>Depending on the data, maybe? SDFs aren't great at rendering large numbers of enumerated objects -- something like a point cloud would be prohibitively expensive, so I wouldn't think to use them for like traditional graphing.</p>
]]></description><pubDate>Mon, 30 Sep 2024 12:14:59 +0000</pubDate><link>https://news.ycombinator.com/item?id=41696288</link><dc:creator>ianthehenry</dc:creator><comments>https://news.ycombinator.com/item?id=41696288</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=41696288</guid></item></channel></rss>