Skip to content

Commit 845fd1c

Browse files
Make next release: ps-0.15.x-v0.31.1 (#590)
* Fix typo in higher kinded data pattern * Upgrade to PS 0.15.2 and package set * Add recursive type workaround with newtype example * Document typed holes on bindings tip/trick * Add entry for `purs-backend-es` and its library * Update example CI files * Cleanup immutability & persistence section via MermaidJs * Update project to 0.15.4; update esbuild * Also recommend `purs-backend-es` as optional tooling * Cleanup the WriterT/ExceptT overviews * Add another page for state-like transformers * Update preface's version of PureScript
1 parent de9cd16 commit 845fd1c

File tree

14 files changed

+367
-71
lines changed

14 files changed

+367
-71
lines changed

.github/workflows/ci.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ jobs:
1414

1515
- name: Set up PureScript toolchain
1616
uses: purescript-contrib/setup-purescript@main
17+
with:
18+
purescript: "0.15.4"
1719

1820
- name: Cache PureScript dependencies
1921
uses: actions/cache@v2

01-Getting-Started/04-Install-Guide.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,22 +47,28 @@ Unlike the manual install, `nvm` properly handles the npm prefix for you. So, yo
4747
Once you have installed `npm`, we can use it to install everything in one command:
4848

4949
```sh
50-
npm i -g [email protected].0 [email protected] esbuild@0.14.38
50+
npm i -g [email protected].4 [email protected] esbuild@0.15.7
5151
```
5252

5353
If you want to install a PureScript formatter, refer to their instructions. The history behind these tools will be covered in the `Build Tools` folder:
5454

5555
- [purs-tidy](https://github.com/natefaubion/purescript-tidy) - A self-contained formatter written in PureScript
5656
- [pose](https://pose.rowtype.yoga/) - A plugin written in PureScript for the [`Prettier`](https://prettier.io/) formatter
5757

58+
If you want to produce optimized JavaScript for your production environment (rather than a developer environment), install [`purs-backend-es`](https://github.com/aristanetworks/purescript-backend-optimizer):
59+
60+
```sh
61+
npm i -g purs-backend-es
62+
```
63+
5864
### Versions Used in this Project
5965

6066
The following commands should now work:
6167

6268
```sh
63-
purs --version # 0.15.0
69+
purs --version # 0.15.4
6470
spago --version # 0.20.9
65-
esbuild --version # 0.14.38
71+
esbuild --version # 0.15.7
6672
```
6773

6874
### Building This Project

02-FP-Philosophical-Foundations/03-Data-Types.md

Lines changed: 132 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,37 +7,138 @@ In order to abide by the principle of pure functions, FP Data Types tend to adhe
77
1. Immutable - the data does not change once created. To modify the data, one must create a copy of the original that includes the update.
88
2. Persistent - Rather than creating the entire structure again when updating, an update should create a new 'version' of a data structure that includes the update
99

10-
For example...
11-
```haskell
12-
{-
13-
Given a linked-list type where
14-
"Nil" is a placeholder representing the end of the list
15-
"←" in "left ← right" is a pointer that points from the
16-
right element to the left element
17-
"=" in "list = x" binds the 'x' name to the 'list' value -}
18-
Nil 1 2 3 = x
19-
{-
20-
To change x's `2` to `4`, we would create a new 'version' of 'x'
21-
that includes the unchanged tail (Nil ← 1)
22-
followed by the new update (← 4) and
23-
a copy of the rest of the list (← 3). -}
24-
Nil 1 2 3 = x
25-
26-
4 3 = y
27-
```
28-
Using a more visual diagram:
29-
30-
![Immutable-Persistent-Via-List](./assets/Immutable-Persistent-via-List.svg)
31-
32-
```haskell
33-
-- At the end of the computation, these are true:
34-
x == x
35-
x /= y
36-
37-
-- x = [3, 2, 1]
38-
-- y = [3, 4, 1]
39-
-- index 0 1 2
40-
(indexAt 2 x) isTheSameObjectAs (indexAt 2 y)
10+
We'll use a linked-list (see below) to demonstrate the above two ideas.
11+
12+
```mermaid
13+
flowchart RL
14+
3 ---> 2
15+
2 ---> 1
16+
1 ---> Nil
17+
```
18+
19+
Each list is one of two values:
20+
- the end of the list (i.e. `Nil`)
21+
- a node that stores one element in the list and a pointer to the rest of the list (i.e. `...<--[3]`)
22+
23+
## Mutability vs Immutability
24+
25+
Let's say we have a list that is assigned to the variable `list1`:
26+
```mermaid
27+
flowchart RL
28+
subgraph x["list1"]
29+
direction RL
30+
3 ---> 2
31+
2 ---> 1
32+
1 ---> Nil
33+
end
34+
```
35+
36+
Let's say we want to change element `2` to `5`. There are a few ways we could do this modification to `list1`.
37+
38+
The first way is to mutate `list1` directly, so that `list1` refers to new list. A data type that gets modified like this is a **mutable data type**.
39+
40+
Before our modification, this is what `list1` looks like:
41+
```mermaid
42+
flowchart RL
43+
subgraph x["list1"]
44+
direction RL
45+
3 ---> 2
46+
2 ---> 1
47+
1 ---> Nil
48+
end
49+
```
50+
51+
After our modification, this is what `list1` looks like:
52+
53+
```mermaid
54+
flowchart RL
55+
subgraph x["list1"]
56+
direction RL
57+
3 ---> 5
58+
5 ---> 1
59+
1 ---> Nil
60+
end
61+
```
62+
63+
The second way is to create a new version of `list1` called `list1Again`. A data type that gets modified like this is an **immutable data type**.
64+
65+
Before our modification, this is what `list1` looks like:
66+
```mermaid
67+
flowchart RL
68+
subgraph x["list1"]
69+
direction RL
70+
3 ---> 2
71+
2 ---> 1
72+
1 ---> Nil
73+
end
74+
```
75+
76+
After our modification, `list1` is unchanged, but the "modified version" is now `list1Again`:
77+
78+
```mermaid
79+
flowchart RL
80+
subgraph x["list1"]
81+
direction RL
82+
3 ---> 2
83+
2 ---> 1
84+
1 ---> Nil
85+
end
86+
87+
subgraph y["list1Again"]
88+
direction RL
89+
3'["3"] ---> 5'
90+
5'["5"] ---> 1'
91+
1'["1"] ---> Nil'["Nil"]
92+
end
93+
```
94+
95+
### Pros & Cons
96+
97+
| Topic | Mutable Data Types | Immutable Data Types |
98+
|-|-|-|
99+
| Reasoning | Code is harder to reason about: `list1` can refer to different values at different times | Code is easier to reason about: `list1` always refers to the same value |
100+
| Memory Usage | Uses less memory; low pressure on garbage collector | Uses more memory; higher pressure on garbage collector |
101+
| Multi-Threading | Risk of deadlocks, race conditions, etc. | No such risks |
102+
103+
## Immutable Data Types: Persistent or Not
104+
105+
There are two ways to modify an immutable data type.
106+
107+
First, one can choose NOT to share values across the copies. This is what was shown previously:
108+
109+
```mermaid
110+
flowchart RL
111+
subgraph x["list1"]
112+
direction RL
113+
3 ---> 2
114+
2 ---> 1
115+
1 ---> Nil
116+
end
117+
118+
subgraph y["list1Again"]
119+
direction RL
120+
3'["3"] ---> 5'
121+
5'["5"] ---> 1'
122+
1'["1"] ---> Nil'["Nil"]
123+
end
124+
```
125+
126+
Second, one can choose to share values across the copies. This is an example of a **persistent immutable data structure**. Sharing is caring:
127+
128+
```mermaid
129+
flowchart RL
130+
subgraph x["list1"]
131+
direction RL
132+
3 ---> 2
133+
2 ---> 1
134+
1 ---> Nil
135+
end
136+
137+
subgraph y["list1Again"]
138+
direction RL
139+
3'["3"] ---> 5'
140+
5'["5"] ---> 1
141+
end
41142
```
42143

43144
## Big O Notation

03-Build-Tools/04-Continuous-Integration.md

Lines changed: 49 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,29 @@
55
```yml
66
name: CI
77

8+
# Run CI when a PR is opened against the branch `main`
9+
# and when one pushes a commit to `main`.
810
on:
911
push:
10-
branches: [master]
12+
branches: [main]
13+
pull_request:
14+
branches: [main]
1115

16+
# Run CI on all 3 latest OSes
1217
jobs:
1318
build:
14-
runs-on: ubuntu-latest
19+
strategy:
20+
matrix:
21+
os: [ubuntu-latest, macOS-latest, windows-latest]
22+
runs-on: ${{ matrix.os }}
1523
steps:
1624
- uses: actions/checkout@v2
1725

1826
- uses: purescript-contrib/setup-purescript@main
1927
with:
20-
purescript: "0.15.0"
21-
purs-tidy: "0.8.0"
28+
purescript: "0.15.4"
29+
purs-tidy: "0.8.2"
30+
psa: "0.7.2"
2231

2332
- uses: actions/setup-node@v
2433
with:
@@ -29,36 +38,54 @@ jobs:
2938
npm install -g bower
3039
npm install
3140
bower install --production
41+
42+
# Compile the library/project
43+
# censor-lib: ignore warnings emitted by dependencies
44+
# strict: convert warnings into errors
3245
- name: Build source
33-
run: npm run-script build
46+
run: |
47+
pulp build -- --censor-lib --strict
3448
3549
- name: Run tests
3650
run: |
3751
bower install
38-
npm run-script test --if-present
52+
pulp test
53+
54+
- name: Check Formatting
55+
run: |
56+
purs-tidy check src test
3957
```
4058
4159
## GitHub Actions - `Spago`-based
4260

4361
```yml
4462
name: CI
4563
64+
# Run CI when a PR is opened against the branch `main`
65+
# and when one pushes a commit to `main`.
4666
on:
4767
push:
48-
branches: [master]
68+
branches: [main]
69+
pull_request:
70+
branches: [main]
4971

72+
# Run CI on all 3 latest OSes
5073
jobs:
5174
build:
52-
runs-on: ubuntu-latest
75+
strategy:
76+
matrix:
77+
os: [ubuntu-latest, macOS-latest, windows-latest]
78+
runs-on: ${{ matrix.os }}
5379

5480
steps:
5581
- uses: actions/checkout@v2
5682

5783
- uses: purescript-contrib/setup-purescript@main
5884
with:
59-
purescript: "0.15.0"
60-
purs-tidy: "0.8.0"
85+
purescript: "0.15.4"
86+
purs-tidy: "0.8.2"
6187
spago: "0.20.9"
88+
psa: "0.7.2"
6289

6390
- name: Cache PureScript dependencies
6491
uses: actions/cache@v2
@@ -88,9 +115,19 @@ jobs:
88115
- name: Install NPM dependencies
89116
run: npm install
90117

118+
# Compile the library/project
119+
# censor-lib: ignore warnings emitted by dependencies
120+
# strict: convert warnings into errors
121+
# Note: `purs-args` actually forwards these args to `psa`
91122
- name: Build the project
92-
run: npm run build
123+
run: |
124+
spago build --purs-args "--censor-lib --strict"
93125
94126
- name: Run tests
95-
run: npm run test
127+
run: |
128+
spago test
129+
130+
- name: Check Formatting
131+
run: |
132+
purs-tidy check src test
96133
```

03-Build-Tools/Readme.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ In PureScript `0.15.0`, we stopped compiling PureScript source code to CommonJS
7575

7676
See the [0.15.0 Migration Guide](https://github.com/purescript/documentation/blob/master/migration-guides/0.15-Migration-Guide.md) for more details.
7777

78+
### Phase 7: Producing Optimized JavaScript and Compiling to Other Languages
79+
80+
While the Purescript compiler produces correct JavaScript code, there were a number of optimizations that haven't been implemented in the compiler. However, the compiler was designed to output not just JavaScript, but an intermediate representation called `CoreFn`. This enables others to transform `CoreFn` to another language.
81+
82+
Soon after the time that PureScript `0.15.4` was released, a new project called `purs-backend-es` was released. This project works on the `CoreFn` representation and transforms it to JavaScript. However, it also optimizes the code significantly during this tranformation. For a few example, see [the `purs` and `purs-backend-es` comparison table in its README](https://github.com/aristanetworks/purescript-backend-optimizer#overview).
83+
84+
While this tool's main purpose is to produce optimized JavaScript code, it enables others to produce new backends. A backend is a target language to which PureScript can be compiled. Before this tool, every backend had to reinvent a lot of code to make it work for that language. With the underlying library, `purescript-backend-optimizer`, one can more easily produce a new backend.
85+
7886
## Overview of Tools
7987

8088
| Name | Type/Usage | Comments | URL |
@@ -84,6 +92,7 @@ See the [0.15.0 Migration Guide](https://github.com/purescript/documentation/blo
8492
| pulp | Build Tool | Front-end to `purs`. Builds & publishes projects | https://github.com/purescript-contrib/pulp |
8593
| bower | Dependency Manager (being deprecated) | -- | https://bower.io/ |
8694
| purs-tidy | PureScript Formatter | -- | https://github.com/natefaubion/purescript-tidy
95+
| purs-backend-es | Produces optimized JavaScript from PureScript | Only intended for production-level usage | https://github.com/aristanetworks/purescript-backend-optimizer
8796
| psa | Pretty, flexible error/warning frontend for `purs` | -- | https://github.com/natefaubion/purescript-psa
8897
| pscid | `pulp --watch build` on steroids | Seems to be a more recent version of `psc-pane` (see below) and uses `psa` | https://github.com/kRITZCREEK/pscid
8998
| psvm-js | PureScript Version Manager | -- | https://github.com/ThomasCrevoisier/psvm-js

0 commit comments

Comments
 (0)