Re: [rust-dev] Destructuring and references

2014-11-10 Thread Vladimir Matveev
Hi, Daniel,

Consider this example:

let vec = vec![(1u, 2u)];

for (a, b) in vec.iter() {
println!({}: {}, a, b);
}

a and b here are of type uint, which is implicitly copyable. It is not
natural to take references to it when passing around its values. That
is, variables under  pattern are not *always* taken as a reference.

Another reason is consistency. Patterns and corresponding constructor
expressions are meant to be inverses of each other:

let x = (1u, 2i);
match x {
(a, b) = ...
}

See how nicely `(a, b)` and `(1, 2)` correspond to each other. `a`
is of type uint, just like the literal 1u, and `b` is int, like 2i.
This expands to other types too, including complex ones like `Box`.
With automatic references there won't be such consistency.

2014-11-10 20:29 GMT+03:00 Daniel Trstenjak daniel.trsten...@gmail.com:

 Dear rust devs,

 let vec = vec![(a.to_string(), b.to_string())];

 for (ref a, ref b) in vec.iter() {
 println!({}: {}, a, b);
 }

 I understand that the '' and 'ref' are needed here, because otherwise
 the 'String' could be moved out of the 'Vec'.

 I don't quite understand, why there's the need for these explicit refs,
 why isn't the outer '' enough to indicate that everything inside of
 the pattern is also referenced?

 Why isn't it possible to just have (with the same semantics):

 for (a, b) in vec.iter() {
 println!({}: {}, a, b);
 }


 Without these refs pattern matching would be aesthetically more in sync
 with the types, which I would consider very pleasing.


 Greetings,
 Daniel
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] String capitalization

2014-09-12 Thread Vladimir Matveev
Hi, Ollie,

This variant is terser, but it could be even more readable if there were some 
kind of connect() for iterators. It surprised me that there is no such thing in 
Rust iterators. It would be possible to use some kind of interleave() for 
iterators for the same purpose, but there is no such thing as well. Hence I had 
to use fold() and then pop_char() which is rather nasty as it breaks method 
chain.

On the other hand, this variant performs less allocations than your original 
version because the resulting string is allocated in advance.

use std::char;

fn name_from_file(file: String) - String {
let mut r = file.as_slice().split('-')
.map(|w| 
char::to_uppercase(w.char_at(0)).to_string().append(w.slice_chars(1, w.len(
.fold(
String::with_capacity(file.len()+1), 
|r, w| r.append(w.as_slice()).append( )
);
r.pop_char();
r
}

fn main() {
let hypenated_string   = hello-there.to_string();
let capitalized_string = name_from_file(hypenated_string);
println!({}, capitalized_string);
}

See it in action here: http://is.gd/UKKB96

BTW, I suggest you to use Stackoverflow [1] (preferred) or Reddit [2] to ask 
questions like this. The active community there is much larger than here, so 
you can get an answer quicker.

  [1]: http://stackoverflow.com/questions/tagged/rust
  [2]: http://www.reddit.com/r/rust/


On 12 сент. 2014 г., at 15:35, Oldřich Vetešník oldrich.vetes...@gmail.com 
wrote:

 Hello,
 
 this is probably going to sound silly, but can this be written better?
 I’d like to turn “hello-there” into “Hello There”.
 I was thinking about something along the lines of split - map - capitalize 
 - join but the capitalization seems kind of awful to me.
 
 use std::char;
 
 fn name_from_file(file: String) - String {
 let mut words: Vecstr = file.as_slice().split('-').collect();
 let mut cap_words= Vec::new();
 
 for word in words.mut_iter() {
 let first = char::to_uppercase(word.char_at(0)).to_string();
 let rest  = word.slice_chars(1, word.len());
 
 let cap_word = first.append(rest);
 cap_words.push(cap_word);
 }
 
 cap_words.connect( )
 }
 
 fn main() {
 let hypenated_string   = hello-there.to_string();
 let capitalized_string = name_from_file(hypenated_string);
 println!({}, capitalized_string);
 }
 
 
 Thanks,
 Ollie
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Closures with owned environments

2014-09-09 Thread Vladimir Matveev
Hi, Allen!

In fact, it is possible to do it now without DST, using unboxed closures only:

#![feature(unboxed_closures, unboxed_closure_sugar)]

fn make_adder(x: int) - Box|: int| - int {
box |: y: int| x + y
}

fn main() {
let f = make_adder(3);
println!({}, f.call((4i,)));
}

Test it here: http://is.gd/mCJ6Dh

This code employs the idea that unboxed closure is just an instance of
some anonymous struct implementing one of Fn* traits, so we can just
return a boxed trait object representing the closure. The call syntax
is ugly, however, but this should change in the nearest future (though
explicit dereferencing, like (*f)(x), will likely be needed anyway).

2014-09-10 0:39 GMT+04:00 Allen Welkie allen.wel...@gmail.com:
 In this stackoverflow question:

 http://stackoverflow.com/questions/21130272/return-a-closure-from-a-function

 Chris Morgan mentions the possibility of adding closures with owned
 environments with the DST implementation. Is this being done with the
 current DST effort? If not, are there plans to add it?

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Is there a PNG lib?

2014-09-08 Thread Vladimir Matveev
Hi!

These libraries may be interesting for you:
 * https://github.com/servo/rust-png
 * https://github.com/PistonDevelopers/rust-image

It is also very simple to run external tools like ImageMagick from Rust. You 
will need Command [1] API for that.

  [1]: http://doc.rust-lang.org/std/io/process/struct.Command.html

On 08 сент. 2014 г., at 17:44, Oldřich Vetešník oldrich.vetes...@gmail.com 
wrote:

 Hello,
 
 I’m curious - is there a PNG processing lib for Rust? I’d like to write a 
 tiny client tool for processing a directory of images into HTML and I’ll need 
 to resize those big images.
 I tried searching but wasn’t very successful. :-)
 
 Thank you,
 Ollie
 
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Is there a PNG lib?

2014-09-08 Thread Vladimir Matveev
You’re welcome :)

Cargo will provide a central repository in the future, but in the meantime you 
can use these sites [1][2] to search for packages. Also, as Github is the main 
repository hosting used by the Rust community, you can search there and you can 
be fairly confident that if you can’t find something there then it probably 
does not exists :)

  [1]: http://www.rust-ci.org/
  [2]: http://rustkit.io/

On 08 сент. 2014 г., at 18:03, Oldřich Vetešník oldrich.vetes...@gmail.com 
wrote:

 Awesome, thank you guys!
 
 I’m really looking forward to “cargo search”. :-)
 
 Ollie
 
 
 On Monday 8 September 2014 at 15:57, Vladimir Matveev wrote:
 
 Hi!
 
 These libraries may be interesting for you:
 * https://github.com/servo/rust-png
 * https://github.com/PistonDevelopers/rust-image
 
 It is also very simple to run external tools like ImageMagick from Rust. You 
 will need Command [1] API for that.
 
 [1]: http://doc.rust-lang.org/std/io/process/struct.Command.html
 
 On 08 сент. 2014 г., at 17:44, Oldřich Vetešník oldrich.vetes...@gmail.com 
 (mailto:oldrich.vetes...@gmail.com) wrote:
 
 Hello,
 
 I’m curious - is there a PNG processing lib for Rust? I’d like to write a 
 tiny client tool for processing a directory of images into HTML and I’ll 
 need to resize those big images.
 I tried searching but wasn’t very successful. :-)
 
 Thank you,
 Ollie
 
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org (mailto:Rust-dev@mozilla.org)
 https://mail.mozilla.org/listinfo/rust-dev
 
 
 
 

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] [ANN] Iobuf

2014-09-04 Thread Vladimir Matveev
Hi!

I’ve noticed this piece of code in your library:

#[inline]
fn as_mut_slice(self) - mut [u8] {
unsafe {
match self {
OwnedBuffer(ref v) = {
let mut_v: mut Vecu8 = mem::transmute(v);
mut_v.as_mut_slice()
},
BorrowedBuffer(ref s) = {
let mut_s: mut mut [u8] = mem::transmute(s);
mut_s.as_mut_slice()
},
}
}
}

I was under impression that transmuting  to mut is undefined behavior in 
Rust, and you need to use RefCell (or UnsafeCell) for this. Am I wrong?

On 04 сент. 2014 г., at 9:17, Clark Gaebel cg.wowus...@gmail.com wrote:

 Hey everyone!
 
 Have you ever needed to communicate with the outside world from a rust 
 application? Do you need to send data through a network interface, or touch a 
 disk? Then you need Iobufs!
 
 An Iobuf is a nifty abstraction over an array of bytes, which makes writing 
 things like highly efficient zero-copy speculative network protocol parsers 
 easy! Any time I need to do I/O, I reach for an Iobuf to do the heavy lifting.
 
 https://github.com/cgaebel/iobuf
 
 Enjoy,
   - Clark
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Implementing a clone trait on mut struct.

2014-08-04 Thread Vladimir Matveev
Forgot to send a copy to mailing list.

2014-08-04 10:30 GMT+04:00 Vladimir Matveev dpx.infin...@gmail.com:
 Hi, Paul,

 The problem with Clone implementation for mutable reference is not
 that it does not make sense at all; after all, it is just an integer
 value behind the fancy name, and, for example, plain  references [are
 cloneable](http://doc.rust-lang.org/std/clone/trait.Clone.html).
 However, Clone can't be implemented for mutable references because
 mut is unaliasable - there can't be more than one mutable reference
 pointing to the same thing at the same time, but Clone does exactly
 this.

 Moreover, you say that `PoolT` is an abstraction over
 `ArcRWLockT`, right? This means that `T` should also be Share +
 Send, and while references are Share, they are not Send - you can't
 send a reference to another task because it can point to original
 task's stack, and if that original task exits, the reference may
 become invalid. So it is likely that your overall design is incorrect.
 It's hard to say more without more details on what you want to do.

 2014-08-04 6:02 GMT+04:00 Paul Nathan pnathan.softw...@gmail.com:
 Hi,

 I've gotten myself in a bit of a bind.

 As part of my work with shared memory with workers, I've implemented a
 (relatively leaky at the moment) abstraction over ArcRWLockT, called
 Pool.

 Part of my abstraction requires the Clone trait be implemented for T.

 However, up in the user layer, I have something that looks roughly like this

 struct Agent { ... }

 struct Tracker {
   Pool'r mut Agent
 }

 At which point, the type checker complains and asks me to implement
 something of this signature:

 impl'r Clone for 'r mut Agent {

 Which seems quite patently ridiculous - as if I understand things something,
 I'm being asked to return a reference to something on the *stack* of the fn
 clone() function. Something smells fishy here...

 Some assistance and clarification would be appreciated.

 Regards,
 Paul

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Rust Executable size

2014-07-11 Thread Vladimir Matveev
Hi, Adrian,

Currently Rust uses static linking to build executables. This means that the 
simplest «hello world» program utilizing standard library will take all of this 
library and all dependent libraries, including Rust runtime, into itself. 
That’s why the binary is large.

If you want to use dynamic linking, you can invoke rustc with `-C 
prefer-dynamic` arguments, this will link the program dynamically, and it will 
be much smaller (8 KB in my case):

% cat main.rs
fn main() {
println!(Hello world)
}
% rustc -C prefer-dynamic main.rs
% ls -lh main   
-rwxr-xr-x 1 dpx-infinity dpx-infinity 8,0K июл 11 12:14 main

However, this will mean that the binary is no longer portable; you can’t 
compile it yourself and distribute it to other machines unless these machines 
also have the same version of Rust installed.

Disk size is cheap these days, and portability really do matter, so that’s why 
the static linkage is default. BTW, Go does exactly the same thing.

On 11 июля 2014 г., at 12:07, Adrian Mercieca amerci...@gmail.com wrote:

 Hi all,
 
 I am just starting out looking at Rust and am following the tutorial.
 
 I have compiled the sample 'hello world' program (code below - copied from 
 the tutorial) and compiled it.
 
 I was somewhat taken aback at the size of the executable size for such a 
 small program.
 
 On my Ubuntu 13.10 machine, the resultant executable was a whopping 1054476 
 bytes.
 I stripped the program and the resultant file was still 806816 bytes.
 
 Why is the executable so large? Is there anything I might be doing wrong?
 Perhaps I need to use some compiler switches?
 
 Thanks for any pointers in this regard.
 
 - Adrian.
 
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Cargo multiple targets

2014-07-02 Thread Vladimir Matveev
Hi, Isak!

According to manifest documentation [1] you can specify crate type (dynamic or 
static lib or rlib) using crate_type option:

[[lib]]
…
crate_type = [dylib, staticlib]

The above configuration should build you both .a and .so files.

[1]: http://crates.io/manifest.html, search for crate_type w/o quotes

On 02 июля 2014 г., at 15:58, Isak Andersson cont...@bitpuffin.com wrote:

 Hi!
 
 Thanks for the reply!
 
 Apparently multiple targets does in fact work. Just that you can't rely on the
 default path anymore, so I had to add the path = ... to both the [[lib]] and 
 [[bin]].
 Not sure if this is a bug or not.
 
 However the library compiles as an rlib and I'm not sure how to change it to 
 build
 a C library instead (a .a or .so on *nix or .lib I think on windows).
 
 Actually I'm not even sure how to make rustc build a C library so I guess 
 that's what
 I will start looking at.
 
 
 On Wed, Jul 2, 2014 at 1:37 PM, Sebastian Gesemann s.gesem...@gmail.com 
 wrote:
 On Wed, Jul 2, 2014 at 12:49 PM, Isak Andersson wrote:
  Hello Rust folks!
 
  I am using Cargo and I am trying to specify mulitple targets in my
  Cargo.toml file.
  First of all is this even possible?
  ...
  [package]
  name = hmproof
  version = 0.1.0
  authors = [ i...@houstonmedia.se ]
  [[bin]]
  name = hmwhoami
  [[lib]]
  name = proof
  (I also tried adding a path)
  path = src/proof.rs
  [dependencies.rust-http]
  git = https://github.com/chris-morgan/rust-http.git;
 
  I also tried putting the [[lib]] part after the dependencies part. The error
  I get is this:
  error: couldn't read src/bin/hmwhoami.rs: couldn't open file (no such file
  or directory [...]
  Whiich doesn't make any sense at all to me. Why does it suddenly start
  looking in src/bin?
 
 According to http://crates.io/manifest.html the default path for a
 binary is src (if there is no other lib) and src/bin (if there is also
 a lib target). You should be able to override this with path =
 src/hmwhoami.
 
  Do I have to put my bin code in src/bin and my lib code in src lib or what?
 
 Currently, only a single lib per package is supported and it seems,
 judging by the document about the manifest format, that Cargo always
 looks for src/lib.rs for a library unless you override this using a
 path=something.
 
 As for how to tell Cargo to invoke rustc with the appropriate -L
 option: I don't know.
 
 HTH,
 sg
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
 
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Fwd: self/mut self in traits considered harmful(?)

2014-06-17 Thread Vladimir Matveev
 Overloading Mul for matrix multiplication would be a mistake, since that 
 operator does not act the same way multiplication acts for scalars.

I think that one of the main reasons for overloading operators is not their 
genericity but their usage in the code.

let a = Matrix::new(…);
let x = Vector::new(…);
let b = Vector::new(…);
let result = a * x + b;

Looks much nicer than

let result = a.times(x).plus(b);

In mathematical computations you usually use concrete types, and having 
overloadable operators just makes your code nicer to read.

That said, for mathematicians it is absolutely not a problem that 
multiplication for matrices works differently than for scalars.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Porting a small DSP test from C++ to Rust: Comments and performance observations

2014-06-11 Thread Vladimir Matveev
Hi, Kevin!

 * What would be the replacement for a struct-scoped static constant, so I 
 could put a static inside a struct instead of making it a global?
It is not possible now. There are some suggestions on associated items, but I 
don’t think they are active. Currently Rust module system is used to control 
scopes of statics.

 * Rust doesn't have prefix/postfix increment? Or, I just didn't find the 
 right syntax of using it?
Yes, Rust doesn’t have it. You should use composite assignment: x += 1. It is 
not an expression, though.

 * My biggest problem was figuring out how to use arrays. Originally, things 
 just weren't working and I think it's because I was inadvertently copying an 
 array instead of referring to the original. t just couldn't figure out how to 
 create a mutable alias to an array passed into a function by reference.
Well, you have correctly figured out that it is done using slices :)

 * I understand the reasoning behind explicit integer conversions, but 
 depending on what one is doing, it can add to a lot of explicit conversions, 
 and I also didn't figure out a way to do an unsigned for loop.
Yes, explicit conversions may sometimes be too verbose. As for unsigned for 
loop, it is easy. Remember, Rust uses type inference to find out correct types 
of all local variables. `range()` function which creates range iterators is 
generic and looks like this:

fn rangeT(from: T, until: T) - RangeT { … }

(actual definition is different because T is not arbitrary but bounded with 
some traits)

The `T` type parameter is determined automatically from the use site of the 
function. In your case it is deduced as `int` because  of `length` variable 
(which is of `int` type). So you can just cast `length` to `uint`:

for i in range(0, length as uint) { … }

and `i` variable will be unsigned. BTW, why did you define `length` parameter 
as `int` at all? You can make it `uint` and you won’t need to do this cast.

 * When creating / using arrays, there is sometimes duplication of the size 
 parameter. Is there a way to reduce that?
I don’t think so. They are statically sized arrays, so they just need their 
size specified. When you don’t care about their size, you usually use slices 
anyway.

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] 7 high priority Rust libraries that need to be written

2014-06-10 Thread Vladimir Matveev
Well, JSR-310 is implemented here [1], and it is licensed under GPL2 license. 
As far as I remember, in that case Google reproduced some internal Java API, so 
this seems to be a different thing. BTW, one of the implementors of JSR-310 
suggested [3] looking into an older implementation which is now a backport of 
JSR-310 to JavaSE 7 [2]. It is licensed under BSD license, which is even more 
permissive.

Also because Rust is a different language with completely different idioms and 
approaches to API design, I think we’ll have no problems in this regard - the 
actual API is going to be quite different from the original JSR-310.

  [1]: http://hg.openjdk.java.net/threeten/threeten/jdk
  [2]: https://github.com/ThreeTen/threetenbp
  [3]: https://github.com/mozilla/rust/issues/14657#issuecomment-45240889

On 10 июня 2014 г., at 20:47, Matthieu Monrocq matthieu.monr...@gmail.com 
wrote:

 Could there be a risk in using JSR310 as a basis seeing the recent 
 judgement of the Federal Circuit Court that judged that APIs were 
 copyrightable (in the Google vs Oracle fight over the Java API) ?
 
 -- Matthieu
 
 
 On Sat, Jun 7, 2014 at 6:01 PM, Bardur Arantsson s...@scientician.net wrote:
 On 2014-06-05 01:01, Brian Anderson wrote:
  # Date/Time (https://github.com/mozilla/rust/issues/14657)
 
  Our time crate is very minimal, and the API looks dated. This is a hard
  problem and JodaTime seems to be well regarded so let's just copy it.
 
 JSR310 has already been mentioned in the thread, but I didn't see anyone
 mentioning that it was accepted into the (relatively) recently finalized
 JDK8:
 
http://docs.oracle.com/javase/8/docs/api/java/time/package-summary.html
 
 The important thing to note is basically that it was simplified quite a
 lot relative to JodaTime, in particular by removing non-Gregorian
 chronologies.
 
 Regards,
 
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
 
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Generic Database Bindings

2014-06-08 Thread Vladimir Matveev
There is also rustsqlite[1].

It would be great to have generic bindings for databases, like in Go or in 
Java. In Rust, however, reflective approaches of these won’t work because Rust 
lacks structural reflection. I guess, generic bindings will have to follow type 
classes approach, like Encodable/Decodable (maybe even use them, taking 
advantage of automatic deriving).

  [1]: https://github.com/linuxfood/rustsqlite

On 08 июня 2014 г., at 16:19, Steve Klabnik st...@steveklabnik.com wrote:

 There isn't no. If you want to build a binding, just do it! The only
 one I'm really aware of right now is
 https://github.com/sfackler/rust-postgres
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Deprecating rustpkg

2014-06-07 Thread Vladimir Matveev
Hi, Fredrik,

Currently a new package manager designed specifically for Rust is under active 
development. It is called Cargo, and you can find it here [1]. It is pretty 
much in very alpha stage now, but one day it will become a full package manager 
and build system for Rust.

  [1]: https://github.com/carlhuda/cargo

On 07 июня 2014 г., at 23:28, Fredrik Ekholdt fre...@gmail.com wrote:

 Hi!
 Seems like this thread has been dead for a while. I am new to rust, but was 
 playing with it today, looking for rustpkg and ended up reading this thread. 
 I have tried to read through this thread, but it is possible that there is a 
 newer more relevant thread covering this topic in which case I excuse myself.
 
 I am currently working on a language agnostic dependency/package manager and 
 I was wondering whether it might suit Rusts requirements. Right now we are 
 targeting it as a replacement to Maven/Ivy on the JVM, but the idea all along 
 is to make it platform independent (and native) by having a small and 
 predicable algorithm for resolution.
 The resolution engine is written 200 LOCs, and the overall logic (excluding 
 metadata reading and so on) is about 400 LOCs more. (I wonder if the Rust 
 implementation will be faster than the one in Scala? :)
 
 If there is interest I might start looking more into how to port it (I will 
 need help though) - if not, I guess it was worth a shot! :)
 
 It is called Adept (https://github.com/adept-dm/adept) and it is in alpha for 
 the Scala/JVM. The docs (listed below) are still unfortunately a bit 
 scattered so I am summarising here.
 
 Some features that might be of interest:
 - Fast and reliable resolution of metadata using  versioned metadata (which 
 is easily  safely cacheable).
 - Fast and reliable artifact (binary files/sources) downloads, i.e. can 
 download from multiple sources in parallel.
 - Authors can describe compatibility matrixes of their modules. The short 
 story is that authors can rank modules and thereby define which ones are 
 compatible (or can be replaced) and in multiple files thereby having many 
 “series” of compatible modules. Using this scheme we can emulate: “normal” 
 versioning, (what is called) semantic” versioning and backward compatibility 
 matrixes, but also other, more exotic, version schemes as well. AdeptHub (see 
 below) will make it easy for authors to use the standard ones, but also make 
 it possible to customise this.
 - Adept’s engine is flexible enough so that authors can publish multiple 
 packages to multiple platforms and based on user input figure out which 
 package  platform a user should get.
 - Adept’s engine is flexible enough to emulate the concept of 
 scopes/configurations/views so an author can publish different 
 scopes/configurations/views of the same package: one for compile, one for 
 runtime, one for testing, etc etc.
 - Supports resolution through multiple attributes author-defined attributes. 
 You can require a specific version, a binary-version, but also “maturity” (or 
 release-type”) or whatever other attribute that might be relevant.  
 - Does not require a user to resolve (figure out which packages you need), 
 when they check out code a project. The way this works is that Adept 
 generates a file after resolution that contains all artifacts (their 
 locations, their hashes, filenames) that is required, as well as current 
 requirements and the context (which metadata and where it should be 
 downloaded from). Users/build server will therefore get exactly the same 
 artifacts each time they build (using the SHA-256 hashes), but using 
 compatibility matrixes it is possible to upgrade to a later compatible 
 version easily/programmatically. This file currently called the lockfile , 
 but it is not to be confused with Rubygem lockfiles. Note the name ‘lockfile' 
 will change of because of this confusion.
 - Is decentralized (as Git), but has a central hub, adepthub.com, (as GitHub) 
 so first-time users can easily find things.
 - Decentralization makes it possible for users to change metadata (and 
 contribute it or put it somewhere else), but also makes it possible to 
 support a dsl/api in the build tool, where users can create requirements on 
 build time (version ranges is supported through this).
 - Works offline (i.e not connected to the intertubes) provided that 
 metadata/artifacts is locally available. It knows exactly what it needs so if 
 something is not available  it can give easy-to-understand error messages for 
 when something is missing (which is different from Ivy/Maven although I am 
 not sure what the story for cargo or rustpkg was…).
 - Supports sandboxed projects reliably (no global/changing artifacts). When 
 you checkout a project that uses Adept, you can be sure it has the same 
 artifacts as the one you used on your dev machine.
 - CLI-like search for packages (through Scalas sbt, but can be extended to a 
 pure CLI tool). Works locally and on online repositories.
 - 

Re: [rust-dev] Passing arguments bu reference

2014-06-01 Thread Vladimir Matveev
Aw, Gmail makes it so easy to press Reply instead of Reply to all.
See below :)

 Hi, Christophe,

 Because `Vec` looks like this:

 struct VecT {
 len: uint,
 cap: uint,
 data: *mut T
 }

 its actual size is just three words, so you can freely pass it around
 regardless of number of items in it. So, the correct signature is this
 one:

 fn my_func(src: Vecu8) - Vecu8

 However, it actually depends on your actual use case. Passing a vector
 by value means that the function you pass it to will consume it, and
 you won't be able to use it again in the calling code:

 let v = vec!(1, 2, 3);
 my_func(v);
 v.push(4);  // error: use of moved value `v`

 If you don't need this (and it happens very rarely, in fact), you
 should use references. Whether they are mutable or not depends on what
 you want to do with the vector.

 fn modify_vector_somehow(v: mut Vecu8) { ... }

 let v = vec!(1, 2, 3);
 modify_vector_somehow(mut v);
 v.push(4);  // all is fine

 2014-06-01 12:34 GMT+04:00 Christophe Pedretti 
 christophe.pedre...@gmail.com:
 Hello all,

 I've read this :
 http://words.steveklabnik.com/pointers-in-rust-a-guide

 I am coming from Java where everything is passed and returned by
 reference (except for primitive data types), no choice.

 I know that with C, you have to use pointers to avoid passing and
 returning by value.

 When i read the mentionned guide, things are not so evident with Rust.

 So, to be precise, imagine i need to write à fonction which takes à
 big Vecu8 (In my case it´s an SQL BLOB) as argument and returns a
 big Vecu8

 Should i use
 Fn my_func(src : Vecu8) - Vecu8
 Fn my_func(src : Vecu8) - ~Vecu8
 Fn my_func(src : Vecu8) -Vecu8
 Fn my_func(src : Vecu8) - Vecu8
 Fn my_func(src : ~Vecu8) - ~Vecu8
 Any other combination ?

 Thanks

 PS : i know that i have to use lifetimes and that ~ are now Box, i've
 omitted them to simplify my demand
 PS2 : genrally with a language you can accomplish the same thing with
 different methods, but there are also common usages, even if Rust is
 young, what is the usage for passing and returning large data values
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

