Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Flashing Twelve
Mar 20, 2007


After a bit of looking around, there's a pretty simple workaround to this. Run it in gdb, enter 'break rust_panic', and when it hits the breakpoint 'bt' for a stacktrace. Apparently rust_panic is specifically there so you can place breakpoints on panics, which is pretty neat.

Adbot
ADBOT LOVES YOU

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
Found this joke on the rust subreddit and enjoyed it:

quote:

The 1st rule of Rust Club is: you don't talk about Rust Club.

The 2nd rule of Rust Club is: error: 1st rule does not live long enough.

error: aborting due to previous error

VikingofRock
Aug 24, 2008




Bognar posted:

Found this joke on the rust subreddit and enjoyed it:

I love it.

Linear Zoetrope
Nov 28, 2011

A hero must cook
That's pretty great.

The Cavern of COBOL › Rust: error: The Cavern of COBOL does not live long enough

Gasbraai
Oct 25, 2010

Lictor my Dictor
Rust seems really cool and interesting but this: https://www.rust-lang.org/conduct.html is loving cancer. I hate it that this tumblr level safe-space bullshit is invading CS topics. It encourages outrage and taking offense while simultaneously discouraging being an adult and hardening the gently caress up. It also serves to minimize the contributions of people that don't have a place in the reverse hierarchy of 'privilege' that tumblr likes to go on about, sorry I'm not a disabled, mayonnaise gendered, polysexual, fartkin gypsy black woman quadriplegic, I hope my pull request gets some attention nonetheless because I'm trying to add value despite being a cis-het white male AKA literally hitler.

(USER WAS PUT ON PROBATION FOR THIS POST)

Redmark
Dec 11, 2012

This one's for you, Morph.
-Evo 2013
I'm not going to touch the rest of your post but the text of that code does not seem particularly unreasonable? Like I don't see how it could get anyone in trouble who's not actively looking for it. Silencing discussion on controversial social issues might be wrong for a general forum, but seems to make sense for a programming language community :shrug:

Subjunctive
Sep 12, 2006

✨sparkle and shine✨

The code is eminently reasonable, and the vast majority of pull requests come from cis-het males. There is an imaginary problem being invented here, but it's not by the authors of the code.

sarehu
Apr 20, 2007

(call/cc call/cc)

Lunixnerd posted:

Rust seems really cool and interesting but this: https://www.rust-lang.org/conduct.html is loving cancer. I hate it that this tumblr level safe-space bullshit is invading CS topics. It encourages outrage and taking offense while simultaneously discouraging being an adult and hardening the gently caress up. It also serves to minimize the contributions of people that don't have a place in the reverse hierarchy of 'privilege' that tumblr likes to go on about, sorry I'm not a disabled, mayonnaise gendered, polysexual, fartkin gypsy black woman quadriplegic, I hope my pull request gets some attention nonetheless because I'm trying to add value despite being a cis-het white male AKA literally hitler.

Sorry you're not a rape victim/breast cancer haver.

quote:

We are committed to providing a friendly, safe and welcoming environment for all, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, nationality, or other similar characteristic.

Translation: Hail Hydra.

piratepilates
Mar 28, 2004

So I will learn to live with it. Because I can live with it. I can live with it.



You've got some real problems if you read that and parse it as anything other than "be nice to people, don't be a dick"

sarehu
Apr 20, 2007

(call/cc call/cc)

quote:

We interpret the term "harassment" as including the definition in the Citizen Code of Conduct;

Never mind building, you can't even read their code of conduct without downloading an external dependency.

sarehu
Apr 20, 2007

(call/cc call/cc)

piratepilates posted:

You've got some real problems if you read that and parse it as anything other than "be nice to people, don't be a dick"

Seriously? Online forums have had "rules" that are about "be nice to people, don't be a dick," since forever, for example, and they read a lot differently when they aren't full of dog-whistles and designed to reinforce a certain political thesis about how the world is.

Bongo Bill
Jan 17, 2012

sarehu posted:

Seriously? Online forums have had "rules" that are about "be nice to people, don't be a dick," since forever, for example, and they read a lot differently when they aren't full of dog-whistles and designed to reinforce a certain political thesis about how the world is.

Online forums, noted bastions of professionalism and decency.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

sarehu posted:

Seriously? Online forums have had "rules" that are about "be nice to people, don't be a dick," since forever, for example, and they read a lot differently when they aren't full of dog-whistles and designed to reinforce a certain political thesis about how the world is.

I think the rules could use tightening, considering you are still posting.

Deus Rex
Mar 5, 2005

Tarion posted:

