Re: [rust-dev] std::num::pow() is inadequate / language concepts

2014-07-25 Thread Marijn Haverbeke
Hello Gregor,

Firstly, blanket statements like "This makes generic programming
impossible" and "it does not allow proper software design" are
unneccesary hyperbole, and do not help the discussion in any way.

Traits provide a more well-defined, easier to reason about alternative
to overloading. They do require the author of an algorithm to decide
ahead of time whether this algorithm needs to be specializeable, which
I guess C++-style overloading does not. Whether that is a good or a
bad thing is debatable, but it is not true that Rust lacks a feature
for specialization.

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


Re: [rust-dev] UTF-8 strings versus "encoded ropes"

2014-05-02 Thread Marijn Haverbeke
On Thu, May 1, 2014 at 10:42 PM, Tony Arcieri  wrote:
> You're wrong.

Though I agree with what you are arguing, starting emails in such a
blunt and dismissive way does not further a pleasant mailing list
climate, and I'd like to ask you to try and be more emphatic in the
future.

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


Re: [rust-dev] NewType change in 0.9

2014-01-11 Thread Marijn Haverbeke
> What does wrapping the 'name' of the variable with it's type on the LHS of
> the : as well as having it on the RHS?

It's a destructuring pattern, extracting the content of the Row/Column
values and binding a variable to it.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Appeal for CORRECT, capable, future-proof math, pre-1.0

2014-01-11 Thread Marijn Haverbeke
I am not aware of an efficient way to provide
automatic-overflow-to-bignum semantics in a non-garbage-collected
language, without also imposing the burden of references/move
semantics/etc on users of small integers. I.e. integers, if they may
hold references to allocated memory can no longer sanely be considered
a simple value type, which doesn't seem like it'd be a good idea for
Rust.

If there is a good solution to this, I'd love to find out about it.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] tutorial (bis)

2013-11-15 Thread Marijn Haverbeke
As the author of the original tutorial I'm interested in what people
hate so much about it. It appears to have slightly bit-rotted, in that
the language moved on and people haphazardly updated stuff here and
there, but the bulk of it still looks coherent. Can I get some
concrete pointers?

On Fri, Nov 15, 2013 at 3:39 PM, Daniel Micay  wrote:
> On Fri, Nov 15, 2013 at 9:33 AM, Gaetan  wrote:
>> after reading this doc, I would love to have:
>> - have a link at the bottom page to the github project
>> - submit one or several pullrequest
>> - doc is magically updated.
>>
>> I'm investigating on this matter to ease documentation. That's is quite
>> interesting, because in my everyday job (I'm a python developer for a
>> buildbot derived project) I'm in a "write tools to ease code documentation
>> and user manual maintainance" mood :)
>
> It gets updated by the doc builder when a pull request is merged. A
> pull request will run through the auto builders before being merged,
> including extracting and testing the samples in the tutorial.
>
> http://buildbot.rust-lang.org/
> http://buildbot.rust-lang.org/bors/bors.html
> ___
> 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] The future of M:N threading

2013-11-14 Thread Marijn Haverbeke
> Unfortunately, instead of actually fixing the underlying problem […] the 
> ECMAScript committee seems to have gone with […] which is lighter syntax but 
> still absurd.

Flaming other languages / committees is very much not the point of
this mailing list. Try to stay on topic and dispassionate.

On Thu, Nov 14, 2013 at 6:23 AM, Bardur Arantsson  wrote:
> On 2013-11-13 21:41, Igor Bukanov wrote:
>> On 13 November 2013 20:41, Bardur Arantsson  wrote:
>>
>>> In practice it's much more difficult to be *explicitly*
>>> async and it should just be delegated to the language/runtime. There are
>>> some things humans just aren't good at.
>>
>> I suspect Rust makes asynchronous programming significantly more
>> bearable. Programming in JS in that style is often painful due to the
>> noise of all those function() { } spread through the code and bugs
>> connected with accessing stuff that should only be ready later. Rust
>> nicely addresses that with shorter syntax for closures/macros and move
>> semantics.
>>
>> So an experiment of writing in asynchronous style in Rust and
>> comparing that with C++/JS/other languages would be very useful to
>> judge.
>>
>
> It's *not* a matter of just making the syntax "lighter". Asynchronous
> callbacks lead to "the pyramid of doom" (as Dave Herman puts it) of
> nested callback functions.
>
> Unfortunately, instead of actually fixing the underlying problem (which
> is the need for an explicit callback model in the first place), the
> ECMAScript committee seems to have gone with
>
>   function foo*(...) {
> yield ;
>   }
>
> which is lighter syntax but still absurd. (To bear fair they also have
> extreme constraints of backward compatibility.)
>
> Python has also (to my great disappointment) gone this route, but there
> you can't even tell "from the outside" if a function is async-safe --
> it's not part of its interface syntactically, but it's of huge
> importance in practice.
>
> My overall point is: Why should the *programmer* be segregating
> functions into asynchronous and synchronous? We have computers and
> compilers which are more than capable than doing this for us at this point!
>
> 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


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

2013-10-20 Thread Marijn Haverbeke
I want to add that we did initially have a scheme where you have to
import every impl you used (not every method), and that this was
abandoned because it was burdensome and, in typical situations,
completely redundant.

Another problem with this proposal seems that it does away with the
possibility of explicitly grouping a bunch of methods that make up the
implementation of an interface. Implementing interfaces go-style, by
just happening to have implemented all the methods that make up the
interface, seems inappropriate for a language where interfaces aren't
structural.

So I very much agree with Patrick. Some aspects of this proposal are
attractive, but it breaks some essential properties of the way methods
currently work (and probably can't be adjusted to work around that
without losing most of it attraction).

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


Re: [rust-dev] RFC: Syntax for "raw" string literals