2014-06-01 12:34 GMT+04:00 Christophe Pedretti christophe.pedre...@gmail.com:
 Hello all,

 I've read this :
 http://words.steveklabnik.com/pointers-in-rust-a-guide

 I am coming from Java where everything is passed and returned by
 reference (except for primitive data types), no choice.

 I know that with C, you have to use pointers to avoid passing and
 returning by value.

 When i read the mentionned guide, things are not so evident with Rust.

 So, to be precise, imagine i need to write à fonction which takes à
 big Vecu8 (In my case it´s an SQL BLOB) as argument and returns a
 big Vecu8

 Should i use
 Fn my_func(src : Vecu8) - Vecu8
 Fn my_func(src : Vecu8) - ~Vecu8
 Fn my_func(src : Vecu8) -Vecu8
 Fn my_func(src : Vecu8) - Vecu8
 Fn my_func(src : ~Vecu8) - ~Vecu8
 Any other combination ?

 Thanks

 PS : i know that i have to use lifetimes and that ~ are now Box, i've
 omitted them to simplify my demand
 PS2 : genrally with a language you can accomplish the same thing with
 different methods, but there are also common usages, even if Rust is
 young, what is the usage for passing and returning large data values
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] failed to find an implementation of trait core::cmp::TotalEq for ~str

2014-05-31 Thread Vladimir Matveev
Hi, Christophe,

You shouldn't be using `~str` at all, you should use `String`. Also,
`box ` is not a replacement for `~`, they have different types.
The proper replacement is `String::new()` or `.to_string().

Your code in modern Rust will look like this:

/// Contains a list of properties. A property is a key-value pair.
pub struct Properties {
props: HashMapString, String
}

impl MapString, String for Properties {
/// Get a property value giving its name. Return None if property
does not exist.
fn find'a('a self, key: String) - Option'a String {
self.props.find(key)
}

/// Return true if a property value exists for the specified key
fn contains_key(self, key: String) - bool {
self.props.contains_key(key)
}
}



2014-05-31 22:21 GMT+04:00 Christophe Pedretti christophe.pedre...@gmail.com:
 Hi all,

 i have updated my rust compiler, i have several compilations errors on my
 project

 StrBuf does not exist any more, no problem, i now use String
 ~ is obsolete, no problem, i use box 
 The last isssue is  failed to find an implementation of trait
 core::cmp::TotalEq for ~str
 util\properties.rs:12   self.props.find(key)
 ^~~~

 My code is very simple and was compiling before

 ///Contains a list of properties. A property is a key-value pair.
 pub struct Properties {
 props : HashMap~str, ~str
 }

 impl Map~str, ~str for Properties {
 ///Get a property value giving its name. Return None if property does not
 exist.
 fn find'a('a self, key : ~str) - Option'a ~str {
 self.props.find(key)
 }
 ///Return true if a property value exists for the specified key
 fn contains_key(self, key: ~str) - bool {
 self.props.contains_key(key)
 }
 }

 what i am doing wrong ?

 Thanks


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] cannot borrow `st` as mutable more than once at a time

2014-05-30 Thread Vladimir Matveev
2014-05-30 5:37 GMT+04:00 Kevin Ballard ke...@sb.org:

 It shouldn't.

 The for-loop desugaring looks like

 match mut st.execute_query() {
 __i = loop {
 match __i.next() {
 None = break,
 Some(mut __value) = {
 let i = __value;
 {
 // for loop body goes here
 }
 }
 }
 }
 }

 It's done with a match statement like this specifically to make the mut 
 binding of the iterator end after the for loop.

Great, didn't know it. Last time I asked (on StackOverflow, I think;
that was some time ago though) there were no `match`. Then from that
code alone it does look like a bug to me. Note that it refers to
`st.set_string(%e%)` and `for` loop ten lines above, that is, the
first one. If mutable borrow of the iterator aren't escaping the loop,
then this error should not appear, right?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A few random questions

2014-05-29 Thread Vladimir Matveev
 It happens even for this:

 struct Test {
   a: int
 }

 impl ToStr for Test {
   fn to_str(self) - String {
 self.a.to_str()
   }
 }

 As you can see, Test is not implementing Show, so I assumed that I
 could implement ToStr instead. I suspect that there is somewhere an
 implementation
   implT: ToStr Show for T
 and after I implemented ToStr, Test automatically became an
 implementation of Show, which in turn led to conflict. I might be
 wrong though. I'd like to note that if there was a sane implementation
 of overloaded functions, this could be resolved.

Yes, that's how trait resolution currently works. There is an RFC on
that which turns traits into something resembling type classes in
Haskell, with proper resolution of overlapping instances:
https://github.com/rust-lang/rfcs/pull/48, however, I'm not sure if it
will help in this case.

Currently if you want to implement `ToStr` manually, you should
implement `std::fmt::Show` instead:

use std::fmt;

impl fmt::Show for Test {
fn fmt(self, f: mut fmt::Formatter) - fmt::Result {
write!(f, {}, self.a)
}
}

Now you can use `to_str()`:

let t = Test { a: 10 }
println!({}, t.to_str());  // 10

2014-05-29 6:17 GMT+04:00 Oleg Eterevsky o...@eterevsky.com:
 Thanks for your answers. Can't say I understand or agree with all the 
 decisions.

 1. Not everyone prefers overloaded functions, or default arguments.

 Suppose, I want to add a new argument to a function in a
 backwards-compatible way. In Python I provide a default and everything
 works fine. In C++ or Java I write something like

 fn test(old_arg: int, new_arg: int) {
   ...
 }

 fn test(old_arg: int) {
   test(old_arg, 0)
 }

 and everything is still good. What should I do in Rust?

 2. Design decision. Basically, we take Erlang's philosophy: recovering
 from errors is tricky and error-prone.

 So basically this mean that you could emulate exceptions by running a
 co-routing and catching its state? It makes sense, though it sounds
 like it overcomplicates things a bit from programmer's perspective.
 Also I'm a bit worried about the number of unwrap's.

 4. It looks like vectors can be concatenated with + operations, but
 strings can't. Is it deliberate?
 4. I believe so, yes. We try not to be overload-heavy.

 In my experience + is much more often used for strings than for
 vectors. Is it not?

 6. I believe there is a default implementation, yes.

 It happens even for this:

 struct Test {
   a: int
 }

 impl ToStr for Test {
   fn to_str(self) - String {
 self.a.to_str()
   }
 }

 As you can see, Test is not implementing Show, so I assumed that I
 could implement ToStr instead. I suspect that there is somewhere an
 implementation
   implT: ToStr Show for T
 and after I implemented ToStr, Test automatically became an
 implementation of Show, which in turn led to conflict. I might be
 wrong though. I'd like to note that if there was a sane implementation
 of overloaded functions, this could be resolved.

 On Wed, May 28, 2014 at 5:47 PM, Steve Klabnik st...@steveklabnik.com wrote:
 A few quick intro answers. Just the high level, not comprehensive.

 1. Not everyone prefers overloaded functions, or default arguments. I
 know pcwalton has strong feelings about the first, so I'll leave him
 to that :)

 2. Design decision. Basically, we take Erlang's philosophy: recovering
 from errors is tricky and error-prone. Better to let a task fail and
 start a new one rather than to try to re-start one in the middle of
 whatever it's doing.

 3. No opinions, but know that all of this has been changing a _lot_
 recently, this may even be planned.

 4. I believe so, yes. We try not to be overload-heavy.

 5. This is being worked on. Vec is a new construct anyway.

 6. I believe there is a default implementation, yes.

 7. I'm not even getting into this one. There's been a toon of
 discussion about this lately.
 https://github.com/rust-lang/rfcs/search?q=mutabilityref=cmdformtype=Issues

 Hope that starts to kick off some good discussion. :)
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] cannot borrow `st` as mutable more than once at a time

2014-05-29 Thread Vladimir Matveev
Hi, Christophe,

Won't wrapping the first `for` loop into curly braces help? I suspect
this happens because of `for` loop desugaring, which kind of leaves
the iterator created by `execute_query()` in scope (not really, but
only for borrow checker).

2014-05-29 19:38 GMT+04:00 Christophe Pedretti christophe.pedre...@gmail.com:
 Hello all,

 i know that this issue is already covered by issues #9113 #6393 and #9113
 but actually i have no solution. My code is a library for accessing
 databases. In my example, the database represented by db containes a table t
 with columns i:integer, f:float, t:text, b:blob.

 Everything works fine except the following code used to test my library

 match db.prepare_statement(SELECT i,f,t,b FROM t where t like ?;) {

 Ok(mut st) = {

 st.set_string(1, %o%);

 for i in st.execute_query() {

 match i {

 Ok(s)  = println!({}:{}:{}:{}, s.get_long(0), s.get_double(1),
 s.get_string(2), s.get_blob(3) ),

 Err(e) = match e.detail {

 Some(s) = println!({}, s),

 None = ()

 }

 }

 }

 st.set_string(1, %e%);  - PROBLEM HERE
 for i in st.execute_query() { - PROBLEM HERE

 ...
 }

 },
 Err(e) = match e.detail {

 None = (),

 Some(s) = println!({}, s)

 }

 }

 The compilation error says

 test-db.rs:71:8: 71:10 error: cannot borrow `st` as mutable more than once
 at a time
 test-db.rs:71
 st.set_string(1, %e%);
 ^~
 test-db.rs:61:17: 61:19 note: previous borrow of `st` occurs here; the
 mutable borrow prevents subse
 quent moves, borrows, or modification of `st` until the borrow ends
 test-db.rs:61   for i in
 st.execute_query() {
  ^~
 test-db.rs:88:7: 88:7 note: previous borrow ends here
 test-db.rs:58   match
 db.prepare_statement(SELECT i,f,t,b FROM t wh
 ere t like ?;) {
 ...
 test-db.rs:88   }
^
 error: aborting due to previous error

 do we have a solution for #6393 ?

 Thanks

 --
 Christophe
 http://chris-pe.github.io/Rustic/


 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] StrBuf and regular expressions

2014-05-26 Thread Vladimir Matveev
 And hopefully in the future the regular expression library will be updated to 
 work on StrBuf instead of str
This is very unlikely. See, you can go from `StrBuf` to `str` without
allocation - `as_slice()` returns a view into the `StrBuf`. This is
very cheap operation. But you cannot go from `str` to `StrBuf`
without allocation and copying, which are much more expensive than
slicing. Hence you should always try to use `str` where possible,
only resorting to `StrBuf` when absolutely necessary (for example,
when you need to accumulate a string dynamically). All APIs should
also take `str` when possible.

2014-05-26 11:31 GMT+04:00 Urban Hafner cont...@urbanhafner.com:
 Thanks guys, I now use as_slice() when necessary. And hopefully in the
 future the regular expression library will be updated to work on StrBuf
 instead of str as this seems to be the main use case (read in file, run
 regexp on it).

 Urban


 On Mon, May 26, 2014 at 8:58 AM, Vladimir Matveev dpx.infin...@gmail.com
 wrote:

  My suspicion is that the automatic conversion will come back at some
  point, but I'm not sure.

 I think it will be possible to make `String` implement `Derefstr`
 when DST land. Then it will be possible to convert from `String` to
 `str` using explicit reborrowing:

 let sgf_slice = *sgf;

 I'm not sure this will be fully automatic when `String` is an
 arbitrary actual argument to arbitrary function, however.

 2014-05-26 10:36 GMT+04:00 Andrew Gallant jams...@gmail.com:
  Try using `self.sgf.as_slice()` instead.
 
  The change is necessary, AFAIK, because `~str` would automatically be
  converted to a borrowed reference without having to explicitly call the
  `as_slice` method. This doesn't happen for the StrBuf (and what is now
  String, I think) type.
 
  My suspicion is that the automatic conversion will come back at some
  point, but I'm not sure.
 
  - Andrew
 
 
  On Mon, May 26, 2014 at 2:32 AM, Urban Hafner cont...@urbanhafner.com
  wrote:
  Hello there,
 
  I just updated the compiler (I use the git master branch) and now when
  I
  read in a file I get a StrBuf instead of a ~str. That is easy enough to
  change, but how do I use regular expressions now? I have the following
  in my
  code:
 
  let re = regex!(rSZ\[(\d+)\]);
  let captures = re.captures(self.sgf).unwrap();
 
  And it fails now because self.sgf is a StrBuf instead of a str. Do I
  have
  just a Rust compiler that is somewhere in between (i.e. not everything
  has
  been changed to StrBuf) or is this intentional? And if so, what's the
  best
  way to use regular expressions now?
 
  Urban
  --
  Freelancer
 
  Available for hire for Ruby, Ruby on Rails, and JavaScript projects
 
  More at http://urbanhafner.com
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev




 --
 Freelancer

 Available for hire for Ruby, Ruby on Rails, and JavaScript projects

 More at http://urbanhafner.com
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] *c_char and *c_uchar

2014-05-10 Thread Vladimir Matveev
Hi!

First of all, if you are writing custom bindings to sqlite not only to
learn Rust, I'd suggest using already existing bindings [1]. That way
you probably won't have to deal with low-level C integration stuff.

However, if you want to learn how to write C bindings, you should
probably start with reading an official tutorial [2] on foreign
function interface. That way you will learn that Rust strings are not
C-compatible, they are not terminated by zero byte, so you can't get a
pointer from a string and pass it to a C routine directly. In order to
properly convert str to *c_char you have to use various conversion
utilities, the most simple one being with_c_str() method:

let s = some_string;
let result = s.with_c_str(|char_ptr| {
// call C functions, char_ptr is a *c_char pointer
// after this block finishes, a buffer pointed to by char_ptr
will be freed
some_result
});

Here [3] is the relevant piece of documentation on C strings conversions.

Your second example is also incorrect. Converting C strings to static
slices is highly unsafe, for example, it will crash your program if
the string is not a valid UTF-8 sequence, not to mention lifetime
issues. There is a reason why it is placed in such inconvenient place
as `std::str::raw`. You shouldn't use it. Instead you should use
std::c_str::CString structure to wrap C strings. BTW, this structure
also forces you to think about ownership. I don't know much about
sqlite API, but if you're not supposed to free a string returned by
sqlite3_errmsg() function, you should create CString like this

CString::new(sqlite3_errmsg(*ppDb), false)

false means that this CString won't own the buffer and won't free it
when it goes out of scope.

When you have CString structure, you can get a string slice out of it
using as_str() method. This all is documented here [4].

[1]: https://github.com/linuxfood/rustsqlite.
[2]: http://static.rust-lang.org/doc/master/guide-ffi.html
[3]: http://static.rust-lang.org/doc/master/std/c_str/index.html
[4]: http://static.rust-lang.org/doc/master/std/c_str/struct.CString.html

2014-05-10 18:14 GMT+04:00 Christophe Pedretti christophe.pedre...@gmail.com:
 Hi all,

 i am writing a wrapper to an SQLite database.

 If i use :
 extern { fn sqlite3_open(filename: *c_char, ppDb : **mut ()) - c_int; }
 i can not use :
 let ppDb : **mut () = RawPtr::null();
 unsafe { res=sqlite3_open(filename.as_ptr(), ppDb);
 because as_ptr() returns an *u8 and c_char is a i8, so i have to use
 extern { fn sqlite3_open(filename: *c_uchar, ppDb : **mut ()) - c_int; }


 Now, suppose i use :
 extern { fn sqlite3_errmsg(pDb : *mut ()) - *c_uchar; }
 i can not use :
 let mut desc=; { unsafe { desc =
 c_str_to_static_slice(sqlite3_errmsg(*ppDb)); } }
 because c_str_to_static_slice taks a *c_char (so an i8) as argument, so i
 have to use
 extern { fn sqlite3_errmsg(pDb : *mut ()) - *c_char; }

 If the second example is quite logical, what about the first one ?
 how to convert str - *c_char ?

 thanks

 --
 Christophe
 http://chris-pe.github.io/Rustic/




 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] 3 ways to do, which is the best one in terms of Rust philosophy ?

2014-05-10 Thread Vladimir Matveev
Christophe,

Indeed, the idiomatic way is to use Result enum [1]. Note that you are
not limited to IoResult, you can use any custom error type, for
example, ResultT, 'static str. The documentation (a link to which
is below) is very nice, it contains a lot of examples and use
patterns.

So, your constructor method will look like this:

pub fn new() - ResultConnection, SomeErrorType { ... }

Usually library-specific ResultT, SomeErrorType is abbreviated via a
type alias:

type YourLibraryResultT = ResultT, SomeErrorType;

IoResult is defined exactly like this:

type IoResultT = ResultT, IoError;

[1]: http://static.rust-lang.org/doc/master/std/result/index.html

2014-05-10 21:38 GMT+04:00 Christophe Pedretti christophe.pedre...@gmail.com:
 Hi all,

 thanks to Vladimir and Valerii for their previous detailed answer to
 my email, now i have a more general question.

 My Connection struct has a new method with open a connection to a
 database. This connection can fails. Three possiblities :

 1/ new returns an IoResultConnection. The connection must be
 unwrapped from the IoResult before using it
 2/ new returns a Connection; after the instantiation, a test must
 be made using a method like getIoResult - OptionIoResult
 3/ any other way to do 

 For me, the 1/ is the best one, the connection can not be used until
 it is returned by new. With 2/, the test can be forgotten.

 Any suggestion ?

 Thanks

 --
 Christophe
 http://chris-pe.github.io/Rustic
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] References to trait objects are not cloneable

2014-05-03 Thread Vladimir Matveev
Hi all,

I posted this question on [Stack Overflow][1], but it is yet to be
answered there, so I ask here too.

Why reference to traits are not cloneable? The following code compiles:

struct Test;

fn clone_vec'a(v: Vec'a Test) - Vec'a Test {
v.clone()
}

But this one doesn't:

trait Test {
fn do_smt(self);
}

fn clone_vec'a(v: Vec'a Test) - Vec'a Test {
v.clone()
}

It spits this error:

main3.rs:7:5: 7:14 error: failed to find an implementation of trait
std::clone::Clone for 'a Testno-bounds
main3.rs:7 v.clone()
   ^

However, Clone trait is implemented for all kinds of references, as
far as I can see. I just don't see why 'a Test where Test is a trait
is not cloneable.

This is very strange provided that I can implement clone_vec() myself,
without using Clone:

fn clone_vec'a(v: Vec'a Test) - Vec'a Test {
let mut result = Vec::new();
for e in v.iter() {
result.push(e);
}
result
}

It works just fine.

If this is a bug, I would gladly submit it to the tracker, but I'm not
sure that I'm not doing something wrong.

[1]: 
http://stackoverflow.com/questions/23426545/references-to-trait-objects-are-not-cloneable
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Alternative to Option types

2014-02-28 Thread Vladimir Matveev
Hi, Tobias,

Yes, there is. A monad is a functor by definition, so it has to accept
a type to produce another type. It can't be represented in another
way, at least in Haskell. You can't come up with a sensible definition
of a functor without HKT:

class Functor (f :: *) probably something else where
fmap :: (a - b) - f - f  -- ???

The above does not make sense at all: you can't specify relationship
between a and b in f's codomain, and additional parameters to the type
class won't help.
Similarly, you cannot make a monad without HKT too.

MPTCs with functional dependencies are used in Haskell only to create
monad *transformers*. In fact, it is possible to create transformers
without MPTCs+FDs (and without type families), but they will be very
inconvenient to use - you won't be to obtain transformer operations
like (get :: StateT s m a - s), (ask :: ReaderT r m a - r) and
others for your monad stack for free.

2014-03-01 2:54 GMT+04:00 Tobias Müller trop...@bluewin.ch:
 Eric Reed ecr...@cs.washington.edu wrote:
 In general, monads require higher-kinded types because for a type to be a
 monad it must take a type variable. That is, OptionT and ListT could
 be monads, but int and TcpSocket can't be monads. So imagine we wanted to
 define a trait Monad in Rust.

 Just for my understanding. Is there an inherent reason that a monad has to
 be a higher kinded type (type constructor)? Couldn't it also be represented
 somehow as a multiparam trait/typeclass?
 AFAIK, higher kinded types are standard haskell, while MPTCs are not, so
 it's the obvious choice for haskell. Is it also for rust?

 Tobi

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Deprecating rustpkg

2014-02-03 Thread Vladimir Matveev
2014-02-02 Thomas Leonard tal...@gmail.com:
 [ I don't want to start another argument, but since you guys are discussing
 0install, maybe I can provide some useful input... ]

 I don't follow this. Whether the developer uses 0install to get the build
 dependencies doesn't make any difference to the generated binary.

 Of course, you *can* distribute the binary using 0install too, but you're
 not required to.

I probably have left this part in that formulation by accident. I
apologize for that, I had been writing this message in several passes.
Yes, of course it does not matter for the developer where he gets
build dependencies from, provided these dependencies are readily
available for the build process and are easily managed.


 0install doesn't automatically check out Git repositories (although that
 would be handy). Here's how we currently do it:

 - Your program depends on libfoo = 1.0-post

 - The latest released version of libfoo is only 1.0

 - You git clone the libfoo repository yourself and register the
   metadata (feed) file inside it:

   $ git clone git://.../libfoo
   $ 0install add-feed libfoo/feed.xml

 - 0install now sees that libfoo 1.0 and 1.0-post are both available.
   Since your program requires libfoo = 1.0-post, it will select the
   Git checkout version.
Seems to be a lot of manual work. This could be automated by Rust
package/build manager, though.


 Given a set of requirements, 0install will tell you where some suitable
 versions of the dependencies are. For example:

   $ cd /tmp
   $ git clone https://github.com/0install/hello-scons.git
   $ cd hello-scons
   $ 0install download Hello-scons.xml --source --show
 - URI: /tmp/hello-scons/Hello-scons.xml
   Version: 1.1-post
   Path: /tmp/hello-scons

   - URI: http://0install.net/2006/3rd-party/SCons.xml
 Version: 2.0.1
 Path:
 /var/cache/0install.net/implementations/sha1new=86311df9d410de36d75bc51762d2927f2f045ebf

 - URI: http://repo.roscidus.com/python/python
   Version: 2.7.6-1
   Path: (package:arch:python2:2.7.6-1:x86_64)

 This says that the build dependencies are:

 - This package's source code (in /tmp/hello-scons)
 - The SCons build tool (which 0install has placed in /var/cache)
 - Python (provided by the distribution)

 The source could also specify library dependencies. How do you get this
 information to the build tool? The usual way is to tell 0install how to run
 the build tool in the XML. In this case, by running SCons on the project's
 SConstruct file.

 But you could get the information to it some other way. For example, a
 rustpkg tool that invokes 0install download ... --source --xml behind
 the scenes and does something with the machine-readable selections document
 produced.
Thanks for the explanation, I didn't know that 0install can run build
tools and that it could provide the information about libraries
locations. This certainly answers my question.

 How should I specify build dependencies for people who want to hack on my
 package?


 List them in the XML file that is in your project's source repository. Users
 should then be able to clone your git repository and build, with build
 dependencies handled for them.
Again, didn't know that 0install can handle build dependencies.


 This is all about run time dependencies, but I think the discussion here is
 about build time, right? You'll have the same issues with any system.
Usually build dependencies are a superset of runtime dependencies,
aren't they? Nonetheless, this was not about runtime dependencies,
this was about general approach. But I think given your explanation of
0install operation this point can be discarded.



 I think any build tool (including go, cabal, pip, rustpkg) will have this
 problem. Ideally, you want distributions to be able to turn upstream
 packages into their preferred format automatically. Whatever system you
 settle on this should be possible, as long as you have some kind of
 machine-readable dependency information.
Yes, you're quite correct on that ideally upstream packages should be
converted to distribution packages automatically. For the new
hypothetical build system I see it like the following: a maintainer
downloads sources for a package, invokes some distro-specific tool
which in turn invokes `rustpkg` to build the package and assemble
dependency information, which is then converted to a distribution
package. Then the maintainer manually adds external dependencies to
the list. Something like that is already done for Haskell in Arch
Linux, for example. It seems that it could be done with 0install, at
least, to some extent.

 Zero install may have integration with package systems, but looks like
 it is very brittle. According to [this
 page](http://0install.net/distribution-integration.html) it is package
 owner's duty to specify how native package dependencies should be
 resolved in each distribution. This is extremely fragile. I don't use
 Debian, for example, 

Re: [rust-dev] Deprecating rustpkg

2014-02-01 Thread Vladimir Matveev
Is it possible at all to find the latest version of a library which is
still compatible completely automatically? Incompatibilites can be
present on logic level, so the compilation wiith incompatible version
will succeed, but the program will work incorrectly. I don't think
that this can be solved without assumptions about versioning (like
semver) and/or without manual intervention.

Couldn't we just use more loose variant of version pinning inside
semantic versioning, with manual user intervention when it is needed?
For example, assuming there is something like semantic versioning
adopted, packages specify dependencies on certain major version, and
the dependency resolver downloads latest available package inside this
major version. If for some reason automatically selected dependency is
incompatible with our package or other dependencies of our package,
the user can manually override this selection, maybe even with another
major version. This is, as far as I understand, the system of slots
used by Portage as Vladimir Lushnikov described. Slots correspond to
major versions in semver terms, and other packages depend on concrete
slot. But the user has ultimate power to select whichever version they
need, overriding automatic choice.

In short, we allow dependency resolver to use the latest possible
packages which should be compatible according to semantic versioning,
and if it fails, we provide the user with ability to override
dependency resolver choices.

2014-02-01 Tony Arcieri basc...@gmail.com:
 On Fri, Jan 31, 2014 at 3:59 PM, Jack Moffitt j...@metajack.im wrote:

 The algorithm here is rather simple. We try to satisfy rust-logger and
 rust-rest. rust-rest has a version (or could be a tag like 1.x) so we
 go get that. It depends on rust-json 2.0 so we get that. Then we try
 to look for rust-logger, whatever version is latest (in rustpkg this
 would mean current master since no version or tag is given). This
 pulls in rust-json 1.0 since 1.0 != 2.0 and those have specific tags.
 Everything is built and linked as normal. Whether rust-json's
 constraints are exact revisions or they are intervals ( 2.0 and =
 2.0 for example), makes little difference I think.


 To reiterate, it sounds like you're describing every package pinning its
 dependencies to a specific version, which I'd consider an antipattern.

 What is to prevent a program using this (still extremely handwavey)
 algorithm from depending on rust-json 1.0, 1.1, 1.2, 1.3, 1.4, 2.0, 2.1, and
 2.2 simultaneously?

 What if some of these are buggy, but the fixed versions aren't used due to
 version pinning?

 What if rust-json 1.0 has a security issue?

 --
 Tony Arcieri

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Deprecating rustpkg

2014-02-01 Thread Vladimir Matveev
 You can do that within a major version, except for one case - multiple 
 developers creating diverged versions of 2.13, based on 2.12, each with 
 their own features.  
 ...
 But doing it per major version recursively raises the question of which 
 major version is authorised: what if you have a single library at 19.x, 
 and TWO people create 20.0 independently?  Again, you have 
 incompatibility.  So, you're back to the question of (a): is it the same 
 library, or should an author simply stay within the bounds of a 
 library's API, and fork a new CONCEPTUALLY DIFFERENT new lib (most 
 likely with a new name) when they break that API?

I think that forks should be considered as completely different libraries. This
shouldn't be a problem when certain naming scheme is used, for example,
two-level names like in Java world. Central repository will certainly help,
because each entry in it will be controlled by concrete user. These entries
can also be linked with version control stream which represents main
development line. No ambiguities here.

It may be desirable then to use specific fork instead of the mainline project.
This can be a feature of overriding system, which will be present anyway. If the
user wants to use a fork instead of a library (all its versions or a specific
version), he/she will be able to specify this requirement somehow, and
dependency resolver will take it into account. Obviously, package authors will
be able to choose default fork which they want to use.

 But what does the user know about library APIs?  He needs to dig into 
 the logic of the program, and worse, the logic of underlying libraries, 
 to figure out that:
 
  somelib::begin() from 
 github://somelib/someplace/v23.2/src/module1/submod2/utils.rs, line 24
 
 does not mean the same as:
 
  somelib::begin() from 
 github://somelib/otherplace/v23.2/src/module1/submod2/utils.rs, line 35
 
 ! ;)
 

When this API is used directly by the package, then the user *should* know
about it. He's using it, after all. If this API belongs to a transitive
dependency, then I don't think there is an ideal solution. Either the version is
pinned (like in Java world), or it is chosen by the dependency resolver. In the
former case all transitive dependencies are guaranteed to be intercompatible,
because these pinned versions were deliberately chosen by libraries developers.

In the latter case there is always a possibility of compatibility problems,
because it is impossible to guarantee complete compatibility - libraries are
written by people, after all. Then it is the user's responsibility to resolve
these problems, no one else will be able to do this.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Deprecating rustpkg

2014-02-01 Thread Vladimir Matveev
To clarify, when I was writing user I meant the developer who uses this
package, not the end user of complete program.

 On 01/02/14 19:32, Vladimir Matveev wrote:
  When this API is used directly by the package, then the user *should* 
  know about it. He's using it, after all.
 
 There are developers (direct library users), and then distro 
 maintainers/admins/users who need to manage libraries installed on their 
 system.  The former should know, but the others shouldn't have to think 
 about it, yet should (must) be able to override the defaults if they 
 need to, at least for shared libraries.  Presumably we want shared 
 libraries and static libraries to function similarly, except for whether 
 the user chooses static or dynamic linkage.

Well, it seems that working for a long time with a code targeting virtual
machines is corrupting :) I completely forgot about different models of
compilation. I see your point. But I think that developing and distributing
should be considered separately. Package manager for developers should be a
part of language infrastructure (like rustpkg is now for Rust and, for example,
go tool for Go language or cabal for Haskell). This package manager allows
flexible management of Rust libraries and their dependencies, and it should be
integrated with the build system (or *be* this build system). It is used by
developers to create applications and libraries and by maintainers to prepare
these applications and libraries for integration with the distribution system
for end users.

Package manager for general users (I'll call it system package manager),
however, depends on the OS, and it is maintainer's task to determine correct
dependencies for each package. Rust package manager should not depend in any
way on the system package manager and its packages, because each system has its
own package manager, and it is just impossible to support them all. Rust also
should not force usage of concrete user-level package manager (like 0install,
for example), because this means additional unrelated software on the user
installation.

Go and Haskell do not have this problem because they are linked statically, and
their binary packages do not have any library dependencies at all. Rust is a
different story as it supports and encourages dynamic linkage. I think that
maintainers should choose standard set of Rust libraries which is OK for most
applications, and support and update them and their dependent applications. If
there are conflicts between versions (for example, some application started to
depend on another fork of a library), then maintainers should resolve this in
the standard way of their distribution system (e.g. slots for Portage, name
suffixes in apt and so on).

Essentially there is a large graph of packages in the Rust world, consisting of
packages under Rust package manager control (main graph). Developers are only
working with this graph. Then for each distribution system maintainers of this
system pull packages from the main graph and adapt it to their system in a way
this system allows and encourages. I don't think that it is possible to achieve
anything better than this. We cannot and should not force end users to use
something other than their packaging system.

  If this API belongs to a transitive dependency, then I don't think 
  there is an ideal solution. Either the version is pinned (like in Java 
  world), or it is chosen by the dependency resolver.
 
 If we're talking about pinning to an absolute version (no upgrades), 
 then I think that's a security / bugfix issue, unless we're also talking 
 about static linkage in that case (which is reasonable because then the 
 bug is essentially part of the black box that is the software the user 
 is installing, and in that case, the software maintainer is also 
 responsible for releasing updates to fix bugs within the statically 
 linked code.
 
  In the former case all transitive dependencies are guaranteed to be 
  intercompatible
 
 Are they?  What if the statically pinned version of a scanner library 
 doesn't support the user's new scanner, there's an update to support his 
 scanner, but it's ignored because the software allows only an absolute 
 version number?

I don't think your example is related. By guaranteed intercompatibility I meant
something like the following. Suppose your package is called `package`. It
depends on `foo-x` who in turn depends on `bar-y`. When versions are always
pinned by their developers, `foo` author deliberately has chosen `bar-y`
version, and he knows that `foo-x` library will work properly with `bar-y`.
This is how Java ecosystem works now. New scanner, however, is not an API
feature. Your example seems to support the general point about outdated
dependencies, and I generally agree with it.

  because these pinned versions were deliberately chosen by libraries 
  developers.
 
 Who are not infallible, and do/should not get to choose everything about 
 the target system's libraries

Re: [rust-dev] Avoiding partially moved values error when consuming a struct with multiple fields

2014-01-26 Thread Vladimir Matveev
Oh, great! I completely forgot that I can destructure structs in let
bindings too. Indeed it works. Thanks!

2014-01-26 Alex Crichton a...@crichton.co:
 You'll want to do destructuring assignment here. This means that you
 take ownership of all fields in parallel:

 fn into_test2(self) - Test2 {
 let Test1 { a, b } = self;
 Test2 {
 c: a,
 d: b as f64
 }
 }

 On Sun, Jan 26, 2014 at 9:32 AM, Vladimir Matveev
 dpx.infin...@gmail.com wrote:
 Hi all,

 Consider this code:

 struct Test1 {
 a: ~str,
 b: f32,
 }

 struct Test2 {
 c: ~str,
 d: f64
 }

 impl Test1 {
 fn into_test2(self) - Test2 {
 Test2 {
 c: self.a,
 d: self.b as f64
 }
 }
 }


 In into_test2() method I want to consume Test1 struct completely. But
 because ~str is not implicitly copyable, self.a is moved out of self,
 and on Test2.d field assignment I get the following error:

 main.rs:15:16: 15:21 error: use of partially moved value: `self`
 main.rs:15 d: self.b as f64
   ^
 main.rs:14:16: 14:22 note: `self.a` moved here because it has type
 `~str`, which is non-copyable (perhaps you meant to use clone()?)
 main.rs:14 c: self.a,
   ^~

 I know that I can, say, do self.a.clone() to avoid moving, but I don't
 want extra allocations. And it is also possible to reorder Test2
 fields assignments and it will work, but it won't if both fields are
 not copyable.

 So, the question is: how to correctly correctly move several pieces of
 data out from a struct without using clone()? Is it possible at all?

 Thanks,
 Vladimir.
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Lifetime help

2014-01-20 Thread Vladimir Matveev
In general it is likely that type annotations will be needed. But in
this case you're quite correct. I have updated the gist, it now has
significantly less noise.

2014/1/20 Evan G eg1...@gmail.com:
 Do you need to type annotate the intermediate variable? Shouldn't let
 sprites = assets.iter() be sufficient? Or is it because of the lifetimes?

 On Jan 20, 2014 1:41 AM, Vladimir Matveev dpx.infin...@gmail.com wrote:

 Hi,

 In fact, you're almost there. You only need to add lifetime
 annotations on `Sprite` in the intermediate HashMap variable and in
 return type. See here: https://gist.github.com/dpx-infinity/8516387

 I tried to emulate rust-sfml types. This gist compiles, and the test
 is successful. BTW, you don't have to write `return` unless you want
 to exit early, for example, from inside a loop. Just leave out
 semicolon at the last line.

 Simple hint to detect mistakes in lifetime annotations: if you only
 have lifetime annotations on parameters or return values but not on
 both parameters and return values, then it is likely that something is
 wrong.

 2014/1/20 benjamin adamson adamson.benja...@gmail.com:
  Hi all!
 
  I having a little trouble resolving this issue on my own, and I think
  it's
  an issue of syntax, not so much comprehending life times.
 
  What I'm doing is, using the RSFML library to try and write a pong clone
  in
  rust. So far it's been going awesome! I'm running into a small problem
  with
  lifetimes though. To give some context, SFML separates textures from
  sprites, and sprites can be created with a borrowed pointer to a
  texture. I
  first load all the textures into a HashMap, and pass that hashmap to a
  function which (is supposed to) will return a HashMap of Sprites. These
  sprites I would like to initialize inside the function with references
  to
  the textures in the input HashMap of textures.
 
  Based on my understanding of borrowed pointers, this should be able to
  work.
  In fact, I wrote a simpler version of my function just to make sure I
  understand what I am not understanding. I wrote a version of the
  function
  which takes the same HashMap of textures, and returns a single sprite
  (not a
  hashmap). The single sprite is created with a reference to the first
  texture
  in the hashmap. I was able to figure out the syntax to express this.
  However
  I can't seem to figure out the syntax for the more complicated case,
  returning the hashmap of Sprites.
 
  I created a gist for easy viewing of the code I am having trouble with,
  and
  I think I've made it very obvious what's happening in the gist link,
  hopefully somebody can help me sort this out :D
  https://gist.github.com/ShortStomp/8513368
 
  also the link to the full file, if it helps.
  https://github.com/ShortStomp/pong-rust/blob/master/main.rs
 
  Thanks in advance!!
 
  ___
  Rust-dev mailing list
  Rust-dev@mozilla.org
  https://mail.mozilla.org/listinfo/rust-dev
 
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Failure stacktraces

2014-01-19 Thread Vladimir Matveev
Hi,

Is it possible to view full stacktraces when task fails? Currently
only the last item in the stacktrace is printed to the terminal when I
run a failing program. I'm very surprised that I was not able to find
any information on this. It looks like that the problem is
nonexistent. However, the ability of getting full failure stacktraces
is of colossal importance. Failures mean stack unwinding, so it
shouldn't be a problem, should it?

Thanks,
Vladimir.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Failure stacktraces

2014-01-19 Thread Vladimir Matveev
Thanks for explanation! I guess gdb will do for me.

2014/1/19 Corey Richardson co...@octayn.net:
 You're not actually seeing a stack entry, you're seeing the string
 that was given to `fail!()`. You can get a real backtrace with gdb,
 break on `rust_fail`. You can also get a super crappy backtrace using
 the backtrace function, see prototype
 https://gist.github.com/cmr/8192817. We used to use it, but it only
 really works for dynamic linking (which we discourage for a variety of
 reasons right now), and doesn't work on OS X.

 Getting a real backtrace when unwinding would be possible, but we'd
 need to start parsing DWARF etc. Not trivial.

 On Sun, Jan 19, 2014 at 12:58 PM, Vladimir Matveev
 dpx.infin...@gmail.com wrote:
 Hi,

 Is it possible to view full stacktraces when task fails? Currently
 only the last item in the stacktrace is printed to the terminal when I
 run a failing program. I'm very surprised that I was not able to find
 any information on this. It looks like that the problem is
 nonexistent. However, the ability of getting full failure stacktraces
 is of colossal importance. Failures mean stack unwinding, so it
 shouldn't be a problem, should it?

 Thanks,
 Vladimir.
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Lifetime help

2014-01-19 Thread Vladimir Matveev
Hi,

In fact, you're almost there. You only need to add lifetime
annotations on `Sprite` in the intermediate HashMap variable and in
return type. See here: https://gist.github.com/dpx-infinity/8516387

I tried to emulate rust-sfml types. This gist compiles, and the test
is successful. BTW, you don't have to write `return` unless you want
to exit early, for example, from inside a loop. Just leave out
semicolon at the last line.

Simple hint to detect mistakes in lifetime annotations: if you only
have lifetime annotations on parameters or return values but not on
both parameters and return values, then it is likely that something is
wrong.

2014/1/20 benjamin adamson adamson.benja...@gmail.com:
 Hi all!

 I having a little trouble resolving this issue on my own, and I think it's
 an issue of syntax, not so much comprehending life times.

 What I'm doing is, using the RSFML library to try and write a pong clone in
 rust. So far it's been going awesome! I'm running into a small problem with
 lifetimes though. To give some context, SFML separates textures from
 sprites, and sprites can be created with a borrowed pointer to a texture. I
 first load all the textures into a HashMap, and pass that hashmap to a
 function which (is supposed to) will return a HashMap of Sprites. These
 sprites I would like to initialize inside the function with references to
 the textures in the input HashMap of textures.

 Based on my understanding of borrowed pointers, this should be able to work.
 In fact, I wrote a simpler version of my function just to make sure I
 understand what I am not understanding. I wrote a version of the function
 which takes the same HashMap of textures, and returns a single sprite (not a
 hashmap). The single sprite is created with a reference to the first texture
 in the hashmap. I was able to figure out the syntax to express this. However
 I can't seem to figure out the syntax for the more complicated case,
 returning the hashmap of Sprites.

 I created a gist for easy viewing of the code I am having trouble with, and
 I think I've made it very obvious what's happening in the gist link,
 hopefully somebody can help me sort this out :D
 https://gist.github.com/ShortStomp/8513368

 also the link to the full file, if it helps.
 https://github.com/ShortStomp/pong-rust/blob/master/main.rs

 Thanks in advance!!

 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev

___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Exporting macros: #[macro_escape] usage

2014-01-11 Thread Vladimir Matveev
Oh, thanks. It does work now. Are macro scoping rules documented
somewhere except the compiler source code?

2014/1/11 Chris Morgan chris.morgani...@gmail.com:
 The macro is being defined after the module is defined. You need to move the
 macro definition before the pub mod submod; line. Also due to the scoping
 rules of macros, you don't need #[macro_escape] there---it's a child, so it
 gets the macro. Only siblings, parents, uncles, aunts, cousins, c. would
 need it.

 On Jan 11, 2014 9:46 AM, Vladimir Matveev dpx.infin...@gmail.com wrote:

 Hi,

 As far as I understand, the current way to export macros is to
 annotate the module with macro_rules definition with #[macro_escape]
 annotation. But I just can't get it right, and my macro is not visible
 in other module :(

 Here is what I have:

 - START -
 /lib.rs:
 #[feature(macro_rules)];

 pub mod m1;

 --
 /m1/mod.rs:
 #[macro_escape];

 pub mod submod;

 macro_rules! example_rule(
 () = (mod test;)
 )

 --
 /m1/submod.rs:
 use m1;

 example_rule!()
 - END -

 I have assumed that putting #[macro_escape] annotation to a module
 makes all macros from that module available in all modules which
 import this module, but apparently I'm wrong because the code above
 does not work with 'macro undefined' error.

 Could please someone explain how #[macro_escape] works in detail? I
 couldn't find any documentation on it, and looking through standard
 libs was not helpful.

 Thanks,
 Vladimir.
 ___
 Rust-dev mailing list
 Rust-dev@mozilla.org
 https://mail.mozilla.org/listinfo/rust-dev
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Exporting macros: #[macro_escape] usage

2014-01-10 Thread Vladimir Matveev
Hi,

As far as I understand, the current way to export macros is to
annotate the module with macro_rules definition with #[macro_escape]
annotation. But I just can't get it right, and my macro is not visible
in other module :(

Here is what I have:

- START -
/lib.rs:
#[feature(macro_rules)];

pub mod m1;

--
/m1/mod.rs:
#[macro_escape];

pub mod submod;

macro_rules! example_rule(
() = (mod test;)
)

--
/m1/submod.rs:
use m1;

example_rule!()
- END -

I have assumed that putting #[macro_escape] annotation to a module
makes all macros from that module available in all modules which
import this module, but apparently I'm wrong because the code above
does not work with 'macro undefined' error.

Could please someone explain how #[macro_escape] works in detail? I
couldn't find any documentation on it, and looking through standard
libs was not helpful.

Thanks,
Vladimir.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Trait method self parameter type clashes with lifetime annotation required by the implementation

2013-09-29 Thread Vladimir Matveev
I think I should have put my code to gist to track changes easily.
Amending: https://gist.github.com/dpx-infinity/6751843

2013/9/29 Vladimir Matveev dpx.infin...@gmail.com:
 Yes, this is what I have observed too, see issue
 https://github.com/mozilla/rust/issues/9597. I didn't know that using
 extra parameter with lifetime will help though. It indeed works. But I
 think that polluting traits-interfaces with lifetime annotation is
 wrong. Why the trait should have lifetime annotation? It is
 implementation detail.

 I just managed to do what I wanted with some kind of hack. The
 following code compiles and works:

 // Some business-logic trait
 trait Walker {
 fn walk(self);  // Just self, without pointers
 }

 // ReaderContainer implementation remains the same

 // A struct which is intended to be an implementor of Walker trait
 // Note that it has lifetime parameter in order to work for any kind
 // of pointer to a Reader
 struct ReaderContainer'self {
 priv reader: 'self Reader,
 priv counter: int
 }

 // Some auxiliary structure for ReaderContainer
 // It may be anything but it should have a reference to ReaderContainer
 // We have to use lifetime parameter because this structure is 'attached'
 // to ReaderContainer, hence it must be of the same lifetime
 struct ReaderContainerIterator'self {
 priv container: 'self mut ReaderContainer'self
 }

 // Some made-up implementation of iterator protocol for our
 // auxiliary structure, it does not really matter
 impl'self Iteratoru8 for ReaderContainerIterator'self {
 fn next(mut self) - Optionu8 {
 if self.container.counter  10 {
 self.container.counter += 1;
 Some(self.container.reader.read_byte() as u8)
 } else {
 None
 }
 }
 }

 impl'self ReaderContainer'self {
 // A constructor for ReaderContainer, nothing special
 fn new'a(reader: 'a Reader) - ReaderContainer'a {
 ReaderContainer { reader: reader, counter: 0 }
 }

 // A method which returns our auxiliary structure, i.e. iterator
 // Note that self parameter has lifetime 'self, otherwise this naturally
 // does not compile
 fn iter('self mut self) - ReaderContainerIterator'self {
 ReaderContainerIterator { container: self }
 }
 }

 // And here are the changes

 // We implement Walker for a reference of the specific type!
 impl'self Walker for 'self mut ReaderContainer'self {
 // Here self automatically is 'self mut reference, so we can safely
 // use iter() method
 fn walk(self) {
 for b in self.iter() {
 println(fmt!(byte %?, b));
 }
 }
 }

 fn main() {
 use std::io;

 let r = io::stdin();
 let mut c = ReaderContainer::new(r);

 c.walk();  // No extra parameters
 }


 In short, I'm implementing `Walker` trait not for
 `ReaderContainer'self` but for `'self mut ReaderContainer'self`.

 This does not feel right, but I do not see immediate problems with
 this solution. Maybe someone who knows more about lifetimes could
 comment on this.

 2013/9/29 David Renshaw dwrens...@gmail.com:
 If I drop the unused parameter, I get an internal compiler error:
 'assertion failed: self.variance.is_some()'
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Trait method self parameter type clashes with lifetime annotation required by the implementation

