Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
massivefermion committed Oct 9, 2023
2 parents 80c6291 + d62c514 commit d3053dc
Show file tree
Hide file tree
Showing 777 changed files with 16,283 additions and 1,321 deletions.
7 changes: 4 additions & 3 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab
uses: actions/checkout@8ade135a41bc03ea155e62e844d188df1ea18608

- uses: erlef/setup-beam@c2e02f777c158310fc6d3d4e11b36a52d2d52db8
- uses: erlef/setup-beam@61e01a43a562a89bfc54c7f9a378ff67b03e4a21
with:
otp-version: "25.2"
gleam-version: "0.27.0"
gleam-version: "0.30.3"
elixir-version: "1.15.0"

- name: Run tests for all exercises
run: bin/test
Expand Down
1 change: 1 addition & 0 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
gleam 0.30.5
4 changes: 2 additions & 2 deletions bin/test
Original file line number Diff line number Diff line change
Expand Up @@ -78,10 +78,10 @@ function run_all {
mkdir -p all_exercises all_exercises/src all_exercises/test

cat <<EOT > all_exercises/test/all_exercises_test.gleam
import gleeunit
import exercism/test_runner
pub fn main() {
gleeunit.main()
test_runner.main()
}
EOT

Expand Down
8 changes: 8 additions & 0 deletions concepts/anonymous-functions/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"blurb": "Gleam has first class functions, meaning they can be assigned to variables and used like any other value.",
"authors": [
"lpil"
],
"contributors": [
]
}
56 changes: 56 additions & 0 deletions concepts/anonymous-functions/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# About

Gleam has first class functions, meaning functions are normal values that can be assigned to variables, passed as arguments, and returned from other functions.

A named function defined in a module can be referenced by its name.

```gleam
pub fn main() {
// Assign the function to a variable
let f = add_one
// Invoke the function
f(1) // -> 2
f(2) // -> 3
}
fn add_one(x) {
x + 1
}
```

Gleam also has anonymous functions, which are defined within other functions.

```gleam
// Define the function
let f = fn(x) { x + 1 }
// Invoke the function
f(1) // -> 2
f(2) // -> 3
```

The type of a function is written using a similar syntax to anonymous functions. The type of a function that takes an `Int` and a `Float` and returns an `Int` is written like this:

```gleam
fn(Int, Float) -> Int
```

Anonymous functions can reference variables that were in scope when they were defined, making them _closures_.

```gleam
let secret_number = 42
// This function always returns 42
fn() { secret_number }
```

The _function capture_ syntax provides a convenient shorthand for creating anonymous functions that pass a single argument to a function. These two expressions are equivalent:

```gleam
// Anonymous function syntax
let f = fn(x) { my_function(1, 2, x) }
// Function capture syntax
let f = my_function(1, 2, _)
```
56 changes: 56 additions & 0 deletions concepts/anonymous-functions/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Introduction

Gleam has first class functions, meaning functions are normal values that can be assigned to variables, passed as arguments, and returned from other functions.

A named function defined in a module can be referenced by its name.

```gleam
pub fn main() {
// Assign the function to a variable
let f = add_one
// Invoke the function
f(1) // -> 2
f(2) // -> 3
}
fn add_one(x) {
x + 1
}
```

Gleam also has anonymous functions, which are defined within other functions.

```gleam
// Define the function
let f = fn(x) { x + 1 }
// Invoke the function
f(1) // -> 2
f(2) // -> 3
```

The type of a function is written using a similar syntax to anonymous functions. The type of a function that takes an `Int` and a `Float` and returns an `Int` is written like this:

```gleam
fn(Int, Float) -> Int
```

Anonymous functions can reference variables that were in scope when they were defined, making them _closures_.

```gleam
let secret_number = 42
// This function always returns 42
fn() { secret_number }
```

The _function capture_ syntax provides a convenient shorthand for creating anonymous functions that pass a single argument to a function. These two expressions are equivalent:

```gleam
// Anonymous function syntax
let f = fn(x) { my_function(1, 2, x) }
// Function capture syntax
let f = my_function(1, 2, _)
```
2 changes: 2 additions & 0 deletions concepts/anonymous-functions/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
13 changes: 10 additions & 3 deletions concepts/basics/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ In Gleam variables are defined using the `let name = expression` syntax.
```gleam
pub fn main() {
let count = 1
// You may shadow existing variables with the same name
let count = "Lots"
}
```

