~sircmpwn/harelang.org

c406649d14b7d9fc70c5113e7149d10530fb31a2 — Drew DeVault 3 months ago ab23cac
Docs overhaul
20 files changed, 84 insertions(+), 1493 deletions(-)

M assets/main.scss
M content/_index.html
D content/conduct.md
D content/developers.md
D content/distributions.md
D content/documentation.md
D content/editors.md
D content/evangelism.md
D content/extended.md
D content/floppies.md
D content/i18n.md
D content/installation.md
D content/platforms.md
D content/roadmap.md
A content/sample.ha
D content/style.md
D content/tools.md
M content/tutorial.md
M layouts/index.html
M layouts/partials/nav.html
M assets/main.scss => assets/main.scss +12 -0
@@ 67,6 67,18 @@ main {
  }
}

.inline-header {
  margin-top: 2rem;

  h3 {
    margin-top: 0;
  }

  p {
    margin-bottom: 0;
  }
}

footer {
  padding-top: 64px;
  text-align: center;

M content/_index.html => content/_index.html +1 -58
@@ 1,61 1,4 @@
---
title: The Hare programming language
# Note: file contents are in layout/index.html
---

<p class="alert">
  <strong>Notice:</strong>
  Hare is a work in progress! It may be mature enough to support your use-case,
  but there may also be some breaking changes between releases. Users are
  strongly encouraged to subscribe to
  <a href="https://lists.sr.ht/~sircmpwn/hare-announce">hare-announce</a>
  for details of breaking changes in each release.
</p>

<p>
Hare is a systems programming language designed to be simple, stable, and
robust. Hare uses a static type system, manual memory management, and a
minimal runtime. It is well-suited to writing operating systems, system tools,
compilers, networking software, and other low-level, high performance tasks.

{{< highlight hare >}}
use fmt;

export fn main() void = {
	const greetings = [
		"Hello, world!",
		"¡Hola Mundo!",
		"Γειά σου Κόσμε!",
		"Привіт, світ!",
		"こんにちは世界!",
	];
	for (let i = 0z; i < len(greetings); i += 1) {
		fmt::println(greetings[i])!;
	};
};{{< / highlight >}}

<h2>Getting started</h2>
<p>
Read the <a href="/installation">installation steps</a> to get Hare for your
system, then read the <a href="/tutorial">tutorial</a>. To see if Hare is
available for your system, consult the
<a href="/platforms">supported platforms list</a>.

<h2>Who's behind Hare?</h2>

<p>
<a href="/who">Ten maintainers and about a hundred contributors</a>.

<h2>Supporting Hare</h2>

<p>
<!--
Font Awesome Free 5.3.1 by @fontawesome - https://fontawesome.com
License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
-->
<svg style="position: relative; top: 1px" width="14" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><path fill="currentColor" d="M433.941 129.941l-83.882-83.882A48 48 0 0 0 316.118 32H48C21.49 32 0 53.49 0 80v352c0 26.51 21.49 48 48 48h352c26.51 0 48-21.49 48-48V163.882a48 48 0 0 0-14.059-33.941zM272 80v80H144V80h128zm122 352H54a6 6 0 0 1-6-6V86a6 6 0 0 1 6-6h42v104c0 13.255 10.745 24 24 24h176c13.255 0 24-10.745 24-24V83.882l78.243 78.243a6 6 0 0 1 1.757 4.243V426a6 6 0 0 1-6 6zM224 232c-48.523 0-88 39.477-88 88s39.477 88 88 88 88-39.477 88-88-39.477-88-88-88zm0 128c-22.056 0-40-17.944-40-40s17.944-40 40-40 40 17.944 40 40-17.944 40-40 40z" class=""></path></svg>
Hare fits on a 3½" floppy disc, which are
<a href="/floppies">available for purchase</a>.

<p>
We also have an <a href="https://opencollective.com/hare">Open Collective</a>
for donations and commercial sponsorships.

D content/conduct.md => content/conduct.md +0 -167
@@ 1,167 0,0 @@
---
title: Hare code of conduct
---

# Contributor Covenant Code of Conduct

## Our Pledge

We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of traits
including but not limited to age, body size, visible or invisible disability,
ethnicity, sex characteristics, gender identity and expression, level of
experience, education, socio-economic status, nationality, personal appearance,
race, caste, color, religion, or sexual identity and orientation.

We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.

## Our Standards

Examples of behavior that contributes to a positive environment for our
community include:

* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
  and learning from the experience
* Focusing on what is best not just for us as individuals, but for the overall
  community
* Acting with patience, humility, and understanding when helping others, in
  particular less technically experienced members of the community

Examples of unacceptable behavior include:

* The use of sexualized language or imagery, and sexual attention or advances of
  any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as their personal address,
  without their explicit permission
* Belittling the views of others using coercion or personal attacks
* Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Enforcement Responsibilities

The conduct enforcement team is responsible for clarifying and enforcing our
standards of acceptable behavior and will take appropriate and fair corrective
action in response to any behavior that they deem inappropriate, threatening,
offensive, or harmful.

Community leaders, including maintainers outside of the conduct enforcement
team, have the right and responsibility to remove, edit, or reject comments,
commits, code, wiki edits, issues, and other contributions that are not aligned
to this Code of Conduct, and will communicate reasons for moderation decisions
when appropriate. Should a maintainer make a discretionary choice with respect
to moderation in the absence of feedback from the conduct enforcement team, the
individuals involved may petition the conduct enforcement team for an
alternative resolution.

Community members are welcome and encouraged to participate in discussions
regarding the code of conduct and its enforcement, and to suggest clarifications
or modifications to the code of conduct, particularly with respect to addressing
ways in which it is lacking sufficient policy and language to make them feel
included and welcome in the community.

## Scope

This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.

Egregious violations of our cultural norms, such as displays of intolerance,
harassment, or other egregiously inappropriate behavior outside of our community
spaces may result in enforcement action within the Hare community, in the
interest of providing a safe space for participants who may be threatened by
individuals who engage in inappropriate conduct beyond our borders.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at the [Hare
conduct mailing list][mailing list]. The leadership responsible for conduct
enforcement may also be reached individually if the complainant so desires:

[mailing list]: mailto:~sircmpwn/hare-conduct@lists.sr.ht

* Drew DeVault <sir@cmpwn.com>
* Ember Sawady <ecs@d2evs.net>
* Vlad-Stefan Harbuz <vlad@vladh.net>

All complaints will be reviewed and investigated promptly and fairly.

All community leaders are obligated to respect the privacy and security of the
reporter of any incident. Reports are kept in confidence and will not be made
publicly available or shared outside of the conduct enforcement team, unless the
reporter explicitly permits this upon request.

## Enforcement Guidelines

The conduct enforcement team will follow these Community Impact Guidelines in
determining the consequences for any action they deem in violation of this Code
of Conduct:

### 1. Correction

**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.

**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.

### 2. Warning

**Community Impact**: A violation through a single incident or series of
actions.

**Consequence**: A formal warning with the understanding that any continuation
or escalation of problematic behaviors will lead to further action from the
enforcement team. No interaction with the people involved, including unsolicited
interaction with those enforcing the Code of Conduct, is permitted for a
specified period of time. This includes avoiding interactions in community
spaces as well as external channels like social media. Violating these terms may
lead to a temporary or permanent ban.

### 3. Temporary Ban

**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.

**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.

### 4. Permanent Ban

**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.

**Consequence**: A permanent ban from any sort of public interaction within the
community.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.1, available at
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].

