RakuはPerlファミリーのプログラミング言語です。[ 6 ]以前はPerl 6と呼ばれていましたが、2019 年 10 月に改名されました。[ 7 ] [ 8 ] Raku は、多くの現代的および歴史的な言語の要素を取り入れています。Perl との互換性は目標ではありませんでしたが、互換性モードは仕様の一部となっています。Raku の設計プロセスは 2000 年に開始されました。
Perl 6では、ユーザーを修正するよりも言語を修正する方が良いと判断しました。
—ラリー・ウォール[ 9 ]
Raku の設計プロセスは、2000 年 7 月 19 日、その年のPerl カンファレンスの 4 日目に、ラリー ウォールがState of the Onion 2000講演で初めて発表しました。[ 10 ] [ 11 ]当時の主な目標は、言語から「歴史的な痣」を取り除くこと、「簡単なことは簡単なまま、難しいことは簡単に、不可能なことは難しく」、そして内部設計とアプリケーション プログラミング インターフェイス(API) の全体的な整理でした。プロセスは、一連のRequest for Comments (RFC) から始まりました。このプロセスはすべての貢献者に開かれており、言語のどの側面も変更に対して閉鎖されていませんでした。[ 12 ]
RFC プロセスが完了すると、ウォールは受け取った 361 件のリクエストをそれぞれレビューして分類しました。その後、彼は「啓示」という用語の本来の意味を使用して、いくつかの「黙示録」の執筆を開始しました。[ 13 ]当初の目標は、 Programming Perlの各章ごとに 1 つの黙示録を執筆することでしたが、各黙示録が執筆されるにつれて、以前の黙示録が後の変更によって無効になることが明らかになりました。このため、各黙示録の内容に関連する一連の概要が公開されましたが、その後の変更は更新に反映されています。現在、Raku 仕様は「roast」テスト スイートによって管理されており、[ 14 ]概要は歴史的参照として保管されています。[ 15 ]
また、ダミアン・コンウェイが書いた一連の解説書があり、各黙示録の内容を実践的な使用法の観点から説明しています。各解説書は、コード例と、その使用法と意味についての議論で構成されています。[ 16 ]
現在、Rakuの開発には主に3つのコミュニケーション方法が用いられています。1つ目はLibera Chat上のRakuインターネットリレーチャット(IRC)チャンネルです。2つ目はメーリングリストのセットです。[ 17 ] 3つ目はGitHubでホストされているGitソースコードリポジトリです。[ 18 ]
ウォール氏が最初のスピーチで示した主な目標は、歴史的に生じた問題点の解消でした。これには、コンテナにおけるシジルの使用に関する混乱、関数間の曖昧さ、そしてベアワードファイルハンドルselectの構文上の影響などが含まれていました。Perlプログラマーが長年解決を議論してきた他の多くの問題も、ウォール氏のスピーチで明確に取り上げられました。
これらの目標が意味するところは、Perl 6 が既存の Perl コードベースとの後方互換性を持たないということだった。つまり、Perl 5 コンパイラで正しく解釈されたコードの一部が、Perl 6 コンパイラでは受け入れられないということである。ソフトウェアの改良において後方互換性は一般的な目標であるため、Perl 6 における破壊的変更は明示的に示す必要があった。Perl 5 と Perl 6 の違いは非常に大きくなったため、最終的に Perl 6 は Raku と改名された。

