These are chat archives for rust-lang/rust

16th
Aug 2017
Michal 'vorner' Vaner
@vorner
Aug 16 2017 05:36
@target-san I believe a lot of internal pointers are never null, even with 0 sizes, to allow that null-ptr optimisation within Option.
Michal 'vorner' Vaner
@vorner
Aug 16 2017 08:05
There should be a huge red warning on Rust's package, saying it is addictive. How am I supposed to use any other language now? 😇
Timmy Jose
@timmyjose
Aug 16 2017 08:06
@vorner Boo
Rust is good, but I wish we had features like function overloading and a more powerful macro system
Since the Rust macro system is already based on Scheme/Racket, why not go whole-hog and support Lisp-like macros?
Michal 'vorner' Vaner
@vorner
Aug 16 2017 08:11
After some years of C++, I'm actually quite glad Rust doesn't have function overloading. With the macros… I probably wouldn't be against them, but with the coming procedural macros I don't really see the need.
I mean, Rust is not flawless and it's good to wish for more, that's how improvements happen. But in parallel with a Rust project I currently work on some C code. It is full of magic that feels a bit like „Walk in here, grab a void * pointer, cast it to a pointer to a hat and pull a rabbit out of it. It was supposed to be white, but is orange-black stripped instead. And, uh, have anyone seen the tiger recently? What happened to it?“
And I have to think „how was I ever able to not curse this style of coding“
Denis Lisov
@tanriol
Aug 16 2017 08:16
The things I'm missing in Rust, coming from Python, are default argument values and named arguments. The builder pattern still looks too heavy-weight to me...
Igor
@target-san
Aug 16 2017 08:31
@timmyjose Because making Turing-complete, type-aware macro system is an epic task - taking into account error reporting.
I'd personally like to see existential types ASAP - to omit explicit types, especially where they're heavy. Current impl Trait isn't enough.
Michal 'vorner' Vaner
@vorner
Aug 16 2017 08:34
Isn't the macro system already Turing complete (when ignoring the recursion limit)?
Igor
@target-san
Aug 16 2017 08:41
I mean macro system which allows arbitrary code executed at compile-time, which observes current program as full AST rather than simple token tree, and is able to transform it arbitrarily.
Michal 'vorner' Vaner
@vorner
Aug 16 2017 08:45
Anyway, with the addictive thing, I meant something like this. Obviously, Rust has bunch of missing things (as this discussion shows), is hard to learn, is terribly slow to compile, many libraries are missing, etc, etc... But despite all this, I don't think I could just say I had enough of Rust and walk away. I probably could do it with any other language I know… C, C++, python, perl, lua. But for some reason, not with Rust. Maybe it's just me.
Zakarum
@omni-viral
Aug 16 2017 08:51
@vorner have you ever tried to compile big grammar written with boost::spirit? It takes many minutes to compile single 100 lines file
Michal 'vorner' Vaner
@vorner
Aug 16 2017 08:57
No, but I did work on a bigger C++ project, which took half an hour for a full build. And the fact that C++ is also terribly slow to compile doesn't really change the thing I'd like my rust code to take seconds, not minutes, to build and run tests. And I know it is being worked on ‒ only that a compile time is a valid point against using Rust. And we still accept that and the other things. With C++, people usually code in it because they have to. I don't think there're many companies forcing their employees to use Rust, so we obviously do it because we want to.
Anyway, it's probably a useless philosophical thinking on my side 😇
Zakarum
@omni-viral
Aug 16 2017 09:47

How to introduce bound onto higher-kind lifetime parameter?
I have

trait TraitName<'a>: for<'b> OtherTrait<'a, 'b> {}

I want to add 'a: 'b to bound so it be read as for all 'b less than or equal to 'a

Jonas Platte
@jplatte
Aug 16 2017 09:50
@omni-viral I'm not entirely sure about this, but I think just doing this should work:
trait TraitName<'a>: OtherTrait<'a, 'a> {}
Michal 'vorner' Vaner
@vorner
Aug 16 2017 09:51
Where doesn't work?
Jonas Platte
@jplatte
Aug 16 2017 09:53

Well, where would you put the where? ^^

I think the natural position to put it in would result in 'b not being in scope, so you couldn't use it in the bound.

Zakarum
@omni-viral
Aug 16 2017 09:54

@jplatte your varinat is not gonna work

trait OtherTrait<'a, 'b> {
    type Type: 'a;
    fn get(&'b mut self) -> Self::Type;
}

I want to tell that if T: TraitName<'a> you can call T::get with self reference with any lifetime smaller then 'a

@omni-viral Lifetimes can coerce into other lifetimes that the compiler knows to be smaller. That's why I think it should probably work. Can you put a more complete example on play.rust-lang.org?
Zakarum
@omni-viral
Aug 16 2017 09:57
@jplatte it can't coerce &mut
Michal 'vorner' Vaner
@vorner
Aug 16 2017 09:57
Hmm, doesn't work in any place that makes sense :-(.
Denis Lisov
@tanriol
Aug 16 2017 09:58
This?
Jonas Platte
@jplatte
Aug 16 2017 09:58
@omni-viral Not sure what you mean. I'm pretty sure &'a mut coerces into &'b mut if 'a: 'b.
Zakarum
@omni-viral
Aug 16 2017 09:58
@jplatte No
Jonas Platte
@jplatte
Aug 16 2017 09:59
@tanriol I think @omni-viral wants the relationship between the two lifetimes to be the other way around.
'a: 'b instead of 'b: 'a
Zakarum
@omni-viral
Aug 16 2017 10:00
You see. I want 'a: 'b so self wouldn't get borrowed for the lifetime of returend value in OtherTrait::get
Maybe making them ('a and 'b') completely independent will work
Jonas Platte
@jplatte
Aug 16 2017 10:04
Zakarum
@omni-viral
Aug 16 2017 10:12
Coercion works. But borrowing occurs
The TraitThree have no relation between 'b' and 'a and works
Jonas Platte
@jplatte
Aug 16 2017 10:16
Well if that is what you want then do that.
twissel
@twissel
Aug 16 2017 15:17
Hello, help needed, How to define function thats return something that implements trait IntoIterator, but not specify IntoIterator::IntoIter type?
fn start_requests(&self) -> Box<IntoIterator<Item=Request, IntoIter=(skip associated type??)>
Restioson
@Restioson
Aug 16 2017 15:21
could you use generic?
Idk how it's done in Rust, but in Java/Kotlin you use a star projection.
I don't think there's any way to skip it (its part of the signature after all!) entirely
Jonas Platte
@jplatte
Aug 16 2017 15:25
@twissel Why do you want to return an IntoIterator instead of calling into_iter() in start_requests() and returning that?
twissel
@twissel
Aug 16 2017 15:27
because start_requests will be overriden in trait implementation
2 min
I will wrote a example
Restioson
@Restioson
Aug 16 2017 15:29
then use generics
twissel
@twissel
Aug 16 2017 15:30
Example
pub trait Spider {
    fn start_requests(&self) -> Box<IntoIterator<Item=Request, ????>;
    }


    impl Spider for SiteSpider {
    fn start_requests(&self) -> Box<IntoIterator<Item=Request, ????> {
    let request = hyper::Request::new(hyper::Method::Get, "http://google.com".parse().unwrap());
    vec![request]


    }
}


    impl Spider for Site2Spider {
    fn start_requests(&self) -> Box<IntoIterator<Item=Request, ????> {
    let request = hyper::Request::new(hyper::Method::Get, "http://google.com".parse().unwrap());
    Ok(request)


    }
}
Restioson
@Restioson
Aug 16 2017 15:30
indenting pls
twissel
@twissel
Aug 16 2017 15:30
sry
Restioson
@Restioson
Aug 16 2017 15:30
pub trait Spider<T> {
    fn start_requests(&self) -> Box<IntoIterator<Item=Request, T>;
}
impl <T> Spider for SiteSpider<T> {
    fn start_requests(&self) -> Box<IntoIterator<Item=Request, T> {
        let request = hyper::Request::new(hyper::Method::Get, "http://google.com".parse().unwrap());
        vec![request]


    }
}
?
replace the T in impl <T> with your type
and all the other <T>s iirc
i dont exactly remember the syntax
Jonas Platte
@jplatte
Aug 16 2017 15:34
I think you want something like this:
pub fn Spider<C, T>
where
    C: IntoIterator<Item = T>
{
    fn start_requests(&self) -> C;
}
Restioson
@Restioson
Aug 16 2017 15:34
i feel like there's an unnecesary generic of C though
Jonas Platte
@jplatte
Aug 16 2017 15:35
Unnecessary generic? But you want the return type to be different each time..
Restioson
@Restioson
Aug 16 2017 15:35
hm, true
and the T?
Jonas Platte
@jplatte
Aug 16 2017 15:36
Wait my example is wrong anyway ^^°
Restioson
@Restioson
Aug 16 2017 15:36
compiled if fn is trait
or idk but intellij says so ^-^
Jonas Platte
@jplatte
Aug 16 2017 15:37
pub trait Spider<T>
where
    T: IntoIterator<Item = Request>
{
    fn start_requests(&self) -> T;
}
Then you can have impl's like
impl<T> Spider<Vec<Request>> for SiteSpider<T> {
    fn start_requests(&self) -> Vec<Request> {
        let request = hyper::Request::new(hyper::Method::Get, "http://google.com".parse().unwrap());
        vec![request]
    }
}
(assuming SiteSpider actually has a generic parameter, otherwise you can of course remove the two <T>s)
Also there probably shouldn't be a type parameter. Sorry I'm a bit all over the place.
twissel
@twissel
Aug 16 2017 15:41
Thanks! I think thats what I need
Jonas Platte
@jplatte
Aug 16 2017 15:41
This makes more sense, unless you want to allow multiple Spider impl's for a single type:
pub trait Spider {
    type Output: IntoIterator<Item = Request>;
    fn start_requests(&self) -> Self::Output;
}
and impl would look like this:
impl Spider for SiteSpider {
    type Output = Vec<Request>;
    fn start_request(&self) -> Vec<Request> { ... }
}
Timmy Jose
@timmyjose
Aug 16 2017 16:38
@Igor But Nim already does pretty much that - at compile time.
(regarding type-aware AST-manipulating macro system)
@vorner I agree about the compile time issue and the specific point that C++ already has such massive inertia that people accept it regardless of the compile times. Rust must definitely consider it a priority to improve compile times if only to convince people to switch/pick it up for their orgs