Journal Articles

CVu Journal Vol 32, #2 - May 2020 + Programming Topics
Browse in : All > Journals > CVu > 322 (9)
All > Topics > Programming (877)
Any of these categories - All of these categories

Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.

Title: Reviews

Author: Bob Schmidt

Date: 01 May 2020 17:29:10 +01:00 or Fri, 01 May 2020 17:29:10 +01:00

Summary: The latest roundup of reviews.

Body: 

We are always happy to receive reviews of anything that may be of use, or of interest, to software developers. The emphasis will tend to be on technical books, but we are also interested in less-technical works – for example the humanities or fiction – and in media other than traditional print books.

Do you know of something you think deserves – or does not deserve – a wider audience? Share it here. We're keen to highlight differing opinions on the same work, so if you disagree with a review here do send in your own! Contact Ian Bruntlett at reviews@accu.org.

The Rust Programming Language

By Steve Klabnik and Carol Nichols with contributions from the Rust community, published by No Starch Press (2018), 511 pages, ISBN: 978-1-59327-828-1

Reviewed by Daniel James

Note: The cover illustration here shows the 2019 edition. ISBN: 978-1-718500440. This review applies equally to both print editions and to the online book.

This is the official book on Rust. It’s available free online (doc.rust-lang.org/book) and also as a paperback book. I read the dead-tree version but referred to the online version while playing with code, so this review is based on both. The online version has the advantage of being more up-to-date, but I didn’t find many differences between the two. This was the first book on Rust I’d read, so it was mostly new material, though I had known of Rust’s goal of eliminating certain classes of bugs by catching common errors at compile time.

The book opens with instructions for installation of the compiler and its associated tools, and illustrates the use of cargo – the package-manager-cum-build-system – by taking the reader through the process of writing a simple command-line number-guessing game. Cargo is a powerful part of the Rust environment, so the treatment here is useful. The programming exercise gives a flavour of the Rust language, but in doing so it uses (without fully explaining) some of the key language elements that are not described until later in the book, which I found unhelpful.

There follows some description of Rust’s basic data types and flow control mechanisms before the book moves on to one of the supposedly ‘difficult’ areas of Rust: ownership. The concept of ownership itself is neither new nor particularly difficult, but Rust’s tracking of ownership of memory is a key part of its correctness checking and the language imposes rules preventing, in particular, the sharing of mutable state. The book attempts to explain these rules and the concepts behind them, but to my mind makes fairly heavy weather of it. The reader is led through a series of examples of code that doesn’t compile before the – actually quite simple – rules for taking and for borrowing resources are eventually spelt out. The authors take this opportunity to explain the sorts of error messages that the compiler may generate when the rules are broken, which hardly seems necessary as the Rust compiler gives quite clear, concise, errors; I think it’s something the reader could have been left discover through trial and error.

Moving on through a description of Rust’s approach to struct and tuple datatypes – which could probably, with benefit, have been lumped together with the earlier section on basic data types – we come to a short chapter on Rust’s enum types and an introduction to matching. Rust’s enums are not simple numbers, like those in (say) C, but are sophisticated discriminated union types. Enums are everywhere in Rust and they deserve to be covered earlier and in more detail. Matching, in Rust, is similar to that of a functional language like Haskell. I felt that this, too, deserved a chapter of its own, early on, with some real-world examples rather than the trivial ones presented here; instead there is an introduction to matching here, and a further chapter near the end of the book.

Next we’re led through Rust’s module system and collection types – concentrating here on string types and the issues caused by the fact that Rust’s strings are Unicode stored in UTF-8 – after which comes ‘Error Handling’. Rust is, unsurprisingly, very big on handling of errors, and we’ve had sneak previews of some of the material here in earlier chapters. I would have preferred to have had a fuller description up-front.

Next comes coverage of Rust’s type traits, generic types, and lifetimes – all in the same chapter. Lifetimes are another of the notoriously ‘difficult’ areas of the language: the idea is simple in concept – the compiler needs to know the lifetimes of references in order to enforce its checking for dangling pointers, and often it needs some help from the programmer. This means that the language includes a special syntax for describing lifetimes and the programmer has to understand it, and when to use it. This is pretty important stuff in Rust and, to my mind, deserves more prominent treatment, earlier in the book. Traits and generics are important too, of course, but they’re not related to lifetimes and not fundamental to Rust’s primary goal of catching errors at compile time, and could have been treated later.

After a section on Rust’s automated testing facilities the reader is led through an exercise in writing a grep-like command-line tool before being introduced to closures and iterators. This is followed by additional coverage of the cargo tool and Rust’s online package repository crates.io before the reader is treated to Rust’s take on smart pointers. The discussion of smart pointers and how they fit into Rust’s compile-time correctness checking scheme is important and deserves to have been covered earlier in the book (but after enums and lifetimes, upon which it depends).

