 How many of you have tried out Rust? That's not bad, great. That makes my top more or less useless. But for those of you who haven't, hopefully this will give you guys a brief intro into what Rust is about. This talk is not a tutorial into Rust. It's more of a, I will cover the same features of Rust that I find interesting. And maybe we can have further discussion on that. And a disclaimer here is that I'm not an expert. I only started learning Rust recently. So if you guys see any mistakes, feel free to point them out. And to guys who are from a CC++ background who feel superiority complex, feel free to air it out as well. It'll be quite fun. So let's start the talk. So how many of you do systems programming at work? Okay, I only see like a few hands. You know why, right? Because it sucks right now, right? Why does it suck? Oh, yeah. Just before I go there, just a bit about me. My name is Omar. I work as an iOS developer at Kareena. I don't do systems programming languages. Systems programming at work either. So I can't blame anyone. So the reason why it sucks is, it's quite deep, but I'll give you a clue. How many of you know what this is? How many of you know what this is? Yes, it's quite cool. It's a bug with a logo. Like how many of your bugs have logos? Like I don't suppose anyone has a bug with a logo. Well, you might. So you work on security. You might have bugs with logos. But that's not the only bug with a logo. A bit more information about those who have not heard of Heartbleed. Heartbleed is a bug in OpenSSL. And this bug basically results from a very simple reason. The simple reason is there's a buffer override happening that exposes some data that allows an attacker to basically break the encryption and get access to the data you should not have access to. It's quite a simple issue if you think about it. But the fact that this issue occurs in OpenSSL, a library that's been open for so long and has been read it through so many times, this is something that's slightly alarming. And it tells you something is not right with the state of things. And this is not the last security bug, right? I mean, for those of you who follow security matters, there's new CVs coming out every few months, like big ones every day, I believe, for you. You have to bring them out. It's your job, right? So, I mean, there's this one, Shell Shock. It's also not a bug with a logo. You might have heard of it. It was quite hot a few years ago. There's this Good-of-Fail. Do you guys have a Good-of-Fail? It's a very famous bug in Apple, Apple's implementation. Pretty funny bug. There's this thing called Sandworm. It's apparently the effects of Windows systems. And the point is that we have a lot of vulnerabilities in these common essential systems-level libraries that we all use all the time. Why is it so? Why isn't it that these libraries are completely correct and valid for us to use? These kinds of issues. And if you boil it down, right? It boils down to the fact that the languages that these libraries and frameworks are implemented in give you a lot of control. They let you do almost everything. They give you too much freedom. And here's a quote I have from the creator of C++, who essentially says that C++ makes it quite easy to shoot yourself in the foot. When you do it, it'll actually blow your whole leg off because it's that powerful. You're basically driving with no safety. I have another quote here from another great philosopher of the 20th century. All the guys might know him. His name is Uncle Ben. Uncle Ben says with great power comes great bugs, because, once again, because you have so much control, because you have direct access to memory and you can manipulate however you want, naturally that makes it quite easy to introduce certain kinds of bugs that will only be detected at runtime. So with this context, in particular, when we're talking about safety, and we're talking about bugs, I'm talking about memory safety, and I'm talking about bugs related to dealing with memory. But what exactly am I talking about? I'm talking about things like buffer overflows. Buffer overflows occur when you have objects in memory and then, so you have a length check missing somewhere over there in implementation. You forgot to check the length, and then suddenly you overwrite into some other object's memory. Then you have things like buffer overreads where you read, once again, you have a missing length check somewhere, you have an off-by-one error somewhere, and you somehow tend to read into some other object's memory. Things like dangling pointers, where you have the address of an object that's actually been deleted and now that the object is not going to do anything, so when you access it, it'll crash, it'll cause a kernel panic or whatever. You have things like double-threading a pointer which can corrupt the heap in some limitations, and there's a bunch of other similar related memory bugs, and these bugs are quite often, if you deal with languages like C and C++, where you have direct access to memory or where you need to, where you need direct access to memory in order to do whatever programming that you are doing. So the response in general to these kind of issues, obviously, is, GC it broke. Like garbage collector is rock. Why don't you use a garbage collector? Why are you dealing with manual memory management at all? GC solved this problem a long time ago. And for those of you who are wondering what I'm talking about, garbage collection, when I'm referring to garbage collection, I'm referring to garbage collection in languages like Java, languages like Java, JVM, or Ruby's Mark and Street garbage collector, aka any, you have an active garbage collector that actually can accumulate garbage over time and then mark and mark it, and then sweep it afterwards. So maybe it can be paused the world, it may only pause the world, doesn't matter. The point is we have very strong, very smart, very efficient garbage collector, the garbage collector implementation is out there right now. The JVM has been optimized for this particular use case of science into optimizing the garbage collector of our JVM. So why can't we use the JVM or why can't we use similar garbage collection mechanisms in systems programming languages directly? There doesn't seem to be an obvious problem, but there is, sadly. And that problem, the biggest problem by far, is that your destruction of memory when you are running a garbage collector is non-terministic. So this is a problem where, especially so in systems programming languages, because you want to be able to have that direct level of control. So if you're implementing a driver and you want to release some buffer that is super massive immediately before you do something else, you need to make sure that buffer is destroyed before you do anything else. You can't rely on the GC that, especially the GC will clear it and my very light framework or my very light driver will still work fine. You need to be very deterministic about when your object is actually going to be destroyed in the system programming language. Another problem with GCs is that the GCs require, GC systems like JVM, they need a lot more memory than your actual process in order to be efficient. So in the language memory, they start crashing and the efficiency of the GC will be a lot less. So this has repercussions because this means that for system programming, when you're talking about programming OSs, kernels, drivers, you need to be as fast as possible and as memory efficient as possible which won't be possible if you have this kind of limitation. So you can't have GC, if you're talking about embedded systems for example and you only have 32 kilobytes of RAM available to you and the GCs using half of that that's not going to be very optimal for whatever use case you're planning to use it for. Another problem with GCs and this is something that's not mentioned as often is that GCs are often power inefficient and that's because they often have to do RAM sweeps in order to clear memory and when every time you do a RAM sweep a RAM sweep inherently is quite expensive in terms of power. So this is one of the reasons why Apple decided not to adopt a garbage collector for Objective-C for example. So Chris Lattner talked about this recently in a podcast whereby one of the reasons why they didn't continue with Objective-C garbage collection in iOS is because GCs would lead to pretty bad power efficiency so they use something called automatic reference counting instead which I might touch later on. Another problem is GCs have this thing whereby they might pause the execution of your entire program in order to do garbage collection. This is not true of all GCs like JVM has and some very mature garbage collectors have very efficient ways to do this whereby they might use separate processes etc. but regardless there may be some GC pauses and a GC pause if you're dealing with software like an air traffic control system it's not acceptable. You don't want your plane to crash because your JVM is collecting memory for those 100mph or 20mph that kind of delay is not acceptable for a hardware of that system. So that's why garbage collection is not the answer sadly. And with that context that's where Rust comes in so Rust aims to provide a memory model whereby you can get away with memory safety without having to resort to garbage collection. And we look at how it does that but first, as a detour I want to show you how easy Rust Hello World is it's only three lines of code so we already win. We already beat C and C++ right? There's no hash import hash include, IO stream new space, blah blah blah so already to 90% of the audience I think I already won so I think I'll stop here but for those of you who are interested let's go on a bit further so what is Rust? Rust is a systems programming language that is focused on three goals safety, speed and concurrency today we'll be focusing on the safety aspect of it in particular memory safety so when it comes to safety Rust encourages or other forces you to have immutability by default so here's some Rust code that I'll show you guys if I declare a variable called letexico10 and I try to assign it to something else it'll throw compiler error because variable assignments in Rust are immutable by default you've got to reassign stuff if you want to reassign a variable you have to mark it with this mute keyword if you want it to be immutable this is a good thing because usually in most languages like C, C++ immutability is not the default mutability is the default if you want immutability you have to use const etc etc and this is a I mean this is a pretty good thing because this means by default most of our variables we don't have to worry about mutating them ok the other thing about Rust is that the other thing about Rust is that it is strongly typed and it is strongly typed with type inference so you do not always have to provide type signatures to your variables you can provide it so like for example over here I declare a variable X which I say is of type but similarly if I train another variable Y in the second scenario Rust will automatically infer the type based on the value you provide so you don't always have to provide values no I always have to provide type definitions to Rust ok yeah sure so the type inference is that directional or is it really low so if I type then use Y somewhere as a flow which I assign flow to I am not entirely sure the full extent of it but what I do know is that it's not very good like it's nowhere near as good it's not in the middle it's not that class at all it's very basic in the sense that for functions you always have to provide type definitions always but within a function body it can infer so I'm not sure yeah I suspect something like that or something like TypeScript for example it's not a very smart type type inference the reasoning for that is the claim is that in Haskell, even though in Haskell you can infer types always you don't need to provide function definitions it's good practice to do so so we're going to make the boss through anyway yeah okay okay can you repeat yourself so it's considered generic and integer value type but not as and you need to have investment for it oh that's good that's good yeah that's good alright okay so let's carry on I'm going to look at vectors for a bit because vectors are what I'm going to use to explain the memory concepts later in the doc so RAS is vectors and the way you declare a vector is very simple it's just let me equal this vector mission mark this exclamation mark thing is a macro we'll discuss more on macros later but the main point here is this thing will instantiate a vector of type interview inside it and our vectors will store content on the heap this is important and we'll go into this a bit later anyone not familiar with stack versus heap what's the what's the drawback what do these do no worries I will go into it very briefly soon so with that just that it's enough for us to go into the memory model of RAS and what makes RAS special so RAS philosophy in general is zero cost of fractions meaning that whatever abstraction they give to you whatever feature RAS provides to you it should have no performance cost and no cost during runtime so they try to maximize whatever they can at compile time rather than you worry rather than impose certain restrictions on you at runtime that'll affect performance and stuff so keeping that in mind the first concept they have in RAS memory model is this concept of ownership and ownership means that variable bindings have ownership they own whatever they're bound to so for example if I declare this variable here in this function v equals the vector of 1 to 3 the variable binding B has ownership of the vector and this also means that when this binding will go out of scope RAS will free the bound resources so the moment this thing will go out of scope even though it's on the heap it will be free so you don't need to have a free statement there or release or whatever or delete if you go from C++ RAS will free it for you regardless whether it's on stacked heap etc and in this case v on the heap is going to be cleaned up so this is great but there are some caveats to it just to clarify for those of you who don't know what I'm talking about when I refer to stack versus heap here's a very simple diagram to briefly explain it so let's say I have a vector v 1 to 3 and I have some variable i equal to a number 42 which is a primitive so my program stack which will push new labels where they come into scope and will pop them when they go out of scope will look something like this I have v which is a vector and it has this little object that's stored on the stack this object holds an address to the memory on the heap which actually stores the content of the vector and it stores some other data that might be useful for put access so things like the size of the vector will be stored on this object on the stack similarly for this variable i on the stack the value for the 2 is stored directly on the stack because it's a primitive and our registers are big enough to hold it so that's like a very simple view into stacking v one of the issues with ownership is Rust will ensure that there is only one binding to a given resource at a particular dump so what that means is that if I do something like this where I assign a vector v then I create another vector v2 and assign it equal to v and then I try to print the value inside v0 this thing will actually give me a compile time error saying error looks like this use of move value error might be confusing but what it means is that this ownership has moved from v to v2 so v no longer can be used it can no longer be used so why does it do this this is not exactly very intuitive so why does it do this actually the reason it does it is if we if we allow two labels to refer to the same vector the problem that we resolved is we would have two pointers pointing to the address of this the real actual point is owning this resource and if you have any modifications hold on a second if you have any modifications to the resource if you have any modifications to the size for example those changes might not affect the other reference holding the holding the same holding the same vector so that's the main reason why ownership only goes one way you can only have one owner label owning reference so the way ownership works is so let's say you have a code like this where you have a function and you pass this function you pass a vector into this function so v owns this vector now and inside this function this local variable this vector and what happens here is not important but afterwards when you try to print the value of v this thing will again give you this error again and this is like what the hell I can't use this anymore because this vector has already moved ownership to this label and then it moved ownership to this label and now it's gone so how am I supposed to do this kind of model how are we supposed to do anything with this kind of stuff let me go up and do a bit more and do why this is so so the reason this is so is let's say I have let's say I'm counting the number of votes that go on from one in the last election let's say this thing is stored as a vector and let's say that this is what the vector looks like it only has three votes right now or at least three people voting for it right now and let's say I want to smudge up the vote numbers and I declare a mutable I declare a mutable reference I declare a mutable variable where I try to own the vector and then I try to change it so I change it over here in this one what would the ownership mechanism look like when it comes to stack and heap so if you look at it I now have two vectors once my actual votes once my fake votes and my actually my heap size has increased the actual data on the heap has increased because I pushed one more variable there but the variable this thing is now corrupted because this data that I stored on the stack is no longer valid and this is the main reason why like I mentioned before Rust does not allow you to have multiple owners you can only own have one owner for a particular for any particular data on the heap what about if that's the case right then what about one easy way to get around it is to do copying this is something you do in many other languages to prevent multiple references from corrupting or something and we can do that actually for primitive types because Rust by default if you have for example code like this this code will compile and this code will compile because numbers are primitive type and implement this thing called the copy trade which allows you to copy over memory every time you actually do an assignment it's not actually going to move the resource into and assign it to another identifier it will just copy or you can do this for any data type but this is actually quite expensive to do if you do it for all your data types so this is not the right way obviously another issue is that if you use ownership and you want to let's say you're only using ownership to do your programming and if you have a function that you want to pass stuff to every time you pass stuff to it you have to return those identifiers back so you can use them again because once again as the rules say you can only have one identifier at a time according to a particular resource so if you are doing a function called for example over here I have a function that takes two vectors and returns a couple of two vectors and some number and every time I do this I will have to return the vectors back although actually in this case I don't actually want to do anything with the vectors I only want my numeric result I don't have a choice because in order to use the vectors ever again I have to pass them back because as the rule that's what the rules of ownership say which is obviously not the right way to program like if you program that way that's not going to work so in order to get around this Rust has another concept called borrowing and the way borrowing works is borrowing allows you to refer to something that's already owned and what you call do stuff with it but there are certain rules associated with it so for example over here I pass this and and looking operator this and looking sign means that instead of owning the resource let this other person borrow it instead and when you borrow it you don't actually own the resource anymore you just have a view into what the resource is so in this case if I do this this thing will compile fine and I don't need to pass my vectors we won't need to in the result anymore so this and right is actually a reference and reference like I mentioned will borrow ownership rather than owning the resource itself the main difference between ownership and references is that the resource will not be developed when the reference goes out of scope the main problem with us having to pass the references past the resources along when we are doing ownership is that if you don't do that the moment it goes out of scope the resource will be released and you won't have access to it anymore but you don't need to worry about it for references because references will not develop anything ok so in my diagram over here I will refer I will use this dotted arrow as a reference and this white arrow is ownership ok so this is the same thing so these both point to the same what you call same data on the heap this thing is one of the resources is the reference to the resource ok one of the issues with references is so let's say I quote like this whereby I create a vector then I call a function where I try to change the value of this vector using the reference itself this thing will throw an error the error will be you cannot borrow a mutual borrow content blah blah blah so the main just of it is that references are immutable that means that you cannot mutate you mutate the content as a reference by default this is a good thing and this is why it's safe to create as many references as you want because you're not actually ever going to change anything it's just a way for you to access the actual quantity of data but you never actually change it so this is great but what if I actually do want to change stuff there is something called a mutable reference it has a special keyword called animate and this is how you declare a mutable reference so over here what I do is I declare a mutable value called 5 and then in this scope block I declare a y which is a mutable reference to x and if I want to change the value of x I will have to b refer y using the star pointer and then I can change the value so this is how I would do mutation using mutable references in Rust and one of the things you have to notice here is that in order for this to work the variable x the original variable x also needs to be marked as mutable the reason is that if you try to borrow if you try to do a borrow reference after I do a mutable reference from any mutable value it will actually give an error which makes sense because you should not be doing that and the star I mentioned is needed to access the content of the reference I might be wondering why did I need to add these braces why did I need to create a new scope for this to work I will get into that now so naturally for borrowing there is a few rules that Rust forces you to follow at compile time if you don't follow these rules the memory model will break down the first rule is that if you are doing borrowing and you have a reference you cannot last for a scope that is greater than the owner this makes sense because if you do that you have a dining pointer by definition so the other thing the other rule they have is that you can only have one mutable reference exclusively or you can have as many references as you want one or more as so basically you cannot have a mutable reference and a mutable reference at the same time you have to you can only have one mutable reference at any given point in time in your program and this makes sense as well because if you look at it this is the definition of a data-race a data-race would occur if two pointers access the memory location at the same time and one of them is writing one of them is reading this would lead to a data-race but if by definition or if you can ensure a compile time that you only have one reference that is writing at any point in time then you will not face this problem I know what I was reading at that point in time then you will not have this problem at all you will not have to worry about data-races and this is how Rust like this is how Rust makes sure that you don't get into a whole host of memory seed memory bugs that would occur otherwise so let me look at this and do a bit more let me show you an example here I have an example where I have a mutable variable called X so it's the same example as before except that I don't have the graces the nested graces and I do a borrow with Y then I try to add and then I try to print the value of X okay and this thing will give me a compile time error saying that it cannot borrow X as immutable because it is also borrowed as immutable what this means is I have two references right now I have a mutable reference and I also have an immutable reference pointing to my variable X so why is the mutable with mutable reference and I have an immutable reference in the print because when you print something they'll actually create immutable reference to whatever you're printing and this thing will then fail because of that so that's the reason why I need to add a scope inside here so that when Y goes out as we look at the previous example if when Y goes out of scope the reference will be gone it will be thrown out of memory and it's known over there so then in that case this is the okay because I only have one immutable reference now I don't have a mutable reference anymore in this particular case similarly references cannot live longer than the resource they're pointing to so for example if I have some code here where I have a reference Y and inside this block I have a variable X equal 5 I try to assign this assignment where I try to assign the reference Y to the variable X this will also throw a compile time error saying that X does not live long enough for Y to be referenced to it so this is in short compile time it's great I don't need to worry about this anymore so that's it that's the entirety of Rust's memory model and with these two guarantees you will lose a whole host of bugs that will otherwise appear there's a few more concepts of Rust that are interesting that I'll go down with that I'll list them or have one of them is structs as in structs are simple in Rust this is how you declare a struct it's just that if I have a struct out point I just do the type definition and I can use this constructor that's available for free and I can I want to do a mutable version of this struct I can just use the mute operator to do a mutable own label and just the own reference to this struct one of the things to do with structs however is that there is no field level mutability for structs so by default all your fields are mutable or all your fields are mutable so you can't have field level like in class if you have one something is read-only something is not read-only to do that the reason that is so is because mutability in Rust is a property of the binding it's not a property of the object itself and you can do it you really need it by using mutable pointers if you really really need field level mutability so you can have a box inside for example but by default you don't get it so that's interesting another thing to note is struct allows you to have methods on structs so for example let's say I have a method called area that I want to implement on this block circle I can implement it like this I can just declare a function I have this implementation block and this thing returns 14.54 bit and this is quite straightforward though the only interesting thing here is that the method when you refer to self you can refer to yourself in three ways you can either have you can either borrow self with a reference using and in that case you won't see this and here and in that case you know the memory what's your problem and you can have a mutable reference to self as well so this is something interesting that you can have methods that use either of those based on whatever you need if you want to mutate if you use and self obviously you cannot mutate the fields that you have you are not a mutable reference you are a mutable reference so if you want to use if you want to mutate you should use and and self and the thing that's interesting about Rust is static and dynamic dispatch so what this means is so Rust will default to static dispatching and what this actually means is I'll get into it in a bit more detail but the main reason to do that is because it allows several optimizations like inlining your function calls so let me just give you an example of why that matters at all to people using Rust let's say I have a function called add because I don't like that operator and I want to redefine add let's say I have a functional programmer and I don't like using the needs plus operator and I only like this kind of syntax so let's say I redefine add and I use this function in some code if I'm not inline this function will probably generate something like this which basically means that you basically push the argument you set some registers for static state push the arguments you call the function then you call the function and you put the result somewhere then you pop all the registers back that's what normally happens in the function call specific register that you have to set you need to push some params call the function, put the result somewhere then pop all the registers back however if you inline you inline your function what will happen is the instruction will produce something like this add instruction directly and the reason the compiler can do this is because it will expand the code when it's inlining instead of applying a method every time the function is called so this allows a lot of nice compiler optimizations however there are some scenarios where also this thing is called static so this thing is the main advantage for using static dispatch for those of you who don't know static dispatch static dispatch means that you have a fixed address for whatever method that you're calling whereas in dynamic dispatch the address is based on time it's also a method of optimization so if you produce a static generator for static dispatch you will optimize the compile time according to the implementation for the static dispatch for the static dispatch you will optimize the compile time according to the implementation for the static dispatch but the point is that there are several compile optimizations that you can do when you have inlining available so with dynamic dispatch this thing is kind of hard to do because you don't have the address available at compile time so in some scenarios however dynamic dispatching is more effective and the reason for this is if you have some method that takes a generic type in Rust for example let's say I have method do something and this thing takes a generic type T and I have several implementations of this type for this type T let's say I have something I want to do for a byte and something else I want to do for a string by the way Rust will actually implement the code that Rust will generate based on each type so that means that you will actually have a lot of code that if you have a type that extends to if you have a lot of types here this thing can generate a lot of instructions and this will can load your code size so static dispatch by default may not always be quite smart so the compiler is quite smart in choosing whether to use dynamic dispatch static dispatch in these kind of cases so aside from that Rust also has support can you decide between the static or the dynamic? yes you can if you want more control and if you feel like you can do a better job you can actually specify whether you want to be static or dynamic by default basically it depends on every it has some heuristic for most functional things it's static by default but I think if you have generics then I think they will use dynamic but unless some heuristics there are some heuristics that they use Rust also has enums and they are a lot more powerful than enums that you might be used to in cc++ there are actually option types like from a functional background this is quite exciting you can do stuff you can actually pack data inside your enums and this might be something that is very normal for a functional programmer there is something quite new in the systems programming world because cc++ don't really have this so you can represent lots of different kinds of data using this if I have a message type and it can be of different types like if I can be a put message can be change color where I provide some RGB values it can be a move where I change the xy coordinates or it can be a write where I string I can model all this and all these will have the same type at the end of the day so this is good it's good to have another thing that Rust is quite interesting in how it deals with strings so Rust supports UTF-8 properly it doesn't do a shorty job of supporting UTF-8 by hiding it as UTF-16 characters or maybe it's a sequence of non-linear determinant bytes Rust properly supports UTF-8 strings what that means is that I'll get into what that means in a bit but basically when you declare a string a statically allocated string for example like let's say this is the static string over here that's how to put it in your code this thing will generate what we call string literal of type this thing is of type str then this thing is statically allocated and it will exist for the entire duration of the program it will basically be stored in the data segment of the program however if you want something if you want a string that's growable they also have a different string type for that it's called string and you can convert strings from one type to the other you can convert str to string I don't know how they pronounce it actually when they talk about it but you can convert the static string into a heap allocated string by this method and similar to some of the new programming languages like SWIFT for example Rust strings do not support indexing what that means is that if you want to find what character you're at in a string you won't get that by default and the reason they don't do this is because in a UTF-A actually when you index a character it's actually an ON algorithm to do so it's not an ON algorithm the reason is you have to walk to find what's the end letter in that string because UTF-A a character can have dynamics in the variable size so there is an algorithm to go through the UTF-A string to find what the actual end character in terms of unit representation is at the end of the day so in Rust it gives you some helper methods to do that but it also allows you to look at the byte representation of the string if you need it for example I have this string with the Japanese string and if I want to go through the characters that is the human readable characters of this string I can do all this method for both cars this will iterate through this is an innumerable level but I want to use the bytes I can also use the bytes correctly so Rust makes this explicit to the programmer from the get go note about the Swift thing I mentioned Swift actually is dropping this model and actually is going to make their string API easier in the next version so it's no longer like Swift but yeah Rust also has a foreign function interface what that means is that you can integrate Rust code in C code and you can expose Rust functions to be called from C and this opens a lot of interesting possibilities so here is a simple example of how to make it work the gist of it is that if you want to call a function from C you can declare it as an external function and then you need to note the unsafe here so unsafe is basically a safety hatch or you're saying okay Rust I'll take control of the memory myself don't worry about it so if you put anything inside unsafe the Rust model checker will not complete anymore inside this unsafe you can call your C function correctly and it should work fine similarly Rust functions can be called from C and you can do if you want to expose your function to the C world or to any other language with FFI you can just mark the function as an external function and you can pass the no-mangle meta argument so that the symbol name is no-mangle and it generates the function name for you so this is great this means that we can use Rust for more stuff than just systems programming and because Rust supports a large variety of architectures for example it supports ARM which is what I always do before there's a reason it can support ARM is because it uses LVM under the hood and it supports every architecture that LVM supports this means that we can do a lot of exciting stuff with Rust not just do OSes but we can do for example shared libraries if you have iOS and Android clients and you want to do a library that you want to share between those clients you don't have to write in cc++ you can write in Rust for example and it will work fine because Rust will work fine on ARM so that's why I as an iOS developer find Rust by fascinating and I can't wait to use it for actual stuff for actual stuff that I work with that, that's the end of my presentation any questions feel free to do I have a question about the very last time so how low can you go is there some runtime around the code which is committed by Rust and how do you think theoretically what do you mean? you can program it in Rust as in because anything you can do in C you can do in Rust because Rust is not as you you have Rust is not as you, you have an OS available or what you call it can have a runtime it's a purely compiled language so there's no it doesn't assume any runtime is there so it will work fine you can use it to control market controllers quite easily yeah, you can do that as well that's good you can you can, because Rust will compile LVM IR because LVM supports ARM it's fine that's interesting I've seen references you can compile it on iOS for example and it works fine I think you want to compile on the native target without cross compiling from x86 that's what you meant I mean you can just cross compile and compile that's right if you want to compile on the target you mean you want to run the compiler I believe it doesn't want to cross compile so it doesn't want to run on the laptop and then run on the target compile on the target that's his point you can do that like you mentioned if you compile the compile that but I'm not going to show it to you I'm pretty sure you can it's running on the target I'm almost certain because the different tiers are supported I'm sure it's not and ARM is about the highest tier in the long run so I'm almost certain so I'm almost certain Any more questions? Very basic stuff nothing too fancy I'm trying to I'm thinking of using it for some projects at work but we have to share libraries that we can forward over to Rast so we haven't started that yet so do we have a build tool for this one? something like something like that say what? there is a very good build tool it's called cargo it's actually a very well designed build tool that allows a lot of things it does dependency management for you for example it will do things like setting up the project for you it will also do things like running tasks running your stuff or building an executable etc it's quite well developed you can use Jenkins to run cargo for example Jenkins is just a program that's running with everything you can call other programs inside Jenkins so you can have a shell script that calls cargo in your Jenkins configuration a lot of stuff it doesn't have to be done given that a similar program is C++ I think that's a problem right now they haven't optimized it yet I think compiler times will be definitely a lot slower than C++ definitely for large code bases and that's something that I think they plan to work on right now they are focusing on making it more friendly for more generic for more programs but I think they haven't optimized compiler times yet it still runs really quite well so if you want to rest on right here you can use the new parameter configuration that you speed up the load process is it 5x5 incremental or a little better it's not about the algorithm there are many ways of the new parameter configuration but they are planning to import the feature off on the stable you can set up on the developers it's quite fast compared to the current combination it's quite fast any more questions what resources do you suggest I recommend the rustland book so there's this google for a rustland book it's a very good resource for picking up rust it's pretty well it's pretty easy to go through and they it's maintained quite actively by the community so when new versions of rust come in people will submit more requests and update it quite often so that's the best resource quite far aside from rustland book I recommend looking at what companies are doing with rust one of the biggest projects with rust is this project called servo so basically the whole reason why rust came about the story of rust is Mozilla wanted to implement its browser rendering engine and they decided to implement a new programming language to do that and that's how rust came about basically and they are using rust to develop servo right now so I think that's a good guide into how what a big rust project look like or how to manage or how to build a rust big rust project I'm not sure of any other very big projects using rust yet I have a job aspect can you do that for me developer tools for me job aspects job aspects I'm not sure I would say it's a tool that you can use so if you're doing system programming or doing low level stuff then you can use this as a tool but I'm not sure that's because I see my rust it's like that so I think we see a lot of companies using rust any companies using rust once again I'm not entirely sure aside from Mozilla chef web sectors of rust with our companies using rust in production there are a lot of job openings for rust so yeah and then you can try actually yeah that's it that was awesome great thanks thanks Omar