fix: flesh out setup

This commit is contained in:
orion 2023-11-06 21:06:44 -06:00
parent f9620e2008
commit a01f0c40fa
Signed by: orion
GPG Key ID: 6D4165AE4C928719
2 changed files with 331 additions and 221 deletions

246
exercise.md Normal file
View File

@ -0,0 +1,246 @@
# thunderstrike.ai intern resources
## contents
* [rust](#rust)
* [in brief](#rust-in-brief)
* [purescript](#purescript)
* [in brief](#purescript-in-brief)
* [example - frontend app](#purescript-example-frontend-app)
* [optional exercise](#exercise)
* [setup](#exercise-setup)
* [task](#exercise-task)
* [further reading](#further-reading)
## rust
**Rust** is a strongly-typed <a href="https://en.wikipedia.org/wiki/Type_safety"><sup>[type safety]</sup></a>
systems programming language <a href="https://en.wikipedia.org/wiki/System_programming_language"><sup>[systems programming language]</sup></a>.
### Rust in brief
<ul>
<li>Error handling is done with a special type that represents "the `Result` of this may be an error"</li>
<li>Null values are represented by special type that represents "this value is `Option`al"</li>
<li>Rust programs are incredibly fast and predictable</li>
</ul>
## purescript
**Purescript** is a strongly-typed <a href="https://en.wikipedia.org/wiki/Type_safety"><sup>[type safety]</sup></a>
purely functional <a href="https://en.wikipedia.org/wiki/Purely_functional_programming"><sup>[purely functional]</sup></a>
programming language that compiles to javascript (like typescript).
### Purescript in brief
<ul>
<li>Error handling is done with a special type that represents "`Either` it succeeded or failed"</li>
<li>Null values are represented by special type that represents "`Maybe` it's present or not"</li>
<li>
effectful code
<a href="https://en.wikipedia.org/wiki/Side_effect_(computer_science)"><sup>[side effect]</sup></a>
is isolated from non-effectful code. This makes programs much more consistent to run and reason about.
</li>
<li>everything is an expression</li>
<li>interacting with raw javascript is relatively painless</li>
</ul>
### Purescript Example - Frontend App
You don't have to understand exactly how these examples work,
I'm providing them simply for you to glance over and get a feeling
for reading typescript/javascript vs purescript.
This app:
1. renders `"Loading..."` until either data or error
1. fetches data from a server
1. if ok, render items in a list. if error, render error span at the bottom of the page.
<details>
<summary><b>React (click to expand)</b></summary>
```typescript
type Item = {id: string, title: string, description: string}
export const App: () => React.Node = () => {
const [items, setItems] = React.useState<Array<Item> | undefined>(undefined)
const [error, setError] = React.useState<Error | undefined>(undefined)
React.useEffect(() => {
fetch('/api/item')
.then(rep => rep.json<Array<Item>>())
.then(items => setItems(items))
.catch(e => setError(e))
}, [])
return error !== undefined
? (<p class="error">{error.message}</p>)
: items === undefined
? (<p>Loading...</p>)
: items.map(item => {
return (
<div key={item.id}>
<p>{item.title}</p>
<span class="small">
{item.description}
</span>
</div>
)
})
}
```
</details>
<details>
<summary><b>Purescript Halogen (click to expand)</b></summary>
```haskell
type Item = { id :: String, title :: String, description :: String }
data State
= StateEmpty
| StateErrored Error
| StateGotItems (Array Item)
data Action = ActionInit
renderItem item = div [] [ p [] [text item.title]
, span
[className "small"]
[text item.description]
]
renderApp StateEmpty = p [] [text "Loading..."]
renderApp (StateErrored e) = p [className "error"] [text (message e)]
renderApp (StateGotItems items) = map renderItem items
action ActionInit = do
response <- fetch (URL "/api/item") {method: Get}
jsonString <- text response
itemsOrError <- readJSON jsonString
case itemsOrError of
Right items -> put (StateGotItems items)
Left error -> put (StateErrored error)
app = mkComponent
{ initialState: StateEmpty
, render: renderApp
, eval: mkEval ( defaultEval { handleAction = action, initialize: Just ActionInit } )
}
```
</details>
## Exercise
This is an optional code exercise for you to use if you have extra
time and would like a somewhat guided foray into one or both of the languages
mentioned here.
### Exercise - Setup
#### Windows
This guide assumes you are using linux or macos.
On windows, install an ubuntu virtual machine on WSL2 using this guide: https://learn.microsoft.com/en-us/windows/wsl/install
After installing, run the following:
```sh
apt-get update -y
apt-get upgrade -y
apt-get install -y wget curl git openssl zsh
```
If using Visual Studio Code, this guide will help you configure VSCode to run in WSL instead of Windows: https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-vscode
#### VSCode
* [rust](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
* [purescript](https://marketplace.visualstudio.com/items?itemName=nwolverson.ide-purescript)
#### asdf
For tooling, I recommend using [asdf](asdf-vm.com)
```sh
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1
echo 'source "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
echo 'source "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
echo '[ -s "~/.bun/_bun" ] && source "~/.bun/_bun"' >> ~/.bashrc
echo 'export BUN_INSTALL="~/.bun"' >> ~/.bashrc
echo 'export PATH=$PATH:$HOME/.bun/bin' >> ~/.bashrc
asdf plugin add rust
asdf plugin add bun
asdf plugin add purescript
asdf install rust latest
asdf install bun latest
asdf install purescript latest
asdf global rust latest
asdf global bun latest
asdf global purescript latest
bun install --global spago@next
cargo --version
echo -n "bun " && bun --version
echo -n "purescript " && purs --version
echo -n "spago " && spago --version
# cargo 1.70.0
# bun 1.0.3
# purescript 0.15.11-3
# spago 0.93.14
```
#### Clone this repo
```sh
git clone https://git.orionkindel.com/orion/intern-resources.git
cd intern-resources/example-rs
cargo build
cargo run
cd ../example-purs
spago build
spago run
```
### Exercise - Task
In either purescript or rust, write a program that operates on CSV data and transforms it into JSON.
#### Purescript Instructions
* use the provided template `./exercise-purs/`
* use the provided CSV parser `./exercise-purs/src/Data.CSV.purs`
* modify `./exercise-purs/src/Main.purs` to read a csv file and print it as JSON to the terminal
_hints:_
* [`Node.FS.Sync.readFile`](https://pursuit.purescript.org/packages/purescript-node-fs/9.1.0/docs/Node.FS.Sync#v:readFile)
* [`Simple.JSON.writeJSON`](https://pursuit.purescript.org/packages/purescript-simple-json/9.0.0/docs/Simple.JSON#v:writeJSON)
#### Rust Instructions
* use the provided template `./exercise-rs/`
* use the [`csv`](https://docs.rs/csv/latest/csv/) crate to parse csvs
* modify `./exercise-rs/src/main.rs` to read a csv file and print it as JSON to the terminal
_hints:_
* [`csv`](https://docs.rs/csv/latest/csv/)
* [`serde_json`](https://docs.rs/csv/latest/serde-json/)
**Example**
The input
```csv
Title,Salary,Name
CEO,100000,Jack
CTO,100000,Bryan
Engineer,80000,Jennifer
```
Should output
```json
[
{"Title": "CEO", "Salary": "100000", "Name": "Jack"},
{"Title": "CTO", "Salary": "100000", "Name": "Bryan"},
{"Title": "Engineer", "Salary": "80000", "Name": "Jennifer"},
]
```
## Further reading
* [purescript website](https://www.purescript.org/)
* [purescript by example (free online book)](https://book.purescript.org/)
* [purescript in depth (free online book)](https://leanpub.com/purescript/read)
* [purescript halogen docs](https://purescript-halogen.github.io/purescript-halogen/)
* [purescript halogen implementation of the realworld project](https://github.com/thomashoneyman/purescript-halogen-realworld)
* [rust website](https://www.rust-lang.org/)
* [rust book (free online book)](https://doc.rust-lang.org/book/)

306
readme.md
View File

@ -1,165 +1,99 @@
# thunderstrike.ai intern resources
# System Setup
## contents
* [rust](#rust)
* [in brief](#rust-in-brief)
* [purescript](#purescript)
* [in brief](#purescript-in-brief)
* [example - frontend app](#purescript-example-frontend-app)
* [optional exercise](#exercise)
* [setup](#exercise-setup)
* [task](#exercise-task)
* [further reading](#further-reading)
## prepare macOS
instructions may differ depending if you're on an intel mac or an apple silicon mac
## rust
**Rust** is a strongly-typed <a href="https://en.wikipedia.org/wiki/Type_safety"><sup>[type safety]</sup></a>
systems programming language <a href="https://en.wikipedia.org/wiki/System_programming_language"><sup>[systems programming language]</sup></a>.
not sure which you have? [follow this guide to find out.](https://www.howtogeek.com/706226/how-to-check-if-your-mac-is-using-an-intel-or-apple-silicon-processor/)
### Rust in brief
<ul>
<li>Error handling is done with a special type that represents "the `Result` of this may be an error"</li>
<li>Null values are represented by special type that represents "this value is `Option`al"</li>
<li>Rust programs are incredibly fast and predictable</li>
</ul>
## purescript
**Purescript** is a strongly-typed <a href="https://en.wikipedia.org/wiki/Type_safety"><sup>[type safety]</sup></a>
purely functional <a href="https://en.wikipedia.org/wiki/Purely_functional_programming"><sup>[purely functional]</sup></a>
programming language that compiles to javascript (like typescript).
### Purescript in brief
<ul>
<li>Error handling is done with a special type that represents "`Either` it succeeded or failed"</li>
<li>Null values are represented by special type that represents "`Maybe` it's present or not"</li>
<li>
effectful code
<a href="https://en.wikipedia.org/wiki/Side_effect_(computer_science)"><sup>[side effect]</sup></a>
is isolated from non-effectful code. This makes programs much more consistent to run and reason about.
</li>
<li>everything is an expression</li>
<li>interacting with raw javascript is relatively painless</li>
</ul>
### Purescript Example - Frontend App
You don't have to understand exactly how these examples work,
I'm providing them simply for you to glance over and get a feeling
for reading typescript/javascript vs purescript.
This app:
1. renders `"Loading..."` until either data or error
1. fetches data from a server
1. if ok, render items in a list. if error, render error span at the bottom of the page.
<details>
<summary><b>React (click to expand)</b></summary>
```typescript
type Item = {id: string, title: string, description: string}
export const App: () => React.Node = () => {
const [items, setItems] = React.useState<Array<Item> | undefined>(undefined)
const [error, setError] = React.useState<Error | undefined>(undefined)
React.useEffect(() => {
fetch('/api/item')
.then(rep => rep.json<Array<Item>>())
.then(items => setItems(items))
.catch(e => setError(e))
}, [])
return error !== undefined
? (<p class="error">{error.message}</p>)
: items === undefined
? (<p>Loading...</p>)
: items.map(item => {
return (
<div key={item.id}>
<p>{item.title}</p>
<span class="small">
{item.description}
</span>
</div>
)
})
}
```
</details>
<details>
<summary><b>Purescript Halogen (click to expand)</b></summary>
```haskell
type Item = { id :: String, title :: String, description :: String }
data State
= StateEmpty
| StateErrored Error
| StateGotItems (Array Item)
data Action = ActionInit
renderItem item = div [] [ p [] [text item.title]
, span
[className "small"]
[text item.description]
]
renderApp StateEmpty = p [] [text "Loading..."]
renderApp (StateErrored e) = p [className "error"] [text (message e)]
renderApp (StateGotItems items) = map renderItem items
action ActionInit = do
response <- fetch (URL "/api/item") {method: Get}
jsonString <- text response
itemsOrError <- readJSON jsonString
case itemsOrError of
Right items -> put (StateGotItems items)
Left error -> put (StateErrored error)
app = mkComponent
{ initialState: StateEmpty
, render: renderApp
, eval: mkEval ( defaultEval { handleAction = action, initialize: Just ActionInit } )
}
```
</details>
## Exercise
This is an optional code exercise for you to use if you have extra
time and would like a somewhat guided foray into one or both of the languages
mentioned here.
### Exercise - Setup
#### Windows
This guide assumes you are using linux or macos.
On windows, install an ubuntu virtual machine on WSL2 using this guide: https://learn.microsoft.com/en-us/windows/wsl/install
After installing, run the following:
### install homebrew
```sh
apt-get update -y
apt-get upgrade -y
apt-get install -y wget curl git openssl zsh
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew update
brew install openssl git-lfs git zsh vscodium
```
If using Visual Studio Code, this guide will help you configure VSCode to run in WSL instead of Windows: https://learn.microsoft.com/en-us/windows/wsl/tutorials/wsl-vscode
## prepare windows
in an administrator powershell window: (press windows > type "powershell" > right click > run as administrator)
```powershell
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
wsl --install -d Debian
```
#### VSCode
* [rust](https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer)
* [purescript](https://marketplace.visualstudio.com/items?itemName=nwolverson.ide-purescript)
then install [vscodium](https://vscodium.com/#install) (or [vscode](https://code.visualstudio.com/Download) if you prefer)
during install, there should be an "additional tasks > add vscode to PATH" option, this is strongly recommended.
#### asdf
For tooling, I recommend using [asdf](asdf-vm.com)
### vscode in wsl mode
open vscode & install the [WSL vscode extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-wsl)
### set up wsl
in powershell:
```powershell
debian -u root
```
```sh
echo "installing packages"
apt-get update -y
apt-get upgrade -y
apt-get install -y git git-lfs libssl-devel curl wget man neovim zsh
echo "adding docker repo"
apt-get update
apt-get install ca-certificates curl gnupg
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
chmod a+r /etc/apt/keyrings/docker.gpg
echo "installing docker"
echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt-get update -y
apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
echo "installing postgresql"
apt install -y postgresql-common
/usr/share/postgresql-common/pgdg/apt.postgresql.org.sh
apt-get install -y postgresql-client-16
echo "changing default user to root, boot using systemd"
cat << "EOF" > /etc/wsl.conf
[user]
default = root
[boot]
systemd=true
EOF
```
if that went well, close the window and in a powershell window:
```powershell
wsl --shutdown
```
then reopen `debian` and try running:
```sh
code .
```
a windows 10 VSCode window should open with "WSL: Debian" displayed in the far bottom left corner of the window
if this all went well, continue to [common](#common) and assume code snippets should be run in `debian`.
feel free to use VSCode in windows for terminal and file editing!
## common
```sh
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.13.1
echo 'source "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
echo 'source "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
echo '[ -s "~/.bun/_bun" ] && source "~/.bun/_bun"' >> ~/.bashrc
echo 'export BUN_INSTALL="~/.bun"' >> ~/.bashrc
echo 'export PATH=$PATH:$HOME/.bun/bin' >> ~/.bashrc
cat << "EOF" >> ~/.zshrc
source "$HOME/.asdf/asdf.sh"
source "$HOME/.asdf/completions/asdf.bash"
[ -s "~/.bun/_bun" ] && source "~/.bun/_bun"
export BUN_INSTALL="~/.bun"
export PATH=$PATH:$HOME/.bun/bin
EOF
asdf plugin add python
asdf plugin add nodejs
asdf plugin add rust
asdf plugin add bun
asdf plugin add purescript
@ -171,76 +105,6 @@ asdf install purescript latest
asdf global rust latest
asdf global bun latest
asdf global purescript latest
bun install --global spago@next
cargo --version
echo -n "bun " && bun --version
echo -n "purescript " && purs --version
echo -n "spago " && spago --version
# cargo 1.70.0
# bun 1.0.3
# purescript 0.15.11-3
# spago 0.93.14
```
#### Clone this repo
```sh
git clone https://git.orionkindel.com/orion/intern-resources.git
cd intern-resources/example-rs
cargo build
cargo run
cd ../example-purs
spago build
spago run
```
### Exercise - Task
In either purescript or rust, write a program that operates on CSV data and transforms it into JSON.
#### Purescript Instructions
* use the provided template `./exercise-purs/`
* use the provided CSV parser `./exercise-purs/src/Data.CSV.purs`
* modify `./exercise-purs/src/Main.purs` to read a csv file and print it as JSON to the terminal
_hints:_
* [`Node.FS.Sync.readFile`](https://pursuit.purescript.org/packages/purescript-node-fs/9.1.0/docs/Node.FS.Sync#v:readFile)
* [`Simple.JSON.writeJSON`](https://pursuit.purescript.org/packages/purescript-simple-json/9.0.0/docs/Simple.JSON#v:writeJSON)
#### Rust Instructions
* use the provided template `./exercise-rs/`
* use the [`csv`](https://docs.rs/csv/latest/csv/) crate to parse csvs
* modify `./exercise-rs/src/main.rs` to read a csv file and print it as JSON to the terminal
_hints:_
* [`csv`](https://docs.rs/csv/latest/csv/)
* [`serde_json`](https://docs.rs/csv/latest/serde-json/)
**Example**
The input
```csv
Title,Salary,Name
CEO,100000,Jack
CTO,100000,Bryan
Engineer,80000,Jennifer
```
Should output
```json
[
{"Title": "CEO", "Salary": "100000", "Name": "Jack"},
{"Title": "CTO", "Salary": "100000", "Name": "Bryan"},
{"Title": "Engineer", "Salary": "80000", "Name": "Jennifer"},
]
```
## Further reading
* [purescript website](https://www.purescript.org/)
* [purescript by example (free online book)](https://book.purescript.org/)
* [purescript in depth (free online book)](https://leanpub.com/purescript/read)
* [purescript halogen docs](https://purescript-halogen.github.io/purescript-halogen/)
* [purescript halogen implementation of the realworld project](https://github.com/thomashoneyman/purescript-halogen-realworld)
* [rust website](https://www.rust-lang.org/)
* [rust book (free online book)](https://doc.rust-lang.org/book/)
Done!