Community Impact Guidelines were inspired by
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].

For answers to common questions about this code of conduct, see the FAQ at
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
[https://www.contributor-covenant.org/translations][translations].

[homepage]: https://www.contributor-covenant.org
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
[Mozilla CoC]: https://github.com/mozilla/diversity
[FAQ]: https://www.contributor-covenant.org/faq
[translations]: https://www.contributor-covenant.org/translations

D content/developers.md => content/developers.md +0 -18
@@ 1,18 0,0 @@
---
title: Resources for developers working on Hare
---

## Development hosts

List of hosts available for Hare development:

- arm64: 200:79e8:976b:8f25:12:e0b2:c00b:4be0 rin
- riscv64: 201:30cb:8913:27b5:7aeb:4593:af70:76c1 kobayashi (only online by request)
- ppc64le: 173.195.146.246 flandre.sr.ht (public internet, non-yggdrasil)
- i686: 200:93b0:ee2:7810:26b0:ea7:ec13:8df9 aoba
- armv6l: 200:aaed:45d7:1b89:7386:d46:293:ab3 hifumi

All hosts are available via [yggdrasil] and are running Linux. Reach out to Drew
DeVault <sir@cmpwn.com> to request a shell account.

[yggdrasil]: https://yggdrasil-network.github.io

D content/distributions.md => content/distributions.md +0 -59
@@ 1,59 0,0 @@
---
title: Hare Installation for Distributions
---

Hare depends on a POSIX-compatible C11 environment, and our compiler backend,
[qbe]. To provide the minimum level of support for Hare, you need qbe, [harec],
and [hare] packages.

[qbe]: https://c9x.me/compile/
[harec]: https://git.sr.ht/~sircmpwn/harec
[hare]: https://git.sr.ht/~sircmpwn/hare

Your distro's packages are our preferred means for users to install Hare and
programs written in Hare. Your support is important to us. Please visit our [IRC
channel] if you have any questions or concerns.

[IRC channel]: irc://irc.libera.chat/#hare

## Hare installation layout

Assuming a typical Unix filesystem layout (you can configure this in config.mk
if you need something different), Hare expects to be installed in the following
places:

- `/usr/bin/hare`: The Hare build driver
- `/usr/bin/harec`: The Hare compiler
- `/usr/bin/haredoc`: The Hare documentation tool
- `/usr/src/hare/stdlib`: The standard library source code
- `/usr/src/hare/third-party`: Third-party library source code

The source code for Hare dependencies must be present to build Hare packages or
read their documentation.

## Timekeeping requirements

Hare's timekeeping support in the standard library relies on a local
installation of the IANA time zone database. **Important**: Hare uses the local
leap second list as well, at `/usr/share/zoneinfo/leap-seconds.list` by default,
which is often not installed by many distributions. Please update your tzdata
package accordingly when packaging Hare.

## Customizing Hare builds

The build driver chooses its linker and such via the LD, AS, and similar
environment variables, and also supports setting flags for each via LDLINKFLAGS et
al.

Hare programs are statically linked. We know you're not a fan of this. We're
sorry.

## Linking to native dependencies

This is supported via the -l flag, which is passed to the linker. This is not
currently done very well. We have plans to replace it with something better,
more customizable, and based on pkg-config, but it has not yet been done.

## Was your question not answered?

Ask us on IRC and we'll add a section here.

D content/documentation.md => content/documentation.md +0 -60
@@ 1,60 0,0 @@
---
title: Hare Documentation
---

Hare ships with man pages for its commands. Run `man hare` to get started.

## Hare tutorials

A number of tutorials are available introducing users to various Hare concepts.

<a href="/tutorial" class="tutorial-link">Hare tutorials</a>

## Standard library reference documentation

The reference documentation is available in your terminal (see haredoc(1) for
details), or online:

<a href="https://docs.harelang.org" class="tutorial-link">Reference documentation</a>

## Hare extended support libraries

The extended support libraries provide official support for use-cases which
fall outside of the standard library mandate, but are nevertheless declared
important or useful for the community.

<a href="/extended" class="tutorial-link">Hare extended support libraries</a>

## Notes on third-party tools and Hare

A guide to debugging, profiling, linking, and more:

<a href="/tools" class="tutorial-link">Notes on third-party tools and Hare</a>

## Language specification

The language specification is available here:

<a href="/specification" class="tutorial-link">Hare specification</a>

## Installation procedure

The Hare installation procedure is provided here:

<a href="/installation" class="tutorial-link">Installing Hare</a>

Instructions are also available for distribution package maintainers:

<a href="/distributions" class="tutorial-link">Hare installation for distributions</a>

## Hare style guide

The style guide defines the canonical coding style for Hare programs:

<a href="/style" class="tutorial-link">Hare style guide</a>

## Hare developer resources

Resources for developers working on Hare itself:

<a href="/developers" class="tutorial-link">Hare developer resources</a>

D content/editors.md => content/editors.md +0 -18
@@ 1,18 0,0 @@
---
title: Editor integrations
---

- Emacs: [hare-mode](https://git.sr.ht/~bbuccianti/hare-mode)
- Vim: [hare.vim](https://git.sr.ht/~sircmpwn/hare.vim)
  - [vim-haredoc](https://git.sr.ht/~torresjrjr/vim-haredoc)
- Vis: [hare.lua](https://git.d2evs.net/~ecs/hare.lua)
- Kakoune: [hare.kak](https://git.sr.ht/~c7s/hare.kak)
- Tree-sitter: [tree-sitter-hare](https://git.d2evs.net/~ecs/tree-sitter-hare)
- VS Code (TmLanguage): [vscode-hare](https://codeberg.org/wackbyte/vscode-hare)
- Nano: [nano-hare](https://git.sr.ht/~lmarz/nano-hare)
- LSP: TODO
- IntelliJ: [harelang-intellij-plugin](https://plugins.jetbrains.com/plugin/19131-harelang)
- Sublime: [hare-highlight](https://github.com/artursartamonovs/hare-highlight)
- Kate: [hare.xml](https://kate-editor.org/syntax/data/syntax/hare.xml)

Hare programs use 8-column wide hard tabs.

D content/evangelism.md => content/evangelism.md +0 -64
@@ 1,64 0,0 @@
---
title: Hare evangelism
---

The success of Hare is dependent on having a thriving community of people
working on Hare, using Hare to build cool things, helping each other, and
developing and maintaining a vibrant ecosystem of tools, libraries, and
other resources. To this end, it's necessary to evangelise Hare a bit, to grow
the ecosystem and attract the interest of people who might like it.

Much like all other goals for Hare, the community is encouraged to contribute by
participating in these efforts. Bringing attention to Hare is a great (and often
under-appreciated) way to contribute to the project.

## Good ideas

These are some good ways to evangelise Hare:

- Publishing content about Hare
  - Write for your personal blog, videos, podcasts, etc
  - Your experiences using Hare and thoughts on the language
  - Write-ups about your Hare projects and contributions
  - Tutorials on Hare libraries or language features[^1]
  - Thoughts on interesting problems you encountered with Hare
- Writing blog posts for harelang.org
  - Outlining discussions from Hare RFCs
  - Design notes about standard library modules
  - Design notes about the compiler or language features
  - etc
- Signal-boosting cool projects written in Hare
- Helping Hare users find interested collaborators
- Participating in (organic!) online discussions about Hare on forums, Mastodon,
  HN, etc
- Participating in industry events (e.g. Advent of Code) with Hare and writing
  about your experience
- Talking about Hare at in-person events and conferences

The [hare-evangelism][0] mailing list has been set up to discuss the broader
promotion of Hare. This is a great place to seek feedback on an idea, propose
topics for blog posts, draw attention to notable projects, or seek editoral
feedback on your writing. This is also where you should go if you, random
internet user, find yourself thinking "wow these Hare users are annoying shills"
so that we can talk about that.

[0]: https://lists.sr.ht/~sircmpwn/hare-evangelism

[^1]: Be careful not to abandon tutorials to bitrot &mdash; consider updating
    them as the language develops and they become outdated, or linking to
    official (maintained) resources on the subject where possible.

## Bad ideas

The following kinds of marketing activities are explicitly discouraged:

- Paid advertising of any kind; sponsorships, banner ads, etc
- Unsolicited calls for FOSS projects to write/rewrite their code in Hare
- Putting down other programming languages or projects because Hare is "better"

When discussing Hare outside of Hare community spaces, the Hare [Code of
Conduct][1] is not necessarily in effect. Nevertheless, you are strongly
encouraged to behave as if it was, and to speak with kindness and empathy
&mdash; don't get into flamewars!

[1]: /conduct

D content/extended.md => content/extended.md +0 -36
@@ 1,36 0,0 @@
---
title: Hare extended support libraries
---

A number of additional libraries are available for Hare outside of the standard
library via the Hare extended libraries collection. These are officially
maintained by Hare upstream, but have a wider mandate than the standard library.
This includes extended support for noteworthy operating systems, third-party
applications and standards, and other libraries which are important but do not
fit within the standard library mandate.

These modules have less stringent requirements for portability, stability, and
completeness compared to the standard library.

## Algorithms

- [hare-compress](https://git.sr.ht/~sircmpwn/hare-compress): Compression
  algorithms for Hare

## Databases

- [hare-redis](https://git.sr.ht/~sircmpwn/hare-redis): Redis support for Hare

## Formats

- [hare-json](https://sr.ht/~sircmpwn/hare-json): JSON support for Hare
- [hare-xml](https://git.sr.ht/~sircmpwn/hare-xml): XML support for Hare

## Graphics

- [hare-png](https://git.sr.ht/~sircmpwn/hare-png): PNG support for Hare

## Operating systems

- [hare-linux](https://git.sr.ht/~sircmpwn/hare-linux): Extended support for
  Linux

D content/floppies.md => content/floppies.md +0 -8
@@ 1,8 0,0 @@
---
title: 3½" Floppy Disc Distribution
---

Hare fits on a 3½" floppy disc. When it's done, you'll be able to buy a floppy
disc with Hare on it to support the project.

![A picture of a floppy disc with Hare on it](/floppy.jpg)

D content/i18n.md => content/i18n.md +0 -5
@@ 1,5 0,0 @@
---
title: Internationalization recommendations for Hare programs
---

TODO: Write me

D content/installation.md => content/installation.md +0 -55
@@ 1,55 0,0 @@
---
title: Hare Installation
---

Additional resources:

- [Editor plugins](/editors)
- [Hare tutorials](/tutorial)
- [Information for package maintainers](/distributions)

### Installing from packages

Installing Hare from your distribution's package manager is the recommended
approach. The suggested name for the Hare package is "hare", but your package
manager may differ.

If you add Hare to your distribution, please [let us know][0] so we can add
yours to this list. Instructions for package maintainers [are available
here](/distributions).

[0]: mailto:~sircmpwn/hare-dev@lists.sr.ht

Hare is young, so packages are not yet available for many distributions. If
yours is unsupported, continue to the bootstrapping steps.

### Bootstrapping Hare from source

Bootstrapping Hare only takes a few minutes.

#### Step 0: Pre-requisites

- A POSIX-compatible environment with a C11 compiler
- [QBE](https://c9x.me/compile/) (the latest version on the git `master` branch,
  not the latest versioned release)
- [scdoc](https://sr.ht/~sircmpwn/scdoc)

#### Step 1: Building the bootstrap compiler

1. Obtain [the bootstrap compiler source code](https://git.sr.ht/~sircmpwn/harec)
2. `cp configs/<platform>.mk config.mk`
3. `make`

Optionally run `make check` to compile and run the test suite as well, then run
`make install` as root to install it to your system.

#### Step 2: Building the build driver & standard library

1. Obtain [the build driver source code](https://git.sr.ht/~sircmpwn/hare)
2. Copy `configs/<platform>.mk` to `config.mk` and edit to taste
3. Run `make`

<!-- TODO: make stage-2 -->

Optionally run `make check` to build & run the standard library test suite as
well, then run `make install` as root to install it to your system.

D content/platforms.md => content/platforms.md +0 -97
@@ 1,97 0,0 @@
---
title: Supported platforms
---

Hare (will) support a variety of platforms. Adding new (Unix-like) platforms and
architectures is relatively straightforward.

Hare does not, and will not, support any proprietary operating systems.

## Architectures

<table>
  <thead>
    <tr>
      <th>Architecture</th>
      <th>Support status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>x86_64</td>
      <td><span class="yes">✓</span> Supported</td>
    </tr>
    <tr>
      <td>aarch64</td>
      <td><span class="yes">✓</span> Supported</td>
    </tr>
    <tr>
      <td>riscv64</td>
      <td><span class="yes">✓</span> Supported</td>
    </tr>
    <tr>
      <td>ppc64le</td>
      <td><span class="todo">…</span> Planned</td>
    </tr>
    <tr>
      <td>i686</td>
      <td><span class="todo">…</span> Planned</td>
    </tr>
    <tr>
      <td>arm32</td>
      <td><span class="todo">…</span> Planned</td>
    </tr>
  </tbody>
</table>

## Operating systems

<table>
  <thead>
    <tr>
      <th>Operating system</th>
      <th>Support status</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Linux</td>
      <td><span class="yes">✓</span> Supported</td>
    </tr>
    <tr>
      <td>FreeBSD</td>
      <td><span class="yes">✓</span> Supported</td>
    </tr>
    <tr>
      <td>OpenBSD</td>
      <td><span class="yes">✓</span> Supported</td>
    </tr>
    <tr>
      <td>NetBSD</td>
      <td><span class="todo">…</span> In progress</td>
    </tr>
    <tr>
      <td>Illumos</td>
      <td><span class="todo">…</span> Planned</td>
    </tr>
    <tr>
      <td>Haiku</td>
      <td><span class="todo">…</span> Planned</td>
    </tr>
    <tr>
      <td>Plan 9</td>
      <td><span class="todo">…</span> Planned</td>
    </tr>
  </tbody>
</table>

Hare can also run on the bare metal, without a host operating system.

## Third-party support

Third parties may provide support for additional platforms. These ports are not
supported by Hare upstream. Do not file tickets, write to the mailing lists, or
ask questions on IRC related to these ports; see each port's own resources for
support.

- [macOS](https://github.com/hshq/harelang)

D content/roadmap.md => content/roadmap.md +0 -55
@@ 1,55 0,0 @@
---
title: Hare roadmap
---

Hare is a work-in-progress. The following goals are prioritized.

## Stability

The scope of the language and standard library are essentially fixed. Once
complete, we will release 1.0 and thenceforth make only minor improvements, bug
fixes, and add new supported platforms. Once all of these goals are met, Hare
will be "done".

## Language design

- Matching against pointers to tagged unions
- Match exhaustivity analysis
- Improvements to mutability semantics
- More robust memory handling for error scenarios
- More robust error handling for OOM scenarios
- Linear types research

## Standard library

- Cryptography: TLS support
- Raw IP sockets

## Extended library

- Graphics (image support, pixel format conversions, vector drawing)
- Mail support (envelope parser, net::smtp, etc)
- SQL (generic interface + dialect drivers)
- net::http

## Tooling

- Better +libc support
- hare.ini

## Ports

- 32-bit: i486 family, 32-bit ARM, riscv32
- PowerPC (incl. big endian)
- MIPS
- NetBSD
- Illumos
- Haiku
- Plan 9
- What are you going to port Hare to?

## Specification

- Needs review, editing, and consensus.
- 8- and 16-bit sub-specification
- ABI specification

A content/sample.ha => content/sample.ha +14 -0
@@ 0,0 1,14 @@
use fmt;

export fn main() void = {
	const greetings = [
		"Hello, world!",
		"¡Hola Mundo!",
		"Γειά σου Κόσμε!",
		"Привіт, світ!",
		"こんにちは世界!",
	];
	for (let i = 0z; i < len(greetings); i += 1) {
		fmt::println(greetings[i])!;
	};
};

D content/style.md => content/style.md +0 -750
@@ 1,750 0,0 @@
---
# vim: ts=8 sw=8 noet :
title: Hare programming style guide
layout: with_toc
summary: |
    There are better things to argue about than how your code looks, so Hare
    has a single canonical programming style which is considered correct.
    We, the designers of the Hare programming language, declare the coding
    style declared herein to be correct, and all others to be incorrect.
---


## A. General conventions

These apply generally to constructs found throughout Hare programs.

1. Hare source files MUST be indented with tabs. The tab size SHOULD be 8
   columns.
2. Lines SHOULD be limited to 80 columns in width, unless it would break up an
   error string, which would prevent grepping for errors.
3. When breaking a long line into several, subsequent lines MUST be indented
   once &mdash; and MUST NOT be aligned vertically to align with features on the
   previous line. If the following line would be indented due to the
   introduction of a new block, the continuation line MUST be indented twice to
   visually distinguish it from the block.
4. (*subjective*) When breaking a long line into several, items SHOULD be
   distributed to achieve "balance", such that if a line were drawn down the
   middle of the expression, an approximately equal number of characters would
   fall to either side.
5. The `;` following the end of an expression MUST be placed on the final line
   of that expression with no space between `;` and the last token of that
   expression.
6. All lines MUST NOT end in a whitespace character (space or tab).

**CORRECT**

```hare
let result = frobnicate_the_frobs(scary_frob,
	sporty_frob, baby_frob, ginger_frob, posh_frob);

if (was_frobbed_correctly(frob_context, FROB_RESULT_SUCCESS,
		FROB_STANDARD_IEEE_7553, result)) {
	return true;
};
```

**INCORRECT**

```hare
let result = frobnicate_the_frobs(scary_frob,
				  sporty_frob,
				  baby_frob,
				  ginger_frob,
				  posh_frob);

if (was_frobbed_correctly(frob_context, FROB_RESULT_SUCCESS,
	FROB_STANDARD_IEEE_7553, result)) {
	return true;
};
```

## B. Source file organization

A Hare module is made up of one or more files in a directory.

1. Hare source files SHOULD be named in `lower_underscore_case`, with the `.ha`
   file extension. Their mimetype is `text/x-hare`.
2. Hare source files may be named with only a tag (e.g. `+linux.ha`) if
   appropriate, but MUST NOT be named `.ha`.
3. Each Hare source file MUST list its imports, followed by its declarations,
   with one empty line between them. This empty line MUST NOT be included if
   there are no imports.
4. Use statements MUST be sorted alphabetically.
5. Declarations which require a single line MAY follow one after the other; but
   declarations which require multiple lines MUST be separated by a single
   empty line.

**CORRECT**

```hare
use bar;
use baz;
use foo;

let x: int = 10;
let y: int = 10;

type my_type = struct {
	x: int,
	y: int,
	z: int,
};

fn foobar() void = {
	// ...
};

export fn main() void = {
	// ...
};
```

## C. Function declarations

These rules govern the declaration of Hare functions and function prototypes.

1. The export status, `fn` keyword, name, parameter list, return type, and the
   `=` and `{` tokens, MUST be on the same line if they fit within 80 columns.
2. If these tokens would *not* fit on the same line, the export status, `fn`
   keyword, name, and opening parenthesis of the parameter list MUST be placed
   on the first line; then each parameter placed on subsequent lines, indented
   once; and on their own line, the `)`, return type, `=`, and `{` tokens. In
   this case, the final parameter MUST end with an extra `,` token, unless the
   function is variadic.
3. Prototypes MUST obey the same rules, but will omit the `=` and `{` tokens,
   and MUST place the semi-colon on the final line following the return type.
4. Function bodies MUST be indented once.
5. Functions whose bodies are not an expression list `{ ... }` MAY place their
   bodies on the next line, indented once.

**CORRECT**

```hare
export fn main() void = {
	do_work(1, 2);
};

fn do_work(x: int, y: int) void = {
	// ...
};

fn many_parameters(
	param_one: int,
	param_two: int,
	param_three: int,
	param_four: int,
	param_five: int,
) void = {
	// ...
};

fn many_variadic(
	param_one: int,
	param_two: int,
	param_three: int,
	param_four: int,
	params: int...
) void = {
	// ...
};
```
## D. Type declarations

Rules governing the declarations of types. For details on style for specific
type subclasses, see [Type specifiers](#g-type-specifiers).

1. Spaces MUST be placed between the `type` token, the type name, the `=` token,
   and the type specifier. All of these tokens MUST be on the same line.
2. Type aliases MUST be named in `lower_underscore_case`.

**CORRECT**

```hare
type my_type = int;
```

## E. Constant declarations

Rules governing constant declarations.

1. A space MUST NOT be placed between the constant name and the `:` token. A
   space MUST be placed between the `:` token and the type specifier.
2. Spaces MUST be placed both before and after the `=` token.
3. Constants MUST be named in `UPPER_UNDERSCORE_CASE`.

**CORRECT**

```hare
def MY_CONSTANT: int = 1234;
```

## F. Global declarations

Rules governing global variable declarations. Note that the use of globals is
often undesirable, as may limit your ability to expand upon or compartmentalize
an interface later.

1. A space MUST NOT be placed between the constant name and the `:` token. A
   space MUST be placed between the `:` token and the type specifier.
2. Spaces MUST be placed both before and after the `=` token.

**CORRECT**

```hare
let my_global: int = 1234;
```

## G. Type specifiers

Rules governing the format of types. Not to be confused with the rules governing
[type declarations](#d-type-declarations).

### i. Struct types

1. Structs MUST be defined with a space between the `struct` and `{` tokens.
3. Structs MAY be defined in either single-line or multi-line style.
4. In the multi-line style, a newline MUST follow the `{` token, followed by the
   struct fields indented once, followed by the `}` token without indentation.
   The final field MUST include the optional `,` token in this style.
5. In the single-line style, the `{` token MUST be followed by a space, followed
   by the struct fields (each separated by a space following the `,` token,
   except for the final field, which MUST omit the `,` token), then a space and
   the `}` token.
6. A field name MUST NOT be separated from the `:` token by a space, but a
   space MUST be placed between the `:` token and the field type.
7. Struct fields MAY be grouped by purpose, with each groups separated by a
   single empty line.
8. Within each group of struct fields, fields MAY be alphabetized by name if the
   subsequent impact on the struct's storage representation is not of
   consequence.

**CORRECT**

```hare
struct {
	x: int,
	y: int,
	z: int,

	metadata: struct {
		foo: int,
		bar: int,
		baz: int,
	},
};
```

### ii. Union types

1. Union types are considered equivalent to struct types for matters of
   style, with the `union` token used in place of the `struct` token.

### iii. Array & slice types

1. There MUST NOT be a space between the `[` token, length expression (if
   present), `]` token, and member type.
2. The use of arrays is preferred when possible, as the extra indirection of a
   slice type incurs a performance cost.

**CORRECT**

```hare
[]int
[5]int
[2 + 2]int
[*]int
[_]int
```

**INCORRECT**

```hare
[ ]int
[ 10 ]int
[] int
```

### iv. Tagged union types

1. Tagged union types may be specified in either a single-line or multi-line
   style. If the type would fit on a single line within 80 columns, the
   single-line style MUST be used.
2. In the single-line style, there MUST NOT be a space between the `(` or `)`
   token and the member type list.
3. In the single-line style, there MUST be a space between the `|` tokens and
   each member type.
4. (*subjective*) In the multi-line style, the programmer MAY use their
   discretion to distribute the member types to achieve "balance" as described
   by rule A.4.
5. When breaking to a new line, place the `|` on the first line. Place the final
   `)` token on the same line as the final members.
6. (*subjective*) When using a tagged union with many member types, consider
   categorizing them into additional aliases and using the `...` operator to
   unwrap them.
7. Tagged union aliases SHOULD be named in the singular.

**CORRECT**

```hare
type my_union = (type_a | type_b | type_d | type_e | type_f | type_g);

type my_result = (result_type_a | result_type_b | result_type_c |
	result_type_d | result_type_e);

type my_error = (error_type_a | error_type_b | error_type_d | error_type_c);

type my_union = (...my_result | ...my_error);
```

### v. Tuple types

1. Tuple types may be specified in either a single-line or multi-line style. If
   the type would fit on a single line within 80 columns, the single-line style
   MUST be used.
2. A tuple type MUST NOT place a space after `(` or before `)`.
3. In the single-line style, a tuple type MUST NOT place a space before each
   `,`, and MUST place a space after each `,`, except for the last, which MUST
   be omitted.
5. In the multi-line style, a tuple type MUST NOT place a space before each `,`,
   and MUST place a space after each `,`, except for the last, which MUST NOT be
   omitted.
4. (*subjective*) In the multi-line style, the programmer MAY use their
   discretion to distribute the member types to achieve "balance" as described
   by rule A.4.
5. When breaking to a new line, place the `,` on the first line. Place the final
   `)` token on the same line as the final members.

**CORRECT**

```hare
type my_tuple = (int, uint);
type my_tuple = (type_a, type_b, type_c,
	type_d, type_e, type_f);
```

### vi. Pointer types

1. Pointer types MUST NOT have a space between the `*` token and the secondary
   type.
2. Nullable pointer types MUST have a space between the `nullable` token and the
   `*` token.
3. Function pointer types MUST NOT have a space between the `fn` token and the
   parameter list.
4. Function pointer types MAY omit the parameter name from each parameter in the
   parameter list.

### vii. Enum types

1. Enum aliases SHOULD be named in the singular.
2. Members MUST be named in ALL_CAPS.

**CORRECT**

```hare
type character_flag = enum {
	BIG,
	FRIENDLY,
	GIANT,
};
```

## H. Values

Rules governing the style for representations of values.

1. When choosing between explicit and hinted types, prefer whichever produces a
   shorter program.

**CORRECT**

```hare
let x = 0z;

let y: [_]u8 = [1, 2, 3];

let z: [_]nullable *size = [&x, null];
```

**INCORRECT**

```hare
let x: size = 0;

let y = [1u8, 2u8, 3u8];

let z = [&x: nullable *size, null: nullable *size];
```

### i. Struct values

1. Struct values MUST be defined with a space between the `struct` and `{`
   tokens, or between the type alias name and the `{` token.
3. Struct values MAY be defined in either single-line or multi-line style.
4. In the multi-line style, a newline MUST follow the `{` token, followed by the
   struct fields indented once, followed by the `}` token without indentation.
5. In the single-line style, the `{` token MUST be followed by a space, followed
   by the struct fields (each separated by a space following the `,` token,
   except for the final field, which MUST omit the `,` token), then a space and
   the `}` token.
6. Either all fields MUST be qualified, or all fields MUST NOT be qualified with
   their type.
7. If a field is qualified, there MUST NOT be a space between the field name and
   the `:` token.
8. There MUST be a space before and after the `=` token.

**CORRECT**

```hare
let x = struct { x: int = 10i, y: int = 10i };

let x = struct {
	x: int = 10,
	y: int = 10,
};

let x = my_struct {
	x = 10,
	y = 10,
};
```

### ii. Array values

1. Array values MAY be defined in either single-line or multi-line style.
2. In the single-line style, there MUST NOT be a space between the `[` and `]`
   tokens and the array members.
3. In the single-line style, a space MUST follow each `,` token, except for the
   last.
4. In the multi-line style, a `,` must be used after the final token.
5. In the mulit-line style, a newline MUST follow the `[` token, and each
   subsequent line up to but not including the `]` token MUST be indented.
6. In the multi-line style, values may be grouped onto the same line. They must
   be separated by spaces per rule 3.
7. When using array initialization shorthand, the `...` token MUST NOT be
   separated from the last value by a space.

**CORRECT**

```hare
let x = [1, 2, 3, 4, 5];
let x = [
	1,
	2,
	3,
	4,
	5,
];
let x = [
	1, 2, 3, 4, 5,
	1, 2, 3, 4, 5,
	1, 2, 3, 4, 5,
	1, 2, 3, 4, 5,
	1, 2, 3, 4, 5,
];
let x: [10]int = [1, 2, 3, 4, 5...];
```

### iii. Tuple values

1. Tuple values MAY be specified in either a single-line or multi-line style. If
   the value would fit on a single line within 80 columns, the single-line style
   must be used.
2. A tuple value MUST NOT place a space after `(` or before `)`.
3. In the single-line style, a tuple value MUST NOT place a space before each
   `,`, and MUST place a space after each `,`, except for the last, which MUST
   be omitted.
4. In the multi-line style, a tuple value MUST NOT place a space before each
   `,`, and MUST place a space after each `,`, except for the last, which MUST
   NOT be omitted.
5. (*subjective*) In the multi-line style, the programmer MAY use their
   discretion to distribute the member value to achieve "balance" as described
   by rule A.4.
6. When breaking to a new line, place the `,` on the first line. Place the final
   `)` token on the same line as the final members.

**CORRECT**

```hare
let x = (1, 2);
let x = (1, 2,
	3, 4, 5);
let x = (foo(), bar());
let x = (foo(),
	bar(), 1337);
```

## I. Variables

1. Variables MUST be named in `lower_underscore_case`.
2. If splitting a long binding list onto multiple lines, each line MUST be
   consistently broken either at the `=` token or the `,` token. The breaking
   token MUST be placed on the first line. An indent MUST precede each
   continuation line.

**CORRECT**

```hare
let x = 10;
let x: int = 10;
let x: int = 10,
	y: int = 20,
	z: int = 30;
let x: int =
	do_work(lots, of, parameters);
```

## J. Expressions and operators

1. Spaces MUST be placed before and after binary operators (e.g. `/`, `&&`).
2. A space MUST NOT be placed between a unary operator (e.g. `-`, `!`) and its
   operand.
3. A space MUST NOT be placed between the `(` and `)` operators and the inner
   expression.
4. When breaking a long line at a binary operator, the operator SHOULD be
   placed on the second line.

**CORRECT**

```hare
2 + 4 + 5;
2 + (5 * 10);
-10 * 20;
!foobar;
let x: int = 2
	+ 2
	+ 2
	+ 2;

let x = foo
	&& (bar || baz);
```

## K. Casts

1. A space MUST NOT be placed between the operand and the `:` token.
2. A space MUST be placed between the `:` token and the type.

**CORRECT**

```hare
let x = y: int;
```

## L. Postfix expressions

Postfix expressions include function calls, array or slice indexing, etc.

1. Postfix operators MUST NOT be separated from their operands by a space.

**CORRECT**

```hare
func(x, y, z);
list[10];
slice[2..4];
size(int);
```

## M. Branching expressions

1. A space MUST NOT be placed between the `(` and `)` operators and the
   branch predicate.
2. If an expression list (i.e. `{}`) is used, a space MUST be placed between
   the `)` and `{` tokens, followed by a newline. Each subsequent line MUST be
   indented, until the `}` token which MUST be aligned with the first token of
   the expression.
3. In `for` loops, each `;` token of the predicate MUST be followed by a space,
   or a newline.

**CORRECT**

```hare
if (x == y) {
	// ...
};

for (let x = 0; x < 10; x += 1) {
	// ...
};

for (x < y) {
	// ...
};

if (do_work(x) == y
		&& do_work(y) == z
		&& do_work(z) == q) {
	// ...
};
```

## N. Match and switch expressions

1. The preferred style is to align match and switch with their subordinate case
   branches on the same column.
2. The body of each case SHOULD be indented an additional level. Generally, `=>`
   SHOULD be followed by a newline.
3. If a default case (`case =>`) is given, it MUST be the last case.
4. If a case shouldn't perform any action, the body SHOULD just be `void`, ie
   `case ... => void;`. In these cases, the body MAY be on the same line as the
   `case` keyword.
5. (*subjective*) It is preferred to arrange any terminal cases (i.e. those that
   return, continue, break, call `os::exit` or `abort()`, etc) before any
   non-terminal cases. This groups the code which does not terminate closer to
   the code which logically follows it after the match or switch expression.

**CORRECT**

```hare
match (x) {
case foo =>
	// ...
case foobar =>
	// ...
case foobarbaz =>
	// ...
};

let foobarbaz = match (x) {
case foo =>
	// ...
	yield ...;
case foobar =>
	// ...
	yield ...;
case foobaz =>
	// ...
	yield ...;
};

match (x) {
case (foo | bar) =>
	// ...
case foobar =>
	// ...
case foobaz =>
	// ...
};
```

## Appendices

### Informal recommendations for function names

To name a function, first identify its purpose. If you were to describe this
purpose in a sentence, you should be able to identify up to three grammatical
items of importance: the verb, the object, and the subject. The subject is
usually the actor, the object is usually being acted upon, and the verb defines
the action being taken.

When naming a Hare function, use the format "subject_verbobject", where the
subject preceeds the verb and object, separated by an underscore, and the object
directly follows the verb. If you can infer the subject or object from context,
they may be omitted, so "verbobject", "subject_verb", or simply "verb" may be
appropriate names.

In the sentence "Sam goes to the store", "Sam" is the subject, "store" is the
object, and "go" is the verb. The equivalent function name would be
"sam_gostore". If we have additional context, for example if this is in the
"sam" module, we could call it "sam::gostore". Or perhaps the object is given by
a parameter, in which case "go" is sufficient:

```hare
fn sam::go(to: destination) void;
```

Abbreviating terms is acceptable, such as "str" for "string" or "tok" for
"token".

This approach prefers terseness when unambiguous. Here are some real-world
examples:

```hare
fn bufio::scantok(stream: *io::stream, delim: u8) ([]u8 | io::EOF | io::error);

fn io::read(stream: *io::stream, buf: []u8) (size | io::EOF | io::error);

fn lex::init(in: *io::stream, path: str) lexer;
```

Note the arrangement of parameters: the object being acted upon comes first. For
example, if you have "source" and "destination" parameters, "destination" should
be placed first in the parameter list.

### Verbs for allocation strategies

It is useful to communicate the allocation strategy in function names, to lend
readability to the implications for Hare's manual memory management system. The
following conventions are recommended.

For functions which initialize a value and return it, either via allocation or
via the stack, name these functions after the object being initialized. For
example, to initialize a SHA-256 hash, you use `crypto::sha256::sha256()`.
If a more specific verb than "allocate" or "initialize" would be appropriate,
name the function after that verb. For example, "open" or "connect" may be more
appropriate names than "file" or "client".

If a function accepts a pointer to a value as a parameter, and will initialize
that value, use the "init" verb to name the function.

For functions which free resources associated with an object, if the object
itself is freed, use the verb "free". If the object itself is not freed, but
some other state associated with it, use the verb "finish".

### Informal recommendations for documentation

Consult `man haredoc` for technical details regarding documenting Hare
interfaces through comments in the source code.

It is useful to have some linguistic conventions for inline documentation. The
following guidelines provide such conventions for any programs which wish to be
consistent with the rest of the Hare ecosystem in their approach to API
documentation.

All programmer-facing documentation should be written in English, and all public
(exported) members should be documented. Not documenting an exported member
signals that it is not designed to be used by third-party programs.

Your documentation should be as concise or as long as is necessary. Programmers
reading the reference documentation are usually in a hurry, but they also
appreciate comprehensive explanations. Aim to be as short as possible without
omitting necessary details.

Include a period after the last sentence.

Function documentation should complete the following thought: "This function
[does, will, is used to]...". Examples:

- "Insert a new entry into the list"
- "Parse the next record from the file"

Type documentation should complete the following thought: "This type is..." or
"This type $verbs...". Examples:

- "An error indicating that an invalid sequence was encountered"
- "Indicates that more data is required to finish processing"
- "Stores the state for an XML parser"

Constant documentation should complete the following thought: "This constant
is..."

- "The size, in bytes, of an MD5 digest"
- "The magic string identifying a PNG file"

### Informal recommendations for errors

These recommendations cover programmer-facing errors. User-facing errors are
addressed separately in [Internationalization recommendations for Hare
programs](/i18n).

Each module should provide an `error` type which is a tagged union of all
possible errors which might be returned by functions in that module, and an
`strerror` function which explains the error as a string. These strings should
be written with "Sentence case" and should not end with a period. It should also
be written so that it makes sense when passed to `fmt::fatal("Error:",
example::strerror(err))`.

Write programmer-facing error messages in English. This includes the return
value from `strerror`, and also the error messages used in `abort` and `assert`
expressions.

D content/tools.md => content/tools.md +0 -30
@@ 1,30 0,0 @@
---
title: Notes on third-party tools and Hare
---

This guide shows you how to best use common external tools for working
with Hare programs.

This page is under construction. Patches are welcome!

## Debugging

### gdb

## Profiling

### perf

### valgrind

[valgrind](https://valgrind.org) is a popular tool for examining memory
usage. Link with libc to make valgrind track malloc/free calls:

```
$ hare build -lc -o example example.ha
$ valgrind ./example
```

## Linking Hare programs with C libraries

## More?

M content/tutorial.md => content/tutorial.md +0 -8
@@ 20,11 20,3 @@ with the design of the Hare standard library and some of its more important
features.

<a href="/tutorials/stdlib" class="tutorial-link">Standard library introduction</a>

### Hare modules tutorial

The modules tutorial explains how to organize your projects into several files
and directories, and how to create new Hare libraries for other users to take
advantage of.

<a href="/tutorials/modules" class="tutorial-link">Hare modules tutorial</a>

M layouts/index.html => layouts/index.html +53 -1
@@ 12,7 12,59 @@
  <body>
    {{ partial "nav.html" }}
    <main>
      {{.Content}}
      <p>
      Hare is a systems programming language designed to be simple, stable, and
      robust. Hare uses a static type system, manual memory management, and a
      minimal runtime. It is well-suited to writing operating systems, system tools,
      compilers, networking software, and other low-level, high performance tasks.

      {{ $sample := readFile "sample.ha" }}
      {{ transform.Highlight $sample "hare" }}

      <h2>Getting started</h2>
      <p>
      Read the <a href="/documentation/install/">installation steps</a> to get Hare
      for your system, then read the <a href="/tutorial">tutorial</a>. To see if Hare
      is available for your system, consult the
      <a href="/documentation/install/#supported-platforms">supported platforms list</a>.

      {{ range first 1 (where .Site.RegularPages "Section" "blog") }}
      <header class="inline-header">
        <div class="heading">
          <div class="info">
            <div class="content">
              <h2>Latest news</h2>
              <p>
              {{.Date.Format "January 2, 2006"}}
              by {{.Params.author}}
            </div>
          </div>
          <div class="content">
            <h3>
              <a href="{{.Permalink}}" class="blog-link">
                {{.Title}}
              </a>
            </h3>
          </div>
        </div>
      </header>
      {{ end }}

      <h2>Who's behind Hare?</h2>

      <p>
      <a href="/who">Ten maintainers and about a hundred contributors</a>.

      <h2>Supporting Hare</h2>

      <p>
      We have an <a href="https://opencollective.com/hare">Open Collective</a> for
      donations and commercial sponsorships.

      <p>
      Hare fits on a 3½" floppy disc &mdash; these will be available for purchase when
      Hare 1.0 is released!

    </main>
    {{ partial "footer.html" }}
  </body>

M layouts/partials/nav.html => layouts/partials/nav.html +4 -4
@@ 8,11 8,11 @@
  <h1>The Hare programming language</h1>
  <ul>
    <li><a href="/">Home</a></li>
    <li><a href="/documentation">Documentation</a></li>
    <li><a href="/roadmap">Roadmap</a></li>
    <li><a href="/documentation/">Documentation</a></li>
    <li><a href="/tutorial">Tutorials</a></li>
    <li><a href="/blog">Blog</a></li>
    <li><a href="/community">Community</a></li>
    <li><a href="https://sr.ht/~sircmpwn/hare">Source code</a></li>
    <li><a href="/documentation/community/">Community</a></li>
    <li><a href="/specification">Specification</a></li>
    <li><a href="https://sr.ht/~sircmpwn/hare">Source code</a></li>
  </ul>
</nav>