<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: mrkeen</title><link>https://news.ycombinator.com/user?id=mrkeen</link><description>Hacker News RSS</description><docs>https://hnrss.org/</docs><generator>hnrss v2.1.1</generator><lastBuildDate>Tue, 20 Oct 2026 08:55:00 +0000</lastBuildDate><atom:link href="https://hnrss.org/user?id=mrkeen" rel="self" type="application/rss+xml"></atom:link><item><title><![CDATA[New comment by mrkeen in "Parser Combinators"]]></title><description><![CDATA[
<p>What kind of mapping/unwrapping are you being subjected to with PCs?</p>
]]></description><pubDate>Sun, 18 Oct 2026 13:37:36 +0000</pubDate><link>https://news.ycombinator.com/item?id=50141000</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50141000</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50141000</guid></item><item><title><![CDATA[New comment by mrkeen in "Parser Combinators"]]></title><description><![CDATA[
<p>Tokenising is actually a strength of PC, it fits the parser structure exactly!<p><pre><code>  pToken :: Parser<Bytestring, Token>

  pExpr :: Parser<List<Token>, Expr></code></pre></p>
]]></description><pubDate>Sun, 18 Oct 2026 13:33:44 +0000</pubDate><link>https://news.ycombinator.com/item?id=50140976</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50140976</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50140976</guid></item><item><title><![CDATA[New comment by mrkeen in "Parser Combinators"]]></title><description><![CDATA[
<p>If you use an Either instead of a List, then you can write an <i>or</i> combinator, which accepts two parsers and tries the second if the first fails.  It branches on the Left/Right of the Either.<p>If it's a List, wouldn't you be forced to write the Cartesian product of two parsers instead?</p>
]]></description><pubDate>Sun, 18 Oct 2026 13:23:22 +0000</pubDate><link>https://news.ycombinator.com/item?id=50140892</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50140892</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50140892</guid></item><item><title><![CDATA[New comment by mrkeen in "Parser Combinators"]]></title><description><![CDATA[
<p>Each parser blindly follows its own rules.<p>If pDigit saw "123 ", according to TFA's design, it would return (1, "23 ").<p>If PInt saw the "123 ", it would return (123, " ").<p>You could <i>approximate</i> pInt in terms of pDigit via:<p><pre><code>  PInt = many1 pDigit
</code></pre>
(Ignoring negatives, int maxvalue, and many1 implies 1-or-more, not 0-or-more.)<p>I say "according to TFA's design" because I've been arguing elsewhere that parsers must return Either<Error,(T, Remainder)> not (T, Remainder)</p>
]]></description><pubDate>Sun, 18 Oct 2026 13:17:00 +0000</pubDate><link>https://news.ycombinator.com/item?id=50140843</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50140843</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50140843</guid></item><item><title><![CDATA[New comment by mrkeen in "Parser Combinators"]]></title><description><![CDATA[
<p>No.  The parser code (in a library that everyone depends on) will branch on success/fail internally.  It has nothing to branch on if it only sees T, because T may not have a success/fail nature.<p>You could take a step back and make sure T has a fail case, e.g. T-extends-Either<A, B>, but what is to be gained?<p>* Firstly, what the hell is A?<p>* The user would need to type Parsers of T=Cat and T=Dog instead as Parsers of T=Either<Error,Dog> and T=Either<Error,Cat>.  If everyone has to do it, pull the common abstraction back into the library itself!  Also the caller would receive a successful parse of T=Either and would then need to check to see if it was success(success) or success(fail).<p>* You also mix abstractions in the same way as newlines in string literals.  You could no longer represent a successful parse of a failed Either, since the failed Either would look like a parse error.</p>
]]></description><pubDate>Sun, 18 Oct 2026 13:05:56 +0000</pubDate><link>https://news.ycombinator.com/item?id=50140761</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50140761</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50140761</guid></item><item><title><![CDATA[New comment by mrkeen in "Parser Combinators"]]></title><description><![CDATA[
<p>No, that was my ironically landed upon definition of partial.<p>The article used it as in a sub-parser, which is the other thing I objected to.  If you add two Integers, you get back an Integer, not a Sum.  Same principle here, two parsers make a parser.  You don't need to write new code to combine a partial parser with a parser, or vice versa.</p>
]]></description><pubDate>Sun, 18 Oct 2026 11:50:28 +0000</pubDate><link>https://news.ycombinator.com/item?id=50140242</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50140242</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50140242</guid></item><item><title><![CDATA[New comment by mrkeen in "Parser Combinators"]]></title><description><![CDATA[
<p>Not a good starting type:<p><pre><code>  type Parser<T> = (input: string) => [T, string]
</code></pre>
This implies that it accepts a string and <i>will return</i> a T.  Parsers <i>might</i> return a T.<p>The article also starts with the concept of a 'partial parser', from which other (non-partial?) parsers can be constructed?<p><pre><code>  Or, and this is where the real power of partial parsers comes in: we wrap the chain up as a new parser of its own.
</code></pre>
Nope, there's no distinction.  If you combine partial parsers, you end up with a partial parser.  If you combine full parsers (whatever that means) you end up with full parsers.<p>(Ironically there is a fitting definition of 'partial' here: the function isn't well defined on all inputs.  For some inputs, T is returned, on other inputs, maybe an error is thrown, who knows..)</p>
]]></description><pubDate>Sun, 18 Oct 2026 10:53:55 +0000</pubDate><link>https://news.ycombinator.com/item?id=50139895</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50139895</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50139895</guid></item><item><title><![CDATA[New comment by mrkeen in "Microsoft Teams is a red flag"]]></title><description><![CDATA[
<p>The last time I was part of a Teams environment (late 2025 or early 2026), search literally did not work.<p>I could see the keywords right there in the chat, enter them into the search bar, and get back 'no results found'.<p>(This was across at least a period of months too, not just an intermittent bug)</p>
]]></description><pubDate>Sun, 18 Oct 2026 06:10:08 +0000</pubDate><link>https://news.ycombinator.com/item?id=50138345</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50138345</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50138345</guid></item><item><title><![CDATA[New comment by mrkeen in "Types of types: Haskell's Kind system"]]></title><description><![CDATA[
<p>"Generic" and "for a particular type" cancel out.<p>You don't need List<A> to write an IntList, nor do you need + to work on different integers in order to have a particular integer.</p>
]]></description><pubDate>Sun, 18 Oct 2026 05:50:06 +0000</pubDate><link>https://news.ycombinator.com/item?id=50138260</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50138260</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50138260</guid></item><item><title><![CDATA[New comment by mrkeen in "Types of types: Haskell's Kind system"]]></title><description><![CDATA[
<p>Just to polish that,<p><i>ArrayList</i>'s kind is type->type<p><i>ArrayList<A></i>'s kind is type.<p>The <i>A</i> is what plugs into <i>type</i> on the LHS of the arrow, leaving only the RHS remaining.</p>
]]></description><pubDate>Sun, 18 Oct 2026 05:33:50 +0000</pubDate><link>https://news.ycombinator.com/item?id=50138190</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50138190</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50138190</guid></item><item><title><![CDATA[New comment by mrkeen in "Types of types: Haskell's Kind system"]]></title><description><![CDATA[
<p>> As any problem can be expressed in C, how would what the author did look like in C? KISS<p>This is C.<p><pre><code>  void * bsearch (const void *key, const void *array, size_t count, size_t size, comparison_fn_t compare)
</code></pre>
How do you express "the thing you get back has the same type as the thing you're looking for"?</p>
]]></description><pubDate>Sun, 18 Oct 2026 05:18:04 +0000</pubDate><link>https://news.ycombinator.com/item?id=50138125</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50138125</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50138125</guid></item><item><title><![CDATA[New comment by mrkeen in "11 year old unsoundness bugs found in Rust borrow checker"]]></title><description><![CDATA[
<p>AFAIK there isn't a language spec.  Rustc is the language for now.</p>
]]></description><pubDate>Tue, 13 Oct 2026 11:26:13 +0000</pubDate><link>https://news.ycombinator.com/item?id=50069960</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50069960</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50069960</guid></item><item><title><![CDATA[New comment by mrkeen in "11 year old unsoundness bugs found in Rust borrow checker"]]></title><description><![CDATA[
<p>Type systems are hard!  Check out <a href="https://counterexamples.org/" rel="nofollow">https://counterexamples.org/</a><p>I gave it a quick scan for Rust examples; there are 11 samples among the following pages:<p><pre><code>  https://counterexamples.org/eventually-nothing.html
  https://counterexamples.org/mutable-matching.html
  https://counterexamples.org/selfishness.html
  https://counterexamples.org/scope-escape.html
  https://counterexamples.org/nearly-universal.html
