◆ JavaScript はセミコロンいらないです
  ◆ 知ってて書いてる人って Python なんかでも とりあえずセミコロン書いてもエラーじゃないなら全部書いてるのかな
◆ セミコロンいらない言語では行を超えて結合されずエラーになることが多い
  ◆ JavaScript だとこれのせいで セミコロン書きたがる人もいるはず
◆ Lua では JavaScript を同じく + や () での関数実行が行を挟んでも実行される
  ◆ なのに Lua ではセミコロンないのが一般的 

JavaScript ってセミコロンいらない言語ですよね
書いてる人多いですけど

書きたい人は書いてれば って思うのですが ふと
「JavaScript でセミコロン書いてる人って C とかのクセで書きたいんだよね
それだと Python や Ruby などでもセミコロン書くの?」  と疑問が

Python も Ruby もセミコロンを書いても問題無いです
JavaScript と同じで一行に複数の文を書くときに使います

JavaScript だとたぶん入門本ではほとんどセミコロン書いてるので 必要だと思い込んでいる初心者の人は別として 中級者にもなればいらないことは知っているはずですよね

いらないと知っても まだセミコロンを書き続けるほどセミコロンにこだわりがあるなら セミコロンを書いても良い言語は全部書いて言語間の差を減らそうとしてるのじゃないかとも思えます
(私も PHP と JavaScript をほぼ平行に書いてた時は PHP でセミコロン抜けが多くて JavaScript でもセミコロン書いてた頃もありましたし)


そんなことを考えていたら 他の言語ってどれがセミコロン必要でどれがいらないのだっけ?と気になってきました

それと 好み以外で JavaScript でわざわざセミコロンを書く理由で考えられる行の結合
var a = 1 +
2
var a = 1
+2
と書いても JavaScript では結合されて a に 3 が入ります

書く側の問題ではありますけど こういうのが構文エラーにならないとバグの元になるからセミコロン書くと考える人もいます

私からすると セミコロンありのコードを編集したときに 後からコードを見なおしていて「あ ここセミコロン忘れてるじゃん」とつけた結果 次の行と結合しないといけないところで逆にバグになったこともあるのでやっぱりセミコロンなんていらないと思いますけど


そんな行間の結合とセミコロンのいるいらないを他の言語で調べてみました

セミコロンいらない言語

Python

# your code goes here
a = 1 +
2
print a
py_compile.PyCompileError:   File "prog.py", line 2
    a = 1 +
          ^
SyntaxError: invalid syntax
# your code goes here
a = 1
+ 2
print a
1

Python3

# your code goes here
a = 1 +
2
print(a)
py_compile.PyCompileError:   File "./prog.py", line 2
    a = 1 +
          ^
SyntaxError: invalid syntax
# your code goes here
a = 1
+ 2
print(a)
1

Ruby

# your code goes here
a = 1 +
2
p a
3
# your code goes here
a = 1
+2
p a
1

Scala

object Main extends App {
// your code goes here
val a = 1 +
2
println(a)
}
3
object Main extends App {
// your code goes here
val a = 1
+ 2
println(a)
}
1

Lua

-- your code goes here
a = 1 +
2
print(a)
3
-- your code goes here
a = 1
+2
print(a)
3

R

# your code goes here
a = 1 +
2
cat( a )
3
# your code goes here
a = 1
+2
cat( a )
[1] 2
1

Go

package main
import "fmt"

func main(){
// your code goes here
a := 1 +
2
fmt.Println(a)
}
3
package main
import "fmt"

func main(){
// your code goes here
a := 1
+2
fmt.Println(a)
}
./prog.go:7: +2 evaluated but not used

Groovy

// your code goes here
def a = 1 +
2
print a
3
// your code goes here
def a = 1
+2
print a
1

VB.Net

public class compiler
  shared function Main as integer
' Here your code !
    Dim a as integer
    a = 1 +
    2
    Console.WriteLine (a)
    return 0
  End function
end class
3
public class compiler
  shared function Main as integer
' Here your code !
    Dim a as integer
    a = 1
    +2
    Console.WriteLine (a)
    return 0
  End function
end class
/workspace/Main.vb (6,7) : error VBNC90019: Expected 'End'.
/workspace/Main.vb (7,12) : error VBNC90019: Expected 'End'.
/workspace/Main.vb (8,11) : error VBNC30203: Identifier expected.
/workspace/Main.vb (9,15) : error VBNC30203: Identifier expected.
/workspace/Main.vb (10,10) : error VBNC30203: Identifier expected.

Haskell

a = 1 +
2

main = do
    print a
prog.hs:2:1:
    parse error (possibly incorrect indentation or mismatched brackets)
a = 1 +
2

main = do
    print a
3
a = 1
+ 2

main = do
    print a
3

Swift

// Project Euler #1 Solution in Swift