2013-09-29 Thread Vladimir Matveev
As far as I understand, you're mostly right, except the structures bit.

Disregarding that it is not possible to use several lifetime
parameters yet, I see only one slight mistake: `s: MyStruct'a` does
not imply that `s` variable has any specific lifetime. If it is a
local variable, then it has 'lexical' lifetime; if it is a field in a
structure, it has lifetime of the structure instance.

 I guess what you meant is this:

s: 'a MyStruct'a

Here `s` pointer have lifetime 'a, as well as `s.r_int`.

BTW, you came up with very nice math-like analogy, it helped me
understand this thing even more. Thanks :)

2013/9/29 Gábor Lehel illiss...@gmail.com:
 'self is not special in any way, except that the compiler has historical
 baggage such that 'self is the only name it lets you use for a lifetime
 parameter on a struct. But that's a bug. In the ideal platonic Rust in the
 sky, you can have any number of lifetime parameters on a struct with
 whatever names you prefer.

 The way I've found to think about lifetimes is that if you have:

 r_int: 'a int

 then 'a refers to a span of time (a scope, a lifetime) such that
 lifetime_of(r_int) = 'a = lifetime_of(*r_int). (Where *r_int is intended
 metaphorically to refer to the original object r_int was created from, not
 the result of the *r_int expression itself.) So 'a is a kind of stand
 between to ensure that r_int does not outlive the object it refers to.

 If you have

 fn foo'a(r_int: 'a int) - 'a int

 then just like any other generics argument, the lifetime 'a is chosen by the
 caller of `foo` (as inferred by the compiler). Typically the caller will
 have an int object (i: int), then borrow a reference to it (r_int: 'a int =
 i) which it passes to `foo`, and then 'a will be the lifetime of the int.
 `foo` will then have to return a reference to (an int that lives at least as
 long). In practice this could either be the r_int it got as argument, or a
 static int.

 `fn foo(arg: int)` is shorthand for an anonymous lifetime parameter: `fn
 foo'a(arg: 'a int)`

 In the return type position `fn foo() - int` is short for `fn foo'a() -
 'a int`, meaning `foo` has to return a reference to (an int that lives as
 long as any lifetime the caller could choose), which in practice means that
 it has to be 'static. I believe you are or will be required to write
 'static explicitly in these cases to avoid confusion.

 With a struct it's not much different.

 s: MyStruct'a means lifetime_of(s) = 'a
 s: MyStruct'a, 'b means lifetime_of(s) = 'a  lifetime_of(s) = 'b

 If you have

 struct MyStruct'self {
 r_int: 'self int
 }

 s: MyStruct'a

 then lifetime_of(s) = 'a  lifetime_of(s.r_int) = 'a. (Which is trivial
 because lifetime_of(s) == lifetime_of(s.r_int).)

 Basically, every object has a lifetime - from its creation to its
 destruction - but a lifetime parameter or argument typically refers to the
 lifetime of something else, which the object itself must not or does not
 outlive.

 (Please yell at me if I got any of this wrong.)



 On Sun, Sep 29, 2013 at 5:23 PM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 Ok, color me confused... perhaps there's somewhere that explains 'self on
 more detail? For example, _why_ does the example below not work without the
 explicit 'self? It seems like it should.

 I have yet to truly understand the whole 'self thing. When I first read
 about lifetimes, my naive expectations were that:

 - Every struct has a 'self lifetime, which is basically as long as this
 struct exists. It doesn't matter if I have a @ of the struct or a ~ of the
 struct or just a local variable with the struct... when the struct is
 dropped, the lifetime ends.

 - It follows there's no need to ever annotate structs as generic with a
 'self parameter - it always exists.

 - Any  in a struct is either 'self or 'static. A simple  should be
 'self as that makes more sense (but if Rust wants me to be explicit, fine).

 This were my least surprise expectations, but things don't work this
 way... the problem is I don't have a simple mental model to replace the
 above with, so I struggle. What _is_ 'self, exactly?

 Isn't a function fn foo(self) - T the same as returning a 'self T? Why
 would I want to say fn foo'a('a self) in the 1st place - 'a is by
 definition the same as 'self? How come David's Foo example fails the borrow
 check?

 Besides failing (my) least surprise expectations, the current rules also
 seem to be a leaky abstraction. If I have a struct that holds a ComplexT
 member, it needs no 'self parameter. If I then add a private member to my
 struct to hold some 'self PartOfT (say, cached access to an internal
 member), then boom, all uses of my struct now have to say 'self, I can no
 longer put it in thread-local-storage, etc. I'd expect keeping these sort of
 cached borrowed pointers should be an internal implementation detail which
 does not affect the users of the struct at all.

 I suppose there's a good reason for all this, and a reasonable mental
 model I 

[rust-dev] Trait method self parameter type clashes with lifetime annotation required by the implementation

2013-09-28 Thread Vladimir Matveev
Hi all,

The problem I'm writing about in this message follows from the one I
have described in my other message:
https://mail.mozilla.org/pipermail/rust-dev/2013-August/005281.html .
I believe I'm now able to formulate it more clearly.

Consider the following example code:

trait Walker {  // Some business-logic trait
fn walk(mut self);
}

// A struct which is intended to be an implementor of Walker trait
// Note that it has lifetime parameter in order to work for any kind
// of pointer to a Reader
struct ReaderContainer'self {
priv reader: 'self Reader,
priv counter: int
}

// Some auxiliary structure for ReaderContainer
// It may be anything but it should have a reference to ReaderContainer
// We have to use lifetime parameter because this structure is 'attached'
// to ReaderContainer, hence it must be of the same lifetime
struct ReaderContainerIterator'self {
priv container: 'self mut ReaderContainer'self
}

// Some made-up implementation of iterator protocol for our
// auxiliary structure, it does not really matter
impl'self Iteratoru8 for ReaderContainerIterator'self {
fn next(mut self) - Optionu8 {
if self.container.counter  10 {
self.container.counter += 1;
Some(self.container.reader.read_byte() as u8)
} else {
None
}
}
}

impl'self ReaderContainer'self {
// A constructor for ReaderContainer, nothing special
fn new'a(reader: 'a Reader) - ReaderContainer'a {
ReaderContainer { reader: reader, counter: 0 }
}

// A method which returns our auxiliary structure, i.e. iterator
// Note that self parameter has lifetime 'self, otherwise this naturally
// does not compile
fn iter('self mut self) - ReaderContainerIterator'self {
ReaderContainerIterator { container: self }
}
}

// Here is the problem: we cannot implement Walker trait!
impl'self Walker for ReaderContainer'self {
// See below for concrete errors description
fn walk(mut self) {  // 
for b in self.iter() {
println(fmt!(byte %?, b));
}
}
}

fn main() {
use std::io;

let r = io::stdin();
let mut c = ReaderContainer::new(r);

c.walk();
}


This program does not compile with the following error:

temp.rs:52:17: 52:30 error: cannot infer an appropriate lifetime due
to conflicting requirements
temp.rs:52 for b in self.iter() {
^
temp.rs:52:17: 52:22 note: first, the lifetime cannot outlive the
expression at 52:17...
temp.rs:52 for b in self.iter() {
^
temp.rs:52:17: 52:22 note: ...due to the following expression
temp.rs:52 for b in self.iter() {
^
temp.rs:52:17: 52:30 note: but, the lifetime must be valid for the
method call at 52:17...
temp.rs:52 for b in self.iter() {
^
temp.rs:52:17: 52:22 note: ...due to the following expression
temp.rs:52 for b in self.iter() {
^
error: aborting due to previous error

This is somewhat expected, because `self` in `walk()` method
implementation does not have 'self lifetime, so it is impossible to
call `iter()` method which needs concrete 'self lifetime. But I cannot
mark it with 'self lifetime either! If I do mark it with 'self:

fn walk('self mut self) {  // 
for b in self.iter() {
println(fmt!(byte %?, b));
}
}

Then the program fails to compile with another message:

temp.rs:51:4: 55:5 error: method `walk` has an incompatible type:
expected concrete lifetime, but found bound lifetime parameter 
temp.rs:51 fn walk('self mut self) {  // 
temp.rs:52 for b in self.iter() {
temp.rs:53 println(fmt!(byte %?, b));
temp.rs:54 }
temp.rs:55 }
temp.rs:51:29: 55:5 note: expected concrete lifetime is the lifetime
'self  as defined on the block at 51:29
temp.rs:51 fn walk('self mut self) {  // 
temp.rs:52 for b in self.iter() {
temp.rs:53 println(fmt!(byte %?, b));
temp.rs:54 }
temp.rs:55 }
error: aborting due to previous error

This is also expected: adding 'self lifetime violates `Walker` trait
signature, in which `walk()` method has plain `mut self` parameter.

So, this is kind of dead end. I think this problem may be formulated
in short as follows: how to implement generic traits for structures
which have lifetime parameters which are used for `self` parameter in
structure methods implementations?

How to do what I want to do? Is it possible at all?

Regards,
Vladimir.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Borrowed pointers with lifetime in structures cause weird errors

2013-08-21 Thread Vladimir Matveev
Hi Niko,

Thank you for your response. I forgot to put it in the original
message, but here is a link to bitbucket repository with all the code
I got so far: https://bitbucket.org/googolplex/algo/src, see module
io. Maybe it will be helpful.

I'm still inclined to think that this is a bug, and I really do not
see how can I do what I want to with two lifetime parameters. There
really should be one lifetime (the one of the Reader), or maybe I'm
missing something?

As for internal iterators, yes, I tried to do that first, but since it
is impossible to break out or return from inside of the iterator loop
directly via `break` or `return` it quickly becomes pretty unfeasible
since I have to use a lot of boilerplate boolean parameters and check
them in many places. This may be not so apparent for finite
structures, but for potentially infinite ones (like a wrapper for
`Reader`) it is.

Nonetheless, as far as I understand, external iterators are the future
of iteration in Rust (generators won't appear in the nearest future,
will they?), so I want to use the most idiomatic style.

2013/8/20 Niko Matsakis n...@alum.mit.edu:
 Hi,

 Sorry for not responding more quickly. I've been wanting to sit down
 and work out your example; I am confident that it can be made to work,
 although from reading it quickly it sounds like a case that might be
 better served with two lifetime parameters, which are not yet
 supported (on my list...).

 However, I did want to briefly point out that you can continue to use
 internal iterators, you just don't get the `for` syntax
 anymore. Just write a higher-order function as you always did,
 possibly returning bool to indicate whether to break or continue.


 Niko


 On Sat, Aug 17, 2013 at 01:54:09PM +0400, Vladimir Matveev wrote:
 Hello,

 I'm writing a simple tokenizer which is defined by this trait:

 trait Tokenizer {
 fn next_token(mut self) - ~str;
 fn eof(self) - bool;
 }

 Obvious application for a tokenizer is splitting a stream going from
 Reader, so I have the following structure which should implement
 Tokenizer:

 pub struct ReaderTokenizer'self {
 priv inner: 'self Reader,
 priv buffer: ~CyclicBuffer,
 priv seps: ~[~str]
 }

 I have used 'self lifetime parameter since I want for the tokenizer
 work for any Reader. CyclicBuffer is another structure which
 essentially is an array of u8 with special read/write operations.

 Implementation of a Tokenizer for ReaderTokenizer involves reading
 from the Reader one byte at a time. I decided to use buffering to
 improve performance. But I still want to keep the useful abstraction
 of single byte reading, so I decided to implement Iteratoru8 for my
 Reader+CyclicBuffer pair. BTW, internal iterators in 0.7 were much
 better for this, because internal iterator code was very simple and
 didn't use explicit lifetimes at all, but 0.7 compiler suffers from
 several errors related to pointers to traits which prevented my
 program from compiling (I couldn't pass a reference to Reader to
 CyclicBuffer method; there were other errors I've encountered too). I
 So, I decided to use trunk version of the compiler in which these
 errors are resolved according to github, but trunk version does not
 allow internal iterators, which is very sad since now I'm forced to
 create intermediate structures to achieve the same thing.

 So, I came up with the following iterator structure:

 struct RTBytesIterator'self {
 tokenizer: 'self mut ReaderTokenizer'self
 }

 impl'self Iteratoru8 for RTBytesIterator'self {
 fn next(mut self) - Optionu8 {
 if self.tokenizer.eof() {
 return None;
 }
 if self.tokenizer.buffer.readable_bytes()  0 ||
self.tokenizer.buffer.fill_from_reader(self.tokenizer.inner)  0 {
 return Some(self.tokenizer.buffer.read_unsafe());
 } else {
 return None;
 }
 }
 }

 Note that tokenizer field is 'self mut since CyclicBuffer is mutable.
 buffer.fill_from_reader() function reads as much as possible from the
 reader (returning a number of bytes read), and buffer.read_unsafe()
 returns next byte from the cyclic buffer.

 Then I've added the following method to ReaderTokenizer:

 impl'self ReaderTokenizer'self {
 ...
 fn bytes_iter(mut self) - RTBytesIterator'self {
 RTBytesIterator { tokenizer: self }
 }
 ...
 }

 This does not compile with the following error:

 io/convert_io.rs:98:37: 98:43 error: cannot infer an appropriate
 lifetime due to conflicting requirements
 io/convert_io.rs:98 RTBytesIterator { tokenizer: self }
  ^~
 io/convert_io.rs:97:55: 99:5 note: first, the lifetime cannot outlive
 the anonymous lifetime #1 defined on the block at 97:55...
 io/convert_io.rs:97 fn bytes_iter(mut self) - RTBytesIterator'self {
 io/convert_io.rs:98 RTBytesIterator { tokenizer: self }
 io/convert_io.rs:99 }
 io/convert_io.rs:98:37: 98

[rust-dev] Borrowed pointers with lifetime in structures cause weird errors

2013-08-17 Thread Vladimir Matveev
Hello,

I'm writing a simple tokenizer which is defined by this trait:

trait Tokenizer {
fn next_token(mut self) - ~str;
fn eof(self) - bool;
}

Obvious application for a tokenizer is splitting a stream going from
Reader, so I have the following structure which should implement
Tokenizer:

pub struct ReaderTokenizer'self {
priv inner: 'self Reader,
priv buffer: ~CyclicBuffer,
priv seps: ~[~str]
}

I have used 'self lifetime parameter since I want for the tokenizer
work for any Reader. CyclicBuffer is another structure which
essentially is an array of u8 with special read/write operations.

Implementation of a Tokenizer for ReaderTokenizer involves reading
from the Reader one byte at a time. I decided to use buffering to
improve performance. But I still want to keep the useful abstraction
of single byte reading, so I decided to implement Iteratoru8 for my
Reader+CyclicBuffer pair. BTW, internal iterators in 0.7 were much
better for this, because internal iterator code was very simple and
didn't use explicit lifetimes at all, but 0.7 compiler suffers from
several errors related to pointers to traits which prevented my
program from compiling (I couldn't pass a reference to Reader to
CyclicBuffer method; there were other errors I've encountered too). I
So, I decided to use trunk version of the compiler in which these
errors are resolved according to github, but trunk version does not
allow internal iterators, which is very sad since now I'm forced to
create intermediate structures to achieve the same thing.

So, I came up with the following iterator structure:

struct RTBytesIterator'self {
tokenizer: 'self mut ReaderTokenizer'self
}

impl'self Iteratoru8 for RTBytesIterator'self {
fn next(mut self) - Optionu8 {
if self.tokenizer.eof() {
return None;
}
if self.tokenizer.buffer.readable_bytes()  0 ||
   self.tokenizer.buffer.fill_from_reader(self.tokenizer.inner)  0 {
return Some(self.tokenizer.buffer.read_unsafe());
} else {
return None;
}
}
}

Note that tokenizer field is 'self mut since CyclicBuffer is mutable.
buffer.fill_from_reader() function reads as much as possible from the
reader (returning a number of bytes read), and buffer.read_unsafe()
returns next byte from the cyclic buffer.

Then I've added the following method to ReaderTokenizer:

impl'self ReaderTokenizer'self {
...
fn bytes_iter(mut self) - RTBytesIterator'self {
RTBytesIterator { tokenizer: self }
}
...
}

