Skip to content

Instantly share code, notes, and snippets.

@lahwran
Last active August 29, 2015 14:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lahwran/6517d119b1b04024b034 to your computer and use it in GitHub Desktop.
Save lahwran/6517d119b1b04024b034 to your computer and use it in GitHub Desktop.
rust tidbits

2-13 12:15 <lahwran> how would one have an owned unknown-size non-resizeable array?
2-13 12:15 <reem> Box<[T]>
2-13 12:15 <lahwran> there's absolutely no way to have it on the stack?
2-13 12:15 <reem> Nope
2-13 12:15 <reem> There is no dynamic sizing on the stack right now

2-13 12:08 <lahwran> how does ownership work with slices? slices are references, right? so someone must keep hold of an owned value or pointer in order for the slice to be allowed?
2-13 12:08 <steveklabnik> lahwran: yes, slices only borrow, they never allocate their own
2-13 12:08 <kmc> lahwran: &[T] doesn't own the buffer; it's borrowing it
2-13 12:08 <mbrubeck> lahwran: Yes, or in the case of string/array literals, the data is static.
2-13 12:08 <kmc> this is checked through the same lifetime mechanism as ordinary references
2-13 12:08 <lahwran> so what's going on if you .... ahhhh
2-13 12:09 <lahwran> so you're borrowing from 'static, and can therefore do so indefinitely
2-13 12:09 <kmc> yep

2-13 11:59 <lahwran> a vec![] is very light, right?
2-13 11:59 <lahwran> an empty one, that is
2-13 12:00 <reem> vec![] is Vec { 0, 0, 0 }
2-13 12:00 <reem> very very cheap
2-13 12:00 <reem> Vec { 1, 0, 0 } technically
2-13 12:00 <lahwran> cool
2-13 12:00 <lahwran> so not even any pointers, just an empty by-value struct
2-13 12:00 <reem> lahwran: Yup, super super cheap.

2-10 09:59 <lahwran> how big is a bool in memory, out of curiosity?
2-10 10:00 <reem> playbot: mem::size_of::<bool>()
2-10 10:00 [playbot] <anon>:14:9: 14:29 error: failed to resolve. Use of undeclared type or module 'mem'
2-10 10:00 [playbot] <anon>:14 mem::size_of::<bool>()
2-10 10:00 [playbot] output truncated; full output at: http://bit.ly/1EX81M5
2-10 10:00 <reem> playbot: ::std::mem::size_of::<bool>()
2-10 10:00 <lahwran> heh
2-10 10:00 [playbot] 1
2-10 10:00 <lahwran> oh one byte huh
2-10 10:00 <reem> lahwran: ^ 1 byte
2-10 10:00 <scp> lahwran: but bools are often optimized out
2-10 10:00 <lahwran> I don't remember where but I heard it was size_of::<isize>()
2-10 10:00 <lahwran> hence the curiosity
2-10 10:00 <scp> well, a lot of the time they'll take up 8 bytes, for alignment reasons
2-10 10:00 <lahwran> oh, good to know
2-10 10:01 <lahwran> doh.

2-12 08:20 <lahwran> how does one get a total ordering of floats in rust? floats do at least have a total ordering, even though addition makes them drift, as long as you don't hit any of the special values
2-12 08:21 <lahwran> so is there a way to say like, have an enum { NaN(nan value), Infinity(infinity type), Real(actual number) }
2-12 08:21 <lahwran> or ... I dunno, that wouldn't be different from fp_class, really
2-12 08:21 <lahwran> but is there some way to get a total order?
2-12 08:22 <FreeFull> I don't think the standard library has the total order built in
2-12 08:22 <lahwran> oh, I see
2-12 08:22 <huon> I believe the IEEE-754 standard defines total order
2-12 08:22 <huon> so one should be able to just implement that
2-12 08:23 <lahwran> huon: wait, really? I thought if you let x = , then !(x < x) && x != x && !(x > x)
2-12 08:23 <huon> lahwran: the total order doesn't match the conventional operations precisely, AIUI
2-12 08:24 <geofft> hm. it's a little weird to me that you can match on floats.
2-12 08:24 <lahwran> well drat. anyway, so one can just implement total order and pass through to partial order?
2-12 08:24 <geofft> is there a valid use case for this?
2-12 08:24 <lahwran> it is possible to get two equal floats
2-12 08:24 <geofft> rusti: match 0.5f32 + 0.5f32 { 1.0f32 => "yes", _ => "no" }
2-12 08:24 [playbot] "yes"
2-12 08:24 <geofft> sure
2-12 08:25 <geofft> rusti: match 0.6f32 + 0.4f32 { 1.0f32 => "yes", _ => "no" }
2-12 08:25 [playbot] "yes"
2-12 08:25 <lahwran> not likely once you math them, but possible
2-12 08:25 <sfackler> lahwran: float1.partial_cmp(float2).unwrap()
2-12 08:25 <geofft> rusti: match 0.6f64 + 0.4f64 { 1.0f64 => "yes", _ => "no" }
2-12 08:25 [playbot] "yes"
2-12 08:25 <lahwran> sfackler: will float's partial_cmp ever return None?
2-12 08:25 <lahwran> does it check for NaN?
2-12 08:25 <nathan7> lahwran: yes
2-12 08:25 <sfackler> if nan is involved yes
2-12 08:26 <lahwran> interesting, what values does it return None for? what is infinity.partial_cmp(infinity)?
2-12 08:26 <scott> playbot: 1f64.partial_cmp(0.0/0.0)
2-12 08:26 [playbot] :14:26: 14:33 error: mismatched types:
2-12 08:26 [playbot] expected &f64,
2-12 08:26 [playbot] output truncated; full output at: http://bit.ly/1B4zfPL
2-12 08:26 <sfackler> lahwran: it returns None if either float is NaN
2-12 08:26 <scott> playbot: 1f64.partial_cmp(0f64/0f64)
2-12 08:26 [playbot] :14:26: 14:35 error: mismatched types:
2-12 08:26 [playbot] expected &f64,
2-12 08:26 [playbot] output truncated; full output at: http://bit.ly/1E6cSHm
2-12 08:26 <sfackler> that's the only condition
2-12 08:26 <scott> playbot: 1f64.partial_cmp(&(0f64/0f64))
2-12 08:26 [playbot] None
2-12 08:26 <lahwran> scott: isn't 0/0 NaN, but 1/0 is inf?
2-12 08:26 <scott> lahwran: yes
2-12 08:27 <lahwran> playbot: (1f64/0f64).partial_cmp(&(1f64/0f64))
2-12 08:27 [playbot] Some(Equal)
2-12 08:27 <lahwran> huh.
2-12 08:28 <nathan7> playbot: 1f64/0f64
2-12 08:28 [playbot] inf
2-12 08:28 <lahwran> yeah, I guess that's what other languages expose too
2-12 08:28 <lahwran> cool, thanks!
2-12 08:28 <scott> it seems weird to me to say inf == inf with floats
2-12 08:28 <lahwran> yeah, there are a bunch of possible inf values, aren't there?
2-12 08:28 <lahwran> I don't know how to get any but the normal one though, same with NaN
2-12 08:28 <huon> lahwran: http://is.gd/D0vgLP
2-12 08:28 <huon> lahwran: (port of http://stackoverflow.com/a/20154751/1256624 )
2-12 08:28 <scott> lahwran: there are only + and - inf
2-12 08:29 <lahwran> huon: what the ffkk
2-12 08:29 <lahwran> scott: ah
2-12 08:29 <sfackler> lahwran: this is how all the primitive's PartialOrds are implemented: https://github.com/rust-lang/rust/blob/master/src/libcore/cmp.rs#L362-L367
2-12 08:29 <huon> lahwran: that's the IEEE total order
2-12 08:30 <lahwran> huon: wacky
2-12 08:31 <lahwran> sfackler: cool

2-12 07:21 <lahwran> what should I use to represent fitness from a real-valued fitness function? ie, how do I float?
2-12 07:22 <doomrobo> lahwran, you can use single or double precision floats with f32 and f64
2-12 07:23 <lahwran> kay, that much I know; what pitfalls should I know about? I hear there are some interesting ones that are inherent to floats and rust makes the programmer deal with, rather than ignoring like other languages do
2-12 07:23 <doomrobo> huh, that's news to me
2-12 07:24 <doomrobo> could you give an example?
2-12 07:24 <lahwran> well, I know comparison is Scary with floats
2-12 07:24 <lahwran> as is equality
2-12 07:24 <lahwran> addition sometimes lies
2-12 07:24 <lahwran> often, actually, because 0.1 + 0.1 + ... == 0.9999999998 or something
2-12 07:25 <iopq> 0.1 + 0.1 == 0.2, but 0.2 + 0.1 != 0.3
2-12 07:25 <doomrobo> those are pitfalls of floats in general, though
2-12 07:25 <lahwran> like, you don't have to get into very large numbers to drift slightly
2-12 07:25 <lahwran> right
2-12 07:25 <lahwran> like I said
2-12 07:25 <lahwran> my understanding was that these float pitfalls are somehow worse in rust
2-12 07:25 <climbandmaintain> lahwran: you could try words ?
2-12 07:25 <lahwran> and I was curious why
2-12 07:25 <huon> lahwran: they're not
2-12 07:25 <lahwran> ok
2-12 07:26 lahwran uses floats
2-12 07:26 <climbandmaintain> lol
2-12 07:26 <huon> that is, float operations in Rust do the same thing as C/C++/Python/...
2-12 07:26 <lahwran> and all the same operations are available?
2-12 07:26 <lahwran> there's nothing like you can't do addition with + or something
2-12 07:26 <climbandmaintain> nope
2-12 07:26 <lahwran> kay, yay
2-12 07:27 <climbandmaintain> + - etc. all work fine
2-12 07:27 <climbandmaintain> in fact
2-12 07:27 <climbandmaintain> the cool thing is
2-12 07:27 <climbandmaintain> you can overload those operators by implementing traits
2-12 07:27 <climbandmaintain> and wrap a basic data type in a newtype struct
2-12 07:27 <doomrobo> lahwran, check this out, it may be enlightening: http://blog.reverberate.org/2014/09/what-every-computer-programmer-should.html
2-12 07:28 <lahwran> doomrobo: I am fairly familiar with floats, though I've been meaning to read that
2-12 07:29 <lahwran> I'm just used to arithmetic, comparison, etc all being the same operators but slightly wonky when dealing with floats
2-12 07:29 <lahwran> and had heard that rust doesn't let you do comparison on floats because they're only partialeq
2-12 07:29 <WindowsBunny> lahwran: Because NaN != NaN
2-12 07:30 <huon> lahwran: PartialEq and PartialOrd provide the operators (==, < etc.)
2-12 07:30 <huon> lahwran: you can't use them directly with sorting and data structures etc.
2-12 07:30 <lahwran> WindowsBunny: yes? that's what I thought was the reason that == wasn't allowed
2-12 07:30 <huon> lahwran: you have to opt-in to a NaN handling strategy.
2-12 07:30 <lahwran> huon: ah, I see
2-12 07:30 <lahwran> okay that's super cool
2-12 07:31 <huon> lahwran: it's also sometimes annoying :P

Note: this is inefficient anyway, don't do it in the first place. but just saying you wanted to:

to go from Vec<Whatever> to Vec<Rc<Whatever>>, instead of this:

let thenewvec: Vec<Rc<Whatever>> = thevec.iter().map(|&x| Rc::new(x)).collect();

do this:

let thenewvec: Vec<Rc<Whatever>> = thevec.into_iter().map(|x| Rc::new(x)).collect();

2-10 09:07 <doomrobo> is there any better way to get the last character of a string than: mystring.as_slice().char_at_reverse(mystring.len())?
2-10 09:08 <lahwran> doomrobo: I don't think you can search backwards in utf-8, so no. you can get the last byte easily, but at that point just use &[u8]
2-10 09:08 <cgaebel> I think you can search backwards...
2-10 09:08 <lahwran> can you?
2-10 09:08 <scott> you can search backwards
2-10 09:08 <cgaebel> (not 100% sure)
2-10 09:09 <scott> you can even drop in the middle of a character and find the character boundaries
2-10 09:09 <doomrobo> hmm
2-10 09:09 <lahwran> scott: huh. noted.
2-10 09:10 <scott> lahwran: this is a property of UTF-8 more than it is of Rust

2-10 12:37 <lahwran> wait, rc is for immutable values
2-10 12:38 <lahwran> there's no mutable-in-place Rc?
2-10 12:38 <mbrubeck> lahwran: Rc<RefCell<_>> and friends
2-10 12:38 <lahwran> oic

2-10 12:50 <moobles> is there a difference between let mut foo = &foo(); and let foo = &mut foo(); ?
2-10 12:51 <Gliptic> moobles, yes
2-10 12:51 <Gliptic> the former is a shared reference, the latter a mutable reference
2-10 12:51 <Gliptic> the "mut" before foo refers to the variable, not the type
2-10 12:51 <lahwran> it doesn't inherit through the pointer, in other words
2-10 12:51 <moobles> Gliptic: so the first one is a pointer that I can alter to point at other things, and the second is a pointer to something that I can alter?
2-10 12:52 <Gliptic> moobles, yes
2-10 12:52 <moobles> Gliptic: hmm ok.

2-11 06:12 <lahwran> if I have somevariable: &Whatever, and Whatever is struct { derp: SomethingElse }, then what do I get if I do somevariable.derp? &SomethingElse, or does it fail to take ownership?
2-11 06:15 <mbrubeck> lahwran: somevariable.derm has type SomethingElse
2-11 06:15 <lahwran> ok. drat.
2-11 06:15 <lahwran> so can I do &somevariable.derp or do I have to do &(somevariable.derp)
2-11 06:15 <mbrubeck> Either works.
2-11 06:15 <lahwran> cool, so . has a higher precedence than & then
2-11 06:15 <mbrubeck> Right.
2-11 06:16 <lahwran> yay

2-12 08:26 <climbandmaintain> quick question: when I do a cargo test, my println!()s don't seem to print. How can I get some kinda console output?
2-12 08:26 <nathan7> climbandmaintain: --nocapture
2-12 08:27 <climbandmaintain> nathan7: how do I turn that off?
2-12 08:27 <climbandmaintain> nathan7: or are you saying to run cargo test --nocapture
2-12 08:27 <nathan7> climbandmaintain: cargo test -- --nocapture
2-12 08:28 <climbandmaintain> nathan7: cargo test -- nocapture didn't do anything
2-12 08:28 <nathan7> climbandmaintain: that's correct
2-12 08:28 <nathan7> climbandmaintain: cargo test -- --nocapture, however
2-12 08:28 <climbandmaintain> Usage: cargo test [options] [--] [...]
2-12 08:28 <climbandmaintain> that's all I get out of -- --nocapture
2-12 08:28 <nathan7> climbandmaintain: yes
2-12 08:28 <nathan7> climbandmaintain: err
2-12 08:28 <nathan7> climbandmaintain: maybe it's --no-capture, idk
2-12 08:28 <nathan7> climbandmaintain: cargo test -- --help will show it
2-12 08:29 <nathan7> climbandmaintain: cargo test -- --nocapture works here
2-12 08:30 <climbandmaintain> http://mibpaste.com/BIDRmP nathan7
2-12 08:30 <climbandmaintain> I'm on the latest nightly
2-12 08:31 <nathan7> climbandmaintain: cargo should pass anything after the -- to the test binary
2-12 08:31 <nathan7> climbandmaintain: what you're pasting is cargo help
2-12 08:31 <nathan7> climbandmaintain: I'm pulling the latest nightly atm
2-12 08:31 <climbandmaintain> okay
2-12 08:31 <climbandmaintain> what does nocapture do?
2-12 08:31 <nathan7> climbandmaintain: http://sprunge.us/DKbQ
2-12 08:32 <nathan7> All tests have their standard output and standard error captured by default.
2-12 08:32 <nathan7> This can be overridden with the --nocapture flag or the RUST_TEST_NOCAPTURE=1
2-12 08:32 <nathan7> environment variable. Logging is not captured by default.
2-12 08:32 <Mutabah> climbandmaintain: Stops cargo test from capturing stdout/stderr
2-12 08:32 climbandmaintain nods
2-12 08:32 <nathan7> well, stops the test fixture from doing it
2-12 08:32 <Mutabah> ^ that
2-12 08:32 <climbandmaintain> So why the hell si mine not working
2-12 08:32 <climbandmaintain> is*
2-12 08:32 <nathan7> cargo doesn't actually handle or know about that flag
2-12 08:32 <nathan7> climbandmaintain: for some reason cargo is picking it up
2-12 08:32 <nathan7> climbandmaintain: the loose -- tells cargo to stop parsing options and pass them to the test binary
2-12 08:33 <climbandmaintain> Usage: cargo test [options] [--] [...] is waht I keep getting
2-12 08:33 <climbandmaintain> maybe it's an error with the current nightly?
2-12 08:33 <nathan7> climbandmaintain: works on the current nightly on my machine
2-12 08:33 <nathan7> climbandmaintain: paste the full thing including your prompt?
2-12 08:33 <climbandmaintain> cargo test -- --nocapture is what I'm putting in
2-12 08:33 <climbandmaintain> sure
2-12 08:33 <climbandmaintain> http://mibpaste.com/FewOE7
2-12 08:34 <nathan7> hmm, maybe this is broken on windows?
2-12 08:34 <climbandmaintain> maybe. Or in powershell

2-10 09:32 <lahwran> wait you can provide default implementations of a trait in the trait declaration!?
2-10 09:32 <lahwran> http://doc.rust-lang.org/std/cmp/trait.PartialOrd.html
2-10 09:33 <blaenk> lahwran: yes
2-10 09:33 <lahwran> you totally can!
2-10 09:33 <lahwran> why didn't someone tell me about this when I was asking about default implementations yesterday? :<

2-11 05:52 <lahwran> (I still don't know what derive actually does)
2-11 05:52 <lahwran> (just generally what you get if you use it... vaguely speaking)
2-11 05:52 <eddyb> lahwran: derive generates AST for implementations of those traits
2-11 05:52 <lahwran> eddyb: from where?
2-11 05:53 <eddyb> based on some simple rules
2-11 05:53 <huon> lahwran: derive basically just calls the relevant function/operator on each field of the contained type
2-11 05:53 <eddyb> lahwran: the set of traits is hardcoded into the compiler
2-11 05:53 <huon> lahwran: (e.g. PartialEq will create a fn eq calling eq on all the fields)
2-11 05:53 <huon> lahwran: http://doc.rust-lang.org/nightly/reference.html#derive
2-11 05:54 <lahwran> huon: oh, cool! okay

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment