{"id":219,"date":"2024-05-07T18:39:00","date_gmt":"2024-05-07T18:39:00","guid":{"rendered":"https:\/\/permutationcity.co.uk\/bp\/?p=219"},"modified":"2024-07-27T08:52:29","modified_gmt":"2024-07-27T08:52:29","slug":"rust","status":"publish","type":"post","link":"https:\/\/permutationcity.co.uk\/bp\/2024\/05\/07\/rust\/","title":{"rendered":"Rust"},"content":{"rendered":"\n<p>I heard about Rust&#8217;s unusual approach to memory management and thought have a look.\n<a href=\"https:\/\/www.oreilly.com\/library\/view\/programming-rust-2nd\/9781492052586\/\">Programming Rust<\/a> from O&#8217;Reilly\nis chunky at about 700 pages and has taken a while to get through but does seem to cover all the bases.\nI&#8217;ve not gone as far as coding in this language so this will just be my opinion looking in from the outside.<\/p>\n\n\n\n<p><a href=\"https:\/\/en.wikipedia.org\/wiki\/Rust_(programming_language)\">Rust<\/a> is a modern general purpose programming language.\nIf your familiar with C++, C# or Java then you&#8217;re going to see a lot of familiar things here:\ndata abstraction and encapsulation, generics, closers and libraries.\nHowever there&#8217;s a big difference: variable ownership and lifetimes.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ownership-and-lifetime\">Ownership and lifetime<\/h2>\n\n\n\n<p>Rust doesn&#8217;t have explicit deletion of pointer objects nor does it have garbage collection.\nInstead the ownership of a variable is tracked throughout it&#8217;s lifetime.\nThis ensure that the variable destroyed or &#8220;dropped&#8221; when appropriate and\nthat nothing can access that variable when it is unsafe to do so.\nThe language enforces strict rules about access to each variable or it&#8217;s references.\nEither a single mutable references can be &#8220;borrowed&#8221; or multiple constant references, but never both at once.\nReferences to a variable can only be borrowed by something with a greater lifetime,\ndangling pointers cannot occur.\nSometimes Rust can infer the lifetime of variables but\nyou may need to add explicit markers to ensure certain variables have matching lifetimes.\nIt looks a bit like adding template parameters to something.\nVariables are allocated on the stack by default but, if you want to use the heap,\nyou can create a <a href=\"https:\/\/doc.rust-lang.org\/std\/boxed\/struct.Box.html\"><code>Box&lt;T&gt;<\/code><\/a> similar to\n<a href=\"https:\/\/en.cppreference.com\/w\/cpp\/memory\/unique_ptr\"><code>std::unique_ptr<\/code><\/a>.\nAssignment is a move operation by default which transfers ownership.<\/p>\n\n\n\n<p>This is all about making code safe by default.\nConcurrency is much easier because lots of unsafe options are just disallowed.\nErrors occur at build time and must be fixed to compile the code.\nI can see this is beneficial in safety critical systems where you have to get it right the first time.\nHowever it also make everything that <em>might<\/em> be an error a build time error\nincluding situations that will never occur in practice.\nIt feels like you will always have to go the extra mile to make correct code even if you don&#8217;t want to.\nI think this could be a problem if your goals and how to achieve them is unclear or if things change along the way.\nI am normally for doing things correctly but this makes me wary.\nBalancing things needs both sides to be available to make choices.\nFor all the good that it brings it also seems to remove choice.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"crates-and-modules\">Crates and modules<\/h2>\n\n\n\n<p><a href=\"https:\/\/doc.rust-lang.org\/book\/ch07-01-packages-and-crates.html\">Crates and packages<\/a> \nare Rust&#8217;s answer for sharing code between projects.\nThese can contain both fully compiled code and generics that must be combined with other code before compilation.\n<a href=\"https:\/\/doc.rust-lang.org\/rust-by-example\/mod.html\">Modules<\/a>\nare it&#8217;s answer to organising source files internally and separating private and public access.\nUnlike other languages I&#8217;ve seen it makes the simplifying assumption that everything within a module\ncan access everything else within a module, even if it is otherwise private.\nThis means that, say, any test code in the module has free access.\nIf you want things to stay private then put it in another module.<\/p>\n\n\n\n<p>Testing and documentation systems are built in.\nTest functions just have to be marked up with an attribute, <code>#[test]<\/code>, to be included in the unit-test.\nDocumentation is marked with a triple slash, <a href=\"https:\/\/doc.rust-lang.org\/reference\/comments.html\"><code>\/\/\/<\/code><\/a>.\nBy default all code snippets within documentation will also be run as unit-tests to ensure correctness.\nThis does make things simple but it could mean a lack of alternative systems.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"matching-and-patterns\">Matching and patterns<\/h2>\n\n\n\n<p>We&#8217;re all familiar with the switch-statement.\nRust doesn&#8217;t have those, it has\n<a href=\"https:\/\/doc.rust-lang.org\/rust-by-example\/flow_control\/match.html\">match-statements<\/a>.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;rust&quot;,&quot;mime&quot;:&quot;text\/x-rustsrc&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Rust&quot;,&quot;language&quot;:&quot;Rust&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;rust&quot;}\">match point {\n    Point { x: 0, y: 0 } =&gt; println!(&quot;At origin&quot;),\n    Point { x: 0, y } =&gt; println!(&quot;On x-axis, y = {}&quot;, y),\n    Point { x, y: 0 } =&gt; println!(&quot;On y-axis, x = {}&quot;, x),\n    Point { x, y } =&gt; println! (&quot;x = {}, y = {}&quot;, x, y)\n}<\/pre><\/div>\n\n\n\n<p>A match-statement can do everything that a switch-statement can do and more.\nIt uses &#8220;<a href=\"https:\/\/doc.rust-lang.org\/reference\/patterns.html\">patterns<\/a>&#8221;\nto check for specific combinations of types and values.\nPartial matches mean you can capture variables and then use those in the response code.\nIt works with literals, ranges, variables, slices, structs and can include arbitrary guard conditions.\nI think this could be a great alternative to some complicated compound if-statements.<\/p>\n\n\n\n<p>Pattern can be used elsewhere, accepting and potentially checking values.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;rust&quot;,&quot;mime&quot;:&quot;text\/x-rustsrc&quot;,&quot;theme&quot;:&quot;material&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:true,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;Rust&quot;,&quot;language&quot;:&quot;Rust&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;rust&quot;}\">let Track { name, artist_id, .. } = song;\n...\nif let Some(artist) = artist_map.get(&amp;artist_id) {\n    ...\n}<\/pre><\/div>\n\n\n\n<p>In simple assignment you can pick out some fields from a struct and ignore the rest.\nIn a function argument you can decompose a struct into it&#8217;s fields.\nTo me decomposing a struct into individual values can be overused.\nIt makes sense when you have an unnamed tuple as you are adding value.\nHowever a normal struct already has perfectly good names which can be referenced.<\/p>\n\n\n\n<p>In an if-statement you can check the value is in the expected form.\nThis is far more interesting and fits well with how Rust reports errors.\nFunctions that can fail either return <a href=\"https:\/\/doc.rust-lang.org\/std\/option\/\"><code>std::option<\/code><\/a> or\n<a href=\"https:\/\/doc.rust-lang.org\/std\/result\/\"><code>std::result<\/code><\/a> both of which have a value if successful and\nthe latter the reason behind any failure.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"generics-and-traits\">Generics and traits<\/h2>\n\n\n\n<p>There is the support for <a href=\"https:\/\/doc.rust-lang.org\/rust-by-example\/generics.html\">generic<\/a>\nclasses and functions you&#8217;d expect to see.\nThere is also support for &#8220;<a href=\"https:\/\/doc.rust-lang.org\/rust-by-example\/trait.html\">traits<\/a>&#8221;\nwhich are similar to C#&#8217;s interfaces.\nA single class can implement multiple traits allowing it to be used anywhere that trait is required.\nOn the other side you can implement a function and\nrequire a specific set of traits be available on the input parameters.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"looping-and-iterators\">Looping and iterators<\/h2>\n\n\n\n<p>Only while-loops and for-loops are available.\nThe first combining neatly with patterns.\nThe second made easy to use with direct support for numeric ranges and\na range of collections and iterator adapters:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Map.html\">map<\/a>: Transforms into another type.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Filter.html\">filter<\/a>: Selects for given property.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Flatten.html\">flatten<\/a>: Concatenates nested iterators.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Take.html\">take<\/a>, <a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.TakeWhile.html\">take_while<\/a>: Use the first part of a list.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Skip.html\">skip<\/a>, <a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.SkipWhile.html\">skip_while<\/a>: Use the last part of a list.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Peekable.html\">peekable<\/a>: Gives any iterator a peek method.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Fuse.html\">fuse<\/a>: Gives any iterator a standard end-of-list behaviour.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Rev.html\">rev<\/a>: Reverses a list.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Chain.html\">chain<\/a>: Go from one iterator to another.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Enumerate.html\">enumerate<\/a>: Give each item a position.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Zip.html\">zip<\/a>: Combine two iterators.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/struct.Cycle.html\">cycle<\/a>: Repeat iterator endlessly.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.count\">count<\/a>, <a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.sum\">sum<\/a>, <a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.product\">product<\/a>: Iterator maths.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.min\">min<\/a>, <a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.max\">max<\/a>, <a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.min_by\">min_by<\/a>, <a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.max_by\">max_by<\/a>: Iterator limits.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.any\">any<\/a>, <a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.all\">all<\/a>: Iterator logic.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.position\">position<\/a>: Value search.<\/li>\n\n\n\n<li><a href=\"https:\/\/doc.rust-lang.org\/std\/iter\/trait.Iterator.html#method.fold\">fold<\/a>: Folds every element into an accumulator using an operation.<\/li>\n<\/ul>\n\n\n\n<p>This is going to cover a lot of the simple iterations with collections without hand coding it.\nC++ has recently gotten a <a href=\"https:\/\/en.cppreference.com\/w\/cpp\/ranges\">ranges library<\/a> but\nit feels clunk in comparison.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"macros\">Macros<\/h2>\n\n\n\n<p>Rust macros fit better into the language than C&#8217;s preprocessor macros but do something similar.\nThere&#8217;s a example in the book of building a <code>json!<\/code> macro which allows properly formatted json\nto be used inside Rust file.\nThese disappointed me.\nMost of them seem so similar to functions that I wish they just <em>were<\/em> functions not an extra set of rules to learn.\nThey obviously let some more advanced initialisation go on but\nthat could probably be done with some simpler initialisation specific system.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"safe-and-unsafe\">Safe and unsafe<\/h2>\n\n\n\n<p>By default the Rust compile ensures you write safe code but you can use the\n<a href=\"https:\/\/doc.rust-lang.org\/book\/ch19-01-unsafe-rust.html\"><code>unsafe<\/code><\/a> to mark code blocks or functions.\nThis reveals that raw pointers are available and multiple systems can change a variable.\nInstead of the language taking care of things it&#8217;s now the developer&#8217;s responsibility.\nIt&#8217;s not that <code>unsafe<\/code> code is necessarily unsafe, it&#8217;s just that it can be.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"in-the-end\">In the end<\/h2>\n\n\n\n<p>Despite a largely presentation it&#8217;s not something I expect to use.\nIt comes down to something really simple.\nI have my own opinions on <a href=\"https:\/\/permutationcity.co.uk\/bp\/2024\/02\/27\/good-names\/\">how to name things<\/a> and\nthis language does things differently.\nSome of the basic keywords are abbreviated, e.g.\n<a href=\"https:\/\/doc.rust-lang.org\/std\/primitive.fn.html\"><code>fn<\/code><\/a>,\n<a href=\"https:\/\/doc.rust-lang.org\/std\/keyword.impl.html\"><code>impl<\/code><\/a>,\n<a href=\"https:\/\/doc.rust-lang.org\/std\/keyword.pub.html\"><code>pub<\/code><\/a>,\n<a href=\"https:\/\/doc.rust-lang.org\/std\/keyword.dyn.html\"><code>dyn<\/code><\/a>.\nWhile I can guess the meanings for these it&#8217;s a bad start.\nI don&#8217;t want to have guess meanings for keywords, types or functions.\nI&#8217;m aware that other languages use abreviations but some of these just seem so unnecessary.<\/p>\n\n\n\n<p>On the other hand if you need safe code, are willing to deal with more build errors and\ndon&#8217;t mind abbreviations then this probably has something for you.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>I heard about Rust&#8217;s unusual approach to memory management and thought have a look. Programming Rust from O&#8217;Reilly is chunky at about 700 pages and has taken a while to get through but does seem to cover all the bases. I&#8217;ve not gone as far as coding in this language so this will just be [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_import_markdown_pro_load_document_selector":0,"_import_markdown_pro_submit_text_textarea":"","footnotes":""},"categories":[34],"tags":[20,26],"class_list":["post-219","post","type-post","status-publish","format-standard","hentry","category-review","tag-books","tag-languages"],"_links":{"self":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/219","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/comments?post=219"}],"version-history":[{"count":2,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/219\/revisions"}],"predecessor-version":[{"id":221,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/posts\/219\/revisions\/221"}],"wp:attachment":[{"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/media?parent=219"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/categories?post=219"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/permutationcity.co.uk\/bp\/wp-json\/wp\/v2\/tags?post=219"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}