I went through the Gleam Language Tour jotting down various small questions, things I wondered about or stuff I found somewhat weird/unclear there or in stdlib. All of the items are pretty minor: no showstoppers, just random bits and thoughts of someone new to the language (and somewhat new to the [typed] FP — my only previous experiences are some Elm in the recent past and some old Scala a long time ago).
Some may read as a bit blunt but it's not meant to criticize the language (I actually really liked it!) — they were meant as a list of questions or things to look up later for me.
Just thought maybe they may have some value for language/tour authors too?
#List of questions/thoughts from Gleam Language Tour
1 messages · Page 1 of 1 (latest)
-
gleam/int&gleam/float:
Why doesdividereturnError(Nil)when dividing by 0 instead of 0 (like/)? -
gleam/int:
There isfloor_dividein addition todivide. Why noceil_divide(and maybe alsoround_division)? -
gleam/int:
It might be nice to have a function for divison that simultaneously returns both modulo and reminder. -
gleam/float:
Why doesroundreturnIntbutfloorandceilingreturnFloat? -
gleam/float:
There islogarithmwhich is a natural logarith, but it seems like there is no something likelogarithm_base(base: Float, of num: Float)(yes, I do know that formula). -
gleam/float:
No trig functions in stdlib?! -
Tour/Floats:
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.
So... how do I deal withNaNandInfinityin those cases? Those don't seem to be valid literals or type variants... I'm confused.
-
Tour/Strings:
Huh, it's pretty neat that I can just use single quotes even for multiline strings! Though it's a bit annoying that single quotes are the only option and there are no alternative syntax to avoid having to always escape quotes that are inside strings.
Also it seems like multiline strings always treat indentation as actual content of the string but there is no stdlib function a-la Python'stextwrap.dedentto automatically deal with that. Though I liked the way Swift dealt with it: it requires multiline strings to start on a new line and the closing quotes are used to mark the indentation level, so you can indent your multiline strings along with the rest of the code but all the spaces that are used purely for code indentation are omitted from the content of the string.
Though I guess Swift-like behavior is still theoretically possible if Gleam chooses to add alternative string syntaxes (either for template strings or just to avoid\"), e.g."""..."""or something that looks more like blocks{"..."}(kinda like in djot). -
Tour/Strings:
Tried to google how to do string interpolation or template string: apparently it's not possible (at least not yet, because there is a proposal). -
gleam/string:
concatseems to have a copy-pasted section of docs fromappend:
This function copies both Strings and runs in linear time. If you find yourself joining Strings frequently consider using the string_tree module as it can append Strings much faster!
concatoperates on an arbitrarily long list of strings not on "both". I assume they probably mean that it usesappendover and over so the same issues apply?
gleam/bool:
Why isexclusive_*not shortened tox*? E.g. why is itexclusive_norand notxnororexclusive_negated_or?
- Tour/Type annotations:
Type annotations may be useful for documentation purposes, but they do not change how Gleam type checks the code beyond ensuring that the annotation is correct.
Maybe I misunderstand something, but I feel like they do change how Gleam type checks the code. For example, choosing to add/omit annotations and changing type parameters of phantom types changes whether the program typechecks or not.
-
Tour/Type imports:
Why istypekeyword required when importing types? Is it to prevent some kinds of collisions? Isn't it obvious that the thing that's imported is a type since its name starts with a capital letter? -
Tour/Generic functions:
Type variables are not like an
anytype, they get replaced with a specific type each time the function is called.
Does this mean that they are not likeanytype in TypeScript, or isanya reserved special type in Gleam too?
-
Tour/Labelled arguments:
Initially I thought labelled arguments are similar to Swift's but there are no mandatory/optional labels (the language lets me completely omit any labels when calling a function), and it doesn't enforce the order of the arguments either, so they behave more like keyword arguments in Python (albeit with outward-facing labels). Not sure which approach I like more, but I do like that outward-facing labels are a thing. Gotta play more with that. -
Tour/Documentation comments
Why is there an empty///commented line above functions? Is it a convention? -
gleam/bool:
There isint.randomandfloat.randombut nobool.random🙁 -
Tour/String patterns:
It seems like I can match strings by prefix but not by suffix (question <> "?" -> ...) or both? That's unexpected. I wonder why?
Also it would've been cool if I could use template strings for pattern matching.
-
Tour/List patterns:
Matching on list's ending like[.., 4] -> "Ends with 4"is not allowed too. I assume that's to discourage it because it's slow/list is the wrong data structure for doing that? -
Tour/Multiple subjects
Is this the same as patter matching on tuples? Or is it possible to use some patters when matching tuples that are not restricted to exactly n patterns for an n-tuple? Or maybe it's the other way around? -
Tour/Alternative patterns:
Currently it is not possible to have nested alternative patterns, so the pattern [1 | 2 | 3] is not valid.
I like that it explicitly states it because that's exactly what I wanted to try to do.
- Tour/Guards:
Guard expressions cannot contain function calls, case expressions, or blocks.
The "or blocks" scared me a bit because I thought that stuff like[first, ...] if first > 2 * {limit + 1}wouldn't work. But it does!
-
Tour/Tuples:
Apparently I cannot match using#(first, ..rest) -> ...on tuples. I wonder why not?
I still don't know if/how tuple pattern matching differs from multiple subjects. -
Tour/Records:
Can records only exist withing a specific type variant? Are there no "general" records like Elm's{value: Type, other: OtherType}? If so I assume there are no things like extensible records either?
- Tour/Record accessors:
This is a somewhat confusing paragraph:
The accessor syntax can always be used for fields with the same name that are in the same position and have the same type for all variants of the custom type. Other fields can only be accessed when the compiler can tell which variant the value is, such after pattern matching in a case expression.
I tried experimenting in the editor by adding additionalidfield to both variants but in differing positions and of different types:
pub type SchoolPerson {
Teacher(name: String, id: String, subject: String)
Student(id: Int, name: String)
}
...and I got no compile errors, echo still works printing both *.id values. Weird? Still not sure what exactly that paragraph actually meant.
-
Tour/Record pattern matching:
Starfish(name: String, favourite_color: String). Huh, I wonder if I finally encoutnered a programming language that actually settled on British spelling as the convention for naming things? Gotta check stdlib. -
Tour/Dict module:
Why does the output of echoed dicts look so strange?
That's it
- So you can handle it as an error instead of 0
- no particular reason
- Nope. stdlib includes things that are very commonly used and maths generally going in maths packages
- Gleam doesn't have those
- Open an issue for this mistakes please 🙏
- We don't use cryptic abbreviations in Gleam. You may have learnt what that shorthand means, but that doesn't means other people know what it means
- Outside of record accessor use in some situations it does not change type checking. Using annotations for functions is recommended and standard though
- To know if you want to import from the type or value namespace. Values can start with capital letters too- custom type variants
- There is no any in Gleam
- Legibility, convention of the codebase
- I'm sure you can manage that implementation
- VM support, performance
- Pattern matching is fast, there's no literal syntax for slow things or for things we don't want to encourage. The language is designed to make the wrong thing harder to do than the right thing
- No, tuples are fixed length tuples, not variable length arrays
- Tuples are fixed length
- No ad hoc records. No extensible records.
- That's because the compiler knows which variant you're using in that context
- The BEAM ecosystem (Erlang, Elixir, Gleam, LFE, etc) uses British/Australian spelling due to being made by Brits and Aussies
- There's no literal syntax for dics. See also Haskell
Wow, thank you so much for taking your time to answer those!
Some of those 😛
favourite_color
🤔
- What happens in JS there will happen in Gleam, except there's no way to detect it in Gleam (this goes for both ints and floats). In case you want arbitrary precision integers in JS, you can use https://hexdocs.pm/bigi/index.html.
Sorry, I'm not really sure what you meant here. I mean that in the Tour the output of echoing a dict looks like this //js(Dict { "root": //js({ "type": 2, "bitmap": -2138832896, "array": #(//js({ "type": 0, "k": "Darius", "v": 14 }), //js({ "type": 0, "k": "Bushra", "v": 16 }), //js({ "type": 0, "k": "Lucy", "v": 13 })) }), "size": 3 })
Instead of being a list of key-value tuples or something like that
Oh yeah that's a bug. The intended syntax is dict.from_list([#(key, value), #(key, value)])
Seems like this has something to do with the wasm compiler specifically? Or using a browser. It works fine when I run it on my machine
Oh, I see
I played around more with it and now I get it. I wonder why does the order matter? I would've expected it to work if all fields of the same name had the same type. Not a problem, just curious
The issue for the echo dict?
Yup
It's due to how custom types are represented in Erlang. They're a tuple where the first element is the tag defining which variant it is, followed by all the fields. If the order is different, it will appear in different places in the tuple so they can't be accessed the same
Should I raise it in gleam-lang/gleam or gleam-lang/playground (if that's what powers the Tour)? (it is reproduced in playground)
playground sounds good
Oh, that's interesting! I understand now, thanks!
26 is funny to me because it uses the american 'color'
oh yes