Re: [rust-dev] real-time programming? usability?

2013-10-19 Thread Daniel Micay
On Sat, Oct 19, 2013 at 12:45 AM, Jerry Morrison jhm...@gmail.com wrote:


 On Fri, Oct 18, 2013 at 6:13 PM, Daniel Micay danielmi...@gmail.comwrote:

 On Fri, Oct 18, 2013 at 7:37 PM, Jerry Morrison jhm...@gmail.com wrote:


 (1) Rust has great potential for *real-time programming* as well as
 secure programming. Perhaps this just needs a library call to fork
 real-time threads that never do garbage collection. (Real-time means
 predictably meeting time deadlines, e.g. in avionics, video capture,
 medical x-ray, and robotics. Speed is important but the crucial point is
 reliably meeting deadlines. Garbage collectors, JIT compilers, and run-time
 optimizers are bad for predictability.) Maybe Rust already has this. What
 determines whether a thread-local managed heap uses reference counting?
 Ref-counting may be OK in a real-time thread if it doesn't deallocate a
 variable-length chain of nodes at an inconvenient time.


 Rust leaves memory allocation up to the user as much as C++. Most code
 can simply use unboxed values and lightweight references, with occasional
 usage of owned boxes (single-owner heap allocations, with lifetime tied to
 scope).


 Ideally, forking a real-time thread could ensure that (1) no GC pauses the
 thread just to find out there's no garbage to collect, and (2) something
 would catch the mistake if it ever calls code (directly or indirectly) that
 evolves to using GC memory.


Rust doesn't currently have a way to forbid features only in some parts of
the code but not others. Avoiding garbage collection as a hard requirement
will likely mean using rust-core (or whatever it evolves to, maybe a
special profile of the standard library).

  If you need shared ownership, it's available via the `Rc`/`RcMut` types.
 Every split of ownership is explicit via a `clone` call since moves are the
 default. There will be a task-local garbage collector providing garbage
 collected pointers, but it still needs to be implemented.


 Sounds good, although I don't understand the details. Does the program
 pick between GC allocation and ref counting allocation via the choice of
 pointer sigils? Via the choice of library calls?


Reference counting is implemented as a library type, so you would make a
reference counted allocation with `Rc::new(value)` and make an explicit
reference count with `box.clone()` (the implementation:
https://github.com/mozilla/rust/blob/master/src/libstd/rc.rs).

There are managed pointers sigils for garbage collection (@, @mut) but I
think consensus is trending towards replacing the syntax with a type
similar to `Rc` allowing cycles and implicit copies. The compiler support
could be exposed via attributes hooks like the operator traits, rather than
syntax.


 The standard library implements N:M concurrency and exposes a blocking API
 for asynchronous I/O. I don't think it would be suitable for a real-time
 application, but you can avoid the standard library:
 https://github.com/thestinger/rust-core


What's N:M concurrency?


The concurrency model implemented in the standard library treats real
threads as schedulers, and maps cooperatively scheduled tasks onto them. If
the task doesn't make calls to functions with yields, it will monopolize a
scheduler thread.

It's a very good model for I/O or for high throughput on many CPU-bound
batch jobs (https://www.threadingbuildingblocks.org/), but it's not going
to be suitable for real-time needs.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Strange behavior about Writer trait

2013-10-19 Thread Oren Ben-Kiki
I run into the following problem (the code below is a toy example).

```
use std::io::Writer; // Makes no difference if added/removed.

trait PrintWithSpice {
fn print(self, writer: Writer, spice: bool);
}

struct Bar {
bar: ~PrintWithSpice,
}

impl Bar {
pub fn print(self, writer: Writer) {
self.bar.print(writer, false);
Bar::print_via_borrowed(writer, self.bar);
}

fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
// Invoking the `print` function via the borrowed pointer to the
`PrintWithSpice` trait:
// Works fine, as expected..
data.print(writer, true);
}
}

struct Foo {
foo: bool
}

impl PrintWithSpice for Foo {
fn print(self, writer: Writer, spice: bool) {
// Invoking the `write_str` function via the borrowed pointer to
the `Writer` trait:
// error: failed to find an implementation of trait std::io::Writer
for std::io::Writerno-bounds
// What is going on?
writer.write_str(format!(foo: {:b} spice: {:b}, self.foo, spice));
}
}
```

I didn't understand what the compiler is complaining about. failed to find
an implementation of Foo for Foono-bounds? A Foo is a Foo, no? Calling
a function via a borrowed pointer to a trait should just work (it does a
few lines above).

After digging I discovered what the compiler really meant (I think). The
`write_str` method is defined for `WriterUtils` rather than for `Writer`.
So, if I replace `Writer` by `WriterUtil` in the above code, it compiles
fine.

So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
using that instead of `Writer` all over my code. I can see doing that as a
workaround, but it doesn't smell right to me.

So:

* Why is the compiler complaining about not finding an implementation for
`Writer` when the method I invoke is from `WriterUtil`?

* Since there is an `implT: Writer for WriterUtil`, shouldn't the
compiler be sufficiently smart to deduce that the code is valid in the
1st place?

* Until the compiler is sufficiently smart (or, if there is a good reason
why it would never be), shouldn't we rename `Writer` to `BasicWriter` and
define `trait Writer: BasicWriter, WriterUtil {}` so `Writer` would become
more usable?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Strange behavior about Writer trait

2013-10-19 Thread Oren Ben-Kiki
Ugh, I was too optimistic. Yes, I can write my code using `MyWriter`, but I
can't cast any @Writer (such as `io::stdout()`) to it. I guess I should
just use `@Writer` everywhere for now :-(

This raises the question of how come the compiler is smart enough to figure
out a `@Writer` has the trait `WriterUtil`, but isn't smart enough to
figure out a `Writer` has the trait...


On Sat, Oct 19, 2013 at 9:08 AM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 I run into the following problem (the code below is a toy example).

 ```
 use std::io::Writer; // Makes no difference if added/removed.

 trait PrintWithSpice {
 fn print(self, writer: Writer, spice: bool);
 }

 struct Bar {
 bar: ~PrintWithSpice,
 }

 impl Bar {
 pub fn print(self, writer: Writer) {
 self.bar.print(writer, false);
 Bar::print_via_borrowed(writer, self.bar);
 }

 fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
 // Invoking the `print` function via the borrowed pointer to the
 `PrintWithSpice` trait:
 // Works fine, as expected..
 data.print(writer, true);
 }
 }

 struct Foo {
 foo: bool
 }

 impl PrintWithSpice for Foo {
 fn print(self, writer: Writer, spice: bool) {
 // Invoking the `write_str` function via the borrowed pointer to
 the `Writer` trait:
 // error: failed to find an implementation of trait
 std::io::Writer for std::io::Writerno-bounds
 // What is going on?
 writer.write_str(format!(foo: {:b} spice: {:b}, self.foo,
 spice));
 }
 }
 ```

 I didn't understand what the compiler is complaining about. failed to
 find an implementation of Foo for Foono-bounds? A Foo is a Foo, no?
 Calling a function via a borrowed pointer to a trait should just work (it
 does a few lines above).

 After digging I discovered what the compiler really meant (I think). The
 `write_str` method is defined for `WriterUtils` rather than for `Writer`.
 So, if I replace `Writer` by `WriterUtil` in the above code, it compiles
 fine.

 So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
 using that instead of `Writer` all over my code. I can see doing that as a
 workaround, but it doesn't smell right to me.

 So:

 * Why is the compiler complaining about not finding an implementation for
 `Writer` when the method I invoke is from `WriterUtil`?

 * Since there is an `implT: Writer for WriterUtil`, shouldn't the
 compiler be sufficiently smart to deduce that the code is valid in the
 1st place?

 * Until the compiler is sufficiently smart (or, if there is a good
 reason why it would never be), shouldn't we rename `Writer` to
 `BasicWriter` and define `trait Writer: BasicWriter, WriterUtil {}` so
 `Writer` would become more usable?

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


Re: [rust-dev] Strange behavior about Writer trait

2013-10-19 Thread Steven Fackler
If T is a trait, its trait objects ~T, @T and T do not implement T. There
is an implementation of Writer for @Writer, but not for ~Writer or Writer
which is why you're seeing that error.

Steven Fackler


On Fri, Oct 18, 2013 at 11:27 PM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 Ugh, I was too optimistic. Yes, I can write my code using `MyWriter`, but
 I can't cast any @Writer (such as `io::stdout()`) to it. I guess I should
 just use `@Writer` everywhere for now :-(

 This raises the question of how come the compiler is smart enough to
 figure out a `@Writer` has the trait `WriterUtil`, but isn't smart enough
 to figure out a `Writer` has the trait...


 On Sat, Oct 19, 2013 at 9:08 AM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 I run into the following problem (the code below is a toy example).

 ```
 use std::io::Writer; // Makes no difference if added/removed.

 trait PrintWithSpice {
 fn print(self, writer: Writer, spice: bool);
 }

 struct Bar {
 bar: ~PrintWithSpice,
 }

 impl Bar {
 pub fn print(self, writer: Writer) {
 self.bar.print(writer, false);
 Bar::print_via_borrowed(writer, self.bar);
 }

 fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
 // Invoking the `print` function via the borrowed pointer to the
 `PrintWithSpice` trait:
 // Works fine, as expected..
 data.print(writer, true);
 }
 }

 struct Foo {
 foo: bool
 }

 impl PrintWithSpice for Foo {
 fn print(self, writer: Writer, spice: bool) {
 // Invoking the `write_str` function via the borrowed pointer to
 the `Writer` trait:
 // error: failed to find an implementation of trait
 std::io::Writer for std::io::Writerno-bounds
 // What is going on?
 writer.write_str(format!(foo: {:b} spice: {:b}, self.foo,
 spice));
 }
 }
 ```

 I didn't understand what the compiler is complaining about. failed to
 find an implementation of Foo for Foono-bounds? A Foo is a Foo, no?
 Calling a function via a borrowed pointer to a trait should just work (it
 does a few lines above).

 After digging I discovered what the compiler really meant (I think). The
 `write_str` method is defined for `WriterUtils` rather than for `Writer`.
 So, if I replace `Writer` by `WriterUtil` in the above code, it compiles
 fine.

 So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
 using that instead of `Writer` all over my code. I can see doing that as a
 workaround, but it doesn't smell right to me.

 So:

 * Why is the compiler complaining about not finding an implementation for
 `Writer` when the method I invoke is from `WriterUtil`?

 * Since there is an `implT: Writer for WriterUtil`, shouldn't the
 compiler be sufficiently smart to deduce that the code is valid in the
 1st place?

 * Until the compiler is sufficiently smart (or, if there is a good
 reason why it would never be), shouldn't we rename `Writer` to
 `BasicWriter` and define `trait Writer: BasicWriter, WriterUtil {}` so
 `Writer` would become more usable?



 ___
 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] Strange behavior about Writer trait

2013-10-19 Thread Oren Ben-Kiki
Hmmm That sounds strange. Shouldn't `obj: T` allow me to invoke
`obj.method_of_T()`?

For example, how did I manage to invoke the `data.print(...)` method via
the borrowed `data: PrintWithSpice` pointer? Automatic dereference? And if
so, why didn't it work for `Writer` as well?

On Sat, Oct 19, 2013 at 9:29 AM, Steven Fackler sfack...@gmail.com wrote:

 If T is a trait, its trait objects ~T, @T and T do not implement T. There
 is an implementation of Writer for @Writer, but not for ~Writer or Writer
 which is why you're seeing that error.

 Steven Fackler


 On Fri, Oct 18, 2013 at 11:27 PM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 Ugh, I was too optimistic. Yes, I can write my code using `MyWriter`, but
 I can't cast any @Writer (such as `io::stdout()`) to it. I guess I should
 just use `@Writer` everywhere for now :-(

 This raises the question of how come the compiler is smart enough to
 figure out a `@Writer` has the trait `WriterUtil`, but isn't smart enough
 to figure out a `Writer` has the trait...


 On Sat, Oct 19, 2013 at 9:08 AM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 I run into the following problem (the code below is a toy example).

 ```
 use std::io::Writer; // Makes no difference if added/removed.

 trait PrintWithSpice {
 fn print(self, writer: Writer, spice: bool);
 }

 struct Bar {
 bar: ~PrintWithSpice,
 }

 impl Bar {
 pub fn print(self, writer: Writer) {
 self.bar.print(writer, false);
 Bar::print_via_borrowed(writer, self.bar);
 }

 fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
 // Invoking the `print` function via the borrowed pointer to the
 `PrintWithSpice` trait:
 // Works fine, as expected..
 data.print(writer, true);
 }
 }

 struct Foo {
 foo: bool
 }

 impl PrintWithSpice for Foo {
 fn print(self, writer: Writer, spice: bool) {
 // Invoking the `write_str` function via the borrowed pointer to
 the `Writer` trait:
 // error: failed to find an implementation of trait
 std::io::Writer for std::io::Writerno-bounds
 // What is going on?
 writer.write_str(format!(foo: {:b} spice: {:b}, self.foo,
 spice));
 }
 }
 ```

 I didn't understand what the compiler is complaining about. failed to
 find an implementation of Foo for Foono-bounds? A Foo is a Foo, no?
 Calling a function via a borrowed pointer to a trait should just work (it
 does a few lines above).

 After digging I discovered what the compiler really meant (I think). The
 `write_str` method is defined for `WriterUtils` rather than for `Writer`.
 So, if I replace `Writer` by `WriterUtil` in the above code, it compiles
 fine.

 So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
 using that instead of `Writer` all over my code. I can see doing that as a
 workaround, but it doesn't smell right to me.

 So:

 * Why is the compiler complaining about not finding an implementation
 for `Writer` when the method I invoke is from `WriterUtil`?

 * Since there is an `implT: Writer for WriterUtil`, shouldn't the
 compiler be sufficiently smart to deduce that the code is valid in the
 1st place?

 * Until the compiler is sufficiently smart (or, if there is a good
 reason why it would never be), shouldn't we rename `Writer` to
 `BasicWriter` and define `trait Writer: BasicWriter, WriterUtil {}` so
 `Writer` would become more usable?



 ___
 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] Unified function/method call syntax and further simplification

2013-10-19 Thread Oren Ben-Kiki
Interesting idea; in that case, one could string together any series of
functions - basically, `.` would become the equivalent of `|` (or whatever
other name you want to call it). That is, instead of writing
`baz(bar(foo(x), y), z)` one could write `foo(x).bar(y).baz(z)`. This would
make it easier to write things in functional style, using the same syntax
as the object style.

It could be viewed as the natural complement for the `do` keyword, which
adds a last block parameter to the end of the function.

I'm less certain about giving up `impl Foo { ... }`, though - that is
useful for logically grouping, documenting and accessing functions (as in
`Foo::foo(...)`). But it seems we don't have to give it up, just make it
optional?

On Sat, Oct 19, 2013 at 3:47 PM, Matthieu Monrocq 
matthieu.monr...@gmail.com wrote:

 I see no reason for the restriction of self. Why not simply say that any
 function can be called with first_arg.func(...) style ?

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


Re: [rust-dev] mutable vs. functional APIs

2013-10-19 Thread Eric Sampson
 Date: Fri, 18 Oct 2013 10:54:23 -0700
 From: Jeff Petkau j...@google.com



 On my code (disclaimer: only toy projects to learn Rust so far),  I've been
 pretty happy with a mut_ prefix for mutable versions.

   newthing = oldthing.push(foo)
   anything.mut_push(foo)

   x = bagofun.sort()
   bagosadness.mut_sort()

   etc.

 Advantages:
 - consistent meaning with the 'mut' keyword.
 - works with pretty much any name.
 - makes mutable versions just a bit uglier than immutable code.

 Disadvantages:
 - If an API is inherently mutable, it gets pretty noisy.
 - A bit ugly, probably turns off newcomers.
 - If the compiler warns on ignoring return values, and mutating methods
 return (), then a convention might be unnecessary.

 --Jeff


What about establishing a convention that mutable methods start with an
uppercase letter while non-mutating methods start with a lowercase letter?
It would be lightweight in terms of character count/looks and at the same
time give mutable methods a slight visual emphasis, which makes sense I
think.

I know this convention is already used by Traits, but when I looked through
some code with the above proposal in mind it would be easy to distinguish
between these two uses of the same convention due to the differing contexts
they're used in.

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


[rust-dev] Should I/O use conditions?

2013-10-19 Thread Steven Blenkinsop
On Saturday, 19 October 2013, Florian Weimer wrote:


 The problem is that if err is of type error, err != nil is true
 after the assignment of a pointer value to err.  So the usual error
 checking idiom doesn't work if your function returns a
 pointer-to-struct (that implements the error interface) instead of a
 (relatively opaque) error interface value.


Don't do that. Return an error, not a naked error implementation. If people
want to inspect it rather than treat it as a string, they'll do a type
assertion rather than just a nil check.

Rust doesn't have type assertions, however I feel this could be handled
satisfactorily by using concrete error types in Rust. Also, the whole nil
vs nil thing is irrelevant to Rust.


 Or put differently, if you put a typed null pointer into an interface
 value, the interface value keeps the type information and is therefore
 no longer equal to nil.


Don't do that. Return either a nil error or a valid value of your error
type. Seriously, the nil interface vs nil contents thing is only a tripping
point for novices who don't understand what interfaces are, it's not
something you run into once you've familiarized yourself with the language.

This wouldn't be an issue in Rust, since people would really have to go out
of their way to conflate an Err(None) with an Ok(v).

That's not a chaining mechanism.


You're going to need to explain what you mean by this, then, and how it
would apply to Rust. Note that if it's something very particular to how Go
code is written, it's probably not constructive here.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] #rust-osdev

2013-10-19 Thread Nicholas Platt
This is right up my alley for interest, but I'm not often on IRC. Will they
be logged somewhere?


On Fri, Oct 18, 2013 at 5:28 AM, Léo Testard leo.test...@gmail.com wrote:

 Hello,

 A new channel appeared on IRC today following a discussion about exo and
 microkernels on #rust.
 This chan is #rust-osdev and is about... guess what... OS development with
 Rust. That's it.

 We will discuss how to use Rust for OS development : how to compile and
 run Rust code without the
 runtime, how to make it boot on the hardware, how to link it with C or
 assembly, how to implement some
 things with Rust, etc. etc. and many other fun things

 I created a wiki page (
 https://github.com/mozilla/rust/wiki/Operating-system-development)
 that will reference resources, projects, etc. It's quite empty for now but
 I hope it will be filled soon :)

 Leo

 ___
 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] Should I/O use conditions?

2013-10-19 Thread Igor Bukanov
This is how we implemented error handling in Java. We defined an
abstract class ErrorSink like in:

class ErrorSink {
void addError(String s);
boolean hasError(s);
// few more methods to add extra attributes like line, file,
column etc of errors
}

A default implementation of the class just throws in the addError
method, but the requirement for addError callers is to assume that
method would not throw and try to recover or return some sensible
value. For example, a method like readFileAsString in case of
IOException reported that and returned an empty string.

A configuration parser that calls readFileAsString to read included
files has a custom implementation of ErrorSink that does not throw but
rather adds all errors on the list. At the end of parsing all those
errors plus all syntax violations was converted into a new detailed
report with proper line numbers etc and reported to the original sink.

This has number of benefits. All unexpected errors like dns failure
when reading URL are nicely formated showing the error origin. Various
low-level helpers like a date parser do not need to worry about
including proper context in the error message as that was
responsibility of the caller. This allowed to reuse the same parser in
GUI dialogs for a date input showing short and very informative
tooltip when user typed invalid date. It was trivial to add warnings
to the system extending the ErrorSink with an addWarning method and
turn those warnings into hard errors at runtime during testing via
simple throw. The callers would not need to check for errors at the
every method call.

The biggest drawback was the need to pass ErrorSink to a lot of
methods or store that as a member of many classes. We experimented
with using Java's thread locals instead, but that was rather
inflexible and inefficient.

I wonder why such error reporting is not used in other programs or languages.

On 18 October 2013 23:20, Florian Weimer f...@deneb.enyo.de wrote:
 * Igor Bukanov:

 So the Go style is to call a function, check if the was an error,
 update the error object (or create a new wrapping the old one) with
 extra information relevant to the current call stack frame and
 propagate the updated error object to the caller.

 It's more common to simply return the object.

 Due to some obscure feature of Go's type system, error values have to
 be interfaces and cannot be struct types, so I have not seen anyone
 trying to updating an existing error.  Wrapping might happen, but
 there is no general chaining mechanism like there is in Java.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Unified function/method call syntax and further simplification

2013-10-19 Thread Gábor Lehel
On Sat, Oct 19, 2013 at 4:08 PM, Oren Ben-Kiki o...@ben-kiki.org wrote:


 I'm less certain about giving up `impl Foo { ... }`, though - that is
 useful for logically grouping, documenting and accessing functions (as in
 `Foo::foo(...)`). But it seems we don't have to give it up, just make it
 optional?


Interesting point. I think this argues in favor of removing anonymous
`impl`s, even as sugar. I was focused on normal (selfish) methods in my
previous letter, rather than static (selfless) ones. You could still
achieve much the same effect, if you wanted to, by writing:

struct Foo { .. }

fn get_thing(self: Foo) - Bar { .. } // for `some_foo.get_thing()`
syntax

mod Foo {
fn new() - Foo { .. } // for `Foo::new()` syntax
}

Rust already allows this trickery: the type and module are imported
together when you write `use some_mod::Foo`. Keeping this seems fine, and
making it more explicit (relative to `impl`) seems like a good thing. What
you lose is that in the case of a generic type, you would have to write the
generic-bits for each function, which is the more typing disadvantage
from earlier. I think losing the `impl` sugar is a small price to pay for
the simplification of the language. Modules would be modules and types
would be types. Append to the advantages list:

 - The complexity related to (possibly-generic) types in paths would go away


On Sat, Oct 19, 2013 at 3:47 PM, Matthieu Monrocq 
 matthieu.monr...@gmail.com wrote:

 I see no reason for the restriction of self. Why not simply say that
 any function can be called with first_arg.func(...) style ?


Yeah, as I mentioned in the last bullet of the previous letter, you could
do this. I don't think it makes much difference either way and don't have a
strong opinion.

In favor of explicit `self` is that it's, well, explicit: you can and
should call this using method syntax. I can imagine there might be
function signatures where using method syntax wouldn't make sense (though
you might say, then don't use it, and I would be inclined to agree). A
non-method function (one without a `self` arg) also wouldn't cause
ambiguity if it were in scope at the same time as you were calling another
method with the same name.

In favor of always allowing method syntax on the first argument is that you
could destructure it in the definition, e.g. `fn area((x, y): (int, int))
- int { x * y }`, and still call the function using method syntax.

They're all pretty minor.

-- 
Your ship was destroyed in a monadic eruption.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Unified function/method call syntax and further simplification

2013-10-19 Thread Patrick Walton
I think it's unfortunately too late to overhaul the language like this. This 
will require redesigns of all Rust code in existence.

I do like unified function/method call syntax, but I think it can be done in a 
backwards compatible way.

Patrick

Gábor Lehel illiss...@gmail.com wrote:
On Sat, Oct 19, 2013 at 4:08 PM, Oren Ben-Kiki o...@ben-kiki.org
wrote:


 I'm less certain about giving up `impl Foo { ... }`, though - that is
 useful for logically grouping, documenting and accessing functions
(as in
 `Foo::foo(...)`). But it seems we don't have to give it up, just make
it
 optional?


Interesting point. I think this argues in favor of removing anonymous
`impl`s, even as sugar. I was focused on normal (selfish) methods in
my
previous letter, rather than static (selfless) ones. You could
still
achieve much the same effect, if you wanted to, by writing:

struct Foo { .. }

   fn get_thing(self: Foo) - Bar { .. } // for `some_foo.get_thing()`
syntax

mod Foo {
fn new() - Foo { .. } // for `Foo::new()` syntax
}

Rust already allows this trickery: the type and module are imported
together when you write `use some_mod::Foo`. Keeping this seems fine,
and
making it more explicit (relative to `impl`) seems like a good thing.
What
you lose is that in the case of a generic type, you would have to write
the
generic-bits for each function, which is the more typing disadvantage
from earlier. I think losing the `impl` sugar is a small price to pay
for
the simplification of the language. Modules would be modules and types
would be types. Append to the advantages list:

- The complexity related to (possibly-generic) types in paths would go
away


On Sat, Oct 19, 2013 at 3:47 PM, Matthieu Monrocq 
 matthieu.monr...@gmail.com wrote:

 I see no reason for the restriction of self. Why not simply say
that
 any function can be called with first_arg.func(...) style ?


Yeah, as I mentioned in the last bullet of the previous letter, you
could
do this. I don't think it makes much difference either way and don't
have a
strong opinion.

In favor of explicit `self` is that it's, well, explicit: you can and
should call this using method syntax. I can imagine there might be
function signatures where using method syntax wouldn't make sense
(though
you might say, then don't use it, and I would be inclined to agree).
A
non-method function (one without a `self` arg) also wouldn't cause
ambiguity if it were in scope at the same time as you were calling
another
method with the same name.

In favor of always allowing method syntax on the first argument is that
you
could destructure it in the definition, e.g. `fn area((x, y): (int,
int))
- int { x * y }`, and still call the function using method syntax.

They're all pretty minor.

-- 
Your ship was destroyed in a monadic eruption.




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

-- 
Sent from my Android phone with K-9 Mail. Please excuse my brevity.___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] real-time programming? usability?

2013-10-19 Thread Jerry Morrison
On Fri, Oct 18, 2013 at 11:02 PM, Daniel Micay danielmi...@gmail.comwrote:

 On Sat, Oct 19, 2013 at 12:45 AM, Jerry Morrison jhm...@gmail.com wrote:


 On Fri, Oct 18, 2013 at 6:13 PM, Daniel Micay danielmi...@gmail.comwrote:

 On Fri, Oct 18, 2013 at 7:37 PM, Jerry Morrison jhm...@gmail.comwrote:


 (1) Rust has great potential for *real-time programming* as well as
 secure programming. Perhaps this just needs a library call to fork
 real-time threads that never do garbage collection. (Real-time means
 predictably meeting time deadlines, e.g. in avionics, video capture,
 medical x-ray, and robotics. Speed is important but the crucial point is
 reliably meeting deadlines. Garbage collectors, JIT compilers, and run-time
 optimizers are bad for predictability.) Maybe Rust already has this. What
 determines whether a thread-local managed heap uses reference counting?
 Ref-counting may be OK in a real-time thread if it doesn't deallocate a
 variable-length chain of nodes at an inconvenient time.


 Rust leaves memory allocation up to the user as much as C++. Most code
 can simply use unboxed values and lightweight references, with occasional
 usage of owned boxes (single-owner heap allocations, with lifetime tied to
 scope).


 Ideally, forking a real-time thread could ensure that (1) no GC pauses
 the thread just to find out there's no garbage to collect, and (2)
 something would catch the mistake if it ever calls code (directly or
 indirectly) that evolves to using GC memory.


 Rust doesn't currently have a way to forbid features only in some parts of
 the code but not others. Avoiding garbage collection as a hard requirement
 will likely mean using rust-core (or whatever it evolves to, maybe a
 special profile of the standard library).


So with a suitable library, real-time threads can avoid garbage collection
pauses. Can it enforce linking to this library for all the code it calls,
or else arrange for the standard GC memory allocator to  fail!()  if it
accidentally called?


   If you need shared ownership, it's available via the `Rc`/`RcMut`
 types. Every split of ownership is explicit via a `clone` call since moves
 are the default. There will be a task-local garbage collector providing
 garbage collected pointers, but it still needs to be implemented.


 Sounds good, although I don't understand the details. Does the program
 pick between GC allocation and ref counting allocation via the choice of
 pointer sigils? Via the choice of library calls?


 Reference counting is implemented as a library type, so you would make a
 reference counted allocation with `Rc::new(value)` and make an explicit
 reference count with `box.clone()` (the implementation:
 https://github.com/mozilla/rust/blob/master/src/libstd/rc.rs).

 There are managed pointers sigils for garbage collection (@, @mut) but I
 think consensus is trending towards replacing the syntax with a type
 similar to `Rc` allowing cycles and implicit copies. The compiler support
 could be exposed via attributes hooks like the operator traits, rather than
 syntax.


Nice.



 The standard library implements N:M concurrency and exposes a blocking
 API for asynchronous I/O. I don't think it would be suitable for a
 real-time application, but you can avoid the standard library:
 https://github.com/thestinger/rust-core


 What's N:M concurrency?


 The concurrency model implemented in the standard library treats real
 threads as schedulers, and maps cooperatively scheduled tasks onto them. If
 the task doesn't make calls to functions with yields, it will monopolize a
 scheduler thread.

 It's a very good model for I/O or for high throughput on many CPU-bound
 batch jobs (https://www.threadingbuildingblocks.org/), but it's not going
 to be suitable for real-time needs.


Thanks. That makes sense.

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


Re: [rust-dev] Unified function/method call syntax and further simplification

2013-10-19 Thread Ziad Hatahet
On Sat, Oct 19, 2013 at 1:52 PM, Patrick Walton pwal...@mozilla.com wrote:

 I think it's unfortunately too late to overhaul the language like this.
 This will require redesigns of all Rust code in existence.

 I do like unified function/method call syntax, but I think it can be done
 in a backwards compatible way.


What do you have in mind at the moment? Implementing UFCS while still
keeping the `impl` syntax around for structs? What about for primitive
types, e.g. would `fn double(a: int) - { 2*a }` be callable as
`2.double()`, without breaking backward compatibility?

Thanks


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


Re: [rust-dev] real-time programming? usability?

2013-10-19 Thread Tim Chevalier
On Sat, Oct 19, 2013 at 2:33 PM, Jerry Morrison jhm...@gmail.com wrote:

 So with a suitable library, real-time threads can avoid garbage collection
 pauses. Can it enforce linking to this library for all the code it calls, or
 else arrange for the standard GC memory allocator to  fail!()  if it
 accidentally called?

There's no dynamic checking needed; you just need to include the
#[deny(managed_heap_memory)] attribute in the crate file. (There's
also a way to do the same thing with a command-line flag.) This will
result in a compile-time failure if any code might use garbage
collection (including code in external libraries that's called by your
code).

Cheers,
Tim


-- 
Tim Chevalier * http://catamorphism.org/ * Often in error, never in doubt
Being queer is not about a right to privacy; it is about the freedom
to be public, to just be who we are. -- anonymous, June 1990
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] real-time programming? usability?

2013-10-19 Thread Jerry Morrison
On Sat, Oct 19, 2013 at 2:36 PM, Tim Chevalier catamorph...@gmail.comwrote:

 On Sat, Oct 19, 2013 at 2:33 PM, Jerry Morrison jhm...@gmail.com wrote:
 
  So with a suitable library, real-time threads can avoid garbage
 collection
  pauses. Can it enforce linking to this library for all the code it
 calls, or
  else arrange for the standard GC memory allocator to  fail!()  if it
  accidentally called?

 There's no dynamic checking needed; you just need to include the
 #[deny(managed_heap_memory)] attribute in the crate file. (There's
 also a way to do the same thing with a command-line flag.) This will
 result in a compile-time failure if any code might use garbage
 collection (including code in external libraries that's called by your
 code).

 Cheers,
 Tim


Fantastic. Thanks, Tim!

For a program with some real-time threads plus other code like UI, I assume
the other code can be in a crate that allows managed_heap_memory.

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


Re: [rust-dev] real-time programming? usability?

2013-10-19 Thread Daniel Micay
On Sat, Oct 19, 2013 at 5:43 PM, Jerry Morrison jhm...@gmail.com wrote:


 On Sat, Oct 19, 2013 at 2:36 PM, Tim Chevalier catamorph...@gmail.comwrote:

 On Sat, Oct 19, 2013 at 2:33 PM, Jerry Morrison jhm...@gmail.com wrote:
 
  So with a suitable library, real-time threads can avoid garbage
 collection
  pauses. Can it enforce linking to this library for all the code it
 calls, or
  else arrange for the standard GC memory allocator to  fail!()  if it
  accidentally called?

 There's no dynamic checking needed; you just need to include the
 #[deny(managed_heap_memory)] attribute in the crate file. (There's
 also a way to do the same thing with a command-line flag.) This will
 result in a compile-time failure if any code might use garbage
 collection (including code in external libraries that's called by your
 code).

 Cheers,
 Tim


 Fantastic. Thanks, Tim!

 For a program with some real-time threads plus other code like UI, I
 assume the other code can be in a crate that allows managed_heap_memory.

 --