</code></pre>
The first thing I always look for is mutability (<i>combined</i> with some other tricky feature), e.g. "Now it's a <i>Just(3):Maybe<Int></i>, now it's a <i>Nothing:Maybe<Int></i>, now it's a <i>Nothing:Maybe<String></i>."<p>I wonder if TFA's example could be reproduced without mutability.</p>
]]></description><pubDate>Tue, 13 Oct 2026 11:16:53 +0000</pubDate><link>https://news.ycombinator.com/item?id=50069883</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50069883</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50069883</guid></item><item><title><![CDATA[New comment by mrkeen in "Elisha Wiesel: The Death of the Nobel Peace Prize"]]></title><description><![CDATA[
<p>The IDF doesn't need your optics.  They really don't give a shit.<p><pre><code>  I have ordered a complete siege on the Gaza Strip. There will be no electricity, no food, no fuel, everything is closed. We are fighting human animals and we are acting accordingly.

  Cited in Defense minister announces ‘complete siege’ of Gaza: No power, food or fuel, The Times of Israel (9 October 2023).</code></pre></p>
]]></description><pubDate>Sat, 10 Oct 2026 11:41:55 +0000</pubDate><link>https://news.ycombinator.com/item?id=50031914</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50031914</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50031914</guid></item><item><title><![CDATA[New comment by mrkeen in "Clojure in the age of language models"]]></title><description><![CDATA[
<p>> A bigger problem is the tedious necessity of having to reconstruct the desired state every single run. When you have something small with limited functionality, that is fine, but as your application grows, rebuilding the state can take a significant effort.<p>This is what tests are for.  There should be no buildup of internal state that can't be arrived at with a simple invocation in a unit test.</p>
]]></description><pubDate>Thu, 08 Oct 2026 09:21:10 +0000</pubDate><link>https://news.ycombinator.com/item?id=50003617</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=50003617</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=50003617</guid></item><item><title><![CDATA[New comment by mrkeen in "The complement of true is true, except when it's false"]]></title><description><![CDATA[
<p>You have some expectations of the size of the bool (it's simply 1 bit but also 8 bits.)<p>What expectations do you have of the value?</p>
]]></description><pubDate>Tue, 06 Oct 2026 13:54:48 +0000</pubDate><link>https://news.ycombinator.com/item?id=49978551</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=49978551</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49978551</guid></item><item><title><![CDATA[New comment by mrkeen in "Cloudflare K2: serverless event streams"]]></title><description><![CDATA[
<p>To support the ordered use-case, put events on the same topic-partition.  To support the unordered use-case, don't.</p>
]]></description><pubDate>Thu, 01 Oct 2026 20:25:12 +0000</pubDate><link>https://news.ycombinator.com/item?id=49926646</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=49926646</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49926646</guid></item><item><title><![CDATA[New comment by mrkeen in "How to speed up the Rust compiler in September 2026"]]></title><description><![CDATA[
<p>If you built two impls, your compiler wouldn't know which to pick.  Or to phrase it differently, if you wanted to be able to choose the right one, it wouldn't be 'orphan impls', it would be 'orphan impls plus some selection mechanism'.  E.g. Scala implicits.  And once you have Scala implicits, non-orphan impls probably start looking like a pretty sweet alternative!</p>
]]></description><pubDate>Thu, 01 Oct 2026 19:07:02 +0000</pubDate><link>https://news.ycombinator.com/item?id=49925787</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=49925787</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49925787</guid></item><item><title><![CDATA[New comment by mrkeen in "Needed 1+1, built a functional programming language"]]></title><description><![CDATA[
<p>I'm absolutely stuck on your comment that trees are the wrong approach, or that trees are somehow incompatible with precedence.  They encode the precedence more explicitly and unambiguously than the original string itself.<p>Trees being incompatible with precedence is like parentheses being incompatible with precedence.</p>
]]></description><pubDate>Wed, 30 Sep 2026 15:47:46 +0000</pubDate><link>https://news.ycombinator.com/item?id=49910511</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=49910511</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49910511</guid></item><item><title><![CDATA[New comment by mrkeen in "Needed 1+1, built a functional programming language"]]></title><description><![CDATA[
<p>Agree with 'solve it during parsing'.<p>I had a look at the link.  The BNF looked good:<p><pre><code>  Expr =
    Expr '+' Expr
    ...
