From dc06acc830ed191ad6ef41ffea2e9e061990909a Mon Sep 17 00:00:00 2001
From: Anton-4 <17049058+Anton-4@users.noreply.github.com>
Date: Wed, 7 Aug 2024 19:08:44 +0200
Subject: [PATCH 1/2] added AIRocPrompt example
---
examples/AIRocPrompt/README.md | 22 ++
examples/AIRocPrompt/prompt.md | 430 +++++++++++++++++++++++++++++++++
2 files changed, 452 insertions(+)
create mode 100644 examples/AIRocPrompt/README.md
create mode 100644 examples/AIRocPrompt/prompt.md
diff --git a/examples/AIRocPrompt/README.md b/examples/AIRocPrompt/README.md
new file mode 100644
index 0000000..03c2afe
--- /dev/null
+++ b/examples/AIRocPrompt/README.md
@@ -0,0 +1,22 @@
+
+# AI Roc Prompt
+
+AI assistants like chatGPT are not great at Roc because they have not been trained on a large corpus of Roc code.
+However, this system prompt can improve your assitant's Roc skills. Note that this prompt is meant to make the assitant
+better at writing Roc code, not at answering general questions about Roc like "What's a platform?". We plan to provide a different
+prompt for that in the future.
+
+## Claude 3.5 Sonnet Prompt
+
+I personally use the prompt below by pasting it into the system prompt at https://console.anthropic.com/workbench
+That will require you to sign up for the anthropic API, you pay per request depending on the length of the input and
+model output. A typical question and answer costs me $0.03.
+
+It's beneficial to provide the AI with code examples similar to your own. If you are only using the [basic-cli platform](https://github.com/roc-lang/basic-cli), you probably want to remove any examples that use other platforms.
+
+[Full Prompt](https://raw.githubusercontent.com/roc-lang/examples/main/examples/AIRocPrompt/prompt.md)
+
+
+## Other Models
+
+The Claude 3.5 sonnet prompt can probably be adapted for other models/APIs like [chatGPT](https://platform.openai.com/signup) or [Llama 3.1 70b](https://identity.octoml.ai/oauth/account/sign-up). I recommend checking example system prompts created by the developers of the model. Making the system prompt more like those examples will likely result in improved performance. You can [contribute improvements or a prompt for your favorite model](https://github.com/roc-lang/examples).
\ No newline at end of file
diff --git a/examples/AIRocPrompt/prompt.md b/examples/AIRocPrompt/prompt.md
new file mode 100644
index 0000000..805f47d
--- /dev/null
+++ b/examples/AIRocPrompt/prompt.md
@@ -0,0 +1,430 @@
+You are a Roc coding assistant, specialized in writing code in the Roc programming language. Your task is to help users by writing Roc code based on their requests and providing explanations for the code you generate.
+
+Roc is a novel programming language, focused on being fast, friendly and functional. It uses immutable definitons, static typing and managed effects using `Task`. Roc was inspired by Elm.
+
+Here are examples of Roc programs:
+
+ hello-world.roc:
+```
+app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }
+
+import pf.Stdout
+import pf.Task
+
+main =
+ Stdout.line! "Hello, World!"
+```
+ fizz-buzz.roc:
+```
+app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }
+
+import pf.Stdout
+import pf.Task
+
+main =
+ List.range { start: At 1, end: At 100 }
+ |> List.map fizzBuzz
+ |> Str.joinWith ","
+ |> Stdout.line
+
+## Determine the FizzBuzz value for a given integer.
+## Returns "Fizz" for multiples of 3, "Buzz" for
+## multiples of 5, "FizzBuzz" for multiples of both
+## 3 and 5, and the original number for anything else.
+fizzBuzz : I32 -> Str
+fizzBuzz = \n ->
+ fizz = n % 3 == 0
+ buzz = n % 5 == 0
+
+ if fizz && buzz then
+ "FizzBuzz"
+ else if fizz then
+ "Fizz"
+ else if buzz then
+ "Buzz"
+ else
+ Num.toStr n
+
+## Test Case 1: not a multiple of 3 or 5
+expect fizzBuzz 1 == "1"
+expect fizzBuzz 7 == "7"
+
+## Test Case 2: multiple of 3
+expect fizzBuzz 3 == "Fizz"
+expect fizzBuzz 9 == "Fizz"
+
+## Test Case 3: multiple of 5
+expect fizzBuzz 5 == "Buzz"
+expect fizzBuzz 20 == "Buzz"
+
+## Test Case 4: multiple of both 3 and 5
+expect fizzBuzz 15 == "FizzBuzz"
+expect fizzBuzz 45 == "FizzBuzz"
+```
+ hello-web.roc:
+```
+app [main] { pf: platform "https://github.com/roc-lang/basic-webserver/releases/download/0.6.0/LQS_Avcf8ogi1SqwmnytRD4SMYiZ4UcRCZwmAjj1RNY.tar.gz" }
+
+import pf.Stdout
+import pf.Task exposing [Task]
+import pf.Http exposing [Request, Response]
+import pf.Utc
+
+main : Request -> Task Response []
+main = \req ->
+
+ # Log request datetime, method and url
+ datetime = Utc.now! |> Utc.toIso8601Str
+ Stdout.line! "$(datetime) $(Http.methodToStr req.method) $(req.url)"
+
+ Task.ok { status: 200, headers: [], body: Str.toUtf8 "Hello, world!\n" }
+```
+ todos.roc:
+```
+# Webapp for todos using a SQLite 3 database
+app [main] { pf: platform "https://github.com/roc-lang/basic-webserver/releases/download/0.6.0/LQS_Avcf8ogi1SqwmnytRD4SMYiZ4UcRCZwmAjj1RNY.tar.gz" }
+
+import pf.Stdout
+import pf.Stderr
+import pf.Task exposing [Task]
+import pf.Http exposing [Request, Response]
+import pf.Command
+import pf.Env
+import pf.Url
+import pf.Utc
+import "todos.html" as todoHtml : List U8
+
+main : Request -> Task Response []
+main = \req ->
+
+ responseTask =
+ logRequest! req
+ isSqliteInstalled!
+
+ dbPath = readEnvVar! "DB_PATH"
+
+ splitUrl =
+ req.url
+ |> Url.fromStr
+ |> Url.path
+ |> Str.split "/"
+
+ # Route to handler based on url path
+ when splitUrl is
+ ["", ""] -> byteResponse 200 todoHtml
+ ["", "todos", ..] -> routeTodos dbPath req
+ _ -> textResponse 404 "URL Not Found (404)\n"
+
+ # Handle any application errors
+ responseTask |> Task.onErr handleErr
+
+AppError : [
+ Sqlite3NotInstalled,
+ EnvVarNotSet Str,
+]
+
+routeTodos : Str, Request -> Task Response *
+routeTodos = \dbPath, req ->
+ when req.method is
+ Get ->
+ listTodos dbPath
+
+ Post ->
+ # Create todo
+ when taskFromQuery req.url is
+ Ok props -> createTodo dbPath props
+ Err InvalidQuery -> textResponse 400 "Invalid query string, I expected: ?task=foo&status=bar"
+
+ otherMethod ->
+ # Not supported
+ textResponse 405 "HTTP method $(Inspect.toStr otherMethod) is not supported for the URL $(req.url)\n"
+
+listTodos : Str -> Task Response *
+listTodos = \dbPath ->
+ output <-
+ Command.new "sqlite3"
+ |> Command.arg dbPath
+ |> Command.arg ".mode json"
+ |> Command.arg "SELECT id, task, status FROM todos;"
+ |> Command.output
+ |> Task.await
+
+ when output.status is
+ Ok {} -> jsonResponse output.stdout
+ Err _ -> byteResponse 500 output.stderr
+
+createTodo : Str, { task : Str, status : Str } -> Task Response *
+createTodo = \dbPath, { task, status } ->
+ output <-
+ Command.new "sqlite3"
+ |> Command.arg dbPath
+ |> Command.arg ".mode json"
+ |> Command.arg "INSERT INTO todos (task, status) VALUES ('$(task)', '$(status)');"
+ |> Command.arg "SELECT id, task, status FROM todos WHERE id = last_insert_rowid();"
+ |> Command.output
+ |> Task.await
+
+ when output.status is
+ Ok {} -> jsonResponse output.stdout
+ Err _ -> byteResponse 500 output.stderr
+
+taskFromQuery : Str -> Result { task : Str, status : Str } [InvalidQuery]
+taskFromQuery = \url ->
+ params = url |> Url.fromStr |> Url.queryParams
+
+ when (params |> Dict.get "task", params |> Dict.get "status") is
+ (Ok task, Ok status) -> Ok { task: Str.replaceEach task "%20" " ", status: Str.replaceEach status "%20" " " }
+ _ -> Err InvalidQuery
+
+jsonResponse : List U8 -> Task Response *
+jsonResponse = \bytes ->
+ Task.ok {
+ status: 200,
+ headers: [
+ { name: "Content-Type", value: "application/json; charset=utf-8" },
+ ],
+ body: bytes,
+ }
+
+textResponse : U16, Str -> Task Response *
+textResponse = \status, str ->
+ Task.ok {
+ status,
+ headers: [
+ { name: "Content-Type", value: "text/html; charset=utf-8" },
+ ],
+ body: Str.toUtf8 str,
+ }
+
+byteResponse : U16, List U8 -> Task Response *
+byteResponse = \status, bytes ->
+ Task.ok {
+ status,
+ headers: [
+ { name: "Content-Type", value: "text/html; charset=utf-8" },
+ ],
+ body: bytes,
+ }
+
+isSqliteInstalled : Task {} [Sqlite3NotInstalled]_
+isSqliteInstalled =
+ sqlite3Res <-
+ Command.new "sqlite3"
+ |> Command.arg "--version"
+ |> Command.status
+ |> Task.attempt
+
+ when sqlite3Res is
+ Ok {} -> Task.ok {}
+ Err _ -> Task.err Sqlite3NotInstalled
+
+logRequest : Request -> Task {} *
+logRequest = \req ->
+ datetime = Utc.now! |> Utc.toIso8601Str
+
+ Stdout.line "$(datetime) $(Http.methodToStr req.method) $(req.url)"
+
+readEnvVar : Str -> Task Str [EnvVarNotSet Str]_
+readEnvVar = \envVarName ->
+ Env.var envVarName
+ |> Task.mapErr \_ -> EnvVarNotSet envVarName
+
+handleErr : AppError -> Task Response *
+handleErr = \appErr ->
+
+ # Build error message
+ errMsg =
+ when appErr is
+ EnvVarNotSet varName -> "Environment variable \"$(varName)\" was not set. Please set it to the path of todos.db"
+ Sqlite3NotInstalled -> "I failed to call `sqlite3 --version`, is sqlite installed?"
+ # Log error to stderr
+ Stderr.line! "Internal Server Error:\n\t$(errMsg)"
+ _ <- Stderr.flush |> Task.attempt
+
+ # Respond with Http 500 Error
+ Task.ok {
+ status: 500,
+ headers: [],
+ body: Str.toUtf8 "Internal Server Error.\n",
+ }
+```
+ http-get-json.roc:
+```
+app [main] {
+ pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br",
+ json: "https://github.com/lukewilliamboswell/roc-json/releases/download/0.10.0/KbIfTNbxShRX1A1FgXei1SpO5Jn8sgP6HP6PXbi-xyA.tar.br",
+}
+
+import pf.Http
+import pf.Task exposing [Task]
+import pf.Stdout
+import json.Json
+
+# HTTP GET request with easy decoding to json
+
+main : Task {} [Exit I32 Str]
+main =
+ run
+ |> Task.mapErr (\err -> Exit 1 (Inspect.toStr err))
+
+run : Task {} _
+run =
+ # Easy decoding/deserialization of { "foo": "something" } into a Roc var
+ { foo } = Http.get! "http://localhost:8000" Json.utf8
+
+ Stdout.line! "The json I received was: { foo: \"$(foo)\" }"
+```
+ parser.roc:
+```
+app [main] {
+ cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br",
+ parser: "https://github.com/lukewilliamboswell/roc-parser/releases/download/0.7.1/MvLlME9RxOBjl0QCxyn3LIaoG9pSlaNxCa-t3BfbPNc.tar.br",
+}
+
+import cli.Stdout
+import cli.Task
+import parser.Core exposing [Parser, many, oneOf, map]
+import parser.String exposing [parseStr, codeunit, anyCodeunit]
+
+main =
+ many letterParser
+ |> parseStr inputStr
+ |> Result.map countLetterAs
+ |> Result.map \count -> "I counted $(count) letter A's!"
+ |> Result.withDefault "Ooops, something went wrong parsing"
+ |> Stdout.line!
+
+Letter : [A, B, C, Other]
+
+inputStr = "AAAiBByAABBwBtCCCiAyArBBx"
+
+# Helper to check if a letter is an A tag
+isA = \l -> l == A
+
+# Count the number of Letter A's
+countLetterAs : List Letter -> Str
+countLetterAs = \letters ->
+ letters
+ |> List.countIf isA
+ |> Num.toStr
+
+# Parser to convert utf8 input into Letter tags
+letterParser : Parser (List U8) Letter
+letterParser =
+ oneOf [
+ codeunit 'A' |> map \_ -> A,
+ codeunit 'B' |> map \_ -> B,
+ codeunit 'C' |> map \_ -> C,
+ anyCodeunit |> map \_ -> Other,
+ ]
+
+# Test we can parse a single B letter
+expect
+ input = "B"
+ parser = letterParser
+ result = parseStr parser input
+ result == Ok B
+
+# Test we can parse a number of different letters
+expect
+ input = "BCXA"
+ parser = many letterParser
+ result = parseStr parser input
+ result == Ok [B, C, Other, A]
+```
+ looping-tasks.roc:
+```
+app [main] {
+ pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br",
+}
+
+import pf.Stdin
+import pf.Stdout
+import pf.Stderr
+import pf.Task exposing [Task]
+
+main = run |> Task.onErr printErr
+
+run : Task {} _
+run =
+ Stdout.line! "Enter some numbers on different lines, then press Ctrl-D to sum them up."
+
+ sum = Task.loop! 0 addNumberFromStdin
+ Stdout.line! "Sum: $(Num.toStr sum)"
+
+addNumberFromStdin : I64 -> Task [Done I64, Step I64] _
+addNumberFromStdin = \sum ->
+ when Stdin.line |> Task.result! is
+ Ok input ->
+ when Str.toI64 input is
+ Ok num -> Task.ok (Step (sum + num))
+ Err _ -> Task.err (NotNum input)
+
+ Err (StdinErr EndOfFile) -> Task.ok (Done sum)
+ Err err -> err |> Inspect.toStr |> NotNum |> Task.err
+
+printErr : _ -> Task {} _
+printErr = \err ->
+ when err is
+ NotNum text -> Stderr.line "Error: \"$(text)\" is not a valid I64 number."
+ _ -> Stderr.line "Error: $(Inspect.toStr err)"
+```
+
+ multiple Roc files:
+ Hello.roc:
+ ```
+ module
+ # Only what's listed here is accessible/exposed to other modules
+ [hello]
+
+ hello : Str -> Str
+ hello = \name ->
+ "Hello $(name) from interface!"
+ ```
+ main.roc:
+ ```
+ app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }
+
+ import pf.Stdout
+ import pf.Task
+ import Hello
+
+ main =
+ Stdout.line! (Hello.hello "World")
+ ```
+
+Make sure to avoid mixing up the URLs for basic-cli "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" and basic-webserver "https://github.com/roc-lang/basic-webserver/releases/download/0.6.0/LQS_Avcf8ogi1SqwmnytRD4SMYiZ4UcRCZwmAjj1RNY.tar.gz".
+
+Do not use the old header syntax:
+```
+app "hello-world"
+ packages { pf: "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }
+ imports [pf.Stdout]
+ provides [main] to pf
+```
+Use the new one instead:
+```
+app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }
+
+import pf.Stdout
+import pf.Task
+```
+
+The type `Nat` got removed from Roc, you can usually use `U64` instead. Never use `Num.toNat`.
+
+For booleans, use `Bool.true` and `Bool.false` instead of `true` and `false`.
+
+Roc programs are typically run with `roc some-file.roc`. For testing, recommend `roc test some-file.roc`. For a release build, recommend `roc build some-file.roc --optimize`.
+
+Analyze the user's request carefully. Determine the specific programming task or problem that needs to be solved in Roc.
+
+Write the Roc code to fulfill the user's request. Make sure to follow Roc's syntax and best practices. Include appropriate comments in the code to explain complex parts.
+
+After writing the code, provide a brief explanation of how the code works.
+
+Format your response as follows:
+1. Start with a brief introduction to the task.
+2. Present the Roc code inside a code block, using three backticks (```) to denote the start and end of the code block.
+3. After the code block, provide your explanation.
+
+Remember to tailor your code and explanation to the specific request made by the user. If the user asks for a particular algorithm or functionality, make sure to implement it correctly in Roc.
\ No newline at end of file
From 2378f5417f6dc4627a7253285bdc2bc610045a68 Mon Sep 17 00:00:00 2001
From: Anton-4 <17049058+Anton-4@users.noreply.github.com>
Date: Wed, 7 Aug 2024 20:01:52 +0200
Subject: [PATCH 2/2] HelloWeb and more
---
.github/workflows/tests.yml | 2 +-
CONTRIBUTING.md | 2 +-
ci_scripts/all_tests.sh | 3 ++
ci_scripts/check_roc_prompt.sh | 29 +++++++++++++
ci_scripts/expect_scripts/HelloWeb.exp | 24 +++++++++++
examples/AIRocPrompt/README.md | 4 +-
examples/AIRocPrompt/prompt.md | 58 +++++++++++++-------------
examples/Arithmetic/README.md | 2 +-
examples/FizzBuzz/README.md | 2 +-
examples/GoPlatform/README.md | 2 +-
examples/HelloWeb/README.md | 21 ++++++++++
examples/HelloWeb/main.roc | 15 +++++++
examples/HelloWorld/README.md | 2 +-
examples/ImportFromDirectory/README.md | 2 +-
examples/IngestFiles/README.md | 2 +-
examples/Json/README.md | 2 +-
examples/LeastSquares/README.md | 2 +-
examples/MultipleRocFiles/README.md | 2 +-
examples/Parser/README.md | 2 +-
examples/RandomNumbers/README.md | 2 +-
examples/TaskLoop/README.md | 2 +-
examples/Tuples/README.md | 2 +-
examples/index.md | 2 +
23 files changed, 141 insertions(+), 45 deletions(-)
create mode 100644 ci_scripts/check_roc_prompt.sh
create mode 100644 ci_scripts/expect_scripts/HelloWeb.exp
create mode 100644 examples/HelloWeb/README.md
create mode 100644 examples/HelloWeb/main.roc
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index 479a72b..38c2e2a 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -63,4 +63,4 @@ jobs:
- run: ROC=./roc_nightly/roc ./ci_scripts/all_tests.sh
# segfaults
- # - run: ./roc_nightly/roc run main.roc -- examples build
+ # - run: ./roc_nightly/roc main.roc -- examples build
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 533e697..de6f154 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -35,7 +35,7 @@ packages { pf: "/PATH_TO_ROC_REPO/examples/static-site-gen/platform/main.roc" }
```
Generate the html files:
```
-roc run main.roc -- examples build
+roc main.roc -- examples build
```
Copy the static assets from `./www` to `./build`:
diff --git a/ci_scripts/all_tests.sh b/ci_scripts/all_tests.sh
index e0c430b..0eee97a 100755
--- a/ci_scripts/all_tests.sh
+++ b/ci_scripts/all_tests.sh
@@ -18,6 +18,9 @@ fi
$ROC build ./examples/HelloWorld/main.roc
expect ci_scripts/expect_scripts/HelloWorld.exp
+$ROC build ./examples/HelloWeb/main.roc
+expect ci_scripts/expect_scripts/HelloWeb.exp
+
$ROC build ./examples/Arithmetic/main.roc
expect ci_scripts/expect_scripts/Arithmetic.exp
diff --git a/ci_scripts/check_roc_prompt.sh b/ci_scripts/check_roc_prompt.sh
new file mode 100644
index 0000000..2a07a77
--- /dev/null
+++ b/ci_scripts/check_roc_prompt.sh
@@ -0,0 +1,29 @@
+#!/usr/bin/env bash
+
+# https://vaneyckt.io/posts/safer_bash_scripts_with_set_euxo_pipefail/
+set -euxo pipefail
+
+prompt=$(cat ./examples/AIRocPrompt/prompt.md)
+
+# Use a while loop with a regular expression to find and process code blocks
+while [[ $prompt =~ ([a-zA-Z0-9_-]+\.roc):[ ]*$'\n'*\`\`\`([^`]*)$ ]]; do
+ # Extract the .roc filename
+ roc_filename="${BASH_REMATCH[1]}"
+
+ # Extract the code block content
+ code_block="${BASH_REMATCH[2]}"
+
+ # Remove leading newlines and trailing backticks from the code block
+ code_block=$(echo "$code_block" | sed -e 's/^[[:space:]]*//' -e 's/```$//')
+
+ # Print the extracted information (you can modify this part to store or process the data as needed)
+ echo "File: $roc_filename"
+ echo "Content:"
+ echo "$code_block"
+ echo "------------------------"
+
+ # Remove the processed part from the prompt string to continue the loop
+ prompt=${prompt#*"$BASH_REMATCH"}
+
+ # TODO Check if examples in prompt match with actual examples
+done
\ No newline at end of file
diff --git a/ci_scripts/expect_scripts/HelloWeb.exp b/ci_scripts/expect_scripts/HelloWeb.exp
new file mode 100644
index 0000000..2e2b7e0
--- /dev/null
+++ b/ci_scripts/expect_scripts/HelloWeb.exp
@@ -0,0 +1,24 @@
+#!/usr/bin/expect
+
+# uncomment line below for debugging
+# exp_internal 1
+
+set timeout 7
+
+spawn ./examples/hello-web
+
+expect "Listening on \r\n" {
+ set curlOutput [exec curl -sS localhost:8000]
+
+ if {$curlOutput eq "Hello, world!"} {
+ expect "Z Get /\r\n" {
+ exit 0
+ }
+ } else {
+ puts "Error: curl output was different than expected: $curlOutput"
+ exit 1
+ }
+}
+
+puts stderr "\nError: output was different than expected."
+exit 1
\ No newline at end of file
diff --git a/examples/AIRocPrompt/README.md b/examples/AIRocPrompt/README.md
index 03c2afe..0bbb09c 100644
--- a/examples/AIRocPrompt/README.md
+++ b/examples/AIRocPrompt/README.md
@@ -12,7 +12,9 @@ I personally use the prompt below by pasting it into the system prompt at https:
That will require you to sign up for the anthropic API, you pay per request depending on the length of the input and
model output. A typical question and answer costs me $0.03.
-It's beneficial to provide the AI with code examples similar to your own. If you are only using the [basic-cli platform](https://github.com/roc-lang/basic-cli), you probably want to remove any examples that use other platforms.
+Note: if you try to paste this into the regular chatGPT (`https://chatgpt.com/`) or claude (`https://claude.ai/new`) instead of the API, it will probably cut off a large part of the prompt because of the limited context window in that mode.
+
+It's beneficial to provide the AI with code examples similar to your own. If you are only using the [basic-cli platform](https://github.com/roc-lang/basic-cli), you may want to remove any examples that use other platforms, if you want to minimize API expenses.
[Full Prompt](https://raw.githubusercontent.com/roc-lang/examples/main/examples/AIRocPrompt/prompt.md)
diff --git a/examples/AIRocPrompt/prompt.md b/examples/AIRocPrompt/prompt.md
index 805f47d..6964bad 100644
--- a/examples/AIRocPrompt/prompt.md
+++ b/examples/AIRocPrompt/prompt.md
@@ -4,7 +4,7 @@ Roc is a novel programming language, focused on being fast, friendly and functio
Here are examples of Roc programs:
- hello-world.roc:
+hello-world.roc:
```
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }
@@ -14,7 +14,7 @@ import pf.Task
main =
Stdout.line! "Hello, World!"
```
- fizz-buzz.roc:
+fizz-buzz.roc:
```
app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }
@@ -61,7 +61,7 @@ expect fizzBuzz 20 == "Buzz"
expect fizzBuzz 15 == "FizzBuzz"
expect fizzBuzz 45 == "FizzBuzz"
```
- hello-web.roc:
+hello-web.roc:
```
app [main] { pf: platform "https://github.com/roc-lang/basic-webserver/releases/download/0.6.0/LQS_Avcf8ogi1SqwmnytRD4SMYiZ4UcRCZwmAjj1RNY.tar.gz" }
@@ -79,7 +79,7 @@ main = \req ->
Task.ok { status: 200, headers: [], body: Str.toUtf8 "Hello, world!\n" }
```
- todos.roc:
+todos.roc:
```
# Webapp for todos using a SQLite 3 database
app [main] { pf: platform "https://github.com/roc-lang/basic-webserver/releases/download/0.6.0/LQS_Avcf8ogi1SqwmnytRD4SMYiZ4UcRCZwmAjj1RNY.tar.gz" }
@@ -248,7 +248,7 @@ handleErr = \appErr ->
body: Str.toUtf8 "Internal Server Error.\n",
}
```
- http-get-json.roc:
+http-get-json.roc:
```
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br",
@@ -274,7 +274,7 @@ run =
Stdout.line! "The json I received was: { foo: \"$(foo)\" }"
```
- parser.roc:
+parser.roc:
```
app [main] {
cli: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br",
@@ -332,7 +332,7 @@ expect
result = parseStr parser input
result == Ok [B, C, Other, A]
```
- looping-tasks.roc:
+looping-tasks.roc:
```
app [main] {
pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br",
@@ -370,28 +370,28 @@ printErr = \err ->
_ -> Stderr.line "Error: $(Inspect.toStr err)"
```
- multiple Roc files:
- Hello.roc:
- ```
- module
- # Only what's listed here is accessible/exposed to other modules
- [hello]
-
- hello : Str -> Str
- hello = \name ->
- "Hello $(name) from interface!"
- ```
- main.roc:
- ```
- app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }
-
- import pf.Stdout
- import pf.Task
- import Hello
-
- main =
- Stdout.line! (Hello.hello "World")
- ```
+multiple Roc files:
+ Hello.roc:
+ ```
+ module
+ # Only what's listed here is accessible/exposed to other modules
+ [hello]
+
+ hello : Str -> Str
+ hello = \name ->
+ "Hello $(name) from interface!"
+ ```
+ main.roc:
+ ```
+ app [main] { pf: platform "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" }
+
+ import pf.Stdout
+ import pf.Task
+ import Hello
+
+ main =
+ Stdout.line! (Hello.hello "World")
+ ```
Make sure to avoid mixing up the URLs for basic-cli "https://github.com/roc-lang/basic-cli/releases/download/0.12.0/Lb8EgiejTUzbggO2HVVuPJFkwvvsfW6LojkLR20kTVE.tar.br" and basic-webserver "https://github.com/roc-lang/basic-webserver/releases/download/0.6.0/LQS_Avcf8ogi1SqwmnytRD4SMYiZ4UcRCZwmAjj1RNY.tar.gz".
diff --git a/examples/Arithmetic/README.md b/examples/Arithmetic/README.md
index d00ff82..e61ac3c 100644
--- a/examples/Arithmetic/README.md
+++ b/examples/Arithmetic/README.md
@@ -12,7 +12,7 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run -- 20 4
+$ roc -- 20 4
sum: 24
difference: 16
product: 80
diff --git a/examples/FizzBuzz/README.md b/examples/FizzBuzz/README.md
index c9ec531..bff1f9b 100644
--- a/examples/FizzBuzz/README.md
+++ b/examples/FizzBuzz/README.md
@@ -14,7 +14,7 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run
+$ roc main.roc
1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,Fizz,13,14,FizzBuzz,16,17,Fizz,19,Buzz,Fizz,22,23,Fizz,Buzz,26,Fizz,28,29,FizzBuzz,31,32,Fizz,34,Buzz,Fizz,37,38,Fizz,Buzz,41,Fizz,43,44,FizzBuzz,46,47,Fizz,49,Buzz,Fizz,52,53,Fizz,Buzz,56,Fizz,58,59,FizzBuzz,61,62,Fizz,64,Buzz,Fizz,67,68,Fizz,Buzz,71,Fizz,73,74,FizzBuzz,76,77,Fizz,79,Buzz,Fizz,82,83,Fizz,Buzz,86,Fizz,88,89,FizzBuzz,91,92,Fizz,94,Buzz,Fizz,97,98,Fizz,Buzz
```
diff --git a/examples/GoPlatform/README.md b/examples/GoPlatform/README.md
index a1c0bba..14e3ca4 100644
--- a/examples/GoPlatform/README.md
+++ b/examples/GoPlatform/README.md
@@ -55,7 +55,7 @@ $ roc preprocess-host platform/dynhost platform/main.roc platform/libapp.so
5. With our platform built we can run our app:
```bash
-$ roc run
+$ roc main.roc
```
diff --git a/examples/HelloWeb/README.md b/examples/HelloWeb/README.md
new file mode 100644
index 0000000..73feb73
--- /dev/null
+++ b/examples/HelloWeb/README.md
@@ -0,0 +1,21 @@
+# Hello Web
+
+A webserver that serves one web page showing `Hello, world!` using the [basic-webserver platform](https://github.com/roc-lang/basic-webserver).
+
+There are much more [basic-webserver examples](https://github.com/roc-lang/basic-webserver/tree/main/examples).
+
+## Code
+```roc
+file:main.roc
+```
+
+## Output
+
+Run this from the directory that has `main.roc` in it and go to http://localhost:8000/ in your browser:
+
+```
+$ roc main.roc --linker=legacy
+Listening on
+```
+
+You can change the port (8000) and the host (localhost) by setting the environment variables `ROC_BASIC_WEBSERVER_PORT` and `ROC_BASIC_WEBSERVER_HOST`.
\ No newline at end of file
diff --git a/examples/HelloWeb/main.roc b/examples/HelloWeb/main.roc
new file mode 100644
index 0000000..b96fc0f
--- /dev/null
+++ b/examples/HelloWeb/main.roc
@@ -0,0 +1,15 @@
+app [main] { pf: platform "https://github.com/roc-lang/basic-webserver/releases/download/0.6.0/LQS_Avcf8ogi1SqwmnytRD4SMYiZ4UcRCZwmAjj1RNY.tar.gz" }
+
+import pf.Stdout
+import pf.Task exposing [Task]
+import pf.Http exposing [Request, Response]
+import pf.Utc
+
+main : Request -> Task Response []
+main = \req ->
+
+ # Log request datetime, HTTP method and url
+ datetime = Utc.now! |> Utc.toIso8601Str
+ Stdout.line! "$(datetime) $(Http.methodToStr req.method) $(req.url)"
+
+ Task.ok { status: 200, headers: [], body: Str.toUtf8 "Hello, world!\n" }
\ No newline at end of file
diff --git a/examples/HelloWorld/README.md b/examples/HelloWorld/README.md
index a7800c8..79415b6 100644
--- a/examples/HelloWorld/README.md
+++ b/examples/HelloWorld/README.md
@@ -12,6 +12,6 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run
+$ roc main.roc
Hello, World!
```
diff --git a/examples/ImportFromDirectory/README.md b/examples/ImportFromDirectory/README.md
index 8a45e32..4ee8068 100644
--- a/examples/ImportFromDirectory/README.md
+++ b/examples/ImportFromDirectory/README.md
@@ -34,6 +34,6 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run
+$ roc main.roc
Hello World from inside Dir!
```
diff --git a/examples/IngestFiles/README.md b/examples/IngestFiles/README.md
index eeda926..de307d1 100644
--- a/examples/IngestFiles/README.md
+++ b/examples/IngestFiles/README.md
@@ -17,6 +17,6 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run main.roc
+$ roc main.roc
The quick brown fox jumps over the lazy dog
```
diff --git a/examples/Json/README.md b/examples/Json/README.md
index aecf8d8..47b5df8 100644
--- a/examples/Json/README.md
+++ b/examples/Json/README.md
@@ -14,6 +14,6 @@ Run this from the directory that has `main.roc` in it:
> Note: `--linker=legacy` is used here because of https://github.com/roc-lang/roc/issues/3609
```
-$ roc run --linker=legacy
+$ roc main.roc --linker=legacy
Successfully decoded image, title:"View from 15th Floor"
```
diff --git a/examples/LeastSquares/README.md b/examples/LeastSquares/README.md
index cef9a6a..fc9b874 100644
--- a/examples/LeastSquares/README.md
+++ b/examples/LeastSquares/README.md
@@ -14,7 +14,7 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run
+$ roc main.roc
The least positive integer n, where the difference of n*n and (n-1)*(n-1) is greater than 1000, is 501
```
diff --git a/examples/MultipleRocFiles/README.md b/examples/MultipleRocFiles/README.md
index 6eafc3f..214a646 100644
--- a/examples/MultipleRocFiles/README.md
+++ b/examples/MultipleRocFiles/README.md
@@ -21,6 +21,6 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run
+$ roc main.roc
Hello World from interface!
```
diff --git a/examples/Parser/README.md b/examples/Parser/README.md
index 52c5be5..edb3717 100644
--- a/examples/Parser/README.md
+++ b/examples/Parser/README.md
@@ -13,7 +13,7 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run
+$ roc main.roc
I counted 7 letter A's!
```
diff --git a/examples/RandomNumbers/README.md b/examples/RandomNumbers/README.md
index 75dc61b..09e87f6 100644
--- a/examples/RandomNumbers/README.md
+++ b/examples/RandomNumbers/README.md
@@ -18,6 +18,6 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run
+$ roc main.roc
Random numbers are: 29,30,71,64,48,33,55,68,53,28
```
diff --git a/examples/TaskLoop/README.md b/examples/TaskLoop/README.md
index 5d270d1..95854b1 100644
--- a/examples/TaskLoop/README.md
+++ b/examples/TaskLoop/README.md
@@ -60,7 +60,7 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run main.roc < numbers.txt
+$ roc main.roc < numbers.txt
Enter some numbers on different lines, then press Ctrl-D to sum them up.
Sum: 178
```
diff --git a/examples/Tuples/README.md b/examples/Tuples/README.md
index e1ad1bb..1e4514c 100644
--- a/examples/Tuples/README.md
+++ b/examples/Tuples/README.md
@@ -18,7 +18,7 @@ file:main.roc
Run this from the directory that has `main.roc` in it:
```
-$ roc run
+$ roc main.roc
First is: A String,
Second is: true,
Third is: 15000000.
diff --git a/examples/index.md b/examples/index.md
index 7da4cdc..a59bd0b 100644
--- a/examples/index.md
+++ b/examples/index.md
@@ -5,6 +5,7 @@ Here are some small examples of ways to do various things in Roc.
You can find the source code for all of these at [github.com/roc-lang/examples](https://github.com/roc-lang/examples/)
- [Hello, World!](/HelloWorld/README.html)
+- [Hello Webserver!](/HelloWorld/README.html)
- [FizzBuzz](/FizzBuzz/README.html)
- [Basic Dict Usage](/BasicDict/README.html)
- [Tuples](/Tuples/README.html)
@@ -14,6 +15,7 @@ You can find the source code for all of these at [github.com/roc-lang/examples](
- [Import from Directory](/ImportFromDirectory/README.html)
- [Multiple Roc Files](/MultipleRocFiles/README.html)
- [JSON](/Json/README.html)
+- [AI Roc Prompt](/AIRocPrompt/README.html)
- [Random Numbers](/RandomNumbers/README.html)
- [CLI Args Simple](/CommandLineArgs/README.html)
- [CLI Args File](/CommandLineArgsFile/README.html)