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年8月20日木曜日

timeengine / Time Engine FRP ( Functional Reactive Programming / 関数型リアクティブ プログラミング) npmライブラリの公開

timeengine / Time Engine FRP ( Functional Reactive Programming / 関数型リアクティブ プログラミング) npmライブラリの公開
worldcomponent
worldtimestream
のコンセプトを継承したライブラリです。
https://github.com/kenokabe/timeengine
https://www.npmjs.com/package/timeengine

timeengine

Time Engine is the True Functional Reactive Programming (FRP) Library from the Point of View of Physics, our World and Time
NPM version DownloadsDependency statusDev Dependency statusnpm
NPM

The World, Time, Physics, Mathematics, Equations, and Functional Reactive Programming

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度とし、空気抵抗を無視したゴルフのスーパーショットっぽい斜方投射を上記時間発展する恒等式をそのまま用いて、
timeengine
Reactを利用して関数型リアクティブプログラミングのコードを書くと以下のようになります。

//MKS system of units
var V0 = 85.0; // m/s
var DEG = 30; //degree
var THETA = DEG / 180 * Math.PI; //radian
var G = 9.8; //gravity const

//10msec time resolution
//t seconds elapsed since t0
var t = __.intervalSeq(10).tMap((tt, t0) => (tt - t0) / 1000);

var x = t.tMap((t) => V0 * Math.cos(THETA) * t);

var y = t.tMap((t) => V0 * Math.sin(THETA) * t - 1/2 * G * Math.pow(t, 2));
The full code is represented at the bottom of this document.

Live Demo

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

Basic

The only API you get to know is tMap.
tMap maps a time-sequence to another time-sequence.
Time Engine is all about tMap.

Reactive Programming in JavaScript

var x = __(); // time sequence
var y = x.tMap((x) => x * 2); // y = x * 2

x.t = 3;
console.log(x.t); //3
console.log(y.t); //6

x.t = 5;
console.log(x.t); //5
console.log(y.t); //10

Declarative code like Math equation and Single (no duplicate) update by automatic dependency resolution

var a = __();
var b = __([a]).tMap(([a]) => a * 2); // b.t = 1 * 2 = 2
var c = __([a, b]).tMap(([a, b]) => a + b * 3); // c.t = 1 + 2 * 3 = 7
var d = __([b]).tMap(([b]) => b * 100); // d.t = 2 * 100 = 200
var e = __([a, b, c, d]).tMap(([a, b, c, d]) => a + b + c + d); //210

a.t = 1; // a is updated, and the whole equations will be evaluated.

Atomic update using Promise

var atomic = __([a, b, c, d, e])
  .tMap(([a, b, c, d, e]) => ({
      a,
      b,
      c,
      d,
      e
  }));

var timeseq10 = atomic.tMap((val) => {
  __.t = __.log('atomic', val);
});

Promise

var m = __();
var n = __();
var o = __();
var p = __([m, n, o]).tMap(() => 'Promised');

var timeseq15 = __.timeoutSeq(6000)
  .tMap(() => m.t = 'some');
var timeseq16 = __.timeoutSeq(7000)
  .tMap(() => n.t = 'time');
var timeseq17 = __.timeoutSeq(8000)
  .tMap(() => o.t = 'other');

var timeseq18 = __.timeoutSeq(10000)
  .tMap(() => m.t = 'some');
var timeseq19 = __.timeoutSeq(11000)
  .tMap(() => n.t = 'time');
var timeseq20 = __.timeoutSeq(12000)
  .tMap(() => o.t = 'other');

var timeseq21 = m.tMap((m) => {
  __.t = __.log({
    m
  });
});

var timeseq22 = n.tMap((n) => {
  __.t = __.log({
    n
  });
});

var timeseq23 = o.tMap((o) => {
  __.t = __.log({
    o
  });
});

var timeseq24 = p.tMap((p) => {
  __.t = __.log({
    p
  });
});

Install

node / io.js

$ npm install timeengine

WebBrowser

ES5 native

include
https://github.com/kenokabe/timeengine/blob/master/timeengine.js
then
<script type="text/javascript" src="./timeengine.js"></script>

ES6 with Babel transpiler

https://babeljs.io/
include
https://github.com/kenokabe/timeengine/blob/master/babel-browser.js
https://github.com/kenokabe/timeengine/blob/master/timeengine.jsx
then
<script src="./babel-browser.js"></script>
<script type="text/babel" src="./timeengine.jsx"></script>

Test

$ npm test
equivalent to
$ babel timeengine.jsx -o timeengine.js; babel-node test.jsx

test.jsx

(() => {
  'use strict';

  var __ = require('./timeengine.js');

  __.t = __.log('test.jsx started...');

  //Reactive and Declarative code ===============
  var x = __(); // time sequence
  var y = x.tMap((x) => x * 2); // y = x * 2
  x.t = 3;
  console.log(x.t); //3
  console.log(y.t); //6

  x.t = 5;
  console.log(x.t); //5
  console.log(y.t); //10

  /*
    //comment out, dependency Error occures here
    //since y depends on x, this is an illegal operation

    y.t = 100;
    console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' + x.t);
    console.log('>>>>>>>>>>>>>>>>>>>>>>>>>>>>>' + y.t);
  */

  //store values on timeStamps ==============

  var i = __(true); //store flag = true
  var j = __([i], true).tMap(() => i.t * 2); // j = i * 2

  i.t = 3;
  console.log(j.t); //6

  i.t = 5;
  console.log(j.t); //10

  // seq can be operated just like vanilla JavaScript Array
  __.t = __.log('i.length', i.length);

  i.map((val) => {
    __.t = __.log('i.t', val); // 3, 5
  });

  j.map((val) => {
    __.t = __.log('j.t', val); //6, 10
  });

  var timestamp_i0 = i.TimestampOnIndex(0);
  var timestamp_i1 = i.TimestampOnIndex(1);
  var timestamp_j0 = j.TimestampOnIndex(0);
  var timestamp_j1 = j.TimestampOnIndex(1);

  __.t = __.log(i.T(timestamp_i0)); //3
  __.t = __.log(i.T(timestamp_i1)); //5
  __.t = __.log(j.T(timestamp_j0)); //6
  __.t = __.log(j.T(timestamp_j1)); //10


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

  //------------------------
  var timeseq0 = __
    .timeoutSeq(500, true) // store === true
    .tMap((t) => {
      __.t = __.log('--------------------------------------------');
      return t;
    });

  var timeseq1 = timeseq0.tMap((t) => {
    __.t = __.log('timeseq0.t', t);
    __.t = __.log('stored to arrray', timeseq0[0]); // same val
  //stored to the seq array
  });

  var f = (tt, t0) => {
    __.t = __.log('t0', t0);
    __.t = __.log('tt', tt);
  };
  var timeseq2 = __.timeoutSeq(1000).tMap(f);
  var timeseq3 = __.timeoutSeq(2000).tMap(f);

  //------------------------

  var timeseq4 = __.timeoutSeq(2500)
    .tMap(__.log('-------------------------------------------'));

  // Single (no duplicate) update by dependency analysis
  var a = __();
  var b = __([a]).tMap(([a]) => a * 2); // b.t = 1 * 2 = 2
  var c = __([a, b]).tMap(([a, b]) => a + b * 3); // c.t = 1 + 2 * 3 = 7
  var d = __([b]).tMap(([b]) => b * 100); // d.t = 2 * 100 = 200
  var e = __([a, b, c, d]).tMap(([a, b, c, d]) => a + b + c + d); //210

  var timeseq5 = a.tMap((a) => {
    __.t = __.log({
      a
    });
  });

  var timeseq6 = b.tMap((b) => {
    __.t = __.log({
      b
    });
  });

  var timeseq7 = c.tMap((c) => {
    __.t = __.log({
      c
    });
  });

  var timeseq8 = d.tMap((d) => {
    __.t = __.log({
      d
    });
  });

  var timeseq9 = e.tMap((e) => {
    __.t = __.log({
      e
    });
  });

  // Atomic update using build-in Promise mechanism

  var atomic = __([a, b, c, d, e])
    .tMap(([a, b, c, d, e]) => ({
        a,
        b,
        c,
        d,
        e
    }));

  var timeseq10 = atomic.tMap((val) => {
    __.t = __.log('atomic', val);
  });

  var timeseq11 = __.timeoutSeq(3000)
    .tMap(() => a.t = 1);

  var timeseq12 = __.timeoutSeq(3500)
    .tMap(__.log('--------------------------------------------'));


  var timeseq13 = __.timeoutSeq(4500)
    .tMap(() => a.t = 5);

  //---------------------------------------------
  var timeseq14 = __.timeoutSeq(5000)
    .tMap(__.log('--------------------------------------------'));


  //Promise---------------------------------------------

  var m = __();
  var n = __();
  var o = __();
  var p = __([m, n, o]).tMap(() => 'Promised');

  var timeseq15 = __.timeoutSeq(6000)
    .tMap(() => m.t = 'some');
  var timeseq16 = __.timeoutSeq(7000)
    .tMap(() => n.t = 'time');
  var timeseq17 = __.timeoutSeq(8000)
    .tMap(() => o.t = 'other');

  var timeseq18 = __.timeoutSeq(10000)
    .tMap(() => m.t = 'some');
  var timeseq19 = __.timeoutSeq(11000)
    .tMap(() => n.t = 'time');
  var timeseq20 = __.timeoutSeq(12000)
    .tMap(() => o.t = 'other');

  var timeseq21 = m.tMap((m) => {
    __.t = __.log({
      m
    });
  });

  var timeseq22 = n.tMap((n) => {
    __.t = __.log({
      n
    });
  });

  var timeseq23 = o.tMap((o) => {
    __.t = __.log({
      o
    });
  });

  var timeseq24 = p.tMap((p) => {
    __.t = __.log({
      p
    });
  });

  var timeseq25 = __.timeoutSeq(13000)
    .tMap(__.log('--------------------------------------------'));

  var f99 = () => {
    __.t = __.log('Any Event Function can be wrapped.');
  };
  __.t = __.wrap(setTimeout)(f99, 14000);
  //onMousemove or whatever instead of setTimeout

  ///-----------------------------------------------

  var timeseq26 = __.timeoutSeq(15000)
    .tMap(() => {
      __.t = __.log('--------------------------------------------');

      var timeseq27 = __
        .intervalSeq(1000)
        .tMap((tt, t0) => (tt - t0) / 1000)
        .tMap((tt) => {
          __.t = __.log(tt);
          return tt;
        });

    });

})();