This does not compile with the following error:

io/convert_io.rs:98:37: 98:43 error: cannot infer an appropriate
lifetime due to conflicting requirements
io/convert_io.rs:98 RTBytesIterator { tokenizer: self }
 ^~
io/convert_io.rs:97:55: 99:5 note: first, the lifetime cannot outlive
the anonymous lifetime #1 defined on the block at 97:55...
io/convert_io.rs:97 fn bytes_iter(mut self) - RTBytesIterator'self {
io/convert_io.rs:98 RTBytesIterator { tokenizer: self }
io/convert_io.rs:99 }
io/convert_io.rs:98:37: 98:43 note: ...due to the following expression
io/convert_io.rs:98 RTBytesIterator { tokenizer: self }
 ^~
io/convert_io.rs:97:55: 99:5 note: but, the lifetime must be valid for
the lifetime 'self  as defined on the block at 97:55...
io/convert_io.rs:97 fn bytes_iter(mut self) - RTBytesIterator'self {
io/convert_io.rs:98 RTBytesIterator { tokenizer: self }
io/convert_io.rs:99 }
io/convert_io.rs:98:8: 98:23 note: ...due to the following expression
io/convert_io.rs:98 RTBytesIterator { tokenizer: self }
^~~
error: aborting due to previous error

OK, fair enough, I guess I have to annotate self parameter with 'self lifetime:

fn bytes_iter('self mut self) - RTBytesIterator'self {
RTBytesIterator { tokenizer: self }
}

This compiles, but now I'm getting another error at bytes_iter() usage
site, for example, the following code:

fn try_read_sep(mut self, first: u8) - (~[u8], bool) {
let mut part = ~[first];
for b in self.bytes_iter() {
part.push(b);
if !self.is_sep_prefix(part) {
return (part, false);
}
if self.is_sep(part) {
break;
}
}
return (part, true);
}

fails to compile with this error:

io/convert_io.rs:117:17: 117:36 error: cannot infer an appropriate
lifetime due to conflicting requirements
io/convert_io.rs:117 for b in self.bytes_iter() {
  ^~~
io/convert_io.rs:117:17: 117:22 note: first, the lifetime cannot
outlive the expression at 117:17...
io/convert_io.rs:117 for b in self.bytes_iter() {
  ^
io/convert_io.rs:117:17: 117:22 note: