Docs fixes
Here are some potential docs fixes I found. I'm not sure if they're all correct so feel free to ignore any that are unwanted.
Page: Why Mojo🔥
When we started Modular, we had no intentions of building a new programming language.
"intentions" → "intention"
The journey there gives good confidence we can do this right for the Python community.
"gives good" → "gives us good"
... where incremental work put in for migration will yield incremental benefit.
"benefit" → "benefits"
For example, Mojo provides a backtick feature that allows use of any keyword as an identifier, ...
"allows use" → "allows the use"
Python is the dominant force in both the field ML and also ...
"field ML" → "ML field"
Python supports development of beautiful and expressive APIs ...
"supports development" → "supports the development"
... which led machine learning frameworks like TensorFlow and PyTorch embraced Python as ...
"embraced" → "to embrace"
More subjectively, we feel that Python is a beautiful language - designed with simple and composable abstractions, eschews needless punctuation that is redundant-in-practice with indentation, and built with powerful (dynamic) metaprogramming features ...
"and built" → "and is built"
Unfortunately, while this approach is an effective way to building high performance Python libraries, ...
"building" → "build"
The challenges with these approaches is that ...
"challenges" → "challenge"
Page: Mojo🔥 programming manual
Location: Overloaded functions and methods
When resolving a function call, Mojo tries each candidate and use the one that works (if only one works), or it picks the closest match (if it can determine a close match), or it reports that the call as ambiguous if it can’t figure out which one to pick.
"use" → "uses" "as ambiguous" → "is ambiguous"
Location: Using parameterized types and functions
fn funWithSIMD():
# Make a vector of 4 floats.
let smallVec = SIMD[DType.f32, 4](1.0, 2.0, 3.0, 4.0)
# Make a big vector containing 1.0 in bfloat16 format.
let bigVec = SIMD[DType.bf16, 32].splat(1.0)
# Do some math and convert the elements to float32.
let biggerVec = (bigVec+bigVec).cast[DType.f32]()
# You can write types out explicitly if you want of course.
let biggerVec2 : SIMD[DType.f32, 32] = biggerVec
Maybe these variables should use snake case to align with the standard Python style (small_vec, big_vec, bigger_vec, bigger_vec_2).
Location: The __copyinit__ and __moveinit__ special methods
This is more control than languages like Swift and Rust, which require values to at least be movable.
I think "offer" should be inserted after "Rust".
Location: Parameterization: compile time meta-programming
We have currently decided to reclaim the word “parameter”, “parameter expression” to mean compile time value, ...
Insert an "and" after the comma, like this:
word “parameter”, and “parameter expression” to mean compile time value, ...
Location: Autotuning / Adaptive compilation
best_idx = f_idx
I think this is supposed to be best_idx = i.
Location: Why argument conventions are important
e.g. “
__iadd__"? How does”let"work and ...
The double quotes could be fixed here, but it might look even better if they were removed altogether, like this:
e.g.
__iadd__? How doesletwork and ...
There are several other occurrences of double quotes around inline code elements on this page where I think the double quotes could be removed since they seem somewhat redundant, but that may just be my personal taste:
Location: fn definitions
- “
object”
Location: Defining parameterized types and functions
- “
SIMD[type, size]”
Location: “Borrowed” argument convention
- “
print_id” - “
const&” - “
const&” - “
use_something_big” - “
Int”, “Float”, and “SIMD” - “
@register_passable”
Location: “Owned” argument convention and postfix ^ operator
e.g., our
MyStringtype from earlier my be defined as:
"my" → "may"
Location: @register_passable struct decorator
it still needs to have a
__copyinit__method to be copyable, may still have a__init__and__del__methods, etc.
This reads strangely because the "a" is singular but "methods" is plural. I think the "a" can be removed:
it still needs to have a
__copyinit__method to be copyable, may still have__init__and__del__methods, etc.
Also in this section:
- instances of
@register_passabletypes do not have predictable identity, and so the ‘self’ pointer is not stable/predictable (e.g. in hash tables).
Maybe "have predictable" should be "have a predictable".
@register_passablearguments and result are exposed to C and C++ directly, instead of being passed by-pointer.
A space can be added between @register_passable and "arguments". And maybe "result" should be changed to "results" or "the result" to make it read more smoothly.
- The
__init__and__copyinit__methods of this type are implicitly static (like new in Python) and returns its result by-value instead of takingself&.
I think "and returns its result by-value" should be "and they return their results by-value".
Location: “Value Lifecycle”: Birth, life and death of a value
... we can look at how to put together together to model important types ...
I think "together together" is supposed to be "them together".
Location: Non-movable and non-copyable types
If we take a step up the ladder of sophistication, we’ll get to types that can be instantiated, but once they are pinned to an address in memory and cannot be implicitly moved or copied.
I think "and cannot" is supposed to be "they cannot".
Location: Unique “move-only” types
fn __moveinit__(self&, consuming existing: Self):
I think consuming existing: Self is supposed to be owned existing: Self. This occurs a second time on this page in the Types that support a “stealing move” section: fn __moveinit__(self&, consuming existing: Self): # as above
Also in this section, I think the code comment # This is the new. was supposed to be something like # This is the new key capability. (which is what the comment is in the example slightly below it.
Also in this section:
This is because instances of FileDescriptor may exist at different locations, and they can be logically moved around - stealing the body of one value and moving it another.
"it another" → "it to another"
Location: Copyable types
Each of these approaches has different tradeoffs, and Mojo takes the opinion that while we want a few common sets of collection types, that we can also support a wide range of specialized ones that focus on particular use cases.
"types, that we" → "types, we"
It implements the
__copyinit__, which maintains the invariant that each instance of MyString owns their underlying pointer and frees it on destruction.
"owns their" → "owns its"
Mojo destroys values eagerly, which allows it to use frequently transform copy+destroy pairs into a move operation, ...
"to use frequently transform" → "to frequently transform"
Location: @value decorator
There is no way to suppress generation of specific methods or customize generation at this time, ...
"suppress generation" → "suppress the generation"
Location: Behavior of destructors
Destroying values at the end of scope in C++ is problematic ...
Maybe "end of scope" should be "end of the scope".
Location: @parameter decorator
A particular aspect of this feature is that it allows closures that captures runtime values to be passed as parameter values.
"captures" → "capture"
Location: Field lifetimes of owned arguments in __del__and __moveinit__
In the section title, a space can be added between __del__ and "and".
Also in this section, there are two places where consume(^str1) is used, but I thought the ^ was supposed to be a postfix operator unless I'm confused and this is different than the postfix-^ "consume" operator.
Also in this section:
In this case, if “consume” implicitly refers to some value in str2 somehow,
this will ensure that str2 isn’t destroyed until the last use when it is accessed by the _ pattern.
Remove the extra line breaks between "somehow," and "this".
Location: Direct access to MLIR
Please take a look at the Low level IR in Mojo to learn how to use the
__mlir_type,__mlir_op,__mlir_typeconstructs.
I'm not sure, but I think the ending of this sentence was supposed to be "__mlir_type, __mlir_op, and __mlir_attr constructs".
All of the builtins and standard library is implemented by just calling ...
Maybe "and standard library" should be "and the standard library".
Page: Mandelbrot in Mojo with Python plots
Not only is Mojo great for writing high-performance code, but it also allows us to leverage huge Python ecosystem of libraries and tools.
"huge" → "the huge"
Page: Mojo🔥 roadmap & sharp edges
It can also be seen as an acknowledgement of ...
"acknowledgement" → "acknowledgment"
The later approach worked well for Swift ...
"later" → "latter"
Mojo aliases can refer to parametric values but themselves cannot be parameter.
"parameter" → "a parameter"
The rememdy is to manually “rebind” the type of x, ...
"rememdy" → "remedy"
... because you pass-by-value compact struct types without indirectin via the stack.
"indirectin" → "indirection"
@register_passable
struct IntTriple:
var x: Int
var y: Int
var z: Int
fn take_int_pair(v: IntPair):
pass
let v = IntPair{x: 1, y: 2, z: 3} # no address -- it isn't on the stack!
take_int_pair(v) # copy all elements
take_int_pair → take_int_triple
IntPair → IntTriple
For instance, DynamicVector will not raise an out-of-bounds accesses (it will crash),
"accesses" → "access"
We will circle back to this when more language features and language-level optimizations are avaiable.
"avaiable" → "available"
Other
Locaion: simd_strided_load
Perform a strided store of the SIMD vector.
"store" → "load"
The stride between stores.
"stores" → "loads"
Location: PrefetchOptions
possible locality values are:
NoLocality,LowLocality,MediumLocality,HighLocality, andVeryHighLocality.
I'm not sure if this is anything that needs to be fixed, but it seemed odd to me so I thought I'd mention it here just in case. The docs mention the possible VeryHighLocality value, but the highest PrefetchLocality alias is HIGH and the highest locality-related method is high_locality(), neither having a "very high" variant. So I wasn't sure if this inconsistency was intentional or not.
Also, when viewing the docs on an iPad using Chrome, toggling the light/dark-theme switch resets the scroll position to the top of the page.
Wow, thank you so much Elliot! @scottamain can you take a look at these next week?
Yes, thank you for all the suggestions!
No problem, happy to help. I've been enjoying learning about Mojo.
If the docs become available on GitHub in the future, I'll be sure to submit a PR instead, but hopefully this method of submitting docs suggestions works in the meantime.
+1, I'd like that too, we just have to get a bit more organized.
Sounds good. This works for me for now.
Woah, @scottamain, I just realized I worked with you at Google! Back around 2016. We were on different teams but your desk was pretty close to mine. Small world. Modular seems like a cool team to be a part of. Hope you're doing well.
Haha, yeah @elliotwaite! My reflexes recognized you and I didn't pause to realize you didn't have access to these files. 😆 Great to see you exploring Mojo! I've been at Modular for a month (it's awesome!) so still exploring it myself.
Haha, nice. Yeah, for a second there I thought there was another public repo I was unaware of, but that makes sense now.
I'm glad to hear you're enjoying it. It seems like an exciting time to be there. From what I've been seeing online, it seems like a lot of people are rooting for you guys.
Well, I should probably save the chitchat for somewhere other than this GitHub issue, but it's good to hear from you, and I'll be looking forward to reading your writing.
Thanks again @elliotwaite ! I believe all doc these issues have been resolved. Many are online now and others will be published soon.
As for the website toggle bug, this is a website framework issue and I can't repro on my mobile, so pretty low priority for us. But thanks for the heads up; I'll look out for similar issues.
Sounds good.