Author Archives: juhan

Rust – il linguaggio – 13

2zN

Eccomi qui /usr/local/share/doc/rust/html/book/enums.html, proseguendo da qui.

Enums

An enum in Rust is a type that represents data that could be one of several possible variants:

enum Message {
    Quit,
    ChangeColor(i32, i32, i32),
    Move { x: i32, y: i32 },
    Write(String),
}

Each variant can optionally have data associated with it. The syntax for defining variants resembles the syntaxes used to define structs: you can have variants with no data (like unit-like structs), variants with named data, and variants with unnamed data (like tuple structs). Unlike separate struct definitions, however, an enum is a single type. A value of the enum can match any of the variants. For this reason, an enum is sometimes called a ‘sum type’: the set of possible values of the enum is the sum of the sets of possible values for each variant.

We use the :: syntax to use the name of each variant: they’re scoped by the name of the enum itself. This allows both of these to work:

let x: Message = Message::Move { x: 3, y: 4 };

enum BoardGameTurn {
    Move { squares: i32 },
    Pass,
}

let y: BoardGameTurn = BoardGameTurn::Move { squares: 1 };

Both variants are named Move, but since they’re scoped to the name of the enum, they can both be used without conflict.

A value of an enum type contains information about which variant it is, in addition to any data associated with that variant. This is sometimes referred to as a ‘tagged union’, since the data includes a ‘tag’ indicating what type it is. The compiler uses this information to enforce that you’re accessing the data in the enum safely. For instance, you can’t simply try to destructure a value as if it were one of the possible variants:

fn process_color_change(msg: Message) {
    let Message::ChangeColor(r, g, b) = msg; // compile-time error
}

Not supporting these operations may seem rather limiting, but it’s a limitation which we can overcome. There are two ways: by implementing equality ourselves, or by pattern matching variants with match expressions, which you’ll learn in the next section. We don’t know enough about Rust to implement equality yet, but we’ll find out in the traits section.

(Solo per Davide: ahemmm… no, questa volta non lo scrivo :wink: ).

Costruttori come funzioni

An enum’s constructors can also be used like functions. For example:

let m = Message::Write("Hello, world".to_string());

is the same as

fn foo(x: String) -> Message {
    Message::Write(x)
}

let x = foo("Hello, world".to_string());

This is not immediately useful to us, but when we get to closures, we’ll talk about passing functions as arguments to other functions. For example, with iterators, we can do this to convert a vector of Strings into a vector of Message::Writes:

let v = vec!["Hello".to_string(), "World".to_string()];
let v1: Vec<Message> = v.into_iter().map(Message::Write).collect();

Ahemmm… :roll: vale l’osservazione di prima, per adesso. È un post che troverà la giustificazione in futuro :grin:

:mrgreen:

Non solo SpaceGames

usborne_computer_books-702x336Il post Computer SpaceGames deve essere considerato solo in inizio :grin:
Sì perché ecco il meraviglioso annuncio: Usborne Releases 1980s Coding Books As Free PDFs.

Raspberry-Pi-Spy-Logo-140x140-OutlineUh! ‘n sito (non ufficiale) dedicato al Raspberry Pi :grin:

Io adesso sarò molto impegnato, prima a scaricare e poi a studiare, sapete com’è allora ero indaffarato su altre cose. Ma voglio aggiornarmi.

Inoltre assolutamente da segnalare: The Official Raspberry Pi Projects Book.

:mrgreen:

Rust – il linguaggio – 12

117

Continuando da qui oggi sono qui: /usr/local/share/doc/rust/html/book/structs.html.

Structs

structs are a way of creating more complex data types. For example, if we were doing calculations involving coordinates in 2D space, we would need both an x and a y value:

let origin_x = 0;
let origin_y = 0;

A struct lets us combine these two into a single, unified datatype:

struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let origin = Point { x: 0, y: 0 }; // origin: Point

    println!("The origin is at ({}, {})", origin.x, origin.y);
}

rs12-0There’s a lot going on here, so let’s break it down. We declare a struct with the struct keyword, and then with a name. By convention, structs begin with a capital letter and are camel cased: PointInSpace, not Point_In_Space.

We can create an instance of our struct via let, as usual, but we use a key: value style syntax to set each field. The order doesn’t need to be the same as in the original declaration.

Finally, because fields have names, we can access the field through dot notation: origin.x.

The values in structs are immutable by default, like other bindings in Rust. Use mut to make them mutable:

struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let mut point = Point { x: 0, y: 0 };

    point.x = 5;

    println!("The point is at ({}, {})", point.x, point.y);
}

rs12-1Rust does not support field mutability at the language level, so you cannot write something like this:

struct Point {  
    mut x: i32,  // nope!
    y: i32,
}

Mutability is a property of the binding, not of the structure itself. If you’re used to field-level mutability, this may seem strange at first, but it significantly simplifies things. It even lets you make things mutable for a short time only:

struct Point {
    x: i32,
    y: i32,
}

fn main() {
    let mut point = Point { x: 0, y: 0 };

    point.x = 5;

    let point = point; // this new binding can’t change now

    point.y = 6; // this causes an error
}

rs12-2

Aggiornamento della sintassi

“Update syntax” dice la guida.
A struct can include .. to indicate that you want to use a copy of some other struct for some of the values. For example:

struct Point3d {
    x: i32,
    y: i32,
    z: i32,
}

This gives point a new y, but keeps the old x and z values. It doesn’t have to be the same struct either, you can use this syntax when making new ones, and it will copy the values you don’t specify:

fn main() {
    struct Point3d {
        x: i32,
        y: i32,
        z: i32,
    }
    let origin = Point3d { x: 0, y: 0, z: 0 };
    let point = Point3d { z: 1, x: 2, .. origin };
    println!("The origin is at ({}, {}, {})", origin.x, origin.y, origin.z);
    println!("The point is at ({}, {}, {})", point.x, point.y, point.z);
   
}

rs12-3

Tuple structs

Rust has another data type that’s like a hybrid between a tuple and a struct, called a ‘tuple struct’. Tuple structs have a name, but their fields don’t:

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

These two will not be equal, even if they have the same values:

let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);

It is almost always better to use a struct than a tuple struct. We would write Color and Point like this instead:

struct Color {
    red: i32,
    blue: i32,
    green: i32,
}

struct Point {
    x: i32,
    y: i32,
    z: i32,
}

Now, we have actual names, rather than positions. Good names are important, and with a struct, we have actual names.

There is one case when a tuple struct is very useful, though, and that’s a tuple struct with only one element. We call this the ‘newtype’ pattern, because it allows you to create a new type, distinct from that of its contained value and expressing its own semantic meaning:

fn main() {
    struct Inches(i32);
    
    let length = Inches(10);
    
    let Inches(integer_length) = length;
    println!("length is {} inches", integer_length);
    
}

rs12-4As you can see here, you can extract the inner integer type through a destructuring let, just as with regular tuples. In this case, the let Inches(integer_length) assigns 10 to integer_length.
Ci devo pensare su un po’ :roll:

Unit-like structs

You can define a struct with no members at all:

struct Electron;
let x = Electron;

Such a struct is called ‘unit-like’ because it resembles the empty tuple, (), sometimes called ‘unit’. Like a tuple struct, it defines a new type.

This is rarely useful on its own (although sometimes it can serve as a marker type), but in combination with other features, it can become useful. For instance, a library may ask you to create a structure that implements a certain trait to handle events. If you don’t have any data you need to store in the structure, you can just create a unit-like struct.

OK, le structs si confermano ancora una volta –come dire– dagli anni ’80… :roll:

:mrgreen:

Rust – il linguaggio – 11

CaKOggi qui: /usr/local/share/doc/rust/html/book/mutability.html proseguendo da qui.

Mutabilità

Mutability, the ability to change something, works a bit differently in Rust than in other languages. The first aspect of mutability is its non-default status:

let x = 5;
x = 6; // error!

We can introduce mutability with the mut keyword:

let mut x = 5;
x = 6; // no problem!

This is a mutable variable binding. When a binding is mutable, it means you’re allowed to change what the binding points to. So in the above example, it’s not so much that the value at x is changing, but that the binding changed from one i32 to another.

If you want to change what the binding points to, you’ll need a mutable reference:

let mut x = 5;
let y = &mut x;

y is an immutable binding to a mutable reference, which means that you can’t bind y to something else (y = &mut z), but you can mutate the thing that’s bound to y (*y = 5). A subtle distinction.

Of course, if you need both:

let mut x = 5;
let mut y = &mut x;

Now y can be bound to another value, and the value it’s referencing can be changed.

It’s important to note that mut is part of a pattern, so you can do things like this:

let (mut x, y) = (5, 6);
fn foo(mut x: i32) {

Mutabilità interna e esterna

Così ho tradotto “Interior vs. Exterior Mutability”.
However, when we say something is ‘immutable’ in Rust, that doesn’t mean that it’s not able to be changed: we mean something has ‘exterior mutability’. Consider, for example, Arc<T>:

use std::sync::Arc;
let x = Arc::new(5);
let y = x.clone();

When we call clone(), the Arc<T> needs to update the reference count. Yet we’ve not used any muts here, x is an immutable binding, and we didn’t take &mut 5 or anything. So what gives?

To understand this, we have to go back to the core of Rust’s guiding philosophy, memory safety, and the mechanism by which Rust guarantees it, the ownership system, and more specifically, borrowing:

You may have one or the other of these two kinds of borrows, but not both at the same time:

  • one or more references (&T) to a resource,
  • exactly one mutable reference (&mut T).

So, that’s the real definition of ‘immutability’: is this safe to have two pointers to? In Arc<T>’s case, yes: the mutation is entirely contained inside the structure itself. It’s not user facing. For this reason, it hands out &T with clone(). If it handed out &mut Ts, though, that would be a problem.

Other types, like the ones in the std::cell module, have the opposite: interior mutability. For example:

use std::cell::RefCell;
let x = RefCell::new(42);
let y = x.borrow_mut();

RefCell hands out &mut references to what’s inside of it with the borrow_mut() method. Isn’t that dangerous? What if we do:

use std::cell::RefCell;
let x = RefCell::new(42);
let y = x.borrow_mut();
let z = x.borrow_mut();

This will in fact panic, at runtime. This is what RefCell does: it enforces Rust’s borrowing rules at runtime, and panic!s if they’re violated. This allows us to get around another aspect of Rust’s mutability rules. Let’s talk about it first.

Mutabilità field-level

Mutability is a property of either a borrow (&mut) or a binding (let mut). This means that, for example, you cannot have a struct with some fields mutable and some immutable:

struct Point {     
    x: i32,
    mut y: i32, // nope
}

The mutability of a struct is in its binding:

struct Point {
    x: i32,
    y: i32,
}

However, by using Cell<T>, you can emulate field-level mutability:

fn main() {
    use std::cell::Cell;
    
    struct Point {
        x: i32,
        y: Cell,
    }
    
    let point = Point { x: 5, y: Cell::new(6) };
    
    point.y.set(7);
    
    println!("y: {:?}", point.y);
    
}

rs11-0We’ve successfully updated y.

Uhmmm… ed è ancora lunga… :roll:
:mrgreen:

Computer SpaceGames

csg
Forse non vale; forse sto facendo una cosa non corretta ma devo farla.
Anche perché io ho cominciato troppo presto ma conosco chi ha vissuto in pieno questa era: quella del Basic, quella dei primi PC, l’inizio dell’era moderna, che ha messo KO i dinosauri, manframes e mini (i mini –ehi! il mio Pr1me— non erano per niente mini, erano armadi quattro stagioni).
Allora quando ho visto il tweet di John Regehr: I had this book ho visto che dovevo dirlo a tutti quelli che non seguono John su Twitter.

Über-fantastico vero?
Del Pr1me ne parlavo, tanto tempo fa, qui.

Rust – il linguaggio – 10

m4

Continuando da qui oggi ecco /usr/local/share/doc/rust/html/book/lifetimes.html.

Lifetimes

Sì contina con i due post precedenti sull’ownership. These three chapters are related, and in order. You’ll need all three to fully understand the ownership system.

Salto il paragrafo “Meta”, sempre uguale.

Lending out a reference to a resource that someone else owns can be complicated. For example, imagine this set of operations:

  • I acquire a handle to some kind of resource.
  • I lend you a reference to the resource.
  • I decide I’m done with the resource, and deallocate it, while you still have your reference.
  • You decide to use the resource.

Uh oh! Your reference is pointing to an invalid resource. This is called a dangling pointer or ‘use after free’, when the resource is memory.

To fix this, we have to make sure that step four never happens after step three. The ownership system in Rust does this through a concept called lifetimes, which describe the scope that a reference is valid for.

When we have a function that takes a reference by argument, we can be implicit or explicit about the lifetime of the reference:

// implicit
fn foo(x: &i32) {
}

// explicit
fn bar<'a>(x: &'a i32) {
}

