-1
* Swift is explicitly a C-family language. In most or all other C-family
languages, for loop statements allow specification of conditions for
exiting the loop but not for filtering. Therefore, Swift's use of `where`
is unprecedented and needs to be learned anew by every user of Swift.
When was this decided? I distinctly remember some bloke under Craig
Federighiās hair saying that it was time to āmove beyondā C and essentially
ditch legacy conventions which no longer make sense.
I think you misunderstood my argument here. I don't mean that we should
yoke ourselves to C conventions, and we should absolutely ditch C
convention when it doesn't make sense. The big-picture argument here is
that `where` doesn't pass the bar of correcting a C convention that no
longer makes sense.
FWIW, on the topic of syntax choices, here is what Chris Lattner had to
say on this list:
Kevin got it exa*c*tly right, but Iād expand that last bit a bit to:
ā⦠pi*c*king the one that is most familiar to programmers in the
extended *C* *family* is a good idea.["]
The extended *C* *family* of language (whi*c*h in*c*ludes *C*, *C*++,
Obj*C*, but also *C*#, Java, Javas*c*ript, and more) is
an extremely popular and widely used set of languages that have a lot of
surfa*c*e-level similarity. I
donāt *c*laim to know the design rationale of all of these languages,
but I surmise that this is not an
a*c**c*ident: programmers move around and work in different languages,
and this allows a non-expert in the
language to understand what is going on. While there are things about
*C* that are really unfortunate IMO
(e.g. the de*c*larator/de*c*laration spe*c*ifier part of the grammar)
there is a lot of goodness in the basi
*c*operator set, fo*c*us on dot syntax, and more.
I do agree that there are some benefits to dit*c*hing bra*c*es and
relying on indentation instead, but there are
also downsides. Deviating from the *C* *family* in this respe*c*t would
have to provide **overwhelmingly** large
advantages for us to take su*c*h a plunge, and they simply donāt exist.
As I understand it, Swift is a new language with new conventions. It is
desirable to align as many of those as possible with existing conventions
so as to be easily learned, but if you limit Swift to other languages
conventions you deny it any identity. Did Python ask anybodyās opinion
before dropping curly-braces? Did people learn whatever Perl is supposed to
be? Look at Cās hieroglyphic for loops!
I don't think we disagree here.
Realistically, āfor ⦠in ⦠whileā is not going to cause incredible
confusion. Removing it would cause a lot of frustration. You canāt on the
one hand say our users are comfortable with the axioms of Cās hieroglyphic
loops, and on the other hand say āfor x in y while" is confusing.
Again, as I said, once you've mastered something, by definition you find
it not confusing. Why should we doom x% of new users to writing a loop
incorrectly at least once when we don't have to?
Ah, but if youāre not ādoomedā to failing once, how will you ever master
anything? Nobody knew how to write a C for-loop until someone showed them
(and even thenā¦). Nobody is going to just open a REPL and start writing
code, with zero prior understanding of what Swift syntax looks like.
The thought here is along the lines of what Chris said, quoted above, and
repeated here: "The extended C family of language [...] is an extremely
popular and widely used set[;] programmers move around and work in
different languages, and [aligning to expectations arising from other C
family languages] allows a non-expert in the language to understand what is
going on." By contrast, the `where` clause violates that expectation and I
do not see "overwhelmingly large advantages" for doing so.
What about C#'s `where` then? As C# is a member of the C family languages
`where` is not violating expectations!
Where is not exactly a part of c# it belongs to linq
And that is not a part of C#??
SQL is a domain-specific language, and LINQ is an internal domain-specific
language with a language extension for C#. Neither is a general purpose
language.
Your example actually goes to one of Laurent's points. Should the Swift
core team or an enterprising community member propose a set of similarly
powerful tools, along with a set of language extensions that add syntactic
sugar for them, I (and I think Laurent, if I understand him correctly)
would absolutely be in favor of such an addition. But as it is, `where` is
an odd duckling. Just as you say, it looks like a component of a query
language, but it does no such thing. In a for loop, it does some filtering,
but until recently it functioned like a comma in `while` loops. Look at
those other keywords which make this sugar possible in C#: in your example,
`from` and `select`. We don't have any of that intrastructure in Swift.
IMHO the team has taken an Ockham Axe to the grammar: in the presence of
multiple ways to produce the same or an acceptable stand-in (for eg when
the only difference is an acceptable temporary perf setback), then the
solution requiring the least assumptions on the compiler wins.
I would even extend this rule with the corollary that between an
assumption materialized as a type checker rule and an assumption
materialized as a full blown extra language keyword, there might be a bias
to accept the former if it kills the latter. But this is just my personal
inference of what their decision heuristic might be based solely on what I
saw. My sole interest in trying to understand their decision making process
is to try to avoid proposals that have little to no chance to go anywhere,
as well as trying to present ones that will align better with where the
language is going.
In this instance, WHERE is a heavy assumption on the compiler for no
greater gain than filters can provide. So I think we save the WHERE keyword
for an outcome that will be really worth it! Something along the idea of
Linq, but with a proper Swift feel to it. What does it look like? I cannot
say yet. But the good news is that having taken WHERE out now will make
that next step a purely additive process (nothing will be taken out then,
but a big thing will be gained).
I am all for extending `for` to be more like Scalaās `for`-expression or
Haskellās `do`-notation. LINQ might be too focused on querying.
Extending the current `where` to be syntax sugar for `filter` would be
quite straightforward, though, so Iām not sure whether removing it first is
really necessary.
That was not object of the pitch to retire `where` from `for`-loops,
though. Instead the argument was (and still is) that `where` might be
misunderstood there by beginners and should therefore be removed. This
argument would apply to an extended `where` unchanged, because I can still
write the exact same code as being criticized now and can even do more
complicated things which would by even more hard to understand for
beginners.
Thatās the argument I disagree with.
The following is an example from MSDN with `where` clearly beaing a
keyword:
*var* numQuery = *from* num *in* numbers *where* (num % 2) == 0 *select* num;
Here is food for your thoughts, you think WHERE is a keyword?! then look
at this:
var numbers = new int{0,1,23,4,5,6,7,87,9};
var numQuery = from num in numbers where (num % 2) == 0 select num;
Program does not compile:
// Error CS1935: An implementation of `Where' query expression pattern
could not be found. Are you missing `System.Linq' using directive or
`System.Core.dll' assembly reference? (CS1935) (SessionsFinder)
using System.Linq;
var numbers = new int{0,1,23,4,5,6,7,87,9};
var numQuery = from num in numbers where (num % 2) == 0 select num;
That program does compiles and runs fine. This tells you that āwhere" is
not at all the ordinary keyword that it appears to be. hence my āit is not
C# per-se, it is Linqā.
Digging into C# Features That Support LINQ - C# | Microsoft Learn and
C# Keywords - C# | Microsoft Learn tells me the
following:
(1) `from`, `where` etc. are contextual keywords, but they are nonetheless
keywords of C# and expressly *not* a specific feature of LINQ: "Although
these new features are all used to a degree with LINQ queries, they are not
limited to LINQ and can be used in any context where you find them useful."
(2) the compiler translates them into standard method calls (like Scalaās
`for`-expression or Haskellās `do`-notation). That is an integral part of
C#.
(3) your error message originates from not having an implementation of a
`Where`-method in scope. You could have provided one yourself instead of
`using System.Linq`.
Of course the compiler knows about it... My exact wording was "ordinary
keyword" implying, "it is one, just not in the sense you are giving it
right now". Knowing you would want to dig further I had to find a
description that was true albeit leaving the fine details out (i doubt too
may actually care about the distinction between contextual and
non-contextual kwd, or the fact that sql is turing complete ;) ).
My thought is to accept the downgrading from its current status because
its complete behavior is limited and hetched in blood inside the grammar,
therefore not extensible without grammar alterations; thereby leaving the
door open for a future re-introduction ala-Linq in v4+. I use the term
"ala-linq" as a placeholder for "some sort of more dynamic behavior
resulting from a close collaboration between compiler, stdlib, runtime and
user code". And i still believe nobody outside doug, joe, chris, or jordan
cares about the actual implementation details.
Again, this is just a personal view on what looks IMHO like a great
opportunity.
Well said. Like you, I don't know what the core team's feelings would be
with respect to contextual sugar for domain-specific uses. IMHO, it is a
very neat concept. If it does arrive in Swift 4+, then `where` as sugar for
`filter()` should come with that. If that's not the direction that the core
team wants to go, I fail to see why filtering a sequence specifically as
part of a loop should be privileged above any other useful operation that
would have a similarly strong claim to sugar.