セミコロンのいる言語 いらない言語
◆ JavaScript はセミコロンいらないです
◆ 知ってて書いてる人って Python なんかでも とりあえずセミコロン書いてもエラーじゃないなら全部書いてるのかな
◆ セミコロンいらない言語では行を超えて結合されずエラーになることが多い
◆ JavaScript だとこれのせいで セミコロン書きたがる人もいるはず
◆ Lua では JavaScript を同じく + や () での関数実行が行を挟んでも実行される
◆ なのに Lua ではセミコロンないのが一般的
◆ 知ってて書いてる人って Python なんかでも とりあえずセミコロン書いてもエラーじゃないなら全部書いてるのかな
◆ セミコロンいらない言語では行を超えて結合されずエラーになることが多い
◆ JavaScript だとこれのせいで セミコロン書きたがる人もいるはず
◆ Lua では JavaScript を同じく + や () での関数実行が行を挟んでも実行される
◆ なのに Lua ではセミコロンないのが一般的
JavaScript ってセミコロンいらない言語ですよね
書いてる人多いですけど
書きたい人は書いてれば って思うのですが ふと
「JavaScript でセミコロン書いてる人って C とかのクセで書きたいんだよね
それだと Python や Ruby などでもセミコロン書くの?」 と疑問が
Python も Ruby もセミコロンを書いても問題無いです
JavaScript と同じで一行に複数の文を書くときに使います
JavaScript だとたぶん入門本ではほとんどセミコロン書いてるので 必要だと思い込んでいる初心者の人は別として 中級者にもなればいらないことは知っているはずですよね
いらないと知っても まだセミコロンを書き続けるほどセミコロンにこだわりがあるなら セミコロンを書いても良い言語は全部書いて言語間の差を減らそうとしてるのじゃないかとも思えます
(私も PHP と JavaScript をほぼ平行に書いてた時は PHP でセミコロン抜けが多くて JavaScript でもセミコロン書いてた頃もありましたし)
そんなことを考えていたら 他の言語ってどれがセミコロン必要でどれがいらないのだっけ?と気になってきました
それと 好み以外で JavaScript でわざわざセミコロンを書く理由で考えられる行の結合
書く側の問題ではありますけど こういうのが構文エラーにならないとバグの元になるからセミコロン書くと考える人もいます
私からすると セミコロンありのコードを編集したときに 後からコードを見なおしていて「あ ここセミコロン忘れてるじゃん」とつけた結果 次の行と結合しないといけないところで逆にバグになったこともあるのでやっぱりセミコロンなんていらないと思いますけど
そんな行間の結合とセミコロンのいるいらないを他の言語で調べてみました
エラーが凄く長かったので省略してます
Erlang と Smalltalk はセミコロンじゃなくて「.」で文の終わり
Pascal は文の終わりじゃなくて文の境目をセミコロン (JavaScript の「,」みたいな)
だいたいこのあたり
両方とも 3 になってるのは Lua Haskell ActionScript3 だけです
ActionScript は JavaScript と近いのは当たり前ですので置いておきます
Haskell はインデントがない場合はエラーでした
なので 一応文が続いているということを書いていることになります
結局残りは Lua だけ
Lua もプロトタイプベースのオブジェクト指向ですし JavaScript に似ている言語です
構文も近いと思います
+ だけじゃなくて 関数の実行が予期せず実行されるという JavaScript でセミコロンを書かないといけないケース
(fn2()) のところが前の行と結合されてしまうので val には fn1 ではなく fn1(fn2()).printA() の結果が代入されてしまいます
これを Lua にすると
同じく val には fn1 ではなく printA() の返り値になってます
JavaScript の undefined や null は lua では nil です
さて Lua ではセミコロン書かないのが一般的ですよね
JavaScript でセミコロン書かない場合に予期せず行が結合されてしまう欠点は Lua でも持っています
なのに JavaScript になると意図せず行結合されることがあるから「常に」セミコロン書きましょうなんて言ってるのはおかしいですよね
ノーセミコロンなライフを送りましょう
書いてる人多いですけど
書きたい人は書いてれば って思うのですが ふと
「JavaScript でセミコロン書いてる人って C とかのクセで書きたいんだよね
それだと Python や Ruby などでもセミコロン書くの?」 と疑問が
Python も Ruby もセミコロンを書いても問題無いです
JavaScript と同じで一行に複数の文を書くときに使います
JavaScript だとたぶん入門本ではほとんどセミコロン書いてるので 必要だと思い込んでいる初心者の人は別として 中級者にもなればいらないことは知っているはずですよね
いらないと知っても まだセミコロンを書き続けるほどセミコロンにこだわりがあるなら セミコロンを書いても良い言語は全部書いて言語間の差を減らそうとしてるのじゃないかとも思えます
(私も PHP と JavaScript をほぼ平行に書いてた時は PHP でセミコロン抜けが多くて JavaScript でもセミコロン書いてた頃もありましたし)
そんなことを考えていたら 他の言語ってどれがセミコロン必要でどれがいらないのだっけ?と気になってきました
それと 好み以外で JavaScript でわざわざセミコロンを書く理由で考えられる行の結合
var a = 1 +
2
や2
var a = 1
+2
と書いても JavaScript では結合されて a に 3 が入ります+2
書く側の問題ではありますけど こういうのが構文エラーにならないとバグの元になるからセミコロン書くと考える人もいます
私からすると セミコロンありのコードを編集したときに 後からコードを見なおしていて「あ ここセミコロン忘れてるじゃん」とつけた結果 次の行と結合しないといけないところで逆にバグになったこともあるのでやっぱりセミコロンなんていらないと思いますけど
そんな行間の結合とセミコロンのいるいらないを他の言語で調べてみました
セミコロンいらない言語
Python
# your code goes here
a = 1 +
2
print a
a = 1 +
2
print a
py_compile.PyCompileError: File "prog.py", line 2
a = 1 +
^
SyntaxError: invalid syntax
a = 1 +
^
SyntaxError: invalid syntax
# your code goes here
a = 1
+ 2
print a
a = 1
+ 2
print a
1
Python3
# your code goes here
a = 1 +
2
print(a)
a = 1 +
2
print(a)
py_compile.PyCompileError: File "./prog.py", line 2
a = 1 +
^
SyntaxError: invalid syntax
a = 1 +
^
SyntaxError: invalid syntax
# your code goes here
a = 1
+ 2
print(a)
a = 1
+ 2
print(a)
1
Ruby
# your code goes here
a = 1 +
2
p a
a = 1 +
2
p a
3
# your code goes here
a = 1
+2
p a
a = 1
+2
p a
1
Scala
object Main extends App {
// your code goes here
val a = 1 +
2
println(a)
}
// 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)
}
// your code goes here
val a = 1
+ 2
println(a)
}
1
Lua
-- your code goes here
a = 1 +
2
print(a)
a = 1 +
2
print(a)
3
-- your code goes here
a = 1
+2
print(a)
a = 1
+2
print(a)
3
R
# your code goes here
a = 1 +
2
cat( a )
a = 1 +
2
cat( a )
3
# your code goes here
a = 1
+2
cat( a )
a = 1
+2
cat( a )
[1] 2
1
1
Go
package main
import "fmt"
func main(){
// your code goes here
a := 1 +
2
fmt.Println(a)
}
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)
}
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
def a = 1 +
2
print a
3
// your code goes here
def a = 1
+2
print a
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
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
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.
/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
2
main = do
print a
prog.hs:2:1:
parse error (possibly incorrect indentation or mismatched brackets)
parse error (possibly incorrect indentation or mismatched brackets)
a = 1 +
2
main = do
print a
2
main = do
print a
3
a = 1
+ 2
main = do
print a
+ 2
main = do
print a
3
Swift
// Project Euler #1 Solution in Swift
var a = 1 +
2
print(a)
var a = 1 +
2
print(a)
3
// Project Euler #1 Solution in Swift
var a = 1
+2
print(a)
var a = 1
+2
print(a)
25:1: error: ambiguous use of operator '+'
+2
^
+2
^
Basic
a = 1 +
2
print a
2
print a
Compile Error
Syntax error - a = 1 +
Syntax error - a = 1 +
a = 1
+2
print a
+2
print a
Compile Error
Syntax error - +2
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
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 +
--> 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
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
--> + 2
Elixir
a = 1 +
2
IO.puts(a)
2
IO.puts(a)
3
a = 1
+2
IO.puts(a)
+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)
}
* 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)
}
* 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
! 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
! 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)
}
}
}
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)
}
}
}
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)
return x
}
function fn2(){
return {
printA: function(){
console.log("A")
}
}
}
var val = fn1
(fn2()).printA()
console.log(val)
A
undefined
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)
return x
end
function fn2()
return {
printA = function()
print("A")
end
}
end
local val = fn1
(fn2()).printA()
print(val)
A
nil
nil
同じく val には fn1 ではなく printA() の返り値になってます
JavaScript の undefined や null は lua では nil です
さて Lua ではセミコロン書かないのが一般的ですよね
JavaScript でセミコロン書かない場合に予期せず行が結合されてしまう欠点は Lua でも持っています
なのに JavaScript になると意図せず行結合されることがあるから「常に」セミコロン書きましょうなんて言ってるのはおかしいですよね
ノーセミコロンなライフを送りましょう
COMMENT
コメント一覧 (2)
-
- 2017/03/10 23:38
-
たくさん比較されていて面白かったです。
セミコロンは、特に1行が長いとき
次の行の先頭を見なくても文が終端していることがわかるというメリットがあります。
扱うライブラリやフレームワークによって横に長くなりやすい環境では、
継続していないことがすぐに判断できると読むスピードが上がるものもあります。
ちなみにc 言語で、長いエラーメッセージなどを書くときに
char * str = "An error occured :\n"
"Reason 1 ..\n"
"Reason 2 ..\n"
;
などのようにして文字列連結できる仕組みがあるのですが、
このような記述が頻出するエラーメッセージがたくさん定義されたファイルなどでは、
終端が目立つことに一定の意味があります。
ちなみにswiftでは2行目以降が捨てられます。
-
- 2017/03/12 20:55
-
なるほどー
目立させるのが目的ということもあるのですね
C のそういう使い方はみたことあります
確かCでは連続するリテラルはメモリ上でも連続して配置されるから続いてるようにあつかえるのでしたっけ
2 行目が捨てられるケースはよくありますよね
python や ruby も連続した文字列は自動結合してくれますが 行をまたいでると別ステートメント扱いになってしまい 2行目が単純に文字列という式だけのステートメントなので何も処理されないとか python だと C# などと同じ感じで値だけの式が許可されてないのでエラーになったりとか
セミコロン必須な言語だと複数行の文字列の結合ではちょっといいかもです