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
taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Subjunctive posted:

People often find it off-putting to be in groups where they feel little commonality. The tweet you quote is describing the poster's feeling, not telling anyone else they need to do something differently.

Kathryn Long ‏@StarKat99 May 15 posted:

I'm glad you're aware of it but I think you need to get some specific plans to improve out there sooner rather than later the longer it goes unaddressed, the harder it will be to fix. And I know I'm not the only one that is going to wait and see until there's some definitive efforts of outreach and not just promises and plans

Adbot
ADBOT LOVES YOU

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

VikingofRock posted:

Definitely keep posting here, I'm learning a lot from thinking about the issues that you are presenting and people's responses to them. Also the Rust IRC is a fantastic resource. If you post a question here and no one answers it, you should ask IRC (and then post their response here so we can learn from it too).

I definitely like having some activity in this thread, and these are great little discussions/examples to look at.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

I'm trying to install rust nightly on a new VM. The download from static.rust-lang.org is going incredibly slowly - about 0.1% per five minutes.

Is there a mirror? If so, how do I specify the mirror for the rustup script?

e: Just tried again and it is fixed now.

taqueso fucked around with this message at 06:00 on Apr 3, 2016

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Is there a nice way to initialize an array with values from the concatenation of two constant arrays or slices of constant arrays?

I'd like to do something like this:
code:
const PART1: [u8; 3] = [ 0, 1, 2 ];
const PART2: [u8; 2] = [ 3, 4 ];

fn main() {
    let array = PART1 + PART2; //or (PART1, PART2).concat() or = PART1.concat(PART2) or something
    println!("{:?}", array);
}
The following works. The compiler should optimize away initializing a with [0; 5], right? If I leave a uninitialized, the copy_from_slice lines are in error.
code:
const PART1: [u8; 3] = [ 0, 1, 2 ];
const PART2: [u8; 2] = [ 3, 4 ];

fn main() {
    let mut a: [u8; 5] = [0; 5];
    a[0..3].copy_from_slice(&PART1);
    a[3..5].copy_from_slice(&PART2);
    println!("{:?}", a);
}
I'm using nightly if that matters.

e: #rust says that it isn't possible yet

taqueso fucked around with this message at 18:58 on Jun 6, 2016

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

I'd like to be able to create byte literals using a different notation than the standard, for 'drawing' in an array of bytes. This is to allow creation of bitmap fonts in the code. I'd like to be able to do something roughly like this:
Rust code:
pub const MY_BYTES: [u8; 3] = [
    draw!( 'XXXX' ),
    draw!( 'X__X' ),
    draw!( '_XX_' ),
];

assert_eq!(draw!('X_X_'), 0b1010_0000);
assert_eq!(draw!('___X'), 0b0001_0000);

Right now, I am doing this instead:
Rust code:
use self::draw::*;

pub const MY_BYTES: [u8; 3] = [
    XXXX,
    X__X,
    _XX_,
];

#[allow(dead_code)]
mod draw {
    use types::u8;
    pub const ____: u8 = 0x00;
    pub const ___X: u8 = 0x10;
    pub const __X_: u8 = 0x20;
    pub const __XX: u8 = 0x30;
    pub const _X__: u8 = 0x40;
    pub const _X_X: u8 = 0x50;
    pub const _XX_: u8 = 0x60;
    pub const _XXX: u8 = 0x70;
    pub const X___: u8 = 0x80;
    pub const X__X: u8 = 0x90;
    pub const X_X_: u8 = 0xA0;
    pub const X_XX: u8 = 0xB0;
    pub const XX__: u8 = 0xC0;
    pub const XX_X: u8 = 0xD0;
    pub const XXX_: u8 = 0xE0;
    pub const XXXX: u8 = 0xF0;
}
}
But I would eventually like to be able to be able to work with all 8 bits and I don't want to have to define each one manually. Is it possible to do this with a macro?

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Jsor posted:

I don't think this is macro-able, but this is practically the example for compiler plugins in the book (they use Roman Numerals, but it's the same idea of parsing identifiers to make numbers).

Thanks for pointing that out, it does seem like a good fit and the right place to do this. And if I understand this right, I would make a plugin library that will function like any other lib within the standard cargo dependency system? Rust is too cool.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

I wrote it too. :hf: It was really easy, since that example was almost perfect. https://github.com/jdeeny/drawbytes

This needs to follow the Chip8 defacto standard for the fonts, so it needs to be the most significant bits ('left justified'). I was mulling over how to make it a little more configurable, maybe an optional format string, like 'u8L' or 'u32R'.

When I run cargo test on the library that uses the plugin, I get an error during the doc-test phase. It would be nice to fix this.

e: I had to add plugin = true to the lib section of the plugin's Cargo.toml


