Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: stack-allocated lambdas #1368

Open
wants to merge 19 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
5b850bc
chore: wip, not actually working
eriksvedang Dec 27, 2021
89970ec
fix: add lambda ref to lifetime mappings
eriksvedang Dec 27, 2021
1d0f127
fix: actually keep the lambda envs on the stack
eriksvedang Dec 28, 2021
79caa06
chore: make a lot of tests run
eriksvedang Dec 29, 2021
68878d4
fix: don't pass double refs to lambdas
eriksvedang Dec 29, 2021
56c289b
fix: don't add ref in `Introspect.with-copy`
eriksvedang Dec 29, 2021
5d3a42a
fix: call lambdas correctly in memory tests
eriksvedang Dec 29, 2021
33f8094
test: temporarily disable letrec test
eriksvedang Dec 29, 2021
81679da
fix: make the Vector module use refs to functions instead
eriksvedang Dec 29, 2021
0ab3fe6
fix: copy lambda to make test run
eriksvedang Dec 30, 2021
3c61561
fix: temporarily disable nested_lambdas.carp test
eriksvedang Dec 30, 2021
1664bd0
fix: let-recursion works again (but the `c` command still fails on th…
eriksvedang Jan 1, 2022
be5f744
fix: make the nested_lambdas tests work again
eriksvedang Jan 1, 2022
c54f3af
fix: add constraint between function-lifetime and lambda-ref-lifetime
eriksvedang Jan 1, 2022
55c54e6
fix: modify expected output
eriksvedang Jan 1, 2022
47f8add
fix: newline at end of file
eriksvedang Jan 2, 2022
398dc01
fix: don't save recBody (with renamed recursive calls) in lambda
eriksvedang Jan 3, 2022
d04365b
chore: Merge branch 'master' into stack-allocated-lambdas
eriksvedang Jan 3, 2022
fd9598e
chore: Merge branch 'master' into stack-allocated-lambdas
eriksvedang Jan 3, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 6 additions & 6 deletions core/Array.carp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ As an example, consider this definition of `sum` based on `reduce`:

```
(defn sum [x]
(reduce &(fn [x y] (+ x @y)) 0 x))
(reduce (fn [x y] (+ x @y)) 0 x))
```

It will sum the previous sum with each new value, starting at `0`.")
Expand Down Expand Up @@ -188,7 +188,7 @@ If the array is empty, returns `Nothing`")

(doc sum "sums an array (elements must support `+` and `zero`).")
(defn sum [xs]
(Array.reduce &(fn [x y] (+ x @y)) (zero) xs))
(Array.reduce (fn [x y] (+ x @y)) (zero) xs))

(doc slice "gets a subarray from `start-index` to `end-index`.")
(defn slice [xs start-index end-index]
Expand Down Expand Up @@ -313,7 +313,7 @@ Example:
```
; if we didn’t have Array.range, we could define it like this:
(defn range [start end step]
(unreduce start &(fn [x] (< x (+ step end))) &(fn [x] (+ x step)))
(unreduce start (fn [x] (< x (+ step end))) &(fn [x] (+ x step)))
)
```")
(defn unreduce [start test step]
Expand Down Expand Up @@ -383,7 +383,7 @@ If the `index` is out of bounds, return `Maybe.Nothing`")

(doc remove "removes all occurrences of the element `el` in the array `arr`, in place.")
(defn remove [el arr]
(endo-filter &(fn [x] (not (= el x)))
(endo-filter (fn [x] (not (= el x)))
arr))

(doc remove-nth "removes element at index `idx` from the array `arr`.")
Expand Down Expand Up @@ -463,12 +463,12 @@ the second one is the element. `f` must return `(Pair accumulator result)`.

Example:
```
(map-reduce &(fn [acc x] (Pair.init (+ @x @acc) (* @x 2))) 0 &[1 2 3])
(map-reduce (fn [acc x] (Pair.init (+ @x @acc) (* @x 2))) 0 &[1 2 3])
; => (Pair 6 [2 4 6])
```")
(defn map-reduce [f acc a]
(reduce
&(fn [a el]
(fn [a el]
(let [l (Pair.b &a)
acc (Pair.a &a)
p (~f acc el)]
Expand Down
35 changes: 18 additions & 17 deletions core/Binary.carp
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,11 @@

If the conversion fails, returns a `Result.Error` containing the byte array passed as an argument.")
(defn byte-converter [f order]
(fn [bs]
@(fn [bs]
(match (~f order bs)
(Maybe.Nothing) (Result.Error @bs)
(Maybe.Just i) (Result.Success i))))

(doc interpreted
"Returns the interpreted value from a sequence of byte-converion results")
(private interpreted)
Expand All @@ -76,7 +77,7 @@
(ref)
(Array.copy-map &Array.length)
(ref)
(Array.reduce &(fn [x y] (+ x @y)) 0)))
(Array.reduce (fn [x y] (+ x @y)) 0)))

(doc system-endianness
"Returns the endianness of the host system.")
Expand Down Expand Up @@ -127,7 +128,7 @@
(defn unsafe-bytes->int16-seq [order bs]
(let [partitions (Array.partition bs 2)
f (fn [b] (unsafe-bytes->int16 order b))]
(Array.copy-map &f &partitions)))
(Array.copy-map f &partitions)))

(doc bytes->int16-seq
"Interprets a sequence of bytes as a sequence of Uint16 values.
Expand Down Expand Up @@ -156,7 +157,7 @@
(sig int16-seq->bytes (Fn [ByteOrder (Ref (Array Uint16) a)] (Array (Array Byte))))
(defn int16-seq->bytes [order is]
(let [f (fn [i] (int16->bytes order @i))]
(Array.copy-map &f is)))
(Array.copy-map f is)))

(doc unsafe-bytes->int32
"Interprets the first four bytes in a byte sequence as an Uint32 value.
Expand Down Expand Up @@ -194,10 +195,10 @@
(match order
(ByteOrder.LittleEndian)
(Array.copy-map &int32-to-byte
&[i (shift 8l) (shift 16l) (shift 24l)])
&[i (~shift 8l) (~shift 16l) (~shift 24l)])
(ByteOrder.BigEndian)
(Array.copy-map &int32-to-byte
&[(shift 24l) (shift 16l) (shift 8l) i]))))
&[(~shift 24l) (~shift 16l) (~shift 8l) i]))))