There then follows a chapter on ‘Fearless Concurrency’, which explains why Rust’s refusal to allow shared access to writable state leads naturally to safe threading, and one on Rust’s Object-Oriented features (traits again) and the fuller treatment of patterns and matching that we’ve been looking forward to for the last 12 chapters.

Finally there is a section on advanced features, which includes a discussion of ‘unsafe’ Rust code, which is not guaranteed by the Rust compiler to be correct (this includes code written in C or another alien language), followed by one last worked example in which a multi-threaded web server is coded in Rust. The book ends with some appendices, the last of which contains a brief description of Rust’s macro language.

I didn’t hate this book – it was an interesting read and I learned a lot about Rust – but you’ve probably gathered that I didn’t entirely like it, either. I found the order in which language features were presented to be illogical – the reader is forever being asked to take a feature from a future chapter on trust while working through an example – and I felt that there was a lack of meaningful examples. Although the introduction states that the reader is expected to know another language it goes on to explain a number of quite basic programming concepts while glossing over several things that are peculiar to Rust and should have been covered in more depth. There are diagrams to show the layout in memory of Rust’s strings, for example, even though they’re pretty unsurprising, but no diagrams showing the layout of the smart pointer types or enums with data fields about which I had wondered while reading their descriptions. At times the book left me with more questions than it answered. The index, by the way, is terrible. I referred to it several times, and never found an entry for the thing I was trying to look up.

I felt, at the end, that I could read Rust code, but I wasn’t confident that I knew how to write it. I had no feeling for the idioms of the language – perhaps in part because of the book’s habit of introducing each topic by showing code that doesn’t work and then fixing it.

That said: the free online version of the book is certainly accessible and economical, and although it wasn’t my cup of tea, but it may be yours.

Programming Rust

By Jim Blandy and Jason Orendorff, published by O’Reilly (2018), 598 pages, ISBN: 978-1-491-92728-1

Reviewed by Daniel James

Recommended.

I read this book (PR) right after The Rust Programming Language (TRPL). Please be aware that I wasn’t approaching PR with the same fresh innocence as I had TRPL, and although I have tried not to allow this to colour my review, I am not sure that I have succeeded completely.

This book begins, appropriately enough with a short chapter entitled ‘Why Rust?’. As expected, this stresses Rust’s emphasis on type-safety. Less expected was the categorization of Rust as specifically a systems programming language – I’d view it as being just as suitable for applications work. The point being made is that efficient close-to-the-metal languages like C and C++ that are typically used for systems work are significantly less typesafe than ‘softer’ languages like Python. As a C++ programmer, I found the comparison rankled, but the authors do have a point.

The second chapter provides a whistle-stop tour of Rust, touching on a great many language features without really explaining any. This is exactly what I complained about in TRPL, but that doesn’t seem to matter here: the presentation makes it clear that the tour is merely a preview to whet the readers’ appetites – like a trailer in the cinema. It’s a flourish of special effects and we’re not supposed to be able to deduce the whole plot from it.

Chapter 3 begins the description of Rust in earnest. The basic data types are discussed, with comments on their acceptable values and ranges. The detail here seems more complete and better arranged than in TRPL and it’s all easy reading. Tuples, arrays, vectors, strings and slices are all introduced here, though not structs or (sadly) enums which are, as in TRPL, left until far too late.

The next couple of chapters discuss ownership (along with moving/taking and borrowing) and references. Lifetimes are introduced here, too, almost incidentally. These are the two ‘difficult’ topics, where Rust’s strictness causes most problems for newcomers, and the treatment here is fairly painless but perhaps underplays their importance. Rust’s smart pointer types Box and Rc are also discussed here.

Chapter 6 is entitled ‘Expressions’, but is actually an introduction to most of the statement types that are still to be introduced. This is not unreasonable as Rust is an expression-oriented language and most statements can be expressions. Functions are introduced, here, in passing, and there’s enough of an overview of matching to allow if and while to be covered sensibly.

Chapter 7 deals with error handling. As Rust handles errors using Result values that are actually enums, it seems odd to talk about errors before explaining in detail what an enum is. The description here is clear enough, I think, but could have been clearer had the authors simply been able to say ‘Result is an enum type’ and had the reader already known what an enum was.

Chapter 8 discusses modules in Rust, and introduces Rust’s notion of a crate (or external library). Crates are expected to contain their own tests and documentation, so unit tests and document comments are covered here, too, as are dependencies and the role played by the cargo tool in managing them.

Chapter 9 discusses structs and introduces methods and derived traits. Traits were introduced briefly in the tour in chapter 2, but haven’t been covered in any detail, so the discussion of derived traits really demands a little more explanation than is here, but what is here is clear enough. We also touch here on Rust’s generic types.

