for i in 1..<10 where i % 2 == 0 {
print(i)
}
But you can immediately understand how it works, because it's consistent with the rest of the language and reads well. for my $i ( 1..(10-1) ) {
next if $i % 2 == 0;
print $i;
}
Here Perl's post-conditional syntax (which works only on a statement and not a block so it's more manageable) combines well with "next" (Perl's version of "continue") to very clearly convey intent without a lot of extra boilerplate. An additional clause is often just an additional line. Comments after each can provide additional context as needed. I think this is a more flexible way to accomplish the same thing, and more readable in all but the simplest of cases. And for those simplest of cases, I would use a grep, which is also useful in other parts of the language: for my $i ( grep { not $_ % 2 } 1..(10-1) ) {
print $i;
}
Any syntax learned that works as a special case to only a single structure is either a case of missed opportunity or a case of extra syntax that needs to be learned which shouldn't be, IMO. switch i {
case 1...100 where i % 2 == 0:
print("\(i) is a small even number")
case ..<0:
print("\(i) is negative")
default:
print("I couldn't care less")
}
Or generic constraints: struct Vector<T> where T: Numeric {
// ...
}
If you so wish, you can always use any of the functional constructs as well, as in for i in (0..<10).filter { $0 % 2 == 0 } {
print(i)
}One of the biggest criticisms that Perl gets is that there's so many different ways to do things, and that's somewhat deserved, so the question is what does "where" offer that "filter" doesn't other than another keyword and concept you have to learn to understand the language? What's the point if it's not really that much more expressive or clear?
> struct Vector<T> where T: Numeric
Is this really the same thing? This seems like a case where the same word is used to mean something else, even if they are loosely conceptually the same.
So, feedback, from someone whose exposure to Swift consists basically of this article but has eaten a metric crapload of many other braced languages over the decades.
What I can tell is that the programmer wanted to print 2,4,6,8. So the intentional readability is there. However when it comes to understanding how it works (i.e. the language mechanics delivering the intuitive reading) I had lexical concerns. I couldn't immediately tell whether the where-clause acts like a guard predicate in the for-statement or an unbraced if-statement i.e. equivalent to
for i in 1..<10 {
next if !(i % 2 == 0)
print(i)
}
or for i in 1..<10 {
if (i % 2 == 0) {
print(i)
}
}
or even (let's hope not) if (i % 2 == 0) {
for i in 1..<10 {
print(i)
}
}
and in a similar vein the lexical scope and binding of i was not clear to me; some languages bind the iterated variable at the level of the statement, others inside the iterated body (which may even be a closure for all I know), and this has implications particularly for the the value of i after the loop, for the binding of i in any function generated inside the loop (example: print could actually talking to an IO object that defers output by prepending lambdas to a chain - I've seen web containers deferring view rendering this way), for name masking, and for the consequences of any flow-control/continuation/exception mechanism that may cause an early loop exit.I do not know Swift's scoping rules and having read through the introductory guide and the flow control chapter I still can't tell you if the loop variable remains visible after the loop, and what it is bound to if so.
No doubt that if I sat down with a REPL or an IDE it'd hopefully be evident by example within a few seconds, but the claim was about dry-reading, not interactive experience.
I'll leave it there with an admonishment against making assumptions/declarations about the obvious-ness of something you're already familiar with.
So I'm not actually calling Swift a major offender, but noting generally that I don't there's ever been a language in which the intuition gap between intention and mechanics was small enough to be irrelevant.
(something at the back of my mind is now whispering "Scheme", but too quietly to be taken seriously)
Is there a case to be made for other behavior? Or an example of a language that intentionally treats it any differently? (Unless you go out of your way to iterate over a variable you’ve declared in an outer scope in C, but then that’s not really a for-in construct.)
for (const i in [1,2,3,4]) {
alert(i);
}
alert("i is now " + i); // ReferenceError
(Not that JS is exactly known for consistent and predictable behavior on edge cases, of course...)Python I don’t have experience with, and it appears I stand corrected on that front! I wonder how intentional it is, and what sort of use case it enables (and if it’s considered good practice to use).
RangeInclusive::new(1, 10) .filter(|x| x % 2 == 0) .for_each(|x|{ println!("{}", x); });
(though you could write it the same way, for i in 1..=-10 { if .. { .. }}
(1...10).filter { $0.isMultiple(of: 2) }.forEach { print($0) }
Do you mean the use of “\(variable)” for string interpolation? What’s wrong with that?
Using backslash has the advantage that there’s only one ‘special’ character in strings, but of course, also has the problem can escape any character with a backsplash, except for opening parentheses.
Which for is for and would work as for for?
I think D has to be this idea (or disease depending on who you ask i.e. Go is based on the idea of only keeping the simple bits) taken to the extreme - you can quite happily write Java in D but also implement a Java in D all the way down to the metal (merrily metaprogramming all the way down)
Don’t get me wrong, I love swift but I think that for what you’re talking about constraints are necessary because we naturally shift towards more complex ways of expression.
Dart is the closest I've found to optimizing the surface area of a language while maintaining flexibility like ObjC.
If anything, that's bad, because it invites projects to adopt a impoverished subset of the language that avoids those features, in which case they might as well not exist because you aren't allowed to use them.
So can Perl.
Or the internalization of the managerial imperative for cheap labor, take your pick.
Companies prefer a churn of cheaper juniors happened.