aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/lux/control/thread.lux
blob: 52c0062ebc8a55b3871ea0f7a507fa6ed4a0e6f5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
(.module:
  [lux #*
   ["@" target]
   [abstract
    [functor (#+ Functor)]
    [apply (#+ Apply)]
    [monad (#+ Monad do)]]
   [control
    ["." io (#+ IO)]]
   [data
    [collection
     ["." array (#+ Array)]]]
   [type
    abstract]])

(type: #export (Thread ! a)
  (-> ! a))

(abstract: #export (Box t v)
  (Array v)

  {#.doc "A mutable box holding a value."}

  (def: #export (box init)
    (All [a] (-> a (All [!] (Thread ! (Box ! a)))))
    (function (_ !)
      (|> (array.new 1)
          (array.write! 0 init)
          :abstraction)))

  (def: #export (read box)
    (All [! a] (-> (Box ! a) (Thread ! a)))
    (function (_ !)
      (for {@.old
            ("jvm aaload" (:representation box) 0)

            @.jvm
            ("jvm array read object"
             (|> 0
                 (:coerce (primitive "java.lang.Long"))
                 "jvm object cast"
                 "jvm conversion long-to-int")
             (:representation box))

            @.js ("js array read" 0 (:representation box))
            @.python ("python array read" 0 (:representation box))
            @.lua ("lua array read" 0 (:representation box))
            @.ruby ("ruby array read" 0 (:representation box))
            @.php ("php array read" 0 (:representation box))})))

  (def: #export (write value box)
    (All [a] (-> a (All [!] (-> (Box ! a) (Thread ! Any)))))
    (function (_ !)
      (|> box :representation (array.write! 0 value) :abstraction)))
  )

(def: #export (run thread)
  (All [a]
    (-> (All [!] (Thread ! a))
        a))
  (thread []))

(def: #export io
  (All [a]
    (-> (All [!] (Thread ! a))
        (IO a)))
  (|>> ..run io.io))

(structure: #export functor
  (All [!] (Functor (Thread !)))

  (def: (map f)
    (function (_ fa)
      (function (_ !)
        (f (fa !))))))

(structure: #export apply
  (All [!] (Apply (Thread !)))

  (def: &functor ..functor)

  (def: (apply ff fa)
    (function (_ !)
      ((ff !) (fa !)))))

(structure: #export monad
  (All [!] (Monad (Thread !)))

  (def: &functor ..functor)

  (def: (wrap value)
    (function (_ !)
      value))

  (def: (join ffa)
    (function (_ !)
      ((ffa !) !))))

(def: #export (update f box)
  (All [a] (-> (-> a a) (All [!] (-> (Box ! a) (Thread ! a)))))
  (do ..monad
    [old (read box)
     _ (write (f old) box)]
    (wrap old)))