LoginSignup
5

More than 5 years have passed since last update.

Perl6 と Python3 の基本的な文法を並べてみる

Posted at

こんにちは:whale2:
Perl 6 Advent Calendar 2016の7日目です。
昨日は @titsuki さんの 「初めてのInline::Perl5」でした。1

今日は、他の言語の人にPerl6を知ってもらおうという気持ちで、基本的な文法について Python3 と Perl6 を並べてみたいと思います。2

環境情報

# Mac のバージョン
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.1
BuildVersion:   16B2555
# Perl6 のバージョン
$ perl6 -v
This is Rakudo version 2016.11 built on MoarVM version 2016.11
implementing Perl 6.c.
# Python3 のバージョン
$ python3 --version
Python 3.5.1 :: Anaconda 4.1.0 (x86_64)

算術計算

Python3
print(1 - 2) #=> -1
print(4 * 5) #=> 20
print(7 / 5) #=> 1.4
print(3 ** 2) #=> 9
Perl6
use v6;
say 1 - 2 ; #=> -1
say 4 * 5 ; #=> 20
say 7 / 5 ; #=> 1.4
say 3 ** 2 ; #=> 9

セミコロン(;)の前に半角スペースを入れているのは趣味です。

データ型

の調べ方

Python3
print(type(10)) #=> <class 'int'>
print(type(2.718)) #=> <class 'float'>
print(type("hello")) #=> <class 'float'>
Perl6
use v6;
say 10.WHAT ; #=> (Int)
say 2.718.WHAT ; #=> (Rat)
say "hello".WHAT ; #=> (Str)

10.^name.say ; #=> Int
2.718.^name.say ; #=> Rat
"hello".^name.say ; #=> Str

WHAT(直球)

変数

動的型付け

Python3
# 初期化
x = 10
y = 3.14
print('%d is %s.' % (x, type(x))) #=> 10 is <class 'int'>.

# 代入
x = x * y
print('%.1f is %s.' % (x, type(x))) #=> 31.4 is <class 'float'>.

Perl6では1つの値が入る変数(スカラー変数)の先頭には$を付けます。

Perl6
use v6;
# 初期化
my $x = 10 ;
my $y = 3.14 ;
say $x ~ ' is ' ~ $x.^name ~ '.' ; #=> 10 is Int.

# 代入
$x = $x * $y ;
say sprintf '%.1f is %s.', $x, $x.^name ; #=> 31.4 is Rat.

Perl6は静的型付けもできます

Perl6
use v6;
# 型を指定して初期化
my Int $x = 10 ;
my Rat $y = 3.14 ;

# Int型の$xへのRat型の値代入はエラーになる
# $x = $x * $y ;

# Int型にすれば代入できる
$x = ($x * $y).Int ;
say $x ~ ' is ' ~ $x.^name ~ '.' ; #=> 31 is Int.

Perl5 では . を使っていた文字列連結が、Perl6 では ~ を使うようになりました。

リスト

Python3
# リストの作成
a = [1, 2, 3, 4, 5]

# リストの中身を出力する
print(a) #=> [1, 2, 3, 4, 5]

# リストの長さを取得
print(len(a)) #=> 5

# 先頭の要素にアクセス
print(a[0]) #=> 1

# 末尾の要素にアクセス
print(a[-1]) #=> 5

# 値を代入
a[4] = 99
print(a) #=> [1, 2, 3, 4, 99]

# インデックスの0番目から2つ取得
print(a[0:2]) #=> [1, 2]

# インデックスの1番目から最後まで取得
print(a[1:]) #=> [2, 3, 4, 99]

# インデックスの最初から3つ取得
print(a[:3]) #=> [1, 2, 3]

# 最初から、最後の要素の1つ前まで取得
print(a[:-1]) #=> [1, 2, 3, 4]

Perl6では配列の変数の先頭には@を付けます。

Perl6
use v6;
# 配列の作成
my Int @a = < 1 2 3 4 5 > ;

# 配列の中身を出力する
say @a ; #=> [1 2 3 4 5]

# 配列の長さを取得
say @a.elems ; #=> 5

# 先頭の要素にアクセス
say @a[0] ; #=> 1

# 末尾の要素にアクセス
say @a[*-1] ; #=> 5

# 値を代入
@a[4] = 99 ;
@a.say ; #=> [1 2 3 4 99]

# インデックスの0番目から2つ取得
say @a.head(2).Array ; #=> [1 2]

# インデックスの1番目から最後まで取得
say @a[1..*].Array ; #=> [2 3 4 99]

