3 ms·
Great work! Love the well-documented source. Will definitely look through it and try out the language. I have used Swift quite a lot in 2014, and loved the way
by jafingi 12y ago
Great work! Love the well-documented source. Will definitely look through it and try out the language.
I have used Swift quite a lot in 2014, and loved the way to do ranges. But it's the complete opposite of Wren:
1...8 includes BOTH 1 and 8. Wren would not include 8.
Is this an error in the documentation, or the actual design of the language?
In the beta of Swift, 1..8 was not including 8. But I really like a change in the final version where it instead is done using 1..<8
It makes it much easier to discern between the two;
1...8
1..8
vs.
1...8
1..<8
- munificent 12y ago> Is this an error in the documentation, or the actual design of the language? It's the actual design. It follows Ruby and (I think?) Perl. Personally "..." feels more naturally inclusive to me since it has one more "." than ".." and thus one more item in the result. But I thought it would be more helpful to follow in the footsteps of existing languages. The Swift solution is definitely explicit but looks kind of ugly to my eyes. Syntax design can be hard.
- gjm11 12y agoI wonder about something like for (0 <= i <= 10) which has obvious (and transparent) variants for making one or both bounds exclusive. For bonus points for (10 >= i >= 1) etc. for looping downwards. You could have unbounded loops too for (0 < i) where you can tell which bit is meant to be declaring a loop variable because it's always the one after the inequality. For extra points, make mathematicians happy with things like this: for (0 <= i < j < 10) which does 45 iterations or for (1 <= i,j,k <= n) which does n^3 iterations, where again you can tell which bits are meant to be declaring loop variables: all but the first and last. These are less transparent because they don't make it clear what order things should be done in; they might also introduce the temptation to introduce fancy syntax to control this, to skip to "the next value of i", etc., which might be complexity that doesn't pay its way. This plays pretty well with filtering as in list comprehensions: for (1 < i < j < 100) where (isGood(i) && isBad(j)) { ... } One possibly-killer drawback to this kind of thing: it makes for a nice for-loop syntax but there's a lot to be said for saying that for-loops are always just iterating over some sort of collection, and turning these into collections might again require more syntactic complication than they justify. E.g., the simplest would be something like this: for (i in (i : 0 <= i <= 10)) which feels painfully repetitititititive with all those "i"s and doesn't generalize well to the fancy versions with multiple variables (but maybe those are a bad idea anyway). It's not hard to think of ways to reduce the repetition but they have their own drawbacks and in any case this comment is too long already. [EDITED to add: All this only makes sense if your syntax allows for "chained" inequality operators. But it really should anyway. (It looks like Wren's doesn't at present, maybe because it's hard to square with the principle that infix operators are always just single-arg method calls in disguise.)]
- munificent 12y agoThat starts to look fairly complex to me. In code that I've looked at, doing numeric iteration is actually not that common. The majority is just iterating over collections. Wren's grammar for loops is actually really simple. It's just: for (<variable name> in <expression>) { ... } That's it. Note that there's no special support for numeric ranges. Instead, ".." and "..." are just regular operator calls. The number type implements them to return a range object. That lets you do: for (n in 1..10) { ... } But also enables: var range = 1..10 for (n in range) { ... } And even: var items = ["a", "b", "c", "d"] var slice = items[1..2] Making the range a first-class object lets you get a lot of mileage out of using it in different places, which is nice. In fact, a range derives from the sequence base class, so you can also do: var evens = (1..10).where {|n| n % 2 == 0}
- gjm11 12y agoYup, strongly agree that having a single iterate-over-collection construct and a nice notation for ranges has big advantages. (I did say that before, but I guess it was buried in among a lot of other stuff.) The drawback is that the nice terse range notation leaves it unclear whether your ranges are inclusive or exclusive (and I conjecture that if you asked 100 experienced software people to guess which of 1..8 and 1...8 is which, you'd get something close to 50% jumping each way). What I'd really like is a syntax for ranges that has clarity comparable to "for (0 <= i < n)" but terseness comparable to "0...n", without being too much a special case. Unsurprisingly, I've never yet seen one. Here's a less-than-half-baked proposal, though. Probably too quirky for Wren. 1. Some syntax like [1 <= i < n] -- inequality operators, delimited in an appropriate way -- indicates a range object and, at least at parse time, carries around an indication of the name of the index variable. (Index variables if we allow fancy stuff like [1 <= i < j < n].) 2. "for <literal-range>" is syntactic sugar for "for (i in <literal-range>)" where i is the name of the variable. (If we allow fancy multi-variable ranges, this only works if your for-loop is able to bind multiple variables as with "for (i,j) in [(1,2),(3,4)]" in Python.) 3. Perhaps "for <literal-range> where <condition>" is likewise syntactic sugar for "for (i in <literal-range>.where(<condition>))" or something. 4. So far, this is less general than your .. and ... operators because it's all special-cased for integers. Except there's no reason why it needs to be. Perhaps, e.g., [a < i < b] invokes a magical method on a, which gets passed the upper bound b and an indication of direction and inclusivity at each end. My fancy multi-variable forms can be implemented in terms of this without any further magic, though not maximally efficiently. [EDITED to add: It happens that I quite often have use for numeric iteration, and even for the fancy multi-variable forms I've described here. But I'm probably atypical.]