6 | Published {{ page.date | date: "%d %b, %Y" }} by {{ page.author }} 7 |
8 | {{ content }} 9 |├── .gitignore ├── CNAME ├── _posts ├── v0.16.0 │ ├── .gitignore │ ├── .gitattributes │ ├── Makefile │ ├── out │ │ ├── hello.js │ │ ├── counter.js │ │ ├── dogs.js │ │ └── multiples.js │ └── src │ │ ├── hello.gleam │ │ ├── counter.gleam │ │ ├── dogs.gleam │ │ └── multiples.gleam ├── 2019-04-15-hello-gleam.md ├── 2019-08-07-gleam-v0.3-released.md ├── 2019-12-25-gleam-v0.6-released.md ├── 2019-09-19-gleam-v0.4-released.md ├── 2020-03-01-gleam-v0.7-released.md └── 2023-04-30-introducing-the-gleam-package-index.md ├── book ├── .nojekyll ├── favicon.png ├── FontAwesome │ └── fonts │ │ ├── FontAwesome.ttf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.ttf │ │ ├── fontawesome-webfont.woff │ │ └── fontawesome-webfont.woff2 ├── fonts │ ├── open-sans-v17-all-charsets-300.woff2 │ ├── open-sans-v17-all-charsets-600.woff2 │ ├── open-sans-v17-all-charsets-700.woff2 │ ├── open-sans-v17-all-charsets-800.woff2 │ ├── open-sans-v17-all-charsets-italic.woff2 │ ├── open-sans-v17-all-charsets-300italic.woff2 │ ├── open-sans-v17-all-charsets-600italic.woff2 │ ├── open-sans-v17-all-charsets-700italic.woff2 │ ├── open-sans-v17-all-charsets-800italic.woff2 │ ├── open-sans-v17-all-charsets-regular.woff2 │ ├── source-code-pro-v11-all-charsets-500.woff2 │ ├── fonts.css │ └── SOURCE-CODE-PRO-LICENSE.txt ├── javascript │ ├── plausible.js │ └── highlightjs-gleam.js ├── tour │ ├── todo.html │ ├── type-annotations │ └── type-annotations.html ├── css │ ├── print.css │ └── general.css ├── ayu-highlight.css ├── highlight.css ├── favicon.svg └── tomorrow-night.css ├── fonts ├── Lexend.woff2 ├── Outfit.woff ├── Lexend-700.woff2 └── CascadiaMono.woff2 ├── images ├── og-image.png ├── sponsors │ ├── memo.png │ ├── nine-fx.png │ └── alembic.svg ├── news │ ├── gleam-v0.21-released │ │ ├── hover.mp4 │ │ ├── hover.webm │ │ ├── compile.mp4 │ │ ├── compile.webm │ │ ├── formatting.mp4 │ │ ├── formatting.webm │ │ ├── goto-definition.mp4 │ │ ├── goto-definition.webm │ │ └── lsp-languages-editors.png │ ├── gleam-v0.14-released │ │ └── night-mode.png │ ├── gleam-v0.23-released │ │ ├── docs-search.mp4 │ │ └── docs-search.webm │ ├── gleam-v0.28-released │ │ └── docs-hover.png │ ├── gleam-v0.7-released │ │ ├── import-cycle.png │ │ ├── type-error.png │ │ └── incorrect-number-of-patterns.png │ ├── gleam-v0.29-released │ │ └── autocompletion.png │ ├── gleam-v0.20-released │ │ └── github-syntax-highlighting.png │ └── gleam-v0.26-released │ │ └── deno_hr_circle.svg ├── sponsor-heart.svg ├── waves.svg ├── pride-wall.svg ├── lucy-charcoal-2.svg └── lucy-pink-2.svg ├── img ├── gleam-0-13-docs-link.jpg ├── gleam-0-13-docs-version.jpg ├── lucy-pink-3.svg └── lucy-pink.svg ├── _layouts ├── post.html ├── page.html ├── layout.html └── old.html ├── javascript ├── plausible.js ├── main.js └── highlightjs-gleam.js ├── _includes ├── chartbar.html ├── hljs.html └── page-header.html ├── README.md ├── news.html ├── Makefile ├── book-src ├── tour │ ├── type-aliases.md │ ├── expression-blocks.md │ ├── README.md │ ├── let-bindings.md │ ├── tuples.md │ ├── external-types.md │ ├── comments.md │ ├── lists.md │ ├── constants.md │ ├── bools.md │ ├── ints-and-floats.md │ ├── strings.md │ ├── todo-and-panic.md │ ├── result.md │ ├── assert.md │ ├── use.md │ ├── external-functions.md │ ├── modules.md │ ├── case-expressions.md │ ├── bit-strings.md │ └── functions.md └── SUMMARY.md ├── book.toml ├── .well-known └── webfinger ├── writing-gleam ├── example-projects.md ├── creating-a-project.md ├── using-the-project.md ├── documenting-the-project.md ├── command-line-reference.sh ├── gleam-toml.md └── command-line-reference.md ├── _config.yml ├── mailing-list.md ├── community.md ├── getting-started.md ├── documentation.md ├── styles └── highlighting.css └── deployment └── fly.md /.gitignore: -------------------------------------------------------------------------------- 1 | _site 2 | -------------------------------------------------------------------------------- /CNAME: -------------------------------------------------------------------------------- 1 | gleam.run 2 | -------------------------------------------------------------------------------- /_posts/v0.16.0/.gitignore: -------------------------------------------------------------------------------- 1 | *.gleam_module 2 | -------------------------------------------------------------------------------- /_posts/v0.16.0/.gitattributes: -------------------------------------------------------------------------------- 1 | out linguist-generated=true 2 | -------------------------------------------------------------------------------- /book/.nojekyll: -------------------------------------------------------------------------------- 1 | This file makes sure that Github Pages doesn't process mdBook's output. 2 | -------------------------------------------------------------------------------- /book/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/favicon.png -------------------------------------------------------------------------------- /fonts/Lexend.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/fonts/Lexend.woff2 -------------------------------------------------------------------------------- /fonts/Outfit.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/fonts/Outfit.woff -------------------------------------------------------------------------------- /images/og-image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/og-image.png -------------------------------------------------------------------------------- /fonts/Lexend-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/fonts/Lexend-700.woff2 -------------------------------------------------------------------------------- /fonts/CascadiaMono.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/fonts/CascadiaMono.woff2 -------------------------------------------------------------------------------- /images/sponsors/memo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/sponsors/memo.png -------------------------------------------------------------------------------- /images/sponsors/nine-fx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/sponsors/nine-fx.png -------------------------------------------------------------------------------- /img/gleam-0-13-docs-link.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/img/gleam-0-13-docs-link.jpg -------------------------------------------------------------------------------- /img/gleam-0-13-docs-version.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/img/gleam-0-13-docs-version.jpg -------------------------------------------------------------------------------- /book/FontAwesome/fonts/FontAwesome.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/FontAwesome/fonts/FontAwesome.ttf -------------------------------------------------------------------------------- /images/news/gleam-v0.21-released/hover.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.21-released/hover.mp4 -------------------------------------------------------------------------------- /images/news/gleam-v0.21-released/hover.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.21-released/hover.webm -------------------------------------------------------------------------------- /_posts/v0.16.0/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: build 2 | build: 3 | rm -rf out 4 | gleam compile-package --name example --target javascript --src src --out out 5 | -------------------------------------------------------------------------------- /images/news/gleam-v0.21-released/compile.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.21-released/compile.mp4 -------------------------------------------------------------------------------- /images/news/gleam-v0.21-released/compile.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.21-released/compile.webm -------------------------------------------------------------------------------- /book/FontAwesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/FontAwesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /book/FontAwesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/FontAwesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /book/FontAwesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/FontAwesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /book/FontAwesome/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/FontAwesome/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-300.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-300.woff2 -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-600.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-600.woff2 -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-700.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-700.woff2 -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-800.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-800.woff2 -------------------------------------------------------------------------------- /images/news/gleam-v0.14-released/night-mode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.14-released/night-mode.png -------------------------------------------------------------------------------- /images/news/gleam-v0.21-released/formatting.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.21-released/formatting.mp4 -------------------------------------------------------------------------------- /images/news/gleam-v0.21-released/formatting.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.21-released/formatting.webm -------------------------------------------------------------------------------- /images/news/gleam-v0.23-released/docs-search.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.23-released/docs-search.mp4 -------------------------------------------------------------------------------- /images/news/gleam-v0.28-released/docs-hover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.28-released/docs-hover.png -------------------------------------------------------------------------------- /images/news/gleam-v0.7-released/import-cycle.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.7-released/import-cycle.png -------------------------------------------------------------------------------- /images/news/gleam-v0.7-released/type-error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.7-released/type-error.png -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-italic.woff2 -------------------------------------------------------------------------------- /images/news/gleam-v0.23-released/docs-search.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.23-released/docs-search.webm -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-300italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-300italic.woff2 -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-600italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-600italic.woff2 -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-700italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-700italic.woff2 -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-800italic.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-800italic.woff2 -------------------------------------------------------------------------------- /book/fonts/open-sans-v17-all-charsets-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/open-sans-v17-all-charsets-regular.woff2 -------------------------------------------------------------------------------- /book/fonts/source-code-pro-v11-all-charsets-500.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/book/fonts/source-code-pro-v11-all-charsets-500.woff2 -------------------------------------------------------------------------------- /images/news/gleam-v0.21-released/goto-definition.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.21-released/goto-definition.mp4 -------------------------------------------------------------------------------- /images/news/gleam-v0.21-released/goto-definition.webm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.21-released/goto-definition.webm -------------------------------------------------------------------------------- /images/news/gleam-v0.29-released/autocompletion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.29-released/autocompletion.png -------------------------------------------------------------------------------- /images/news/gleam-v0.21-released/lsp-languages-editors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.21-released/lsp-languages-editors.png -------------------------------------------------------------------------------- /images/news/gleam-v0.20-released/github-syntax-highlighting.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.20-released/github-syntax-highlighting.png -------------------------------------------------------------------------------- /images/news/gleam-v0.7-released/incorrect-number-of-patterns.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pietroppeter/gleam-website/main/images/news/gleam-v0.7-released/incorrect-number-of-patterns.png -------------------------------------------------------------------------------- /_layouts/post.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | --- 4 |
6 | Published {{ page.date | date: "%d %b, %Y" }} by {{ page.author }} 7 |
8 | {{ content }} 9 |{{ page.subtitle }}
9 | {% endcapture %} 10 | {% include page-header.html image=page.header_image content=header_content %} 11 | 12 |Redirecting to... ./todo-and-panic.html.
11 | 12 | 13 | -------------------------------------------------------------------------------- /book/tour/type-annotations: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |Redirecting to... ./let-bindings.html.
11 | 12 | 13 | -------------------------------------------------------------------------------- /book/tour/type-annotations.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |Redirecting to... ./let-bindings.html.
11 | 12 | 13 | -------------------------------------------------------------------------------- /news.html: -------------------------------------------------------------------------------- 1 | --- 2 | layout: page 3 | title: News log 4 | subtitle: What's happening in the Gleam world? 5 | --- 6 |{{ post.subtitle }}
12 | {% endif %} 13 | Published {{ post.date | date: "%d %b, %Y" }} by {{ post.author }} 14 | {% endfor %} 15 |12 | We'll send you at most one newsletter a month, and we'll never share 13 | your email with anyone else. 14 |
15 |16 | This site is protected by reCAPTCHA and the Google 17 | Privacy Policy and 18 | Terms of Service apply. 19 |
20 |
20 |
21 | This is a big improvement over previous versions which would struggle with
22 | highlighting multi-line code sections, and would state the problem as being
23 | `Int != Float` rather than `List(Int) != List(Float)`.
24 |
25 | Other improved error messages include the import cycle error message:
26 |
27 |
28 |
29 | Error messages for invalid patterns in case expressions:
30 |
31 |
32 |
33 | And a slew of error messages relating to errors when trying to read or write
34 | files in a Gleam project.
35 |
36 | Gleam aims to be an exceptionally friendly and productive language, so error
37 | messages are important. If there are any errors that you find confusing or
38 | unclear please get in touch and let us know!
39 |
40 | In adding these new error messages we discovered a bug in rebar3 where unicode
41 | characters would be printed incorrectly in some circumstances. This bug is now
42 | fixed now but if you find your errors look incorrect please try upgrading
43 | your rebar3 version by running `rebar3 local upgrade`.
44 |
45 |
46 | ## Alternative patterns
47 |
48 | Sometimes when writing case expressions we want multiple different clauses to
49 | be able to trigger the same clause with different shaped data. To meet this
50 | need we're introducing alternative patterns, separated by the `|` operator.
51 |
52 | In this case expression the first clause will match if the variable `number`
53 | holds 2, 4, 6 or 8.
54 |
55 | ```gleam
56 | case number {
57 | 2 | 4 | 6 | 8 -> "This is an even number"
58 | 1 | 3 | 5 | 7 -> "This is an odd number"
59 | _ -> "I'm not sure"
60 | }
61 | ```
62 |
63 |
64 | ## Clause guards
65 |
66 | Sometimes when pattern matching we want to assert that two variables have the
67 | same value. Before this release we'd need to nested case expressions, now we
68 | have clause guards.
69 |
70 | ```gleam
71 | case xs {
72 | [a, b] if a == b -> "Two equal elements"
73 | [a, b] if a != b -> "Two unequal elements"
74 | _other -> "Something else"
75 | }
76 | ```
77 |
78 |
79 | ## Named sub-patterns
80 |
81 | Sometimes when pattern matching we want to assign a name to a value while
82 | specifying it's shape at the same time. With this release we can now do this
83 | using the `as` keyword.
84 |
85 | ```gleam
86 | case xs {
87 | [[_, _] as inner_list] -> inner_list
88 | other -> []
89 | }
90 | ```
91 |
92 |
93 | ## Type aliases
94 |
95 | Sometimes it can be tiring writing long type names in function annotations
96 | such as `Result(List(tuple(String, String)), Nil)`, often we'd rather write a
97 | short alias instead such as `Option(Headers)`. With type aliases this is now
98 | possible.
99 |
100 |
101 | ```gleam
102 | pub type Option(value) =
103 | Result(value, Nil)
104 |
105 | pub type Headers =
106 | List(tuple(String, String))
107 |
108 | pub fn headers() -> Option(Headers) {
109 | Ok([tuple("x-served-by", "Gleam")])
110 | }
111 | ```
112 |
113 | The `Option(value)` alias above is often pretty useful! If you want to use it
114 | it is defined in the `gleam/result` module of the Gleam standard library.
115 |
116 |
117 | ## Windows support
118 |
119 | The Gleam compiler's test suite is now running successfully on Windows, and a
120 | Windows binary is being compiled for new releases. If you're developing on
121 | Windows please do give it a try and let us know of any problems you encounter.
122 |
123 |
124 | ## The rest
125 |
126 | In addition to these changes there's been a bunch of bug fixes, performance
127 | improvements, and refactorings to the compiler. Please see the
128 | [changelog](https://github.com/gleam-lang/gleam/blob/master/CHANGELOG.md) for
129 | more detail.
130 |
131 | If you want to try out the new version of Gleam head over to the [installation
132 | page][installation]. I'd love to hear how you find it and get your feedback so
133 | Gleam can continue to improve.
134 |
135 | Want to view some existing Gleam projects? Head on over to the
136 | [awesome-gleam][awesome-gleam] list. Looking for something to build in
137 | Gleam? Check out [the suggestions tracker][suggestions].
138 |
139 | [awesome-gleam]: https://github.com/gleam-lang/awesome-gleam
140 | [suggestions]: https://github.com/gleam-lang/suggestions/issues
141 | [installation]: https://gleam.run/getting-started/installing-gleam.html
142 |
143 |
144 | ## Thanks
145 |
146 | Lastly, a huge thank you to the contributors to and sponsors of Gleam since
147 | last release!
148 |
149 | - [Ahmad Sattar](https://github.com/thehabbos007)
150 | - [Anthony Bullard](https://github.com/gamebox)
151 | - [BSKY](https://github.com/imbsky)
152 | - [Christian Wesselhoeft](https://github.com/xtian)
153 | - [Guilherme Pasqualino](https://github.com/ggpasqualino)
154 | - [JHZheng](https://github.com/zjhmale)
155 | - [John Palgut](https://github.com/Jwsonic)
156 | - [RJ Dellecese](https://github.com/rjdellecese)
157 | - [Stefan Hagen](https://github.com/sthagen)
158 | - [ontofractal](https://github.com/ontofractal)
159 | - [szTheory](https://github.com/szTheory)
160 |
161 |
162 | If you would like to help make strongly typed programming on the Erlang
163 | virtual machine a production-ready reality please consider [sponsoring
164 | Gleam][sponsor] via the GitHub Sponsors program.
165 |
166 | Thanks for reading! Have fun! 💜
167 |
168 | [sponsor]: https://github.com/sponsors/lpil
169 |
--------------------------------------------------------------------------------
/images/news/gleam-v0.26-released/deno_hr_circle.svg:
--------------------------------------------------------------------------------
1 |
2 |
4 |
93 |
--------------------------------------------------------------------------------
/_posts/2023-04-30-introducing-the-gleam-package-index.md:
--------------------------------------------------------------------------------
1 | ---
2 | author: Louis Pilfold
3 | title: Introducing the Gleam package index
4 | subtitle: Find packages for your Gleam projects
5 | tags:
6 | - Release
7 | ---
8 |
9 | Gleam is a member of the BEAM family of languages, alongside Erlang, Elixir, and
10 | others. As such Gleam packages are distributed on [Hex.pm][hex], the
11 | package manager for the BEAM ecosystem. Hex provides an excellent experience,
12 | but up until now there has been one small problem: discovering Gleam packages.
13 |
14 | There are thousands of packages on Hex, and while Gleam projects can use
15 | packages written in Erlang or Elixir, most of the time we want to use packages
16 | that are either written in Gleam or already have Gleam bindings. Hex does not
17 | currently provide a way to search by language, so finding these packages is more
18 | difficult than it should be.
19 |
20 | To solve this problem we have created the [Gleam package index][packages], a
21 | website for exploring the Gleam subset of the Hex repository. ✨
22 |
23 | Today it provides a list of all the Gleam packages on Hex as well as a text
24 | search, and future we could add fancy Gleam specific features such as
25 | [searching by type information][elm-search], or [language server integration][lsp]
26 | so packages can be discovered directly from your editor.
27 |
28 | [hex]: https://hex.pm/
29 | [packages]: https://packages.gleam.run/
30 | [elm-search]: https://klaftertief.github.io/elm-search/
31 | [lsp]: /news/v0.21-introducing-the-gleam-language-server/
32 |
33 | ## How does it work?
34 |
35 | The package index is a web application written using the
36 | [`gleam_http`][gleam_http] package. It talks to a PostgreSQL database which it
37 | populates with Gleam packages found by crawling the Hex JSON API. All of this is
38 | deployed to [Fly][fly], who kindly sponsor Gleam's development.
39 |
40 | [gleam_http]: https://github.com/gleam-lang/http
41 | [fly]: https://fly.io/
42 |
43 | In `gleam_http` a web service is a simple function that takes the `Request` type
44 | as an argument and returns the `Response` type. We want some extra data (a
45 | database connection) alongside the request when responding, so we create a
46 | `Context` type that can hold the request and any other data we need.
47 |
48 | ```gleam
49 | pub type Context {
50 | Context(db: pgo.Connection, request: Request(BitString))
51 | }
52 |
53 | /// This function takes a database connection and returns as
54 | /// service function that will response to individual requests
55 | /// by calling `handle_request`.
56 | ///
57 | pub fn make_service(db: pgo.Connection) {
58 | fn(request) {
59 | let context = Context(db, request)
60 | handle_request(context)
61 | }
62 | }
63 | ```
64 |
65 | The `handle_request` function calls the appropriate function for the requested
66 | path, passing the context along with it. Thanks to Gleam's pattern matching we
67 | don't need a complex and slow router abstraction, we can use the super fast and
68 | familiar `case` expression, like any other Gleam code.
69 |
70 | ```gleam
71 | pub fn handle_request(context: Context) {
72 | let path = request.path_segments(context.request)
73 | case path {
74 | [] -> search(context)
75 | ["styles.css"] -> stylesheet()
76 | _ -> redirect(to: "/")
77 | }
78 | }
79 | ```
80 |
81 | The handler functions are where the logic of responding to requests lives. In
82 | the `search` handler we get the search term (if any) from the request, search
83 | the database for appropriate packages, render HTML from the list of packages,
84 | and return a response with this HTML to the user.
85 |
86 | ```gleam
87 | fn search(context: Context) -> Response(String) {
88 | // Search in the database for packages
89 | let term = get_search_parameter(context.request)
90 | let assert Ok(packages) = database.search(context.db, term)
91 |
92 | // Render HTML to show the results
93 | let html = packages_page(packages, term)
94 |
95 | // Return a response
96 | response.new(200)
97 | |> response.set_header("content-type", "text/html; charset=utf-8")
98 | |> response.set_body(html)
99 | }
100 | ```
101 |
102 | For rendering HTML we are using [Nakai][nakai], a package for writing HTML on
103 | the server (or anywhere) in a somewhat similar style to Elm or React, giving us
104 | fully type checked HTML within Gleam.
105 |
106 | [nakai]: https://nakaixo.github.io/
107 |
108 | ```gleam
109 | fn packages_page(packages: List(Package), term: String) -> String {
110 | html.Html([], [
111 | html.head([
112 | meta([charset("utf-8")]),
113 | meta([name("viewport"), content("width=device-width, initial-scale=1")]),
114 | link([rel("stylesheet"), href("/styles.css")]),
115 | title_text([], "Gleam Packages"),
116 | ]),
117 | // ... etc
118 | ```
119 |
120 | Once the service is written we can serve it using [Mist][mist], Alex Manning's
121 | pure Gleam web server. Mist is a fantastic demonstration of Gleam's maturity and
122 | what the language is capable of, and [in benchmarks][benchmarks] it is
123 | comfortably faster than Cowboy, the most commonly used Erlang web server.
124 |
125 | [mist]: https://github.com/rawhat/mist
126 | [benchmarks]: https://github.com/rawhat/http-benchmarks
127 |
128 | ```gleam
129 | pub fn main() {
130 | let assert Ok(key) = os.get_env("HEX_API_KEY")
131 | let db = index.connect()
132 |
133 | // Start syncing new releases every 60 seconds
134 | let sync = fn() { sync_new_gleam_releases(key, db) }
135 | let assert Ok(_) = periodically(sync, waiting: 60 * 1000)
136 |
137 | // Start the web server
138 | let service = web.make_service(db)
139 | let assert Ok(_) = mist.run_service(3000, service, max_body_limit: 4_000_000)
140 | io.println("Started listening on http://localhost:3000 ✨")
141 |
142 | // Put the main process to sleep while the web server handles traffic
143 | process.sleep_forever()
144 | }
145 | ```
146 |
147 | Here in the main function we start two actors, one that periodically syncs new
148 | releases from the Hex API, and one that runs the web server. I won't go into
149 | detail of the syncing process here, but in short it queries the Hex API for
150 | packages ordered by time of last update, and iterates across pages until it has
151 | found all the packages that have been updated since the last time it ran.
152 |
153 | If you'd like to see more of how this project works the source code is available
154 | [on GitHub][source]. I hope you enjoy using the package index, and do let us
155 | know if you have any ideas or suggestions!
156 |
157 | [source]: https://github.com/gleam-lang/packages
158 |
159 |
160 | Happy hacking! 💖
161 |
--------------------------------------------------------------------------------
/images/lucy-charcoal-2.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/images/lucy-pink-2.svg:
--------------------------------------------------------------------------------
1 |
27 |
--------------------------------------------------------------------------------
/images/sponsors/alembic.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/book-src/tour/functions.md:
--------------------------------------------------------------------------------
1 | # Functions
2 |
3 | ## Named functions
4 |
5 | Named functions in Gleam are defined using the `pub fn` keywords.
6 |
7 | ```gleam
8 | pub fn add(x: Int, y: Int) -> Int {
9 | x + y
10 | }
11 |
12 | pub fn multiply(x: Int, y: Int) -> Int {
13 | x * y
14 | }
15 | ```
16 |
17 | Functions in Gleam are first class values and so can be assigned to variables,
18 | passed to functions, or anything else you might do with any other data type.
19 |
20 | ```gleam
21 | /// This function takes a function as an argument
22 | pub fn twice(f: fn(t) -> t, x: t) -> t {
23 | f(f(x))
24 | }
25 |
26 | pub fn add_one(x: Int) -> Int {
27 | x + 1
28 | }
29 |
30 | pub fn add_two(x: Int) -> Int {
31 | twice(add_one, x)
32 | }
33 | ```
34 |
35 | ## Pipe Operator
36 |
37 | Gleam provides syntax for passing the result of one function to the arguments of another function, the pipe operator (`|>`). This is similar in functionality to the same operator in Elixir or F#.
38 |
39 | The pipe operator allows you to chain function calls without using a plethora of parentheses. For a simple example, consider the following implementation of `string.reverse` in Gleam:
40 |
41 | ```gleam
42 | string_builder.to_string(string_builder.reverse(string_builder.from_string(string)))
43 | ```
44 |
45 | This can be expressed more naturally using the pipe operator, eliminating the need to track parentheses closure.
46 |
47 | ```gleam
48 | string
49 | |> string_builder.from_string
50 | |> string_builder.reverse
51 | |> string_builder.to_string
52 | ```
53 |
54 | Each line of this expression applies the function to the result of the previous line. This works easily because each of these functions take only one argument. Syntax is available to substitute specific arguments of functions that take more than one argument; for more, look below in the section "Function capturing".
55 |
56 | ## Type annotations
57 |
58 | Function arguments are normally annotated with their type, and the
59 | compiler will check these annotations and ensure they are correct.
60 |
61 | ```gleam
62 | fn identity(x: some_type) -> some_type {
63 | x
64 | }
65 |
66 | fn inferred_identity(x) {
67 | x
68 | }
69 | ```
70 |
71 | The Gleam compiler can infer all the types of Gleam code without annotations
72 | and both annotated and unannotated code is equally safe. It's considered a
73 | best practice to always write type annotations for your functions as they
74 | provide useful documentation, and they encourage thinking about types as code
75 | is being written.
76 |
77 | ## Generic functions
78 |
79 | At times you may wish to write functions that are generic over multiple types.
80 | For example, consider a function that consumes any value and returns a list
81 | containing two of the value that was passed in. This can be expressed in Gleam
82 | like this:
83 |
84 | ```gleam
85 | fn list_of_two(my_value: a) -> List(a) {
86 | [my_value, my_value]
87 | }
88 | ```
89 |
90 | Here the type variable `a` is used to represent any possible type.
91 |
92 | You can use any number of different type variables in the same function. This
93 | function declares type variables `a` and `b`.
94 |
95 | ```gleam
96 | fn multi_result(x: a, y: b, condition: Bool) -> Result(a, b) {
97 | case condition {
98 | True -> Ok(x)
99 | False -> Error(y)
100 | }
101 | }
102 | ```
103 |
104 | Type variables can be named anything, but the names must be lower case and may
105 | contain underscores. Like other type annotations, they are completely optional,
106 | but may aid in understanding the code.
107 |
108 | ## Labelled arguments
109 |
110 | When functions take several arguments it can be difficult for the user to
111 | remember what the arguments are, and what order they are expected in.
112 |
113 | To help with this Gleam supports _labelled arguments_, where function
114 | arguments are given an external label in addition to their internal name.
115 |
116 | Take this function that replaces sections of a string:
117 |
118 | ```gleam
119 | pub fn replace(string: String, pattern: String, replacement: String) {
120 | // ...
121 | }
122 | ```
123 |
124 | It can be given labels like so.
125 |
126 | ```gleam
127 | pub fn replace(
128 | in string: String,
129 | each pattern: String,
130 | with replacement: String,
131 | ) {
132 | // The variables `string`, `pattern`, and `replacement` are in scope here
133 | }
134 | ```
135 |
136 | These labels can then be used when calling the function.
137 |
138 | ```gleam
139 | replace(in: "A,B,C", each: ",", with: " ")
140 |
141 | // Labelled arguments can be given in any order
142 | replace(each: ",", with: " ", in: "A,B,C")
143 |
144 | // Arguments can still be given in a positional fashion
145 | replace("A,B,C", ",", " ")
146 | ```
147 |
148 | The use of argument labels can allow a function to be called in an expressive,
149 | sentence-like manner, while still providing a function body that is readable
150 | and clear in intent.
151 |
152 | ## Anonymous functions
153 |
154 | Anonymous functions can be defined with a similar syntax.
155 |
156 | ```gleam
157 | pub fn run() {
158 | let add = fn(x, y) { x + y }
159 |
160 | add(1, 2)
161 | }
162 | ```
163 |
164 | ## Function capturing
165 |
166 | There is a shorthand syntax for creating anonymous functions that take one
167 | argument and call another function. The `_` is used to indicate where the
168 | argument should be passed.
169 |
170 | ```gleam
171 | pub fn add(x, y) {
172 | x + y
173 | }
174 |
175 | pub fn run() {
176 | let add_one = add(1, _)
177 |
178 | add_one(2)
179 | }
180 | ```
181 |
182 | The function capture syntax is often used with the pipe operator to create
183 | a series of transformations on some data.
184 |
185 | ```gleam
186 | pub fn add(x: Int , y: Int ) -> Int {
187 | x + y
188 | }
189 |
190 | pub fn run() {
191 | // This is the same as add(add(add(1, 3), 6), 9)
192 | 1
193 | |> add(_, 3)
194 | |> add(_, 6)
195 | |> add(_, 9)
196 | }
197 | ```
198 |
199 | In fact, this usage is so common that there is a special shorthand for it.
200 |
201 | ```gleam
202 | pub fn run() {
203 | // This is the same as the example above
204 | 1
205 | |> add(3)
206 | |> add(6)
207 | |> add(9)
208 | }
209 | ```
210 |
211 | The pipe operator will first check to see if the left hand value could be used
212 | as the first argument to the call, e.g. `a |> b(1, 2)` would become `b(a, 1, 2)`.
213 |
214 | If not it falls back to calling the result of the right hand side as a function
215 | , e.g. `b(1, 2)(a)`.
216 |
217 | ## Documentation
218 |
219 | You may add user facing documentation in front of function definitions with a
220 | documentation comment `///` per line. Markdown is supported and this text
221 | will be included with the module's entry in generated HTML documentation.
222 |
223 | ```gleam
224 | /// Does nothing, returns `Nil`.
225 | ///
226 | fn returns_nil(a) -> Nil {
227 | Nil
228 | }
229 | ```
230 |
231 | ## Stdlib references
232 |
233 | - [gleam/function](https://hexdocs.pm/gleam_stdlib/gleam/function.html)
234 |
--------------------------------------------------------------------------------
/img/lucy-pink-3.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
74 |
--------------------------------------------------------------------------------
/img/lucy-pink.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
74 |
--------------------------------------------------------------------------------