The 'a reads ‘the lifetime a’. Technically, every reference has some lifetime associated with it, but the compiler lets you elide (i.e. omit, see “Lifetime Elision” below) them in common cases. Before we get to that, though, let’s break the explicit example down:

fn bar<'a>(...)

We previously talked a little about function syntax [/usr/local/share/doc/rust/html/book/functions.html], but we didn’t discuss the <>s after a function’s name. A function can have ‘generic parameters’ between the <>s, of which lifetimes are one kind. We’ll discuss other kinds of generics later in the book [/usr/local/share/doc/rust/html/book/generics.html], but for now, let’s just focus on the lifetimes aspect.

We use <> to declare our lifetimes. This says that bar has one lifetime, 'a. If we had two reference parameters, it would look like this:

fn bar<'a, 'b>(...)

Then in our parameter list, we use the lifetimes we’ve named:

...(x: &'a i32)

If we wanted an &mut reference, we’d do this:

...(x: &'a mut i32)

If you compare &mut i32 to &'a mut i32, they’re the same, it’s just that the lifetime 'a has snuck in between the & and the mut i32. We read &mut i32 as ‘a mutable reference to an i32’ and &'a mut i32 as ‘a mutable reference to an i32 with the lifetime 'a’.

Nelle struct

You’ll also need explicit lifetimes when working with structs:

struct Foo {
    x: &'a i32,
}

fn main() {
    let y = &5; // this is the same as `let _y = 5; let y = &_y;`
    let f = Foo { x: y };

    println!("{}", f.x);
}

rs10-0As you can see, structs can also have lifetimes. In a similar way to functions,

struct Foo<'a> {

declares a lifetime, and

x: &'a i32

uses it. So why do we need a lifetime here? We need to ensure that any reference to a Foo cannot outlive the reference to an i32 it contains.

Blocchi impl

Let’s implement a method on Foo:

struct Foo {
    x: &'a i32,
}

impl Foo {
    fn x(&self) -> &'a i32 { self.x }
}

fn main() {
    let y = &5; // this is the same as `let _y = 5; let y = &_y;`
    let f = Foo { x: y };

    println!("x is: {}", f.x());
}

rs10-1As you can see, we need to declare a lifetime for Foo in the impl line. We repeat 'a twice, just like on functions: impl<'a> defines a lifetime 'a, and Foo<'a> uses it.
Ahemmm:roll:

Lifetimes multiple

If you have multiple references, you can use the same lifetime multiple times:

fn x_or_y<'a>(x: &'a str, y: &'a str) -> &'a str {

This says that x and y both are alive for the same scope, and that the return value is also alive for that scope. If you wanted x and y to have different lifetimes, you can use multiple lifetime parameters:

fn x_or_y<'a, 'b>(x: &'a str, y: &'b str) -> &'a str {

In this example, x and y have different valid scopes, but the return value has the same lifetime as x.

Pensare per scopes

A way to think about lifetimes is to visualize the scope that a reference is valid for. For example:

fn main() {
    let y = &5;     // -+ y goes into scope
                    //  |
    // stuff        //  |
                    //  |
}                   // -+ y goes out of scope

Adding in our Foo:

struct Foo {
    x: &'a i32,
}

fn main() {
    let y = &5;           // -+ y goes into scope
    let f = Foo { x: y }; // -+ f goes into scope
    // stuff              //  |
                          //  |
}                         // -+ f and y go out of scope

Our f lives within the scope of y, so everything works. What if it didn’t? This code won’t work:

struct Foo {
    x: &'a i32,
}

fn main() {
    let x;                    // -+ x goes into scope
                              //  |
    {                         //  |
        let y = &5;           // ---+ y goes into scope
        let f = Foo { x: y }; // ---+ f goes into scope
        x = &f.x;             //  | | error here
    }                         // ---+ f and y go out of scope
                              //  |
    println!("{}", x);        //  |
}

rs10-2atz! :shock: Whew! As you can see here, the scopes of f and y are smaller than the scope of x. But when we do x = &f.x, we make x a reference to something that’s about to go out of scope.

Named lifetimes are a way of giving these scopes a name. Giving something a name is the first step towards being able to talk about it.

'static

The lifetime named ‘static’ is a special lifetime. It signals that something has the lifetime of the entire program. Most Rust programmers first come across 'static when dealing with strings:

let x: &'static str = "Hello, world.";

String literals have the type &'static str because the reference is always alive: they are baked into the data segment of the final binary. Another example are globals:

static FOO: i32 = 5;
let x: &'static i32 = &FOO;

This adds an i32 to the data segment of the binary, and x is a reference to it.

Lifetime elision

Rust supports powerful local type inference in function bodies, but it’s forbidden in item signatures to allow reasoning about the types based on the item signature alone. However, for ergonomic reasons a very restricted secondary inference algorithm called “lifetime elision” applies in function signatures. It infers only based on the signature components themselves and not based on the body of the function, only infers lifetime parameters, and does this with only three easily memorizable and unambiguous rules. This makes lifetime elision a shorthand for writing an item signature, while not hiding away the actual types involved as full local inference would if applied to it. (Cioè :shock: mica sicuro di aver capito :roll:, spero che la spiegazione renda questa frase barocca e principalmente decorativa).

When talking about lifetime elision, we use the term input lifetime and output lifetime. An input lifetime is a lifetime associated with a parameter of a function, and an output lifetime is a lifetime associated with the return value of a function. For example, this function has an input lifetime:

fn foo<'a>(bar: &'a str)

This one has an output lifetime:

fn foo<'a>() -> &'a str

This one has a lifetime in both positions:

fn foo<'a>(bar: &'a str) -> &'a str

Here are the three rules:

  • Each elided lifetime in a function’s arguments becomes a distinct lifetime parameter.
  • If there is exactly one input lifetime, elided or not, that lifetime is assigned to all elided lifetimes in the return values of that function.
  • If there are multiple input lifetimes, but one of them is &self or &mut self, the lifetime of self is assigned to all elided output lifetimes.

Otherwise, it is an error to elide an output lifetime.

Esempi

Here are some examples of functions with elided lifetimes. We’ve paired each example of an elided lifetime with its expanded form.

fn print(s: &str); // elided
fn print(s: &'a str); // expanded

fn debug(lvl: u32, s: &str); // elided
fn debug(lvl: u32, s: &'a str); // expanded

// In the preceding example, `lvl` doesn’t need a lifetime because it’s not a
// reference (`&`). Only things relating to references (such as a `struct`
// which contains a reference) need lifetimes.

fn substr(s: &str, until: u32) -> &str; // elided
fn substr(s: &'a str, until: u32) -> &'a str; // expanded

fn get_str() -> &str; // ILLEGAL, no inputs

fn frob(s: &str, t: &str) -> &str; // ILLEGAL, two inputs
fn frob(s: &'a str, t: &'b str) -> &str; // Expanded: Output lifetime is ambiguous

fn get_mut(&mut self) -> &mut T; // elided
fn get_mut(&'a mut self) -> &'a mut T; // expanded

fn args(&mut self, args: &[T]) -> &mut Command; // elided
fn args(&'a mut self, args: &'b [T]) -> &'a mut Command; // expanded

fn new(buf: &mut [u8]) -> BufWriter; // elided
fn new(buf: &'a mut [u8]) -> BufWriter; // expanded

:evil: quasi panico, forse.

:mrgreen:

Visto nel Web – 221

Allora oggi ci sono le categorie, ancora provvisorie, devo migliorarele, servono suggerimenti. CMQ ecco cosa ho visto nel Web.

domenico-scilipoti
Internet speed in Europe
#:Web, Internet
::: ianbremmer

Data about os used at the FOSDEM
#:free open source software
::: Google+

General birthday problem
#:algoritmi, codice
::: John D. Cook

European SpaceDataHighway’s first satellite lifts off
#:hardware #:sicurezza, spionaggio
::: Engadget

Apple: Losing Out On Talent and In Need of a Killer New Device
#:ditte
::: Slashdot

nq160122

Un attacco informatico e 50 milioni di euro in fumo … quale lezione?
#:sicurezza, spionaggio
::: Tech Economy

What is open hardware?
#:hardware #:free open source software
::: Opensource

Here’s some of the Apollo 11 source code
#:storia
::: randal_olson

Rust for Web
#:linguaggi di programmazione
::: Medium

Microsoft Edge’s Private Browsing Mode Isn’t Actually Private
#:sicurezza, spionaggio
::: Slashdot

CZUQtAcW0AAUjaM

Feature Comparison: LibreOffice – Microsoft Office
#:free open source software
::: The Document Foundation

Big Satellite Systems, Simulated On Your Desktop
#:Web, Internet #:innovazioni, futuro
::: Slashdot

La Marca monomarca
#:free open source software
::: Tech Economy

#madswag
#:economia #:spam
::: kOoLiNuS

RTFM
#:sistemi operativi
::: cosmo e dintorni

2012-05-31-einstein

Back to the stone age!
#:dispositivi mobili #:umorismo
::: SciencePorn

#lisp Picrin – a lightweight R7RS scheme implementation in pure C89
#:lisp e derivati
::: reddit_lisp

#lisp SBCL 1.3.2 released! | redd.it/43kuq7
io sono fermo a 1.2.14, come passa il tempo; sono vecchio :roll:
#:lisp e derivati
::: reddit_lisp

emacs is like a hobby
#:umorismo
::: ErgoEmacs

Mary livecodes a drum machine
#:algoritmi, codice
::: Mary Rose Cook

road

Default random-number generators are slow
#:algoritmi, codice
::: Daniel Lemire

How To Build a TimesMachine
#:algoritmi, codice #:storia #:dati, raccolta
::: Slashdot

Alphabet Becomes The Most Valuable Public Company In The World
#:ditte
::: TechCrunch

Harvard: No, Crypto Isn’t Making the FBI Go Dark
#:sicurezza, spionaggio
::: Slashdot

The Guix System Distribution
#:sistemi operativi #:free open source software
::: GNU

dark-side

On WebKit Security Updates
#:sicurezza, spionaggio
::: GNOME Blogs

“Così abbiamo convinto il Ministero della Difesa a convertirsi all’open-source”
#:free open source software
::: Motherboard

Expand Your #Programming Vocabulary (for Beginners)
#:linguaggi di programmazione
::: Donearm

Backslashes
#:umorismo
::: xkcd

12647446_1294591863904147_7754700145032717863_n

Safe Harbor addio, arriva il nuovo accordo Privacy Shield tra Europa e USA
#:sicurezza, spionaggio #:dati, raccolta
::: Downloadblog

8 non-code ways to contribute to open source
#:free open source software
::: Opensource

Microsoft steps up AI push with Swiftkey deal
#:ditte
::: Financial Times

Gavin McGimpsey wrote a nice macro outline as an introduction to Racket macros
#:lisp e derivati
::: racketlang

Tianhe-2 is the world’s fastest supercomputer powered by Linux
#:sistemi operativi
::: letozaf

12670617_10208843459187057_3563909602246832200_n

The TPP is a continuation of our disastrous trade policies that have devastated manufacturing cities and towns all over this country
#:economia
::: BernieSanders

Latest #Windows10 May Have a #Linux Subsystem Hidden Inside!
#:sistemi operativi
::: EPietrafesa

Be sure to read our #PrivacyShield fact sheet to better understand the agreement
#:sicurezza, spionaggio
::: CommerceGov

Linux 0.11 source code
#:storia #:sistemi operativi #:free open source software
::: gigitux

UN panel ‘rules in Julian Assange’s favour’
#:sicurezza, spionaggio
::: BBC ::: la Repubblica

CaKOa5rWYAAMWEC

Google’s new head of search is an AI research leader
#:ditte #:algoritmi, codice
::: Engadget

Today, 77% of adults ages 30-49 use social media, compared with 8% in 2005
#:social media
::: pewinternet

This looks big, if early reports are correct: UN finds UK unlawfully detained @WikiLeaks founder #Assange
#:sicurezza, spionaggio
::: Snowden

Torrents Time Lets Anyone Launch Their Own Web Version of Popcorn Time
#:Web, Internet
::: Slashdot

Fear of Macros
#:lisp e derivati
devo ancora leggerlo, poi vi racconto :wink:
::: Greg Hendershott

CaP4aLIWAAIeuxg

Latest Windows 10 May Have a Linux Subsystem Hidden Inside
#:sistemi operativi
::: The Hacker News

With Rand Paul out of the race, is there anyone left to fight the NSA?
#:sicurezza, spionaggio
::: The Verge

L’ultrabroadband in Italia
#:Web, Internet
::: manteblog

GNU Guile 2.1.2 released!
::: davexunit

Mozilla to end development on Firefox OS for smartphones after v2.6
::: daw985

vRF9b47

ABC della sicurezza: Furto di Identità
#:sicurezza, spionaggio
::: Tech Economy

“Sfiduciati” sulla strada del CAD: coinvolgiamo tutti gli stakeholder
::: Forum PA

Apple, pizza e mandolino
#:ditte
::: Un altro orizzonte

New Concurrent Hash Maps for C++
#:algoritmi, codice
::: Preshing on Programming

A Brief History of Open Source Code – Infographic by Kinvey
#:free open source software #:storia
::: BSD MAG

CaZTSXjWEAALCet

Privacy, il nuovo accordo tra Europa e Usa ci tutela davvero?
#:sicurezza, spionaggio
::: L’Espresso

AI Is Transforming Google Search. The Rest of the Web Is Next
#:ditte #:innovazioni, futuro #:Web, Internet
::: Wired

Riconoscere un font
::: patfumetto

Heisenberg developers
#:programming, codice, snippet
::: Grab the Blaster

Marco Rubio Wants To Permanently Extend NSA Mass Surveillance
#:sicurezza, spionaggio
::: Slashdot

12654482_10208805769971395_5498060997450067380_n

Firefox 44 Deletes Fine-Grained Cookie Management
#:Web, Internet #:sicurezza, spionaggio
::: Slashdot

Renzi, Carrai e Padoan. Cosa succede davvero sulla cyber security
#:sicurezza, spionaggio
::: Formiche

Wearable Devices Market Worth $28.7 Billion In 2016: Smartwatch To Drive the Growth
#:dispositivi mobili
::: Dazeinfo

The Essence of Scala
#:programmazione funzionale
::: Scala

X projects: Alphabet’s ‘moonshot’ ventures that could change the world
#:ditte #:innovazioni, futuro
::: the Guardian

12669607_946359752079504_4494371113854956777_n

Error 53: Apple remotely bricks phones to punish customers for getting independent repairs
#:ditte
::: Boing Boing

Writing an Infrared Logic Analyser in Racket
#:lisp e derivati
::: (expr:labs)

Racket ships with a fantastic tileset for 2D games
#:lisp e derivati
::: thelittlelisper

Callback Hell: A guide to asynchronous #JavaScript programming
#:linguaggi di programmazione
::: Donearm

Brotli has potential to replace GZIP for compression of dynamic assets
#:algoritmi, codice
::: openwebdaily

12647115_537654666395690_8314991193723485884_n

The Performance of Ubuntu Linux Over the Past 10 Years
#:sistemi operativi
::: Slashdot

Don’t Sleep On New Data Privacy Regulations
#:sicurezza, spionaggio
::: TechCrunch

Six degrees of separation?
#:sicurezza, spionaggio #:Web, Internet
::: Snowden

The Linux user experience
#:umorismo
::: thegrugq

Modern Java – A Guide to Java 8
#:manuali, how to #:linguaggi di programmazione
::: winterbe
CaiaevoW0AAvpr3

Rust – il linguaggio – 9

t3

Oggi qui: /usr/local/share/doc/rust/html/book/references-and-borrowing.html, continuando da qui.

References and Borrowing

Non traduco tanto quello si usa :roll:
This guide is two of three presenting Rust’s ownership system. Come detto nel post appena citato.

Meta

Importante quello che dice ma è la ripetizione di quello già detto. OK, salto, tanto i post vanno letti in sequenza, si sa.
With that in mind, let’s learn about borrowing.

Borrowing

At the end of the ownership [sì, sempre quel post] section, we had a nasty function that looked like this:

fn foo(v1: Vec, v2: Vec) -> (Vec, Vec, i32) {
    // do stuff with v1 and v2

    // hand back ownership, and the result of our function
    (v1, v2, 42)
}
let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];
let (v1, v2, answer) = foo(v1, v2);

This is not idiomatic Rust, however, as it doesn’t take advantage of borrowing. Here’s the first step (l’ho modificato per togliere i warnings):

fn main() {
    fn foo(v1: &Vec, v2: &Vec) -> i32 {
        // do stuff with v1 and v2
        let x = v1[1] + v2[2];
        println!("x vale {}", x);
        // return the answer
        42
    }
    
    let v1 = vec![1, 2, 3];
    let v2 = vec![1, 2, 3]; 
    let answer = foo(&v1, &v2); // we can use v1 and v2 here!
    println!("La risposta è {}", answer);
}

rs9-0Instead of taking Vec<i32>s as our arguments, we take a reference: &Vec<i32>. And instead of passing v1 and v2 directly, we pass &v1 and &v2. We call the &T type a ‘reference’, and rather than owning the resource, it borrows ownership. A binding that borrows something does not deallocate the resource when it goes out of scope. This means that after the call to foo(), we can use our original bindings again.

References are immutable, just like bindings. This means that inside of foo(), the vectors can’t be changed at all:

fn foo(v: &Vec) {
     v.push(5);
}
let v = vec![];
foo(&v);

errors with: error: cannot borrow immutable borrowed content `*v` as mutable v.push(5);

Pushing a value mutates the vector, and so we aren’t allowed to do it.

&mut references

There’s a second kind of reference: &mut T. A ‘mutable reference’ allows you to mutate the resource you’re borrowing. For example:

fn main() {
    let mut x = 5;
    {
        let y = &mut x;
        *y += 1;
    }
    println!("{}", x);
}

rs9-1We make y a mutable reference to x, then add one to the thing y points at. You’ll notice that x had to be marked mut as well, if it wasn’t, we couldn’t take a mutable borrow to an immutable value.

You’ll also notice we added an asterisk (*) in front of y, making it *y, this is because y is an &mut reference. You’ll also need to use them for accessing the contents of a reference as well.

Otherwise, &mut references are just like references. There is a large difference between the two, and how they interact, though. You can tell something is fishy in the above example, because we need that extra scope, with the { and }. If we remove them, we get an error:

error: cannot borrow `x` as immutable because it is also borrowed as mutable
    println!("{}", x);
                   ^

note: previous borrow of `x` occurs here; the mutable borrow prevents subsequent moves, borrows, or modification of `x` until the borrow ends let y = &mut x;.

note: previous borrow ends here
fn main() {

}
^

As it turns out, there are rules. :roll: Logico ma pistino assay! :roll:

Le regole

The rules dice lui.
First, any borrow must last for a scope no greater than that of the owner. Second, you may have one or the other of these two kinds of borrows, but not both at the same time:

  • one or more references (&T) to a resource,
  • exactly one mutable reference (&mut T).

You may notice that this is very similar, though not exactly the same as, to the definition of a data race:

There is a ‘data race’ when two or more pointers access the same memory location at the same time, where at least one of them is writing, and the operations are not synchronized.

With references, you may have as many as you’d like, since none of them are writing. If you are writing, you need two or more pointers to the same memory, and you can only have one &mut at a time. This is how Rust prevents data races at compile time: we’ll get errors if we break the rules.
Qui mi sa che rischio di dimenticarmelo :roll: anche se è tremendamente logico :grin:

With this in mind, let’s consider our example again.

Pensare per scopes

Here’s the code:

let mut x = 5;
let y = &mut x;

*y += 1;

println!("{}", x);

This code gives us this error: error: cannot borrow `x` as immutable because it is also borrowed as mutable println!("{}", x);

This is because we’ve violated the rules: we have a &mut T pointing to x, and so we aren’t allowed to create any &Ts. One or the other. The note hints at how to think about this problem: l’indicatore di dov’è l’errore (il segno ^) si trova sotto la } finale.

In other words, the mutable borrow is held through the rest of our example. What we want is for the mutable borrow to end before we try to call println! and make an immutable borrow. In Rust, borrowing is tied to the scope that the borrow is valid for. And our scopes look like this:

let mut x = 5;
let y = &mut x;    // -+ &mut borrow of x starts here
                   //  |
*y += 1;           //  |
                   //  |
println!("{}", x); // -+ - try to borrow x here
                   // -+ &mut borrow of x ends here

The scopes conflict: we can’t make an &x while y is in scope.

So when we add the curly braces:

let mut x = 5;
{
    let y = &mut x; // -+ &mut borrow starts here
    *y += 1;        //  |
}                   // -+ ... and ends here

println!("{}", x);  // <- try to borrow x here

There’s no problem. Our mutable borrow goes out of scope before we create an immutable one. But scope is the key to seeing how long a borrow lasts for.

Problemi che il borrowing previene

Why have these restrictive rules? Well, as we noted, these rules prevent data races. What kinds of issues do data races cause? Here’s a few.

invalidazione di iteratori
One example is ‘iterator invalidation’, which happens when you try to mutate a collection that you’re iterating over. Rust’s borrow checker prevents this from happening:

fn main() {
    let v = vec![1, 2, 3];
    for i in &v {
        println!("{}", i);
    }
}

rs9-2As we iterate through the vectors, we’re only given references to the elements. And v is itself borrowed as immutable, which means we can’t change it while we’re iterating:

fn main() {
    let mut v = vec![1, 2, 3];
    for i in &v {
        println!("{}", i);
        v.push(34);
    }
}

rs9-3We can’t modify v because it’s borrowed by the loop.

uso dopo il free (o devo dire deallocazione?)
References must not live longer than the resource they refer to. Rust will check the scopes of your references to ensure that this is true.
If Rust didn’t check this property, we could accidentally use a reference which was invalid. For example:

fn main() {
    let y: &i32;
    {
        let x = 5;
        y = &x;
    }
    println!("{}", y);

rs9-4y is only valid for the scope where x exists. As soon as x goes away, it becomes invalid to refer to it. As such, the error says that the borrow ‘doesn’t live long enough’ because it’s not valid for the right amount of time.
The same problem occurs when the reference is declared before the variable it refers to. This is because resources within the same scope are freed in the opposite order they were declared:

fn main() {
    let y: &i32;
    let x = 5;
    y = &x;
    println!("{}", y);

rs9-5In the above example, y is declared before x, meaning that y lives longer than x, which is not allowed.

Pensierino della sera (anche se non è l’ora): da sempre * e & sono –come dire… :roll:

:mrgreen:

Ancora Wallis

bb9Ancora qualche considerazioni sul post relativo al prodotto di Wallis.
Intanto la sua inefficienza, per ottenere un approssimazione decente occorrono davvero tante iterazioni, ecco, con Python:

#!/usr/bin/python3

# calcolo di pi con la formula di Wallis

p = 1            
lsup = 1000 * 1000 * 100 + 1
stp = lsup // 10
for n in range(1, lsup):
    t = 4 * pow(n, 2.0)
    p = p * t /(t - 1)
    if n % stp == 0:
    	print(n, p, 2 * p)

w-py

46 secondi per 100 milioni di iterazioni :grin:

Ma molto più interessante che non servono; dopo i 40 milioni il risultato non migliora; Il numero di cifre previste per il float è stato raggiunto e fine. Vero è che anche con Python si potrebbe fare molto meglio, con NumPy/SciPy, per esempio.

Ma se invece provassimo con Racket, il mio linguaggio preferito (ce ne sono tanti altri pari merito –quasi)?
Racket non approssima, ha il tipo rational [/usr/racket/doc/guide/numbers.html] e quindi si può prevedere… Provo.

Adesso devo confessare una cosa personale: nei periodi in cui mi occupo di linguaggi di programmazione diversi le mie prestazioni diminuiscono fortemente. Ultimamente sono alle prese con Rust (molto interessante, grazie Robitex), Python (da sempre, sono tendenzialmente evangelista Python) e –almeno in questo momento– Racket. Ecco faccio confusione, non riesco a ragionare in termini funzionali. Il codice che segue è la traduzione dello script Python, non è bello, potrei fare di meglio, abuso di set!, cosa evitabile con let (e let*). Anzi a mia idea era quella, non è detto che in futuro… :wink:
Inoltre, per ragioni di tempo il numero delle iterazioni è ridotto, un solo milione. Ecco cosa ottengo

#lang racket                        ;; wallis
                                    ;; product 
(define (wallis)
  (define t 0)
  (define p 1)
  (for ([n (range 1 1000001)])      ;; 1M
    (set! t (* 4 n n))
    (set! p (/ (* p t) (- t 1)))
    (when (zero? (modulo n 100000)) ;; 100K
      (printf "~a ~a ~a \n"
              n (exact->inexact p)
              (exact->inexact (* 2 p))))))

(wallis)

Semplice vero? Uso la procedura exact->inexact per visualizzare i risultati altrimenti è il diluvio.

Alla partenza mi trovo in queste condizioni:

i

Sì, una delle CPU è subito riservata al task, poi si procede

i2

intanto attendo, attendo, attendo e infine:

fine2

Quasi 81 minuti! E non si è raggiunta l’approssimazione di Python. Bisognerebbe proseguire ancora. Ma la vita è troppo breve; e io sono in ritardo :roll:

Racket dev’essere preso per il suo verso. E roll over Beethoven Wallis (quasi-cit.) :grin:

:mrgreen:

Rust – il linguaggio – 8

dorai

Continuando da qui oggi sono qui: /usr/local/share/doc/rust/html/book/ownership.html.

Ownership

Come tradurre? Possesso, sì, forse sì. Ma meglio vedere cos’è secondo Rust.

This is one of Rust’s most unique and compelling features, with which Rust developers should become quite acquainted. Ownership is how Rust achieves its largest goal, memory safety. There are a few distinct concepts, each with its own chapter:

  • ownership, which you’re reading now;
  • borrowing [/usr/local/share/doc/rust/html/book/references-and-borrowing.html], and their associated feature ‘references’;
  • lifetimes [/usr/local/share/doc/rust/html/book/lifetimes.html], an advanced concept of borrowing.

These three chapters are related, and in order. You’ll need all three to fully understand the ownership system.

Meta

Before we get to the details, two important notes about the ownership system.
Rust has a focus on safety and speed. It accomplishes these goals through many ‘zero-cost abstractions’, which means that in Rust, abstractions cost as little as possible in order to make them work. The ownership system is a prime example of a zero-cost abstraction. All of the analysis we’ll talk about in this guide is done at compile time. You do not pay any run-time cost for any of these features.
However, this system does have a certain cost: learning curve. Sì, conosco, e già sentito. Per non spaventare e spaventarmi faccio un salto avanti.

There is good news, however: more experienced Rust developers report that once they work with the rules of the ownership system for a period of time, they fight the borrow checker less and less. Yeah! :grin:

With that in mind, let’s learn about ownership.

Ownership

Variable bindings have a property in Rust: they ‘have ownership’ of what they’re bound to. This means that when a binding goes out of scope, Rust will free the bound resources. For example:

fn foo() {
    let v = vec![1, 2, 3];
}

When v comes into scope, a new Vec<T> is created. In this case, the vector also allocates space on the heap, for the three elements. When v goes out of scope at the end of foo(), Rust will clean up everything related to the vector, even the heap-allocated memory. This happens deterministically, at the end of the scope.

Semantica spostata

“Move semantics” dice la guida.
There’s some more subtlety here, though: Rust ensures that there is exactly one binding to any given resource. For example, if we have a vector, we can assign it to another binding:

let v = vec![1, 2, 3];
let v2 = v;  // attenzione qui :sad:

But, if we try to use v afterwards, we get an error:

fn main() {
    let v = vec![1, 2, 3];
    let v2 = v;
    println!("v[0] is: {}", v[0]);
}

rs8-0

A similar thing happens if we define a function which takes ownership, and try to use something after we’ve passed it as an argument:

fn main() {
    fn take(v: Vec) {
        // what happens here isn’t important.
    }
    let v = vec![1, 2, 3];
    take(v);
    println!("v[0] is: {}", v[0]);
}

rs8-1

Same error: ‘use of moved value’. When we transfer ownership to something else, we say that we’ve ‘moved’ the thing we refer to. You don’t need some sort of special annotation here, it’s the default thing that Rust does.

I dettagli

The reason that we cannot use a binding after we’ve moved it is subtle, but important. When we write code like this:

let v = vec![1, 2, 3];
let v2 = v;  // attenzione qui :sad:

The first line allocates memory for the vector object, v, and for the data it contains. The vector object is stored on the stack and contains a pointer to the content ([1, 2, 3]) stored on the heap. When we move v to v2, it creates a copy of that pointer, for v2. Which means that there would be two pointers to the content of the vector on the heap. It would violate Rust’s safety guarantees by introducing a data race. Therefore, Rust forbids using v after we’ve done the move.

It’s also important to note that optimizations may remove the actual copy of the bytes on the stack, depending on circumstances. So it may not be as inefficient as it initially seems.

Copy types

We’ve established that when ownership is transferred to another binding, you cannot use the original binding. However, there’s a trait that changes this behavior, and it’s called Copy. We haven’t discussed traits yet, but for now, you can think of them as an annotation to a particular type that adds extra behavior. For example:

fn main() {
    let v = 1;
    let v2 = v;
    println!("v is: {}", v);
}

rs8-2
In this case, v is an i32, which implements the Copy trait. This means that, just like a move, when we assign v to v2, a copy of the data is made. But, unlike a move, we can still use v afterward. This is because an i32 has no pointers to data somewhere else, copying it is a full copy.

All primitive types implement the Copy trait and their ownership is therefore not moved like one would assume, following the ´ownership rules´. To give an example, the two following snippets of code only compile because the i32 and bool types implement the Copy trait.

fn main() {
    let a = 5;

    let _y = double(a);
    println!("{}", a);
}

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

rs8-3

fn main() {

    let a = true;

    let _y = change_truth(a);
    println!("{}", a);
}

fn change_truth(x: bool) -> bool {
    !x
}

rs8-4

If we would have used types that do not implement the Copy trait, we would have gotten a compile error because we tried to use a moved value. Come abbiamo visto sopra, con double.

We will discuss how to make your own types Copy in the traits [/usr/local/share/doc/rust/html/book/traits.html] section.

Ancora sull’ownership

Of course, if we had to hand ownership back with every function we wrote:

fn foo(v: Vec) -> Vec {
    // do stuff with v
    // hand back ownership
    v
}

This would get very tedious. It gets worse the more things we want to take ownership of:

fn foo(v1: Vec, v2: Vec) -> (Vec, Vec, i32) {
    // do stuff with v1 and v2
    // hand back ownership, and the result of our function
    (v1, v2, 42)
}

let v1 = vec![1, 2, 3];
let v2 = vec![1, 2, 3];

let (v1, v2, answer) = foo(v1, v2);

Ugh! The return type, return line, and calling the function gets way more complicated.
Luckily, Rust offers a feature, borrowing, which helps us solve this problem. It’s the topic of the next section!

Uh! l’intrigo diventa intrigante :grin:

:mrgreen:

Iscriviti

Ricevi al tuo indirizzo email tutti i nuovi post del sito.

Segui assieme ad altri 89 follower