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
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
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,
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.
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
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
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,
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).
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,
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,
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.
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
'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
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 --
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
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
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
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
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
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.
___
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.
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
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
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
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?
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:
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
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
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
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
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
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 T: add, mult, sub, div type parameter.
___
Rust-dev mailing
(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
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.
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
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
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
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
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
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
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'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
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
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
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
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
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.
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
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).
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
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
Ah, I should have clarified. 'none' refers to the std::option type,
which is defined as `tag optionT { none; some(T); }`.
let x = MyContainerMysteryT();
x.insert(3); // now infer that x is really a MyContainerint
How would the compiler infer that?
Well, you can't write MysteryT there, but
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
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
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
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
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
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
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
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
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]:
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
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
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
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
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
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).
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
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
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
Backtraces do seem to work on the Mac GDB, once it's appropriately patched
Is this patch in upstream gdb? Ubuntu currently comes with gdb 7.2.
Can I expect that to work, or should I build a patched on myself?
___
Rust-dev mailing list
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
I see two potential problems with this... We can't use references for
the yielded values, which might be a major penalty in some cases. And
I somewhat doubt that it is easy to optimize. Firstly, our objects are
heap-allocated, so you have a malloc/free for every loop, and
secondly, inlining things
Minor thing: What is the purpose of |put;| (with no arguments)?
It's equivalent to 'put ()', for consistency with 'ret;'. We should
probably remove support for this, since it's too rare to abbreviate.
___
Rust-dev mailing list
Rust-dev@mozilla.org
In gdb, I can get stack traces from inside rust and from upcalls just
fine. But when an assertion in LLVM is hit, gdb gets confused a nd
just shows me the LLVM funtions on the stack, and then below that
bogus addresses labeled with '???'. Doing 'ret' to get out of the LLVM
functions doesn't help
If an explicit copy operator is needed for uniques, then this isn't even
ambiguous, is it?
So I guess you're planning to make vectors and strings (and anything
containing them) also explicit-copy-only? In that case, I guess we're
fine. (Though, with strings, I expect this to cause some pain.)
I'm less concerned about blocks than I am about @fn (which we still have
AFAIK) and objects.
To recap, immutably rooted references (which is most of them) are safe
as long as their root isn't touched. So closures and objects don't
cause a problem there. Mutably rooted references are the
The problem: Accessor functions always have to copy their return
value, so you can't efficiently get at the content of data structures
(except by duplicating the logic needed to access them).
The original solution proposed was to pass the accessor a block and
pass the value to that block by
B) Limiting implied-semicolons-after-blocks to blocks that end with a
trailing semicolon, requiring blocks in loops (where the value is
discarded anyway) to end in a trailing semicolon, and always treating
blocks that do end in semicolons as the end of the expression.
I went ahead and
This one is ... a confusing set of rules. I take it empty loops have an
implied trailing semi in their body? That is: while true {}? I know it's a
degenerate case, just trying to clarify.
{} is a non-expression block. The phrase 'trailing semicolon' was
badly picked. The deciding factor is
Thoughts?
So do you intend to make bracey-if a statement? What about
expression-alt? That'd still have the current awkwardness when
followed by '(' or '['.
___
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev
Would anyone be opposed to...
A) Marking 'free' blocks (blocks not part of a
function/loop/if/alt/etc, but used solely for a new scope or to do
something before an expression) with a more explicit syntax.
This has the advantage of making them easier to spot and parse
(distinguishing '{ foo; bar;
Where you used to write
fn(by_alias: some_ty, by_mut_alias: mutable [int], by_move: -int) { ... }
You now write
fn(by_reference: some_ty, by_mut_reference: [int], -by_move: int) { ... }
That is, the mode glyph now comes before the argument name (in
function types, when there is no
Update: The approach sketched earlier does not work out because it is
possible for a function to take a parameterized type without the
caller knowing that it does. (For example, a fnT(x: fn(T)), when
given a function fn(int), will call it with the argument given by
reference, since it sees it as
Now that structural types are always passed by reference, we can pass
all values conceptually by alias (i.e., without doing a take/drop on
them). The current alias analysis can be used to insert a refcount
bump or explicit copy on the caller side in those cases where it can't
prove the aliasing is
While this is attractive from the perspective of having the
right defaults, it also makes the semantics of the code at a glance more
subtle.
The semantics are not effected at all -- both with 'structurally
immutable' and with immediate values, it is not observable whether the
parameter was
These concerns are why I advanced
the suggestion earlier: make no sigil mean immutable alias semantics, but
the compiler may choose to promote to value if the value is immutable and
small, but have an explicit copy sigil mean always copy.
I see. This is what I meant when I said we can
A mystery-heuristic that programmers can't depend on is much less
attractive. Users are going to write unsafe code that occasionally observes
the distinction. I don't want to be hiding this.
The only point where I suggested a heuristic was for when to emit
warning for implicit copying. The
[Thank you, gmail send hotkey. So, as I was saying...]
I just pushed something that will make the following program valid:
fn main() {
let x = 10;
let x = x + 10;
log x;
}
let bindings now have a scope starting from their definition, and may
shadow each other
There are different ways to handle this problem (monomorphization being an
especially attractive one, I think), but it seems to me that the simplest
solution for a 0.1 release to just have GC bail out when it discovers a
dynamically-sized frame on the stack. Is this okay with others?
Where
Yesterday's snapshot made it safe to start using destructuring
patterns in let, for, and for each. I also fixed a few bugs that
prevented for and for each from properly deriving a type for the loop
variable when you didn't specify one. The happy result is that you can
now do things like this:
Perhaps it would be possible to apply some compile-time transformation to
mitigate the problem:
I don't really understand your transformation, but it seems like the
resulting code would still consume stack space for the 'tail' call.
___
Rust-dev
What I've been doing in these situation is just not passing bcx by
alias. Then you have a regular, mutable local.
As an unrepentant Lisper, I wouldn't be opposed to let introducing a
new scope (that is, in fact, how Hob works), but I don't think it fits
really well in the c heritage that we're
I've been throwing around some ideas about a simpler way to 'alias'
(non-owning reference) things with Patrick, and am in the process of
working out some ideas. A bunch of the possible directions, and the
ones that seem most promising to me at the moment, work poorly with
tail calls. Having the
As was decided when resources were introduced (I hope most of you were
informed), we wanted to drop support for object destructors. Resources
are now mostly useable -- though if you want to store or pass them
somewhere, you have to box them immediately on creation until we get
our move semantics
I just pushed a bunch of commits that remove uses of tuples from our
code, and drop tuple support from the compiler. Some of you may be
saddened by this. The good news is that you can still say rec(_0=10,
_1=20) (soon to be {_0: 10, _1: 20}) if you really want to, which is
equivalent to our old
With this change, would you be allowed to write this?
alt fail foo {
1 {...}
2 {...}
}
We'll have to rig the parser to not go screwy on 'alt fail { ... }' by
checking whether there is a non-brace token following the fail/cont
and only interpreting it as an alt modifier when there is, but
First, a relatively non-controversial case:
auto ccx = cx.fcx.lcx.ccx; // Look ma, no refcounting bumps!
This case is very similar to alt/for blocks, and the alias checker
could check it with a relatively simple extension.
Next, of couse, I'm going to argue that 'accessing things through
let h1 = @hashmap::mk();
let h2 = id(h1); // identity fn; compiler can't see through this
hashmap::insert(*h1, foo, bar);
hashmap::get(*h1, foo, { |val|
hashmap::delete(h2, foo);
print val; // crash
});
The alias checker would yell at you for the hashmap::delete line,
since
I don't understand how the alias checker figures into it. It's a lifetime
thing. How do you ensure the aliased value remains live as long as the alias
does?
Right, I was too vague on that. You can only return aliases that are
'rooted' (by the rules I explained in the previous alias-checking
1 - 100 of 121 matches
Mail list logo