(doc unsafe-bytes->int32-seq
"Interprets a sequence of bytes as a sequence of Uint32 values.
Expand All @@ -206,7 +207,7 @@
(defn unsafe-bytes->int32-seq [order bs]
(let [partitions (Array.partition bs 4)
f (fn [b] (unsafe-bytes->int32 order b))]
(Array.copy-map &f &partitions)))
(Array.copy-map f &partitions)))

(doc bytes->int32-seq
"Interprets a sequence of bytes as a sequence of Uint32 values.
Expand Down Expand Up @@ -235,7 +236,7 @@
(sig int32-seq->bytes (Fn [ByteOrder (Ref (Array Uint32) a)] (Array (Array Byte))))
(defn int32-seq->bytes [order is]
(let [f (fn [i] (int32->bytes order @i))]
(Array.copy-map &f is)))
(Array.copy-map f is)))

(doc unsafe-bytes->int64
"Interprets the first eight bytes in a byte sequence as an Uint64 value.
Expand Down Expand Up @@ -280,14 +281,14 @@
(match order
(ByteOrder.LittleEndian)
(Array.copy-map &int64-to-byte
&[i (shift 8l) (shift 16l)
(shift 24l) (shift 32l)
(shift 40l) (shift 48l) (shift 56l)])
&[i (~shift 8l) (~shift 16l)
(~shift 24l) (~shift 32l)
(~shift 40l) (~shift 48l) (~shift 56l)])
(ByteOrder.BigEndian)
(Array.copy-map &int64-to-byte
&[(shift 56l) (shift 48l)
(shift 40l) (shift 32l)
(shift 24l) (shift 16l) (shift 8l) i]))))
&[(~shift 56l) (~shift 48l)
(~shift 40l) (~shift 32l)
(~shift 24l) (~shift 16l) (~shift 8l) i]))))

(doc unsafe-bytes->int64-seq
"Interprets a sequence of bytes as a sequence of Uint64 values.
Expand All @@ -296,7 +297,7 @@
(defn unsafe-bytes->int64-seq [order bs]
(let [partitions (Array.partition bs 8)
f (fn [b] (unsafe-bytes->int64 order b))]
(Array.copy-map &f &partitions)))
(Array.copy-map f &partitions)))

(doc bytes->int64-seq
"Interprets a sequence of bytes as a sequence of Uint64 values.
Expand Down Expand Up @@ -325,7 +326,7 @@
(sig int64-seq->bytes (Fn [ByteOrder (Ref (Array Uint64) a)] (Array (Array Byte))))
(defn int64-seq->bytes [order is]
(let [f (fn [i] (int64->bytes order @i))]
(Array.copy-map &f is)))
(Array.copy-map f is)))

(defn to-hex-str [b]
(let [hi (Byte.bit-and b (from-int 0xF0))
Expand Down Expand Up @@ -373,5 +374,5 @@
(sig bytes->hex-string (Fn [(Ref (Array Byte) q)] String))
(defn bytes->hex-string [bs]
(let [f (fn [b] (to-hex-str @b))]
(String.join " " &(Array.copy-map &f bs))))
(String.join " " &(Array.copy-map f bs))))
)
24 changes: 12 additions & 12 deletions core/Control.carp
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@ other higher order concepts.")
(set! result (~f result)))
result))