result

> babel timeengine.jsx -o timeengine.js; babel-node test.jsx

test.jsx started...
3
6
5
10
6
10
i.length 2
i.t 3
i.t 5
j.t 6
j.t 10
3
5
6
10
--------------------------------------------
timeseq0.t 1440134670777
stored to arrray 1440134670777
t0 1440134670277
tt 1440134671278
t0 1440134670277
tt 1440134672277
-------------------------------------------
{ c: 7 }
{ e: 210 }
atomic { a: 1, b: 2, c: 7, d: 200, e: 210 }
{ d: 200 }
{ b: 2 }
{ a: 1 }
--------------------------------------------
{ c: 35 }
{ e: 1050 }
atomic { a: 5, b: 10, c: 35, d: 1000, e: 1050 }
{ d: 1000 }
{ b: 10 }
{ a: 5 }
--------------------------------------------
{ m: 'some' }
{ n: 'time' }
{ p: 'Promised' }
{ o: 'other' }
{ m: 'some' }
{ n: 'time' }
{ p: 'Promised' }
{ o: 'other' }
--------------------------------------------
Any Event Function can be wrapped.
--------------------------------------------
1.002
2.004
3.006
4.007
5.008

React Physics Test

enter image description here


index.jsx

/*global React __ */

(() => {
  'use strict';
  //MKS system of units
  var V0 = 85.0; // m/s
  var DEG = 30; //degree
  var THETA = DEG / 180 * Math.PI; //radian
  var G = 9.8; //gravity const

  //10msec time resolution
  //t seconds elapsed since t0
  var t = __.intervalSeq(10).tMap((tt, t0) => (tt - t0) / 1000);

  var x = t.tMap((t) => V0 * Math.cos(THETA) * t);

  var y = t.tMap((t) => V0 * Math.sin(THETA) * t - 1/2 * G * Math.pow(t, 2));

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

  class ReactComponent extends React.Component {

    constructor() {
      super();
      var timeseq = __([x, y])
        .tMap(([x, y]) => [50 + x * Drawscale, 300 - y * Drawscale])
        .tMap(([x, y]) => {
          this.rx = x;
          this.ry = y;
          this.forceUpdate();
        });
    }

    render() {
      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.rx}
      cy = {this.ry}/>
    </svg>
  </div>
      );
      return el;
    };
  }

  var mount = React.render(<ReactComponent/>, document.body);

})();

Live Demo

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

0 コメント:

コメントを投稿

Popular Posts