Follow Slashdot stories on Twitter

 



Forgot your password?
typodupeerror

Comment Re:What could possibly go wrong? (Score 1) 157

FWIW, Rust also supports interfaces and extensions thereof, including extensions of multiple interfaces. In fact, you have to do some really unusual things in Rust to define a type that doesn't implement at least one interface, and most implement many. Even primitive types implement many interfaces. The lowly "u8" (C++: uint8_t), for example, implements well over a hundred interfaces.

Most such interface implementation in Rust is static, meaning it doesn't make use of dynamic dispatch, but it's also extremely common in Rust to define interfaces that can have multiple implementations but be referenced only through the interface and use dynamic dispatch to call methods. In Rust (as in C++, actually), you can use either compile-time or run-time polymorphism.

The restrictions on the above, compared to C++, are that (a) all Rust interfaces ("traits") are pure[*] and (b) while you can have arbitrarily-deep stacks of interface inheritance, once you derive a concrete type -- a non-pure "class" -- you can't subclass that. Inheritance is of interfaces only, though interfaces can inherit from one another and multiple inheritance is not just common but nigh-universal.

The lack of the ability to subclass a concrete type isn't an omission or oversight, it's a deliberate design decision to avoid the trickiest and least-useful characteristic of C++'s object model. Indeed, current common wisdom among C++ developers (I've been writing C++ professionally since 1991 and have seen the evolution of the wisdom, and the pain that drove it) is that implementation inheritance is generally a bad idea. It's not forbidden, by any means, but it's treated as a mild code smell, and a design that makes very heavy use of implementation inheritance is almost always a bad design. And, of course, multiple implementation inheritance is just asking for eternal pain.

For those interested, the way this stuff works in Rust, and in Rust nomenclature, is that interfaces are called "traits". A trait is like a C++ class that contains only pure virtual and static methods. It has no data members and cannot be instantiated; it's not a concrete type. Traits can extend other traits, and can mix in multiple traits. Like C++ or Java interfaces, functions can take traits as arguments, though they must be passed by reference, not value. Of course, in Java all objects are passed by reference, while in C++ you have to explicitly pass a pointer or a reference to an abstract interface.

Concrete types come in a few flavors, but the one most relevant here is a "struct". A "struct" is like a C++ struct/class. It can have data. It's generally a concrete type that can be instantiated. Structs can implement any number of traits, and it's a pretty rare struct that doesn't implement several traits implicitly, and often they implement multiple traits explicitly, too. Trait implementation is so common that there's macro infrastructure specifically to facilitate it.

For example, very often you'll see struct definitions with a line above them like #[derive(Debug,Clone,Copy,PartialEq,Eq,PartialOrd,Ord)]. That macro invocation declares that the struct implements those seven traits, and automatically generates the methods to implement them:

* The "Debug" trait is implemented by things that can provide a string representation of themselves suitable for debug output. The macro generates a reasonable format, two of them, actually, a compact one and a "pretty" one. If you don't like those formats, you can instead manually implement the trait.
* The "Clone" trait is implemented by things that can be copied, but only with an explicit "clone()" method call. The macro generates an implementation that clones all of the fields. This only works if the fields all implement Clone. You can, of course, provide a custom implementation if needed.
* The "Copy" trait is implemented by things that can be copied automatically. Essentially, this tell the compiler that it's allowed to insert "clone()" calls as convenient and that by-value arguments of this type should be cloned rather than moved (like C++, Rust supports move semantics, but unlike C++ in Rust moving is the default). To implement "Copy" you must also implement "Clone", which provides the implementation for copying, and on top of that you're asserting that copies are cheap.
* The "PartialEq" trait is implemented by things that can be compared for equality, but doesn't promise an equivalence relation (i.e. A == B && B == C does not necessarily imply that A == C). The macro implements a default partial equality operator that checks field by field, which only works if all of the data members also implement PartialEq (otherwise, compile error).
* The "Eq" trait is implemented by things that can be compared and do promise an equivalence relation. Types must implement PartialEq to implement Eq. The macro provides a field-wise comparator. * The "PartialOrd" and "Ord" traits are implemented by things that can be ordered, similar to "PartialEq" and "Eq". The macros implement an ordering that compares fields lexicographically. Obviously the data members must also implement the ordering traits for this to work.

In addition to those, an ordinary struct automatically implements the "Sized", "Send", "Sync" and "Unpin" traits:

* The Sized trait means that the data structure has a fixed size. Note that apparently variable-length structures like vectors and strings also implement Sized; a "String" structure has a fixed size, but contains a pointer a heap buffer that may be resized. A concrete type must implement "Sized" in order to be instantiated because we need to know how much memory to allocate.
* The "Send" trait means the data structure is safe to send to another thread. This is automatically implemented if all of the data members are "Send".
* The "Sync" trait means the data structure is safe to read from another thread. This is automatically implemented if all of the data members are "Sync".
* The "Unpin" trait means the data structure can be safely moved in memory (assuming references to the data are managed appropriately -- Unpin is a promise that nothing inside the data structure will break if it's moved, i.e. it doesn't contain any pointers to itself, not a promise that nothing outside of the data structure will be broken if it's moved).

And, of course, structs may explicitly implement traits, and must define the necessary methods for the traits they implement.

One really big difference with C++ is the interaction between local types defined in the current program (or library) and types defined in other libraries. In C++ if a library exports an interface (pure or not), you can subclass it, but you cannot make a library type a subclass of an interface you created. In Rust you can do both. This works in Rust because Rust doesn't put vtable pointers inside the struct, unlike C++. In C++, the memory allocated for an object with virtual methods contains a pointer to the vtable used to find those methods when they're called. In Rust, the object does not contain the vtable pointer. Instead a pointer (or reference) to an object through an interface is "fat", containing the address of the object and the address of the vtable for the interface (trait) the pointer is referencing. Obviously, if you're referencing the concrete type directly there's no need for a vtable at all. It's only when you're referencing an object through some abstract interface that you need the vtable.

Anyway, I can think of no construction in C++ that can't be translated into Rust, though some amount of refactoring may be required, most especially in the case of C++ code that makes heavy use of implementation inheritance. The basic process of converting a deeply-layered inheritance hierarchy is (a) pull all the virtual methods out into one or more traits and (b) replicate the inheritance hierarchy with a set of increasingly-nested structs. Even multiple virtual inheritance hierarchies can be transformed this way.

If someone can think of a C++ construction that can't be fairly easily translated into Rust, I'd love to hear about it. Obviously, many C++ constructions are hard to translate into safe Rust, because they're unsafe. Converting them to unsafe Rust would often require deeper refactoring. Still, the unsafe Rust version wouldn't be any less safe than C++, and after conversion you can start the process of refactoring to eliminate or minimize the unsafe bits. Equally obviously, directly translating C++ to Rust is going to result in very non-idiomatic Rust. Among other things it's going to be littered with "mut" everywhere because in C++ stuff is mutable by default while in Rust stuff is immutable by default. Really well-written C++ uses "const" everywhere it can and tries to minimize mutability, so that'll convert more nicely, at least in that aspect.

What is most likely to be problematic in large-scale, automated translation is borrow checking. The C++ code is almost guaranteed to violate borrow checker rules all over the place, and some of those violations will only be fixable with very deep refactoring or really sketchy Rust code. This doesn't mean the C++ can't be translated, just that the result will be nasty (even if not unsafe).

[*] Interfaces (traits) actually can have default method implementations, which subclasses (structs) that implement them can optionally override. Since the interface has no data members this usually only makes sense when there are methods that can be implemented in terms of other interface methods, without direct reference to instance data.

Comment Re:needs to work with no network as well! (Score 1) 141

Here's one example.

I spent some time searching and that actually appears to be the only example. It's the only one ever cited in all of the many articles about this issue.

However, as this article notes, it turns out legislation going into effect in about six months is slated to provide a way for police to report the violation to the California DMV.

That seems like the right approach, though nothing is preventing police from reporting it to the DMV now. And certainly the DMV has to be well aware of this highly-publicized case :)

Comment Re:needs to work with no network as well! (Score 1) 141

They are driving in highly controlled tests. It is the control keeping accidents down.

Nonsense. They are driving fully-operational automated taxi services in multiple cities, logging 2.5M miles per month, with accident rates far below those of professional drivers.

Comment Re:Desktop Linux needs to stop sucking is all (Score 3, Insightful) 195

You should try it on PC hardware. That people have been able to get Linux working tolerably well on Apple hardware is a testament to their fortitude and bullheadedness, given how hard Apple has made it. I like Apple's laptops, and I'd rather run Linux than OS X, but it's just not worth it. Running Linux on a PC laptop or desktop is great, though. Suspend/resume and even hibernation work perfectly on the desktop Debian machine I'm typing this on.

Comment Re:needs to work with no network as well! (Score 1) 141

The point is that in California there currently appears to be NO penalty or state-wide mechanism for addressing traffic violations by a robotaxi. Police apparently have little choice but to just let them go on their way without any action (at least that is what police are doing).

Is that what they're doing? It seems to me that the appropriate action is to report the event to the regulator and have them follow up.

Do you have a link to information about what police are or aren't doing?

Comment Re:Education Funding (Score 1) 94

Decades ago people were going to school with shotgun racks on their vehicles.

Heh. My dad used to keep a rifle and ammunition in his school locker. He'd carry the rifle into the school and put it in his locker every morning, and reverse the process every afternoon. Why? He hunted jackrabbits every afternoon, on his way home from school. The local farmers paid a bounty for jackrabbit ears because the rabbits ate their crops. He tried using a shotgun for a while, but the shells were a lot more expensive, so assuming sufficient skill to hit fast-moving rabbits with a rifle, it was the better choice.

Simpler times...

Comment Re:Education Funding (Score 1) 94

Imagine if those millions of dollars were spent on teaching students.

I'm sure the district would love to spend the money that way, but we live in a society that values easy access to guns more than it values safety, so the district's hand is forced.

This is Beverly Hills, and school districts are funded by property tax revenues. This school district has money coming out of its metaphorical ears.

That, of course, is also a problem, that some school districts are lavishly funded and others struggle mightily. But if the Beverly Hills school district weren't blowing $5M on questionable safety equipment, they'd be blowing it on something else.

Comment Re:needs to work with no network as well! (Score 1) 141

I think the whole notion of applying a behavior-management program designed for individual drivers to a company operating a fleet of robot drivers makes no sense. It's a different situation, and calls for different regulatory strategies. I'm not saying there shouldn't be regulation of autonomous vehicles, just that it should be tailored to address that problem, rather than applying a solution designed for a different problem.

And, frankly, California's strategy seems like a good one. They're allowing systems to be built and tested on public roads because the systems will, when fully operational, yield enormous benefits to the people; safer roads, lower-cost transport, recovery of vast amounts of space currently devoted to parking lots, etc. They're also overseeing this testing, requiring regular reports, being ready to intervene and impose additional requirements or revoke permission to operate, etc.

Comment Re:needs to work with no network as well! (Score 1) 141

In California it's still not clear who gets a ticket in case of a moving violation and who gets points on their record when autonomous cars violate the law and who pays the fines and fees - so nobody does.

Are those mechanisms relevant or useful for regulating autonomous vehicles? It seems to me that you're applying a system designed to incentivize and manage the behavior of individual human drivers to an entirely different context. That doesn't make sense.

What does? Well, pretty much what California is doing. There's a regulatory agency tasked with defining rules for licensing self-driving systems to operate on state roads. Failure to comply with regulatory requirements, or evidence of failure to behave safely and effectively results in the state rescinding the license to operate. Of course, not every failure is of a magnitude that justifies license revocation, and how the maker of the system responds to problems is a key factor in determining an appropriate response.

In this case, Waymo had a significant problem. Waymo responded by immediately suspending service until, presumably, they figure out how to address the problem. Assuming they fix it, that's reasonable behavior that doesn't warrant much response by the regulator, except perhaps to look into Waymo's design and testing processes to see whether this gap is indicative of others.

This all makes a lot more sense than trying to fit policies designed for humans onto machines.

Comment Re:needs to work with no network as well! (Score 1) 141

Section 227.32 on page 11 says the autonomous vehicle test driver is mandatory. Earlier it says there should be a communications link between the driver and the vehicle, but it doesn't say it must go through a "network."

Thanks. I guess this requirement goes away when the system graduates out of "test" mode?

Comment Re: needs to work with no network as well! (Score 1) 141

The requirement that there be a way to 'take over' the vehicle in case of a problem literally requires network access for a remote 'driver' to take over in case of a problem involving a 'driverless' vehicle.

How can a remote driver take over a vehicle's controls if there is no network?

I was looking for a reference. Luckily, ObliviousGnat was actually helpful.

Slashdot Top Deals

I've got a bad feeling about this.

Working...