Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ReScript_hokkaido_js

神崎
March 01, 2025
19

 ReScript_hokkaido_js

hokkaido.jsのTLで説明したReScriptについての概要説明

神崎

March 01, 2025
Tweet

Transcript

  1. •㈱バリューソース •神崎 善司 •twitter:@zenzengood •RDRA:https://www.rdra.jp/ •著作 •モデルベース要件定義テクニック •RDRA2.0ハンドブック •開発したツール(ReScript) •LLMで要件定義を行う:RDRAZeroOne

    •要件定義支援 :RDRAGraph •仕事 •RDRA導入支援 •要件定義支援 •既存システムの可視化支援 •好きな事 •システムの可視化 •モデリング •表形式でのモデリング LLMの活用したプログラミング RDRAZeroOne RDRAGraph
  2. ReScript 基本的な特徴 • Ocaml由来の関数型言語 ◦ 基本的にimmutable(不変)だがmutableも可能 ◦ 高階関数、カリー化など基本的な関数型言語の特徴を備える ◦ React用のライブラリもある

    • 構文 ◦ JavaScriptに比べて構文が簡潔 ◦ 強力な構文 ⇒ Variant/record/Pattern Matching ◦ 使いやすいライブラリ(JSとほぼ同じように使える) ◦ 抽象プログラミング可能:Module Functor • トランスパイル ◦ 型の整合性を厳密にチェック:option型によるnull安全性 ◦ トランスパイルが非常に高速 ◦ 効率的な実行 ▪ JSの処理に変換(ReScript用のライブラリ不使用) ▪ 出力されるJSもReadableで効率的なJSに変換
  3. 基本構文 JavaScript ReScript no types type point = {x: int,

    mutable y: int} {x: 30, y: 20} Same point.x Same point.y = 30; Same {...point, x: 30} Same Object/Record JavaScript ReScript [1, 2, 3] Same myArray[1] = 10 Same [1, "Bob", true] (1, "Bob", true) Array 型があるのでタプル JavaScript ReScript for (let i = 0; i <= 10; i++) {...} for i in 0 to 10 {...} for (let i = 10; i >= 0; i--) {...} for i in 10 downto 0 {...} while (true) {...} while true {...} Loop JavaScript ReScript if (a) {b} else {c} if a {b} else {c} * a ? b : c Same switch pattern matching! If-else 式なので返される型は 同じでないといけない 基本的な構文はJSとほぼ同じ
  4. Variant type myResponse = | Yes | No | PrettyMuch

    let areYouCrushingIt = Yes type account = | None | Instagram(string) | Facebook(string, int) let myAccount = Facebook("Josh", 26) let friendAccount = Instagram("Jenny") type user = | Number(int) | Id({name: string, password: string}) let me = Id({name: "Joe", password: "123"}) 複雑な構造を簡潔に記述
  5. Pattern Matching let message = switch person1 { | Teacher({name:

    "Mary" | "Joe"}) => `Hey, still ~?` | Teacher({name}) => `Hello ${name}.` | Student({name, reportCard: {passing: true, gpa}}) => `${name}, ${Float.toString(gpa)}~` | Student({ reportCard: {gpa: 0.0}, status: Vacations(daysLeft) | Sabbatical(daysLeft)}) => `~${Int.toString(daysLeft)} ~` | Student({status: Sick}) => `How are you feeling?` | Student({name}) => `Good luck next semester ${name}!` } let students = ["Jane", "Harvey", "Patrick"] switch students { | [] => Console.log("There are no students") | [student1] => Console.log("There's ~: " ++ student1) | manyStudents =>Console.log2("The students ~: ", manyStudents) } 複雑なパターン Arrayのパターン 0件 1件 多数
  6. トランスパイル open Array let funA = () => [1, 2,

    3] let b = funA() -> map(x => x * 2) let c = b -> filter(x => x < 2) function funA() { return [1, 2,3]; } var b = [1,2,3].map(function (x) { return (x << 1); }); var c = b.filter(function (x) { return x < 2; }); ReScript Javascript type account = | None | Instagram(string) | Facebook(string, int) let myAccount = Facebook("Josh", 26) let friendAccount = Instagram("Jenny") ReScript Javascript var myAccount = { TAG: "Facebook", _0: "Josh", _1: 26 }; var friendAccount = { TAG: "Instagram", _0: "Jenny" }; JSのArray処理 関数定義 JSの関数 タグ付けされた オブジェクト
  7. トランスパイル1 var categoryId = 2; var isBig = true; var

    myAnimal = "Cat"; type animal = Dog | Cat | Bird let isBig = true let myAnimal = Cat let categoryId = switch (isBig, myAnimal) { | (true, Dog) => 1 | (true, Cat) => 2 | (true, Bird) => 3 | (false, Dog | Cat) => 4 | (false, Bird) => 5 } ReScript Javascript トランスパイル 時に最適化
  8. トランスパイル2 ReScript Javascript function categoryId2(isBig, myAnimal) { if (isBig) {

    switch (myAnimal) { case "Dog" : return 1; case "Cat" : return 2; case "Bird" : return 3; } } else { switch (myAnimal) { case "Dog" : case "Cat" : return 4; case "Bird" : return 5; } } } let categoryId2 = (isBig, myAnimal) => switch (isBig, myAnimal) { | (true, Dog) => 1 | (true, Cat) => 2 | (true, Bird) => 3 | (false, Dog | Cat) => 4 | (false, Bird) => 5 } 関数化 JSの関数に変換
  9. Javascriptとの連携 @send external cyNodeField : (cyNodesT,string) => string = "data"

    @send external cyEdgeField : (cyEdgesT,string) => string = "data" ele.data( name ) Get a particular data field for the element. name The name of the field to get. let msg1 = %raw(" (a) => a.content ") let msg2:string => string = %raw(“ (a) => a ++ “AA” ") ReScript Cytoscape Node(アイコン)とEdge(線)で タイプが異なるので2つ定義 CytoscapeのAPI JSの関数をそのまま記述 引数の型も帰り値の型も不定 型を記述 JSの処理を生で記述