taqueso fucked around with this message at 03:54 on Jul 9, 2016

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Rust code:
    fn store(&mut self, dest: Dest, data: usize) -> Chip8Result<()> {
        match dest {
            Dest::Register(r) => if r < self.v.len() { self.v[r] = data as MemoryCell & 0xFF; Ok(()) } else { Err(Chip8Error::OutOfBounds(r)) },
            ...
        }
    }
    fn load(&mut self, src: Src) -> Chip8Result<usize> {
        match src {
            Src::Register(r)    => if r < self.v.len() { Ok(self.v[r] as usize) } else { Err(Chip8Error::OutOfBounds(r)) },
            ...
        }
    }
Is there a better way to turn an vector index into a result?

e: I found get and get_mut in the docs, so I can use
code:
            Dest::Register(r) => self.v.get_mut(r).map(|reg| {*reg = data as Register8 & 0xFF; () }).ok_or(Chip8Error::OutOfBoundsAt(r)),
...
            Src::Register(r)  => self.v.get(r).map(|reg| *reg as usize).ok_or(Chip8Error::OutOfBoundsAt(r)),
I'm not sure if that is better.

taqueso fucked around with this message at 06:45 on Jul 12, 2016

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

QuantumNinja posted:

I'd write it more like:

code:
            Dest::Register(r) => self.v.get_mut(r)
                                       .and_then(|reg| { *reg = data as Register8 & 0xFF; Some(())} )
                                       .ok_or(Err(Chip8Error::OutOfBoundsAt(r))),
...
            Src::Register(r)  => self.v.get(r)
                                       .and_then(|reg| *reg as usize)
                                       .ok_or(Chip8Error::OutOfBoundsAt(r)),
That said, the Dest register thing seems a bit like a misuse of the Result type. Do you plan to catch and handle that Chip8Error? If not, use a panic!. If you do, a Result containing a unit on one side is an Option, and it would probably be nicer to just write update_reg(reg: Reg, index: usize) -> Option<Chip8Error> and call that.

I don't want to panic inside my library for a minor error like this. I'm trying to pass the results all the way out to the API boundary so the calling app can see & handle the errors. I considered using Option here, but didn't use it for 2 reasons - I read somewhere that it was bad form to use None to indicate an error condition, and also so I don't have to convert the Option to a Result in the calling functions. This is pretty analogous to std's use of None when popping from a collection, so it is mostly for the second reason.

The library is pretty functional now, I'll try to post the code later today.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Here's the library: https://github.com/jdeeny/rust-chip8
And here's the SDL2 emulator application: https://github.com/jdeeny/vipchip

The emulator app is pretty bare. cargo run examples/computer.hex will run it. It will run code from a file filled with hex data like you get from Octo or a binary file. Escape to exit.

A few weeks ago I had everything working to about the same point as this, but that time it was all one monolithic app with no tests. This is the result of trying to split it into the UI and a library to handle the core chip8 simulation task. I've gone round in circles on more than a few design decisions in the library.

I used locks on the state data that I thought the UI would want to have fast access to, and channels for the other stuff. Honestly, I just wanted to try both. It sure seems like locks will be faster, but it intrudes on the code everywhere. Curious about a more ergonomic way to do this.

I started with the Operations as classes implementing a trait, but there was a ton of boilerplate so I switched to Enums. I found out about default implementations, so maybe I should switch back. I really don't like how the enums have un-named data. Especially now that I have some operations with flags, it is really ugly.

Can I do Src/SrcKind and Dest/DestKind in a better way? Maybe I need a macro.

Known problem: SimulatorTask needs a run function that will execute instructions autonomously, without the other thread stepping it. Right now it is sort of pointless.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Jsor posted:

Is the untyped Arena dead? I seem to only be able to get TypedArena on nightly.

Looked for the change in github - I think it got moved to the any-arena crate

https://github.com/rust-lang/rust/commit/e2ccc4f744b93f89666fe4c8828905297bb76178#diff-d83049850151ade6fa9c57a0545754ad
https://crates.io/crates/any-arena

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

I wanted a case-insensitive equivalent of tag_s! from nom, so I wrote this one. Is this efficient? Can it be done in a better way?

https://github.com/jdeeny/nom/commit/ef00efa647f77cfd4486c7db50ea2819c81f639d

Rust code:
#[macro_export]
macro_rules! tag_nocase_s (
  ($i:expr, $tag: expr) => (
    {
      let res: $crate::IResult<_,_> = if $tag.len() > $i.len() {
        $crate::IResult::Incomplete($crate::Needed::Size($tag.len()))
      } else if $i[0..$tag.len()].chars().map(|c| (c).to_lowercase().next().unwrap_or(c))
                    .zip($tag.chars().map(|c| (c).to_lowercase().next().unwrap_or(c)))
                    .map(|(tc, ic)| tc == ic)
                    .take_while(|r| *r == true)
                    .count() == $tag.len()
      {
        $crate::IResult::Done(&$i[$tag.len()..], &$i[0..$tag.len()])
      } else {
        $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TagStr, $i))
      };
      res
    }
  );
);
e: Got some help on #rust. Turns out case-insensitive comparison of unicode characters is harder than I thought - https://botbot.me/mozilla/rust/2016-08-18/?msg=71530738&page=13

