Variable argument lists?
Re: multi-way if, how about something like
if := fun (cond, lazy then) `(conds, lazy thens) {
case cond {
false, 0, nil := case conds.len {
0 := nil
_ := if `(conds, thens)
}
_ := then
}
}
else := true
if { x = 2,
println("x is 2")
} { x < 2,
println("x is less than 2")
} { else,
println("x is more than 2")
}
That is, the ` signifies that the whole argument list can occur multiple times, and will be ‘unzipped’ into two sequences conds and thens. We can then proceed by recursion/iteration. Inside the function, you can also see the arglists being zipped back up and recursed on — the first of each will make up the mandatory arglist at the beginning, which is checked next. When we run out, conds.len is zero (and so if thens.len, of course), and we stop.
Similarly to this, regular varargs uses a backtick, kwargs… I don’t know. Double backtick looks weird, but maybe I’ll get used to it. Though writing fun(a, `bs, ``cs) in Markdown takes three backticks (or more) as the delimiters.
The reason I changed my mind from going with the flow and using * is that I don’t want placement of spaces to be significant, and if * (conds, thens) just looks too much like multiplication. It was all right when it was inside the brackets, but not now. Either way, it doesn’t ruin the consistency of the syntax that much to have backticks outside brackets; fun already has to be a special form as its arguments introduce new names.
Another problem is this:
weird := fun `(_) { 2 }
weirder := weird
Now, what is weirder? Is it weird applied to zero arglists, i.e. 2? Or is it another name for the same function? Probable answer: neither, because fun must have at least one mandatory arglist, so it would have to be:
weird := fun `(_) () { 2 }
not_as_weird := weird()
Also, as shown here, I don’t really see a reason why the varargs have to go at the end, as long as there is only one of them per arglist, and only one varlist per function. If certainly doesn’t help with the ambiguity here:
returned := fun (arg) `(args) { ... }
returner := fun (arg) `(args) { ...; returned }
what := returner(1)(2)(3)(4)(5)(6)
How do we split up the arglists between returner and returned here? I have no idea! Maybe this is why no-one else has varlists!
Way way way up at the top, you may have noticed that I had a parameter lazy then, instead of ?then as I said yesterday. And well noticed! I just changed my mind, that’s all. There’s also fun arg for an argument that’s not cached, but re-evaluated whenever it’s mentioned, for use as loop bodies and things like that:
repeat := fun (times) (fun body) {
if { x > 0, (body; repeat(times - 1)(body)) }
}
Perhaps I should also note that I intend to have some sort of iteration primitive, I just haven’t decided what yet. This language is going to be slow enough without having to express everything as recursion with no TCO (at least to start with).
And I think I’m keeping the brace/paren equivalence, as the samples here presumably made clear. I know this lets you write dumb things like fun {x} (x + 3), but I’ll just have to make sure not to.