You're not really supposed to use unwrap in 'production' code anyways.

Sure you are. Maybe not as much, or in all the same ways, as when you're hacking together a prototype, though.

Alereon
Feb 6, 2004

Dehumanize yourself and face to Trumpshed
College Slice
:siren:We are not having this stupid loving argument in this thread or forum:siren:

If you really want to post about it ask a D&D mod if you can have a thread.

VikingofRock
Aug 24, 2008




Rust is officially getting some new syntactic sugar to make error handling less painful (specificially, a ? operator and a catch statement expression).

edit: fixed link, and statement -> expression

VikingofRock fucked around with this message at 23:34 on Feb 8, 2016

Vanadium
Jan 8, 2005

It's a catch expression thank you very much :colbert:

VikingofRock
Aug 24, 2008




Vanadium posted:

It's a catch expression thank you very much :colbert:

:doh: So it is. I've edited my post.

gonadic io
Feb 16, 2011

>>=
Does anybody want to critique my babby's first data structure? http://codepad.org/SG2ERyJn

There were a few things that I tried to do and failed. I know that the methods should probably be implemented in an impl with a &self parameter but I'm ignoring that for now.

VikingofRock
Aug 24, 2008




gonadic io posted:

Does anybody want to critique my babby's first data structure? http://codepad.org/SG2ERyJn

There were a few things that I tried to do and failed. I know that the methods should probably be implemented in an impl with a &self parameter but I'm ignoring that for now.

I took a stab at re-writing this a little more idiomatically, which should hopefully be helpful. I would probably write the OctreeNode as this, or as this if keeping the ull indexing is important to you. I also made a more-minimally modified version of you code here, keeping the no-impl way of doing things intact.

gonadic io
Feb 16, 2011

>>=
Thanks very much, that's enough to get me started. I've decided to go back and finish the Rust introduction though, as I'm hoping things like into_iter will he explained by its end.

E: let's just say that I'm getting a renewed sense of the frustrations that people often feel when learning haskell

gonadic io fucked around with this message at 13:50 on Feb 19, 2016

VikingofRock
Aug 24, 2008




You might want to do something besides data structures for your first Rust project--they often have difficult ownership relations, so you'll spend a *ton* of time fighting the borrow checker, which is tough when you first start out. I've been coding in Rust for a year and a half now and I still had trouble with the borrow checker when I was coding up some of those Octree examples.

Of course, I guess you could also make the case that going straight for data structures is a good way to dive into Rust head first, in which case go for it!

Linear Zoetrope
Nov 28, 2011

A hero must cook
I'm a bad Rust programmer because once some data structures, especially graphs or trees that require knowing their parents, are involved, I inevitably end up with a couple unsafe blocks. Like, I make 95% of my Rust code safe. I even endeavor to make it effectively impossible to have runtime crashes in FFI wrappers. But a lot of data structures? My feelings end up being, "God drat it, mom! Don't tell me how to live my life! I know what I'm doing!"

E: Actually, on a mostly unrelated note, can someone explain Box to me? I mean, I know what it does. It's a lot like a malloc'd pointer in C. I just can never find a place to use it because every time I try it feels like the Box type ends up infecting the return stack of the entire program.

Linear Zoetrope fucked around with this message at 00:09 on Feb 20, 2016

gonadic io
Feb 16, 2011

>>=
It works!

https://play.rust-lang.org/?gist=3c137f16de010859622b&version=stable

And after only 2 and a half glasses of wine too!

This is step 1 on my plan for world domination writing my game in F#/Unity with the core data structures in Rust.

e: and now to implement ray casting... although I am cheating slightly because I've already implemented all of this in F# before I restarted in Scala and now I'm restarting again in Rust so I'm pretty familiar with the actual logic.

gonadic io fucked around with this message at 00:33 on Feb 20, 2016

Asymmetrikon
Oct 30, 2009

I believe you're a big dork!
Curious - how easy is Rust to integrate into F#/Unity?

gonadic io
Feb 16, 2011

>>=
Not that I've actually done it yet, but Rust's FFI can be used in place of a C++ external function as described by this blog post:
code:
// The plugin referenced by `DLLImport` must be compiled
// and placed in your project's Assets/Plugins/ folder.
// Make sure that you rename the lib<name>.dylib to
// lib<name>.bundle so that Unity can find it.

[DllImport("libunity_rust")]
private static extern int double_input(int x);
// call 'double_input' like any other function
so it doesn't seem that bad to do although anything involving the heap will probably be annoying. There's still lots of resources on the topic though.

