Learn Rust, Contribute to SAFE, and Save the World


#21

https://doc.rust-lang.org/book/variable-bindings.html
5.1. Variable Bindings

What I learned today:
1: the difference between a variable and a variable binding
2: variables are used to store values i.e. #'s and letters
3: rust uses type inference, which is like a kind of auto complete for programming
4: variable bindings are immutable by default, which means they can not be changed
5: variable bindings must have a value assigned to them or they will receive an error

Comments: Variable bindings are like regular variables with super powers. I am begging to suspect that rust was developed to be dummy proof.


#22

https://doc.rust-lang.org/book/functions.html
5.2. Functions

What I learned today:
1: programs are nothing more than a series of functions
2: program functions are similar to math functions
3: Rust is an expression-based language
4: Statements are a direct action, while expressions return a value

Comments: I am beginning to get a sense of how all of this works. Programs seem to work a lot like math.

Questions:
1: what does a return statement do and how does it work?


#23

A return statement stops the execution of the current subroutine (function) and returns to the position in the code (address) from where the function was called, and resumes execution of code from there. A return statement is not always explicitly written. If not, code execution will simply “return” when the end of the current function code is reached.

In many functions a return statement is followed by a value, the return value. This value can then be used by the code executed after the return, either in an expression or a statement.


#24

Thanks for the help. I have a couple more questions.

If a function returns at the end anyway, why would you need/want to use a return statement?

So the return value is used to transport a value from one function to another?

In your own words what’s the deference between a expression and a statement?


#25

Yes, or possibly to return somewhere in the middle of the function if a particular condition is met.

An expression evaluates to a value, and a statement does not. A statement always changes/does something, while an expression may or may not. If a function is part of an expression, and that function contains statements, then that expression both evaluates to a value and changes/does something.


#26

Thank you that makes a lot of sense.


#27

http://doc.rust-lang.org/book/primitive-types.html
5.3. Primitive Types

What I learned today:
1: boolean is a variable that is true or false
2: char is a single character
3: str is a string of characters
4: Singed integers are just like integer numbers
5: Unsigned integers are just like whole numbers
6: Floating points are just like real numbers
7: Arrays are a fixed-size list of elements of the
same type
8: Tuples are a fixed-size list of elements of the
different types

Comments: Yet more math similarities

Questions:
1: can anyone explain what is happening in this function?

fn foo(x: i32) -> i32 { x }

2: what does -> do?


#28

8: Tuples are a fixed-size list of elements of the
same type

Are you sure about that?

fn foo(x: i32) -> i32 { x }

It return x that is included in the Argument.

fn main() {
let result = foo(5); // It will return 5 and store it in result;
}

2: what does -> do?

Nothing! I think it’s only esthetic.

EDIT: I have hard time with my edit.


#29

I copied my tuples explanation from the array explanation. I meant to say that tuples are of different types.

If it is aesthetic, then could be coded like this…?

fn foo(x: i32) { x }


#30

No it’s required by the syntax if a value is returned by the function. If there is no value returned it’s just like that:
fn foo(x: i32) {
// some stuff to do
}


#31

The i32 after the -> mean the function return a i32 type and nothing else.


#32

So the arrow sends the type into the function?

What does x equal?


#33

When you call the function like my exemple:
fn main() { let result = foo(5);}
x will equal 5;

if it’s fn main() { let result = foo(10);}
x will equal 10

If it’s fn main() { let result1 = foo(5); let result2 = foo(10);}
my variables here result1 will equal 5 and result2 will = 10;


#34

So, x does not equal a value in…
fn foo(x: i32) -> i32 { x }

x only equals a value when the foo function is called and argument is used?


#35

Yes and the only expression you have in your function is “x” inside { } that mean it will return the same value.


#36

Cool, I think I get it know. Thank you so much for your help.


#37

The arrow returns that type of value from the function. In this case the x having no semi colon is the return (expression) so if you run the function as foo(45) the x is set to 45 and that value is returned. So like this

fn double(x : i32)-> i32 {
x * 2
}

will accept a value (x will be bound to the value passed, say 42) and return the value doubled (84 in this case).

so

fn square(x : i32)-> i32 {
x * x // similar to  "return x * x;" but not an expression then if that makes sense 
}

returns the number squared.


#38

Kind of like an algebra function :wink:

Edit: Thank you, the concept really just clicked in my head.


#39

That’s all it is, now you will see what I mean when I dislike huge code bases, as in algebra we factor the code down to small sensible units. Weird in code it’s called re-factor, but essentially it’s factoring.

The other thing to consider is types (like i32 or MyStruct etc.) These should be something and something that is unique and has a particular purpose, easily understood.

Then traits, these are traits of a type, so a vector of some stuff may need to be sorted, so say a vector of u64 integers. For the vector sort to work, it will demand the type is order-able, or can be ordered. This generally means defining a less than function. This less than function is part of the order-able trait. so the function can say, hey I am a vector sort function and I demand the types in the vector have the order-able trait defined, so I can know when I order them then they behave as the designer of the type has allowed for.

People go trait mad, but like algebraic methods you do not need many, possibly 12-18 to satisfy nearly all of maths.

We will also have serialisable traits for types we wish to serialise and send over the network to be de-serialised (or parsed) at the other side.

So lots of power, but keep code small and traits minimal and valid and then things fall in to place. It’s hard but should be as the code is begging you to find the fundamental algorithm/function to express clearly your intent. Doing that is hard but surprisingly liberating as you factor down the mess into a stunning small and reusable algorithm that does exactly what it should and has a clear name.

Lots of fun, but not under time pressure :slight_smile:


#40

There is a sort of Zen quality to it all.