Marco Arena - Perché nel 2015 parliamo ancora di C++? | Codemotion Milan 2015Codemotion
Un sacco di applicazioni che utilizziamo quotidianamente sono sviluppate in C++. Per esempio, se stai leggendo questo abstract in un browser, allora probabilmente stai usando un software scritto in C++. Nonostante la diffusione di tanti altri eccellenti linguaggi, perché il C++ è ancora così utilizzato? Sapevi che nel 2014 è stato il secondo linguaggio più amato della SO Developer Survey? Cosa offre in più rispetto ad altre tecnologie? Presenterò la mia visione, e anche alcuni “segreti” che rendono il C++ speciale ed evoluto.
Marco Arena - Perché nel 2015 parliamo ancora di C++? | Codemotion Milan 2015Codemotion
Un sacco di applicazioni che utilizziamo quotidianamente sono sviluppate in C++. Per esempio, se stai leggendo questo abstract in un browser, allora probabilmente stai usando un software scritto in C++. Nonostante la diffusione di tanti altri eccellenti linguaggi, perché il C++ è ancora così utilizzato? Sapevi che nel 2014 è stato il secondo linguaggio più amato della SO Developer Survey? Cosa offre in più rispetto ad altre tecnologie? Presenterò la mia visione, e anche alcuni “segreti” che rendono il C++ speciale ed evoluto.
50 minuti per svelare la tigre, il cavallo e sapere che esiste il delfino.
La nuova versione di Java implementa caratteristiche che da tempo erano attese
nello standard del linguaggio: Metadata, Generic Types, AutoBoxing e
Unboxing dei tipi primitivi, Static import, gestione dinamica dei Loop e delle
Enumeration.
Per Java 6: gestione di SystemTray e motori di scripting.
Vediamo di cosa si tratta e di come poter utilizzare queste nuove feature all'interno dei nostri programmi
TypeScript, ovvero JavaScript che "non si rompe"BENTOSA
Le slide del seminario introduttivo su TypeScript, il superset di JavaScript di Microsoft. Antonio e Federico ci hanno illustrato le potenzialità di questo linguaggio per scrivere del codice JavaScript con meno errori.
Qt Lezione0: uso del C++ per scrivere applicazioni QtPaolo Sereno
Per essere sicuri che la nostra competenza di C++ sia sufficiente per la programmazione delle librerie Qt, facciamo un piccolo ripasso dei concetti principali
Queste slide dal titolo provocatorio cercano di dare l'idea che la stupidità e la pigrizia possono avere un effetto positivo nela programmazione per la ricerca di soluzioni semplici. Nello specifico caso parliamo di funzioni in C
More Related Content
Similar to Overload di funzioni in Rust - Come ho imparato a vivere felicemente senza
50 minuti per svelare la tigre, il cavallo e sapere che esiste il delfino.
La nuova versione di Java implementa caratteristiche che da tempo erano attese
nello standard del linguaggio: Metadata, Generic Types, AutoBoxing e
Unboxing dei tipi primitivi, Static import, gestione dinamica dei Loop e delle
Enumeration.
Per Java 6: gestione di SystemTray e motori di scripting.
Vediamo di cosa si tratta e di come poter utilizzare queste nuove feature all'interno dei nostri programmi
TypeScript, ovvero JavaScript che "non si rompe"BENTOSA
Le slide del seminario introduttivo su TypeScript, il superset di JavaScript di Microsoft. Antonio e Federico ci hanno illustrato le potenzialità di questo linguaggio per scrivere del codice JavaScript con meno errori.
Qt Lezione0: uso del C++ per scrivere applicazioni QtPaolo Sereno
Per essere sicuri che la nostra competenza di C++ sia sufficiente per la programmazione delle librerie Qt, facciamo un piccolo ripasso dei concetti principali
Queste slide dal titolo provocatorio cercano di dare l'idea che la stupidità e la pigrizia possono avere un effetto positivo nela programmazione per la ricerca di soluzioni semplici. Nello specifico caso parliamo di funzioni in C
Similar to Overload di funzioni in Rust - Come ho imparato a vivere felicemente senza (20)
Overload di funzioni in Rust - Come ho imparato a vivere felicemente senza
1. Overload di funzioni in Rust - Come ho
imparato a vivere felicemente senza
Nicola Musatti
nicola.musatti@gmail.com
@NMusatti
Rust Milano Meetup - 24 gennaio 2018
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
2. Chi sono
• Un appassionato di C++ di vecchia data, disilluso dalla complessità sempre
maggiore del linguaggio
• Lavoro in Java e su attività non di programmazione
• Un principiante Rust di lungo corso
• Adoro anche Python!
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
3. Cosa ci facciamo qui
• Cos’è l’overload di funzioni e cosa c’è di buono
• Cosa si può fare quando non è supportato
• Quali funzionalità di Rust possiamo usare per affrontare gli stessi problemi
• Alcune implicazioni di portata più ampia
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
4. Un esempio semplice
• Un tipo semplice: Element
• Un tipo collezione di Element: Collection
• Vogliamo aggiungere singoli elementi a una collezione
• Vogliamo aggiungere ad una collezione tutti gli elementi di un’altra
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
5. Come l’avremmo scritto in C
#define MAX_SIZE 100
struct Element {
};
struct Collection {
struct Element * elements[MAX_SIZE];
int size;
};
void add_element(struct Collection * self, struct Element * el) {
if (self->size < MAX_SIZE)
self->elements[self->size++] = el;
}
void add_collection(struct Collection * self, struct Collection * cl) {
int i;
for (i = 0; i < cl->size && self->size < MAX_SIZE; i++)
self->elements[self->size++] = cl->elements[i];
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
6. Lo stesso in Rust
pub struct Element {
}
pub struct Collection {
pub elements: Vec<Element>
}
impl Collection {
pub fn add_element(& mut self, e: Element) {
self.elements.push(e);
}
pub fn add_collection(& mut self, c: Collection) {
self.elements.extend(c.elements);
}
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
7. Qual è il problema
• Espressività ridotta: devo ripetere i nomi dei tipi solo per disambiguare
• I nomi sono più distanti dal dominio del problema
• Le funzioni non possono essere invocate in modo generico (problema specifico
C++)
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
8. Una versione C++
#include <vector>
class Element {
};
class Collection {
public:
void add(Element const& e) {
elements.push_back(e);
}
void add(Collection const& c) {
elements.insert(elements.end(), c.elements.begin(), c.elements.end());
}
std::vector<Element> elements;
};
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
9. Cos’è l’overload di funzioni
• La possibilità di definire due o più funzioni con lo stesso nome che prendono
parametri che differiscono per tipo e/o numero
• La possibilità di chiamare una «funzione» con tipi e/o numero di parametri diversi,
indipendentemente da come ciò è ottenuto
Chiamare è la cosa importante se definire non è troppo complicato
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
10. Costrutti collegati
• Generici o template
• Argomenti di default
• «Duck typing»
• Ereditarietà (?)
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
11. Un esempio con template C++
template <typename T> void add(Collection & c, T const & t) {
c.add(t);
}
int main() {
Element e;
Collection c;
add(c, e);
Collection c1;
c1.elements.insert(c1.elements.end(), 5, Element());
add(c, c1);
return c.elements.size() == 6 ? 0 : 1;
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
12. Un esempio di «duck typing» in Python
class Element:
pass
class Collection:
def __init__(self):
self.elements = []
def add(self, arg):
if isinstance(arg, Collection):
self.elements.extend(arg.elements)
else:
self.elements.append(arg)
def test(self):
e = Element()
c = Collection()
c.add(e)
c1 = Collection()
c1.elements.append(Element())
c.add(c1)
self.assertTrue(len(c.elements) == 2)
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
13. Un esempio in Python con argomenti di default
class Element:
pass
class Collection:
def __init__(self):
self.elements = []
def add(self, element=None, collection=None):
if collection is not None:
self.elements.extend(collection.elements)
else:
self.elements.append(element)
def test(self):
e = Element()
c = Collection()
c.add(e)
c1 = Collection()
c1.elements.append(Element())
c.add(collection=c1)
self.assertTrue(len(c.elements) == 2)
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
14. Bé…
L’overload è meglio!
• E” più pulito
• Rispetta il principio Aperto/Chiuso
• Gli switch sui tipi sono malvisti nei linguaggi che non hanno gli enum di Rust
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
15. E Rust?
• Una forma limitata di overload può essere implementata coi trait:
• Il numero di parametri non può variare
• L’implementazione è un po” più complicata
• C’è una discrepanza concettuale: i trait forniscono un livello aggiuntivo di
astrazione, l’overload non dovrebbe
• Non supporta gli argomenti di default
• Non supporta il «duck typing»: Rust scoraggia o proibisce il completamento
casuale
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
16. Esempio di overload in Rust
pub struct Element {
}
pub struct Collection {
pub elements: Vec<Element>
}
trait Addable<T> {
fn add(& mut self, t: T);
}
impl Addable<Element> for Collection {
fn add(& mut self, t: Element) {
self.elements.push(t);
}
}
impl Addable<Collection> for Collection {
fn add(& mut self, t: Collection) {
self.elements.extend(t.elements);
}
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
17. Esempio di overload in Rust (cont.)
fn test() {
let e = Element{};
let mut c = Collection{ elements: Vec::new() };
let c1 = Collection{ elements: Vec::new() };
c.add(e);
c.add(c1);
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
18. Anche l’overload ha i suoi problemi!
Supponiamo di voler implementare un tipo Point che possa essere costruito:
• Da coordinate cartesiane
• Da coordinate polari
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
19. Un esempio (errato) in C++
#include <cmath>
class Point {
public:
Point(double x, double y) : x(x), y(y) {
}
Point(double r, double t) : x(r * std::cos(t)), y(r * std::sin(t)) {
}
private:
double x, y;
};
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
20. Gli argomenti di default di Python sono di aiuto
class Point:
def __init__(self, x=None, y=None, r=None, t=None):
if x is not None and y is not None:
self.x = x
self.y = y
else:
self.x = r * math.cos(t)
self.y = r * math.sin(t)
def __eq__(self, other):
return self.x == other.x and self.y == other.y
def test(self):
p1 = Point(x=2.0, y=0.0)
p2 = Point(r=2.0, t=0.0)
self.assertTrue(p1 == p2)
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
21. Rust viene in soccorso
…o come per me dovrebbero essere implementate le funzioni sovraccaricate in Rust:
Un’unica funzione con un unico parametro enum che elenchi tutte le
combinazioni di argomenti da supportare
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
22. L’esempio del tipo Point in Rust
pub enum Coordinates {
Cartesian(f64, f64),
Polar(f64, f64)
}
#[derive(PartialEq)]
pub struct Point {
pub x: f64,
pub y: f64
}
impl Point {
pub fn new(c: Coordinates) -> Point {
use self::Coordinates::*;
match c {
Cartesian(x, y) => Point{x,y},
Polar(r, t) => Point{ x: r * t.cos(), y: r * t.sin() }
}
}
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
23. Estendiamo l’esempio Point in Rust
pub enum Angle {
Degrees(f64),
Radians(f64)
}
pub enum Coordinates {
Cartesian(f64, f64),
Polar(f64, Angle)
}
#[derive(PartialEq)]
pub struct Point {
pub x: f64,
pub y: f64
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
24. Estendiamo l’esempio Point in Rust (cont.)
impl Point {
pub fn new(c: Coordinates) -> Point {
use self::Coordinates::*;
use std::f64::consts::*;
match c {
Cartesian(x, y) => Point{x,y},
Polar(r, a) => {
let t = match a {
Angle::Degrees(d) => d * 2. * PI / 360.,
Angle::Radians(r) => r
};
Point{ x: r * t.cos(), y: r * t.sin() }
}
}
}
}
fn test() {
let c = Point::new(Coordinates::Cartesian(2.,0.));
let p = Point::new(Coordinates::Polar(2.,Angle::Radians(0.)));
assert!(c == p);
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
25. L’esempio originale in Rust
pub struct Element {
}
pub struct Collection {
pub elements: Vec<Element>
}
pub enum Args {
Elem(Element),
Coll(Collection)
}
impl Collection {
pub fn add(&mut self, args: Args) {
match args {
Args::Elem(e) => self.elements.push(e),
Args::Coll(c) => self.elements.extend(c.elements)
}
}
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
26. Cosa non va
• Chiamare la funzione è un po” più prolisso dell’overload vero e proprio
• Viola il principio Aperto/Chiuso: aggiungere combinazioni di parametri richiede di
modificare codice esistente
• L’enum degli argomenti può risultare un po” artificiale
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
27. Cosa c’è di buono
• Le alternative disponibili sono descritte in un unico posto
• L’intenzione è espressa esplicitamente attraverso la scelta dell’enumerazione
appropriata
• Rust impone che tutti i casi dichiarati siano gestiti
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
28. C’è di più
• Un aspetto fondamentale della tipizzazione statica è l’imposizione di vincoli sui
parametri
• E” meglio fare i controlli subito in modo che il type system inoltri i vincoli
automaticamente
• L’enum degli argomenti sposta il controllo dei parametri fuori dalla funzione
• Questo si potrebbe estendere ad altri controlli:
• Range di validità
• Vincoli combinati
• Purtroppo la mancanza di costruttori standard rende la sintassi non proprio ideale
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
29. Un ultimo esempio
use num::Float;
pub struct Positive<T: Float> {
pub value: T
}
impl<T: Float> Positive<T> {
pub fn new(t: T) -> Positive<T> {
assert!(t >= T::zero());
Positive{ value : t }
}
}
pub fn sqrt<T: Float>(v: Positive<T>) -> T {
v.value.sqrt()
}
fn test() {
assert!(sqrt(Positive::new(4.0)) == 2.0);
}
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018
30. Fine
Domande o pizza, questo è il dilemma
Nicola Musatti - Function Overloading in Rust - Rust Milano Meetup - Mikamai - 24 January 2018