ABC 言語への簡単な入門

以下の文章は、プログラミング言語の一つである「ABC」を紹介したもので、 配布されている ABC Release 1.04.01 の添付文書 "abc.intro" の日本語訳です。 夏鰯が訳したものを、作者に許可をいただいて 掲載しています。用語などは正確でないかもしれません。 軽いバージョンもあります。 当サイトの ABC 紹介記事もご覧ください。

ABC 言語の最新情報や実行環境を手に入れるには、作者による A Short Introduction to the ABC Language [英語] を ご覧ください。


この記事は、プログラミング言語 ABC とその実装についての短時間での概要を説明し、 ABC でのプログラムの例をいくつか示すものです。 ABC に関する完全なドキュメンテーションは、『The ABC Programmer's Handbook』(詳細後述) に 載っています。

言語

ABC は、もともとは BASIC に代わるものとして、対話的で学びやすいけれど 構造化され高度になるように設計された、命令言語です。 ABC は反復して設計が行われ、現在のバージョンは第 4 の反復になります。 以前のバージョンは B と呼ばれていました (C 言語のもとになったものと 混同しないで下さい)。

ABC は一般的で日常的なプログラミング、つまり、 BASIC や Pascal や AWK を使っていたたぐいのプログラミングに適しています。 システムプログラミングの言語ではありません。 ABC は優れた教育向け言語であり、対話的なのでプロトタイピング用に優れています。 速く計算することでは、Unix の 'bc' よりずっと高速です。

ABC のプログラムは、かならずコンパクトにおさまり、Pascal や C の同等のプログラムの 1/4 から 1/5 のサイズになります。ただし、これは可読性を犠牲にしてはおらず、 実際にはその逆で読みやすいものになっています (以下の例を参照してください)。

ABC は、言語中で存在する型が少ない (5 つ) ため、簡単に学べます。 すでに Pascal やそれに近い言語をご存知なら、言語全体を 1 時間かそこらで 習得できます。データ型が非常に高度なので、簡単に使えます。

5 つの型は、次のとおりです。

環境

実装にはプログラムの作成をずっと楽にしてくれるプログラミング環境が含まれます。 この環境が言語についてたくさん知っていて、あなたに代わってたくさん仕事をしてくれるわけです。 例えば、あなたが W をタイプすると、システムはあなたのためにコマンドの補完を提案します。

    W?RITE ?     

それがあなたの求めるものなら、[tab] を押せばその表現が入力されます。 あなたのほしいのが WHILE なら、H をタイプすればシステムは適合する候補を変更します。

    WH?ILE ?:     

このしくみは、あなたが自分で定義したコマンドにも働きます。 同様に、あなたが開いた括弧や引用符をタイプすると、 閉じる方の括弧や引用符はなにもしなくても入力されます。 候補を無視したければ、コマンド全体をタイプすれば無視できます。

異なるプログラムを開発するためのワークスペースをサポートしています。 各ワークスペースの変数は維持されるので、ABC を使うのを中断して後で戻ってきても、 変数はそのまま残っています。これでファイル処理の機能は必要なくなります。 ABC では、変数とファイルの間に概念的な違いはありません。

この言語は強い型づけがなされていますが、宣言はありません。 型は文脈によって決定されるのです。

ABC の能力を評価していただくのに最善 (から2番目) の方法は、 いくつか例をご覧いただくことです (最善なのは使っていただくことです)。 この後で、>>> は ABC のプロンプトです。

数値

	>>> WRITE 2**1000                                                     
	107150860718626732094842504906000181056140481170553360744375038837    
	035105112493612249319837881569585812759467291755314682518714528569    
	231404359845775746985748039345677748242309854210746050623711418779    
	541821530464749835819412673987675591655439460770629145711964776865    
	42167660429831652624386837205668069376                                
	                                                                      
	>>> PUT 1/(2**1000) IN x                                              
	>>> WRITE 1 + 1/x                                                     
	107150860718626732094842504906000181056140481170553360744375038837    
	035105112493612249319837881569585812759467291755314682518714528569    
	231404359845775746985748039345677748242309854210746050623711418779    
	541821530464749835819412673987675591655439460770629145711964776865    
	42167660429831652624386837205668069377                                

テキスト

	>>> PUT ("ha " ^^ 3) ^ ("ho " ^^ 3) IN laugh   
	>>> WRITE laugh                                
	ha ha ha ho ho ho                              
	                                               
	>>> WRITE #laugh                               
	18                                             
	                                               
	>>> PUT "Hello! "^^1000 IN greeting            
	>>> WRITE #greeting                            
	7000                                           

リスト

	>>> WRITE {1..10}                                    
	{1; 2; 3; 4; 5; 6; 7; 8; 9; 10}                      
	>>> PUT {1..10} IN l                                 
	>>> REMOVE 5 FROM l                                  
	>>> INSERT 4 IN l                                    
	>>> INSERT pi IN l                                   
	>>> WRITE l                                          
	{1; 2; 3; 3.141592653589793; 4; 4; 6; 7; 8; 9; 10}   
	                                                     
	>>> PUT {} IN ll                                     
	>>> FOR i IN {1..3}:                                 
	        INSERT {1..i} IN ll                          
	>>> WRITE ll                                         
	{{1}; {1; 2}; {1; 2; 3}}                             
	>>> FOR l IN ll:                                     
	        WRITE l /                                    
	{1}                                                  
	{1; 2}                                               
	{1; 2; 3}                                            
	>>> WRITE #ll                                        
	3                                                    

コンパウンド

	>>> PUT ("Square root of 2", root 2) IN c   
	>>> WRITE c                                 
	("Square root of 2", 1.414213562373095)     
	>>> PUT c IN name, value                    
	>>> WRITE name                              
	Square root of 2                            
	>>> WRITE value                             
	1.414213562373095                           

電話帳

この例ではテーブル・データ型を使っています。使ううえでは、テーブルは配列に似ています。

	>>> PUT {} IN tel                 
	>>> PUT 4054 IN tel["Jennifer"]   
	>>> PUT 4098 IN tel["Timo"]       
	>>> PUT 4134 IN tel["Guido"]      
	                                  
	>>> WRITE tel["Jennifer"]         
	4054                              

ABC の値をすべて書き出すことができます。テーブルはキーによってソートされています。

	>>> WRITE tel                                           
	{["Guido"]: 4134; ["Jennifer"]: 4054; ["Timo"]: 4098}   

keys 関数はリストを返します。

	>>> WRITE keys tel                    
	{"Guido"; "Jennifer"; "Timo"}         
	                                      
	>>> FOR name IN keys tel:             
	       WRITE name, ":", tel[name] /   
	Guido: 4134                           
	Jennifer: 4054                        
	Timo: 4098                            

自分でコマンドを定義することができます。

	HOW TO DISPLAY t:                 
	   FOR name IN keys t:            
	      WRITE name<<10, t[name] /   
	                                  
	>>> DISPLAY tel                   
	Guido      4134                   
	Jennifer   4054                   
	Timo       4098                   

指定した名前のユーザを探すには、量指定子をつかいます。

	>>> IF SOME name IN keys tel HAS tel[name] = 4054:   
	       WRITE name                                    
	Jennifer                                             

今度は、逆順のテーブルを作ります。

	>>> PUT {} IN subscriber                                
	>>> FOR name IN keys tel:                               
	       PUT name IN subscriber[tel[name]]                
	                                                        
	>>> WRITE subscriber[4054]                              
	Jennifer                                                
	                                                        
	>>> WRITE subscriber                                    
	{[4054]: "Jennifer"; [4098]: "Timo"; [4134]: "Guido"}   

コマンドや関数はポリモーフィックです。

	>>> DISPLAY subscriber   
	4054       Jennifer      
	4098       Timo          
	4134       Guido         

関数はどんな型でも返すことができます。