And then F# in place of C# is trivial although I might need one or two C# wrappers if Unity demands C# in places? I'm not sure there either.

Basically this is a fun adventure where I throw myself into the deep end and learn some new technologies/languages! I've never used Rust before, nor Unity, the only non-GC'd language I've used before is 1-2 tiny toy C programs, and I haven't really done all that much in F# before.

I am however pretty good at Haskell :q:

gonadic io fucked around with this message at 00:32 on Feb 20, 2016

Tarion
Dec 1, 2014

Deus Rex posted:

Sure you are. Maybe not as much, or in all the same ways, as when you're hacking together a prototype, though.

Ideally, you would have production code that doesn't allow panics to get to the user. That would be a more nuanced way of saying what I originally did.

gonadic io
Feb 16, 2011

>>=
Is there a better way to get the first Some in a list of Options (and if there isn't any, return None) than this?
code:
let children : [(bool, bool, bool); 10] = ...;
let test_child : (bool, bool, bool) -> Option<Vec3<f32>> = ...;

children.into_iter()
        .map(|&(x, y, z)| test_child(x, y, z))
        .find(|x| x.is_some())
        .and_then(|x| x)
test_child is quite an expensive function so I want to calculate it lazily, i.e. only for the children that I need to. I had a look through the standard library but couldn't find anything like msum (as it's called in Haskell) or a more specialised variant in Iterator or Option's docs.

If anybody is interesting in my ongoing project, the ray casting functionality is done now. Also the file's reached 200 lines so I guess I should probably split it into modules and stuff. Any pointers or references are appreciated: https://gist.github.com/anonymous/224fcfb0e171941715a6

gonadic io fucked around with this message at 19:25 on Feb 21, 2016

FamDav
Mar 29, 2008

gonadic io posted:

Is there a better way to get the first Some in a list of Options (and if there isn't any, return None) than this?
code:
let children : [(bool, bool, bool); 10] = ...;
let test_child : (bool, bool, bool) -> Option<Vec3<f32>> = ...;

children.into_iter()
        .map(|&(x, y, z)| test_child(x, y, z))
        .find(|x| x.is_some())
        .and_then(|x| x)
test_child is quite an expensive function so I want to calculate it lazily, i.e. only for the children that I need to. I had a look through the standard library but couldn't find anything like msum (as it's called in Haskell) or a more specialised variant in Iterator or Option's docs.

If anybody is interesting in my ongoing project, the ray casting functionality is done now. Also the file's reached 200 lines so I guess I should probably split it into modules and stuff. Any pointers or references are appreciated: https://gist.github.com/anonymous/224fcfb0e171941715a6

map is lazy though: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.map
and find is short circuiting: https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.find

gonadic io
Feb 16, 2011

>>=

What I have (map and find) works and is short-circuiting, I was just wondering if there was a cleaner solution like [].cat_maybes().head_option() or something.

gonadic io fucked around with this message at 20:16 on Feb 21, 2016

FamDav
Mar 29, 2008

gonadic io posted:

What I have (map and find) works and is short-circuiting, I was just wondering if there was a cleaner solution like [].cat_maybes.head_option or something.

oh gotcha. from your first post it sounded like you were arguing it wasn't.

nothing in the stdlib that handles this, though if you wanted to you could create your own on iterators via an extension


code:
impl<T: Iterator> CoolDudesCoolStuff for T {
  ...
}
and include it where you'd like. I think the only case where they fuse certain iterator methods is something like filter_map where the resulting type of map.filter is redundant.

Aaronepower
Feb 20, 2014

Jsor posted:

E: Actually, on a mostly unrelated note, can someone explain Box to me? I mean, I know what it does. It's a lot like a malloc'd pointer in C. I just can never find a place to use it because every time I try it feels like the Box type ends up infecting the return stack of the entire program.

The only use case I've found that requires a Box is doing direct recursive relationships. http://is.gd/z1z4yB

You'd also want to wrap big data structures in a Box, the stack you're given is probably around 2MB. So stuff like images, or if you're doing data visualisation, you'll probably have a huge dataset, which would probably cause a stack overflow.

FamDav
Mar 29, 2008
super confused; why does

code:
        let a = [1, 2, 3];

        let doubled: Vec<i32> = a.iter()
            .map(|&x| x)
            .collect();
compile whereas

code:
        let a = [1, 2, 3];

        let doubled: Vec<i32> = a.iter()
            .collect();
fails because its trying to build a Vec<&i32>?

Aaronepower
Feb 20, 2014

FamDav posted:

super confused; why does

code:

        let a = [1, 2, 3];

        let doubled: Vec<i32> = a.iter()
            .map(|&x| x)
            .collect();

compile whereas

code:

        let a = [1, 2, 3];

        let doubled: Vec<i32> = a.iter()
            .collect();

fails because its trying to build a Vec<&i32>?

.iter() doesn't consume the collection it is based on, which is why it gives references. So you can have the Iterator, and the collection. If don't want the collection anymore, you can call .into_iter(), which will take the collection, and convert it into an Iterator.
The reason the map works where you dereference x, is because i32 has the trait Copy, so when you dereference it, you're implicitly cloning the value. Neither one of these will compile with a non Copyable type such as a String.

Aaronepower fucked around with this message at 02:07 on Feb 22, 2016

piratepilates
Mar 28, 2004

So I will learn to live with it. Because I can live with it. I can live with it.



Alright so I'm learning Rust again, and I'm trying to make a program that modifies images. I'm making a function that takes an image and returns a copy of that image that is grayscale, but I can't get it to compile yet.

Here's what I have so far:

(The image library is the piston image library (https://github.com/PistonDevelopers/image)
code:
extern crate image;

use std::fs::File;
use std::path::Path;

fn grayscale_image_buffer(input_image: image::ImageBuffer) -> image::ImageBuffer {
    let (image_x, image_y) = input_image.dimensions();

    image::ImageBuffer::from_fn(image_x, image_y, |x, y| {
        let pixel = input_image.get_pixel(x, y);
        let r = pixel.data[0] as f32;
        let g = pixel.data[1] as f32;
        let b = pixel.data[2] as f32;
        let average = (r + g + b) / 3.0;
        image::Luma([average as u8])
    })
}
Now this complains about not having the right number of arguments to ImageBuffer in the parameter and return types, which makes sense since it's a generic container of <Pixel, Container>.

If I change the function to be generic I get this:

code:
extern crate image;

use std::fs::File;
use std::path::Path;

fn grayscale_image_buffer<P, C>(input_image: image::ImageBuffer<P, C>) -> image::ImageBuffer<image::Luma<u8>, C> {
    let (image_x, image_y) = input_image.dimensions();

    image::ImageBuffer::from_fn(image_x, image_y, |x, y| {
        let pixel = input_image.get_pixel(x, y);
        let r = pixel.data[0] as f32;
        let g = pixel.data[1] as f32;
        let b = pixel.data[2] as f32;
        let average = (r + g + b) / 3.0;
        image::Luma([average as u8])
    })
}
Which gives the error "error: the trait `image::buffer::Pixel` is not implemented for the type `P`
[E0277]{" on the function definition line.

Making the function definition read like "fn grayscale_image_buffer<P: image::Pixel, C>" just gives me more errors about, well, everything. Can't find methods for the image passed in that I know exist on ImageBuffer, mismatched types, "error: the type of this value must be known in this context".

Basically all hell breaks loose and I'm not sure what the compiler is expecting of me at this point. What am I missing to make this function work?

Vanadium
Jan 8, 2005

Generally: Getting more errors when you fix one error is perfectly normal and just means the compiler now understands enough of your code to be really unhappy about it. Being unable to find methods you know exist probably has to do with the trait bounds of the impl where the methods are defined not being fulfilled. The type-must-be-known thing is a what you usually get when you try to make it do more inference than it reasonably can, or I guess when it tries to figure out how to continue with code that's already erroneous.

It looks like you need to do input_image.get_pixel(x, y).to_rgb(); before you can get at the data field, because the data field is a thing defined on the concrete Rgb type and not on the Pixel trait (traits don't define fields), but it also looks like you could just call .to_luma() instead and skip the manual averaging and also get some weird weighting they do for each channel.

gonadic io
Feb 16, 2011

>>=
Today I wrote the line
code:
lazy_static! { static ref PLUGIN: Mutex<Cell<Option<UnityPlugin<'static>>>> = Mutex::new(Cell::new(None)); }
That's what I get for trying to port C++ bindings (that make heavy use of global mutable pointers) to Rust I suppose.

VikingofRock
Aug 24, 2008




piratepilates posted:

Alright so I'm learning Rust again, and I'm trying to make a program that modifies images. I'm making a function that takes an image and returns a copy of that image that is grayscale, but I can't get it to compile yet.

...

Basically all hell breaks loose and I'm not sure what the compiler is expecting of me at this point. What am I missing to make this function work?

I took a stab at this, and I'll walk you through my thought process:

First step: the code that you gave has the following error:

quote:

src/lib.rs:10:42: 10:52 error: no method named `dimensions` found for type `image::buffer::ImageBuffer<P, C>` in the current scope
src/lib.rs:10 let (image_x, image_y) = input_image.dimensions();
^~~~~~~~~~
src/lib.rs:10:42: 10:52 note: the method `dimensions` exists but the following trait bounds were not satisfied: `C : core::ops::Deref`

Reading the note there, it seems like we were just not meeting enough of the trait bounds for `dimensions` to exist. It only exists for ImageBuffer<P, C> where P is a Pixel and C is a container which implements `Deref<Target=[P::Subpixel]>` (see http://www.piston.rs/image/image/struct.ImageBuffer.html), but we haven't specified the latter.

So now we have this:
code:
fn grayscale_image_buffer<P, C>(input_image: image::ImageBuffer<P, C>)
    -> image::ImageBuffer<image::Luma<u8>, C> where
        P: image::Pixel,
        C: std::ops::Deref<Target=[P::Subpixel]>
{
    let (image_x, image_y) = input_image.dimensions();

    image::ImageBuffer::from_fn(image_x, image_y, |x, y| {
        let pixel = input_image.get_pixel(x, y);
        let r = pixel.data[0] as f32;
        let g = pixel.data[1] as f32;
        let b = pixel.data[2] as f32;
        let average = (r + g + b) / 3.0;
        image::Luma([average as u8])
    })
}
Progress! But now we get this error:

quote:

src/lib.rs:15:17: 15:27 error: attempted access of field `data` on type `&P`, but no field with that name was found
src/lib.rs:15 let r = pixel.data[0] as f32;

Okay, so what is `data`? I can't find it under the documentation for Pixel, which makes sense because the error is saying it's not there. My guess is that you wanted to implement this for RGB images though (given your variable names), and `image::Rgb<T>` does have a field called `data`. Now this is not generic over all Pixel types: instead, we will just implement it for `image::RGB<T>`, with the appropriate bounds on `T`.

code:
fn grayscale_image_buffer<T, C>(input_image: image::ImageBuffer<image::Rgb<T>, C>)
    -> image::ImageBuffer<image::Luma<u8>, C> where
        T: image::Primitive + 'static,
        C: std::ops::Deref<Target=[T]>
{
    let (image_x, image_y) = input_image.dimensions();

    image::ImageBuffer::from_fn(image_x, image_y, |x, y| {
        let pixel = input_image.get_pixel(x, y);
        let r = pixel.data[0] as f32;
        let g = pixel.data[1] as f32;
        let b = pixel.data[2] as f32;
        let average = (r + g + b) / 3.0;
        image::Luma([average as u8])
    })
}
Now we get another error:

quote:

src/lib.rs:13:5: 20:7 error: mismatched types:
expected `image::buffer::ImageBuffer<image::color::Luma<u8>, C>`,
found `image::buffer::ImageBuffer<image::color::Luma<u8>, collections::vec::Vec<u8>>`

This is because from_fn() returns an ImageBuffer<P, Vec<P::Subpixel>>. So we need to specify this in our return type. After doing that, there are just a few more type errors to fix (you over-specified a few things). The final version looks like this:

code:
fn grayscale_image_buffer<T, C>(input_image: image::ImageBuffer<image::Rgb<T>, C>)
    -> image::ImageBuffer<image::Luma<T>, Vec<T>> where
        T: image::Primitive + 'static,
        C: std::ops::Deref<Target=[T]>
{
    let (image_x, image_y) = input_image.dimensions();

    image::ImageBuffer::from_fn(image_x, image_y, |x, y| {
        let pixel = input_image.get_pixel(x, y);
        let r = pixel.data[0];
        let g = pixel.data[1];
        let b = pixel.data[2];
        let average = (r + g + b) / T::from(3).expect("3 should be convertable to T");
        image::Luma([average])
    })
}
Hopefully this helps!

Urit
Oct 22, 2010
So I'm experimenting with Rust after using Go for a while and I'm having trouble with the classic threading model (I really like Go's process model/goroutine stuff but I want generics and immutability). Are there any solid libraries that let me do CSP-style stuff/selects over channels etc. easily?

Adbot
ADBOT LOVES YOU

gonadic io
Feb 16, 2011

>>=
Is this a reasonable way to pass an optional value over a FFI boundary? Passing a (nullable) pointer and then having the C# code calling another function to free it seems like lots of pain.

code:
#[repr(C)]
pub struct BadOption<T : Sized> {
	is_some : bool,
	value : T
}
e: here's the context.

gonadic io fucked around with this message at 22:04 on Mar 13, 2016

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply