Creating a Swift syntax extension: the Lisp 'cond' function
appventure.me
appventure.me
func cond<T>(#fallback: T, testsAndExprs: (test: @auto_closure () -> Bool, expr: @auto_closure () -> T)...) -> T {
for (t, e) in testsAndExprs {
if t() {
return e()
}
}
return fallback
}
And in use: // y is assigned "0 == 0, of course"
let y = cond(fallback: "fallback", (test: false, expr: "not this branch"), (test: 0 == 0, expr: "0 == 0, of course"))I do like the idea of @auto_closure, but I bet it will confuse the hell out people reading swift code unless the IDE highlights it in some way.
But i'm going to be the first one to point out that having function arguments not evaluated at call time is very, very unintuitive. Anyone with a background in traditional (procedural/OO) languages is reasonably going to expect both `perform_side_effects` calls to be invoked here.
var ctest = cond_1(a == 1, 2 + perform_side_effects1(),
a == 2, 3 + perform_side_effects2(),
0)Scala is another language that supports declaration-site opt-in for non-strict evaluation, very similarly to how swift seems to be doing it. I'm not the biggest fan of Scala, but my limited experience with it has left me with the impression that you can't trust any normal-looking code to actually be normal until you look at its documentation and/or source.
- exceptions short circuiting one of the side effects (C++, C#, etc.)
- the indeterminate order of execution of the side effects (C, C++)
- macros with conditional evaluation behavior (such as assert depending on... _DEBUG? NDEBUG?)
> ...
> Much like a switch statement,
No. cond is nothing like a switch statement. cond is Lisp's version of if..else if...else if..else.
The distinction being, of course, that if you have a contiguous range of cases in your switch statement, a proper C compiler will compile it to an O(1) jump table, rather than an O(n) set of tests like an extended if-statement. This is so crucial and basic a distinction that I am astounded every time I find another person claiming that cond==switch.
The closest thing that Lisp has to a switch statement (and this is a significant failing in the language) is CASE. And that's only if you are careful and have a very smart compiler -- not sure if SBCL will jump-table it for you, for example.
I sympathize with the idea of creating a language mostly defined as a library of itself.
It's nerdy, it's neat, it's minimal, it's very Lattnerish.
But it has a fatal flaw: it assumes people will use that feature set in an intelligent, restrained, minimal way. For good.
And let's face it. Most of us devs are fucking morons. It took people only a few days to start abusing it. I wonder where we'll be a year from now.
We're not special. Like everything else in the world, developers follow Sturgeon's law.