These are chat archives for rust-lang/rust

26th
Nov 2018
David O'Connor
@David-OConnor
Nov 26 2018 00:20

@MartinNuc Current status: wasm_bindgen and web_sys appear fully-featured, but there are no user-friendly guides available for much of their functionility. There are a handful of frontend web frameworks that show promise, but have little-no docs, and I haven't been able to get any of them working (Yew, ruukh, draco, squark). I'm working on my own framework, but it's going very slow, since I'm working off bindgen/web_sys's raw API docs, and the handful of code examples in the guide. I plan to release it with docs and examples that anyone can follow without prior knowledge.

Once this gets sorted out, I imagine Rust could replace JS/TS entirely.

laurent bernabé
@loloof64
Nov 26 2018 06:48
Hi everyone ! I would like to improve the code in this snippet : https://pastebin.com/GQJtKTUK
Is there a way to use the same chess_board_ref in all places of the function ? I mean, in the call to chess_board_ref.drawing_area.connect, inside the connect closure and in the return (Some(chess_board_ref) ?
Because in the currrent implementation, the changes made inside the closure are not reflected to the board whose connect method is called to.
laurent bernabé
@loloof64
Nov 26 2018 06:57
Because i I try this
let chess_board = ChessBoard {
                    drawing_area,
                    reversed: false,
                    logic: game_logic,
                    cells_size,
                };

                let chess_board_ref = RefCell::new(chess_board);

                chess_board_ref.borrow().drawing_area.connect_draw(|_drawing_area, cr|{
                    chess_board_ref.borrow().paint(cr);
                    Inhibit(false)
                });

                Some(chess_board_ref)
I get
error[E0373]: closure may outlive the current function, but it borrows `chess_board_ref`, which is owned by the current function
  --> src/chess_position_trainer/graphic/chessboard.rs:68:68
   |
68 |                 chess_board_ref.borrow().drawing_area.connect_draw(|_drawing_area, cr|{
   |                                                                    ^^^^^^^^^^^^^^^^^^^ may outlive borrowed value `chess_board_ref`
69 |                     chess_board_ref.borrow().paint(cr);
   |                     --------------- `chess_board_ref` is borrowed here
help: to force the closure to take ownership of `chess_board_ref` (and any other referenced variables), use the `move` keyword
   |
68 |                 chess_board_ref.borrow().drawing_area.connect_draw(move |_drawing_area, cr|{
   |                                                                    ^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error
Otherwise, fixing this in a simple way could at least fix the majority part of my program (needing to use the chessboard as mut as well as immutable borrow)
zx9w
@zx9w
Nov 26 2018 07:03

Hi, I presume it's okay to ask stupid questions here?

I have a 2d array of numbers and I want to implement a greedy way to find what is essentially a hamiltonian path, the way I've done it is I start off by picking a row and finding the index of the smallest number in the row, I record the index and then I go to the row with that index and do the same thing (except past indices are filtered out)

The implementation is:

row
.iter().enumerate()
.filter(|(index, _)| !path.contains(&index))
.min_by(|(_, value)| value)

However the items are all wrapped in options after I filter so the min_by doesn't work but if I try to put a .map(|x| x.unwrap()) inbetween it doesn't see the option wrapper?

So basically I'm damned if I do and damned if I don't and I have no idea how to proceed or what's wrong. Please help, would sincerely appreciate :(

laurent bernabé
@loloof64
Nov 26 2018 07:08
(As far as I know, it is really hard to define what is a stupid question regarding computer science, particularly for Rust, which is not a so easy language to master at first)
red75prime
@red75prime
Nov 26 2018 07:09
@zx9w .filter() doesn't wrap items into options. They should come from somewhere else. What error message says?
zx9w
@zx9w
Nov 26 2018 07:12
This message was deleted
error[E0593]: closure is expected to take 2 arguments, but it takes 1 argument  
  --> src/main.rs:30:20                                                         
   |                                                                            
30 |                   .min_by(|&(_, dist)| dist)                               
   |                    ^^^^^^ ------------ takes 1 argument                    
   |                    |                                                       
   |                    expected closure that takes 2 arguments                 

error[E0308]: mismatched types                                                  
  --> src/main.rs:28:19                                                         
   |                                                                            
28 |           path.push(roads                                                  
   |  ___________________^                                                      
29 | |                   .filter(|(index, _)| !path.contains(&index))           
30 | |                   .min_by(|&(_, dist)| dist)                             
   | |____________________________________________^ expected usize, found enum `std::option::Option`
   |                                                                            
   = note: expected type `usize`                                                
              found type `std::option::Option<(usize, &f64)>`                   

error: aborting due to 2 previous errors                                        

Some errors occurred: E0308, E0593.                                             
For more information about an error, try `rustc --explain E0308`.               
error: Could not compile `code`.
oooh min_by is deprecated, min_by_key gives the error that f64 doesn't implement Ord
hey cool now everything is almost working, I just need to be able to compare floats
google will solve this
thanks for being a rubber duck
red75prime
@red75prime
Nov 26 2018 07:19
You can use .min_by(|&(_, dist1), &(_, dist2)| dist1.partial_cmp(dist2).unwrap()), but it will panic if you have NaNs in there, which can be a good thing. NaN distance is most likely a bug
zx9w
@zx9w
Nov 26 2018 07:24
Yep,
thank!
s
haha
Tim Robinson
@1tgr
Nov 26 2018 07:25
@loloof64 the compiler is right, make the closure move |_drawing_area, cr|
laurent bernabé
@loloof64
Nov 26 2018 08:22
But with move i get other errors. Of outlive closure or something like that.
Tim Robinson
@1tgr
Nov 26 2018 08:39
You’ll probably need to keep the move and work out what the other problems are
Is the compiler giving you a hint on how to fix it?
Inside your closure, is there any code other than what you pasted above?
Maybe the closure needs to own some stuff (like the Rc) but borrow others
laurent bernabé
@loloof64
Nov 26 2018 09:17
Thank you for your suggestions : will try them this evening after work
I dont remember of particular hints from the compiler
The closure is as tiny as paste above. I will post the paint method later.
Tim Robinson
@1tgr
Nov 26 2018 09:28
Sometimes the compiler tells you directly what to do, like adding the move keyword
Other times, it might not tell you exactly what to do, but it gives hints that lead you along the right direction
Rust’s approach to errors is to help you, not to print a screen full of technical jargon and give up
laurent bernabé
@loloof64
Nov 26 2018 09:33
Maybe I read too fastly. This evening I'll post the exact error and hints.
trsh
@trsh
Nov 26 2018 11:00
Hi im getting this error when working with futures Message: 'Multiple executors at once: EnterError { reason: "attempted to run an executor while another executor is already running" }'. If some executor is allready running is there some global method to retrieve it?
Denis Lisov
@tanriol
Nov 26 2018 15:08
@loloof64 The easiest way is to write something like
let chess_board_ref_2 = chess_board_ref.clone();
chess_board_ref.borrow().drawing_area.connect_draw(move |_drawing_area, cr|{
    chess_board_ref_2.borrow().paint(cr);
    Inhibit(false)
});
Denis Lisov
@tanriol
Nov 26 2018 15:14
I usually simplify code like that with a macro, however, to avoid thinking up extra variable names.
Tim Robinson
@1tgr
Nov 26 2018 15:16
This is the trick I use:
chess_board_ref.borrow().drawing_area.connect_draw({
    let chess_board_ref = chess_board_ref.clone();    
    move |_drawing_area, cr|{
        // ...code here...
    }
});
In other words, clone the Rc and declare a new variable immediately before the move closure
Gov Ven
@bonorumetmalorum
Nov 26 2018 17:35
Hey guys! I'm just wondering what this syntax means when declaring a trait
trait something : Any {}
Denis Lisov
@tanriol
Nov 26 2018 17:38
To implement Something for a type, you need to have Any implemented too, and do not need any additional types or methods.
Juan Aguilar
@botika
Nov 26 2018 17:47
I have a very strange error in windows, I leave the report and the rust-iendo/v_escape@6475a9d. I do not understand very well what happens since the same commit in gnu and nigthly works correctly.
laurent bernabé
@loloof64
Nov 26 2018 20:28
Thank you very much @tanriol and @1tgr : the code now compiles (even if the gui still does not react as expected, but that's another story). Great to know that I can also move the variables of the closure later in the block :smile:
laurent bernabé
@loloof64
Nov 26 2018 20:46
The problem is that the paint method does not rely this time on the updated chessboard state.
The full chessboard class : https://pastebin.com/YEJixh23
The reversed method does not seem to update the same variable that the one used inside the closure
Denis Lisov
@tanriol
Nov 26 2018 21:06
Sure it does not, you need to use Rc<RefCell<T>> to have both interior mutability and multiple owners...
laurent bernabé
@loloof64
Nov 26 2018 21:38
Ok thank you :smile: Trying with this
Thank you very much :smile: Now the board flip size as expected whenever I press on the related app button :smile:
Denis Lisov
@tanriol
Nov 26 2018 22:00
The new_from_* functions look weird... why do they return Option at all?
laurent bernabé
@loloof64
Nov 26 2018 22:01
Indeed : that was before I used Rc and RefCell :smile:
Oh : that came back to me : the new_from_fen can fail, because of a bad FEN string, and I kept the same Option for the new_from_default, even if it is not meant to fail. So that I have an uniform interface for both methods.
laurent bernabé
@loloof64
Nov 26 2018 22:06
let logic = ChessGame::new_from_fen(initial_position);

        match logic {
            Some(game_logic) => {
Inside get_chessboard, I get a chessboard logical instance from the Shakmaty crate, which ensure that we can pass valid as well as invalid FEN strings => So I use an Option myself in return type to give the caller responsibility of handling error, instead of ChessBoard itself.
Denis Lisov
@tanriol
Nov 26 2018 22:13
If this is due to a possible error, a Result is usually more appropriate. Also, why not just pass an existing ChessGame to the main constructor?
IIUC, your ChessBoard is meant to be a GUI widget for the ChessGame, correct?
laurent bernabé
@loloof64
Nov 26 2018 22:15
Yes, ChessBoard has a GtkDrawingArea, meant to be drawn as a GUI widget
As for Result, you're right : I often misuse Option/Result
I did not understand what you meant for the main constructor
laurent bernabé
@loloof64
Nov 26 2018 22:26
Did you meant this ?
pub fn new_from_default(cells_size: u32) -> Result<Rc<RefCell<ChessBoard>>, String>
    {
        ChessBoard::new_from_fen(
            cells_size,
            "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1",
        )
    }
Denis Lisov
@tanriol
Nov 26 2018 22:45
pub fn new(board: ChessGame) -> Rc<RefCell<ChessBoard>> { ... }
laurent bernabé
@loloof64
Nov 26 2018 22:48
Oh yes, it's just because I wanted to give more meaningful names to "constructors" : but you're right, I should replace the new_from_fen method by new(cells_size: u32, board: ChessGame)
Denis Lisov
@tanriol
Nov 26 2018 23:11
Why is cells_size actually a parameter? Shouldn't you determine it from the amount of space available for your widget?
laurent bernabé
@loloof64
Nov 26 2018 23:11
Indeed I can
That's a old habit from Android, where i can't control the window size
(where width/height of the board takes full size)