Web情報を保存するとは何か

 先日のクローズアップ現代で「忘れられる権利」を中心にWebのプライバシー問題が取り上げられていました。

“忘れられる権利”はネット社会を変えるか? – NHK クローズアップ現代

 Webとプライバシーの問題は個人的に興味があるところですので、近いうちにこのプログで少し書いてみるつもりですが、今回はそのクロ現の放送を観て考えさせられたWeb情報の長期的な保存の話を少しばかり。

 あの放送を観ながらプライバシーの問題をいろいろと考えさせられつつも、情報の長期保存という観点から以下の考えが頭をよぎりました。

  1. 善し悪しはともかく、大量に複製することがWeb情報の長期的な保存方法として最もfuture-proofではないか。
  2. 善意によるにしろ、悪意によるにしろ、その意図はともかく、ネットユーザーが関心を持ち、残そうと思われるWeb情報ほど大量に複製されてWeb上から消えにくくなる。つまり、情報が残りやすくなる。
  3. 複製されるにしても、ウェブサイトやウェブページをそのまま保存することはほとんどなく、ウェブサイトに掲載された1つの画像ファイルとか、ワンセンテンスのテキストなど情報の一断片が複製されていく。断片化され、複製を繰り返される情報は図書館業界が保存したいと考える「Web情報」とは違うのか。違うならその違いは何か。

 Internet Archive各国の国立図書館がウェブアーカイブプロジェクトを進めています。これらのプロジェクトの多くはウェブサイトやウェブページをなるべく公開された状態に近い形で保存しています。ウェブサイトに掲載された情報だけではなく、それを載せていた器(ウェブサイト)も保存しているわけです。

 そもそも論で、これはWeb情報に限らず、ですが、情報はそれを載せていた器も非常に重要な情報です。加えて公開者による事後的な変更が容易なWebの場合、信頼できる機関がWebサイトをそのまま保存して、その真正性を担保することも非常に重要になってきます。では、器(原ウェブサイト)から切り離され、複製を繰り返された断片的なWeb情報に価値はないかというとそうでもないと思うのです。

 理由は主に2つです。

 理由の1つは身も蓋もない話ですが、ほとんどの人が日常生活の中でWeb情報に歴史学者の史料批判に耐えうるほどの真正性を求めてがいないだろうということです。多くの場合はぱっと見て、「まあ、たぶんこれで問題ないかな」と感じさせる程度の確かさで満足することが多いのではないかと思うのです。探して自分が納得するものが見つかればそれでいい。

 もう1つは(これも身も蓋もないですが)、全く残らないよりは断片的でも残るほうがはるかにマシではないかということです。史料批判に耐えうる形で保存されることは重要です。Web情報がある時点でその形で公開されていたということが重要になってくるので、可能な限りWeb情報は公開されたそのままの状態で保存することは望ましい。複製を繰り返し、もはや原情報の有り様が全くわからなくなった状態ではその情報の真正性は担保されなくなってしまいます。とはいえです。転載を繰り返えされた断片的な情報しか残っていなかった場合はどうなるのでしょうか。例えば、すで閉鎖されたある政治家のブログのあるエントリの一部分が転載を繰り返し、2chのまとめサイトにのみ残っている。もしくは、ある芸術家の顔写真、もはやそれを掲載していた新聞記事はとうの昔に削除されてしまったが、かろうじてTumblrでクリッピングされていたので残っている。そんな場合です。その断片的なWeb情報を真正性に問題があることを前提としてやはり使用せざるをえないのではないかと思うのです。Web情報はウェブアーカイブによって器(原ウェブサイト)ごと残されていくものと、器(原ウェブサイト)を失って複製を繰り返された断片化したものとに分かれていくのだと思いますが、未来の歴史学者が後者に頼らざるを得ないケースもしばしば出てくるかもしれません。断片化されたWeb情報を史料として扱うための研究手法や経験が歴史学に蓄積されていくようになるのかもしれませんね※1

 特定の人間、特定の機関が集中的に管理するのではない。個々のネットユーザーが関心を持ったWeb上の情報が結果として大量に複製されて残りやすくなる。Web上の情報が細分化されて分散的に保存されていく仕組みになっている。各機関が進めるウェブアーカイブプロジェクトも、器(原ウェブサイト)の保存も重要だと考える人間、機関が器ごとWeb情報を保存をしているわけですが、これも上に挙げた2に当てはめて考えると、Webというシステムが持つ情報を残そうという志向に結果として包含されているように思えます。どちらにせよ、ウェブアーカイブプロジェクトによって保存されるWeb情報とWebのその有り様から結果として残っている断片的なWeb情報は相対立するものではなく、大きな海の中で補完しあう関係にあるのでしょう。

 Webが誕生してまだ20年と少し、ウェブアーカイブプロジェクトも15年ちょっとの歴史しかありません。紙の上に載せられた情報が歩んだ歴史的スパンを考えると、Web情報の長期保存について最適解を出せる段階ではまだまだないでしょうが、Webというシステムは情報の保存という観点から考えても割と柔軟でしなやかな仕組みを備えているのかもしれません。

 

※1

と、書いたものの、今の時代と時代的にあまりに近すぎるので当分の間は歴史学の仕事でなく、他の分野の仕事になるかもしれないという気もします。

純粋関数型プログラミング言語Haskellを触ってみました。(『7つの言語 7つの世界』第7章)

7つの言語 7つの世界』(オーム社)の第7章で紹介されているHaskell(ハスケル)です。 

Haskell
http://www.haskell.org/haskellwiki/Haskell

1.Haskellについて

 Haskellは純粋関数型プログラミング言語です。「すごいH本」が出てWeb上で話題になったり、「関数型言語を学ぶならHaskellですよ!」と同僚に勧められたりと公私ともに非常に熱い言語のようです。

 他の関数型言語がオブジェクト指向言語の要素を取り入れたりするなど、関数言語としては非純粋ではないため、「純粋」なHaskellは関数型言語を学ぶのに向いているということなのでしょうか。
 

2.Haskellのインストール

 以下を参考にしました。Homebrewでもインストール可能なようですが、バージョンがやや古くなるそうなので、The Haskell Platformからインストーラー(.pkg)をダウンロードしてインストールしました。私はすでにインストールしていたので特に問題ありませんでしたが、事前にXcodeをインストールしておく必要があるそうです。
Haskell環境構築:Mac OS X – Google グループ
The Haskell Platform
 

3.Hello,World

ターミナルで「ghci」と打つとHaskellのシェルが起動します。

$ ghci
GHCi, version 7.4.1: http://www.haskell.org/ghc/  😕 for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude>

終了は「:quit」。

Prelude> :quit
Leaving GHCi.

 
 
 ではではということで、数値や文字列を入力してみます。

Prelude> 1+1
2
Prelude> "Hello, World"
"Hello, World"
Prelude> "1"+"1"

<interactive>:4:4:
    No instance for (Num [Char])
      arising from a use of `+'
    Possible fix: add an instance declaration for (Num [Char])
    In the expression: "1" + "1"
    In an equation for `it': it = "1" + "1"
Prelude> "1" ++ "1"
"11"

  
 可変長なデータセットであるリスト

Prelude> [1,2]
[1,2]
Prelude> ["a","b"]
["a","b"]
Prelude> ['H','e','l','l','o',',','W','o','r','l','d']
"Hello,World"
Prelude> "Hello,World" ==  ['H','e','l','l','o',',','W','o','r','l','d']
True

 リスト内でシングルクォーテーションで囲うと一つの文字列として返されます。つまり、文字列も単なる文字のリストということらしいです。

 固定長なデータセットであるタプル

Prelude> (1,2,3)
(1,2,3)
Prelude> ("a","b","c")
("a","b","c")

 

4. 変数

 
 変数の定義。変数は変更可能らしい。

Prelude> let x = 1
Prelude> x
1
Prelude> let x = 2
Prelude> x
2

 

5. 外部ファイルとしてのプログラム作成とコンパイル、ロード

 
 モジュールdouble.hsのコンパイルとロード。

Prelude> :load double.hs
[1 of 1] Compiling Main             ( double.hs, interpreted )
Ok, modules loaded: Main.

 上でコンパイルしたファイルの実行。

*Main> double 5
10

 

6. 関数

6.1. 関数の定義

 add という関数を定義してみる。

Prelude> let add n= 1 + n
Prelude> add 2
3
 

 外部ファイルとして作成し、プログラムをコンパイルして上のプログラムを実行してみます。

add n = n + 1

 上を”add.hs”というファイル名で保存し、コンパイルして読み込む。

Prelude>:load add.hs
[1 of 1] Compiling Main             ( add.hs, interpreted )
Ok, modules loaded: Main.
*Main> add 1
2

 

6.2. 再帰

 階乗を求める。

Prelude> let fac x = if x == 0 then 1 else fac (x -1)*x
Prelude> fac 1
1
Prelude> fac 5
120
Prelude> fac 100
93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000

 

6.3. カリー化

 Haskellでは、「全ての関数は常に1つの引数をとる」のだそうです。つまり、1つの関数で2つ以上の引数をとることができないということです。「2つ以上の引数を使う関数を使いたい場合はどうするの?」という疑問が当然生じてきます。2つの引数をとる関数は引数を1つずつ順番に受け取りながら処理をしていくのだそうです。

 例えば、こんな感じで引数を2つとる関数testを定義しています。

Prelude> let test  a b = a + b * 2
Prelude> test 2 4
10

 一見、上のtest関数は2つの引数をとるように見えますが、実はこの場合、

(test 2) 4

 と実行していることになるのだそうです。つまり、まず最初に引数2をとり、

test 2 

 を実行しますので、引数2が a に代入されて

2 + b*2

 となり、続けてbに引数4が代入されて

2 + 4*2

となり、10という結果が返ってきます。

 だらだらと書いてしまいたが、引数を一つずつ処理していくプロセスがカリー化と呼ばれるのだとか。
 

 

7.型クラス(type class)

 Haskellは型推論を行ってくれるので、特に型を定義をする必要はありません。しかし、プログラマがきちんと型付けしたい場合もあります。そんなときは

Prelude> 1 :: Int
1

“:t”で上で定義した「型」を確認することもでき・・・・・

Prelude> :t 1
1 :: Num a => a

 Intと型を定義したのにNumが返ってきます。以下によるとNumは型クラス(type class)で、Intは(インスタンス)なのだそうです。“:t”では上で「型」と書いてしまいましたが、型クラスを返すみたいですね。

10分で学ぶHaskell – HaskellWiki
オブジェクト指向から理解する型クラス – think and error
 
 次は文字列です。
 
 文字列の場合は、StringというCharというがあるようです。ちなみに以下によるとChar型とString型はPreludeモジュールで定義されたRead、Show、Eq、 Ord、Enum および Boundedという型クラスの型(インスタンス)のようです。
The Haskell 98 Report: 定義ずみの型とクラス
Prelude Standard types, classes and related functions

  Charは文字、Stringは文字列を示す型なのだそうで、ダブルクォーテーションで囲ってしまうと文字列になってしまうらしく、Charという型では定義できません。シングルクォーテーションで囲った1文字の文字であればCharで定義できます。

Prelude> "a" :: String
"a"
Prelude> :t "a"
"a" :: [Char]
Prelude> 'b'::Char
'b'
Prelude> :t 'b'
'b' :: Char
Prelude> "b"::Char

<interactive>:21:1:
    Couldn't match expected type `Char' with actual type `[Char]'
    In the expression: "b" :: Char
    In an equation for `it': it = "b" :: Char
Prelude> 'abc'::Char

<interactive>:20:1:
    Syntax error on 'abc'
    Perhaps you intended to use -XTemplateHaskell

 しかし、文字列”a”は「3.Hello,World」で少し触れたように[‘a’]というリストでもあるわけですので、リストの要素として扱えばCharになるんでしょうか、たぶん。

  Haskellが組み込みの型クラスと型はPreludeモジュールで定義されているようです。その型クラスと型は上で一度紹介しましたが、以下で一覧されています。
Prelude Standard types, classes and related functions

 Slideshareでは型クラスと型についてわかりやすく紹介している発表資料がいくつもありましたので、そのうち2つを掲載します(一つは上で紹介したものですが)。