内容简介:Thanks to all our new contributors Gleam’s development is faster than ever and it’s time for another release! Let’s take a look.The main way that errors are represented and handled in Gleam is through the Result type. It’s baked into the language itself, b
Thanks to all our new contributors Gleam’s development is faster than ever and it’s time for another release! Let’s take a look.
Improved error handling
The main way that errors are represented and handled in Gleam is through the Result type. It’s baked into the language itself, but if you were to implement it in a library it would be implemented like so:
pub type Result(success_value, failure_detail) { Ok(success_value) Error(failure_detail) }
If a function can fail then it returns a Result, wrapping a successful return value in an Ok record, or returning detail on the failure in an Error record if it’s not successful.
// parse_int(String) -> Result(Int, String) parse_int("123") // -> Ok(123) parse_int("erl") // -> Error("expected a number, got `erl`")
When a function returns a Result we can pattern match on it to handle success and failure:
case parse_int("123") { Error(e) -> io.println("That wasn't an Int") Ok(i) -> io.println("We parsed the Int") }
This works but if you need to handle multiple Result values in the same function then it becomes verbose, and the error handling obscures the business logic.
case parse_int(a) { Error(e) -> Error(e) Ok(int_a) -> case parse_int(b) { Error(e) -> Error(e) Ok(int_b) -> Ok(int_a) -> case parse_int(c) { Error(e) -> Error(e) Ok(int_c) -> Ok(int_a + int_b + int_c) } } }
With this release Gleam now has the try
keyword which makes error handling
easier and more concise. Rewritten using try
the previous example looks like
this:
try int_a = parse_int(a) try int_b = parse_int(b) try int_c = parse_int(c) Ok(int_a + int_b + int_c)
When a variable is declared using try
Gleam checks to see whether the value
is an Error or an Ok record. If it’s an Ok then the inner value is assigned to
the variable:
try x = Ok(1) Ok(x + 1) // -> Ok(2)
If it’s an Error then the Error is returned immediately:
try x = Error("failure") Ok(x + 1) // -> Error("failure")
We’ve been testing try
in our applications for a while and we’re very happy
with how it cleans up error handling. Why not give it a try? :stuck_out_tongue_winking_eye:
Opaque types
Gleam’s new opaque type feature allows a library writer to export a custom type without exporting the internal details of the type.
// in src/box.gleam pub opaque type Box { Box(inner_value: Int) } pub fn new(x: Int) -> Box { Box(inner_value: x) }
If another module imports this custom type they will be able to create a Box
using the new
function, but they cannot call the Box
constructor, use the .inner_value
accessor, or pattern match on a Box to get the inner value.
import box let one = box.new(1) // This is permitted one.inner_value // Compile error! let box.Box(i) = one // Compile error! box.Box(1) // Compile error!
This feature is great for creating a carefully controlled API for your data types, hiding any private implementation details to ensure that they are used correctly, which brings us to the next features:
standard library additions
The standard library has gained a wealth of new modules, types, and functions. Here’s some of the highlights, some of which were made possible with the new opaque type feature.
Iterator
The new Iterator type is a lazily evaluated sequence of elements, similar to the Stream type in Elixir.
Iterators are useful when working with collections that are too large to fit in memory (or those that are infinite in size) as they only require the elements currently being processed to be in memory.
Here we can see the Iterator type used to create an infinitely long sequence of Ints, which is then mapped over, and the first 5 elements are evaluated.
import gleam/iterator let double = fn(x) { x * 2 } [1, 2, 3] |> iterator.from_list // Create a 3 element iterator |> iterator.cycle // Repeat the iterator forever |> iterator.map(double) // Double each element |> iterator.take(5) // Evaluate the first 5 elements // -> [2, 4, 6, 2, 4]
Because Iterators are lazy even though this Iterator has infinite size the double
function is only called 5 times.
For more information see the iterator documentation .
Set
A Set is a collection value. Unlike a List is it unordered, cannot contain duplicate values, and finding a value in a Set is very fast.
import gleam/set let pop_band = set.new(["Iris", "Karl", "Priya"]) set.contains(pop_band, "Iris") // -> True set.contains(pop_band, "Martin") // -> False
For more information see the set documentation .
Queue
A Queue is an ordered collection of elements. It’s similar to a List, however it’s fast to add and remove from both ends of a queue, while a list can only be quickly accessed from the front.
import gleam/queue queue.new() |> queue.push_front(1) |> queue.push_front(2) |> queue.push_back(3) |> queue.push_back(4) |> queue.to_list // -> [2, 1, 3, 4]
For more information see the queue documentation .
Option
Option is a type used to represent values which may be present or absent, making it similar to nullable values in other languages. It’s defined like so:
pub type Option(a) { Some(a) None }
If an optional Int “ some_int
” is present it’s represented as Some(the_int)
, while if it’s absent it’s None
.
For more information see the option documentation .
The rest
Other additions to the standard library include an io
module, additions to
the result
, dynamic
, list
, and string
modules, and some changes to
labels to make them more consistent. For full details see the
changelog
.
Other additions to the compiler include improvements to the formatter style,
the ability to include additional markdown pages in generated code
documentation, initial support for Elixir’s mix
build tool, type annotations
on let
+ assert
+ try
, custom type support in case clause guards, and
several bug fixes. For more info see the changelog
Thanks
It would not have been possible to have a release this big without the support of all Gleam’s sponsors and contributors, so a huge thank you to them:
- Al Dee
- Arian Daneshvar
- Arno Dirlam
- Bruno Dusausoy
- Bruno Michel
- Bryan Paxton
- BSKY
- Chris Young
- Christian Wesselhoeft
- Clever Bunny LTD
- David cao
- Erik Terpstra
- Fernando Briano
- Hasan YILDIZ
- Hécate
- John Palgut
- José Valim
- Kasim Tuman
- kyle-sammons
- Lars Wikman
- Michael Borohovski
- ontofractal
- Parker Selbert
- Peter Saxton
- Quinn Wilton
- Regan Heath
- Sasan Hezarkhani
- Sascha Wolf
- Saša Jurić
- Sebastian Porto
- Simone Vittori
- Sylvan Morris
- Tom Whatmore
- Tyler Wilcock
If you would like to help make strongly typed programming on the Erlang virtual machine a production-ready reality please consider sponsoring Gleam via the GitHub Sponsors program.
Thanks for reading! Have fun! :purple_heart:
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
现代应用数学手册
《现代应用数学手册》编委会 / 清华大学出版社 / 2005-1-1 / 48.00元
本书是进行科学计算的常备工具书,内容新颖,查阅方便,实用性强。主要介绍生产、科研、管理、数学等实践中在计算机上使用的各种计算方法和技巧。全书分为14章,依次为数值计算概论、插值法、函数逼近与曲线拟合、数值积分与数值微分、方程求根、线性方程组的直接解法和迭代解法、矩阵特征值问题、非线性方程组数值解与最优化方法、常微分方程初值问题和边值问题的数值解法、偏微分方程的数值解法、多重网络法和积分方程数值解法......一起来看看 《现代应用数学手册》 这本书的介绍吧!