2013-09-20 Thread Marijn Haverbeke
>> If I need to embed both ''' and """ in a string, I'm out of luck.
>
> The chance of that is as remote as can be. I've never seen or heard of
> it happen. And mind, the issue must happen *in a rawstring* which is
> even more unlikely.

You should note that, as soon as you include something in the language
itself, that creates meaningful strings (programs in the language)
that include the token, which are not likely, at some point, to need
to be written as a multiline string in the language itself.

(As a related example, as someone writing JavaScript-analyzing code in
JavaScript, I've had several bugs caused by the fact that the
nonsense, no-one-is-ever-going-to-use-this word __proto__ has a very
hard to suppress special meaning, and you *are* going to use it when
analyzing the elements in another JavaScript program.)
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Rust compiler bootstrapped

2013-09-10 Thread Marijn Haverbeke
The Rust team is aware of this possibility, and is guarding against it
by keeping a log of checksums and source git revisions for the various
versions of the compiler, so that compilers downloaded from the net
can be checked, and we could, if something dodgy is found, back-track
to a known trusted version of the compiler (or even all the way back
to the OCaml bootstrap compiler, though that'd be a lot of work).

It is theoretically possible that someone manages to sneak in a commit
that adds an exploit to the compiler, but since patches are reviewed,
that is not terribly likely to succeed. Also, Rust is a small target
still, and it would be a marvelous feat of engineering to install a
functioning exploit in a compiler that is being overhauled and changed
all the time.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Order of evaluation of struct initializers

2013-03-12 Thread Marijn Haverbeke
There is code in the compiler explicitly making sure initializers run
in source order, and I expect it will stay that way. So I guess this
should be mentioned in the documentation as being something you can
rely on.

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


Re: [rust-dev] idea for Rust playground - seeking comments

2013-02-01 Thread Marijn Haverbeke
See also http://codemirror.net/mode/rust/ . Unfortunately, the syntax
has changed massively since I wrote that highlighting mode. On the
bright side, I believe the syntax became somewhat more regular, so
(though I'm not sure about this) a lot of the complexity in the
highlighter (and believe me, it is complex) might no longer be needed.

Best,
Marijn

On Fri, Feb 1, 2013 at 10:51 PM, Dean Thompson
 wrote:
> Rust Dev,
>
> Pablo Fernandez and I are planning to build a simple "Rust playground" -- a
> site where people can try running small Rust programs and then record
> examples of working or broken Rust code. We wrote down our current strawman
> approach at https://github.com/rusthub/rustpad . We would greatly value
> feedback from this group before we begin.
>
> Dean
>
> ___
> 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] RFC: All extern "C" functions are unsafe

2012-10-15 Thread Marijn Haverbeke
>
> The question I guess is how often this situation comes up.  Is it just
> libmath? Or is this sort of thing extremely common when doing bindings?
>

Extremely common. I'm somewhat appalled that the blanket 'all C functions
are unsafe' idea is even being considered (and enthusiastically supported).
Yes, C code can segfault and do other nasty things if you call it
incorrectly. But wrapping every call to a C function in an unsafe block
will dilute the 'red flag' role of unsafe blocks to the point of making
them just painful noise, and wrapping the C functions themselves in a
wrapper function to make them safe is, in most cases, a wax nose -- the
wrapper will not be able to guarantee that the call won't go wrong, so no
safety is added.

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


Re: [rust-dev] Why does Rust compile slowly?

2012-10-14 Thread Marijn Haverbeke
Regardless of all that, yes, the Rust compiler *is* slower than the Go
compiler. Not a factor 25, when you make a fair comparison, but still
quite a lot slower.

This has two reasons. Firstly, the Go language has partially been
designed with compiler speed in mind. It is a simple language,
compared to Rust, and thus the compiler simply has to do less work.
Secondly, Rob Pike has probably implemented more compilers than all of
the Rust team combined, so there's the issue of the Rust compiler
simply not being written as cleverly as the Go compiler. This second
factor can, and will, be mitigated in the future as the language
stabilizes and the compiler gets streamlined further. The first issue
means that Rust will probably never compile quite as quickly as Go,
because it trades developer ergonomics for compilation time.

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


Re: [rust-dev] Proposal/request to precede variable binding with "let" in destructuring pattern matching and closures

2012-09-11 Thread Marijn Haverbeke
> Are you saying that struct destructuring also occurs outside of
> match constructs, as a stand-alone assignment statement?

Yes, he is, and that fact is one of the major constraints on what
patterns may look like. The same pattern syntax is used in regular
assignment and alt matching.

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


Re: [rust-dev] passing by mutable ref

2012-05-09 Thread Marijn Haverbeke
I agree that this shouldn't be allowed. A nullary variant name is not an lvalue.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] method calls vs closure calls

2012-05-05 Thread Marijn Haverbeke
How would one take the value of a method? I think Patrick's ->
proposal, or some variation thereof, is preferable, in that it uses
obviously different syntax for the different concepts, and is less
likely to confuse people.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] In favor of types of unknown size

2012-04-27 Thread Marijn Haverbeke
I must say I prefer Graydon's syntax. `[]T` sets off all kinds of
alarms in my head.

I have no strong opinion on dynamically-sized types. Not having them
is definitely a win in terms of compiler complexity, but yes, some of
the things that they make possible are nice to have.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] iter library

2012-04-27 Thread Marijn Haverbeke
> Sorry if I didn't make my purpose clear.  The wrapper type is to distinguish
> the different modes of iteration.

What Joe meant is that you could simply write multiple impls on the
same type with different names for the various modes of iteration.

impl of iter for maptype { ... }
impl iter_keys of iter for maptype { ... }
impl iter_vals of iter for maptype { ... }

You could then do 'import map::iter_keys;` at the top of a block to
force the key-iterating impl to take precedence there.

I think the ergonomics of this kind of trick didn't work out as well
as hoped, though. You'd get multiple applicable impl errors when
importing `map::*`, and seeing which impl is currently closest in a
scope is somewhat indirect and confusing.

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


Re: [rust-dev] proposal for auto-unboxing and impls

2012-04-19 Thread Marijn Haverbeke
How about intermediate half-unboxed types? (If there's an impl for @X,
can you directly call its methods on @@X?)

I was going to implement this, but it somehow slipped through the cracks.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] paring back the self type to be, well, just a type

2012-04-16 Thread Marijn Haverbeke
It's not just monads that require parameterized self types. It comes
up even in something like a generic collection type, if you want to
have a map operator.

I agree that the problems you raised are real, but I think giving up
on the self type this easily would be a shame. It seems that it
wouldn't be hard to take the low-tech approach of simply spitting out
a well-defined error when one of the situations you describe occurs.
Self types are used only as a kind of templates that are filled in
when an impl implements an iface. They don't leak into the type system
in general, as far as I can see (granted, I can't see all that far,
for I am not a type theoretician).

Best,
Marijn

On Fri, Apr 13, 2012 at 12:52 AM, Niko Matsakis  wrote:
> On 4/12/12 2:08 PM, Dave Halperin wrote:
>>
>> I'm not advocating either way on this in terms of the complexity tradeoff
>> for adding a kind system, just pointing out that it's what you'd need to
>> make the current system work and it's not completely crazy to want that
>> flexibility out of the type system.
>
>
> Yes, this was one use case that the self type was intended to model (though
> not the one that I think will come up most often).  I don't think this is
> crazy by any means, but right now our type system has no notion of
> (Haskell-style) kinds and it'd be a big change to add them.
>
> It's possible that the self type should be yanked altogether, but it's come
> in handy for me many times, but always in its simpler incarnation of "the
> type of the receiver" rather than "the type function defined by the current
> iface".
>
> In any case, I spent some time trying to adapt the iface system---in any
> form!---to writing generic monadic code and I decided it's just not a very
> good fit.  There are two major hurdles.
>
> First, we have no good way to define a "return" function (though perhaps we
> could add static or class methods to ifaces).
>
> Second, and this is more major, we define monadic implementations for some
> concrete type and we should be doing it for all types.  In principle,
> something like
>    impl of monad for option { ... }
> seems like it does what we want, but it also permits things like:
>    impl of monad for option { ... }
> for which there is no clear mapping from which to derive the self type.  I
> think to do this correctly, we'd rather write something like:
>    impl of monad for option {  ... }
> which would also fit with the "kind" notion of Haskell: here the type being
> implemented for has kind * => * and so does monad.
>
> Of course, we would also need to be able to write things like:
>    fn mapM(
>        a: [A],
>        b: fn(A) -> M) -> M<[B]> { ... }
> Here the parameter M is bound to some (* => *) type constructor for which
> monad is defined.
>
> I am not opposed to adding such capabilities at some point.  But they don't
> feel like burning issues to me right *now*.
>
>
>
> Niko
> ___
> 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] read file line by line

2012-04-04 Thread Marijn Haverbeke
> Isn't it possible to pass str::trim directly to vec::map? It the indirection 
> through the block really needed?

Currently it is, due to argument modes (map takes a function that
expects its argument by-reference, str::split takes it by value).
We're hopeful that we've found a way to get rid of this restriction,
once the region work is more complete, but it might take a while
before all that is implemented.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] building on SunOS, regex

2012-04-01 Thread Marijn Haverbeke
> 'do' is the German abbreviation.

Dutch, too. I guess my brain momentarily flipped back to my native
language when typing out these abbreviations. Thanks for fixing that.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Update: break/cont/ret in blocks

2012-03-28 Thread Marijn Haverbeke
> Yes, I think vec::iter() should be removed eventually.

Say you happen to have a top-level function that you want to apply to
all elements in a vector. It doesn't return bool, so vec::each can't
be applied to it. vec::iter is useful there.

Though maybe this could be some adaptor function built on top of the
iter library instead, so that we only have to write it once, rather
than for every iterable type.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Update: break/cont/ret in blocks

2012-03-28 Thread Marijn Haverbeke
> True.  But it's not clear to me why you would use vec::all() for the loop
> function unless you wanted to know whether you broke out of the loop or not
> (in other words, if you don't want to see the result, don't use vec::all()).

Sure. But now we have three variants for almost the same thing --
`vec::iter` to iterate without breaking, `vec::each` to be able to
break but not return a result, and `vec::all` to get a result value.
This seems excessive.

Anyway, the current implementation does what you wanted, and I'm not
about to change it, so rest easy.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Update: break/cont/ret in blocks

2012-03-27 Thread Marijn Haverbeke
> One question: does the for loop generate
> a return value?  Is it just whatever the function itself returns?

Correct. I'm not 100% sure this is desirable yet -- it's more
flexible, which is good, but it also means that if you, for example,
use vec::all as your iterator, you'll need a semicolon after the loop,
or you get a type error.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Update: break/cont/ret in blocks

2012-03-27 Thread Marijn Haverbeke
Hi list,

I've pushed a series of patches that implement an alternate `for` loop
syntax -- when the `for` keyword is followed by a block-style call
({||}-block as last argument, outside the parentheses), the block is
treated specially: it must return (), but the function argument that
it is passed to must be a function type that returns bool. The idea is
that this is used to call iterators that stop iterating when their
block returns false. An implicit return value of true will be wired
into the block, and any instances of `cont` will make the block return
true, break will make the block return false. See [1] for some
test/example code.

I've added vec::each, str::each, and list::each functions for use with
this construct. They are expected to be replaced by something more
refined (the iter library, probably) down the line.

When the block in a `for` loop like this contains a `ret` statement
(which are now disallowed in regular blocks), it will cause a return
from the outer function. It does this by closing over its parent's
return pointer and a flag that it sets when returning, which the outer
function checks when the call returns. All this only happens when an
actual return is present, so you don't pay for it when you don't use
it.

I've replaced a big chunk of the for loops in the codebase with `for
vec::each(v) {|elt| ... }` constructs. This produced a small slowdown
in our cycle times (a little over 1%), which is expected, since more
inlining and optimization will be needed on the side of LLVM to pummel
these into tight loops. Small benchmarks show that the performance of
these new-style for loops in the same ballpark, but not the same as,
the performance of the primitive for construct (~30% slower for tight,
long loops). I expect we'll be able to squeeze out a bit more by
making vec::each more optimizable.

This was all more or less foreshadowed in the discussion of bug #1619
[2], but (as usual) I took some liberty in the implementation. Comment
here if you feel something should be done differently. If there are no
serious objections, I'd like to remove support for the old for syntax
soon.

[1]: 
https://github.com/mozilla/rust/blob/master/src/test/run-pass/ret-break-cont-in-block.rs
[2]: https://github.com/mozilla/rust/issues/1619

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


Re: [rust-dev] Return in block functions

2012-03-27 Thread Marijn Haverbeke
See issue [1] for some discussion. The reason was that A) people are
bound to expect ret to return from the outer function, which we don't
support in most cases, and B) I am in the process of adding a case
(for loops on top of blocks) where we *do* support returning out of
the outer function from a block, and treating ret differently in
different kinds of blocks seems like a bad idea.

When going over the existing code that was using ret in blocks, I did
find two cases that had to be transformed with a big, right-drifting
if, but the rest were loops that would have benefited from proper
ret/cont/break support. So yeah, it's not all roses, but I'd argue
that huge blocks aren't very good style, and they might benefit from
being factored into a few top-level functions.

[1]: https://github.com/mozilla/rust/issues/1619

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


Re: [rust-dev] ACL proposal

2012-03-20 Thread Marijn Haverbeke
Looks good on the whole. I guess there'll also be a way to change the
default visibility per-module? It might become tedious, when exporting
a bunch of things to a specific submodule, to repeat the path for
every item.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] LLVM-MC PE/COFF overflow bug (was Re: Some reductions)

2012-03-15 Thread Marijn Haverbeke
I can't thank you enough, Graydon! This would have taken me at least a
week to figure out.

I'm about to land the full monomorphization code, and finally get rid
of the daily ritual of merging my hugely invasive branch with changes
to master.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Some reductions

2012-03-13 Thread Marijn Haverbeke
Hi Graydon,

Thanks for digging into this so deeply. This probably also explains
why the non-optimized build currently fails on Windows (#959) -- it
simply generates binaries that are too big.

The prospects are looking a little bleak, I guess. Debugging linkers
sounds like it'll get hairy.

Maybe, as a temporary workaround, we could try finally splitting off
the syntax/ part of rustc into its own crate?

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


Re: [rust-dev] a proposal for break, ret, and cont

2012-02-29 Thread Marijn Haverbeke
I was actually thinking there wouldn't have to be a special may_return
type at all. The returned value can be an option, and return can store
to that and then break. Code after the call to the iterator then
checks for a `some` value in the return slot and, if found, returns
it.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] datetime module and some questions

2012-02-21 Thread Marijn Haverbeke
> Just to be clear, do you mean a function outside the iface and impl?

Yes, that's what I meant.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] datetime module and some questions

2012-02-21 Thread Marijn Haverbeke
> It wasn't the cast that felt funny to me, it was the role of 0_u32 in the 
> expression.  Its only purpose is to give access to the date impl over u32 
> which is ok, but I'm used to having something like class methods for that.

Right. As I said, just use constructor functions with different names.
We may end up supporting this directly in our class system at some
point, but that seems an easy enough workaround.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] datetime module and some questions

2012-02-21 Thread Marijn Haverbeke
> let d = (0_u32 as date).from_str("2001-04-01");

There's no reason to cast to an iface just to call a method on a
value. 0_u32.from_str("...") should be equivalent.

If you want to have different from_str constructor functions, though,
just give them different names instead of using a kludge like this.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] type holes and identifying immutable memory

2012-02-11 Thread Marijn Haverbeke
I feel that I simply don't have the type-theoretic background to say
anything definite about this. I'm going to change my stance from
'grumbling darkly in the background' to 'I guess you guys know what
you're doing, I'm not objecting'...

> hopefully today I can come back with some data about how disruptive this is 
> to the existing codebase.

Right. This is important. If a change end up introducing a lot of
awfulness in existing code, that should be a reason to re-think it.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] RFC: Addressing Dan's bug through immutable memory

2012-02-08 Thread Marijn Haverbeke
> C++ has the same restriction. In practice I've found that it rarely comes
> up.

Obviously, since const field are rare in C. In Rust, one rarely uses a
record type that doesn't have immutable fields.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] RFC: Addressing Dan's bug through immutable memory

2012-02-08 Thread Marijn Haverbeke
> Yes. What would be legal would be:
>
>    let x = @{a: 10};
>    x = @{a: 20};

That seems a rather heavy-handed restriction.

> No, it is legal to do `f(foo.x)` but, depending on the type of `foo.x`,
> `f()` might be restricted in what it can do with the reference.  For
> example:

How about this:

let x = @{mutable y: 10};
let f = fn@(u: int) { x.y = 20; log(error, u); }
f(x.y); // Where f's arg is passed by reference, whichever
notation you'd use for that
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] RFC: Addressing Dan's bug through immutable memory

2012-02-08 Thread Marijn Haverbeke
Help me understand -- does this mean 'let x = {a: 10}; x = {a: 20};'
would be illegal (assigning to non-assignable type)?

Also, you only mention pattern matching, but function calls also
create references to the arguments. Would it be forbidden to do
f(foo.x) where x is a mutable field?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] bind syntax change proposal

2012-02-04 Thread Marijn Haverbeke
First, I like this a lot. I think applying it to operators as well is
definitely a good thing. I don't feel strongly about these closures
needing to copy the bound values. If you consider them a syntax for
currying, one would expect them to copy, but you could also look at
them as a shorthand for block/lambda syntax, in which case not copying
makes perfect sense. The difference might be moot, actually, since fn@
will copy anyway, and blocks don't escape the call that uses them
mutation of the closed over variables will rarely be an issue.

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


Re: [rust-dev] libuv updated

2012-02-02 Thread Marijn Haverbeke
>> cd src/libuv && git checkout master && git pull --rebase

Thanks! You saved me at least ten minutes of confused stumbling.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: rename sequence concatenation operator to ++

2012-01-26 Thread Marijn Haverbeke
You're right that the impls can be static, in which case interfaces
don't enter into it. Also, method names can overlap in Rust (unlike in
Haskell) without causing conflicts. So I guess this is not a direct
issue. And yes, I do intend to implement support for super-interfaces,
they seem to be useful in a lot of situations.

Given all that, I'd still like to rename the vector append operator. I
think it'd be an improvement in readability.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] A couple of tweaks to make typeclasses easier?

2012-01-25 Thread Marijn Haverbeke
> (1) Typeclass imports become "import impl". So you'd write "import impl
> driver::diagnostic::handler" where you'd write "import
> driver::diagnostic::handler" today. This way, when you look at a method call
> and you don't know where it's coming from, you just grep for "import impl"
> and look at all the implementations in scope.

It can often be pleasant to have impls included in a * import (but
then, it is also occasionally not what you want). Similarly, it is
currently very convenient to name a type and an impl with the same
name, so that importing it gets you both the type and its methods.
Maybe we can somehow tweak the syntax to also allow a form that
imports both impls and other things?

> (2) Change method calls to '->', like C++, Perl, and PHP. That operator is
> free and it has precedent. And getting away from overloading the dot worked
> well when we changed module access from '.' to '::'.

I considered this when I did the first implementation. I figured that
simply giving record field access precedence was good enough, but the
readability argument is valid.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: rename sequence concatenation operator to ++

2012-01-25 Thread Marijn Haverbeke
> What about an add interface?

That works, but doesn't provide the conceptual simplicity of a number
interface, and if you want to write a generic over any numeric type,
it could end up taking a  type parameter.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Proposal: rename sequence concatenation operator to ++

2012-01-25 Thread Marijn Haverbeke
Currently it is simply '+'.

The thing that prompted this is issue #1520 -- operator overloading.
Delegating + on non-builtin-numeric types to a `num` interface that
implements methods add/sub/mult/div/rem/neg methods seems elegant, and
similar to Haskell's approach. Vector-concatenation + messes
everything up though, since vectors can't meaningfully implement the
full num interface.

In general, it seems preferable to have operators mean a single thing.
The code in the compiler that handles + is often quite clumsy,
precisely because two very different things have to be dealt with.

I briefly floated the idea on IRC to just get rid of a concat binop
altogether, and use library calls for this, but it seems people like
their concatenating operator, so ++ seems a good choice (it has
something of a precedent in Haskells list append operator).

Those who oppose, start arguing.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] The obj system is no more

2012-01-13 Thread Marijn Haverbeke
So I've always had a difficult relationship with the obj system, or
rather its implementation. I couldn't help grinding my teeth every
time I ran into a special case for obj values in the trans pass or had
to scroll past some long, ugly block of code for the
ast::expr_anon_obj case in some code. Now that we have a viable
alternative to objs, and no one objected to removing them, I jumped at
the chance and converted all uses of objs to some other approach --
and finally, earlier today, removed support for the obj system from
the compiler completely.

May it rest in peace.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] tutorial on interfaces: bounded type parameters

2012-01-12 Thread Marijn Haverbeke
> Note the phrase "aren't known at compile time." That reads as if bounded types
> offer runtime polymorphism. (They don't, do they?)

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


Re: [rust-dev] CSV implementation

2012-01-10 Thread Marijn Haverbeke
> I can understand the need for an implicit copy when I pass 'x' to
> str::from_chars. However, in the 'inquote' alt branch the copy seems to be
> triggered by the access to 'st.quote'.

This has to do with the reference safety checker. As soon as you refer
to `st` again the checker can no longer guarantee that the `x`
reference, which points at a mutable field of `st`, is still live. If
you flip the statements around so that `x` is not used after `st`, the
warning (and the copy) will go away.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Interfaces!

2012-01-05 Thread Marijn Haverbeke
> |// This implements an interface `iter_util` for vector types

Ah, I see what you mean now. I've updated the wiki page.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Interfaces!

2012-01-05 Thread Marijn Haverbeke
> If I write "impl foo for bar" does that define an impl
> named `foo` with no interface, or an impl of the interface `foo`?

No interface.

> In that case, I write "impl of foo for bar" to get an impl of
> the interface `foo` named `foo` for the type `bar`?

Correct. How is this inconsistent? There's an optional `of` clause to
specify the interface. As an abbreviation, you can leave off the
proper name when you want to use the name of the interface (and you
specified one).
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Interfaces!

2012-01-05 Thread Marijn Haverbeke
Interfaces and implementations are mostly working now. They aren't
snapshotted yet, and there are some details such as binding methods
that don't work yet, but there should be enough implemented to play
with. Please file any bugs that you find in this, and assign them to
me.

A description of the syntax and semantics can be found at
https://github.com/graydon/rust/wiki/Interfaces

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


Re: [rust-dev] Documentation

2012-01-04 Thread Marijn Haverbeke
I agree with what Matt suggested on IRC -- that non-HTML docs mostly
don't matter anymore.

Markdown's syntax rules are an abomination, but in practice their
poorly thought-out corner cases don't really get in the way much. It
has 'won' as far as HTML-near markup languages go, and almost every
programmer is fluent in it.

>  - A tutorial written in hand-extended markdown and processed
>   by hand-written javascript

The tutorial is actually standard markdown, with the addition of using
the definition list extension (which is supported by most parsers),
and doing some post-processing on code blocks to syntax-highlight them
and to remove some magic directives to make it possible to execute
them (thus making it easy to keep it in sync with the actual
compiler). This code post-processing is completely orthogonal to the
markup format we use -- something like it would have to happen in
texinfo as well. (The choice of JS for the rendering script was
prompted by the fact that we already have a very good Rust highlighter
in JS -- the CodeMirror mode I wrote).

Integrating markdown in rustdoc seems like a very good idea. In
general, my vote is for more markdown.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] syntactic sugar for blocks in expressions

2012-01-02 Thread Marijn Haverbeke
My first reaction is 'oh god no! that complicates the rules even
more!'. But then I remembered how frustrating it is to work out a
proposal and have it shot down for vague knee-jerk reasons like that.
So, eh, let's just try this for a while and see whether it causes more
confusion than the rules we have now.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] unicode support and core

2011-12-23 Thread Marijn Haverbeke
> I'm also curious what people think are "the important parts" of unicode.

Character classification is very important, and should be in core I
think (if only to encourage people to actually use it instead of
rolling their own... badly).

Encodings are something people will occasionally need, but a much less
important thing. This doesn't have to be in core, I think. (And, if I
understand correctly, much of libicu is encoding tables.)
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] minor things that annoy you about Rust?

2011-12-23 Thread Marijn Haverbeke
> Yeah. One thing that concerns me about that is that it means we lose the
> ability to write rebind-the-variable functional-style code:

Oh. You'd make this apply to irrevocable patterns as well? Or do you
intend to get rid of the restriction that let patterns are
irrevocable?

In the second case, I think I'd prefer a 'you can shadow anything,
except consts and tag variants' rule to a blanket 'no shadowing' one.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] names needed for function types

2011-12-23 Thread Marijn Haverbeke
> I wasn't saying the implementation sounded freaky.  I was just imagining
> looking at a 30,000 line Rust source file with large fn definitions and
> trying to figure out whether each one is a block with interesting side
> effects through the mutable closure or not.

They don't become closures. They just can be passed to functions that
expect closures.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] names needed for function types

2011-12-23 Thread Marijn Haverbeke
> The idea that a fn (no closure) could implicitly turn into a block (mutable
> closure) seemed freaky when I read the tutorial.

There is no actual allocation going on -- the function pointer is
paired with a null environment pointer, and that's the closure. You
pay nothing, and since a (non-closing) fn can't do anything that a
closure couldn't do, I'm not sure why you'd call this freaky.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] minor things that annoy you about Rust?

2011-12-23 Thread Marijn Haverbeke
> Marijn's note on the wiki[1] about this says he is not a fan. Is this still
> true? Is the opposition strong or weak?

I'm still not optimistic. I think we'll want to extend pattern
matching to also handle matching against constants and maybe even
local variables. So probably the rule would end up being that you
can't shadow something with a pattern binding. I'm okay with trying
that and seeing how it works out, but I *am* worried that it'd
introduce a new problem -- the set of names that you can bind will be
much reduced, and adding something somewhere up the scope chain will
invalidate code further down.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Fwd: minor things that annoy you about Rust?

2011-12-22 Thread Marijn Haverbeke
> and there'll always be that one jerk on your team who runs their literals 
> together without the separator.

*raises hand*

But seriously, I think that if our approach to type inference
supported it, inferring the type of literals (with warning for
overflows) would be great. But it doesn't -- or rather, it doesn't to
the extend where the result would be pleasant to program with -- so
I'm okay with just living with the suffixes.

I do prefer 'u8' to 'b' (or similar), simply because it's easier to remember.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] minor things that annoy you about Rust?

2011-12-22 Thread Marijn Haverbeke
Here's another one: The fact that, when changing a tag variant, you
have to update every single place that matches against it. We might
want to revisit the idea of named variant args, that you match by
name, so that A) you can leave off all the '_' placeholders, and B)
you only need to update your patterns when the actual fields you're
interested in change.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] minor things that annoy you about Rust?

2011-12-21 Thread Marijn Haverbeke
> 4. Lack of break, continue, and labels.  I know this is a big one but some 
> loops are difficult to write without. Anything
>   more than what is there today will be much apreciated.

'break' and 'cont' exist (though without labels, and not able to break
out of a block function).
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Proposal: different alt form flavours

2011-12-21 Thread Marijn Haverbeke
This was prompted by the 'minor annoyances thread'. A big annoyance
for me is the recurring `_ {}` at the end of alt patterns that fall
through. A worse form is `_ { fail "this is a bug"; }` (alt already
fails when not matching, with a line number reference to the alt that
blew up, so this kind of `fail` statements mostly just muddle up the
code).

Instead, I propose:

// This one falls through without failing
alt myoption pass {
   some(x) { do_something_with(x); }
}
// This one explicitly says that is is non-exhaustive, and that
// it will fail for bad input
alt myoption fail {
   some(x) { ... }
}

Normal alt would be required to be exhaustive, and give a compile-time
error if it isn't. This is more self-documenting (you're explicitly
annotating what you're trying to do when writing a non-exhaustive
alt), and somewhat more succinct.

I'm not terribly attached to those keywords (`pass` and `fail`), would
happily hear alternatives.

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


Re: [rust-dev] minor things that annoy you about Rust?

2011-12-21 Thread Marijn Haverbeke
> Sorry, I meant wildcard bindings at the top level of a match only.

We've been thinking down the road of making binders at the top of a
pattern special a few times, but as you say, that'd cause
inconsistency and probably make things even more confusing than they
are now.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] minor things that annoy you about Rust?

2011-12-21 Thread Marijn Haverbeke
> 1000-page error messages.

These should be solved now. If you're still seeing them, submit a bug
with the code that triggers one.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] minor things that annoy you about Rust?

2011-12-21 Thread Marijn Haverbeke
> 2. The dot after the nullary tag. In general I want to write a nullary tag a 
> LOT
> more often than I want to write a wildcard binder, so I feel like this is the
> wrong way for this choice to go, but I'll understand if this is a decided 
> issue
> already.

I agree the dot is problematic, but I'm *very* skeptical about your
assertion that you're writing more nullary tag patterns than binders.
At least in the compiler, I think we see at least ten times more
binders than nullary tags.

> 4. I wish a lot more of the standard library was object-oriented. I realize 
> this
> is somewhat of a slippery slope, but writing 'vec::len(thing)' is less nice 
> (to
> me) than thing.len(). I think that things in the standard library that are
> object-like (vec, str, ...) should be objects.

This is part of the reason we're implementing interfaces (type classes).

> 5. I do not like the mk_foo()/obj foo {} idiom; it forces code another tabstop
> to the right.

If interfaces work out, they'll probably replace the current obj system.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] runtime libraries and stage1

2011-12-14 Thread Marijn Haverbeke
What I've been doing for difficult snapshots is to temporarily modify
the makefiles to do the thing  Niko describes (use stdlib and runtime
from snapshot for stage1), building the snapshot, and then reverting
the changes to the makefile again. It would be nice if this was
something that could be simply turned on and off with a single switch
somewhere, but my Makefile-fu wasn't strong enough to actually
implement it that way.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Emacs rust-mode updated

2011-12-09 Thread Marijn Haverbeke
It now handles blocks better, and should no longer get confused about
objects so easily. Get it from https://github.com/marijnh/rust-mode

(Don't forget to byte-compile it!)
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Semantics/tutorial feedback

2011-12-09 Thread Marijn Haverbeke
Ah, I should have clarified. 'none' refers to the std::option type,
which is defined as `tag option { none; some(T); }`.

> let x = MyContainer();
> x.insert(3); // now infer that x is really a MyContainer
>
> How would the compiler infer that?

Well, you can't write  there, but you can leave off the <>
part, and the type parameter will be unified with the type of the 3,
and things will Just Work.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Semantics/tutorial feedback

2011-12-09 Thread Marijn Haverbeke
> 1. Supporting the ternary operator "?:" when "if" is already an
> expression seems redundant.

As a compulsive code golfer, I'm kind of attached to ?: -- but the
point about the '?' and ':' symbols being useful for other things is
very valid (we're definitely running out glyphs).

> 2. Inferring the type of 'x' in "let x = []" is neat, but is this type
> of inference a privilege restricted to the builtin types?

No. 'let x = none;' also works (and none is defined as a regular sum
type in the stdlib).

> 3. The subject says semantics but this is really a syntax objection. I
> think "3 as float" will ultimately be a language wart

Good call. I've been noticing this too -- there are a bunch of special
cases in the parser and pretty-printer to work around this. Added to
that, the low precedence on 'as' keeps surprising me. I'd be okay with
using a different syntax -- though as(3) seems overly ugly.

> 4. target_os and similar attributes may seem convenient but I suspect
> will have Rust biting off more than it can chew. What version of win32
> does target_os="win32" mean?

It is possible for users to define and check against their own flags.
I think there is no harm in providing some basic ones in the compiler.

> 7. Not sure if this is intentional or an oversight: but it looks like
> there's no way to extend a polymorphic data type while maintaining
> independent compilation.

We're trying to avoid subtyping. We're working on something akin to
type classes, which might address your point here.

> 8. Having a 'cycle collector' for shared box types seems as bad as
> having a garbage collector.

I don't know the details of our cycle collector, but I think we can
statically determine which types *might* contain cycles, and only run
it on those. Most programs won't have any cyclic types in them.

> 9. I'm curious as to the justification for making log a builtin
> keyword rather than a builtin library.

There are plans to add some reflection features that would make it
possible to implement log in the stdlib (and allow people to implement
and use alternatives).

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


Re: [rust-dev] A proposal: No implicit copies

2011-12-07 Thread Marijn Haverbeke
Looks good.

I'd like to include immutable records of implicitly copyable types as
implicitly copyable.

> The primary use case for move mode arguments was to “give away” a unique 
> pointer: this is now achieved by having the callee simply declare a parameter 
> of unique type and having the caller move it to them.

When doing channel communication or data-structure construction,
there'll probably be a lot of calls that are 'giving away' arguments.
I fear that requiring callers to annotate every one of them will be
cumbersome. How about changing the semantics of by-move and by-copy
parameters to simply automatically insert the copy/move annotation
into every call?

When exactly would you want to have functions with a
non-single-word-sized return value not be constructor functions? I
still feel we'd be better off trying to make this implicit and not
exposing it to the user.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] do we need lambda?

2011-12-05 Thread Marijn Haverbeke
If bind is staying (there was talk of removing it in favour of lambda
at some point), I think we can do without lambda. But the concept of
shared closures (which is what bind creates) would still be there.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] criteria for core lib

2011-12-04 Thread Marijn Haverbeke
> Actually, now that I stare at it, the no-inlining issue might make the
> core/std split a pretty bad idea at this point.

When platform limitations stand in the way of proper software design,
I think we should be working on circumventing them. Telling people to
write monolithic libraries because the linker model penalizes a more
modular approach seems very unfortunate.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] criteria for core lib

2011-12-02 Thread Marijn Haverbeke
I agree with your categorization of what should be in core. I'd split
the stdlib into different crates though -- most programs don't need
json/rope/treemap/etc . We could put them in a standard distribution,
as separate crates, or when the package manager is functional, simply
rely on that for providing them.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Interface / typeclass proposal

2011-12-01 Thread Marijn Haverbeke
> Do you feel (straw-vote) like  you'd be sufficiently happy to be able to
> override the former group but not the latter?

Definitely.

> (Also: please say you've no interest in permitting user-defined
> operator-symbols with their own associativity and precedence. Right?)

This is from my xmonad config:

composeOne [ isDialog -?> manageHook defaultConfig,
   isKDETrayWindow -?> manageHook defaultConfig,
   return True -?>  insertPosition End
Newer <+> manageHook defaultConfig ]

It seems to work, but I still don't really understand what it says.
Let's not go there in Rust.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Interface / typeclass proposal

2011-11-30 Thread Marijn Haverbeke
https://github.com/graydon/rust/wiki/Interface-and-Implementation-Proposal
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Interface / typeclass proposal

2011-11-30 Thread Marijn Haverbeke
I agree with Graydon that there's probably not much to be gained from
overriding copy and send. I think they should look and act like
interfaces when specified as type parameter bounds, but the actual
implementations should be automatically derived by the compiler (as
they are now).

For operator overloading, I disagree -- I think we'll definitely want
that to implement decent bignum, complex number, or (mathematical)
vector types. Yes, people can go crazy and do dumb things with
overloaded operators, but people can do dumb things with just about
any feature you give them. A pragma to turn it off is probably an easy
thing to support.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Interface / typeclass proposal

2011-11-28 Thread Marijn Haverbeke
> there's no way to declare that it does without changing the third-party 
>library's code

This is true in classical sealed classes, but not in open typeclasses.
You can always declare an implementation of an interface for a
3rd-party datatype in your own module, or in the module that declares
the interface.

If there really is no connection between the interface and the methods
that a module happens to implement, the chance that they will
coincidentally match and implement the same protocol is very small
anyway. A wrapper/adapter impl is extremely trivial to write.

I'm still skeptical about monomorphizing all bounded generics. Might
work out, but it'll require an overhaul of the compiler and some
extensive measurement (for unintended bloat). The first version of
this should probably do vtable-passing.

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


Re: [rust-dev] Interface / typeclass proposal

2011-11-28 Thread Marijn Haverbeke
Hi Niko,

Actually, after I sent this off I realized "... but I didn't really
make any good points in favour of nominal interfaces at all".

I prefer them because they enforce a much more structured way of
thinking. Declaring grab-bags of methods and assembling them into
interfaces ad-hoc seems clumsy and, as you mention, error prone ---
just because a method has a given name, doesn't mean it actually does
the same thing as other methods by that name. Explicitly declaring
what interface you're implementing would remove this vagueness.

It also makes generating and reusing vtables easier -- most of them
would only have to be generated once, and can be exported from the
module that declares the category. Once we have categories / instances
that depend on another type conforming to an interface, those'll have
to be parameterized by the other type's vtable, so things get more
tricky (much like our current dynamic tydescs).

> - I don't see why every category must declare an associated interface.  I
> like the idea of *allowing* categories to declare associated interfaces, as
> it will lead to better error reporting, but I think *requiring* it is too
> much.  It implies that the main purpose of a category is dynamic dispatch
> and I am not sure that will be the case.

I don't really see explicitly declared interfaces as having a lot,
specifically, to do with dynamic dispatch.

I you're right guess ad-hoc category declarations can be nice
sometimes, especially since they allow post-hoc interop with code that
wasn't written with any kind of interface in mind. But the latter can
already be done by, once you've defined your interface, simply
declaring an instance that calls the existing methods.

Would you be satisfied with ad-hoc, interface-less methods that can
only be called statically?

> - I think the term instance ought to be reserved for runtime values

You're probably right. But I'm not sure 'category' is much more
helpful here. Maybe 'implementation'? (`impl`)

> I am a bit
> concerned about the definition of comparison and equality because they
> really want to have two receiver types.

Our == requires both operands to be of the same type. It seems all
sane equality implementation have that property.

However, there are two receive values, and we definitely don't want to
end up writing foo.==(bar) or something awful like that. There are
several ways to get around this by doing some
surface-syntax-shuffling. But I think eventually we'll want to support
both oo-method-style interfaces (written val.method(), used when there
is clearly a single receiver), and functional-style interfaces
(written method(arg, arg2), used when this is not the case). The
resolution for the second type is actually easier to do. x == y could
desugar to std::cmp::eq(x, y), or we could define some correspondence
between infix ops and function names (which would remove the need for
things like std::int::add and std::str::eq) the way Haskell does it.

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


Re: [rust-dev] Interface / typeclass proposal

2011-11-28 Thread Marijn Haverbeke
Hi David,

> What would you do with multiple instance declarations that differ by 
> specificity? For example, one declared on [int] and one declared on [T].

Eventually, we'll have to specify a scoring scheme. The closest import
always wins, so you can disambiguate explicitly. If you have multiple
interface implementations imported at the same level, I'd make that an
error in the first version of this system, but I agree that eventually
we'll want specificity rules.

> This comes down to the different implementation approaches polymorphism. 
> Monomorphizing is rare in the ML/Haskell tradition, so type classes with 
> dictionary-passing is a nice fit. But it's not as clear what happens to type 
> classes when you introduce specialization.

Monomorphizing generics that take interfaces sounds wrong. It is
probably a win in some situations, and heuristics can be found to
detect such situations, but I doubt we'll want to do in general.

(What happens seems quite clear though -- you compile a version of the
function with the vtable known at compile-time, so all dispatch
becomes static.)

> Overloaded arithmetic is definitely a pleasant aspect of Haskell's type 
> classes. But they do exploit type inference pretty heavily. For example, 
> literals have polymorphic types, and expressions can be given different types 
> based on the expected type of their context. Have you thought about how this 
> would look in our system, where inference is more limited?

If we stick to our current approach (literals have unambiguous types,
binops always act on values of the same type), the only new subtlety
is that the type checker has to figure out the return type of a
method. I think this can be done early enough, but I'm not deeply
familiar with our type checker, so I'd have to try and see.

> For example, how do we prevent programmers from declaring some things to be 
> instances of `send` that aren't supposed to be?

For `copy`, this is easy -- your `copy` method does a copy, and the
compiler has the full type of the arguments when compiling the method
body, so it checks, and complains when you implement a copy method on
an invalid type. We'll have to introduce some explicit way of checking
whether a type is sendable to do the same for `send`.

We'll probably have to wire in automatic 'derived'
instances/categories for this to be pleasant though, or you'll be
forced to implement your own instances for every tag you declare. Or
maybe `copy` and `send` will just look and behave like interfaces on
the surface, and in fact refer to some built-in magic interface that
the compiler handles specially.

> And IINM, there are still blockers that are well-established and fundamental, 
> like stack growth and x64, no?

Right, but those have very competent people working on them already
(and are progressing really well).

Actually, I agree that this isn't something that has any bearing on a
first release. Coming up with new neat requirements at the last moment
is a sure way to make that release be delayed. But at least having a
proposal to point people to when they ask about support for dynamic
dispatch would be a plus.

(And yes, this will end up on the wiki, but I find that initial
discussion is better done in the mailing list.)
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Interface / typeclass proposal

2011-11-25 Thread Marijn Haverbeke
Niko proposed categories [1] two weeks ago. I'm happy that we're
looking in this direction. Niko's proposal makes interfaces
structural. I'm going to argue that nominal interfaces have advantages
both in programmer ergonomics and in compilation-model complexity.

[1]: https://mail.mozilla.org/pipermail/rust-dev/2011-November/000941.html

I'll be sticking rather closely to Haskell's type class system, which
has proven itself in practice. If you aren't already enthusiastic
about Haskell's type classes, I recommend watching Simon Peyton Jones'
talk about them [2]. He goes over the way type classes can be
implemented, and shows a number of really cool applications.

[2]: 
http://channel9.msdn.com/posts/MDCC-TechTalk-Classes-Jim-but-not-as-we-know-them
(try to skip the first 3 minutes, they might spoil your appetite)

Context: I'd like to implement some minimum viable dynamic dispatch
system and get rid of our `obj` implementation before the first public
release. Something that can be extended later with classes and traits,
but for now just allows us to define vtables that accompany types.

To recap, Niko's categories look like this:

category vec_seq([T]) {
  fn len() -> uint { vec::len(self) }
  fn iter(f: block(T)) { for elt in self { f(elt); } }
}

Having that, you can do

import vec::vec_seq;
assert [1].len() == 1u;
[1, 2, 3].iter({|i| log i; })

Which is statically resolved. Dynamic dispatch (if I understand
correctly), would look like this:

type iterable = iface { fn iter(block(T)); };
fn append_to_vec(x: iterable, y: itable) -> [T] {
let r = [];
x.iter {|e| r += [e];}
y.iter {|e| r += [e];}
r
}
// Assuming there exists a category for lists that implements iter
append_to_vec([1, 2, 3] as iterable, list::cons(4, list::nil) as iterable)

That causes the compiler to create two vtables, both containing an
`iter` method, and wrap the arguments in {vtable, @value} structures
when they are cast to `iterable` (they'll probably have to be boxed to
make sure the size of such a value is uniform, and cleanup is
straightforward).

Alternatively, my proposal looks like this: interfaces could be fixed
groups of methods, that are always implemented all at once.

// Define an interface called `seq`
interface seq {
fn len() -> uint;
fn iter(f: block(T));
}
// Declare [T] to be an instance of seq
instance [T] seq {
fn len() -> uint { vec::len(self) }
fn iter(f: block(T)) { for elt in self { f(elt); } }
}

The static way to use this would look the same as above. If you've
imported `vec::seq` (std::vec's implementation of seq), you can simply
say [1].len(). If there is any instance in scope that applies to type
[int] and has a method `len`, that instance's implementation is
called. If multiple interfaces are found, the one in the closes scope
is chosen. If they are in the same scope, or no interface is found,
you get a compiler error.

Dynamic dispatch works differently.

// Declare T to be an instance of the seq interface
fn total_len(seqs: [T]) -> uint {
let cnt = 0u;
for s in seqs { count += s.len(); }
count
}

In this proposal, the seq vtable is not something that get attached to
the value by casting it to an interface, but rather acts as an
implicit parameter to the function. The cool thing is that we already
have these implicit parameters -- they map very closely to our type
descriptors, which we are implicitly passing to generics. What would
happen, for such a call, is that the compiler notices that the type
parameter has an interface bound, so that instead of passing just a
tydesc, it passes both a tydesc and the `seq` vtable that belongs to
that type. Inside the function, `s` is known to be of type `T:seq`, so
the `s.len` call looks up the `len` method in the vtable passed for
type parameter T.

You can also require type parameter to conform to multiple interfaces,
as in `fn foo(...)` -- that requires passing multiple
vtables. (Niko: this is the thing you asked about. Turns out it's not
hard to do.)

It should be noted that this has both advantages and disadvantages
compared to the 'wrap by casting to interface approach'. For one
thing, it doesn't allow this

fn draw_all(shapes: [T]) { for s in shapes { s.draw(); } }

.. or at least, it doesn't do what you want, because it requires all
arguments to be of the same type, and only passes a single vtable. An
extension can be implemented (at a later time), to support this
instead:

fn draw_all(shapes: [drawable]) { ... }
draw_all([my_circle as drawable, my_rectangle as drawable]);

The drawable interface, when used as a type instead of a type
parameter bound, would denote a boxed value paired with a vtable, just
like in Niko's proposal.

And the good part: In the case where the interface is used as a type
parameter bound, which should cover most use cases, things do not have
to be boxed to

Re: [rust-dev] Kind system update

2011-11-18 Thread Marijn Haverbeke
I somewhat share your worries about the cleverness of the
last-userule. But my logic for adding it anyway is: A) We need to do
thisanyway as an optimization, so B) if we are already doing it, we
mightas well remove the burden of explicitly annotating moves from the
userto the compiler. I still think an explicit unary move would be
auseful addition for allowing people to write more obvious code, but
Idon't think the kind checker should complain about copies that
arealready going to be optimized to moves anyway.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Kind system update

2011-11-18 Thread Marijn Haverbeke
I pushed the new kind system today. Things to be aware of are:

- We now have proper copyability analysis, and resources can be used
in saner ways.

- The way arguments are passed to tag, object, and resource
constructors changed. See my other e-mail to the list.

- 'Last uses' of locals (arguments passed in a mode that makes them
owned by the function, and local let variables) are now treated
specially -- when stored or passed somewhere, they are moved instead
of copied. Most importantly, this makes most returning a local or
putting it in a data structure more efficient. This is taken into
account by the copyability analysis, so that you only get an error
when your program actually tries to use a noncopyable local after
storing it somewhere.

- The kinds are now called 'sendable', 'copyable', and 'noncopyable'.
The keywords to mark generic parameters are 'send' and 'copy'
(noncopyable is what you get when you don't specify a keyword).

- I got rid of the 'implicit shared [copyable] kind for generic
functions' thing again. This means you'll once again often forget to
add 'copy' and have to add it after the compiler complains. About 40%
of the generic functions in our standard library require copyable
arguments -- this is more than I expected. Still, over half can
operate on noncopyable types. Defaulting to copyable would have an
effect similar to the 'const' keyword in C++ -- people forget to think
about it when they write generic functions, so when you do need to
apply a generic to a noncopyable kind, you'll first have to fix the
generic and all generics it calls to have the right kind bound.

- Warning about copying of unique types is easy now (it's implemented
and commented out at
https://github.com/graydon/rust/blob/master/src/comp/middle/kind.rs#L127
), but it generates an enormous amount of warnings because we're
copying vectors everywhere. I think we might as well leave this off
until we have non-unique vector types.

That's it. I'll write something up in the tutorial early next week. I
think the new system is easier to think about and to explain. And the
last-use analysis provided a nice speedup by saving us a bunch of
copies.

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


[rust-dev] I added another parameter passing style

2011-11-18 Thread Marijn Haverbeke
I'm sorry.

There is now a mode called by-copy, which was needed to make
constructors behave sensibly in the face of proper enforcement of
noncopyability. By-copy works just like by-move, except that when the
passed value is an lvalue, it is copied instead of moved (or, if it is
a type that can't be copied, an error is raised). By-copy guarantees
that the callee owns the passed argument, and does it in a way that
generates as few copies as possible. Tag variant constructors, object
constructors, and resource constructors now all take their arguments
by copy.

Don't worry too much about passing-style proliferation. I think
by-copy will turn out to supersede by-move. Once we have warnings for
accidental copies of uniques (the code exists, but it won't be
practical to turn it on until vectors become non-unique again), there
won't be much of a reason to use by-move over by-copy. We'll also be
able to remove the user-visible distinction between by-val and by-ref
at some point (though we might want to keep that in native functions
only).

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


[rust-dev] Kind system revision proposal

2011-11-04 Thread Marijn Haverbeke
Kinds are assigned to generic type parameters to determine what a
generic function can do with values of that kind.

Rust currently has three kinds:
 - 'unique' types can be moved and sent (all the scalar types, unique
boxes with no resources in them)
 - 'shared' types can be moved, but can not be sent (anything
involving refcounted boxes-- @, obj, lambda)
 - 'pinned' types can be sent, but not moved (this currently applies
to resources, anything including resources, and blocks)

I'm arguing that this is not a very good system, and that we'd be
better off considering 'copying' rather than 'moving' as a property.
This was the way the system was originally designed, but when
implementing it, Graydon changed to the system outlined above. In
private mail, he told me that the reason for this was that we couldn't
allow blocks (functions closing over local frames) to be moved.

I propose the following alternative, which allows resources to be
moved again (*), greatly reduces the awkwardness of declaring types
for generic functions, and defines a more specialized approach to
safety for blocks (**), and actually help define noncopyability (which
the current system doesn't do at all).

We'd have the following kinds (better terms will have to be found, but
I'm using these for clarity):
- 'send,copy' types can be copied and sent (scalar types, unique boxes
without resources in them)
- 'nosend,copy' types can be copied, not sent (the same as the
'shared' types above, refcounted things)
- 'nosend,nocopy' types can't be sent or copied (resources, unique
boxes with resources in them, blocks)

Contrary to the old kinds, this forms a hierarchy, and the kinds lower
in the list can be treated as sub-kinds of those above them (a
'send,copy' value can be safely treated as a 'nosend,nocopy' value).
Most generic functions will neither send nor copy values of their
parameterized type, so they can safely default to 'nosend,nocopy'
without losing genericity. When they *do* copy or send, and the
programmer forgets to annotate the type parameter as such, a clear,
understandable error message can be provided.

Generic types (type and tag) do not seem to have a reason to
ever narrow their kind bounds in this system, so (unless I am missing
something), they should probably not even be allowed to specify a kind
on their parameters.

We'll have to define more closely when copying happens. I probably
forgot some cases here, but—an lvalue (rvalues are always conceptually
moved) is copied when:
- It is assigned to some other lvalue with =
- It is copied into a lambda closure
- It is passed as an argument in an unsafe way (safe argument passing
does not copy)
- It is used as the content of a newly created data structure (it is
not yet clear how tag/resource constructors can be distinguished from
other functions for this purpose. maybe they should take their args in
move mode, though that would require one to always say
option::some(copy localvar), which is also awkward)
- It is returned from a function or block

It might be useful to consider the last use of a local (let) variable
to be an rvalue, since that local will never be referenced again, and
it is always safe to move out of it. This will cause most returns to
become moves (though returning a non-move-mode argument or the content
of a data structure is still a copy). The intention is to only
annotate things as a copy where there will *actually* be two reachable
versions of a value after the operation. (The translator pass is
already optimizing most of the situations where this isn't the case
into a move or construct-in-place. This system could move some of that
logic into the kind-checking pass.)

Block safety will have to be handled on a more or less syntactic
level. Values with block type can be restricted to only appear in
function argument or callee position, and when appearing in argument
position, the argument mode has to be by-reference. This is a kludge,
but a relatively simple one (a small pass coming after typechecking
can verify it).

Given this, we can have a kind-checking pass that actually works,
without imposing a big burden on users. Generic functions (and
objects, as they currently exist) will have their parameters be
'nocopy,nosend' when no kind annotation is present, which will usually
be the right thing. Generic data types will never have to be annotated
with kinds.

I hope people agree this system is easier to understand than the
current one. I also hope I didn't miss any gaping soundness holes.
Please comment.

*) Resources that can't be moved are rather useless. They can only
exist as local variables and never be stored in a data structure. This
is why there is currently a kludge in the kind-checking code to allow
resources to be constructed into data structures. This is needlessly
special-cased, and doesn't really work very well at the moment (you
can't, for example, put a resource in a tag value.)

**) If the 'regions' design that Patrick and Niko are working on

Re: [rust-dev] First skeleton of a tutorial

2011-11-01 Thread Marijn Haverbeke
I wrote the sections on modules and native functions today, cleaned up
some of the existing text, and added pretty syntax highlighting to the
code in the HTML output.

Still at http://marijnhaverbeke.nl/rust_tutorial

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


[rust-dev] First skeleton of a tutorial

2011-10-31 Thread Marijn Haverbeke
http://marijnhaverbeke.nl/rust_tutorial (I didn't have time to
integrate it with rust-lang.net today, and that probably should wait
until it's a bit more fleshed out).

Please comment. There's a bunch of stuff completely missing for now
(tasks, most notably).
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Renaming "tag" and "log_err"

2011-10-31 Thread Marijn Haverbeke
Also relevant here: log_err was originally added as a stopgap
temporary solution, with the idea being that logging eventually would
be a more primitive operation where you specified  both a log level
and a message, and there would be a macro that'd help you do this in a
more nice-looking way. We have four log levels, but are only using two
of them at the moment. Making log polymorphic has removed one reason
for making it a macro (the idea was to integrate #fmt), but proper
support for more log levels would still be nice.

(Tangentially, the standard prelude, if such a thing materializes,
would be the ideal spot for such a logging macro.)
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Renaming "tag" and "log_err"

2011-10-29 Thread Marijn Haverbeke
> but I suppose it can't be helped unless we really want to
> have a std::pervasives module that's imported by default.

I've been thinking that something like the Haskell standard prelude
(small, guaranteed to always be available) might be nice. It could
hold some stuff like the std::option datatype, a print-to-stdout
function, and a few other things that are really common in tiny
programs.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Renaming "tag" and "log_err"

2011-10-28 Thread Marijn Haverbeke
It might be relevant that (for the same "hello world should be simple"
reason) recently added `std::io::print` and `std::io::println` to the
stdlib.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Change the syntax for type parameter kinds?

2011-10-25 Thread Marijn Haverbeke
I implemented this today. The rationale for making T represent
'pinned' is that 'pinned' is the broadest category -- all types can be
passed to a function expecting a pinned type. I still think that
making the default 'shared' is a good idea, but there are downsides --
it's easy to define a generic function or datatype as taking a more
narrow type than it really accepts.

Maybe we could have the compiler warn in such a case?
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] The new way to do iteration

2011-10-25 Thread Marijn Haverbeke
> Does this mean that the little code snippet on
> http://www.rust-lang.org/ is no longer valid?

No, that's a vector for loop. Only 'for each x in myiter() { ... }' was removed.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] The new way to do iteration

2011-10-25 Thread Marijn Haverbeke
> This seems to make the feature not very useful. Is there a way we can get
> around this limitation?

Why do you say that? It is trivial to get around this limitation, but
it seems that block calls like this in expression position would just
look even weirder than the form where you have the block inside the
parentheses. Compare

let sum = reduce({|a, b| a + b}, myseq) + 2;

let sum = reduce(myseq) {|a, b| a + b} + 2;

Do you prefer the second? I figured this would just be a trick to make
statement-style loops look better.

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


Re: [rust-dev] Change the syntax for type parameter kinds?

2011-10-24 Thread Marijn Haverbeke
Opened https://github.com/graydon/rust/issues/1067 for this.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] Change the syntax for type parameter kinds?

2011-10-24 Thread Marijn Haverbeke
At least two people have confused @T with a boxed type in the past
weeks. Even me, who really should know better at this point,
occasionally misinterpret some code because of the similarity between
the two. The same probably goes for ~T.

I think we should change the syntax. It can be a little more verbose,
I think, as long as it doesn't resemble other type-related syntax.

I'd also support making 'shared' the default kind for type parameters.
It is usually what you want.

Proposal: 'pinned T' and 'unique T' for pinned/unique type params. 'T'
for shared ones.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


[rust-dev] The new way to do iteration

2011-10-21 Thread Marijn Haverbeke
As agreed on in this week's meething, I removed compiler support for
iter functions and for-each loops today. Instead, it is now possible
to say

uint::range(0u, 10u) {|i|
log_err i;
}
my_map.items {|key, val|
...
}

If an call expression in statement position is followed directly by a
block ({| or {||), that block is added as a final argument to the
call. For a non-call expression, the expression becomes a call with a
single argument, the block.

(The reason it only recognizes expressions in statement position---at
the top level of an outer block---is that this way, you don't need to
terminate a block call with a semicolon. When using higher-order
functions in a way that returns a value, you'll have to put the block
inside the parentheses as before.)

Iterators are now simply functions that take a block as their last
argument. They are strictly as powerful as our old iterators, and
require much less compiler machinery.

An open problem is whether we want to allow break/continue or even
returning from the outer function inside a block. (This didn't work
for the old iterators either.)

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


[rust-dev] Why are there &&-signs in my function signatures? (or: update on by-value arguments)

2011-10-07 Thread Marijn Haverbeke
You'll notice that, as of today, Rust is once again more picky about
passing functions to higher-order functions. Each argument to each
function is marked as either by-reference or by-value, and you can not
pass a function expecting a by-value arg (`fn(+type)`) to a
higher-order function that wants a by-ref function (`fn(&&type)`). The
new system is different from the old (pre-my-alias-overhaul) approach
in two ways:

 - You don't have to explicitly annotate most functions. The compiler
chooses a default passing convention (by-value for immediate types --
scalars, box/unique pointers, natives -- and by-ref for everything
else). In practice, you only need to add a && in front of the arg name
when your function takes something that defaults to by-value, but you
need a function that passes by ref.

- The 'ownership' of the arg stays with the caller, even for by-value
args, so that we can usually avoid having to do a take and a drop on
args.

I think the result is pleasing. We don't have the constant clutter of
ampersands in function signatures, but do get the performance benefits
of using an appropriate and efficient passing style for each type.
Having to line up passing styles for higher-order functions is a bit
of a pain, but no more than it used to be before I started messing
with call styles. I hope that at one point we'll monomorphize our
generics (generate different version for different types), at which
point we could simply make them call the given function in the right
style, and remove this burden from the programmer.

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


Re: [rust-dev] Task scheduling and optimisation

2011-10-06 Thread Marijn Haverbeke
Another thing that makes iterators-as-tasks not really work is data
sharing. You want to be able to share data with your iterator, you
can't share data with other tasks.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Removing ty_native

2011-10-05 Thread Marijn Haverbeke
One thing that might make using nominal tags like this awkward is that
tags are, currently, always structural, so that they will always be
passed by reference. I'm hard at work on making immediates be passed
by value again, and I think we really want such natives to also be
immediate.

Looking into the content of tags to decide whether to make them
immediate seems kludgy. Maybe we do need a nominal type that's not a
tag after all.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Java-style iterators

2011-09-30 Thread Marijn Haverbeke
> Hm? I thought we were assuming {|e| ... } only adheres to a call expression
> to its left, is considered "the last argument" to the call.

Sure, that solves the ambiguity.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Proposal: Java-style iterators

2011-09-30 Thread Marijn Haverbeke
I'm also fine with this. As for the syntax...

>    vec::each(v) {|e| ... }

This once again produces ambiguity with fail and ret: does 'fail {|e|
...}' mean 'call the function produced by fail with this block', or
'fail with this block as the message'. Can be hacked around, or we can
just specify that the second version holds, but it's a wart.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


Re: [rust-dev] Parameter passing and native calls

2011-09-30 Thread Marijn Haverbeke
> Not anymore, with the C decl.

Can you elaborate on that?

> How about what I proposed earlier: the '+' sigil means by-value, the '&'
> sigil means by-immutable-reference, and leaving it off has the compiler
> choose a sensible default based on the type?

That'd work, though it'd be a little obscure (a function fn(T) will
always take its arg by reference, even when instantiated with T=int).
I guess it's a good stopgap until we decide what to do with
monomorphizing.

Would passing structural types by value be allowed? How would that
look? (Using load/store as we used to do, or passing by pointer with
the caller owning the value, or passed by pointer with the callee
copying it into its frame?)
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev


  1   2   3   >