Chapter 10 brings the long-awaited discussion of enums and of matching. The discussion of enums is thorough and includes a description of how the compiler arranges enum objects, whose fields may be of different sizes, in memory. The discussion of matching might have given more examples of matching of patterns against enum types … but by now we’ve become so familiar with seeing matches against Result and Option types, introduced ahead of time, that there isn’t much new to tell.

Chapter 11 brings a discussion of Rust’s traits, and how they are used to add functionality to types, and to implement generic behaviour. This discussion is carried on in the next couple of chapters in which operator overloading (which depends on traits) and utility traits are discussed. Utility traits include things like Copy and Clone (among others) that are used to add system-defined behaviours to user-defined types so that the compiler can handle them efficiently. Their treatment here is thorough and well-explained.

Chapters follow on closures, iterators, collections, strings and text, and input and output. The last touches on networking while noting that it is beyond the scope of the book. Then comes a chapter on concurrency – one of the longest in the book – which shows how Rust’s type-safety prevents the sharing of mutable data between threads, and shows how communication between threads can nevertheless be safely achieved.

A chapter on macros gives a good overview of writing macros for Rust with a number of practical examples, and finally a chapter on unsafe code brings the book to a close.

PR has some 20% more pages than TRPL, and feels as though it contains about twice as much information with much clearer explanations – though of course it could just be that the material seemed clearer because the subject matter wasn’t all new to me, in which case TRPL must take some of the credit! I was annoyed by a few snide digs at C++ for being less safe than Rust – yes, of course a Rust enum is more typesafe than a C union … but you don’t use a C union in C++ you use something like std::variant – those things aside the book is readable and informative. I felt that the ordering of material wasn’t optimal – in particular: Rust’s enum is pervasive and needs to be explained early on – but for the most part the book doesn’t use features that haven’t yet been covered, so there are few surprises. The index isn’t great, but I did find most things that I tried to look up, so it’s better than many.

C++ Templates The Compete Guide, Second Edition

By David Vandevoorde, Nicolai M Josuttis, Douglas Gregor, published by Pearson Addison-Wesley (2018), 770 pages, http://www.tmplbook.com/

Reviewed by Paul Floyd

Recommended for advanced users. I would suggest that beginners start with something else.

I read the first edition of this book sometime back in 2003 (reviewed here https://accu.org/index.php?module=bookreviews&func=search&rid=506). A great deal has changed in the 15 years between the two editions – 3 new revisions of the C++ standard in particular. This shows up in the page count, and even visibly with the second edition being about 2cm thicker.

This being an ‘upgrade’ read, I thought that I would just be able to skim over the ‘new bits’ in just a few days. Boy, was I wide of the mark… several weeks more like it. Even though, when I look at the two chapter listings, clearly the two books have the same structure, my feeling was that the second edition was an entirely different experience. In part this is due to the large amount of extra material, and also in part a change in my perspective. Back then I thought that I knew a bit about template programming. Now I’m sure that I know little about it.

The book covers templates in depth for all C++ versions up to and including C++17, plus a bit on additions expected a bit in C++20, especially concepts. I won’t list the chapters (there are 28 of them, plus 5 appendices). There are 3 parts to the book, ‘Basics’, ‘Templates in Depth’ and ‘Templates and Design’. I did laugh (out loud even) at the start of part 2 when I read that part 1 (‘Basics’) “is sufficient to answer most questions that may arise in everyday C++”. I doubt that your average C++ programmer’s needs get much past chapter 2 and perhaps chapter 9 (covering instantiation and error messages).

As you would expect, everything regarding templates is covered. Function and Class Templates, Nontype Parameters, much about traits/policies and meta programming. There’s also a lot on overloading and name lookup. There’s considerable coverage of how templates interact with language features, which is very important if you want to understand which types will be used to instantiate your template functions (and to a lesser extent classes). There is some nitty-gritty, but this is no ‘C++ Templates in 7 Days’. The last few chapters cover a few concrete examples such as Tuple and Variant template classes.

The book contains a lot of examples in the form of snippets, often in the form of a few definitions followed a list of 4 or 5 example uses with comments like “// OK T deduced as long int” or “// ERROR”. I found that this bogged down the compiler in my head, and I would often spend 5 or 10 minutes trying to think through why a certain piece of code would resolve to which types. Perhaps I should have skimmed through quickly a first reading and then a more thorough second pass.

I don’t know what sort of reader will benefit from this book. It is neither a tutorial/cookbook nor a straight reference book. I suppose that, as it says on the cover, ‘guide’ is the best way to describe it. Compiler writers (there are a few sections on parsing) and template library writers will want a copy. After that, if you already have copies of Stroustrup, Meyers and Josuttis then you will also want to get this one.

Notes: 

More fields may be available via dynamicdata ..