# インデックスの最初から3つ取得
say @a.head(3).Array ; #=> [1 2 3]
say @a[^3].Array ; #=> [1 2 3]

# 最初から、最後の要素の1つ前まで取得
say @a[0..^*-1].Array ; #=> [1 2 3 4]
say @a[0..*-2].Array ; #=> [1 2 3 4]

※ Perl6の操作でList型が返却されるものについて、一応Array型に変換しています。

ディクショナリ

Python3
# ディクショナリを作成
me = {'height':180}

# 要素にアクセス
print(me['height']) #=> 180

# 新しい要素を追加
me['weight'] = 70
print(me) #=> {'weight': 70, 'height': 180}

Perl6ではこういうのをハッシュと呼んで、先頭には%を付けます。

Perl6
use v6;
# ハッシュを作成
my %me = 'height' => 180 ;

# 要素にアクセス
say %me{'height'} ; #=> 180

# 新しい要素を追加
%me{'weight'} = 70 ;
say %me ; #=> {height => 180, weight => 70}

ブーリアン

Python3
hungry = True
sleepy = False

print(type(hungry)) #=> <class 'bool'>
print(not hungry) #=> False
print(hungry and sleepy) #=> False
print(hungry or sleepy) #=> True
Perl6
use v6;
my Bool $hungry = True ;
my Bool $sleepy = False ;

say $hungry.^name ; #=> Bool
say not $hungry ; #=> False
say ( $hungry and $sleepy ) ; #=> False
say ( $hungry or $sleepy ) ; #=> True

ちゃんとBoolean型があるなんて、なんて素晴らしい言語なんだ

if文

Python3
hungry = True
if hungry:
    print("I'm hungry")

hungry = False
if hungry:
    print("I'm hungry")
else:
    print("I'm not hungry")
Perl6
use v6;
my Bool $hungry = True ;
if $hungry {
    say "I'm hungry" ;
}

$hungry = False ;
if $hungry {
    say "I'm hungry" ;
}
else {
    say "I'm not hungry" ;
}

for文

Python3
for i in [1, 2, 3]:
    print(i)
Perl6
use v6;
for 1, 2, 3 -> $i {
    say $i ;
}

余談ですが、Perl5 では以下のように書いてました。

Perl5
use v5;
for my $i (1, 2, 3) {
    print $i . "\n" ;
}

for文に関しては Perl6 より Python3 の方が Perl5 に似てる感。

関数

Python3
def hello():
    print("Hello World!")

hello() #=> Hello World!

def hello2(object):
    print("Hello " + object + "!")

hello2("Neighbor") #=> Hello Neighbor!

( これ、 object が文字列型じゃなかったら文字列連結でエラーになるのではないだろうか )

Perl6
use v6;
my sub hello {
    say "Hello World!" ;
}

hello() #=> Hello World!

my sub hello2(Str $object) {
    say "Hello " ~ $object ~ "!" ;
}

hello2("Neighbor") #=> Hello Neighbor!

引数は文字列型に限定しています。

クラス

Python3
class Man:
    def __init__(self, name):
        self.name = name
        print("Initialized!")

    def hello(self):
        print("Hello " + self.name + "!")

    def goodbye(self):
        print("Good-bye " + self.name + "!")

m = Man("Alice")
m.hello()
m.goodbye()
Perl6
use v6;
my class Man {
  has Str $.name is readonly;

  method new(Str $name){
      say "Initialized!" ;
      return self.bless(:$name) ;
  }

  method hello {
      say "Hello " ~ self.name ~ "!" ;
  }

  method goodbye {
      say "Good-bye " ~ self.name ~ "!" ;
  }
}

my $m = Man.new("Alice") ;
$m.hello ;
$m.goodbye ;

上記では引数の指定方法をPython版に合わせるためにコンストラクタを再定義しましたが、普通はこんな感じで書くかもしれません。

Perl6
use v6;
my class Man {
  has Str $.name is required;

  method hello {
      say "Hello " ~ self.name ~ "!" ;
  }

  method goodbye {
      say "Good-bye " ~ self.name ~ "!" ;
  }
}

my Man $m .= new(name => "Alice") ;
$m.hello ;
$m.goodbye ;

おわり

他の言語と並べてみると、似ているところとか、逆にものすごくPerl6独特なところがあって面白いですね:camel:

参考と注釈


  1. 昨年のアドベントカレンダーでInline::Perl5ネタ書こうと思ったらインストールに失敗した…という思い出がよみがえりました。 

  2. Pythonのコードは ゼロから作るDeep Learning1章 Python入門を参考にしました。 

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
5