Jerry


The `managed_heap_memory` lint will prevent using any types containing
managed pointers, but won't strictly prevent calling code using garbage
collection.

In a `#[no_std]` codebase, the compiler will prevent using managed pointers
unless the hooks for them are defined.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Strange behavior about Writer trait

2013-10-19 Thread Steven Blenkinsop
Consider this program:


trait AdderIncr {
fn add(self, x: Self) - Self;
fn incr(mut self);
}

impl AdderIncr for int {
fn add(self, x: int) - int { *self + x }
fn incr(mut self) { *self += 1; }
}

fn incrAdd(x: mut AdderIncr, y: mut AdderIncr) {
x.incr();
x.add(y);
}

fn main() {}


It fails to compile:


Documents/test.rs:13:1: 13:10 error: cannot call a method whose type
contains a self-type through an object
Documents/test.rs:13x.add(y);
^


The Self type is meaningless in object methods, since I have no way to
ensure that y has the same underlying type as x. Thus, only a subset of the
methods of a trait are available on the corresponding object, which means
that objects can't automatically implement their corresponding trait.

That means any impls that implement a trait for all types that implement
AdderIncr, for example, won't implement that trait for AdderIncr, since
AdderIncr doesn't implement AdderIncr.



On Sat, Oct 19, 2013 at 2:47 AM, Oren Ben-Kiki o...@ben-kiki.org wrote:

 Hmmm That sounds strange. Shouldn't `obj: T` allow me to invoke
 `obj.method_of_T()`?

 For example, how did I manage to invoke the `data.print(...)` method via
 the borrowed `data: PrintWithSpice` pointer? Automatic dereference? And if
 so, why didn't it work for `Writer` as well?

 On Sat, Oct 19, 2013 at 9:29 AM, Steven Fackler sfack...@gmail.comwrote:

 If T is a trait, its trait objects ~T, @T and T do not implement T.
 There is an implementation of Writer for @Writer, but not for ~Writer or
 Writer which is why you're seeing that error.

 Steven Fackler


 On Fri, Oct 18, 2013 at 11:27 PM, Oren Ben-Kiki o...@ben-kiki.orgwrote:

 Ugh, I was too optimistic. Yes, I can write my code using `MyWriter`,
 but I can't cast any @Writer (such as `io::stdout()`) to it. I guess I
 should just use `@Writer` everywhere for now :-(

 This raises the question of how come the compiler is smart enough to
 figure out a `@Writer` has the trait `WriterUtil`, but isn't smart enough
 to figure out a `Writer` has the trait...


 On Sat, Oct 19, 2013 at 9:08 AM, Oren Ben-Kiki o...@ben-kiki.orgwrote:

 I run into the following problem (the code below is a toy example).

 ```
 use std::io::Writer; // Makes no difference if added/removed.

 trait PrintWithSpice {
 fn print(self, writer: Writer, spice: bool);
 }

 struct Bar {
 bar: ~PrintWithSpice,
 }

 impl Bar {
 pub fn print(self, writer: Writer) {
 self.bar.print(writer, false);
 Bar::print_via_borrowed(writer, self.bar);
 }

 fn print_via_borrowed(writer: Writer, data: PrintWithSpice) {
 // Invoking the `print` function via the borrowed pointer to
 the `PrintWithSpice` trait:
 // Works fine, as expected..
 data.print(writer, true);
 }
 }

 struct Foo {
 foo: bool
 }

 impl PrintWithSpice for Foo {
 fn print(self, writer: Writer, spice: bool) {
 // Invoking the `write_str` function via the borrowed pointer
 to the `Writer` trait:
 // error: failed to find an implementation of trait
 std::io::Writer for std::io::Writerno-bounds
 // What is going on?
 writer.write_str(format!(foo: {:b} spice: {:b}, self.foo,
 spice));
 }
 }
 ```

 I didn't understand what the compiler is complaining about. failed to
 find an implementation of Foo for Foono-bounds? A Foo is a Foo, no?
 Calling a function via a borrowed pointer to a trait should just work (it
 does a few lines above).

 After digging I discovered what the compiler really meant (I think).
 The `write_str` method is defined for `WriterUtils` rather than for
 `Writer`. So, if I replace `Writer` by `WriterUtil` in the above code, it
 compiles fine.

 So, I ended up defining `trait MyWriter: Writer + WriterUtil` and I am
 using that instead of `Writer` all over my code. I can see doing that as a
 workaround, but it doesn't smell right to me.

 So:

 * Why is the compiler complaining about not finding an implementation
 for `Writer` when the method I invoke is from `WriterUtil`?

 * Since there is an `implT: Writer for WriterUtil`, shouldn't the
 compiler be sufficiently smart to deduce that the code is valid in the
 1st place?

 * Until the compiler is sufficiently smart (or, if there is a good
 reason why it would never be), shouldn't we rename `Writer` to
 `BasicWriter` and define `trait Writer: BasicWriter, WriterUtil {}` so
 `Writer` would become more usable?



 ___
 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] Unified function/method call syntax and further simplification

