Live data from Hacker News

A Week with Mozilla's Rust

relistan.com

21–30 of 104 posts

Re: A Week with Mozilla's Rust

#21

The example of match usage is really poor. From the looks of it there is no "pattern matching" going on at all here. I don't know the syntax, but even something like this would be a better demonstration: let computed_key = match (key.len() > self.block_size, key.len() self.zero_pad(self.hash(key).digest), (false, true) => self.zero_pad(key), (false, false) => key } At least there is some matching here, unlike in the…

> Also, does the compiler complain about my example above being not exhaustive?

Yes, although the error message isn't very good:

    crypto.rs:55:23: 59:5 error: non-exhaustive patterns: true not covered
    crypto.rs:55     let computed_key = match (key.len() > self.block_size, key.len()  self.zero_pad(self.hash(key).digest),
    crypto.rs:57         (false, true) => self.zero_pad(key),
    crypto.rs:58         (false, false) => key
    crypto.rs:59     };
    error: aborting due to previous error
And technically that's not a good thing, since (true, true) is not possible considering the input.

Re: A Week with Mozilla's Rust

#22
post #8

I don't want to turn this into a Go vs. Rust discussion, because the two languages are very different and have very different goals. However, I want to question the claim: > Go is also not particularly friendly to interface to external libraries written in C which doesn't seem to be explained anywhere in the article, and jars with my understanding. Go does play very well with C; cgo[0] makes this pretty straightforwa…

Rust not having the garbage collection as far as I understand can be made to produce routines that are part of C application. As far as I understand, by design Go can't be a "nice" citizen in a C application, the Go routine will bring with itself the whole city it lives in to your flat. So Go applications are something like "compiled, fast Ruby or Python." As far as I understand, Rust should theoretically be a way to…

I've took a look on one "real" example, I admit I haven't spent much time with the language, I just want to get the idea looking at the code which really does something, I like that more than starting with boring tutorials:

https://github.com/mozilla/rust/blob/master/src/libextra/jso...

I know it's the least interesting thing, but for me the simplest rule to recognize Rust vs Go is that at the moment Go has the nice and minimalistic := and Rust the clumsy (for my aesthetics at least) "let."

Still, I understand that Rust attempts to solve more than Go in some aspects, and I really hope it can succeed. For that, yay Rust!

Can somebody explain me the reason for constructs like this:

    self.error(~"trailing characters")
vs

     self.parse_ident("ull", Null),
I read that ~ means "owned box on heap." Why should something that are facto string literals be owned and on heap? Isn't the need to allocate and box string literals on the heap something that makes the language unnecessarily slow? And why there's a need somewhere to explicitly box something that's known at the compile time and somewhere there isn't?

Re: A Week with Mozilla's Rust

#23
post #20

Earlier quoted context omitted.

As far as I understand, by design Go can't be a "nice" citizen in a C application, the Go routine will bring with itself the whole city it lives in to your flat. That is correct, but the GP is correct as well. Using C code in Go is easy(just use cgo etc.), vice versa not so much(no such thing as goc etc.).

At the bottom of the cgo command documentation [0] is an example of exporting go functions to C. I don't fully understand how those functions work when running in C land (does the GC come with?), but the implementation doesn't look difficult. [0] http://golang.org/cmd/cgo/

How it works (from http://golang.org/src/pkg/runtime/cgocall.c )

    36	// The above description skipped over the possibility of the gcc-compiled
    37	// function f calling back into Go.  If that happens, we continue down
    38	// the rabbit hole during the execution of f.
    39	//
    40	// To make it possible for gcc-compiled C code to call a Go function p.GoF,
    41	// cgo writes a gcc-compiled function named GoF (not p.GoF, since gcc doesn't
    42	// know about packages).  The gcc-compiled C function f calls GoF.
    43	//
    44	// GoF calls crosscall2(_cgoexp_GoF, frame, framesize).  Crosscall2
    45	// (in cgo/gcc_$GOARCH.S, a gcc-compiled assembly file) is a two-argument
    46	// adapter from the gcc function call ABI to the 6c function call ABI.
    47	// It is called from gcc to call 6c functions.  In this case it calls
    48	// _cgoexp_GoF(frame, framesize), still running on m->g0's stack
    49	// and outside the $GOMAXPROCS limit.  Thus, this code cannot yet
    50	// call arbitrary Go code directly and must be careful not to allocate
    51	// memory or use up m->g0's stack.
    52	//
    53	// _cgoexp_GoF calls runtime.cgocallback(p.GoF, frame, framesize).
    54	// (The reason for having _cgoexp_GoF instead of writing a crosscall3
    55	// to make this call directly is that _cgoexp_GoF, because it is compiled
    56	// with 6c instead of gcc, can refer to dotted names like
    57	// runtime.cgocallback and p.GoF.)
    58	//
    59	// runtime.cgocallback (in asm_$GOARCH.s) switches from m->g0's
    60	// stack to the original g (m->curg)'s stack, on which it calls
    61	// runtime.cgocallbackg(p.GoF, frame, framesize).
    62	// As part of the stack switch, runtime.cgocallback saves the current
    63	// SP as m->g0->sched.sp, so that any use of m->g0's stack during the
    64	// execution of the callback will be done below the existing stack frames.
    65	// Before overwriting m->g0->sched.sp, it pushes the old value on the
    66	// m->g0 stack, so that it can be restored later.
    67	//
    68	// runtime.cgocallbackg (below) is now running on a real goroutine
    69	// stack (not an m->g0 stack).  First it calls runtime.exitsyscall, which will
    70	// block until the $GOMAXPROCS limit allows running this goroutine.
    71	// Once exitsyscall has returned, it is safe to do things like call the memory
    72	// allocator or invoke the Go callback function p.GoF.  runtime.cgocallbackg
    73	// first defers a function to unwind m->g0.sched.sp, so that if p.GoF
    74	// panics, m->g0.sched.sp will be restored to its old value: the m->g0 stack
    75	// and the m->curg stack will be unwound in lock step.
    76	// Then it calls p.GoF.  Finally it pops but does not execute the deferred
    77	// function, calls runtime.entersyscall, and returns to runtime.cgocallback.
    78	//
    79	// After it regains control, runtime.cgocallback switches back to
    80	// m->g0's stack (the pointer is still in m->g0.sched.sp), restores the old
    81	// m->g0.sched.sp value from the stack, and returns to _cgoexp_GoF.
    82	//
    83	// _cgoexp_GoF immediately returns to crosscall2, which restores the
    84	// callee-save registers for gcc and returns to GoF, which returns to f.

Re: A Week with Mozilla's Rust

#24

The example of match usage is really poor. From the looks of it there is no "pattern matching" going on at all here. I don't know the syntax, but even something like this would be a better demonstration: let computed_key = match (key.len() > self.block_size, key.len() self.zero_pad(self.hash(key).digest), (false, true) => self.zero_pad(key), (false, false) => key } At least there is some matching here, unlike in the…

As noted by masklinn, the compiler will complain about the non-exhaustive match. Stuff like this makes me want a dependently typed language for practical programming, in which I can express the concept of "this case ought to be impossible", and convince the compiler by supplying a proof. Also, this would eliminate the false dichotomy between "fast, unchecked, unsafe array indexing" and "slow, checked, safe array indexing", which would be a huge win for safe systems programming.

Re: A Week with Mozilla's Rust

#25
post #11

Of all the upcoming languages out there. I think rust is best positioned. The fact that it is really the only contender that can preform the same role as C, but it folds in lots of the language design theory of the past three decades puts it in a league of its own.

Exactly! This is what makes Rust exciting - as opposed to yawnfests like Go that merely provide a compiled, somewhat faster Python.

Re: A Week with Mozilla's Rust

#26
post #22
post #8

Earlier quoted context omitted.

Rust not having the garbage collection as far as I understand can be made to produce routines that are part of C application. As far as I understand, by design Go can't be a "nice" citizen in a C application, the Go routine will bring with itself the whole city it lives in to your flat. So Go applications are something like "compiled, fast Ruby or Python." As far as I understand, Rust should theoretically be a way to…

I've took a look on one "real" example, I admit I haven't spent much time with the language, I just want to get the idea looking at the code which really does something, I like that more than starting with boring tutorials: https://github.com/mozilla/rust/blob/master/src/libextra/jso... I know it's the least interesting thing, but for me the simplest rule to recognize Rust vs Go is that at the moment Go has the nice…

> I know it's the least interesting thing, but for me the simplest rule to recognize Rust vs Go is that at the moment Go has the nice and minimalistic := and Rust the clumsy (for my aesthetics at least) "let."

It is not possible for us to have ":=" because we don't know whether to parse a pattern or an expression without a prefix token like "let". Rust's pattern language is far more expressive than Go's and one grammar will not cover both.

> Why should something that are facto string literals be owned and on heap? Isn't the need to allocate and box string literals on the heap something that makes the language unnecessarily slow?

Probably the `error` method explicitly asked for a heap-allocated string, perhaps because it wants to pass it to someone who will later free it. (Unlike in C, it would be a type error to attempt to free a constant string in read-only memory, which is what a plain string literal is in Rust.)

Re: A Week with Mozilla's Rust

#27
post #11

Of all the upcoming languages out there. I think rust is best positioned. The fact that it is really the only contender that can preform the same role as C, but it folds in lots of the language design theory of the past three decades puts it in a league of its own.

Exactly! This is what makes Rust exciting - as opposed to yawnfests like Go that merely provide a compiled, somewhat faster Python.

agreed. no fan of Go.

Re: A Week with Mozilla's Rust

#28
post #22

Earlier quoted context omitted.

I've took a look on one "real" example, I admit I haven't spent much time with the language, I just want to get the idea looking at the code which really does something, I like that more than starting with boring tutorials: https://github.com/mozilla/rust/blob/master/src/libextra/jso... I know it's the least interesting thing, but for me the simplest rule to recognize Rust vs Go is that at the moment Go has the nice…

> I know it's the least interesting thing, but for me the simplest rule to recognize Rust vs Go is that at the moment Go has the nice and minimalistic := and Rust the clumsy (for my aesthetics at least) "let." It is not possible for us to have ":=" because we don't know whether to parse a pattern or an expression without a prefix token like "let". Rust's pattern language is far more expressive than Go's and one gramm…

Does it mean that to do

    self.error(~"trailing characters")
there has to be the complete allocation of enough memory to store the copy of the whole string, then copying of all characters there, only in order for the target function to be able to do "free"? If the intention of the language is to "properly" work with a lot of strings (and it should be) it would be good not to have glaring inefficiencies? Wouldn't it be a good optimization to have the free routine check if the pointer is inside of the static area and then not do anything. That way you can pass the pointer to the static area avoiding copying and also avoid freeing. And the only thing needed is that free has "static_begin" and "static_end" addresses?

There are also other possibilities -- by knowing that the heap allocated things have lower bits of addresses 0 you can mark the stuff using the lowest bits of pointers.

I know, I have maybe too low level approach. But why not, as soon as you want to be more convenient than C, you have to think low level too.

Still what I like is that at least at the moment this explicit declaration of boxing gives a nice feeling that nothing is done "behind the back" of the programmer, which is good -- the main problem of C++ is that you can't know if somebody hid something very nasty behind some plain innocent looking construct, or even what the compiler will implicitly do or won't.

EDIT-addition: Regarding "pattern" if the := would be a single token, not allowed in patterns, wouldn't it be OK then? Do you have such a valid sequence in the patterns as the combination of the single operators or whatever?

Re: A Week with Mozilla's Rust

#29
post #22
post #8

Earlier quoted context omitted.

Rust not having the garbage collection as far as I understand can be made to produce routines that are part of C application. As far as I understand, by design Go can't be a "nice" citizen in a C application, the Go routine will bring with itself the whole city it lives in to your flat. So Go applications are something like "compiled, fast Ruby or Python." As far as I understand, Rust should theoretically be a way to…

I've took a look on one "real" example, I admit I haven't spent much time with the language, I just want to get the idea looking at the code which really does something, I like that more than starting with boring tutorials: https://github.com/mozilla/rust/blob/master/src/libextra/jso... I know it's the least interesting thing, but for me the simplest rule to recognize Rust vs Go is that at the moment Go has the nice…

I'm new to Rust and I'm not familiar with this code, but here's an attempt at an explanation anyways:

The "error" function returns a struct containing the error string. I suspect the intention is to allow dynamically constructed error messages like "syntax error at line 4, char 3" (although it doesn't seem to be doing this anywhere). Since the string might be dynamically allocated, it has to be freed when the struct is freed, which obviously can't happen if the struct just has a pointer to the literal in static memory. (You could flag the string somehow as "should be freed/should not be freed", as you suggest in your other comment, but this has its own tradeoffs)

If you wanted an "error" function that would take string literals directly (and only string literals) you would do something like this: https://gist.github.com/bct/6300740

The "parse_ident" function doesn't return any portion of the input string, so it can just use a borrowed reference.

Re: A Week with Mozilla's Rust

#30
post #23
post #20

Earlier quoted context omitted.

At the bottom of the cgo command documentation [0] is an example of exporting go functions to C. I don't fully understand how those functions work when running in C land (does the GC come with?), but the implementation doesn't look difficult. [0] http://golang.org/cmd/cgo/

How it works (from http://golang.org/src/pkg/runtime/cgocall.c ) 36 // The above description skipped over the possibility of the gcc-compiled 37 // function f calling back into Go. If that happens, we continue down 38 // the rabbit hole during the execution of f. 39 // 40 // To make it possible for gcc-compiled C code to call a Go function p.GoF, 41 // cgo writes a gcc-compiled function named GoF (not p.GoF, since gc…

I'm not particularly familiar with either language... that documentation seems to be talking only about Go called from C-called-from-Go, not from arbitrary C. In other words, it handles Go calling a C function that expects a callback, and handing it a Go function. This does not handle a fundamentally-C program calling a Go function.

Again, not an expert, I could be mistaken, but this seems to not be addressing the original issue raised (that C/Go interop is one-way only).

Post reply on HN