mirror of
https://github.com/roc-lang/roc.git
synced 2025-08-04 04:08:19 +00:00
Merge pull request #4605 from roc-lang/tutorial-changes
Tutorial and homepage updates
This commit is contained in:
commit
9ce2f4e1ff
2 changed files with 36 additions and 49 deletions
|
@ -177,26 +177,17 @@
|
|||
|
||||
<p>The REPL fully supports entering arbitrary expressions, and will evaluate them and print the
|
||||
results. It remembers recent expressions entered in the current session (if you press the up arrow),
|
||||
but it can't yet execute effects, and any named variables you define currently exist only for the
|
||||
next expression it evaluates; they don't yet persist for the remainder of the session. You can try
|
||||
out the REPL in a browser at <a href="https://roc-lang.org/repl">roc-lang.org/repl</a> - it uses a
|
||||
WebAssembly build of Roc's compiler, and compiles the code you write to WebAssembly on the fly,
|
||||
which it then executes in the browser to display the answer.</p>
|
||||
but it can't yet execute effects. You can try out the REPL in a browser at
|
||||
<a href="https://roc-lang.org/repl">roc-lang.org/repl</a> - it uses a WebAssembly build of Roc's
|
||||
compiler, and compiles the code you write to WebAssembly on the fly, which it then executes in
|
||||
the browser to display the answer.</p>
|
||||
|
||||
<p>The compiler works well enough on a basic level to build things with it, but some error messages
|
||||
could use significant improvement, and it has a lot of known bugs and missing features. You can
|
||||
currently use it on macOS (either Intel or Apple Silicon), Linux (only x86 machines at the moment),
|
||||
and Windows (only recently supported; there are definitely still a number of issues to iron out).
|
||||
Support for other operating systems has not yet been discussed.</p>
|
||||
|
||||
<p>In the future, the entire Roc toolset should work completely as a standalone binary, but for now,
|
||||
application development requires additionally having some combination of
|
||||
<a href="https://clang.llvm.org">clang</a>,
|
||||
<a href="https://www.rust-lang.org/">Rust</a>, and
|
||||
<a href="https://ziglang.org">Zig</a> installed on your machine. These are needed to compile
|
||||
certain platform dependencies on the fly; in the future, the plan is to have the package manager
|
||||
include precompiled target-specific binaries for these dependencies, so the only binary you'll need
|
||||
to have is the one that includes the Roc compiler itself.</p>
|
||||
currently use it on macOS (either Intel or Apple Silicon), Linux (only x86-64 machines at the moment),
|
||||
and Windows (only recently supported; debugging and testing features don't work on it yet, and
|
||||
there are likely bugs we haven't encountered yet due to lack of battle testing). Support for other
|
||||
operating systems has not yet been discussed.</p>
|
||||
|
||||
<p>The compiler doesn't yet support incremental compilation or hot code loading, and build times vary
|
||||
based on what machine you're building for.</p>
|
||||
|
@ -220,12 +211,13 @@ longer to run than generating unoptimized machine code directly.)</p>
|
|||
ways to go, but improving them can be done by anyone with the patience to read some documentation;
|
||||
we have issues split up for them, and are happy to help new contributors get up and running!</p>
|
||||
|
||||
<p>Builds on x86 Linux also use Roc's surgical linker instead of the system linker, which runs so
|
||||
fast that linking essentially disappears from the performance profile altogether. The surgical linker
|
||||
currently only works on x86 Linux. Work has started on the Windows and macOS implementations, but
|
||||
these have been more challenging in large part because up-to-date public documentation for macOS's
|
||||
Mach-O file format is hard to find. If you're interested in working on that, please get in touch on
|
||||
<a href="https://roc.zulipchat.com/">Roc Zulip</a>!</p>
|
||||
<p>Builds on Linux and Windows also use Roc's surgical linker instead of the system linker, which
|
||||
runs so fast that linking essentially disappears from the performance profile altogether. The
|
||||
surgical linker currently only works on Linux and Windows, and it currently supports building
|
||||
executables but not (yet) dynamic libraries, which is relevant if you're using Roc to create
|
||||
plugins or want to call Roc functions from existing code bases in other languages. Work has started
|
||||
on macOS surgical linking, but it isn't usable yet. If you're interested in working on that,
|
||||
please get in touch on <a href="https://roc.zulipchat.com/">Roc Zulip</a>!</p>
|
||||
|
||||
<p>The test runner currently has first-class support for running standard non-effectful tests.
|
||||
It does not yet have first-class support for effectful tests, property-based tests, snapshot tests,
|
||||
|
|
|
@ -175,13 +175,17 @@ to use them for more than that.</p>
|
|||
<p>Let's move out of the REPL and create our first Roc application!</p>
|
||||
<p>Make a file named <code>main.roc</code> and put this in it:</p>
|
||||
<samp><span class="kw">app</span> <span class="str">"hello"</span>
|
||||
<span class="kw">packages</span> <span class="brace">{</span> pf: <span class="str">"https://roc-lang.org/basic-cli/1.0.0/oUkxSOI9zFGtSoIaMB40QPdrXphr1p1780eiui2iO9Mz.rp1"</span> <span class="brace">}</span>
|
||||
<span class="kw">packages</span> <span class="brace">{</span> pf: <span class="str">"examples/cli/cli-platform/main.roc"</span> <span class="brace">}</span>
|
||||
<span class="kw">imports</span> <span class="brace">[</span>pf.Stdout<span class="brace">]</span>
|
||||
<span class="kw">provides</span> <span class="brace">[</span>main<span class="brace">]</span> <span class="kw">to</span> pf
|
||||
|
||||
main <span class="kw">=</span>
|
||||
Stdout.line <span class="str">"I'm a Roc application!"</span>
|
||||
</samp>
|
||||
<p>In order to get access to this <code>examples/cli/cli-platform/main.roc</code> file, you'll need
|
||||
to download the <a href="https://github.com/roc-lang/roc">Roc source code repository</a>, which
|
||||
contains the <code>examples</code> directory at the beginning of that string. Make sure you <code>cd</code>
|
||||
into that directory once you've downloaded it!</p>
|
||||
<p>Try running this with:</p>
|
||||
<samp>roc dev</samp>
|
||||
<p>You should see this printed to the terminal:</p>
|
||||
|
@ -198,7 +202,6 @@ total <span class="kw">=</span> Num.toStr <span class="paren">(</span>birds <spa
|
|||
|
||||
main <span class="kw">=</span>
|
||||
Stdout.line <span class="str">"There are <span class="str-esc">\(</span><span class="str-interp">total</span><span class="str-esc">)</span> animals."</span>
|
||||
<span class="kw">|></span> Program.quick
|
||||
</samp>
|
||||
<p>Now if you run <code>roc dev</code>, you should see this:</p>
|
||||
<samp>There are 5 animals.</samp>
|
||||
|
@ -232,7 +235,6 @@ total <span class="kw">=</span> Num.toStr <span class="paren">(</span>birds <spa
|
|||
|
||||
main <span class="kw">=</span>
|
||||
Stdout.line <span class="str">"There are <span class="str-esc">\(</span><span class="str-interp">total</span><span class="str-esc">)</span> animals."</span>
|
||||
<span class="kw">|></span> Program.quick</span>
|
||||
|
||||
addAndStringify <span class="kw">= \</span>num1<span class="kw">,</span> num2 <span class="kw">-></span>
|
||||
Num.toStr <span class="paren">(</span>num1 <span class="op">+</span> num2<span class="paren">)</span>
|
||||
|
@ -320,9 +322,9 @@ a concise tag like <code>T</code>:
|
|||
<samp><span class="kw">dbg</span> T "the value of `count` is:" count</samp>
|
||||
</section>
|
||||
<p>Note that <code>dbg</code> is a debugging tool, and is only available when running
|
||||
your program via <code>roc dev</code>, <code>roc run</code>, or <code>roc test</code>. When you
|
||||
build a standalone application with <code>roc build</code>, any uses of <code>dbg</code> won't
|
||||
be included!</p>
|
||||
your program via a <code>roc</code> subcommand (for example using <code>roc dev</code>,
|
||||
<code>roc run</code>, or <code>roc test</code>). When you build a standalone application with
|
||||
<code>roc build</code>, any uses of <code>dbg</code> won't be included!</p>
|
||||
<section><h2 id="records"><a href="#records">Records</a></h2>
|
||||
<p>Currently our <code>addAndStringify</code> function takes two arguments. We can instead make
|
||||
it take one argument like so:</p>
|
||||
|
@ -1230,7 +1232,7 @@ Roc compiler. That's why they're called "builtins!"</p>
|
|||
<p>Let's take a closer look at the part of <code>main.roc</code> above the <code>main</code> def:</p>
|
||||
<samp><span class="hljs-selector-tag">app</span> "<span class="hljs-selector-tag">hello</span>"
|
||||
<span class="hljs-selector-tag">packages</span> { <span class="attribute">pf</span>: <span class="str">"examples/cli/cli-platform/main.roc"</span> }
|
||||
<span class="hljs-selector-tag">imports</span> <span class="hljs-selector-attr">[pf.Stdout, pf.Program]</span>
|
||||
<span class="hljs-selector-tag">imports</span> <span class="hljs-selector-attr">[pf.Stdout]</span>
|
||||
<span class="hljs-selector-tag">provides</span> <span class="hljs-selector-tag">main</span> <span class="hljs-selector-tag">to</span> <span class="hljs-selector-tag">pf</span>
|
||||
</samp>
|
||||
<p>This is known as a <em>module header</em>. Every <code>.roc</code> file is a <em>module</em>, and there
|
||||
|
@ -1243,7 +1245,7 @@ named <code>hello</code> (or <code>hello.exe</code> on Windows) and run it. You
|
|||
without running it by running <code>roc build</code>.</p>
|
||||
<p>The remaining lines all involve the <em>platform</em> this application is built on:</p>
|
||||
<samp><span class="hljs-selector-tag">packages</span> { <span class="attribute">pf</span>: <span class="str">"examples/cli/cli-platform/main.roc"</span> }
|
||||
<span class="hljs-selector-tag">imports</span> <span class="hljs-selector-attr">[pf.Stdout, pf.Program]</span>
|
||||
<span class="hljs-selector-tag">imports</span> <span class="hljs-selector-attr">[pf.Stdout]</span>
|
||||
<span class="hljs-selector-tag">provides</span> <span class="hljs-selector-tag">main</span> <span class="hljs-selector-tag">to</span> <span class="hljs-selector-tag">pf</span>
|
||||
</samp>
|
||||
<p>The <code>packages { pf: "examples/cli/cli-platform/main.roc" }</code> part says two things:</p>
|
||||
|
@ -1251,19 +1253,17 @@ without running it by running <code>roc build</code>.</p>
|
|||
<li>We're going to be using a <em>package</em> (that is, a collection of modules) called <code>"examples/cli/cli-platform/main.roc"</code></li>
|
||||
<li>We're going to name that package <code>pf</code> so we can refer to it more concisely in the future.</li>
|
||||
</ul>
|
||||
<p>The <code>imports [pf.Stdout, pf.Program]</code> line says that we want to import the <code>Stdout</code> and <code>Program</code> modules
|
||||
from the <code>pf</code> package, and make them available in the current module.</p>
|
||||
<p>The <code>imports [pf.Stdout]</code> line says that we want to import the <code>Stdout</code> module
|
||||
from the <code>pf</code> package, and make it available in the current module.</p>
|
||||
<p>This import has a direct interaction with our definition of <code>main</code>. Let's look
|
||||
at that again:</p>
|
||||
<samp><span class="attr">main</span> <span class="op">=</span> Stdout.line <span class="str">"I'm a Roc application!"</span> |> Program.quick
|
||||
<samp><span class="attr">main</span> <span class="op">=</span> Stdout.line <span class="str">"I'm a Roc application!"</span>
|
||||
</samp>
|
||||
<p>Here, <code>main</code> is calling a function called <code>Stdout.line</code>. More specifically, it's
|
||||
calling a function named <code>line</code> which is exposed by a module named
|
||||
<code>Stdout</code>.
|
||||
Then the result of that function call is passed to the <code>quick</code> function of the <code>Program</code> module,
|
||||
which effectively makes it a simple Roc program.</p>
|
||||
<p>When we write <code>imports [pf.Stdout, pf.Program]</code>, it specifies that the <code>Stdout</code>
|
||||
and <code>Program</code> modules come from the <code>pf</code> package.</p>
|
||||
<p>When we write <code>imports [pf.Stdout]</code>, it specifies that the <code>Stdout</code>
|
||||
module comes from the <code>pf</code> package.</p>
|
||||
<p>Since <code>pf</code> was the name we chose for the <code>examples/cli/cli-platform/main.roc</code>
|
||||
package (when we wrote <code>packages { pf: "examples/cli/cli-platform/main.roc" }</code>),
|
||||
this <code>imports</code> line tells the Roc compiler that when we call <code>Stdout.line</code>, it
|
||||
|
@ -1271,7 +1271,7 @@ should look for that <code>line</code> function in the <code>Stdout</code> modul
|
|||
<code>examples/cli/cli-platform/main.roc</code> package.</p>
|
||||
<p>If we would like to include other modules in our application, say <code>AdditionalModule.roc</code> and <code>AnotherModule.roc</code>, then they can be imported directly in <code>imports</code> like this: </p>
|
||||
<samp><span class="hljs-selector-tag">packages</span> { <span class="attribute">pf</span>: <span class="str">"examples/cli/cli-platform/main.roc"</span> }
|
||||
<span class="hljs-selector-tag">imports</span> <span class="hljs-selector-attr">[pf.Stdout, pf.Program, AdditionalModule, AnotherModule]</span>
|
||||
<span class="hljs-selector-tag">imports</span> <span class="hljs-selector-attr">[pf.Stdout, AdditionalModule, AnotherModule]</span>
|
||||
<span class="hljs-selector-tag">provides</span> <span class="hljs-selector-tag">main</span> <span class="hljs-selector-tag">to</span> <span class="hljs-selector-tag">pf</span>
|
||||
</samp>
|
||||
<h2 id="comments"><a href="#comments">Comments</a></h2>
|
||||
|
@ -1301,12 +1301,11 @@ platforms. Let's use the CLI platform in <code>examples/cli/cli-platform/main.ro
|
|||
<p>First, let's do a basic "Hello World" using the tutorial app.</p>
|
||||
<samp><span class="kw">app</span> <span class="str">"cli-tutorial"</span>
|
||||
packages { pf: <span class="str">"examples/cli/cli-platform/main.roc"</span> }
|
||||
imports [pf.Stdout, pf.<span class="kw">Program</span>]
|
||||
imports [pf.Stdout]
|
||||
provides [main] to pf
|
||||
|
||||
main <span class="op">=</span>
|
||||
Stdout.<span class="kw">line</span> <span class="str">"Hello, World!"</span>
|
||||
|> <span class="kw">Program</span>.quick
|
||||
</samp>
|
||||
<p>The <code>Stdout.line</code> function takes a <code>Str</code> and writes it to <a href="https://en.wikipedia.org/wiki/Standard_streams#Standard_output_(stdout">standard output</a>).
|
||||
It has this type:</p>
|
||||
|
@ -1327,12 +1326,10 @@ when it runs (hence the <code>*</code>).</p>
|
|||
<p>Let's change <code>main</code> to read a line from <code>stdin</code>, and then print it back out again:</p>
|
||||
<samp>app <span class="str">"cli-tutorial"</span>
|
||||
packages { pf: <span class="str">"examples/cli/cli-platform/main.roc"</span> }
|
||||
imports [pf.Stdout, pf.Stdin, pf.Task, pf.Program]
|
||||
imports [pf.Stdout, pf.Stdin, pf.Task]
|
||||
provides [main] to pf
|
||||
|
||||
main <span class="op">=</span> Program.quick task
|
||||
|
||||
task <span class="op">=</span>
|
||||
main <span class="op">=</span>
|
||||
Task.await Stdin.line \text <span class="op">-></span>
|
||||
Stdout.line <span class="str">"You just entered: \(text)"</span>
|
||||
</samp>
|
||||
|
@ -1364,12 +1361,10 @@ the program isn't doing anything when we start it up:</p>
|
|||
<p>This works, but we can make it a little nicer to read. Let's change it to the following:</p>
|
||||
<samp>app <span class="str">"cli-tutorial"</span>
|
||||
packages { pf: <span class="str">"examples/cli/cli-platform/main.roc"</span> }
|
||||
imports [pf.Stdout, pf.Stdin, pf.Task.{ await }, pf.Program]
|
||||
imports [pf.Stdout, pf.Stdin, pf.Task.{ await }]
|
||||
provides [main] to pf
|
||||
|
||||
main <span class="op">=</span> Program.quick task
|
||||
|
||||
task <span class="op">=</span>
|
||||
main <span class="op">=</span>
|
||||
await (Stdout.line <span class="str">"Type something press Enter:"</span>) \_ <span class="op">-></span>
|
||||
await Stdin.line \text <span class="op">-></span>
|
||||
Stdout.line <span class="str">"You just entered: \(text)"</span>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue