プログラミング言語におけるcomefrom文(カムフロム文、: comefrom statement)とは、コード内の任意のポイント(専らラベルで指定される)から、そのcomefrom文の場所へ制御がジャンプ(移動)するという制御構造のひとつである「」である。goto文とほぼ反対の働きをするものであり、元々は冗談として提唱されたものだったが、一部のプログラミング言語で実際に実装されている。gotogo toとも書かれるように、comefromcome fromとも書かれる。

概要 編集

コード内の移動元のポイントは、通常comefrom引数として指定される。指定されたポイントで移動が発生するかどうかは、使用される言語によって異なる。同じ移動元を指定するcomefrom文が複数ある場合、言語によって、そのようなcomefromは無効となるもの、非決定的となるもの、定義済みの優先順位で実行されるものや、INTERCALのような並列計算もしくは並行計算が行われるものがある。

comefrom文の簡単な例"comefrom x"で説明する。この文は、トラップドアとして機能するラベル x と対になって使用される。このラベルは、対応するcomefrom文の近くに物理的に配置する必要はない。コードの実行がラベルに達すると、対応するcomefrom文に制御が移動する。if文の中にラベルがある場合は、goto文の場合と同様に、if文の条件が満たされた場合のみ移動が行われる。goto文がコードのローカル構造のみに依存するのに対し、comefrom文はグローバル構造に依存する。goto文の場合はgoto文のある行に到達すると無条件に制御が移動するが、comefrom文は、ラベルのあるスコープ内にcomefrom文があるか確認し、条件がヒットしたかどうかを確認するために、プログラムまたはスコープ全体をスキャンする必要がある。これにより、デバッグ(およびプログラムの制御フローの理解)が非常に困難になる。これは、問題の行やラベルの近くに制御のジャンプ先を示すものがなく、その行またはラベルを参照しているcomefrom文をプログラム全体から探す必要があるためである。

Python gotoモジュールでは、デバッガフックを使用してcomefrom文を実装できる[1]後述)。また、Linuxカーネルの構成オプション CONFIG_JUMP_LABEL で使用されるgcc機能"asm goto"でも実装できる。 no-opの場所は保存されており、no-opの後に命令に戻る実行可能フラグメントへのジャンプに置き換えられる。

歴史 編集

comefromは、冗談のアセンブリ言語の命令'CMFRM'として現れたのが最初である。これは、1973年に『データメーション英語版』誌に掲載された、R・ローレンス・クラークによるエドガー・ダイクストラの文書「Go To Statement Considered Harmful英語版(Go to 文は有害と考えられる)」に反応した記事にて詳しく説明されていたものである[2]

comefrom文は最終的に、難解プログラミング言語の1つであるINTERCALの変種であるC-INTERCALに、さらに曖昧な'computed comefrom'(計算されたcomefrom)とともに実装された。また、Fortranに、既存のdo文を補完するための'assigned COME FROM'と'DONT'を追加する提案もあった[3]

2004年4月1日、Richie Hindleが、Python用のGOTOCOMEFROMの実装を公開した[1]エイプリルフールに公開されたものであり、真面目に使用することを意図したものではないが、構文は正当であり、実装は完全に機能する。

実用的な用途 編集

BASIC 編集

以下は、"GOTO"の代わりに"COMEFROM"を使用した架空のBASIC方言のプログラムの例である。

10 COMEFROM 40
20 INPUT "WHAT IS YOUR NAME? "; A$
30 PRINT "HELLO, "; A$
40 REM

このプログラムは、ユーザに名前を質問し、入力された名前に対し挨拶をするという動作を繰り返す。行40の命令"REM"は、単なるNOP(この場合はコメント)である。行10の"COMEFROM"文は、その内容に関係なく、実行が行40に達するとこの行に戻る。

Python 編集

以下に、joke gotoモジュールがインストールされたPythonでの完全に実行可能な例(デバッガフックを使用してプログラムの実行を制御する)を示す。

from goto import comefrom, label

comefrom .repeat
name = raw_input('What is your name? ')
if name:
    print("Hello", name)
    label .repeat
print("Goodbye!")

Ruby 編集

以下に、Intercal comefrom文のRubyでの実装を示す。

$come_from_labels = {}

def label(l)
  if $come_from_labels[l]
    $come_from_labels[l].call
  end
end

def come_from(l)
  callcc do |block|
    $come_from_labels[l] = block
  end
end

OS/360 Fortran G 編集

OS/360のFortran Gコンパイラには、デバッグパケット機能がある。その"AT"文は、制御フローをデバッグブロックに渡すという点でcomefrom文に似ている。ブレークポイントは一般的に似ている[4]

  • 例1:SOLON、GFAR、EWELLの値は、文10の完了時に検査される。AT文は文11を示す。
      INTEGER SOLON, GFAR, EWELL
         .
         .
         .
10    SOLON = GFAR * SQRT(FLOAT(EWELL))
11    IF (SOLON) 40, 50, 60
         .
         .
         .
      DEBUG UNIT(3)
      AT 11
      DISPLAY GFAR, SOLON, EWELL
      END
  • 例2:文35が検出されると、STOCKの全ての値が表示される。
      DIMENSION STOCK(1000),OUT(1000)
         .
         .
         .
      DO 30 I=1, 1000
25    STOCK(I)=STOCK(I) - OUT(I)
30    CONTINUE
35    A = B + C
         .
         .
         .
      DEBUG UNIT(3)
      AT 35
      DISPLAY STOCK
      END
  • 例3:トレースは文10で始まり、ループの実行中に文20でトレースが停止し、ループの後に再開する。文30が実行される直前にトレースが停止する。
10    A = 1.5
12    L = 1
15    B = A + 1.5
20    DO 22 I = 1,5
         .
         .
         .
22    CONTINUE
25    C = B + 3.16
30    D = C/2
      STOP
         .
         .
         .
      DEBUG UNIT(3), TRACE
C     DEBUG PACKET NUMBER 1
      AT 10
      TRACE ON
C     DEBUG PACKET NUMBER 2
      AT 20
      TRACE OFF
      DO 35 I = 1,3
         .
         .
         .
35    CONTINUE
      TRACE ON
C     DEBUG PACKET NUMBER 3
      AT 30
      TRACE OFF
      END

関連項目 編集

comefrom文に類似した概念

脚注 編集

  1. ^ a b Hindle, Richie (1 April 2004), goto for Python, Entrian, http://entrian.com/goto/ .
  2. ^ Clarke, Lawrence, “We don't know where to GOTO if we don't know where we've COME FROM. This linguistic innovation lives up to all expectations.”, Datamation, オリジナルの2018-07-16時点におけるアーカイブ。, https://web.archive.org/web/20180716171336/http://www.fortran.com/fortran/come_from.html 2004年9月24日閲覧。 
  3. ^ Modell, Howard; Slater, William (April 1978). “Structured programming considered harmful”. ACM SIGPLAN Notices 13 (4): 76–79. doi:10.1145/953411.953418. http://www.modell.com/Magery/SPharmful.html 2014年7月18日閲覧。. 
  4. ^ IBM System/360 and System/370 Fortran IV Language, GC28-6515-10, May 1974
  5. ^ F. X. Reid, On the Formal Semantics of the COMEFROM Statement. FACS FACTS, Issue 2006-1, pages 18–20, March 2006.

外部リンク 編集