Expand All @@ -50,6 +47,16 @@ pub fn main() {
}
```

## String literals

In Gleam strings are written using double quotes.

```gleam
pub fn greeting() {
"Hello, world!"
}
```

## Code comments

Comments can be used to leave notes for other developers reading the source code. Comments in Gleam are single lines preceeded by `//`.
Expand Down
13 changes: 10 additions & 3 deletions concepts/basics/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,6 @@ In Gleam variables are defined using the `let name = expression` syntax.
```gleam
pub fn main() {
let count = 1
// You may shadow existing variables with the same name
let count = "Lots"
}
```

Expand All @@ -50,6 +47,16 @@ pub fn main() {
}
```

## String literals

In Gleam strings are written using double quotes.

```gleam
pub fn greeting() {
"Hello, world!"
}
```

## Code comments

Comments can be used to leave notes for other developers reading the source code. Comments in Gleam are single lines preceeded by `//`.
Expand Down
8 changes: 8 additions & 0 deletions concepts/bit-strings/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"blurb": "A bit string is a contiguous sequence of bits in memory.",
"authors": [
"lpil"
],
"contributors": [
]
}
93 changes: 93 additions & 0 deletions concepts/bit-strings/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
# Introduction

Working with binary data can be tricky, so Gleam provides a `BitString` type and accompanying syntax to construct and to pattern match on binary data.

Bit string literals are defined using the `<<>>` syntax. When defining a bit string literal, it is defined in segments. Each segment has a value and and annotation, separated by a `:`. The annotation specifies how many bits will be used to encode the value, and can be omitted completely, which will default to a 8-bit integer value.

```gleam
// This defines a bit string with three segments of a single bit each
<<0:1, 1:1, 0:1>>
// This defines a bit string with three segments of 8 bits each
<<0, 1, 0>>
```

Specifying the type as `:1` is a shorthand for writing `:size(1)`. You need to use the longer syntax if the bit size comes from a variable.

```gleam
let segment_size = 1
<<0:size(segment_size), 1:size(segment_size), 0:size(segment_size)>>
```

## Binary

When writing binary integer literals, we can write them directly in base-2 notation by prefixing the literal with `0b`. Note that they will be displayed as decimal numbers when printed in tests or in your program.

```gleam
<<0b1011:4>> == <<11:4>>
// -> True
```

## Truncating

If the value of the segment overflows the capacity of the segment's type, it will be truncated from the left.

```gleam
<<0b1011:3>> == <<0b0011:3>>
// -> True
```

## Prepending and appending

You can both prepend and append to an existing bit string using the bit string syntax. The `:bit_string` annotation must be used for the existing bit string.

```gleam
let value = <<0b110:3, 0b001:3>>
let new_value = <<0b011:3, value:bit_string, 0b000:3>>
// -> <<120, 8:size(4)>>
```

## Concatenating

We can concatenate bit strings stored in variables using the syntax. The `:bit_string` annotation must be used when concatenating two bit strings of variable sizes.

```gleam
let first = <<0b110:3>>
let second = <<0b001:3>>
let concatenated = <<first:bit_string, second:bit_string>>
// -> <<49:size(6)>>
```

## Pattern matching

Pattern matching can also be done to obtain values from the bit string. You have to know the number of bits for each fragment you want to capture, with one exception: the `:bit_string` annotation can be used to pattern match on a bit string of an unknown size, but this can only be used for the last fragment.

```gleam
let assert <<value:4, rest:bit_string>> = <<0b01101001:8>>
value == 0b0110
// -> true
```

## Inspecting bit strings

~~~~exercism/note
Bit strings might be printed in a different format than the format that was used
to create them. This often causes confusion when learning bit strings.
~~~~

By default, bit strings are displayed in fragments of 8 bits (a byte), even if you created them with fragments of a different size.

```gleam
<<2011:11>>
// -> <<251, 3:size(3)>>
```

If you create a bit string that represents a printable UTF-8 encoded string, it may displayed as a string by functions such as `io.debug`. This is due to an implementation detail of how Gleam represents strings internally.

```gleam
<<>>
// -> ""
<<65, 66, 67>>
// -> "ABC"
```
Loading

0 comments on commit d3053dc

Please sign in to comment.