23

I normally code in either c# or Objective-C and recently took it upon myself to learn Apple's new programming language - Swift.

The first thing I noticed is that you don't need to add semicolons to end a line in Swift but if you do-at least from what I've tested-it does not interfere with the compiler.

When I write:

int someNumber = 0;

in Objective-C the semicolon tells the program that the line is over and to not fall through to the next line.

With Swift I can declare a variable with

var someNumber:Int = 5

and not add a semicolon and the system knows that this is the end of the line.

What allows the some languages to do this and others to not? Why not keep a uniform system of adding the semicolon to the end?

Memj
  • 335
  • 3
  • 8
  • Not everyone comes from other languages, so how would they even know they're not uniform? Won't Apple attract more new programmers with Swift by getting rid of the Objective-C parts that many people dislike? – JeffO Aug 06 '15 at 16:13
  • 2
    Lots of Obj-C vets are unhappy with Swift and much prefer Obj-C. This can be seen through the Apple forums. Swift only came out in 2014 and if FULL of bugs and changes are made every few months to the language with Swift2.0 coming out this fall. Swift is based on Obj-C but is aimed to make coding easier to learn with more plain english. – Memj Aug 06 '15 at 16:23
  • 1
    Old compiler implementers were just lazy and/or had to be more efficient with simpler parsing. There is no need for this anymore. It's the same as local type inference, you don't have it only if your compiler writer is lazy and doesn't care about developer experience. – Ebuall Sep 30 '18 at 07:58

2 Answers2

21

What allows the some languages to do this and others to not? Why not keep a uniform system of adding the semicolon to the end?

Robert gave a good answer regarding Swift, I'll try to add bit more about parsing in general and why to use or not semicolons.

When you compile the program, there are several steps before your source file is turned into executable code, one of the first being reading and parsing. During parsing your code is transformed from a sequence of characters into a structured representation according to the grammar of the language. For this it's necessary that the elements that compose your code (variables, constants, declarations, etc.) are somehow identified and separated. When you make a declaration like:

int someNumber = 0;

It's just a sequence of characters that somehow needs to be turned unto the concept "create a 'thing' called someNumber of type int and assign 0 to it".

This requires identifying where exactly the statement begins and ends. Imagine if you had this:

int someNumber = 0;
int otherNumber = 1;

You would need to know that those are two different declarations. The ; in C-like languages is used for that, so the parser reads the characters until it finds one, and attempts to understand what was just read as a single statement. This allows, as Robert said, to have several statements in the same line, like:

int someNumber = 0; int otherNumber = 1;

Which has exactly the same effect as writing them in two lines.

In other languages, like Python, you are expected to put each statement in a different line.

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

So there is no need to add a ;, because the language itself prevents you from adding statements in the same line!

Yet other languages, like LISP or Scheme, have a very different way of grouping statements (ok, they are not really statements, but let's ignore that for now). So you have just parenthesis for everything:

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

Again, you don't need the ; just because you use the same symbols (), () for things that in other languages are {, }, :, etc. Someone who only knows Lisp syntax might ask you: Why do you need ; at the end of your statements?

Just to add a stranger example: OCaml not only has a semicolon at the end of statements... it has two!

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

Why? I don't know. :)

Different languages are designed with different purposes and different philosophies. If all languages shared the same syntax and conventions, they would probably only allow you to do the same things in the same way.

Sebastian
  • 464
  • 2
  • 7
  • 5
    Good closing sentence. – Thomas Eding Aug 06 '15 at 17:02
  • Nice examples, but you didn't answer the question. – Robo Robok Jul 23 '17 at 10:23
  • Additional data point: Some languages take a sort of reverse-approach to the C-style family: E.g. HyperTalk uses line breaks as the hard end of a line (instead of semicolons), and require escaping line breaks if you want to continue a statement over several lines. Funnily, C's very own preprocessor also works that way. – uliwitness May 02 '18 at 13:02
15

Line breaks are used instead of semicolons to delimit the end of a statement.

In Language guide: The Basics it says:

Unlike many other languages, Swift does not require you to write a semicolon (;) after each statement in your code, although you can do so if you wish. Semicolons are required, however, if you want to write multiple separate statements on a single line.

Why? Because that's how the language designers wanted to do it.

The second sentence above hints at why you don't need semicolons; most statements are single line. Observe this Bubble Sort example; the combination of single-line statements and no semicolons makes for very clean syntax that's VB-like, but less verbose:

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
            }
        }
    }
}

Because statements in Swift usually end on a line break, the need for semicolons to mark the end of a statement is reduced. Other languages that use semicolons don't work this way; you can freely write multi-line statements, but the only way the compiler knows that the statement has ended is when you place your semicolon at the end of it.

When statements don't end on a line break, you have to put the line break at a place that the Swift compiler can recognize as a continuation of the previous line:

let s2 = str
        .lowercaseString
        .replace("hello", withString: "goodbye")
Robert Harvey
  • 198,589
  • 55
  • 464
  • 673
  • 2
    The last statement is false, there is no specific location to place line breaks. It is good to keep your lines of code indented and aligned to improve readability. – Eneko Alonso Aug 25 '16 at 21:10
  • 2
    Fun fact: This has a knock-on effect on error reporting. Many C compilers (clang is especially good at that) use semicolons to find the end of a statement with a syntax error and can use that information to e.g. report missing closing parentheses closer to where they actually are missing. Lacking semicolons, making an error in Swift can often cause the following line to be contracted into its error-containing predecessor and lead to really weird error messages. – uliwitness May 02 '18 at 13:11