この言語のマスコットは「楽虫のカメリア」です。[ 1 ]彼女の名前は、 Perl に関連付けられているラクダのマスコットにちなんだもので、その姿は、Perl コミュニティのダジャレ好きの伝統に倣って「ソフトウェア バグ」をもじったものです。蝶のような羽に埋め込まれた螺旋模様は、Perl 6 の愛称である「P6」という文字に似ており、中心からずれた目の位置は、「外反母趾」をもじった意図的なものです。[ 19 ]
ロゴの活気に満ちたカラフルなデザインの背後にある目標の1つは、コミュニティにおける女性蔑視を抑制し、「男性的な傾向」を持つ人々が繊細な側面を示す機会となることだった。[ 20 ]
2017年現在活発に開発されているのはRakudo の実装のみです。公式の Raku 実装として指定される実装はありません。むしろ、「公式テストスイートに合格するものはすべて Raku です。」[ 21 ]
Rakudo Perl 6 [ 22 ] [ 23 ]は、 MoarVM、Java 仮想マシン、JavaScriptなどの多数の仮想マシンを対象としています。MoarVM は、 Rakudo [ 24 ]および NQP コンパイラ ツールチェーン[ 25 ]のために特別に構築された仮想マシンです。Rakuと仮想マシンの間には Not Quite Perl 6 (NQP) と呼ばれるレイヤーがあり、 Raku を解析するためのRaku ルール、抽象構文木、およびバックエンド固有のコード生成を実装しています。Rakudo の大部分は Raku またはそのサブセットである NQP で記述されています。Rakudo は完全に自己ホスト型の実装ではなく、現時点では Rakudo をブートストラップ コンパイラにする具体的な計画もありません。
Pugs は、 Audrey Tangが主導したHaskellで書かれた Perl 6 の初期実装です。Pugs はかつて Perl 6 の最も先進的な実装でした。2007 年半ばの時点で、ほとんど休止状態にあり、更新はGlasgow Haskell Compiler (GHC)の最新バージョンを追跡するためだけに行われていました。2014 年 11 月現在、Pugs はメンテナンスされていません。[ 26 ]
2007年に、Perl 5を使用してPerl-6.0.0 STDをブートストラップする手段として、v6-MiniPerl6("mp6")とその再実装であるv6-KindaPerl6("kp6")が作成された。STDはPerl 6の完全な文法であり、Perl 6で記述されている。理論的には、STDを解析して実行可能コードを生成できるものはすべて、Perl 6の適切なブートストラップシステムである。kp6は現在mp6によってコンパイルされ、複数のバックエンドで動作することができる。[ 27 ] [ 28 ] mp6とkp6は完全なPerl 6実装ではなく、完全なPerl 6コンパイラをブートストラップするために必要な最小限の機能セットを実装することのみを目的として設計されている。
YapsiはPerl 6で書かれたPerl 6コンパイラおよびランタイムでした。そのため、Rakudo Starリリースのいずれかのような既存のPerl 6インタープリタが必要でした。[ 29 ]
Nieczaは、Perl 6の実装におけるもう一つの主要な取り組みであり、最適化と効率的な実装の研究に重点を置いている。これは共通言語インフラストラクチャを対象としている。[ 30 ]
Raku仕様では、モジュールを名前、バージョン、および権限で識別することを要求しています。[ 31 ]モジュールの特定のバージョンのみをロードすることも、バージョンまたは権限が異なる同じ名前の2つのモジュールをロードすることも可能です。便宜上、短い名前へのエイリアスが提供されています。
Perlモジュール配布システムであるCPANは、まだRakuモジュールを扱っていません。代わりにプロトタイプモジュールシステムが使用されています。[ 32 ]
PerlとRakuは根本的に異なる言語ですが、一般的には「RakuをPerlのままにする」という意図があり、Rakuは明らかに「Perlプログラミング言語」です。変更点のほとんどは、言語を標準化し、初心者から熟練者まで理解しやすくし、「簡単なことはもっと簡単に、難しいことはもっと簡単に」できるようにすることを目的としています。
PerlとRakuの技術的な違いではない大きな違いは、Rakuが仕様として始まったことです。[ 33 ]これは、必要に応じてRakuを再実装できることを意味し、また、プログラマーが特定の機能に関する最終的な権威を得るためにソースコードを読む必要がないことも意味します。対照的に、Perlでは、公式ドキュメントは権威あるものとはみなされておらず、実際のPerlインタープリタの動作を非公式に記述するだけです。ドキュメントと実装の間に矛盾が見つかった場合、どちらかが他方を反映するように変更される可能性があり、このダイナミズムがPerlリリースの継続的な開発と改良を促進します。
Rakuでは、 Perlの動的型システムに静的型が追加されました。[ 34 ]例えば、
my Int $i = 0 ; my Rat $r = 3.142 ; my Str $s = "Hello, world" ; しかし、静的型付けはオプションであるため、プログラマーは明示的な型付けを一切行わなくてもほとんどの処理を実行できます。
my $i = "25" + 10 ; # $i は 35 ですRakuは段階的な型付けシステムを提供しており、プログラマーは静的型付け、動的型付け、またはその両方を組み合わせることを選択できます。
Perl では、正式なパラメータリストを一切使用せずにサブルーチンを定義します (ただし、Perl の「プロトタイプ」を使用して、単純なパラメータのカウントや一部の型チェックを行うことができます)。サブルーチンに渡される引数は、配列の要素にエイリアスされます@_。の要素が@_変更されると、その変更は元のデータに反映されます。
Rakuは言語に真の形式パラメータを導入する。[ 35 ] Rakuでは、サブルーチン宣言は次のようになる。
sub do_something ( Str $thing , Int $other ) { ... } Perlと同様に、仮引数(つまり、引数リスト内の変数)は実引数(渡される値)のエイリアスですが、デフォルトではエイリアスは定数でis rwあるため変更できません。プログラマがローカルで変更する必要がある場合は、それぞれ`in`または`in`ディレクティブを使用して、元の値の読み書き可能なエイリアスまたはコピーとして明示的に宣言できますis copy。
Rakuは、パラメータを渡すための3つの基本的なモードを提供します。位置パラメータ、名前付きパラメータ、およびスラーピーパラメータです。
位置パラメータは、ほとんどのプログラミング言語で使用される、一般的な順序付きパラメータリストです。すべてのパラメータは、名前を使用して順序なしで渡すこともできます。名前のみのパラメータ(:パラメータ名の前に が付いている)は、名前を指定することによってのみ渡すことができ、位置引数をキャプチャすることはありません。スラーピーパラメータ(*パラメータ名の前に が付いている)は、可変引数関数を作成するための Raku のツールです。スラーピーハッシュは、名前で渡された残りのパラメータをキャプチャしますが、スラーピー配列は、位置で渡された残りのパラメータをキャプチャします。
以下に、3つのパラメータ渡しモードすべてを使用した例を示します。
sub somefunction ( $a , $b , : $c , : $d , * @e ) { ... } somefunction ( 1 , 2 , : d ( 3 ), 4 , 5 , 6 ); # $a=1, $b=2, $d=3, @e=(4,5,6)上記で使用したような位置パラメータは、オプションであることを示すために末尾に を付けない限り、常に必須です?。名前付きパラメータはデフォルトではオプションですが、変数名の後に を追加することで必須として指定できます!。スラーピーパラメータは常にオプションです。
パラメータは、クロージャとして機能する任意のブロックにも渡すことができます。たとえば、forループイテレータはこのようにwhile命名されています。次の例では、リストが一度に 3 つの要素で走査され、変数としてループのブロックに渡されます$a, $b, $c。[ 36 ]
@list -> $a、$b、$cの場合{ ... } これは一般的に「pointy sub」または「pointy block」と呼ばれ、矢印はsubキーワードとほぼ同じように動作し、匿名クロージャ(Perl の用語では匿名サブルーチン)を導入します。[ 35 ]
Perlでは、変数名の前に付く記号(シジル)は、変数の使用方法に応じて変化します。
# Perlコード my @ array = ('a', 'b', 'c'); my $element = $ array[1]; # $element は 'b' に等しい、 my @extract = @ array[1, 2]; # @extract は ('b', 'c') と等しい my $element = @ array[1]; # 'b' には警告が表示されます (5.10 オプション)
楽では、印は不変であり、配列が必要か配列要素が必要かによって変化しないことを意味します。[ 34 ]
# 楽コード my @ array = 'a', 'b', 'c'; my $element = @ array[1]; # $element は 'b' と等しい my @extract = @ array[1, 2]; # @extract は ('b', 'c') と等しい my @extract = @ array[1]; # @extract は ('b') と等しい
Perlにおける数のばらつきは、英語をはじめとする多くの自然言語における数の一致にヒントを得ています。
「このリンゴ。」 # $a 正解 「これらのリンゴ。」 # @a 正解 「この3つ目のリンゴ。」 # $a[3] 正解 「この3つ目のリンゴ。」 # @a[3] 間違い
しかし、参照を用いる場合、この概念的なマッピングは破綻する。なぜなら、参照はスカラーであってもデータ構造を参照する可能性があるからである。したがって、ネストされたデータ構造を扱うには、単一の用語で単数形と複数形の両方を表現する必要があるかもしれない。
# Perl コード: 配列を含むハッシュを含むハッシュのリーフからリストを取得しますmy @trans_verbs = @ { $dictionary { 'verb' }{ 'transitive' } };この複雑さは、自然言語の一般的な使用法にも他のプログラミング言語にも匹敵するものはなく、複雑なデータ構造を操作するコードを書く際に高い認知負荷を引き起こします。これはRakuにおける同じコードです。
# Raku コード: 配列を含むハッシュを含むハッシュのリーフからリストを取得しますmy @trans_verbs = %dictionary<verb><transitive><> ; Perlは、ブレッシングと呼ばれるメカニズムを通じてオブジェクト指向プログラミングをサポートしています。任意の参照をブレッシングすることで、特定のクラスのオブジェクトにすることができます。ブレッシングされたオブジェクトに対しては、「アロー構文」を使用してメソッドを呼び出すことができます。これにより、Perlは名前で適切なサブルーチンを検索(ディスパッチ)し、ブレッシングされた変数を最初の引数として呼び出します。
非常に強力な機能ではあるものの、オブジェクト指向の最も一般的なケースである、構造体のようなオブジェクトとそれに伴うコードを扱う場合、不必要に複雑になってしまう。さらに、Perlは使用されているオブジェクトモデルについて何の仮定もできないため、メソッド呼び出しをうまく最適化することができない。
「簡単なことは簡単に、難しいことは可能にする」という精神に基づき、Rakuは祝福モデルを維持しつつ、一般的なケースに対してより堅牢なオブジェクトモデルを提供します。[ 37 ]例えば、デカルト座標の点をカプセル化するクラスは、次のように定義して使用できます。
クラスPointはrw { has $.x ; has $.y ; メソッドdistance ( Point $p ) { sqrt (( $!x - $p . x ) ** 2 + ( $!y - $p . y ) ** 2 ) } メソッド distance - to-center { self.distance : Point.new ( x = > 0 , y = > 0 ) } } my $point = Point . new ( x => 1.2 , y => - 3.7 ); say "Point の位置: (" , $point . x , ', ' , $point . y , ')' ; # 出力: Point の位置: (1.2, -3.7)# xとyを変更する(メソッド「x」と「y」がlvaluesとして使用されていることに注意してください):$point . x = 3 ; $point . y = 4 ; say "Point's location: (" , $point . x , ', ' , $point . y , ')' ; # 出力: Point's location: (3, 4)my $other-point = Point.new ( x => -5 , y => 10 ) ; $ point.distance ( $other-point ) ; #=> 10 $point.distance - to-center ; # => 5メソッド呼び出しの構文としてドットを採用している他の多くの言語( C++、Java、Pythonなど)への敬意を表して、矢印の代わりにドットが使われるようになった。
Raku の用語では、$.xは「属性」と呼ばれます。一部の言語では、これらをフィールドまたはメンバーと呼びます。属性にアクセスするために使用されるメソッドは「アクセサ」と呼ばれます。自動アクセサ メソッドは、自動的に作成され、x上記の例のメソッドのように属性名と同じ名前が付けられるメソッドです。これらのアクセサ関数は、属性の値を返します。クラスまたは個々の属性が修飾子is rw(「読み取り/書き込み」の略) で宣言されている場合、自動アクセサには、属性に設定する新しい値を渡すことができます。または、 (例のように) をlvalueとして直接割り当てることもできます。プログラマが属性に対してより豊富なインターフェイスを必要とする場合、自動アクセサはユーザー定義メソッドに置き換えることができます。属性は、属性がどのように宣言されているかに関係なく、構文を介してクラス定義内から直接のみアクセスできます。$!その他のすべてのアクセスは、アクセサ メソッドを介して行う必要があります。
Rakuのオブジェクトシステムは、Rakuの多くのオブジェクト指向プログラミング機能をPerlに導入したMooseフレームワークに影響を与えた。
継承とは、オブジェクトや型が既存のオブジェクトや型のコードや定義を再利用できるようにする手法です。例えば、プログラマーは標準型に属性を追加したい場合などに利用できます。Javaなどの他の言語では、クラスを既存のクラスのサブクラスにすることで継承を実現しています。
Rakuは、他の言語のクラスと同様のクラスとロールによる継承を提供します。
Raku のロールは、 Java のインターフェース、 Ruby のミックスイン、PHPおよびSmalltalk の派生言語Squeakのトレイト[ 38 ]の機能を担います。これらはクラスによく似ていますが、より安全な合成メカニズムを提供します。[ 39 ]これらは、クラスとともに使用される場合、継承チェーンに追加するのではなく、合成を実行するために使用されます。ロールは名目上の型を定義します。動作と状態の集合に意味的な名前を提供します。ロールとクラスの根本的な違いは、クラスはインスタンス化できますが、ロールはインスタンス化できないことです。[ 40 ]
ロールはクラスとは異なりますが、ロールを直接インスタンス化したり、ロールを型オブジェクトとして使用したりする Raku コードを書くと、Raku はロールと同じ名前のクラスを自動的に作成するため、ロールをクラスであるかのように透過的に使用できます。[ 41 ]
基本的に、ロールとは、継承を使用せずにクラスに追加できる(抽象的な場合もある)メソッドと属性の集合です。ロールは個々のオブジェクトに追加することもできます。この場合、Rakuは匿名サブクラスを作成し、そのサブクラスにロールを追加し、オブジェクトのクラスを匿名サブクラスに変更します。
例えば、犬は哺乳類です。なぜなら、犬は乳腺や(哺乳類の親である脊椎動物を通して)背骨など、哺乳類から特定の特性を受け継いでいるからです。一方で、犬はいくつかの異なるタイプの行動をとることもあり、これらの行動は時間とともに変化する可能性があります。例えば、犬はペット、野良犬(捨てられたペットは、ペットとは関係のない生存のための行動を身につけます)、盲導犬(盲導犬は訓練を受けているため、最初から盲導犬として生まれてくるわけではありません)などです。しかし、これらは犬に追加できる行動の集合です。また、これらの行動を他の動物にも応用できるような形で記述することも可能です。例えば、猫も同様にペットにも野良犬にもなり得ます。したがって、犬と猫は互いに区別されますが、どちらもより一般的なカテゴリーである哺乳類に属しています。つまり、哺乳類はクラスであり、犬と猫は哺乳類から継承するクラスです。しかし、ペット、野良犬、ガイド犬に関連付けられた動作は、クラスに追加できる役割、またはクラスからインスタンス化できるオブジェクトです。
クラスMammalは脊椎動物です { ... } クラスDogは哺乳類です { ... } 役割ペット{ ... } 役割ストレイ{ ... } 役割ガイド{ ... } ロールは、キーワードを使用してクラスまたはオブジェクトに追加されますdoes。クラスからの継承を示すには、別のキーワードを使用しますis。これらのキーワードは、2つの機能の意味の違いを反映しています。ロール合成はクラスにロールの振る舞いを与えますが、クラスがロールと完全に同じものであることを示すものではありません。
class GuideDog is Dog does Guide { ... } # サブクラスがロールを構成するmy $dog = new Dog ; $dog does Guide ; # 個々のオブジェクトが役割を構成する役割はクラスとは異なりますが、どちらも型であるため、通常クラスを記述する変数宣言箇所に役割を記述することができます。例えば、人間の盲目の役割には、ガイド型の属性を含めることができます。この属性には、盲導犬、盲導馬、盲導人間、あるいは盲導機械などが含まれる可能性があります。
class Human { has Dog $dog ; # ガイド の役割を果たすかどうかに関わらず、あらゆる種類の犬を含めることができます。 } role Blind { has Guide $guide ; # ガイドの役割を果たすオブジェクトであれば何でも含めることができます 。... # 犬でも他のものでも構いません } Perl の正規表現と文字列処理のサポートは、常に Perl の特徴の一つでした。[ 42 ] Perl のパターンマッチング構造は、しばらくの間正規言語表現の能力を超えていたため、 [ 43 ] Raku のドキュメントでは、それらを正規表現と呼び、正式な定義から切り離しています。
Raku は正規表現に関して Perl の機能のスーパーセットを提供し、それらを「ルール」と呼ばれるより大きなフレームワークに統合します。このルールは、文脈依存の構文解析形式 (構文解析式文法やANTLR の構文述語など)の機能を提供するとともに、語彙スコープに関してクロージャとして機能します。[ 44 ]ルールは、サブルーチン定義と非常によく似た使い方をするキーワードで導入されます。匿名ルールは、 (または) キーワードで導入することも、 (一致) または(置換) 演算子を介して Perl の正規表現のようにインラインで使用することもできます。ruleregexrxms
『アポカリプス 5』の中で、ラリー・ウォールは「現在の正規表現文化」に関する20の問題点を列挙した。その中には、Perlの正規表現が「コンパクトすぎて『かわいい』」、「メタ文字への依存が少なすぎる」、「名前付きキャプチャのサポートがほとんどない」、「文法のサポートがほとんどない」、「『実際の』言語との統合が不十分」といったものがあった。[ 45 ]
Rakuでは、Perlの構文の一部が変更され、最も一般的なケースに合わせてさまざまな構文上の手がかりが最適化されています。たとえば、 Perlの制御フロー構文で必要だった括弧(丸括弧)は、現在は省略可能です。[ 36 ]
if is-true () { for @array { ... } } また、,(カンマ)演算子はリストコンストラクタになったため、リストを括弧で囲む必要はなくなりました。
@array = 1 , 2 , 3 , 4 ; これで、@array要素が「1」、「2」、「3」、「4」のみの配列が作成されます。
Rakuでは比較を「連鎖」させることができます。つまり、以下のような一連の比較が可能です。
20 <= $temperature <= 25の場合、 「室温は 20 度から 25 度の間です!」と表示する。 } これは、各左から右への比較がそれぞれ独立して実行されたかのように扱われ、その結果がand演算によって論理的に結合されます。
Rakuは、 Haskellなどの一部の関数型プログラミング言語の特徴であるリストの遅延評価の方法を使用しています。[ 46 ]
@integers = 0 .. Inf ; # 0から無限大までの整数上記のコードは、無限サイズのリストを配列に代入しようとしてクラッシュすることはありませんし@integers、検索するスロット数が限られている場合にリストを拡張しようとして無限にハングアップすることもありません。
これにより、入出力操作、リスト変換、パラメータ渡しなど、Rakuにおける多くの一般的なタスクが簡素化されます。
遅延評価に関連して、 IconやPythonなどの言語のジェネレーターのように動作する、gatherおよびを使用した遅延リストの構築があります。take
my $squares = lazy gather for 0 .. Inf { take $_ * $_ ; }; $squaresこれは平方数の無限リストになりますが、遅延評価により、gather要素はアクセスされたときにのみ計算されることが保証されます。
Rakuは、他の値の合成値であるジャンクションの概念を導入しています。 [ 46 ]最も単純な形では、ジャンクションは一連の値を結合演算子で組み合わせることによって作成されます。
# | ("any") ジャンクションの例: my $color = 'white' ; unless $color eq 'white' | 'black' | 'gray' | 'grey' { die "カラー印刷はサポートされていません\n" ; } # & ("all") ジャンクションの例: my $password = 'secret!123' ; if $password ~~ /<:alpha>/ & / <:digit> / & / <:punct> / { say "あなたのパスワードは十分に安全です" ; } |は、左辺または右辺の引数のいずれかと等しい値を示します。 は、左辺と右辺の&両方の引数と等しい値を示します。 これらの値は、通常の値を使用するコードであればどれでも使用できます。 ジャンクションに対して実行される操作は、ジャンクションのすべてのメンバーに等しく作用し、論理積演算子に従って結合されます。 したがって、は を生成します。 比較では、ジャンクションは比較に対して単一の真または偽の結果を返します。 " " ジャンクションは、ジャンクションのいずれかの要素に対して比較が真である場合に真を返します。 " " ジャンクションは、ジャンクションのすべての要素に対して比較が真である場合に真を返します。("apple"|"banana") ~ "s""apples"|"bananas"anyall
ジャンクションは、型のジャンクションに限定されたジェネリックプログラミングのスタイルを導入することで、型システムをより豊かに拡張するためにも使用できます。
subset Color of Any where RGB_Color | CMYK_Color ; sub get_tint ( Color $color , Num $opacity ) { ... } 低レベル言語では、 C プリプロセッサの普及により、マクロの概念はソースコードのテキスト置換と同義語となっています。しかし、 Lispなどの高レベル言語は、C より先に、はるかに強力なマクロを使用していました。[ 47 ] Raku はこの Lisp のようなマクロの概念を利用します。[ 35 ]この種のマクロの強力さは、プログラムを単純なテキストとしてではなく、高レベルのデータ構造として操作し、プログラミング言語のすべての機能を自由に利用できるという事実から生まれます。
Raku マクロ定義はサブルーチンまたはメソッド定義のように見え、解析されていない文字列、事前に解析されたコードを表すAST、またはその 2 つの組み合わせに対して操作を実行できます。マクロ定義は次のようになります。[ 48 ]
macro hello ( $what ) { quasi { say "こんにちは { {{{$what}}} }" }; } この例では、マクロはC言語スタイルのテキスト置換と大差ありませんが、マクロパラメータの解析はマクロが呼び出し元のコードに対して動作する前に行われるため、診断メッセージははるかに有益な情報を提供します。しかし、マクロの本体は使用されるたびにコンパイル時に実行されるため、多くの最適化手法を適用できます。コンパイル時に処理を行うことで、結果として得られるプログラムから複雑な計算を排除することも可能です。
Perlでは、識別子名にASCII英数字とアンダースコアを使用できます。これらは他の言語でも使用可能です。Rakuでは、英数字にはほとんどのUnicode文字が含まれます。さらに、ハイフンとアポストロフィも使用できます(ただし、数字が後に続かないなど、いくつかの制限があります)。名前の単語をアンダースコアの代わりにハイフンで区切るスタイルは、「ケバブケース」と呼ばれます。
「ハローワールド」プログラムは、言語を紹介する際によく使われるプログラムです。Rakuでは、「ハローワールド」は次のようになります。
「こんにちは、世界」と言いましょう。 ただし、その方法は一つだけではありません。
Rakuにおける階乗関数は、いくつかの異なる方法で定義されています。
# 再帰(`if\else`構文を使用)sub fact ( UInt $n --> UInt ) { if $n == 0 { 1 } else { $n * fact ( $n-1 ) } } # 再帰を使用 (if をステートメント修飾子として使用) sub fact ( UInt $n --> UInt ) { return 1 if $n == 0 ; return $n * fact ( $n-1 ); } # 再帰(`when`構文を使用)sub fact ( UInt $n --> UInt ) { when $n == 0 { 1 } default { $n * fact ( $n-1 ) } } # 三項演算子の使用sub fact ( UInt $n --> UInt ) { $n == 0 ?? 1 !! $n * fact ( $n-1 ) } # 複数のディスパッチを使用multi fact ( 0 ) { 1 } multi fact ( UInt $n --> UInt ) { $n * fact ( $n - 1 ) } # 還元メタ演算子sub fact ( UInt $n --> UInt ) を使用する { [*] 1 .. $n } # 階乗演算子を作成し、還元メタ演算子sub postfix を使用します: <!>( UInt $n --> UInt ) { [*] 1 .. $n } # `state` 宣言子を使用してメモ化された階乗サブファクトを作成します( UInt $n --> UInt ) { state %known = 0 => 1 ; return %known { $n } if %known { $n }: exists ; %known { $n } = $n * fact ( $n-1 ); return %known { $n }; } クイックソートはよく知られたソートアルゴリズムです。関数型プログラミングパラダイムを用いた動作する実装[ a ]は、Rakuで簡潔に記述できます。
# 空のリストは空のリストにソートされます。マルチクイックソート([]) { () } # それ以外の場合は、最初の項目をピボットとして抽出します... multi quicksort ([ $pivot , * @rest ]) { # パーティション。my @before = @rest . grep (* < $pivot ); my @after = @rest . grep (* >= $pivot ); # パーティションをソートします。flat ( quicksort ( @before ), $pivot , quicksort ( @after )) } log2(list_length)パーティションと の大きい方を反復処理しbefore、after小さい方のパーティションのみを再帰することで制限できます。ハノイの塔は、コンピュータサイエンスにおける再帰プログラミングの導入によく用いられる。この実装では、Rakuのマルチディスパッチ機構とパラメトリック制約を使用している。
multi sub hanoi ( 0 , $, $, $) { } # ディスクがないので、何も行わないmulti sub hanoi ( $n , $a = 'A' , $b = 'B' , $c = 'C' ) { # $n 個のディスクと 3 つのペグ A、B、C から開始hanoi $n - 1 , $a , $c , $b ; # まず、A から B へ $n - 1 個のディスクを移動しますsay "ディスク $n をペグ $a からペグ $c へ移動" ; # 次に、A から C へ最後のディスクを移動hanoi $n - 1 , $b , $a , $c ; # 最後に、B から C へ $n - 1 個のディスクを移動 } Rakuの歴史において、書籍執筆は2つの波に分かれて展開されました。最初の波は、2000年のPerl 6の発表後に起こりました。これらの書籍は当時の言語設計を反映しており、内容はほとんどが時代遅れとなっています。2番目の波は、2015年のバージョン1.0の発表後に起こり、既に出版されている書籍と、現在執筆中の書籍がいくつか含まれています。
また、初期のPerl 6仮想マシンの1つであるParrotに特化した書籍が2009年に出版された。
「Perl」は言語ファミリーであり、「Raku」(旧称「Perl 6」)はそのファミリーの一部ですが、独自の開発チームを持つ独立した言語です。「Raku」の存在は、「Perl」の継続的な開発に大きな影響を与えるものではありません。
{{cite web}}: CS1 maint: 数値名: 著者リスト (リンク)Perl の正規表現は「正規」ではありません。つまり、sed や grep のように後方参照もサポートされているため、この言語は厳密には正規言語ではなくなります。