Skip to content

Commit

Permalink
Release v3.0.3 (#776)
Browse files Browse the repository at this point in the history
  • Loading branch information
evhub authored Jul 29, 2023
2 parents 603a27f + 6b6c174 commit dbec988
Show file tree
Hide file tree
Showing 40 changed files with 2,998 additions and 1,303 deletions.
3 changes: 1 addition & 2 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@ install:
- rustup-init.exe -yv --default-toolchain stable --default-host i686-pc-windows-msvc
- "SET PATH=%APPDATA%\\Python;%APPDATA%\\Python\\Scripts;%PYTHON%;%PYTHON%\\Scripts;c:\\MinGW\\bin;%PATH%;C:\\Users\\appveyor\\.cargo\\bin"
- "copy c:\\MinGW\\bin\\mingw32-make.exe c:\\MinGW\\bin\\make.exe"
- python -m pip install --user --upgrade setuptools pip
- python -m pip install .[tests]
- make install

build: false

Expand Down
6 changes: 4 additions & 2 deletions .github/workflows/run-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ name: Coconut Test Suite
on: [push]
jobs:
build:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
strategy:
matrix:
python-version:
- '2.7'
- '3.4'
- '3.5'
- '3.6'
- '3.7'
Expand All @@ -24,9 +25,10 @@ jobs:
steps:
- uses: actions/checkout@v3
- name: Setup python
uses: actions/setup-python@v4
uses: MatteoH2O1999/setup-python@v1.3.1
with:
python-version: ${{ matrix.python-version }}
cache: pip
- run: make install
- run: make test-all
- run: make build
Expand Down
7 changes: 4 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,13 @@ __pypackages__/
.vscode

# Coconut
coconut/tests/dest/
docs/
/coconut/tests/dest/
/docs/
pyston/
pyprover/
bbopt/
coconut-prelude/
index.rst
vprof.json
coconut/icoconut/coconut/
/coconut/icoconut/coconut/
__coconut_cache__/
4 changes: 2 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ _Note: Don't forget to add yourself to the "Authors:" section in the moduledocs

First, you'll want to set up a local copy of Coconut's recommended development environment. For that, just run `git checkout develop`, make sure your default `python` installation is some variant of Python 3, and run `make dev`. That should switch you to the `develop` branch, install all possible dependencies, bind the `coconut` command to your local copy, and set up [pre-commit](http://pre-commit.com/), which will check your code for errors for you whenever you `git commit`.

Then, you should be able to use the Coconut command-line for trying out simple things, and to run a paired-down version of the test suite locally, just `make test-basic`.
Then, you should be able to use the Coconut command-line for trying out simple things, and to run a paired-down version of the test suite locally, just `make test-univ`.

After you've tested your changes locally, you'll want to add more permanent tests to Coconut's test suite. Coconut's test suite is primarily written in Coconut itself, so testing new features just means using them inside of one of Coconut's `.coco` test files, with some `assert` statements to check validity.

Expand Down Expand Up @@ -154,7 +154,7 @@ After you've tested your changes locally, you'll want to add more permanent test

1. Preparation:
1. Run `make check-reqs` and update dependencies as necessary
2. Run `make format`
2. Run `sudo make format`
3. Make sure `make test`, `make test-py2`, and `make test-easter-eggs` are passing
4. Ensure that `coconut --watch` can successfully compile files when they're modified
5. Check changes in [`compiled-cocotest`](https://github.com/evhub/compiled-cocotest), [`pyprover`](https://github.com/evhub/pyprover), and [`coconut-prelude`](https://github.com/evhub/coconut-prelude)
Expand Down
531 changes: 300 additions & 231 deletions DOCS.md

Large diffs are not rendered by default.

22 changes: 11 additions & 11 deletions HELP.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,11 +349,11 @@ return acc

Now let's take a look at what we do to `reduce` to make it multiply all the numbers we feed into it together. The Coconut code that we saw for that was `reduce$(*)`. There are two different Coconut constructs being used here: the operator function for multiplication in the form of `(*)`, and partial application in the form of `$`.

First, the operator function. In Coconut, a function form of any operator can be retrieved by surrounding that operator in parentheses. In this case, `(*)` is roughly equivalent to `lambda x, y: x*y`, but much cleaner and neater. In Coconut's lambda syntax, `(*)` is also equivalent to `(x, y) -> x*y`, which we will use from now on for all lambdas, even though both are legal Coconut, because Python's `lambda` statement is too ugly and bulky to use regularly.
First, the operator function. In Coconut, a function form of any operator can be retrieved by surrounding that operator in parentheses. In this case, `(*)` is roughly equivalent to `lambda x, y: x*y`, but much cleaner and neater. In Coconut's lambda syntax, `(*)` is also equivalent to `(x, y) => x*y`, which we will use from now on for all lambdas, even though both are legal Coconut, because Python's `lambda` statement is too ugly and bulky to use regularly.

_Note: If Coconut's `--strict` mode is enabled, which will force your code to obey certain cleanliness standards, it will raise an error whenever Python `lambda` statements are used._

Second, the partial application. Think of partial application as _lazy function calling_, and `$` as the _lazy-ify_ operator, where lazy just means "don't evaluate this until you need to." In Coconut, if a function call is prefixed by a `$`, like in this example, instead of actually performing the function call, a new function is returned with the given arguments already provided to it, so that when it is then called, it will be called with both the partially-applied arguments and the new arguments, in that order. In this case, `reduce$(*)` is roughly equivalent to `(*args, **kwargs) -> reduce((*), *args, **kwargs)`.
Second, the partial application. Think of partial application as _lazy function calling_, and `$` as the _lazy-ify_ operator, where lazy just means "don't evaluate this until you need to." In Coconut, if a function call is prefixed by a `$`, like in this example, instead of actually performing the function call, a new function is returned with the given arguments already provided to it, so that when it is then called, it will be called with both the partially-applied arguments and the new arguments, in that order. In this case, `reduce$(*)` is roughly equivalent to `(*args, **kwargs) => reduce((*), *args, **kwargs)`.

_You can partially apply arguments in any order using `?` in place of missing arguments, as in `to_binary = int$(?, 2)`._

Expand Down Expand Up @@ -531,7 +531,7 @@ data vector2(x, y):
# Test cases:
vector2(1, 2) |> print # vector2(x=1, y=2)
vector2(3, 4) |> abs |> print # 5
vector2(1, 2) |> fmap$(x -> x*2) |> print # vector2(x=2, y=4)
vector2(1, 2) |> fmap$(x => x*2) |> print # vector2(x=2, y=4)
v = vector2(2, 3)
v.x = 7 # AttributeError
```
Expand Down Expand Up @@ -579,7 +579,7 @@ Now that we have a constructor for our n-vector, it's time to write its methods.
"""Return the magnitude of the vector."""
self.pts |> map$(.**2) |> sum |> (.**0.5)
```
The basic algorithm here is map square over each element, sum them all, then square root the result. The one new construct here is the `(.**2)` and `(.**0.5)` syntax, which are effectively equivalent to `(x -> x**2)` and `(x -> x**0.5)`, respectively (though the `(.**2)` syntax produces a pickleable object). This syntax works for all [operator functions](./DOCS.md#operator-functions), so you can do things like `(1-.)` or `(cond() or .)`.
The basic algorithm here is map square over each element, sum them all, then square root the result. The one new construct here is the `(.**2)` and `(.**0.5)` syntax, which are effectively equivalent to `(x => x**2)` and `(x => x**0.5)`, respectively (though the `(.**2)` syntax produces a pickleable object). This syntax works for all [operator functions](./DOCS.md#operator-functions), so you can do things like `(1-.)` or `(cond() or .)`.

Next up is vector addition. The goal here is to add two vectors of equal length by adding their components. To do this, we're going to make use of Coconut's ability to perform pattern-matching, or in this case destructuring assignment, to data types, like so:
```coconut
Expand Down Expand Up @@ -733,7 +733,7 @@ _Hint: the `n`th diagonal should contain `n+1` elements, so try starting with `r

That wasn't so bad, now was it? Now, let's take a look at my solution:
```coconut
def diagonal_line(n) = range(n+1) |> map$(i -> (i, n-i))
def diagonal_line(n) = range(n+1) |> map$(i => (i, n-i))
```
Pretty simple, huh? We take `range(n+1)`, and use `map` to transform it into the right sequence of tuples.

Expand Down Expand Up @@ -856,7 +856,7 @@ data vector(*pts):
"""Necessary to make scalar multiplication commutative."""
self * other
def diagonal_line(n) = range(n+1) |> map$(i -> (i, n-i))
def diagonal_line(n) = range(n+1) |> map$(i => (i, n-i))
def linearized_plane(n=0) = diagonal_line(n) :: linearized_plane(n+1)
def vector_field() = linearized_plane() |> starmap$(vector)
Expand Down Expand Up @@ -919,7 +919,7 @@ _Hint: Look back at how we implemented scalar multiplication._

Here's my solution for you to check against:
```coconut
def __truediv__(self, other) = self.pts |> map$(x -> x/other) |*> vector
def __truediv__(self, other) = self.pts |> map$(x => x/other) |*> vector
```

### `.unit`
Expand Down Expand Up @@ -1036,7 +1036,7 @@ data vector(*pts):
"""Necessary to make scalar multiplication commutative."""
self * other
# New one-line functions necessary for finding the angle between vectors:
def __truediv__(self, other) = self.pts |> map$(x -> x/other) |*> vector
def __truediv__(self, other) = self.pts |> map$(x => x/other) |*> vector
def unit(self) = self / abs(self)
def angle(self, other `isinstance` vector) = math.acos(self.unit() * other.unit())
Expand Down Expand Up @@ -1082,7 +1082,7 @@ abcd$[2]

### Function Composition

Next is function composition. In Coconut, this is primarily accomplished through the `f1 ..> f2` operator, which takes two functions and composes them, creating a new function equivalent to `(*args, **kwargs) -> f2(f1(*args, **kwargs))`. This can be useful in combination with partial application for piecing together multiple higher-order functions, like so:
Next is function composition. In Coconut, this is primarily accomplished through the `f1 ..> f2` operator, which takes two functions and composes them, creating a new function equivalent to `(*args, **kwargs) => f2(f1(*args, **kwargs))`. This can be useful in combination with partial application for piecing together multiple higher-order functions, like so:
```coconut
zipsum = zip ..> map$(sum)
```
Expand Down Expand Up @@ -1111,9 +1111,9 @@ Another useful trick with function composition involves composing a function wit
def inc_or_dec(t):
# Our higher-order function, which returns another function
if t:
return x -> x+1
return x => x+1
else:
return x -> x-1
return x => x-1
def square(n) = n * n
Expand Down
Loading

0 comments on commit dbec988

Please sign in to comment.