Eh—I would have designed SQL differently if I were in charge (especially for casts, function definitions, and string munging) but leaving that aside, I disagree that the JOIN ON syntax is unnecessarily complex.
We do not write programming languages solely for computers. We write them for humans too. Humans make mistakes and come at codebases at all manners of experience, both in breadth and depth.
For example, it may literally be someone's first time looking at SQL when they're confronted with the following:
SELECT *
FROM classrooms, enrolments
WHERE classrooms.id=\classroom_id;
It is inherently less clear than the following:
SELECT *
FROM classrooms
LEFT JOIN enrolments
ON classrooms.id = classroom_id;
It's easier to figure out bugs too, because it leaves more room to understand what the person
intended to do rather than what they actually did. For example, say the classrooms table had, due to legacy issues, a nullable id field, but we didn't want to include those classrooms. Someone may have inadvertently typed:
SELECT *
FROM classrooms
LEFT JOIN enrolments
ON classrooms.id = classroom_id
WHERE classroom_id IS NOT NULL;
// ^ should have been classrooms.id
Because the NOT NULL criteria is in the where clause, it's clear it's not supposed to impact the join. It's supposed to be part of the filter. I know it's the same thing practically, but they're conceptually different.
Further, as you get into more complex queries (unions, recursive, cross joins, aggregations) stuffing everything into one hairy WHERE statement gets impossible to understand because it does everything all at once.