Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Externals #346

Merged
merged 8 commits into from
Sep 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions concepts/external-functions/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"blurb": "External functions enable Gleam programs to use code written in other languages.",
"authors": [
"lpil"
],
"contributors": [
]
}
43 changes: 43 additions & 0 deletions concepts/external-functions/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# About

Gleam can run on the Erlang virtual machine (BEAM), or on JavaScript runtimes. There are many other languages that use these runtimes, and it is often useful to be able to call code written in these languages from Gleam.

Gleam's _external functions_ feature permits functions in other languages to be imported into Gleam and called with no runtime overhead.

If your Gleam project runs on the Erlang virtual machine and you wish to call the `reverse` function from the Erlang `lists` module you can do it by adding the `@external` attribute to a Gleam function head like this:

```gleam
@external(erlang, "lists", "reverse")
pub fn reverse_list(x: List(a)) -> List(a)
```

This can then be called as a normal Gleam function:

```gleam
let reversed = reverse_list([1, 2, 3])
// -> [3, 2, 1]
```

If you attempt to compile this code for JavaScript runtimes it will fail with an error message as there is no implementation for JavaScript. Another implementation can be specified for JavaScript runtimes like this:

```gleam
@external(erlang, "lists", "reverse")
@external(javascript, "./my_module.mjs", "reverse")
pub fn reverse_list(x: List(a)) -> List(a)
```

It is also possible to write a Gleam implementation that will be used when there is no external implementation for the current compile target:

```gleam
@external(erlang, "lists", "reverse")
pub fn reverse_list(x: List(a)) -> List(a) {
tail_recursive_reverse(x, [])
}

fn tail_recursive_reverse(list, reversed) {
case list {
[] -> reversed
[x, ..xs] -> tail_recursive_reverse(xs, [x, ..reversed])
}
}
```
43 changes: 43 additions & 0 deletions concepts/external-functions/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Introduction

Gleam can run on the Erlang virtual machine (BEAM), or on JavaScript runtimes. There are many other languages that use these runtimes, and it is often useful to be able to call code written in these languages from Gleam.

Gleam's _external functions_ feature permits functions in other languages to be imported into Gleam and called with no runtime overhead.

If your Gleam project runs on the Erlang virtual machine and you wish to call the `reverse` function from the Erlang `lists` module you can do it by adding the `@external` attribute to a Gleam function head like this:

```gleam
@external(erlang, "lists", "reverse")
pub fn reverse_list(x: List(a)) -> List(a)
```

This can then be called as a normal Gleam function:

```gleam
let reversed = reverse_list([1, 2, 3])
// -> [3, 2, 1]
```

If you attempt to compile this code for JavaScript runtimes it will fail with an error message as there is no implementation for JavaScript. Another implementation can be specified for JavaScript runtimes like this:

```gleam
@external(erlang, "lists", "reverse")
@external(javascript, "./my_module.mjs", "reverse")
pub fn reverse_list(x: List(a)) -> List(a)
```

It is also possible to write a Gleam implementation that will be used when there is no external implementation for the current compile target:

```gleam
@external(erlang, "lists", "reverse")
pub fn reverse_list(x: List(a)) -> List(a) {
tail_recursive_reverse(x, [])
}

fn tail_recursive_reverse(list, reversed) {
case list {
[] -> reversed
[x, ..xs] -> tail_recursive_reverse(xs, [x, ..reversed])
}
}
```
2 changes: 2 additions & 0 deletions concepts/external-functions/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
8 changes: 8 additions & 0 deletions concepts/external-types/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"blurb": "External types can be used in Gleam to refer to types defined in other languages.",
"authors": [
"lpil"
],
"contributors": [
]
}
9 changes: 9 additions & 0 deletions concepts/external-types/about.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# About

External types can be used to refer to data types defined in other languages, such as Erlang or JavaScript.

To define an external function declare a type but do not provide any constructors. This can then be used in the same way as any other type.

```gleam
pub type OrderedDictionary(element)
```
9 changes: 9 additions & 0 deletions concepts/external-types/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Introduction

External types can be used to refer to data types defined in other languages, such as Erlang or JavaScript.

To define an external function declare a type but do not provide any constructors. This can then be used in the same way as any other type.

```gleam
pub type OrderedDictionary(element)
```
2 changes: 2 additions & 0 deletions concepts/external-types/links.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[
]
27 changes: 24 additions & 3 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,20 @@
"options"
],
"status": "active"
},
{
"slug": "erlang-extraction",
"name": "Erlang Extraction",
"uuid": "1ba3d119-a973-4b54-ac6e-b86979783175",
"concepts": [
"external-functions",
"external-types"
],
"prerequisites": [
"custom-types",
"maps"
],
"status": "active"
}
],
"practice": [
Expand Down Expand Up @@ -1281,7 +1295,6 @@
"prerequisites": [
"ints",
"lists",
"bitwise",
"case-expressions",
"custom-types"
],
Expand Down Expand Up @@ -1438,7 +1451,6 @@
],
"prerequisites": [
"ints",
"random",
"custom-types",
"iterators"
],
Expand Down Expand Up @@ -1525,7 +1537,6 @@
"practices": [
],
"prerequisites": [
"random",
"iterators",
"strings",
"lists",
Expand Down Expand Up @@ -1978,6 +1989,16 @@
"uuid": "c4b81d7a-29ed-4df4-8c32-af74e75fd517",
"slug": "regular-expressions",
"name": "Regular Expressions"
},
{
"uuid": "b6631661-19d7-4cc2-8859-9848244bd38e",
"slug": "external-functions",
"name": "External Functions"
},
{
"uuid": "6b3a8671-4fef-4e72-ab58-2fc12893d9ae",
"slug": "external-types",
"name": "External Types"
}
],
"key_features": [
Expand Down
10 changes: 5 additions & 5 deletions exercises/concept/bandwagoner/manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
# You typically do not need to edit this file

packages = [
{ name = "exercism_test_runner", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "glance", "gleam_erlang", "simplifile", "gleam_json", "gleam_stdlib", "gap"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "336FBF790841C2DC25EB77B35E76A09EFDB9771D7D813E0FDBC71A50CB79711D" },
{ name = "gap", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "AF290C27B3FAE5FE64E1B7E9C70A9E29AA0F42429C0592D375770C1C51B79D36" },
{ name = "glance", version = "0.6.2", build_tools = ["gleam"], requirements = ["glexer", "gleam_stdlib"], otp_app = "glance", source = "hex", outer_checksum = "85DD95322E6945813EA79147F2C867617B076306CDDD4F047516BE0A383341A9" },
{ name = "exercism_test_runner", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_json", "gap", "gleam_stdlib", "glance", "gleam_erlang", "simplifile"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "336FBF790841C2DC25EB77B35E76A09EFDB9771D7D813E0FDBC71A50CB79711D" },
{ name = "gap", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_community_ansi"], otp_app = "gap", source = "hex", outer_checksum = "AF290C27B3FAE5FE64E1B7E9C70A9E29AA0F42429C0592D375770C1C51B79D36" },
{ name = "glance", version = "0.7.0", build_tools = ["gleam"], requirements = ["glexer", "gleam_stdlib"], otp_app = "glance", source = "hex", outer_checksum = "760F587A98F28DACBF5B9BE8A26C00F738F01EBB32B4E056C937ED73B3BFE5FC" },
{ name = "gleam_bitwise", version = "1.3.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "E2A46EE42E5E9110DAD67E0F71E7358CBE54D5EC22C526DD48CBBA3223025792" },
{ name = "gleam_community_ansi", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib", "gleam_bitwise"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "6E4E0CF2B207C1A7FCD3C21AA43514D67BC7004F21F82045CDCCE6C727A14862" },
{ name = "gleam_community_ansi", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_bitwise", "gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "6E4E0CF2B207C1A7FCD3C21AA43514D67BC7004F21F82045CDCCE6C727A14862" },
{ name = "gleam_community_colour", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_bitwise", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "D27CE357ECB343929A8CEC3FBA0B499943A47F0EE1F589EE16AFC2DC21C61E5B" },
{ name = "gleam_erlang", version = "0.22.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "367D8B41A7A86809928ED1E7E55BFD0D46D7C4CF473440190F324AFA347109B4" },
{ name = "gleam_json", version = "0.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "C6CC5BEECA525117E97D0905013AB3F8836537455645DDDD10FE31A511B195EF" },
{ name = "gleam_otp", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "ED7381E90636E18F5697FD7956EECCA635A3B65538DC2BE2D91A38E61DCE8903" },
{ name = "gleam_stdlib", version = "0.30.2", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "8D8BF3790AA31176B1E1C0B517DD74C86DA8235CF3389EA02043EE4FD82AE3DC" },
{ name = "glexer", version = "0.6.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "703D2347F5180B2BCEA4D258549B0D91DACD0905010892BAC46D04D913B84D1F" },
{ name = "simplifile", version = "0.1.10", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "263B7C7F4B29263555DEA2D30BA918425A27120CDD1E1352744EAB4D56CE01CE" },
{ name = "simplifile", version = "0.1.11", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "C71E4D63A003C8E0A5C613B64EC6819FFBF67132655F252CE0B09A2FCDF185DD" },
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" },
]

Expand Down
10 changes: 5 additions & 5 deletions exercises/concept/bettys-bike-shop/manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
# You typically do not need to edit this file

packages = [
{ name = "exercism_test_runner", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "glance", "gleam_erlang", "simplifile", "gleam_json", "gleam_stdlib", "gap"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "336FBF790841C2DC25EB77B35E76A09EFDB9771D7D813E0FDBC71A50CB79711D" },
{ name = "gap", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "AF290C27B3FAE5FE64E1B7E9C70A9E29AA0F42429C0592D375770C1C51B79D36" },
{ name = "glance", version = "0.6.2", build_tools = ["gleam"], requirements = ["glexer", "gleam_stdlib"], otp_app = "glance", source = "hex", outer_checksum = "85DD95322E6945813EA79147F2C867617B076306CDDD4F047516BE0A383341A9" },
{ name = "exercism_test_runner", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_json", "gap", "gleam_stdlib", "glance", "gleam_erlang", "simplifile"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "336FBF790841C2DC25EB77B35E76A09EFDB9771D7D813E0FDBC71A50CB79711D" },
{ name = "gap", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_community_ansi"], otp_app = "gap", source = "hex", outer_checksum = "AF290C27B3FAE5FE64E1B7E9C70A9E29AA0F42429C0592D375770C1C51B79D36" },
{ name = "glance", version = "0.7.0", build_tools = ["gleam"], requirements = ["glexer", "gleam_stdlib"], otp_app = "glance", source = "hex", outer_checksum = "760F587A98F28DACBF5B9BE8A26C00F738F01EBB32B4E056C937ED73B3BFE5FC" },
{ name = "gleam_bitwise", version = "1.3.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "E2A46EE42E5E9110DAD67E0F71E7358CBE54D5EC22C526DD48CBBA3223025792" },
{ name = "gleam_community_ansi", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib", "gleam_bitwise"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "6E4E0CF2B207C1A7FCD3C21AA43514D67BC7004F21F82045CDCCE6C727A14862" },
{ name = "gleam_community_ansi", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_bitwise", "gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "6E4E0CF2B207C1A7FCD3C21AA43514D67BC7004F21F82045CDCCE6C727A14862" },
{ name = "gleam_community_colour", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_bitwise", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "D27CE357ECB343929A8CEC3FBA0B499943A47F0EE1F589EE16AFC2DC21C61E5B" },
{ name = "gleam_erlang", version = "0.22.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "367D8B41A7A86809928ED1E7E55BFD0D46D7C4CF473440190F324AFA347109B4" },
{ name = "gleam_json", version = "0.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "C6CC5BEECA525117E97D0905013AB3F8836537455645DDDD10FE31A511B195EF" },
{ name = "gleam_otp", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "ED7381E90636E18F5697FD7956EECCA635A3B65538DC2BE2D91A38E61DCE8903" },
{ name = "gleam_stdlib", version = "0.30.2", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "8D8BF3790AA31176B1E1C0B517DD74C86DA8235CF3389EA02043EE4FD82AE3DC" },
{ name = "glexer", version = "0.6.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "703D2347F5180B2BCEA4D258549B0D91DACD0905010892BAC46D04D913B84D1F" },
{ name = "simplifile", version = "0.1.10", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "263B7C7F4B29263555DEA2D30BA918425A27120CDD1E1352744EAB4D56CE01CE" },
{ name = "simplifile", version = "0.1.11", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "C71E4D63A003C8E0A5C613B64EC6819FFBF67132655F252CE0B09A2FCDF185DD" },
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" },
]

Expand Down
10 changes: 5 additions & 5 deletions exercises/concept/bird-count/manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
# You typically do not need to edit this file

packages = [
{ name = "exercism_test_runner", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "glance", "gleam_erlang", "simplifile", "gleam_json", "gleam_stdlib", "gap"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "336FBF790841C2DC25EB77B35E76A09EFDB9771D7D813E0FDBC71A50CB79711D" },
{ name = "gap", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "AF290C27B3FAE5FE64E1B7E9C70A9E29AA0F42429C0592D375770C1C51B79D36" },
{ name = "glance", version = "0.6.2", build_tools = ["gleam"], requirements = ["glexer", "gleam_stdlib"], otp_app = "glance", source = "hex", outer_checksum = "85DD95322E6945813EA79147F2C867617B076306CDDD4F047516BE0A383341A9" },
{ name = "exercism_test_runner", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_json", "gap", "gleam_stdlib", "glance", "gleam_erlang", "simplifile"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "336FBF790841C2DC25EB77B35E76A09EFDB9771D7D813E0FDBC71A50CB79711D" },
{ name = "gap", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "gleam_community_ansi"], otp_app = "gap", source = "hex", outer_checksum = "AF290C27B3FAE5FE64E1B7E9C70A9E29AA0F42429C0592D375770C1C51B79D36" },
{ name = "glance", version = "0.7.0", build_tools = ["gleam"], requirements = ["glexer", "gleam_stdlib"], otp_app = "glance", source = "hex", outer_checksum = "760F587A98F28DACBF5B9BE8A26C00F738F01EBB32B4E056C937ED73B3BFE5FC" },
{ name = "gleam_bitwise", version = "1.3.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "E2A46EE42E5E9110DAD67E0F71E7358CBE54D5EC22C526DD48CBBA3223025792" },
{ name = "gleam_community_ansi", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib", "gleam_bitwise"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "6E4E0CF2B207C1A7FCD3C21AA43514D67BC7004F21F82045CDCCE6C727A14862" },
{ name = "gleam_community_ansi", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_bitwise", "gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "6E4E0CF2B207C1A7FCD3C21AA43514D67BC7004F21F82045CDCCE6C727A14862" },
{ name = "gleam_community_colour", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_bitwise", "gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "D27CE357ECB343929A8CEC3FBA0B499943A47F0EE1F589EE16AFC2DC21C61E5B" },
{ name = "gleam_erlang", version = "0.22.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "367D8B41A7A86809928ED1E7E55BFD0D46D7C4CF473440190F324AFA347109B4" },
{ name = "gleam_json", version = "0.6.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "C6CC5BEECA525117E97D0905013AB3F8836537455645DDDD10FE31A511B195EF" },
{ name = "gleam_otp", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "ED7381E90636E18F5697FD7956EECCA635A3B65538DC2BE2D91A38E61DCE8903" },
{ name = "gleam_stdlib", version = "0.30.2", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "8D8BF3790AA31176B1E1C0B517DD74C86DA8235CF3389EA02043EE4FD82AE3DC" },
{ name = "glexer", version = "0.6.2", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "703D2347F5180B2BCEA4D258549B0D91DACD0905010892BAC46D04D913B84D1F" },
{ name = "simplifile", version = "0.1.10", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "263B7C7F4B29263555DEA2D30BA918425A27120CDD1E1352744EAB4D56CE01CE" },
{ name = "simplifile", version = "0.1.11", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "C71E4D63A003C8E0A5C613B64EC6819FFBF67132655F252CE0B09A2FCDF185DD" },
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" },
]

Expand Down
Loading