mirror of
https://github.com/carp-lang/Carp.git
synced 2024-09-11 05:25:28 +03:00
* feat: add box templates and box type
This commit adds an implementation of Boxes, memory manged heap
allocated values.
Boxes are implemented as C pointers, with no additional structure but
are treated as structs in Carp. To facilitate this, we need to add them
as a clause to our special type emissions (TypesToC) as they'd otherwise
be emitted like other struct types.
Co-authored-by: Veit Heller <veit@veitheller.de>
* fix: slight memory management fix for Box
Make sure we free the box!
* test: add tests for box (including memory checks)
* Revert "fix: Ignore clang nitpick"
This reverts commit 70ec6d46d4
.
* fix: update example/functor.carp
Now that a builtin type named Box exists, the definitions in this file
cause a conflict. I've renamed the "Box" type in the functor example to
remove the conflict.
* feat: add Box.peek
Box.peek allows users to transform a reference to a box into a a
reference to the box's contained value. The returned reference will have
the same lifetime as the box. This function allows callers to manipulate
the value in a box without re-allocation, for example:
```clojure
(deftype Num [val Int])
(let-do [box (Box.init (Num.init 0))]
(Num.set-val! (Box.peek &box) 1)
@(Num.val (Box.peek &box)))
```
This commit also includes tests for Box.peek.
Co-authored-by: TimDeve <TimDeve@users.noreply.github.com>
Co-authored-by: Veit Heller <veit@veitheller.de>
Co-authored-by: Erik Svedäng <erik@coherence.io>
Co-authored-by: TimDeve <TimDeve@users.noreply.github.com>
41 lines
1.3 KiB
Plaintext
41 lines
1.3 KiB
Plaintext
(use IO)
|
|
(use Int)
|
|
(use Array)
|
|
(Project.no-echo)
|
|
|
|
(definterface fmap (λ [(Ref (λ [a] b)) (f a)] (f b)))
|
|
|
|
(defmodule ArrayExtension
|
|
(defn fmap [f a] (Array.endo-map f a))
|
|
(implements fmap ArrayExtension.fmap)
|
|
)
|
|
|
|
(deftype (MyBox a) [x a])
|
|
|
|
(defmodule MyBox
|
|
(defn fmap [f box] (let [new-x (~f @(MyBox.x &box))]
|
|
(MyBox.set-x box new-x)))
|
|
(implements fmap MyBox.fmap))
|
|
|
|
(use MyBox)
|
|
(use ArrayExtension)
|
|
|
|
;; TODO: This function currently concretizes to the type of the first (f *) it
|
|
;; receives. Is there a way for us to ensure it remains generic?
|
|
;; N.B. the only reason it worked previously was because it was ill-typed as
|
|
;; (a -> a) which erroneously served as a universal type.
|
|
;(sig higherOrder (Fn [(f a)] (f b)))
|
|
;(defn higherOrder [x] (fmap &Int.inc x))
|
|
|
|
(defn main []
|
|
(do
|
|
(println &(str @(MyBox.x &(fmap &Int.inc (MyBox.init 100)))))
|
|
(println &(str @(MyBox.x &(MyBox.fmap &inc (MyBox.init 100)))))
|
|
(println &(str &(ArrayExtension.fmap &inc [10 20 30 40 50])))
|
|
(println &(str &(fmap &Int.inc [10 20 30 40 50])))
|
|
(println &(Array.str &(fmap &Int.inc [10 20 30 40 50])))
|
|
(println &(Array.str &(ArrayExtension.fmap &Int.inc [10 20 30 40 50])))
|
|
;(println &(str &(higherOrder (Box.init 999))))
|
|
;(println &(str &(higherOrder [9 99 999 9999])))
|
|
))
|