var a = 1 +
2
print(a)
3
// Project Euler #1 Solution in Swift

var a = 1
+2
print(a)
25:1: error: ambiguous use of operator '+'
+2
^

Basic

a = 1 +
2
print a
Compile Error
Syntax error -  a = 1 +
a = 1
+2
print a
Compile Error
Syntax error -  +2

HSP

*main
    redraw 0
    color 0,0,32:boxf
    a = 1 +
    2
    color 255,255,255:pos 10,24:mes a

    redraw 1
    await 33

    goto *main
source.hsp(6) : error 4 : パラメーター式の記述が無効です (6行目)
--> a = 1 +
*main
    redraw 0
    color 0,0,32:boxf
    a = 1
    + 2
    color 255,255,255:pos 10,24:mes a

    redraw 1
    await 33

    goto *main
source.hsp(7) : error 2 : 文法が間違っています (7行目)
--> + 2

Elixir

a = 1 +
2
IO.puts(a)
3
a = 1
+2
IO.puts(a)
tmp/src.exs:2: warning: the result of the expression is ignored (suppress the warning by assigning the expression to the _ variable)

Kotlin

/**
* We declare a package-level function main which returns Unit and takes
* an Array of strings as a parameter. Note that semicolons are optional.
*/

fun main(args: Array<String>) {
    var a = 1 +
    2
    println(a)
}
3
/**
* We declare a package-level function main which returns Unit and takes
* an Array of strings as a parameter. Note that semicolons are optional.
*/

fun main(args: Array<String>) {
    var a = 1
    +2
    println(a)
}
1

Fortran

program TEST
! your code goes here
integer :: a = 1 +
2
print *, a
stop
end
error
program TEST
! your code goes here
integer :: a = 1
+2
print *, a
stop
end
error

エラーが凄く長かったので省略してます

ActionScript3

package{
import flash.display.Sprite
import flash.text.TextField

public class Sample extends Sprite{
public function Sample(){
var a:int = 1 +
2
var tf:TextField = new TextField()
tf.text = a.toString()
this.addChild(tf)
}
}
}
3
package{
import flash.display.Sprite
import flash.text.TextField

public class Sample extends Sprite{
public function Sample(){
var a:int = 1
+2
var tf:TextField = new TextField()
tf.text = a.toString()
this.addChild(tf)
}
}
}
3

セミコロン(など)がある言語

  • C
  • C++
  • C#
  • Objective-c
  • D
  • Delphi
  • Perl
  • Perl6
  • PHP
  • Hack
  • Java
  • Ceylon
  • Rust
  • Dart
  • haxe
  • Erlang
  • Smalltalk
  • Pascal

Erlang と Smalltalk はセミコロンじゃなくて「.」で文の終わり
Pascal は文の終わりじゃなくて文の境目をセミコロン (JavaScript の「,」みたいな)

使用ツール

基本的に PC のローカルに実行環境は入れないのでオンライン実行環境を使いました

だいたいこのあたり

  • ideone
  • paiza io
  • run swift
  • run basic
  • try haxe
  • elixir playground
  • try kotlin

実行環境なし

オンラインで実行する環境が見当たらなくて試せなかったセミコロンいらない言語
  • io
  • leaf

まとめ

+ で終わってるときは次の文と結合してくれるのが多いですが + で始まってる行が前の行と結合してくれないのが多いです
両方とも 3 になってるのは Lua Haskell ActionScript3 だけです

ActionScript は JavaScript と近いのは当たり前ですので置いておきます

Haskell はインデントがない場合はエラーでした
なので 一応文が続いているということを書いていることになります

結局残りは Lua だけ
Lua もプロトタイプベースのオブジェクト指向ですし JavaScript に似ている言語です
構文も近いと思います

+ だけじゃなくて 関数の実行が予期せず実行されるという JavaScript でセミコロンを書かないといけないケース
function fn1(x){
return x
}
function fn2(){
return {
printA: function(){
console.log("A")
}
}
}

var val = fn1
(fn2()).printA()

console.log(val)
A
undefined

(fn2()) のところが前の行と結合されてしまうので val には fn1 ではなく fn1(fn2()).printA() の結果が代入されてしまいます

これを Lua にすると
function fn1(x)
return x
end

function fn2()
return {
printA = function()
print("A")
end
}
end

local val = fn1
(fn2()).printA()

print(val)
A
nil

同じく val には fn1 ではなく printA() の返り値になってます
JavaScript の undefined や null は lua では nil です

さて Lua ではセミコロン書かないのが一般的ですよね
JavaScript でセミコロン書かない場合に予期せず行が結合されてしまう欠点は Lua でも持っています
なのに JavaScript になると意図せず行結合されることがあるから「常に」セミコロン書きましょうなんて言ってるのはおかしいですよね

ノーセミコロンなライフを送りましょう