TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

The Ultimate Conditional Syntax

145 pointsby azhenley7 months ago

14 comments

dan-robertson7 months ago
I like that there is this left-to-right flow. I think it’s a bit nicer to read than if-let ordering where the pattern comes before the thing it will be matched against. I think it’s also good for ocaml-style constructor disambiguation, which tends to go in lexical order.<p>Another nice aspect of making guards a less special case is that it avoids complexities in deciding if a binding is unused. I believe this logic was a source of lots of compiler warning bugs in ocaml.<p>This syntax doesn’t seem to solve the following problem with matching where there are two paths to the same binding, (say you have an option in one branch but it isn’t optional in the other, and maybe you’d like to handle both cases with the same code. Currently you can do that with a match (match …) with … pattern.<p>I worry that the semantics around exhaustiveness and mutable values may be confusing, though I guess OCaml already has that problem:<p><pre><code> type t = { mutable x : bool } let n = function true -&gt; 1 | false -&gt; 0 let f t = match t with | { x = false } when ( t.x &lt;- true; false) -&gt; -1 | { x } -&gt; n x * 2 + n t.x </code></pre> What does t { x = false } return? Similarly if you changed the second case to be two cases instead of binding x?
评论 #41900278 未加载
klauserc7 months ago
C# pattern matching gets very close. I think C# can do everything except for their last example (&quot;splitting conditional prefixes in arbitrary places&quot;). One of the things I miss when switching to Rust.<p><pre><code> if foo(args) == 0 then &quot;null&quot; |&gt; abs &gt; 100 then &quot;large&quot; &lt; 10 then &quot;small&quot; else &quot;medium&quot; </code></pre> That last syntax took me a while to parse in the paper, but I can imagine numerous places in our everyday code where such syntax would more concisely capture intent.
评论 #41908403 未加载
评论 #41908888 未加载
评论 #41907446 未加载
upghost7 months ago
Kudos to the authors. It takes some fortitude to try to make a contribution to something as fundamental and ubiquitous as the &quot;if&quot; statement. Appreciate providing the grammar and the thorough explanations, will save a lot of pain when trying to implement!
zelphirkalt7 months ago
&gt; Below, the code on the left is equivalent to the more verbose ML expression on the right:<p>Wait a sec ... ML has the pipe of Elixir? Damn, I didn&#x27;t know that!<p>I like the brevity, but I don&#x27;t like the (at least visual) need to indent or whitespace focus. I guess I am too much a sucker for S-expressions now. But a similar structure could probably be written as a macro in a lisp, avoiding any whitespace focus or even dependency on it.
评论 #41903854 未加载
clark8007 months ago
Looks very similar to lambda zero syntax (<a href="https:&#x2F;&#x2F;github.com&#x2F;clark800&#x2F;lambda-zero">https:&#x2F;&#x2F;github.com&#x2F;clark800&#x2F;lambda-zero</a>):<p><pre><code> def getNaturalName(tag, globals) if globals.lookup(&quot;0&quot;) is Just(Global(_, _, term)) if term is Numeral(_, type, _) return Just(Name(getTermTag(type))) error showSyntaxError(&quot;0 must be a numeral to use numerals&quot;, tag) return Void </code></pre> Though this ultimate conditional syntax is more general because lambda zero only allows one destructuring per conditional to simplify parsing.
评论 #41907919 未加载
andyferris7 months ago
The other one I want occassionally is &quot;or&quot;.<p>Imagine Left and Right contained data of compatible types, then I&#x27;d like to extract that data (regardless of tag) like so:<p><pre><code> if x is Left(y) or x is Right(y) then ... </code></pre> That way I only need to write the `...` part once. (This could be combined with the rest of the pattern matching machinery in interesting ways, and would probably need to have eager matching &#x2F; short-circuiting semantics in case both cases match).
评论 #41900262 未加载
hoosieree7 months ago
They missed one:<p><pre><code> def agent(data, predicate, fns): ps = map(predicate, data) fs = map(lambda x:fns[x], ps) return map(fs, data) </code></pre> Basically you want to apply one of N functions to each of the items in your data iterable, so you have a predicate to figure out which function to apply first. The degenerate case is when you have just 2 functions and your predicate returns a boolean (0 or 1).<p>This is &quot;agent&quot; from J: <a href="https:&#x2F;&#x2F;code.jsoftware.com&#x2F;wiki&#x2F;Vocabulary&#x2F;atdot#agent" rel="nofollow">https:&#x2F;&#x2F;code.jsoftware.com&#x2F;wiki&#x2F;Vocabulary&#x2F;atdot#agent</a>
huqedato7 months ago
Elixir already has this - &quot;with&quot;. <a href="https:&#x2F;&#x2F;www.openmymind.net&#x2F;Elixirs-With-Statement&#x2F;" rel="nofollow">https:&#x2F;&#x2F;www.openmymind.net&#x2F;Elixirs-With-Statement&#x2F;</a> E.g.:<p><pre><code> with true &lt;- is_email_address?(email), true &lt;- String.length(code) === 6, %EmailConfirmation{} &lt;- EmailConfirmations.get_email_confirmation(email), nil &lt;- EmailAddresses.get_email_address(email), {:ok, user} &lt;- Users.create_user(data), {:ok, email_address} &lt;- EmailAddresses.create_email_address(user, email) do ... else ... end</code></pre>
评论 #41900911 未加载
评论 #41899154 未加载
lou13067 months ago
Kudos for publishing in OOPSLA, but alas I&#x27;m skeptical. This seems to add visual clutter&#x2F;mental overhead as one needs to parse a decision tree rather than having a &quot;flat&quot; sequence of patterns with the optional when-condition.<p>Also,<p>&gt; all the branches in the corresponding pattern matching expression would need to destructure the pair, even when only one of its components is needed<p>Can&#x27;t one just bind the unneeded component to _ ? Isn&#x27;t that actually a good thing, as it clearly self-documents we won&#x27;t need that value on that branch?
thom7 months ago
There&#x27;s an online playground for MLscript at:<p><a href="https:&#x2F;&#x2F;hkust-taco.github.io&#x2F;mlscript&#x2F;" rel="nofollow">https:&#x2F;&#x2F;hkust-taco.github.io&#x2F;mlscript&#x2F;</a>
评论 #41908364 未加载
ajb7 months ago
This is really cool<p>It reminds me a lot of the kind of flow you get in mathematics sometimes. I guess theorem prover languages may be keen to adopt it.<p>I&#x27;d be less keen in a language with side effects, unless the language has a way to restrict it to pure functions
评论 #41904550 未加载
mgaunard7 months ago
I don&#x27;t understand how it&#x27;s better than traditional pattern matching.
评论 #41898886 未加载
评论 #41899208 未加载
breck7 months ago
I love this.<p>Not the implementation, I think one could do better, but the fact that they identified an interesting opportunity: coming up with the Ultimate Conditional Syntax for pattern matching.<p>I would love to see them take one more crack at it, and this time try to think about how to reduce the syntax to the bare minimum.<p>Here&#x27;s my read&#x2F;adding of this language to PLDB: <a href="https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=UzsDaq0UdnM" rel="nofollow">https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=UzsDaq0UdnM</a>
andrewstuart7 months ago
This is the ultimate conditional syntax:<p><pre><code> if (x === 1) console.log(“it’s 1”) </code></pre> The “if” bothers me though, be nice not to have it.
评论 #41902758 未加载