Skip to content

Commit

Permalink
various changes
Browse files Browse the repository at this point in the history
  • Loading branch information
giacomocavalieri authored and lpil committed Feb 2, 2025
1 parent 8a68cac commit bb1360d
Show file tree
Hide file tree
Showing 13 changed files with 127 additions and 134 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- Fixed a bug that would result in `list.unique` having quadratic runtime.
- Fixed the implementation of `list.key_set` to be tail recursive.

## v0.53.0 - 2025-01-23

Expand Down
4 changes: 2 additions & 2 deletions src/gleam/bit_array.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ fn is_utf8_loop(bits: BitArray) -> Bool {
fn is_utf8_loop(bits: BitArray) -> Bool {
case to_string(bits) {
Ok(_) -> True
_ -> False
Error(_) -> False
}
}

Expand Down Expand Up @@ -111,7 +111,7 @@ fn unsafe_to_string(a: BitArray) -> String
pub fn concat(bit_arrays: List(BitArray)) -> BitArray

/// Encodes a BitArray into a base 64 encoded string.
///
///
/// If the bit array does not contain a whole number of bytes then it is padded
/// with zero bits prior to being encoded.
///
Expand Down
2 changes: 1 addition & 1 deletion src/gleam/bytes_tree.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ pub fn prepend_tree(to second: BytesTree, prefix first: BytesTree) -> BytesTree
pub fn append_tree(to first: BytesTree, suffix second: BytesTree) -> BytesTree {
case second {
Many(trees) -> Many([first, ..trees])
_ -> Many([first, second])
Text(_) | Bytes(_) -> Many([first, second])
}
}

Expand Down
44 changes: 21 additions & 23 deletions src/gleam/dict.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ fn from_list_loop(
) -> Dict(k, v) {
case list {
[] -> initial
[x, ..rest] -> from_list_loop(rest, insert(initial, x.0, x.1))
[#(key, value), ..rest] -> from_list_loop(rest, insert(initial, key, value))
}
}

Expand Down Expand Up @@ -210,21 +210,20 @@ fn do_map_values(f: fn(k, v) -> a, dict: Dict(k, v)) -> Dict(k, a) {
///
@external(erlang, "maps", "keys")
pub fn keys(dict: Dict(k, v)) -> List(k) {
let list_of_pairs = to_list(dict)
do_keys_loop(list_of_pairs, [])
}

fn reverse_and_concat(remaining: List(a), accumulator: List(a)) -> List(a) {
case remaining {
[] -> accumulator
[item, ..rest] -> reverse_and_concat(rest, [item, ..accumulator])
}
do_keys_loop(to_list(dict), [])
}

fn do_keys_loop(list: List(#(k, v)), acc: List(k)) -> List(k) {
case list {
[] -> reverse_and_concat(acc, [])
[first, ..rest] -> do_keys_loop(rest, [first.0, ..acc])
[#(key, _value), ..rest] -> do_keys_loop(rest, [key, ..acc])
}
}

fn reverse_and_concat(remaining: List(a), accumulator: List(a)) -> List(a) {
case remaining {
[] -> accumulator
[first, ..rest] -> reverse_and_concat(rest, [first, ..accumulator])
}
}

Expand All @@ -250,7 +249,7 @@ pub fn values(dict: Dict(k, v)) -> List(v) {
fn do_values_loop(list: List(#(k, v)), acc: List(v)) -> List(v) {
case list {
[] -> reverse_and_concat(acc, [])
[first, ..rest] -> do_values_loop(rest, [first.1, ..acc])
[#(_key, value), ..rest] -> do_values_loop(rest, [value, ..acc])
}
}

Expand Down Expand Up @@ -283,7 +282,7 @@ fn do_filter(f: fn(k, v) -> Bool, dict: Dict(k, v)) -> Dict(k, v) {
let insert = fn(dict, k, v) {
case f(k, v) {
True -> insert(dict, k, v)
_ -> dict
False -> dict
}
}

Expand Down Expand Up @@ -324,7 +323,7 @@ fn do_take_loop(
let insert = fn(taken, key) {
case get(dict, key) {
Ok(value) -> insert(taken, key, value)
_ -> taken
Error(_) -> taken
}
}
case desired_keys {
Expand Down Expand Up @@ -354,17 +353,17 @@ pub fn merge(into dict: Dict(k, v), from new_entries: Dict(k, v)) -> Dict(k, v)
|> fold_inserts(dict)
}

fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) {
insert(dict, pair.0, pair.1)
}

fn fold_inserts(new_entries: List(#(k, v)), dict: Dict(k, v)) -> Dict(k, v) {
case new_entries {
[] -> dict
[first, ..rest] -> fold_inserts(rest, insert_pair(dict, first))
}
}

fn insert_pair(dict: Dict(k, v), pair: #(k, v)) -> Dict(k, v) {
insert(dict, pair.0, pair.1)
}

/// Creates a new dict from a given dict with all the same entries except for the
/// one with a given key, if it exists.
///
Expand Down Expand Up @@ -443,11 +442,10 @@ pub fn upsert(
update key: k,
with fun: fn(Option(v)) -> v,
) -> Dict(k, v) {
dict
|> get(key)
|> option.from_result
|> fun
|> insert(dict, key, _)
case get(dict, key) {
Ok(value) -> insert(dict, key, fun(option.Some(value)))
Error(_) -> insert(dict, key, fun(option.None))
}
}

/// Combines all entries into a single value by calling a given function on each
Expand Down
12 changes: 6 additions & 6 deletions src/gleam/dynamic/decode.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,7 @@ pub fn run(data: Dynamic, decoder: Decoder(t)) -> Result(t, List(DecodeError)) {
let #(maybe_invalid_data, errors) = decoder.function(data)
case errors {
[] -> Ok(maybe_invalid_data)
_ -> Error(errors)
[_, ..] -> Error(errors)
}
}

Expand Down Expand Up @@ -784,7 +784,7 @@ pub fn dict(
// don't need to run the decoders, instead return the existing acc.
case a.1 {
[] -> fold_dict(a, k, v, key.function, value.function)
_ -> a
[_, ..] -> a
}
})
}
Expand Down Expand Up @@ -897,7 +897,7 @@ pub fn collapse_errors(decoder: Decoder(a), name: String) -> Decoder(a) {
let #(data, errors) as layer = decoder.function(dynamic_data)
case errors {
[] -> layer
_ -> #(data, decode_error(name, dynamic_data))
[_, ..] -> #(data, decode_error(name, dynamic_data))
}
})
}
Expand All @@ -913,7 +913,7 @@ pub fn then(decoder: Decoder(a), next: fn(a) -> Decoder(b)) -> Decoder(b) {
let #(data, _) as layer = decoder.function(dynamic_data)
case errors {
[] -> layer
_ -> #(data, errors)
[_, ..] -> #(data, errors)
}
})
}
Expand Down Expand Up @@ -944,7 +944,7 @@ pub fn one_of(
let #(_, errors) as layer = first.function(dynamic_data)
case errors {
[] -> layer
_ -> run_decoders(dynamic_data, layer, alternatives)
[_, ..] -> run_decoders(dynamic_data, layer, alternatives)
}
})
}
Expand All @@ -961,7 +961,7 @@ fn run_decoders(
let #(_, errors) as layer = decoder.function(data)
case errors {
[] -> layer
_ -> run_decoders(data, failure, decoders)
[_, ..] -> run_decoders(data, failure, decoders)
}
}
}
Expand Down
27 changes: 12 additions & 15 deletions src/gleam/float.gleam
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
//// Functions for working with floats.
////
////
//// ## Float representation
////
////
//// Floats are represented as 64 bit floating point numbers on both the Erlang
//// and JavaScript runtimes. The floating point behaviour is native to their
//// respective runtimes, so their exact behaviour will be slightly different on
//// the two runtimes.
////
//// the two runtimes.
////
//// ### Infinity and NaN
////
////
//// Under the JavaScript runtime, exceeding the maximum (or minimum)
//// representable value for a floating point value will result in Infinity (or
//// -Infinity). Should you try to divide two infinities you will get NaN as a
//// result.
////
//// result.
////
//// When running on BEAM, exceeding the maximum (or minimum) representable
//// value for a floating point value will raise an error.
////
Expand Down Expand Up @@ -240,7 +240,7 @@ pub fn floor(x: Float) -> Float
pub fn round(x: Float) -> Int {
case x >=. 0.0 {
True -> js_round(x)
_ -> 0 - js_round(negate(x))
False -> 0 - js_round(negate(x))
}
}

Expand Down Expand Up @@ -311,7 +311,7 @@ fn do_to_float(a: Int) -> Float
pub fn absolute_value(x: Float) -> Float {
case x >=. 0.0 {
True -> x
_ -> 0.0 -. x
False -> 0.0 -. x
}
}

Expand Down Expand Up @@ -409,7 +409,7 @@ pub fn sum(numbers: List(Float)) -> Float {

fn sum_loop(numbers: List(Float), initial: Float) -> Float {
case numbers {
[x, ..rest] -> sum_loop(rest, x +. initial)
[first, ..rest] -> sum_loop(rest, first +. initial)
[] -> initial
}
}
Expand All @@ -424,15 +424,12 @@ fn sum_loop(numbers: List(Float), initial: Float) -> Float {
/// ```
///
pub fn product(numbers: List(Float)) -> Float {
case numbers {
[] -> 1.0
_ -> product_loop(numbers, 1.0)
}
product_loop(numbers, 1.0)
}

fn product_loop(numbers: List(Float), initial: Float) -> Float {
case numbers {
[x, ..rest] -> product_loop(rest, x *. initial)
[first, ..rest] -> product_loop(rest, first *. initial)
[] -> initial
}
}
Expand Down
19 changes: 7 additions & 12 deletions src/gleam/int.gleam
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,7 @@ pub fn absolute_value(x: Int) -> Int {
/// ```
///
pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) {
base
|> to_float()
to_float(base)
|> float.power(exponent)
}

Expand All @@ -85,8 +84,7 @@ pub fn power(base: Int, of exponent: Float) -> Result(Float, Nil) {
/// ```
///
pub fn square_root(x: Int) -> Result(Float, Nil) {
x
|> to_float()
to_float(x)
|> float.square_root()
}

Expand Down Expand Up @@ -420,7 +418,7 @@ pub fn sum(numbers: List(Int)) -> Int {

fn sum_loop(numbers: List(Int), initial: Int) -> Int {
case numbers {
[x, ..rest] -> sum_loop(rest, x + initial)
[first, ..rest] -> sum_loop(rest, first + initial)
[] -> initial
}
}
Expand All @@ -435,15 +433,12 @@ fn sum_loop(numbers: List(Int), initial: Int) -> Int {
/// ```
///
pub fn product(numbers: List(Int)) -> Int {
case numbers {
[] -> 1
_ -> product_loop(numbers, 1)
}
product_loop(numbers, 1)
}

fn product_loop(numbers: List(Int), initial: Int) -> Int {
case numbers {
[x, ..rest] -> product_loop(rest, x * initial)
[first, ..rest] -> product_loop(rest, first * initial)
[] -> initial
}
}
Expand Down Expand Up @@ -535,8 +530,8 @@ fn undigits_loop(numbers: List(Int), base: Int, acc: Int) -> Result(Int, Nil) {
///
pub fn random(max: Int) -> Int {
{ float.random() *. to_float(max) }
|> float.floor()
|> float.round()
|> float.floor
|> float.round
}

/// Performs a truncated integer division.
Expand Down
Loading

0 comments on commit bb1360d

Please sign in to comment.