* feat: Can omit .init in simple cases
* fix: Don't treat unqualified modules as interface sym:s
* feat: Can handle implicit init of type inside 'use':d module
* fix: Give deftypes and sumtypes correct parent environment!
* test: A few test cases
* refactor: Remove commented out code
Co-authored-by: Erik Svedang <erik@Eriks-iMac.local>
* chore: Moved examples that work more as tests to folder 'test/produces-output'
* fix: Corrections to the release script
* fix: Correct filename on Windows
* fix: Move more files around
* fix: Remove check-malloc example
* fix: Apparently unicode example does not work
* chore: Move nested_lambdas.carp back to examples
* chore: Remove .DS_Store files
* fix: Bring back unicode test
* test: Make sure benchmark compile (had to remove mandelbrot and n-bodies)
* fix: Replacement implementation of clock_gettime on Windows
* chore: Trigger CI
* fix: Define CLOCK_REALTIME
Co-authored-by: Erik Svedang <erik@Eriks-iMac.local>
Indexing from zero is consistent with the rest of Carp's indexing
behavior, so this should make the function more predictable. I've also
added a note to the docs about this.
with-copy better communicates that this macro will produce a function
that performs a copy--it doesn't cover the fact that it creates a
references to an anonymous function...but there's only so much we can
cover in a name.
I've also updated the documentation.
It's a fairly common pattern in Carp to call a higher-order function on
some structure of values, such as an Array. However, these structures,
and their members, all have lifetimes under Carp's memory management
model, which means they expect functions that are mapped over them to
take *a reference to a value* rather than a pure value. Array.reduce is
one example of such a "referential" higher-order, the type of its
function argument is:
```
(Fn [a, (Ref b c)] a)
```
That is, this function takes some pure initial value, then expects to be
called against the members of an array, which are *references* to the
values that are alive throughout the Array's lifetime.
However, one often wants to use a function that operates on pure values
in such contexts, such as +, which forces the programmer to write
anonymous functions that handle copying referenced values to pass them
to the underlying "pure" function:
```
(Array.reduce &(fn [x y] (+ x @y)) 0 &[1 2 3])
```
So, in using some high-order function over some structure in Carp one
usually has to do two things:
1. Wrap the function in a ref
2. Handle copying references into values in order to pass them into some
simpler function that can also be used outside of memory-bound
contexts.
The `proxy` macro captures this pattern. It wraps a given function in a
referenced anonymous function and copies an argument of that function at
a designated position before calling the underlying function. For
example, with `proxy`, the above example becomes:
```
(Array.reduce (proxy + 2) 0 &[1 2 3])
```
The macro effectively gives a name to a common pattern--typically it
will only save the programmer a few characters, but it perhaps makes the
act of using a "function that doesn't care about references" in a
reference dominant context more apparent.
One can also use the macro to develop more specialized macros for
certain higher-orders, since these usually dictate where copying must be
performed. For instance, the `Array.reduce` function argument always
expects the referenced value to occur in the second position, thus one
could write:
```
(defmacro reducer [function] (eval (list proxy function 2)))
```
Then the above code becomes even simpler:
```
(Array.reducer (reducer +) 0 &[1 2 3])
```
Which roughly means, "use the + function (which has no concept of
references) in this reference dependent context".
N.B. The examples using `+` won't work as of now due to current bugs
related to calling `arity` directly on an interface--but a synonym for
plus `add` defined as an explicit function will make all the above work
as expected.
Constrained interfaces require little change to core carp. In rare cases
(illustrated in test/interfaces.carp) we need to make our functions
slightly more specific. This weakens inference slightly, but in my
opinion is a reasonable case of weakness and not a fault of the type
system.
Exceptional cases that were typed `a-> a` that is, cases that relied on
the previous typing errors related to interfaces, as might be expected,
no longer work (as is the case for the higher-order use of fmap in
examples/functor.carp).
Aside from that, nothing changes.