<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: jfecher</title><link>https://news.ycombinator.com/user?id=jfecher</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Tue, 07 Jul 2026 01:57:47 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=jfecher" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by jfecher in "Ante: A new way to blend borrow checking and reference counting"]]></title><description><![CDATA[
<p>Creator of Ante here, passing `Rc<T>` as `&T` or `&Rc<T>` is a somewhat standard practice Ante inherits from Rust and C++ here.<p>As for cycles, `Rc t` in Ante isn't magic and when used in cycles it will leak. Ante does not use region inference, just the related, derived field of borrow-checking. The family tree there roughly resembles MLKit -> Cyclone -> Rust -> Ante in that regard.<p>When borrowing the inner element of an `Rc t`, the type system ensures that the resulting `ref t` cannot be dropped while it is still held. In particular, dereferencing an `Rc t` requires a unique value, but only gives you a shared value to the element: `Rc.as_mut: fn (uniq Rc t) -> mut t`. In practice, this means if you only have a shared ref to an Rc but need a reference to the element inside, you either need to clone the outer Rc (guaranteeing it won't be dropped while the borrow is alive), or use the local uniqueness conversion and avoid using any possible aliases while using the reference.</p>
]]></description><pubDate>Wed, 01 Jul 2026 15:44:15 +0000</pubDate><link>https://news.ycombinator.com/item?id=48748730</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=48748730</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48748730</guid></item><item><title><![CDATA[New comment by jfecher in "Ante: A new way to blend borrow checking and reference counting"]]></title><description><![CDATA[
<p>Most uses of `uniq` in the article aren't necessary and are just included for explicitness. Anywhere a `uniq` ref is required but you only have a `mut` ref, Ante will convert it to a `local uniq` ref with the various rules required while it is still in scope. So you'll still be protected and will get the same compile errors if you try to access an alias while the locally unique reference is still alive.</p>
]]></description><pubDate>Wed, 01 Jul 2026 15:25:40 +0000</pubDate><link>https://news.ycombinator.com/item?id=48748434</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=48748434</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48748434</guid></item><item><title><![CDATA[New comment by jfecher in "Ante: A new way to blend borrow checking and reference counting"]]></title><description><![CDATA[
<p>What would your ideal version look like? I recommend reading the C++ or Rust equivalent code in the article. I like the example because it is copied 1:1 with example code from a textbook with only some keywords changed and a Copy constraint. Any other language without a GC and with unboxed types today represents it far more verbosely to the point where the meaning becomes obscured and a typo becomes more likely to survive code review.</p>
]]></description><pubDate>Wed, 01 Jul 2026 00:47:55 +0000</pubDate><link>https://news.ycombinator.com/item?id=48741147</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=48741147</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48741147</guid></item><item><title><![CDATA[New comment by jfecher in "Ante: A new way to blend borrow checking and reference counting"]]></title><description><![CDATA[
<p>Creator of Ante here. It's just a term I made up for mutation which does not change the "shape" of data in a way that can invalidate any of that data. Mutating a struct or tuple field, even if nested, is stable for example, but mutating an optional string to None is not because you may be dropping a string which there may be a reference to somewhere.</p>
]]></description><pubDate>Wed, 01 Jul 2026 00:44:11 +0000</pubDate><link>https://news.ycombinator.com/item?id=48741115</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=48741115</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48741115</guid></item><item><title><![CDATA[New comment by jfecher in "Ante: A new way to blend borrow checking and reference counting"]]></title><description><![CDATA[
<p>Creator of Ante here, Ante inherits Rust's Send/Sync for thread-safety. `mut` refs and `Rc` which provides shared mutability don't implement either and thus can't be shared across threads. So shared mutability is only within a single thread.</p>
]]></description><pubDate>Wed, 01 Jul 2026 00:42:34 +0000</pubDate><link>https://news.ycombinator.com/item?id=48741106</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=48741106</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=48741106</guid></item><item><title><![CDATA[Safe Aliasable Mutability via Stable References in Ante]]></title><description><![CDATA[
<p>Article URL: <a href="https://antelang.org/blog/stable_mutable_refs/">https://antelang.org/blog/stable_mutable_refs/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=45087812">https://news.ycombinator.com/item?id=45087812</a></p>
<p>Points: 1</p>
<p># Comments: 0</p>
]]></description><pubDate>Sun, 31 Aug 2025 22:54:17 +0000</pubDate><link>https://antelang.org/blog/stable_mutable_refs/</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=45087812</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45087812</guid></item><item><title><![CDATA[New comment by jfecher in "Group Borrowing: Zero-cost memory safety with fewer restrictions"]]></title><description><![CDATA[
<p>> I'm actually hoping to find a way to blend Nick's approach seamlessly with reference counting (preferably without risking panics or deadlocks) to get the best of both worlds, so that we can consider it for Mojo. I consider that the holy grail of memory safety, and some recent developments give me some hope for that!<p>Ante's approach manages to blend a similar scheme for safe, shared mutability with Rc. There are some examples on the most recent blog post on its website of it. IMO combined with its shared types it emulates high-level GC'd code very well.</p>
]]></description><pubDate>Thu, 28 Aug 2025 16:53:19 +0000</pubDate><link>https://news.ycombinator.com/item?id=45054382</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=45054382</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45054382</guid></item><item><title><![CDATA[Stable, Mutable References (PL Design)]]></title><description><![CDATA[
<p>Article URL: <a href="https://antelang.org/blog/stable_mutable_refs/">https://antelang.org/blog/stable_mutable_refs/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=45013649">https://news.ycombinator.com/item?id=45013649</a></p>
<p>Points: 2</p>
<p># Comments: 0</p>
]]></description><pubDate>Mon, 25 Aug 2025 13:30:12 +0000</pubDate><link>https://antelang.org/blog/stable_mutable_refs/</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=45013649</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=45013649</guid></item><item><title><![CDATA[New comment by jfecher in "Why Algebraic Effects?"]]></title><description><![CDATA[
<p>Right, compared to explicitly passing the parameter, with effects:<p>- You wouldn't have to edit the body of the function to thread through the parameter.
- The `can Use Strings` part can be inferred (and in Ante's case, it is my goal to have the compiler write in inferred types for you so that top-level definitions can be inferred if desired but still annotated when committed for code review).
- Most notably, the `can Use Strings` can be included in a type alias. You could have an alias `MyEffects = can Use Strings, Throw FooError`, etc for the effects commonly used in your program. If your state type is used pervasively throughout, this could be a good option. When you have such an alias it also means you'd just be editing the alias rather than every function individually.<p>Generally though, while I think the passing around of state through effects can be useful it isn't the most convincing use of effects. I mention it more for "here's another benefit they can have" rather than "here's this amazing reason you should definitely use them for"</p>
]]></description><pubDate>Sun, 25 May 2025 03:29:39 +0000</pubDate><link>https://news.ycombinator.com/item?id=44085302</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=44085302</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44085302</guid></item><item><title><![CDATA[New comment by jfecher in "Why Algebraic Effects?"]]></title><description><![CDATA[
<p>> As I understand it, AE on low level is implemented as a longjmp instruction with register handling (so you can resume).<p>Not quite. setjmp/lonjmp as they exist in C at least can jump up the call stack but not back down. I mention this at the end of the article but each language implements algebraic effects differently, and efficiency has improved in recent years. Languages can also optimize the effect differently based on how the handler is defined:<p>- Handlers which are tail-resumptive can implement the effect as a normal closure call.<p>- Handlers which don't call resume can be implemented as an exception or just return an error value at every step until the function exits the handler.<p>- Handlers which perform work after resume is called (e.g. `| my_effect x -> foo (); resume (); bar ()` can be implemented with e.g. segmented call stacks.<p>- Handlers where resume is called multiple times need an equivalent of a delimited continuation.<p>Another way to implement these generally is to transform the effects into monads. For any set of effects you can translate it into a monad transformer where each effect is its own monad, or the free monad can be used as well. The cost in this approach is often from boxing closures passed to the bind function.<p>Koka has its own approach where it translates effects to capability passing then bubbles them up to the handler (returns an error value until it gets to the handler).<p>With just a few restrictions you can even specialize effects & handlers out of the program completely. This is what Effekt does.<p>There really are a lot of options here. I have some links at the end of the article in the foot notes on papers for Koka and Effekt that implement the approaches above if you're interested.</p>
]]></description><pubDate>Sun, 25 May 2025 03:23:11 +0000</pubDate><link>https://news.ycombinator.com/item?id=44085281</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=44085281</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44085281</guid></item><item><title><![CDATA[New comment by jfecher in "Why Algebraic Effects?"]]></title><description><![CDATA[
<p>If the database effect wrote to a file it'd require the `IO` effect and code using it would need that effect as well. A compiler can generally show a function to be free of most side effects if it uses no effects. The exceptions to this are things like divergence. As long as the language is Turing complete you can't prove it won't loop forever of course. Another exception could be extern functions which the compiler can't verify the correctness of the type signature. Different languages handle these differently but if users are allowed to write any (and the language doesn't force them to have an IO effect) then they can be a source of unsafety. Languages like Koka and Effekt are considered pure though and enforce this through their effect systems.</p>
]]></description><pubDate>Sun, 25 May 2025 02:56:36 +0000</pubDate><link>https://news.ycombinator.com/item?id=44085191</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=44085191</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44085191</guid></item><item><title><![CDATA[New comment by jfecher in "Why Algebraic Effects?"]]></title><description><![CDATA[
<p>Developer of Ante here. Functions in languages with effect systems are usually effect polymorphic. You can see the example in the article of a polymorphic map function which accepts functions performing any effect(s) including no effect(s). For this reason effect systems are one of the solutions to the "what color is your function" problem.</p>
]]></description><pubDate>Sun, 25 May 2025 02:50:24 +0000</pubDate><link>https://news.ycombinator.com/item?id=44085172</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=44085172</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44085172</guid></item><item><title><![CDATA[New comment by jfecher in "Why Algebraic Effects?"]]></title><description><![CDATA[
<p>Author of Ante here - it actually already has an (extremely basic) LSP. Tooling more or less required for new languages out of the gate these days and I'm eyeing the debugging experience too to see if I can get replayability at least in debug mode by default.</p>
]]></description><pubDate>Sat, 24 May 2025 20:07:10 +0000</pubDate><link>https://news.ycombinator.com/item?id=44083479</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=44083479</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44083479</guid></item><item><title><![CDATA[Why Algebraic Effects?]]></title><description><![CDATA[
<p>Article URL: <a href="https://antelang.org/blog/why_effects/">https://antelang.org/blog/why_effects/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=44071889">https://news.ycombinator.com/item?id=44071889</a></p>
<p>Points: 3</p>
<p># Comments: 0</p>
]]></description><pubDate>Fri, 23 May 2025 11:35:40 +0000</pubDate><link>https://antelang.org/blog/why_effects/</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=44071889</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=44071889</guid></item><item><title><![CDATA[New comment by jfecher in "Algebraic effects, ownership, and borrowing"]]></title><description><![CDATA[
<p>Ante is still mostly unusable unfortunately! Ownership & Borrowing were a relatively recent change and I've still yet to implement them. Algebraic effects are also still in progress in a dev branch and won't be merged for some time. You can use the language today but it will feel more like C with traits, generics, and bugs rather than a more featureful language.<p>The language does have a basic language server already though! It currently supports inline diagnostics and hover to show type.</p>
]]></description><pubDate>Thu, 22 Feb 2024 10:53:35 +0000</pubDate><link>https://news.ycombinator.com/item?id=39465408</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=39465408</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=39465408</guid></item><item><title><![CDATA[New comment by jfecher in "Algebraic effects, ownership, and borrowing"]]></title><description><![CDATA[
<p>Hi, author here!<p>If anyone's curious, here's how ante addresses these issues:<p>- It causes memory unsafety: Ante's `shared` references prevent memory unsafety by preventing projecting them into "shape-unstable" types like a vector's element<p>- Iterator invalidation: This is the previous point in disguise. Since iterating over a shared vector would grab references to its elements - this is prevented since it is shape-unstable. You'd need to clone the elements.<p>- It's effectively threaded: This is the same bug yet again! Once shared-ness is tracked this becomes a non-issue. Ante is still able to have the static guarantee that this can't happen but does not need to prevent sharing to do so.<p>- Safe Abstractions: This section is a bit general but it's worth noting Ante still has the ability to have `&own mut t` references if needed. The `swap` function there could use them for example.<p>Overall the claim that "Aliasing that doesn’t fit the RWLock pattern is dangerous" is fairly rust-centric. It would be dangerous if you had no other restrictions, but we could also adopt different restrictions that still permit aliasing but disallow projection into shape-unstable types instead.</p>
]]></description><pubDate>Thu, 22 Feb 2024 10:43:45 +0000</pubDate><link>https://news.ycombinator.com/item?id=39465352</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=39465352</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=39465352</guid></item><item><title><![CDATA[Programming Language Design: Safe, Shared Mutability with Unboxed Types]]></title><description><![CDATA[
<p>Article URL: <a href="https://antelang.org/blog/safe_shared_mutability/">https://antelang.org/blog/safe_shared_mutability/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=39228417">https://news.ycombinator.com/item?id=39228417</a></p>
<p>Points: 11</p>
<p># Comments: 0</p>
]]></description><pubDate>Fri, 02 Feb 2024 13:40:49 +0000</pubDate><link>https://antelang.org/blog/safe_shared_mutability/</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=39228417</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=39228417</guid></item><item><title><![CDATA[Achieving Safe, Aliasable Mutability with Unboxed Types]]></title><description><![CDATA[
<p>Article URL: <a href="https://antelang.org/blog/safe_shared_mutability/">https://antelang.org/blog/safe_shared_mutability/</a></p>
<p>Comments URL: <a href="https://news.ycombinator.com/item?id=39205218">https://news.ycombinator.com/item?id=39205218</a></p>
<p>Points: 1</p>
<p># Comments: 0</p>
]]></description><pubDate>Wed, 31 Jan 2024 15:50:52 +0000</pubDate><link>https://antelang.org/blog/safe_shared_mutability/</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=39205218</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=39205218</guid></item><item><title><![CDATA[New comment by jfecher in "Ante: A low-level functional language"]]></title><description><![CDATA[
<p>Hi! An uninterpreted function is one where the only thing we can assume about it is that `(x = y) => (f x = f y)`. That is if we give it the same input, we should get the same result out. In the context of refinement types this can be used for, among other things, tagging values with some predicate.
For example, if we know `good_index array 3` and `x = 3` then we know `good_index array x`.</p>
]]></description><pubDate>Mon, 20 Jun 2022 01:57:46 +0000</pubDate><link>https://news.ycombinator.com/item?id=31805495</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=31805495</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=31805495</guid></item><item><title><![CDATA[New comment by jfecher in "Ante: A low-level functional language"]]></title><description><![CDATA[
<p>C can sometimes be an easier target since you don't have to learn LLVM's API.
C is also more portable than llvm since there is a greater variety of C compilers for a greater variety of architectures than llvm targets.</p>
]]></description><pubDate>Sat, 18 Jun 2022 03:09:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=31786974</link><dc:creator>jfecher</dc:creator><comments>https://news.ycombinator.com/item?id=31786974</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=31786974</guid></item></channel></rss>