インデントが重要だということに注意してください --- BEGIN-END や { } は出てきません。

	HOW TO RETURN inverse t:                                
	   PUT {} IN inv                                        
	   FOR k IN keys t:                                     
	      PUT k IN inv[t[k]]                                
	   RETURN inv                                           
	                                                        
	>>> WRITE inverse tel                                   
	{[4054]: "Jennifer"; [4098]: "Timo"; [4134]: "Guido"}   
	                                                        
	>>> DISPLAY inverse inverse tel                         
	Guido      4134                                         
	Jennifer   4054                                         
	Timo       4098                                         

クロスリファレンス索引生成

「テキストファイル」は数値を文字列に関連付けたテーブルとして表現されます。

	>>> DISPLAY poem                         
	1         I've never seen a purple cow   
	2         I hope I never see one         
	3         But I can tell you anyhow      
	4         I'd rather see than be one     

次に挙げる関数は、そのようなドキュメントを受け取って、ドキュメントのクロスリファレンス索引、つまり単語を行番号に関連付けたテーブルを返します。

	HOW TO RETURN index doc:              
	   PUT {} IN where                    
	   FOR line.no IN keys doc:           
	      TREAT LINE                      
	   RETURN where                       
	TREAT LINE:                           
	   FOR word IN split doc[line.no]:    
	      IF word not.in keys where:      
	     PUT {} IN where[word]            
	      INSERT line.no IN where[word]   

ここでは TREAT LINE が生成部で、段階的な生成をじかにサポートしています。'split' は文字列を空白で区切られた単語単位に分割する関数です。

	>>> WRITE split "Hello world"   
	{[1]: "Hello"; [2]: "world"}    
	                                
	>>> DISPLAY index poem          
	But        {3}                  
	I          {2; 2; 3}            
	I'd        {4}                  
	I've       {1}                  
	a          {1}                  
	anyhow     {3}                  
	be         {4}                  
	can        {3}                  
	cow        {1}                  
	hope       {2}                  
	never      {1; 2}               
	one        {2; 4}               
	purple     {1}                  
	rather     {4}                  
	see        {2; 4}               
	seen       {1}                  
	tell       {3}                  
	than       {4}                  
	you        {3}                  

詳しい情報

ABC とその実装について、たくさんのプログラム例とともに詳しく述べた完全な文書が『The ABC Programmer's Handbook』(Leo Geurts・Lambert Meertens・Steven Pemberton 共著、Prentice-Hall 刊、ISBN 0-13-000027-2) に載っています。

IEEE Software Vol. 4, No. 1, January 1987, pp.56-64 にある、 Steven Pemberton の『An Alternative Simple Language and Environment for PCs』も 参照してください。

私たちによる不定期のニュースレター (アドレスは後述) や議論のためのメーリングリスト も利用可能です。参加するには、ご希望の E-mail アドレスを abc-list-request@cwi.nl に 送ってください。

実装

Unix 版用のソースが Usenet の comp.sources.unix グループに、 バイナリが comp.binaries.{mac, ibm.pc, atari.st} に投稿されています。 これらはいくつかのサーバから入手でき、例えば、 hp4nl.nluug.nl [192.16.202.2]、mcsun.eu.net [192.16.202.1]、 uunet.uu.net [192.48.96.2] の {pub}/{programming}/languages/abc ディレクトリから anonymous FTP で入手できます。 また、

	request: programming/languages/abc   
	topic: index                         

というメールメッセージを info-server@hp4nl.nluug.nl に送れば 入手可能なファイルの一覧が手に入りますし、

	topic: <filename>                    

でそのファイルの 1 つを入手することもできます。

この記事の執筆時点で入手可能なファイルは以下のとおりです。

index
利用可能なファイルの一覧
abc.intro
ABC の概要 (以下の実装にも含まれる)
abcst.arc
Atari ST 版
abcpc.arc
IBM PC 版
abc.mac.sit.hqx
Mac 版
abc.unix.tar.Z
Unix 版
README
上記ファイル解凍の仕方の説明

アドレス

ABC Implementations
CWI/AA
Kruislaan 413
1098 SJ AMSTERDAM
The Netherlands

Email: abc@cwi.nl



Presented by 夏鰯 <sardine@toyfish.net>