</code></pre>
Then the author fixed the left-recursion and precedence (which also looks good,) but then complains about the fixed version - "the “shape” of expressions feels completely lost in this new formulation." :<p><pre><code>  Expr =
    Factor
  | Expr '+' Factor
  ...
</code></pre>
Then the author takes us through Pratt parsing and ends up at:<p><pre><code>  fn expr_bp(lexer: &mut Lexer, min_bp: u8) -> S { 
    let mut lhs = match lexer.next() {
        Token::Atom(it) => S::Atom(it),
        t => panic!("bad token: {:?}", t),
    };

    loop {
        let op = match lexer.peek() {
            Token::Eof => break,
            Token::Op(op) => op,
            t => panic!("bad token: {:?}", t),
        };
    ...
</code></pre>
Yikes!  I think he criticised the wrong code.  I'll take the '{expression} is a {factor} or an {expression plus a factor}' formulation over the 'mut-loop-peek-panic-lexer-next' approach any day!</p>
]]></description><pubDate>Wed, 30 Sep 2026 13:25:00 +0000</pubDate><link>https://news.ycombinator.com/item?id=49908614</link><dc:creator>mrkeen</dc:creator><comments>https://news.ycombinator.com/item?id=49908614</comments><guid isPermaLink="false">https://news.ycombinator.com/item?id=49908614</guid></item></channel></rss>