Почему Swift не требует точек с запятой? [закрыто]

20

Обычно я пишу код на языке C # или Objective-C и недавно взял на себя обязательство изучать новый язык программирования Apple - Swift.

Первое, что я заметил, это то, что вам не нужно добавлять точки с запятой в конце строки в Swift, но если вы делаете - по крайней мере из того, что я тестировал - это не мешает компилятору.

Когда я пишу:

int someNumber = 0;

в Objective-C точка с запятой сообщает программе, что строка окончена и не переходит на следующую строку.

С Swift я могу объявить переменную с

var someNumber:Int = 5

и не добавляйте точку с запятой, и система знает, что это конец строки.

Что позволяет некоторым языкам делать это, а другим - нет? Почему бы не сохранить единую систему добавления точки с запятой в конец?

Memj
источник
Не все выходцы из других языков, так откуда они вообще знают, что они не одинаковы? Разве Apple не привлечет новых программистов с помощью Swift, избавившись от частей Objective-C, которые не нравятся многим людям?
JeffO
2
Многие ветеринары Obj-C недовольны Swift и предпочитают Obj-C. Это можно увидеть на форумах Apple. Swift вышел только в 2014 году, и если ПОЛНОСТЬЮ ошибок и изменений будут вноситься каждые несколько месяцев, язык Swift2.0 выйдет этой осенью. Swift основан на Obj-C, но нацелен на то, чтобы облегчить изучение кодирования на более простом английском языке.
Memj
Старые реализации компилятора были просто ленивы и / или должны были быть более эффективными с более простым анализом. В этом больше нет необходимости. Это то же самое, что и локальный вывод типа, у вас его нет только в том случае, если ваш автор компилятора ленив и не заботится об опыте разработчика.
Ebuall

Ответы:

18

Что позволяет некоторым языкам делать это, а другим - нет? Почему бы не сохранить единую систему добавления точки с запятой в конец?

Роберт дал хороший ответ относительно Swift, я постараюсь добавить немного больше о синтаксическом анализе в целом и о том, зачем использовать точки с запятой или нет.

Когда вы компилируете программу, есть несколько шагов, прежде чем ваш исходный файл превратится в исполняемый код, одним из первых из которых будет чтение и анализ . Во время синтаксического анализа ваш код преобразуется из последовательности символов в структурированное представление в соответствии с грамматикой языка. Для этого необходимо, чтобы элементы, составляющие ваш код (переменные, константы, объявления и т. Д.) Были как-то идентифицированы и разделены. Когда вы делаете заявление, как:

int someNumber = 0;

Это просто последовательность символов, которую нужно как-то превратить в концепцию «создать« вещь », называемую someNumberтипом, intи присвоить 0ей» .

Это требует определения, где именно утверждение начинается и заканчивается. Представьте, если бы у вас было это:

int someNumber = 0;
int otherNumber = 1;

Вы должны знать, что это две разные декларации. Для этого ;используется язык C-like, поэтому синтаксический анализатор читает символы до тех пор, пока не найдет их, и пытается понять то, что было только что прочитано, как одно утверждение. Это позволяет, как сказал Роберт, иметь несколько операторов в одной строке, например:

int someNumber = 0; int otherNumber = 1;

Который имеет тот же эффект, что и запись их в две строки.

На других языках, таких как Python , вы должны помещать каждое утверждение в отдельную строку.

x = 3
if x < 10:
   print 'x smaller than 10'
else:
   print 'x is bigger than 10 or equal'

Поэтому нет необходимости добавлять ;, потому что сам язык не позволяет вам добавлять операторы в одной строке!

Тем не менее, другие языки, такие как LISP или Scheme , имеют совсем другой способ группировки утверждений (хорошо, они на самом деле не являются утверждениями, но давайте пока проигнорируем это). Таким образом, у вас есть только круглые скобки для всего:

(define (do-stuff x)
  (begin
    (display (format "value: ~a" x))
    x))

Опять же, вам не нужно ;только потому, что вы используете те же символы ( ), () для вещей, которые в других языках {,} , :и т.д. Кто - то , кто знает синтаксис Lisp может спросить: Зачем вам ;в конце вашего заявления ?

Просто чтобы добавить пример с незнакомцем: OCaml точка с запятой не только в конце операторов, но и с двумя!

let rec fact x =
    if x <= 1 then 1 else x * fact (x - 1);;

Почему? Я не знаю. :)

Разные языки предназначены для разных целей и разных философий. Если бы все языки имели одинаковый синтаксис и соглашения, они, вероятно, позволили бы вам делать одни и те же вещи одинаково.

Себастьян
источник
4
Хорошее заключительное предложение.
Томас Эдинг
Хорошие примеры, но вы не ответили на вопрос.
Робо Робок
Дополнительная точка данных: Некоторые языки используют своего рода обратный подход к семейству стилей языка C. Например, HyperTalk использует разрывы строк в качестве жесткого конца строки (вместо точек с запятой) и требуют экранирования разрывов строк, если вы хотите продолжить оператор на несколько строк. К счастью, собственный препроцессор C также работает таким образом.
Uliwitness
11

Разрывы строк используются вместо точек с запятой для разделения конца оператора.

В руководстве по языку: Основы сказано:

В отличие от многих других языков, Swift не требует от вас писать точку с запятой (;) после каждого оператора в вашем коде, хотя вы можете сделать это, если хотите. Точка с запятой требуется, однако, если вы хотите написать несколько отдельных операторов в одной строке.

Почему? Потому что так хотели это сделать дизайнеры языка.

Второе предложение выше намекает на то, почему вам не нужны точки с запятой; большинство утверждений в одну строку. Посмотрите на этот пример Bubble Sort; Сочетание однострочных операторов и отсутствие точек с запятой обеспечивает очень чистый синтаксис, похожий на VB, но менее подробный:

func bubbleSort<T:Comparable>(inout list:[T]) {
    var done = false
    while !done {
        done = true
        for i in 1..<list.count {
            if list[i - 1] > list[i] {
                (list[i], list[i - 1]) = (list[i - 1], list[i])
                done = false
            }
        }
    }
}

Поскольку операторы в Swift обычно заканчиваются переводом строки, потребность в точках с запятой для обозначения конца оператора уменьшается. Другие языки, которые используют точки с запятой, не работают таким образом; Вы можете свободно писать многострочные операторы, но единственный способ, которым компилятор знает, что оператор закончился, - это когда вы ставите точку с запятой в конце.

Когда операторы не заканчиваются на разрыв строки, вы должны поместить разрыв строки в место, которое компилятор Swift может распознать как продолжение предыдущей строки:

let s2 = str
        .lowercaseString
        .replace("hello", withString: "goodbye")
Роберт Харви
источник
2
Последнее утверждение ложно, нет конкретного места для разрыва строки. Хорошо, чтобы ваши строки кода были с отступом и выровнены для улучшения читабельности.
Энеко Алонсо
Интересный факт: это влияет на сообщения об ошибках. Многие компиляторы C (особенно хорош clang) используют точки с запятой, чтобы найти конец оператора с синтаксической ошибкой, и могут использовать эту информацию, например, для сообщения об отсутствующих закрывающих скобках ближе к тому месту, где они фактически отсутствуют. Отсутствие точек с запятой, создание ошибки в Swift часто может привести к сокращению следующей строки в ее предшественнике, содержащем ошибки, и привести к действительно странным сообщениям об ошибках.
10