Skip to content

Commit

Permalink
Merge branch 'nightly' into heap-proposal
Browse files Browse the repository at this point in the history
  • Loading branch information
bgreni authored Jan 16, 2025
2 parents 9310377 + ccdb14a commit 9bec4f3
Show file tree
Hide file tree
Showing 152 changed files with 10,427 additions and 2,137 deletions.
85 changes: 81 additions & 4 deletions docs/changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,70 @@ what we publish.
var y : Int = x[idx] # Just works!
```

- You can now overload positional arguments with a keyword-only argument, and
keyword-only arguments with different names:

```mojo
struct OverloadedKwArgs:
var val: Int
fn __init__(out self, single: Int):
self.val = single
fn __init__(out self, *, double: Int):
self.val = double * 2
fn __init__(out self, *, triple: Int):
self.val = triple * 3
fn main():
OverloadedKwArgs(1) # val=1
OverloadedKwArgs(double=1) # val=2
OverloadedKwArgs(triple=2) # val=3
```

This also works with indexing operations:

```mojo
struct OverloadedKwArgs:
var vals: List[Int]
fn __init__(out self):
self.vals = List[Int](0, 1, 2, 3, 4)
fn __getitem__(self, idx: Int) -> Int:
return self.vals[idx]
fn __getitem__(self, *, idx2: Int) -> Int:
return self.vals[idx2 * 2]
fn __setitem__(mut self, idx: Int, val: Int):
self.vals[idx] = val
fn __setitem__(mut self, val: Int, *, idx2: Int):
self.vals[idx2 * 2] = val
fn main():
var x = OverloadedKwArgs()
print(x[1]) # 1
print(x[idx2=1]) # 2
x[1] = 42
x[idx2=1] = 84
print(x[1]) # 42
print(x[idx2=1]) # 84
```

### Standard library changes

- The `int` function to construct an `Int` has been removed, this was a
temporary workaround when Mojo didn't have a way to distinguish between
implicit and explicit constructors. You can do a search and replace for `int(`
to `Int(` to update your programs.
- These functions have been deprecated: `int`, `str` in favor of constructors:
`Int`, `String`. The functions were a temporary workaround for when Mojo
didn't have a way to distinguish between implicit and explicit constructors.
You can do a search and replace e.g. from `int(` to `Int(` to update your
programs. This release will show a deprecation warning for the old functions,
and they'll be removed in the next release.

- `UnsafePointer`'s `bitcast` method has now been split into `bitcast`
for changing the type, `origin_cast` for changing mutability,
Expand Down Expand Up @@ -111,6 +169,10 @@ what we publish.
`Stringable`.
- Added `String` constructor from `Char`
- `Char` can be converted to `UInt32` via `Char.to_u32()`.
- `Char` provides methods for categorizing character types, including:
`Char.is_ascii()`, `Char.is_posix_space()`, `Char.is_python_space()`,
`Char.is_ascii_digit()`, `Char.is_ascii_upper()`, `Char.is_ascii_lower()`,
`Char.is_ascii_printable()`.
- `chr(Int)` will now abort if given a codepoint value that is not a valid
`Char`.
Expand All @@ -119,6 +181,10 @@ what we publish.
a `StringSlice` from a buffer containing UTF-8 encoded data. This method will
raise if the buffer contents are not valid UTF-8.
- Added `StringSlice.chars()` which returns an iterator over `Char`s. This is a
compliant UTF-8 decoder that returns each Unicode codepoint encoded in the
string.
- Several standard library functions have been changed to take `StringSlice`
instead of `String`. This generalizes them to be used for any appropriately
encoded string in memory, without requiring that the string be heap allocated.
Expand Down Expand Up @@ -149,6 +215,15 @@ what we publish.
has narrower comparison methods that support comparing only with
`StringSlice`'s with the exact same origin.
- Added `StringSlice.char_length()` method, to pair with the existing
`StringSlice.byte_length()` method.
In a future version of Mojo, `StringSlice.__len__()` may be changed to return
the length in bytes, matching the convention of string length methods in
languages like C++ and Rust. Callers that know they need the length in
Unicode codepoints should update to calling `StringSlice.char_length()`
instead.
- Removed `@implicit` decorator from some standard library initializer methods
that perform allocation. This reduces places where Mojo code could implicitly
allocate where the user may not be aware.
Expand Down Expand Up @@ -215,6 +290,8 @@ what we publish.

- You can now use `max()` and `min()` with variadic number of arguments.

- A new `LinkedList` type has been added to the standard library.

### Tooling changes

- mblack (aka `mojo format`) no longer formats non-mojo files. This prevents
Expand Down
12 changes: 6 additions & 6 deletions docs/manual/errors.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,12 @@ recovery that's appropriate for your application.

If you provide the name of a variable after the `except` keyword, then the
`Error` instance is bound to the variable if an error occurs. The `Error` type
implements the [`Writable`](/mojo/stdlib/utils/write/Writable) trait, so
you can pass it as an argument to the [`print()`](/mojo/stdlib/builtin/io/print)
implements the [`Writable`](/mojo/stdlib/utils/write/Writable) trait, so you can
pass it as an argument to the [`print()`](/mojo/stdlib/builtin/io/print)
function if you'd like to print its error message to the console. It also
implements the [`Stringable`](/mojo/stdlib/builtin/str/Stringable) trait, so you
can pass it to the [`str()`](/mojo/stdlib/builtin/str/str) function if you want
to extract the error message as a `String` for further processing.
can construct a `String` with `String(error)` if you want to extract the error
message as a `String` for further processing.

If desired, you can re-raise an error condition from your `except` clause simply
by executing a `raise` statement from within its code block. This can be either
Expand Down Expand Up @@ -152,7 +152,7 @@ def main():
print("try =>", value[])
if value[] == 1:
continue
result = str("{} incremented is {}").format(value[], incr(value[]))
result = String("{} incremented is {}").format(value[], incr(value[]))
except e:
print("except =>", e)
else:
Expand Down Expand Up @@ -384,7 +384,7 @@ struct ConditionalTimer:
print("Elapsed time:", elapsed_time_ms, "milliseconds")
fn __exit__(mut self, e: Error) raises -> Bool:
if str(e) == "just a warning":
if String(e) == "just a warning":
print("Suppressing error:", e)
self.__exit__()
return True
Expand Down
4 changes: 2 additions & 2 deletions docs/manual/functions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -364,12 +364,12 @@ fn print_string(s: String):
print(s, end="")
fn print_many[T: Stringable, *Ts: Stringable](first: T, *rest: *Ts):
print_string(str(first))
print_string(String(first))
@parameter
fn print_elt[T: Stringable](a: T):
print_string(" ")
print_string(str(a))
print_string(String(a))
rest.each[print_elt]()
print_many("Bob")
```
Expand Down
15 changes: 8 additions & 7 deletions docs/manual/get-started.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: "Get started with Mojo"
sidebar_label: "Tutorial: Get started with Mojo"
description: "Install Mojo and learn the language basics by building a complete Mojo program"
github_url: https://github.com/modularml/mojo/tree/nightly/examples/life
image: /images/artwork/mojo-get-started.jpg
---

import GetMagic from '@site/src/includes/get_magic.mdx';
Expand Down Expand Up @@ -646,11 +647,11 @@ produces the same output. You can verify that by running the program again.

## 9. Implement support for the `StringableRaising` trait

You can pass most Mojo types to the built-in `str()` function to produce a
You can convert most Mojo types to `String` using `String(my_val)` to produce a
`String` representation of that instance. But you'll get an error if you try to
do that with our current implementation of `Grid`. So let's fix that.

Because the Mojo compiler performs static type checking, a function like `str()`
Because the Mojo compiler performs static type checking, a `String` constructor
can accept a value only if its type implements some required behavior—in this
case, it only accepts types that can generate a `String` representation.

Expand All @@ -662,7 +663,7 @@ any type that conform to a specified trait. (This type of function is sometimes
referred to as a [*generic*
function](/mojo/manual/parameters/#parameters-and-generics).)

In the case of `str()`, it requires a type to conform to either the `Stringable`
In the case of `String()`, it requires a type to conform to either the `Stringable`
or `StringableRaising` trait. Each trait requires a conforming type to implement
a `__str__()` method that returns a `String` representation. The only difference
between the two traits is that `Stringable` requires that the method *cannot*
Expand Down Expand Up @@ -691,13 +692,13 @@ struct Grid(StringableRaising):
...
```

Now let's verify that `str()` works with an instance of `Grid`.
Now let's verify that `String()` works with an instance of `Grid`.

```mojo title="life.mojo"
def main():
...
start = Grid(8, 8, glider)
print(str(start))
print(String(start))
```

If you run the program again, you should still see the same glider pattern as before.
Expand Down Expand Up @@ -895,7 +896,7 @@ and print it.
def main():
start = Grid.random(8, 16)
print(str(start))
print(String(start))
```

Run the program a few times to verify that it generates a different grid each
Expand Down Expand Up @@ -1008,7 +1009,7 @@ from gridv1 import Grid
def run_display(owned grid: Grid) -> None:
while True:
print(str(grid))
print(String(grid))
print()
if input("Enter 'q' to quit or press <Enter> to continue: ") == "q":
break
Expand Down
7 changes: 4 additions & 3 deletions docs/manual/operators.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1100,7 +1100,7 @@ c2: Real: 3.1415899999999999; Imaginary: 0.0
To make it simpler to print `Complex` values, let's implement the
[Writable](/mojo/stdlib/utils/write/Writable) trait. While we're at it, let's
also implement the [`Stringable`](/mojo/stdlib/builtin/str/Stringable) trait so
that we can use the `str()` function to generate a `String` representation of a
that we can use the `String()` constructor to generate a `String` representation of a
`Complex` value. You can find out more about these traits and their associated
methods in [The `Stringable`, `Representable`, and `Writable`
traits](/mojo/manual/traits#the-stringable-representable-and-writable-traits).
Expand Down Expand Up @@ -1137,13 +1137,14 @@ between defining functions with `def` and `fn`.
:::

Now we can print a `Complex` value directly, and we can explicitly generate a
`String` representation by passing a `Complex` value to `str()`.
`String` representation by passing a `Complex` value to `String.write()` which
constructs a new `String` from all the arguments passed to it.

```mojo
c3 = Complex(3.14159, -2.71828)
print("c3 =", c3)
var msg: String = "The value is: " + str(c3)
var msg = String.write("The value is: ", c3)
print(msg)
```

Expand Down
28 changes: 13 additions & 15 deletions docs/manual/parameters/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ conforms to the [`Stringable`](/mojo/stdlib/builtin/str/Stringable) trait:
fn repeat[MsgType: Stringable, count: Int](msg: MsgType):
@parameter
for i in range(count):
print(str(msg))
print(String(msg))
# Must use keyword parameter for `count`
repeat[count=2](42)
Expand All @@ -125,7 +125,7 @@ by the argument. Now you can pass the following parameter `count` positionally:
fn repeat[MsgType: Stringable, //, count: Int](msg: MsgType):
@parameter
for i in range(count):
print(str(msg))
print(String(msg))
# MsgType is always inferred, so first positional keyword `2` is passed to `count`
repeat[2](42)
Expand Down Expand Up @@ -252,7 +252,7 @@ struct Container[ElementType: CollectionElement]:
def __str__[StrElementType: StringableCollectionElement, //](
self: Container[StrElementType]) -> String:
return str(self.element)
return String(self.element)
def use_container():
float_container = Container(5)
Expand Down Expand Up @@ -282,7 +282,7 @@ This trait must be a superset of `ElementType`'s original trait: for example,
all of requirements of the original trait.

Note that the `use_container()` function calls the `__str__()` method directly,
rather than calling `str(float_container)`. One current limitation of
rather than calling `String(float_container)`. One current limitation of
conditional conformance is that Mojo can't recognize the struct
`Container[Int]` as conforming to `Stringable`, even though the `__str__()`
method is implemented for any `ElementType` that's also `Stringable`.
Expand Down Expand Up @@ -545,11 +545,11 @@ struct Two[Type: StringableCollectionElement]:
fn __init__(out self, one: One[Type], another: One[Type]):
self.val1 = one.value
self.val2 = another.value
print(str(self.val1), str(self.val2))
print(String(self.val1), String(self.val2))
@staticmethod
fn fire(thing1: One[Type], thing2: One[Type]):
print("🔥", str(thing1.value), str(thing2.value))
print("🔥", String(thing1.value), String(thing2.value))
def use_two():
s3 = Two(One("infer"), One("me"))
Expand Down Expand Up @@ -1163,17 +1163,15 @@ For example, suppose we have a `Fudge` struct with three parameters:
@value
struct Fudge[sugar: Int, cream: Int, chocolate: Int = 7](Stringable):
fn __str__(self) -> String:
return str("Fudge (") + str(sugar) + "," +
str(cream) + "," + str(chocolate) + ")"
return String.write("Fudge (", sugar, ",", cream, ",", chocolate, ")")
```

We can write a function that takes a `Fudge` argument with just one bound
parameter (it's *partially bound*):

```mojo
fn eat(f: Fudge[5, *_]):
print("Ate " + str(f))
print("Ate " + String(f))
```

The `eat()` function takes a `Fudge` struct with the first parameter (`sugar`)
Expand All @@ -1185,7 +1183,7 @@ on the `eat` function. In practice, this is roughly equivalent to writing:

```mojo
fn eat[cr: Int, ch: Int](f: Fudge[5, cr, ch]):
print("Ate", str(f))
print("Ate", String(f))
```

In both cases, we can call the function by passing in an instance with the
Expand Down Expand Up @@ -1218,7 +1216,7 @@ parameter value with a single underscore (`_`):

```mojo
fn devour(f: Fudge[_, 6, _]):
print("Devoured", str(f))
print("Devoured", String(f))
```

Again, the unbound parameters (`sugar` and `chocolate`) are added as implicit
Expand All @@ -1228,7 +1226,7 @@ parameters, `su` and `ch`:

```mojo
fn devour[su: Int, ch: Int](f: Fudge[su, 6, ch]):
print("Devoured", str(f))
print("Devoured", String(f))
```

You can also specify parameters by keyword, or mix positional and keyword
Expand All @@ -1239,7 +1237,7 @@ And `cream` is explicitly bound to the value 6:

```mojo
fn devour(f: Fudge[_, chocolate=_, cream=6]):
print("Devoured", str(f))
print("Devoured", String(f))
```

All three versions of the `devour()` function work with the following calls:
Expand All @@ -1261,7 +1259,7 @@ for example:

```mojo
fn nibble(f: Fudge[5]):
print("Ate", str(f))
print("Ate", String(f))
nibble(Fudge[5, 4, 7]())
Expand Down
2 changes: 1 addition & 1 deletion docs/manual/pointers/unsafe-pointers.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ type](/mojo/manual/types#register-passable-memory-only-and-trivial-types) (like
`Int`) or a newly-constructed, "owned" value:

```mojo
str_ptr.init_pointee_move(str("Owned string"))
str_ptr.init_pointee_move(String("Owned string"))
```

Alternately, you can get a pointer to an existing value using the static
Expand Down
Loading

0 comments on commit 9bec4f3

Please sign in to comment.