(doc when-success
(doc when-success
"Executes a side effect, `f`, when `result` is `Success`ful."
"```"
"(def suc (the (Result Int Int) (Result.Success 0)))"
"(def err (the (Result Int Int) (Result.Error 0)))"
""
"(when-success &(fn [] (IO.println \"success!\")) suc)"
"(when-success (fn [] (IO.println \"success!\")) suc)"
"=> success!"
"(when-success &(fn [] (IO.println \"success!\")) err)"
"(when-success (fn [] (IO.println \"success!\")) err)"
"=> "
"```")
(sig when-success (Fn [&(Fn [] ()) (Result a b)] ()))
Expand All @@ -37,15 +37,15 @@ other higher order concepts.")
(Result.Success _) (~f)
_ ()))

(doc when-error
(doc when-error
"Executes a side effect, `f`, when `result` is `Error`oneus."
"```"
"(def suc (the (Result Int Int) (Result.Success 0)))"
"(def err (the (Result Int Int) (Result.Error 0)))"
""
"(when-error &(fn [] (IO.println \"error!\")) err)"
"(when-error (fn [] (IO.println \"error!\")) err)"
"=> error!"
"(when-error &(fn [] (IO.println \"error!\")) suc)"
"(when-error (fn [] (IO.println \"error!\")) suc)"
"=> "
"```")
(sig when-error (Fn [&(Fn [] ()) (Result a b)] ()))
Expand All @@ -54,15 +54,15 @@ other higher order concepts.")
(Result.Error _) (~f)
_ ()))

(doc when-just
(doc when-just
"Executes a side-effect, `f`, when `maybe` is `Just`."
"```"
"(def just (Maybe.Just 2))"
"(def nothing (the (Maybe Int) (Maybe.Nothing)))"
""
"(when-just &(fn [] (IO.println \"just!\")) just)"
"(when-just (fn [] (IO.println \"just!\")) just)"
"=> just!"
"(when-just &(fn [] (IO.println \"just!\")) nothing)"
"(when-just (fn [] (IO.println \"just!\")) nothing)"
"=> "
"```")
(sig when-just (Fn [&(Fn [] ()) (Maybe a)] ()))
Expand All @@ -71,15 +71,15 @@ other higher order concepts.")
(Maybe.Just _) (~f)
_ ()))

(doc when-nothing
(doc when-nothing
"Executes a side-effect, `f`, when `maybe` is `Nothing`."
"```"
"(def just (Maybe.Just 2))"
"(def nothing (the (Maybe Int) (Maybe.Nothing)))"
""
"(when-nothing &(fn [] (IO.println \"nothing!\")) nothing)"
"(when-nothing (fn [] (IO.println \"nothing!\")) nothing)"
"=> nothing!"
"(when-nothing &(fn [] (IO.println \"nothing!\")) just)"
"(when-nothing (fn [] (IO.println \"nothing!\")) just)"
"=> "
"```")
(sig when-nothing (Fn [&(Fn [] ()) (Maybe a)] ()))
Expand Down
2 changes: 1 addition & 1 deletion core/Filepath.carp
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
(let [segments (split-by path &[\/])
n (dec (length &segments))
without-last (prefix &segments n)]
(concat &(copy-map &(fn [s] (str* s "/")) &without-last))))
(concat &(copy-map (fn [s] (str* s "/")) &without-last))))

(doc file-from-path "removes the base name part of a path to a file, similar to the `filename` utility in Shell scripting.")
(defn file-from-path [path]
Expand Down
2 changes: 1 addition & 1 deletion core/Generics.carp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ The margin of error is 0.00001.")
(not (neg? x)))

(defn id [x] x)
(defn const [x] (fn [_] x))
(defn const [x] @(fn [_] x))

(defn null? [p]
(Pointer.eq NULL (the (Ptr t) p)))
Expand Down
4 changes: 2 additions & 2 deletions core/Introspect.carp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
(reduce (with-copy + 2) 0 &[1 2 3])
=> 6
;; compare this with an inline anonymous function that achieves the same thing:
(reduce &(fn [x y] (+ x @y)) 0 &[1 2 3]) === (reduce (with-copy + 2) 0 &[1 2 3])
(reduce (fn [x y] (+ x @y)) 0 &[1 2 3]) === (reduce (with-copy + 2) 0 &[1 2 3])
```

This is useful when using higher-order functions that operate over structures that
Expand Down Expand Up @@ -194,5 +194,5 @@
call (cons function (map (fn [x] (if (= target x) prox x)) local-names))]
(if (> pos (Introspect.arity (eval function)))
(macro-error "with-copy error: the specified argument position is greater than the given function's arity.")
(list 'ref (list 'fn local-names call)))))
(list 'fn local-names call))))
)