2013-10-19 Thread David Piepgrass

  This is meant as a followup to an earlier thread[1] on the subject and
 the
  related ticket[2].
 
  [1]: http://thread.gmane.org/gmane.comp.lang.rust.devel/2622/
  [2]: https://github.com/mozilla/rust/issues/6974
 
  The idea in those earlier discussions is that methods could also be
 called
  using function syntax, supplying `self` as the first argument, so instead
  of `self_arg.method(arg)`, you could write `method(self_arg, arg)`. I'm
  wondering if this could be taken a couple steps further to simplify the
  whole story regarding functions, methods, traits, and impls. The idea is
  that the distiction between functions and methods would be erased almost
  completely, and methods (now being just functions) would be imported
  explicitly.
 
  It would involve the following pieces:
 
   - If the first argument of a top-level `fn` is named `self`, it can be
  called using method syntax. So if you have `fn foo(self: MyType, n: int)
  { .. }` at the top level, you can write `object_of_my_type.foo(123)`. You
  can also still call it using function syntax: `foo(object_of_my_type,
 123)`.
 

 I see no reason for the restriction of self. Why not simply say that any
 function can be called with first_arg.func(...) style ?


D has that rule (which they call UFCS), and I find it confusing
sometimes. When a function is declared with function syntax and it makes
sense or feels right that it should be a function, my mind is not
expecting to see method syntax and I may have trouble figuring out later
what an apparent method call refers to, even if I've seen the function
declaration. Mind you it is worse in D than Rust, because in D, function
declarations can be hidden inside what they call eponymous templates,
which has stumped me in the past.

In any case, wouldn't it help narrow down searches if you could search for
fn foo(self instead of only fn foo? (again though, Rust is not as bad
for searching as the C-family languages that have no fn keyword.) In C#
it's nice that I can find all the so-called extension methods by searching
for (this .
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Unified function/method call syntax and further simplification

2013-10-19 Thread Ziad Hatahet
On Sat, Oct 19, 2013 at 4:35 PM, David Piepgrass qwertie...@gmail.comwrote:

 In C# it's nice that I can find all the so-called extension methods by
 searching for (this .



Aren't `impl`s in Rust somewhat similar to extension methods in C#? For
instance:

trait Doubler {
fn double(self) - Self;
}

impl Doubler for int {
fn double(self) - int { *self * 2 }
}


Then you can call 5.double().


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


[rust-dev] This Week in Rust

2013-10-19 Thread Corey Richardson
Welcome to another issue of *This Week in Rust*, a weekly summary of Rust's
progress and happenings in the community.

# What's cooking in master?

48 PRs were merged this week.

## Breaking changes

- Slices are now represented as [number of elements, not number of
  bytes](https://github.com/mozilla/rust/pull/9885).
- `fmt!` has been [completely
  removed](https://github.com/mozilla/rust/pull/9919).
- Some fields in `std::comm` [have been made
  private](https://github.com/mozilla/rust/pull/9935).
- `std::sys::refcount` [has been
  moved](https://github.com/mozilla/rust/pull/9922) to
  `std::managed::refcount`.
- [A bunch of
  
functions](https://github.com/mozilla/rust/pull/9896/files#diff-69196c6d2488bf8d5b3471084e854407L22)
  have moved from `std::sys` to `std::mem`.
- `once fn` is [now a feature gate](https://github.com/mozilla/rust/pull/9863)
  rather than a `-Z` flag.
- `Path` has been [completely
  rewritten](https://github.com/mozilla/rust/pull/9655).
- `extra::flatpipes` [has been
  removed](https://github.com/mozilla/rust/pull/9886).

## Other changes

- `jemalloc` has been [removed from the
  runtime](https://github.com/mozilla/rust/pull/9933). The [associated
  issue](https://github.com/mozilla/rust/issues/9925) is quite scary.
- `rustdoc` [struct field
  visibility](https://github.com/mozilla/rust/pull/9946) is now corrected (it
  stripped fields where it should not have).
- `rustdoc` also [uses the actual privacy
  rules](https://github.com/mozilla/rust/pull/9941) to strip methods.
- `format!` now gives [much better](https://github.com/mozilla/rust/pull/9932)
  error messages for invalid format strings.
- The `fmt::Default` trait, used for default formatting with `format!`, is
  [now documented](https://github.com/mozilla/rust/pull/9938).
- `include_bin!` has been optimized, and the `k-nucleotides` benchmark now
  compiles [187x faster](https://github.com/mozilla/rust/pull/9851).
- Vectors now have [`starts_with` and `ends_with`
  methods](https://github.com/mozilla/rust/pull/9907), which take slices.
- An `abort` intrinsic [has been
  added](https://github.com/mozilla/rust/pull/9860).
- Vectors now have a [`get_opt`
  method](https://github.com/mozilla/rust/pull/9608).

## New contributors

A new section for new contributors! The new contributors this week are (as
reported by git):

- Chris Sainty
- Eduard Burtescu
- Erik Lyon
- Harry Marr
- Sébastien Chauvel
- Vijay Korapaty
- Ziad Hatahet
- chitra

# Weekly Meeting

The [weekly
meeting](https://github.com/mozilla/rust/wiki/Meeting-weekly-2013-10-15)
discussed removing rusti, changing the attribute syntax, destructors in
statics, and more multi-crate packages with rustpkg.

# Announcements etc

- Rust (and Servo) are participating in the [GNOME Outreach Program for
  Women](https://groups.google.com/forum/#!topic/mozilla.dev.servo/7kX_E0FlfkA).
  A bunch of people have already come into IRC about it.
- http://exercism.io [is getting full Rust
  support](https://github.com/kytrinyx/exercism.io/pull/866). This is a very
  cool resource, and could help a lot getting newcomers acclimated.
- [Unified Function/method Call Syntax and further
  
simplification](https://mail.mozilla.org/pipermail/rust-dev/2013-October/006034.html).
- [Safe Memory Management in
  
Cyclone](http://www.reddit.com/r/rust/comments/1osbq2/safe_manual_memory_management_in_cyclone_research/).
- [Audio](http://opensourcebridge.org/sessions/970) from Tim's talk in June is
  finally available!
- An
  [OSdev](https://github.com/mozilla/rust/wiki/Operating-system-development)
  community has sprung up! The channel is `#rust-osdev`.
- [Should I/O use
  
conditions?](http://www.reddit.com/r/rust/comments/1omw47/should_io_use_conditions/).
- [Pointers in Rust: A
  
Guide](http://www.reddit.com/r/rust/comments/1opo36/pointers_in_rust_a_guide/).
- I am on a [Rust hiatus](http://cmr.github.io/blog/2013/10/14/rust-hiatus/),
  for the time being. TWiR will still be happening, as you are reading it
  right now.
- [rust-core](https://github.com/thestinger/rust-core) - A stub standard
  library.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Unified function/method call syntax and further simplification

2013-10-19 Thread Steven Blenkinsop
On Saturday, October 19, 2013, Ziad Hatahet wrote:

 On Sat, Oct 19, 2013 at 4:35 PM, David Piepgrass 
 qwertie...@gmail.comjavascript:_e({}, 'cvml', 'qwertie...@gmail.com');
  wrote:

 In C# it's nice that I can find all the so-called extension methods by
 searching for (this .



 Aren't `impl`s in Rust somewhat similar to extension methods in C#?


Loosely, if you ignore that each impl overloads an abstract interface
(trait) over the Self type, and that you can constrain a type parameter
based on whether there's an overload of a certain abstract interface for it.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev