Topics

・関数型プログラミングとオブジェクト指向のパラダイムとしての対立 国内の【自称】関数型コミュニティと海外の論調の違い

ガラパゴス・ネットスラング=「関数型ポエム」という呪詛、先入観的読書と、フェアなレビューの登場

Qiitaの騒動から派生して、東北大学の住井 英二郎@esumii氏、らくだの卯之助@camloeba氏その他が、犯罪者集団に合流して2ちゃんねるでの誹謗中傷チームの「8賢者」「ウィザード組」とかアホなことをやってる件について

JavaScriptではES6+とReact-JSXからES5へのトランスパイルが標準に / ATOMエディタで最速環境構築 厳選パッケージ 3 + 3 2015年夏バージョン

2016年のnode、ES6、React、Babel、Atomエディタ界隈の方向性

Dockerじゃないsystemd-nspawn+machinectlが非常に良い

99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その1】「計算機科学のほんとうの基礎」を理解していない。IQ145のJKと同じ事を語るMITの権威とSICPという聖典の権威を借りてマインドコントロールを解いてみよう

99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その2】関数型プログラミングのイミュータブルな世界観とイミュータブルな実世界を完全に統合

10年先を行く斬新な関数型(FRP)データベースについて説明する 99%のプログラマがIQ145のJKに「ダサい」と言われてしまう理由とは?【その3】

[React (.js Facebook)解説 関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間 サポート記事【静的HTML編】React 解説【動的HTML-FRP編】

量子コンピュータが超高速である原理と量子論とそれに至るまでの科学哲学史をゼロからわかりやすく解説01量子コンピュータが超高速である原理と量子論とそれに至るまでの科学哲学史をゼロからわかりやすく解説02

『関数型プログラミングに目覚めた!』のレビュー(Day-1)について

LISPデータ構造の問題点の指摘と抜本的解法としての新プログラミング言語の策定/純粋関数型言語「SPINOZA」

著書『関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間』 [Day1]たち読み記事 無料公開中

『関数型プログラミングに目覚めた! IQ145の女子高生の先輩から受けた特訓5日間』を大変多くの方々にお買い求めいただき、感謝します。本書の全目次を公開し、質問を受け付けます。

2015年7月31日金曜日

JavaScriptで時間発展する物理系=私達が生活するこの宇宙の挙動を、関数型プログラミングでイミュータブルに記述する、という関数型リアクティブプログラミング(FRP)の概念実証

時間発展する物理系、つまり、私達が生活するこの宇宙の挙動を、関数型プログラミングでイミュータブルに記述する、という関数型リアクティブプログラミング(FRP)の概念実証をJavaScript言語でしてみましょう。

我々の馴染みの深い「放物線」を例に取ります。
「放物線を描く」と日常的によく使いますが、物理学(日本語)では正確には、「斜方投射」と言います。

斜方投射(しゃほうとうしゃ)とは物体をある初速度をもって空中に投げ出す動作である。空気抵抗が十分小さく無視できる場合、斜方投射された物体の軌跡は放物線を描く

enter image description here

水平方向にx軸、
鉛直上向きにy軸をとります。

初速 
偏角 
のとき、
斜方投射してからの経過時間   における
物体の速度および座標

という恒等式で表せます。(は 重力加速度=9.8 m/ss)

これがニュートン物理学の時間発展する恒等式です。

. タイガー・ウッズの平均ヘッドスピード57.5m/s ボール初速度85.0~86.5m/sと公表されています。

らしいですから、
初速を85.0m/s、偏角30度とし、空気抵抗を無視したゴルフのスーパーショットっぽい斜方投射を上記時間発展する恒等式をそのまま用いて、
worldtimestream
Reactを利用して関数型リアクティブプログラミングのコードを書くと以下のようになります。

code

恒等式の宣言

worldtimestreamで、物理系の時間tをコードに恒常的にマップするworldengineとして宣言しておきます。

___.world = ___((t) => { // world engine

//===========================================================================

});

その中で、恒等式の初期設定が宣言され、

  var V0 = 85.0; // m/s
  var deg = 30; //degree
  var THETA = deg / 180 * Math.PI; //radian
  var G = 9.8; //gravity const

恒等式そのものがtの時間関数coordinateEquationで宣言されています。

  var coordinateEquation = (t) => {
    var x = V0 * Math.cos(THETA) * t;
    var y = V0 * Math.sin(THETA) * t - G * Math.pow(t, 2);
    return {
      x: x,
      y: y
    };
  };

これで、すべての関係性は記述されていますが、この時間発展する時間関数の恒等式を実際の画面表示をするための「計算」は一切なされていません。

つまり、ここまでは、物理系と物理量コードのストリームとの関係性が100%抽象世界として宣言されただけで、コンピュータのハードウェアでその関係性の具現化、つまりふたたび、そのストリームが具体的な物理系としての画面に反映する「計算」タイミングなどの指示は行われていません。

計算からの画面描写(画面描写も関係式の計算に他ならない)

この「計算」部分を一手に司るのが、ReactコンポーネントReactComponentです。

componentWillMount()において、

        var init = () => {
          var T0 = t();
          var f = () => {
            ___.world = ___coordinate.appear(coordinateEquation((t() - T0) / 1000));
          };
          ___.world = t.computeInterval(f, 10); //calculate 10milsec resolution 
        };
        ___.world = t.computeTimeout(init, 0);

で、___coordinateというストリームを、10ミリセカンドの解像度をもってtの時間関数coordinateEquationで「計算」することを宣言します。

___x={___()} ___y={___()}というReactが描写するコンポーネントのXY座標に相当する、worldtimestreamのストリームとして定義されたプロパティは、___coordinateが「計算」されると、適切な画面座標に投影しながら

        var com = this;
        ___.world = ___coordinate.compute((coordinate) => {
          ___.world = com.props.___x.appear(50 + coordinate.x * Drawscale);
          ___.world = com.props.___y.appear(300 - coordinate.y * Drawscale);
          com.forceUpdate();
        });

コンポーネントを再描画します。

このように、FRPライブラリworldtimestreamとReactを利用することで、簡潔に、
時間発展する物理系、つまり、私達が生活するこの宇宙の挙動を、関数型プログラミングでイミュータブルに記述する、という関数型リアクティブプログラミング(FRP)を実現可能です。

___.world = ___((t) => { // world engine 
  //=========================================================================== 
  //MKS system of units 

  var ___coordinate = ___();

  var V0 = 85.0; // m/s 
  var deg = 30; //degree 
  var THETA = deg / 180 * Math.PI; //radian 
  var G = 9.8; //gravity const 

  var coordinateEquation = (t) => {
    var x = V0 * Math.cos(THETA) * t;
    var y = V0 * Math.sin(THETA) * t - G * Math.pow(t, 2);
    return {
      x: x,
      y: y
    };
  };

  //============================================================== 
  var Drawscale = 4; //4 dot = 1 meter 

  var ReactComponent = React.createClass(
    {
      componentWillMount() {
        var com = this;
        ___.world = ___coordinate.compute((coordinate) => {
          ___.world = com.props.___x.appear(50 + coordinate.x * Drawscale);
          ___.world = com.props.___y.appear(300 - coordinate.y * Drawscale);
          com.forceUpdate();
        });

        var init = () => {
          var T0 = t();
          var f = () => {
            ___.world = ___coordinate.appear(coordinateEquation((t() - T0) / 1000));
          };
          ___.world = t.computeInterval(f, 10); //calculate 10milsec resolution 
        };
        ___.world = t.computeTimeout(init, 0);
      },
      render() {
        var com = this;

        var el = (
        <div>
          <h1>For new shot, Just Reload the browser page</h1>
          <svg height = "100%"  width = "100%">
              <circle r="5" fill="blue"
        cx = {this.props.___x.t()}
        cy = {this.props.___y.t()}/>
          </svg>
        </div>
        );
        return el;
      }
    });

  var mount = React.render(<ReactComponent ___x={___()} ___y={___()} />, document.body);
//============================================================== 
//=========================================================================== 
});


Live Demo

http://sakurafunctional.github.io/demo/react-physics/

0 コメント:

コメントを投稿

Popular Posts

Blog Archive