taqueso fucked around with this message at 16:56 on Aug 18, 2016

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

sarehu posted:

I went to a Rust meetup a couple days ago. Seven people showed.

One guy was a C guy asking questions who seemed to have shown up with no idea what Rust was for. He asked what is it for. He also asked if it had as good a prepocessor system as the C preprocessor. Another seemed to know quite a bit about Rust, and other things. Another guy spent the entire time editing some Medium post. We spent the time doing an exercism.io exercise where an object has a mutable String field.

But, as a result, I wrote my actual first self-originated line of Rust code, so there's that!

Edit: On that note, is there any way to make a match pattern redundantly declare the type of a variable? Take for example
code:
pub fn hello(name: Option<&str>) -> String {
    "Hello, ".to_string() + &match name {
        Some(s) => s.to_string(),
        None => "World".to_string()
    } + &"!".to_string()
}
I wanted to write Some(s: &str). That doesn't work. Is there any way to do that?

Where was your meetup?

I don't think you can do redundant typing inside the match pattern. At least, I couldn't make it happen the other day.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Looks like they have a bay area meetup once a month or so: https://air.mozilla.org/bay-area-rust-meetup-july-2016/

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

gonadic io posted:

Or even better I could make a macro that's invoked like:
code:
let zero = eight_segment_digit!(
  _ 
 | | 
 |_|
);
let two_point = eight_segment_digit!(
  _
  _|
 |_ o
);
:q:

Awhile back I made a thing to allow binary literals to be entered as XX_XXX_XX to allow 'drawing' sprites for a Chip8 emulator. You need to use a compiler plugin rather than a macro to do that kind of stuff.

Here is the response to my post: https://forums.somethingawful.com/showthread.php?threadid=3694683&pagenumber=6&perpage=40#post461902966

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Yes, it is Scientology, but you aren't invited. Sorry. Not sorry.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

xtal posted:

That's dumb as hell

Do you have any reasoning behind that hot take?

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

I guess I don't know much about macros! I love that the quiz has a nice explanation for each Q.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

It matches normal ranges. (..)

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

netcat posted:

If I want to cross compile rust (to ARM), is https://github.com/rust-embedded/cross what I want or are there other/better approaches?

That's what you want. Install and enable docker, run 'cargo install cross' and then 'cross <cargo command like build> --target <target>'. It's fairly magical, I was very impressed with how well it worked.

Except, I had to use the version from this PR: https://github.com/rust-embedded/cross/pull/251
Because without it, it doesn't support SELinux. :/

e: so the install command is 'cargo install --git https://github.com/cyplo/cross/ --branch selinux-support cross'

taqueso fucked around with this message at 18:20 on Jun 13, 2019

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

I'm experiencing semantic satiation for 'borrowed' now, thanks.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

giogadi posted:

What's the rule/guideline for keeping a cargo package's dependencies up-to-date? For example, if a library I want to use is pulling in a super old version of another dependency, is that how things should be or is it expected for maintainers to periodically go through and bump up the required versions of the dependencies in their library?

That's basically how it works, as far as I know. The maintainer is supposed to update occasionally, and use semantic versioning so some updating happens automatically. I guess if you see that and think it is important that the library move to a newer version you would make a PR to update it or fork it.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Mirconium posted:

If you want to do linear algebra there are 2 major libraries, like 5 minor unsupported ones, and they all have overlapping features, yet each one is also missing important stuff. nalgebra has a bunch of types named poo poo like "Matrix2" "Matrix3" "Matrix4" etc, so I'm not particularly optimistic about the fundamental design choices. ndarray cannot invert a matrix without linking to BLAS or LAPAK.

I had a chance to use nalgebra yesterday and remembered this post. Despite rust not yet landing const generics, the library uses the typenum crate to provide type-level numbers. The basic Vector type is, for example, Vector<N, D: Dim>, generic over type and dimension.

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

Did they fix cross working with selinux finally? I've been running off a PR from a year ago that never seems to land. Other than that, the tool is top notch and provides the easiest cross compiles I've ever done.

Adbot
ADBOT LOVES YOU

taqueso
Mar 8, 2004


:911:
:wookie: :thermidor: :wookie:
:dehumanize:

:pirate::hf::tinfoil:

It is really good at "if it compiles it works" assuming you have the right logic.

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