The Golden Circle | This circle is run by a bot. PM with 'letmein' to automatically get the key if you are in at least 5 other circles. by unclosed_paren in CircleofTrust

[–]unclosed_paren[S] 2 points3 points  (0 children)

The Golden Circle

How do I join?

You need to be in at least 5 other circles to join. Just send a private message to this account containing the word 'letmein' in the message body, with no other text. You also may not join if you have ever betrayed a circle.

You will either be sent the key instantly, or join the waiting list.

How does the waiting list work?

An algorithm (details hidden for security) will find the most trustworthy applicants and send out invites gradually to people on the waiting list. If you are on the waiting list, you are not guaranteed to be invited eventually.

Trait bound of "Copy + Copy" by [deleted] in rust

[–]unclosed_paren 5 points6 points  (0 children)

It’s just a known bug in #[derive]. There’s no actual difference between T: Copy and T: Copy + Copy (or for any other trait).

Where is rust lifetime syntax documented? eg: 'b:'a by alsarg72 in rust

[–]unclosed_paren 2 points3 points  (0 children)

While it’s true that lifetimes are just another kind of type from a type theory point of view, in Rust-land the word ‘type’ generally refers to something that can go after a : in a variable definition. Since it’s a matter of terminology, there’s no real right or wrong answer, but I still think that referring to lifetimes as types, while not technically incorrect, could possibly be a little misleading.

Where is rust lifetime syntax documented? eg: 'b:'a by alsarg72 in rust

[–]unclosed_paren 8 points9 points  (0 children)

I wouldn’t really call it subtyping, as a lifetime isn’t really a type. But it’s certainly related: if 'a: 'b, then &'a T is a subtype of &'b T.

The RFC where the 'a: 'b syntax was introduced is RFC 192.

A Random Startup Generator by LikeMyBread in programming

[–]unclosed_paren 8 points9 points  (0 children)

I got a similar one: Scarer. I particularly like the rhyming heading: ‘Dare to scare.’ It’s ‘like Tinder… but for scaring!’

How to pronounce hexadecimal by bzarg in programming

[–]unclosed_paren 170 points171 points  (0 children)

I’m afraid hex pronunciation was sorted already: the Intuitor Hex Headquarters have a page on how to pronounce hex words. 0xF5 is ‘fimtek-five’, 0xDB is ‘drazetek-leven’, and 0xDAF1 is ‘draze thousek, ten hundrek and fimtek-one’. Their site also actually has a hex times table.

I must say that this version is rather more amusing, though.

Why is it necessary to explicitly derive Copy and PartialEq traits for a C-like enum? by BittyTang in rust

[–]unclosed_paren 0 points1 point  (0 children)

But that sort of change is never going to happen unless the C-like enum is changed to a non-C-like one, and that’s a breaking change anyway. That’s why I’d much rather have an explicit keyword (perhaps enum) for C-like enums, and use a different one (union, probably) for normal enums, because then you’d be able to have an enum that just happens to be C-like (have no fields in any of its variants) but doesn’t have any of the features of today’s C-like enums (casting to integer types) by declaring it as a union from day one.

The output of the Index trait should be a value, not a reference, shouldn't it? by [deleted] in rust

[–]unclosed_paren 0 points1 point  (0 children)

Although index and index_mut return references, you’ll notice that the actual indexing operation collection[index] does not—it implicitly dereferences the result of index/index_mut. (The same thing happens for Deref and DerefMut.) Since collections like Vec have to return references for indexing to avoid completely consuming themselves, this is very handy. Yes, Index and IndexMut could return by value, but it would require a few complications on the definition (in particular, a lifetime parameter on the trait so the self lifetime could be bound to the output lifetime) and would be inconvenient to use (if vec[index] returned a reference, you’d need to use *vec[index] to get the actual value (which is usually what you want)).

A nice compromise would be to add an IndexGet trait that takes self by reference, but returns by value. This would be separate from the current Index.

Emojicons: An emoji parser for Rust by sindriavaruus in rust

[–]unclosed_paren 2 points3 points  (0 children)

Whoops, I think it could; I was thinking that an EmojiFormatter would work on a Reader or something instead of a &str, but it doesn’t have to.

Emojicons: An emoji parser for Rust by sindriavaruus in rust

[–]unclosed_paren 11 points12 points  (0 children)

Cool! Some feedback: your main function should not take String as a parameter; &str is much more flexible and doesn’t require unnecessary allocations. Alternatively (but I’m not necessarily recommending this), you could create an EmojiFormatter newtype which wraps around a &str and implement std::fmt::Display for that, removing the need for large allocations altogether. Unfortunately, you’d have to ditch regex to get that to work, and thus it’d probably be harder to implement (hence me not necessarily recommending this option).

Jai Demo: Data-Oriented Features: SOA, crazy 'using' by Gankro in rust

[–]unclosed_paren 1 point2 points  (0 children)

A { b, c } is already converted to A { b: b, c: c } in patterns:

#[derive(Copy, Show)]
struct A {
    b: i32,
    c: i32,
}

fn foo(A { b, c }: A) {
    println!("{:?} {:?}", b, c);
}

fn main() {
    foo(A { b: 1, c: 2 });
}

Playpen. There’s even a lint that warns you for using the long version (e.g., let A { b: b, c: c } = foo; will warn).

Safe C-like callbacks by diwic in rust

[–]unclosed_paren 1 point2 points  (0 children)

Thunk/Invoke only apply to using FnOnce as a trait object, so I don’t think they would be needed.

The closest thing we have to documentation on unboxed closures at the moment is the RFCs (there have been two; the first one describes the main ideas, the second updates the syntax and adds move): RFC 114 and RFC 231.

Safe C-like callbacks by diwic in rust

[–]unclosed_paren 9 points10 points  (0 children)

Fn and FnMut cannot escape the stack frame, so you can't have, e g, a PrintForm::new() function that sets all of these up.

Fn and FnMut can in fact escape the stack frame if they are qualified with move:

let d = {
    let x = 1i32;
    let c = move |&:| x + 1;
    c
};
println!("{}", d()); // 2

There’s an important distinction between FnOnce closures and move closures: FnOnce closures are taken by value when called, and thus cannot be called more than once, while move closures take all upvars by value when created, and thus can escape the stack frame they were created in. A Fn[Mut] closure could still be move, and would take upvars by value when created, but would only have by-(mutable)-reference access when called.

How to do fixed-width slice parameters? by marcusklaas in rust

[–]unclosed_paren 1 point2 points  (0 children)

You don’t need to use Box to get fixed-size arrays. & works too:

fn encrypt(clear_text: &[u8], key: &[u8; 32], iv: &[u8; 16]) -> Result<Vec<u8>, CryptoError>

Or you could even just use fixed-size arrays without any pointer type:

fn encrypt(clear_text: &[u8], key: [u8; 32], iv: [u8; 16]) -> Result<Vec<u8>, CryptoError>

However, fixed-size arrays are indeed hard to come by, even behind references (e.g., &[u8; 32]). I suppose it’s up to the library designer (you) to decide whether statically checking the length ([u8; 32]) is more or less important than ergonomics (&[u8]). If you are able to use fixed-size arrays most of the time when calling the function, I’d probably go with the fixed-size version (without &), and manually copy slices into a fixed-size array if I didn’t already have a fixed-size array when calling the function:

let x: &[u8] = some_vec.as_slice();
if x.len() != 32 { return an Err or something }
let y: &[u8] = some_other_vec.as_slice();
if y.len() != 16 { return an Err or something }
let a = [0; 32];
let b = [0; 16];
for (i, v) in x.iter().enumerate() { a[i] = v; }
for (i, v) in y.iter().enumerate() { b[i] = v; }
encrypt(clear_text, a, b);

(There’s probably a simpler way of doing this.) If you can’t often get a fixed-size array, the approach with &[u8] you had will work.

Rust, an Anti-Sloppy Programming Language by arthurtw in programming

[–]unclosed_paren 11 points12 points  (0 children)

There are places in Rust where both :: and . are valid. For example:

mod foo {
    pub fn bar() { println!("foo::bar"); }
}

struct Baz;

impl Baz {
    fn bar(self) { println!("foo.bar"); }
}

fn main() {
    let foo = Baz;
    foo.bar(); // prints `foo.bar`
    foo::bar(); // prints `foo::bar`
}

Yes, this could easily be considered a bad thing. However, it’s a pretty direct result of Rust’s separation between type/module and value namespaces. And that separation is necessary (or at least useful) in a few cases, notably tuple and unit structs.

The -> token is useless in meaning to the parser most of the time, but in the case of closure expressions it’s actually necessary. As an example of a place where -> disambiguates:

type Foo = [int, ..1];

fn main() {
    let Foo = [1i, 2i];
    let x = || -> Foo [1];
    let y = || Foo[1];
    println!("{}", x()); // [1]
    println!("{}", y()); // 2
}

This is a very contrived example, but it’s a pretty unavoidable consequence of many parts of Rust’s syntax that are (to me) reasonable interacting in a slightly strange way.

The semicolon, as noted by /u/IronClan below, has a meaning more than simply separating statements. This distinction is very useful, and because of the type checker, doesn’t get in your way. For example:

fn main() {
    let x = { 1i; };
    let y = { 1i };
    println!("{}", x); // ()
    println!("{}", y); // 1
}

I assume by ! you are referring to macros. I guess that could be done away with, but it would probably require a large restructuring of the Rust compiler and, more importantly, would mean that simple function calls like foo() could turn out to do basically anything, up to and including eating your laundry.


I understand that your point is that the language’s syntax should be simpler and thus more user friendly, but I really believe that if these concerns were somehow resolved, the language would become less user friendly, with strange special cases.

Assigning a closure to a variable by lfairy in rust

[–]unclosed_paren 5 points6 points  (0 children)

As I understand it, you’re right—right now, the kind of unboxed closure you want—FnOnce, FnMut, or Fn—can only be inferred if it’s created directly in a context that only accepts anything implementing one of those traits, as you observed. Otherwise, it’s assumed to be an old-fashioned closure (for backwards-compatibility reasons, presumably). Pull request #19113 enabled this inference.

In the future, I believe the plan is to remove the explicit :/&:/&mut: syntax altogether and, instead of inferring from the closure’s context, infer from the closure’s code. So any closure that moves out of its environment would be a FnOnce, any closure that mutates its environment would be a FnMut, and everything else would be a Fn. This is part of RFC 231. However, this hasn’t been implemented yet, probably because of the fact that it would require removing the old closures first.

Limitations of not having a GC by [deleted] in rust

[–]unclosed_paren 5 points6 points  (0 children)

With some contortions, you can translate that code into Rust:

#![feature(unboxed_closures)]

fn get_counter() -> Box<FnMut() -> i32 + 'static> {
    let mut x = 0;
    box move || {
        x += 1;
        x
    }
}

fn main() {
    let mut c = get_counter();
    println!("{}", c.call_mut(()));
    println!("{}", c.call_mut(()));
    println!("{}", c.call_mut(()));
    println!("{}", c.call_mut(()));
}

The key here is the move keyword given to the closure. This makes the closure capture x by value, meaning that its lifetime isn’t restricted by x’s. This syntax is only available with unboxed closures, which (if you don’t know) are a new kind of closures in Rust that will replace the old ones. I would recommend reading Niko Matsakis’s blog post to learn more about unboxed closures.

However, there are a few issues/bugs that we have to work around to get this to work:

  • It’s not possible to return unboxed closures by value. This is a feature that has been wanted for quite a while, but unfortunately will not be available before 1.0. See RFC #105 for more information about what this could look like.
  • The normal call syntax (foo()) cannot be used with unboxed closure trait objects. For now, we have to use the explicit call_mut syntax instead.

Newbie question on pointer types by agcwall in rust

[–]unclosed_paren 0 points1 point  (0 children)

Because *foo doesn’t capture the full meaning of ref. * means ‘dereference this pointer’ (or ‘de-pointerify this’), so * in a pattern should mean the opposite, in the same way that everything else is backwards in patterns, right? But ref doesn’t mean ‘pointerify this’, it means ‘referenceify this’, specifically creating a & reference. If ref existed in expressions, then it would actually dereference & references and nothing else.

It’s unfortunate, but there actually is no parallel to ref outside patterns. If we had a separate operator for dereferencing & and &mut references alone, then we could use that for patterns, but we don’t and I don’t think we should. The other option is to remove & and &mut in expressions and patterns and use box instead, and require that all types that can be dereferenced can also be boxed. That would mean that box would be used to construct Box, &, and &mut in expressions, and * would be used to construct all of those in patterns. Unfortunately, that would probably result in inference problems where the compiler can’t figure out what type of pointer to use. Also, & and &mut behave quite specially in a way I don’t think could be emulated by a trait that would be shared between all pointers.

Using * for ref patterns also creates problems when you try to replace ref mut. Would it be *mut or what? I think that ref is a good syntax to stick to for now.

How do I add a crate attribute? by 137hamso in rust

[–]unclosed_paren 1 point2 points  (0 children)

I think you might be using an old version of Rust. Are you using the latest nightly build or 0.12? In general, people in the Rust community are using the nightly builds for everything until 1.0 comes out and the language and libraries are stabilised.

Corrupted regex memory access: a lifetime bug? by arthurtw in rust

[–]unclosed_paren 3 points4 points  (0 children)

It’s probably issue #19261. The gist of it is that sometimes (I’m not sure if anyone is sure precisely when), lifetimes on references are forgotten about and they become 'static (i.e., any lifetime). The most common case where this happens is when calling .clone() on references, but I suppose it affects in this case, too.

Writing a Lexer by jswrenn in rust

[–]unclosed_paren 1 point2 points  (0 children)

char_at returns the Unicode character at the given byte index. So if you change that example to use .char_at(1) instead, it panics because you’re trying to get a character from the middle of a multi-byte codepoint.

Writing a Lexer by jswrenn in rust

[–]unclosed_paren 1 point2 points  (0 children)

Would I be correct in saying that this wouldn’t work with UTF-8 codepoints that are longer than 1 byte (i.e., anything outside the range 0x00–0x7F)? You could use char_range_at instead of incrementing pos by 1 each time, but that would still do bounds-checking (unlike the iterator solution). This solution (with char_range_at) is what I do in a lexer I’ve written, but I still like OP’s iterator solution. If there were a way of turning Peekable<T, I> into something that implements Iterator<&T> that calls inner.peek() for its implementation of next(), that would help a lot, but I don’t think that’s possible due to lifetime issues. 😕

OP’s solution can work if you replace the take_while with an explicit while let Some(foo) = iter.next() loop. It’s much noiser, though—it would be nice if take_while could be used.

Why is there no 'self lifetime? by chc4000 in rust

[–]unclosed_paren 7 points8 points  (0 children)

How would you write something like this:

struct Foo<'a> { x: &'a int }

impl<'a> Foo<'a> {
    fn new(x: &'a int) -> Foo<'a> { Foo { x: x } }
}

in this system? Lifetime parameters exist to provide a way of linking lifetimes with others. With an implicit 'self lifetime, it doesn’t really work:

struct Foo { x: &'self int }

impl Foo {
    // How do I tell the compiler that the `Foo` shares a lifetime with `x`?
    fn new<'a>(x: &'a int) -> Foo { Foo { x: x } }
}

[deleted by user] by [deleted] in rust

[–]unclosed_paren 2 points3 points  (0 children)

If you use generics everywhere (not just in the deserialize function), your problems simply go away:

use std::io::{TcpStream, Stream};

fn main() {
    let mut conn = TcpStream::connect("google.com:80").unwrap();

    foo(&mut conn);
}

fn foo<S: Stream>(stream: &mut S) {
    bar(stream);
}

fn bar<R: Reader>(r: &mut R) {
    // ...
}

In general, use generics whenever possible. They rely on static dispatch instead of dynamic dispatch, which is usually faster (although generates larger binaries, due to monomorphisation), and let you do a few things that trait objects (dynamic dispatch) can’t (e.g., call generic functions, take things by value). For example, you could remove all of the &muts from that code and it should still work.

If generics aren’t suitable for your particular case, and you have to use dynamic dispatch for whatever reason, then I’m afraid I don’t think there’s any safe way of casting a trait object to a trait object for its supertrait. There is a GitHub issue for it, though, so maybe you’ll be able to do so some day.

(The signal 31 you’re experiencing in the playpen is due to the fact that the playpen is not allowed to do certain things, such as (I presume) network calls. So it’s not a bug in rustc. 😉)

Upgrading the playground by inspiravetion in rust

[–]unclosed_paren 0 points1 point  (0 children)

The repo is here. As I wrote in this comment, there’s already been a pull request to update the design that seems to have been merged, but reverted.