# Micro Pre-RFC: todo! macro

**URL:** <https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925>\
**Category:** libs\
**Created:** [November 29, 2018, 3:18pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925 "2018-11-29T15:18:54Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [November 29, 2018, 3:18pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/1 "2018-11-29T15:18:54Z")

</div>

# Rename `unimplemented!` macro to `todo!`

Basically, the title says it all: deprecate the current `unimplemented!` macro, and replace it with equivalent `todo!()`. `unimplemented` is a pain to type, and usually is used in situations when you want to type code fast. Snippets/completion do not work equally well everywhere.

What do you think about this?

Case study: Kotlin has a similar function, TODO: [https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-t-o-d-o.html](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/-t-o-d-o.html)

---

<div class="post-metadata">

**Author:** ![bjz](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bjz/32/72_2.png) [@bjz](https://internals.rust-lang.org/u/bjz)\
**Post date:** [November 29, 2018, 3:20pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/2 "2018-11-29T15:20:25Z")

</div>

As the person who gave `unimplemented!` it’s unfortunate name, I very much support this!

---

<div class="post-metadata">

**Author:** ![RustyYato](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/rustyyato/32/13627_2.png) [@RustyYato](https://internals.rust-lang.org/u/RustyYato)\
**Post date:** [November 29, 2018, 3:20pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/3 "2018-11-29T15:20:31Z")

</div>

~~We cannot rename stable things, because that would be a breaking change.~~

I missed the word deprecate 🙃

* * *

This would be nice

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [November 29, 2018, 3:21pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/4 "2018-11-29T15:21:03Z")

</div>

That’s why the first sentence after the title says _deprecate_ 😉

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [November 29, 2018, 3:24pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/5 "2018-11-29T15:24:58Z")

</div>

Interesting observation: normally, we can’t deprecate widely used things for the fear of warnings flood. And `unimplemented!` **is** widely used, but **not** in the committed code, usually, so we can get away with hard deprecation (as opposed to edition based soft deprecation).

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 29, 2018, 3:25pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/6 "2018-11-29T15:25:13Z")

</div>

🚲 🏘

What about `fixme!()`;

//begin-hyper-overanalysis

It has the advantage that the `!` is close to the `e` at the end so your finger is closer to it;

//end-hyper-overanalysis

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [November 29, 2018, 3:30pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/7 "2018-11-29T15:30:07Z")

</div>

Fixme is longer, and `e` is on the same hand and other finger then `!`, which makes it _harder_ to type. Words that alternate hands are usually easier to touch type.

Intrestingly enough, both todo and fixme alone are alternating.

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 29, 2018, 3:32pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/8 "2018-11-29T15:32:26Z")

</div>

> [@matklad](#):
>
> Fixme is longer, and `e` is on the same hand and other finger then `!` , which makes it _harder_ to type. Words that alternate hands are usually easier to touch type.

I suppose; I tried typing both in rapid succession and there was more or less no difference 😉

Whether you go with fixme or todo, I think you can add to the list of motivations:

- unimplemented is not a common word whereas the latter two are; this helps with grep.

---

<div class="post-metadata">

**Author:** ![Soni](https://avatars.discourse-cdn.com/v4/letter/s/a3d4f5/32.png) [@Soni](https://internals.rust-lang.org/u/Soni)\
**Post date:** [November 29, 2018, 3:38pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/9 "2018-11-29T15:38:59Z")

</div>

fixme has different meaning than todo

while todo is unimplemented, fixme is implemented but broken

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 29, 2018, 3:44pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/10 "2018-11-29T15:44:35Z")

</div>

> [@Soni](#):
>
> while todo is unimplemented, fixme is implemented but broken

Yeah that's a good point;

Consider `fixme!` retracted. 😉

---

<div class="post-metadata">

**Author:** ![Lokathor](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/lokathor/32/2463_2.png) [@Lokathor](https://internals.rust-lang.org/u/Lokathor)\
**Post date:** [November 29, 2018, 3:48pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/11 "2018-11-29T15:48:17Z")

</div>

`unimplemented!()` being hard to type is the encouragement that you need to not put it into your program.

Rust is always guiding you towards success!

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [November 29, 2018, 3:55pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/12 "2018-11-29T15:55:11Z")

</div>

I don’t agree with this reasoning (also, I am not sure where this is a serious argument or a joke 🙂 ): `unimplemented` is hugely useful for exploratory programming, where discouragement does not make sense. The best way to discourage the use of unimplemented would be to just not have it in the std in the first place, but it is in std, exactly because it is useful to put `unimplemented` in your program while you figuring the stuff out

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [November 29, 2018, 4:01pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/13 "2018-11-29T16:01:32Z")

</div>

Thinking about it more, perhaps we need to add `todo!` _without_ deprecating `unimplemented!()`? That way, we change the meaning of `unimplemented!()` to “intentionally not implemented, don’t call this function at runtime”, sort of like caller-checked `unreachable!()`.

See an example of this use-case here: [https://github.com/rust-lang/rust/blob/0c1dc62c1ec3c23dcb5e90500a2b3b25817ad03a/src/bootstrap/builder.rs#L89-L95](https://github.com/rust-lang/rust/blob/0c1dc62c1ec3c23dcb5e90500a2b3b25817ad03a/src/bootstrap/builder.rs#L89-L95)

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 29, 2018, 4:02pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/14 "2018-11-29T16:02:14Z")

</div>

Ostensibly, a typed hole `?` (as Agda et. al have) might be better for prototyping:

```rust
let x = ?;

foo(?);

let x: ? = 1;

```

In this case, the type system (and IDEs) can reason about what you are trying to do (unlike `todo!()` which will expand to some diverging expression).

Thus, you can do things like:

```rust
fn foo() -> Result<MyType, impl MyTrait> {
    // This wouldn't work if you had `x : !` because `! :/ impl MyTrait` in general
    Err(?)
}

```

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [November 29, 2018, 4:09pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/15 "2018-11-29T16:09:19Z")

</div>

For the IDE `todo!` macro and a special `?` syntax are exactly equivalent. Also, we’ve completed the whole circle here, because this proposal was born from this holes discussion: [https://salsa.zulipchat.com/#narrow/stream/145099-general/subject/structured.20editing](https://salsa.zulipchat.com/#narrow/stream/145099-general/subject/structured.20editing). It also discusses the point that, for IDEs, having holes in the surface syntax is not really necessary, because it’s not that hard to treat literally nothing as a hole.

Don’t have an opinion about type-system side of things, but adding holes to a language seems to be a massive change which is unlikely to happen any time soon.

---

<div class="post-metadata">

**Author:** ![Nemo157](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nemo157/32/11585_2.png) [@Nemo157](https://internals.rust-lang.org/u/Nemo157)\
**Post date:** [November 29, 2018, 4:17pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/16 "2018-11-29T16:17:26Z")

</div>

> [@Centril](#):
>
> It has the advantage that the `!` is close to the `e` at the end so your finger is closer to it;

`e` and `!` are 9 columns and 2 rows apart for me... Actually trying both out `todo` is far _far_ _ **far** _ easier to type in dvorak than `fixme` (right-middle, left-ring, right-index-inner-column, left-ring; all on the home row—vs—right-index-inner-column-upper-row, left-index-inner-column, left-index-inner-column-bottom-row, right-index-bottom-row, left-middle). That index-finger dance for `fix` is torture.

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 29, 2018, 4:24pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/17 "2018-11-29T16:24:16Z")

</div>

> [@Nemo157](#):
>
> Actually trying both out `todo` is far _far_ _ **far** _ easier to type in dvorak than `fixme`

We resolved `fixme!` already; let's move on. 🙂

> [@matklad](#):
>
> For the IDE `todo!` macro and a special `?` syntax are exactly equivalent.

Sure; the `todo!` macro could expand to the same construct in the language and thus be equivalent.

However, you'll need to have that construct in the type system to be able to say things like `let x: todo!() = expr;`

> [@matklad](#):
>
> It also discusses the point that, for IDEs, having holes in the surface syntax is not really necessary, because it’s not that hard to treat literally nothing as a hole.

Perhaps not necessary no; but it does make it clearer where the holes are and it makes less things legal syntax in the grammar (and this is significant due to macros). My experience with holes in Idris and Agda have been nothing but positive.

> [@matklad](#):
>
> adding holes to a language seems to be a massive change which is unlikely to happen any time soon.

Elaborate? Why would it be so _massive_ (and do you mean implementation complexity or user facing complexity?)?

From the side of the grammar you'd need to add the token `?` (or something else, but this one seemed apt...) to 3 places: the term grammar, the type grammar, the trait grammar.

For the term grammar `?` becomes a diverging expression for an unknown empty type which happens to coerce to everything else and also implements all traits (~ modulo some questions around what traits this is sound for; we can start with a conservative subset...).

For the type side of things, `?` becomes a type error that tells you what the inferencer found; Most of this machinery should already exist; we mostly need to tailor the error messages.

For the bound side of things, you can now write `where T: ?` and inference should tell you what the most permissive bound `?` could be to make the body typeck.

None of this strikes me as massively complex to implement; On the user complexity side of things `?` is a fairly intuitive syntax for "I don't know, please tell me"; it's also uniformly the same syntax for incomplete programs everywhere so that seems simple enough to explain to people.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [November 29, 2018, 5:02pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/18 "2018-11-29T17:02:31Z")

</div>

> [@Centril](#):
>
> However, you’ll need to have that construct in the type system to be able to say things like `let x: todo!() = expr;`

That's true, yeah. Though, I don't think IDEs need that hole to be explicit? They certainly can do useful stuff with the missing type: [https://www.youtube.com/watch?v=5atAmTxbGBk&feature=youtu.be](https://www.youtube.com/watch?v=5atAmTxbGBk&feature=youtu.be)

> My experience with holes in Idris and Agda have been nothing but positive.

I don't have to much of experience with these languages, but, as a Rust IDE developer, I've never felt a need to have missing stuff explicit in the source language. I suspect that has to do with the fact that Rust has comparatively weaker type system than Idris & Agda, so there's comparatively fewer useful things you can do with a hole (fill the type of the type-hole, complete the expression-hole, generate function definition from a call), and they all can be achieved perfectly without any surface syntax for holes.

> Elaborate? Why would it be so _massive_ (and do you mean implementation complexity or user facing complexity?)?

Implementation mostly: `?` seems strictly more complicated then `!`, and we've been waiting for the never type for years.

In general, I feel that it's probably a bad idea to invent a language feature for what can be achieved at 90% by a library/macro. \<rant\>I personally feel that we have such a laundry list of language features to implement to match C++ in expressiveness (in terms of the generated asm) and a significant technical debt in the "Quality Of Implementation" (ides, alternative implementations, compilation performance), so discussing non-trivial language "niceties", _at this time_, seems not that productive \</rant\>

---

<div class="post-metadata">

**Author:** ![Centril](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/centril/32/3334_2.png) [@Centril](https://internals.rust-lang.org/u/Centril)\
**Post date:** [November 29, 2018, 5:21pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/19 "2018-11-29T17:21:45Z")

</div>

> [@matklad](#):
>
> That’s true, yeah. Though, I don’t think IDEs need that hole to be explicit? They certainly can do useful stuff with the missing type: [https://www.youtube.com/watch?v=5atAmTxbGBk&amp;feature=youtu.be](https://www.youtube.com/watch?v=5atAmTxbGBk&amp;feature=youtu.be)

(Aside: That's quite nice, maybe I should switch to IntelliJ from VSCode...)

That is mostly enough; but it works less well with `.collect::<?>()`; here, I don't want to use `_` because I want to tell the compiler explicitly to stop compiling. I also wonder how IDEs can cope with holes inside macros...?

> [@matklad](#):
>
> I don’t have to much of experience with these languages

(Aside: try them out sometime if you get some free extra time (it's hard, I know ^.^); they are a good learning experience / good fun)

> [@matklad](#):
>
> I suspect that has to do with the fact that Rust has comparatively weaker type system than Idris & Agda, so there’s comparatively fewer useful things you can do with a hole (fill the type of the type-hole, complete the expression-hole, generate function definition from a call), and they all can be achieved perfectly without any surface syntax for holes.

That's mostly true; however, with const generics, Rust is closing the gap to Idris and Agda so there are suddenly more places where holes become useful due to improved inference.

> [@matklad](#):
>
> Implementation mostly: `?` seems strictly more complicated then `!` , and we’ve been waiting for the never type for years.

It is strictly more complicated than `!` yes; but also more useful. Furthermore, some of the issues to get `?` working would also need to be solved to get `!` working better. As for waiting for `!`, we were blocked on type inference doing the wrong thing and we might possibly be unblocked soon: [trigger unsized coercions keyed on Sized bounds by arielb1 · Pull Request #56219 · rust-lang/rust · GitHub](https://github.com/rust-lang/rust/pull/56219). Another semi-blocking factor was around questions re. uninhabitedness in general and pattern matching; we'll need to resolve those as well.

> [@matklad](#):
>
> In general, I feel that it’s probably a bad idea to invent a language feature for what can be achieved at 90% by a library/macro.

Tastes differ of course, but I find macros to be unsatisfying as compared to the language feature wrt. the commonality of the use and the user friendliness; for example, [eRFC: if- and while-let-chains, take 2 by Centril · Pull Request #2497 · rust-lang/rfcs · GitHub](https://github.com/rust-lang/rfcs/pull/2497) seems strictly better than [`if_chain`](https://docs.rs/if_chain/0.1.3/if_chain/). Macros offer a good way to keep the pressure on language design smaller so that we may prototype; that's really nice.

> [@matklad](#):
>
> discussing non-trivial language “niceties”, _at this time_ , seems not that productive

Alright; I will support the addition of `todo!` at this time as a strict improvement over `unimplemented!()` and we can consider typed holes later.

---

<div class="post-metadata">

**Author:** ![matklad](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/matklad/32/12266_2.png) [@matklad](https://internals.rust-lang.org/u/matklad)\
**Post date:** [November 29, 2018, 7:21pm UTC](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925/20 "2018-11-29T19:21:28Z")

</div>

Ok, here we go: [https://github.com/rust-lang/rust/pull/56348](https://github.com/rust-lang/rust/pull/56348)

[Next page](https://internals.rust-lang.org/t/micro-pre-rfc-todo-macro/8925.md?page=2)
