►
Description
Second talk for the first Rust Edinburgh meetup, the first Scottish meetup about the Rust programming language.
Simon Brand from Codeplay Software Ltd. presents his talk "How Rust gets polymorphism right".
Many thanks to our sponsors Maidsafe and Codeplay.
Find out more about us here:
https://meetup.com/rust-edi
https://rust-edi.github.io
A
B
Everyone
welcome
to
this
week's
meeting
of
programmers.
Anonymous
I'm
very,
very
pleased
feet
here.
My
name
is
Simon
and
I'm
a
C++
programmer
yeah.
So
I
am
what
you
might
call
a
beginner
in
rust.
I'm,
a
CMOS
plus
expert
I
spend
most
of
my
time.
Writing
C++
ran
compilers,
debuggers
profilers,
doing
standards
work
all
this
kind
of
stuff
and
that
my
rust
is
not
fantastic.
So
if
I
do
anything
non,
idiomatic
or
I
think
it's
weird,
it's
not
because
I'm
being
smart,
it's
because
I'm
being
wrong.
B
So
please
tell
me
if
you
see
something
which
you
do
not
agree
with,
because
it's
probably
just
being
silly
so
my
talk
today
is
on
high.
Rust
gets
polymorphism
right,
so
I'm
gonna
be
mostly
comparing
to
C++,
because
that's
what
I
know
and
that's
kind
of
what
a
lot
of
rust
and
the
user
base
know
as
well.
People
come
to
rust
from
C++
a
lot
of
times
so
just
to
get
a
feel
for
the
room,
and
can
you
put
your
hand
up
if
you
do
not
know
C++
one
hand,
so
pretty
much.
B
So
if
you
aren't
too
comfortable
with
some
of
the
concepts,
just
ask
me,
a
question
feel
free
to
stop
me
at
any
point
or
not
field
and
be
able
to
answer
any
other
questions.
I
work
at
copeley,
which
is
based
here,
I
work
on
compiler
backends
at
the
moment,
and
we
do
heterogeneous
systems
tools
for
our
things,
like
GPUs
and
DSPs.
B
My
short
definition
is
LS
constructs
dive
act
differently,
based
on
the
types
which
are
used
or
to
treat
some
kind
of
some
set
of
types
with
the
same
interface,
so
I'm,
mostly
going
to
make
differentiation
between
static
polymorphism
which
operates
at
compile
time
and
dynamic
polymorphism
which
operates
at
runtime.
So
some
of
the
examples
of
static
polymorphism
function,
overloading
is
a
very
simple
one.
In
C++
you
can
use
the
same
name
for
functions
which
take
different
types.
They
can
even
return
different
types.
They
can
do
completely
different
things.
B
You
could
have
a
function
called
print
which
actually
just
ask
together
a
couple
more
numbers
and
returns
them.
They
don't
whatever
you'd
be
wrong,
but
we
have
templates
in
C++
which
are
suppose
this
kind
of
major
static
polymorphism
for
generic
interfaces.
A
lot
of
languages
have
generics
unless
you're
go.
B
And
then
traits
which
are
a
feature
of
rust,
which
I'm
sure
all
of
you
know
about
I
will
be
going
into
detail
about
some
of
these
concepts
later
on
they're,
not
a
polymorphism
again
at
runtime.
Some
possible
examples
of
this
are
virtual
functions
where
you
have
some
kind
of
inheritance
hierarchy
and
you
can
do
dynamic
dispatch
based
on
the
type
of
something
at
runtime,
rather
than
the
type
at
compile
time.
B
We
have
things
like
the
visitor
pattern,
which
is
often
used
to
kind
of
add
functionality
to
classes
from
outside
of
the
definition,
and
this
is
going
to
be
quite
relevant
later
on,
where
the
variants,
which
can
either
be
a
library
feature,
or
they
can
be
a
language
feature.
And
then
we
have
things
like
checked
astÃn
in
Sivas
possible,
dynamic
cast
which
allows
to
checked
cast
of
the
dynamic
type
of
an
object
using
some
runtime
type
information
such
my
lightning
tour
polymorphism
and
I'm
gonna,
compare
see
most
awesome,
rusts
approaches
to
some
of
these
concepts.
B
So
here's
a
little
table
which
I
made
up
the
sumo
squats,
have
a
lot
of
different
concepts
which
roughly
more
or
less
map
on
to
rusts
traits.
These
are
other
traits
or
trait
objects
which
attends
a
dynamic
version
of
the
trace
and
then
down
in
bottom.
Here
we
have
variant
which
maps
on
to
rust
and
enums,
which
are
very,
very
powerful
if
you're,
just
familiar
with
the
C++
version
of
enums
and
I'm
gonna
be
going
into
more
detail
about
all
of
these.
So
that's
bold
statement,
inheritance
for
dynamic
polymorphism
is
too
intrusive.
B
B
If
it
has
a
function
called
print
which
takes
no
arguments
and
returns,
nothing
services,
just
gonna,
be
like
dumping
out
of
my
class
to
still
see
a
wider
and
then
have
a
couple
of
classes
which
inherit
from
this
you
see
here
is
inheriting
from
printable
and
so
it's
bar
and
we
can
override
this
print
function.
So
now
at
runtime,
I
could
have
some
pointer
to
printable
and
maybe
it's
a
food.
Maybe
it's
a
bar
I
can
call
print
and
it
won't
do
the
right
thing,
dude
and
dynamic
dispatch.
B
B
C
B
Was
it's
not
printable
and
yes,
that's
the
problem.
It
is
not
inherit
from
our
printable
interface,
abstract
class.
So
if
I
want
to
do
something
like
this
have
a
vector
of
printable
objects,
then
I
can
very
happily
dynamically
allocate
a
few
object
and
a
bar
object
and
push
them
into
this
vector.
This
will
work
of
fine.
It
will
do
dynamic
dispatch,
but
if
I
try
and
do
this
with
an
own
own,
then
the
compiler
shouts
at
me
it
gets
very,
very
mad
because
oh
no
does
not
inherit
from
printable.
B
Oh
no
I
don't
know,
but
here
is
some
library.
Class
I
cannot
just
go
in
and
change
the
definition
of
this
class.
If
I
could.
This
would
all
be
fine,
because
I
can
just
make
inherit
from
printable
and
everyone's
happy,
but
there
are
many
many
cases
in
which
you
can't
do
this.
Maybe
you
don't
own
this
code?
Maybe
you
don't
have
all
the
source.
You
only
have
the
headers.
B
This
is
very,
very
common
occurrence.
Maybe
you
just
don't
want
to
break
third
library
code.
This
is
not
a
very
maintainable
or
flexible
situation
to
be
in
so
inheritance
or
dynamic.
Polymorphs
that
this
polymorphism
is
too
intrusive.
On
the
other
hand,
trait
objects
are
unobtrusive,
so
in
rust,
I
can
say
something
like
this.
I
can
say
something
is
printable
if
it
has
a
function
called
print
which
takes
a
reference
to
self.
This
is
the
same
kind
of
thing.
B
Is
there
if
the
virtual
function
we
saw
in
the
C++
example
and
takes
a
reference
to
self
and
returns
nothing
and
then
I
can
have
a
few
classes,
such
as
or
struts,
through
bar
98,
but
notice
that
I
haven't
defined
the
print
function
for
foo
and
bar.
Yet
nor
for
you,
I'm
gonna.
Do
it
separately
here
so
I,
say
I'm
going
to
implement
printable
for
these
types
for
food,
for
bar
for
you
and
I
can
make
these
do
whatever
I
want.
These
implementations
can
differ
as
much
as
I
need.
B
B
Okay,
so
the
common,
who
is
that
wish
to
do
with
have
to
implement
these
and
and
certain
modules
by
really
looking
for
is
these
definitions
are
very
much
the
same.
I
don't
have
to
implement
these
definitions
in
a
different
way,
depending
on
whether
I
own
the
code
or
whether
it's
a
library,
I,
don't
have
to
put
the
implementation
of
these
functions
in
the
definition
of
my
types,
whereas
in
C++
I
did
so.
B
I
can
very
very
easily
take
some
yay
type
from
a
library
which
maybe
has
some
predefined
behavior
for
dumping
out
to
a
stream
and
I
can
adapt
it
for
my
own
needs
and
then,
when
I
go
on
to
make
a
vector
of
these
things,
then
I
can
happily
push
in
a
game
a
bar
and
food.
Then
I
can
print
the
map
and
it's
all
the
same
interface
all
just
works.
B
This
is
very,
very
powerful
because
ways
in
C++
I
have
a
very
obtrusive
method
of
dynamic
polymorphism.
This
one
is
a
lot
less
intrusive.
It
likes
me
very,
very
flexibly
ad.
They
leave
your
own
types,
which
are
doing
Poli,
so
inheritance
for
dynamic
polymorphism
is
too
intrusive
and
trait
objects
are
no
truces.
Does
anyone
disagree
with
these
or
have
any
questions
about
this
part
of
the
talk.
D
B
This
boxes
rusts
dynamic
allocation
type,
so
this
is
saying
that
I'm
going
to
be
storing
and
principal
objects
somewhere
and
anything
which
implements
the
printable
trait
is
going
to
be
horrible,
so
I
don't
have
to
care
about
it
like
allocating
these
myself,
I'm
gonna.
Let
the
implementation
deal
with
all
of
that
I
just
care
the
printable
is
implemented
for
these
types
of
contracts.
Yes,
it's
kind
of
like
a
contract
which
is
enforced
to
compile,
and
yes,
yes,.
C
C
B
B
B
So
now
I
want
to
add
some
kind
of
way
of
providing
functionality
onto
these
types
without
needing
to
intrusively
change
the
definition
of
my
classes,
so
just
as
we
saw
trait
objects
a
few
few
minutes
ago-
and
we
want
to
do
something
kind
of
similar
and
one
way
of
doing
this
is
the
visitor
patterns
where
they
have
classic
design
patterns,
which
you
may
see
in
C++
or
Java,
or
any
number
of
these
languages,
which
kind
of
allow
an
object,
orientated
style.
So
I
do
something
like
this.
B
Let's
say
my
animal
accepts,
some
visitor
and
dog
accept
something
too
severe
and
can't
accept
some
visitor
and
then
a
visitor
is
something
which
can
operate
on
dogs
and
cats,
and
then
the
dog
and
cat
methods
forward
on
themselves
to
these
visit
functions.
The
way
this
works
is
because
this
in
this
function
is
a
type
dog
star,
and
in
this
one
it's
a
cat
star.
We
get
a
method
by
which
we
can
know
what
types
we're
dealing
with,
and
we
have
this
interface,
which
is
dealing
directly
with
dogs
and
cats
rather
than
just
animals.
B
B
So
then
I
can
do
something
like
of
a
pointer
to
an
animal,
make
a
print
visitor
and
then
say
animal
except
my
visitor,
and
it
will
run
through
all
of
this
awful
awful
boilerplate
and
give
me
what
I
want
if
you've
used
any
languages
which
support
things
like
multiple
dispatch
like
most
dialects
things
like
this,
they
support
this
in
the
language.
You
don't
have
to
make
awful
inheritance
based
hacks
around
it.
So
the
pattern
is
a
hack.
B
So,
instead
of
all
of
that
inheritance,
malarkey
and
virtual
functions
and
overriding,
we
can
just
say
that
we
have
a
dog
and
a
cat
and
an
animal
is
one
of
a
dog
or
a
cat.
I
can
then
create
an
animal
set
it
to
something
and
then
I
want
to
do
something
which
will
print
out
cat
or
dog,
just
like
we
did
in
here.
B
So
one
way
in
which
I
could
do
that
is
I
could
create
a
type
called
printer
which
just
overrides
these:
the
call
operator
for
dogs
and
cats,
and
then
I
guess
you
see
here.
This
is
quite
an
improvement
on
our
visitor
pattern,
but
it's
still
not
great
like
we
don't
want
to
be
creating
types
just
in
order
to
specify
this
kind
of
behavior.
We
want
to
do
it
in
place
like
while
we're
writing
the
function.
B
One
possible
solution
to
this
switches
come
up
and
has
got
Standish
proposal
for
it
and
what
people
use
is
this
overloaded
concept?
So
what
this
does
is
takes
a
bunch
of
lambdas
and
composes
them
into
some
object,
which
does
the
same
kind
of
thing.
Is
this?
So,
instead
of
overriding
a
bunch
of
co-operators,
we
just
pass
a
bunch
of
lambdas.
E
B
E
E
B
The
return
type
is
deduced,
the
parameter
types
are
specified
by
the
run,
everything,
and
so
you
can
use
this
kind
of
overloaded
thing
and
the
problem
with
this
is
visit
to
this
visitor
type
and
sorry,
this
variant
type
there's
supposed
to
be
something
which
is
accessible,
something
which
is
a
vocabulary
type
which
we
can
say
if
I
want
to
have
something
which
is
this
or
this
or
this.
This
is
the
kind
of
concept
I
want
to
be
reaching
for,
but
suddenly
I
have
to
teach
beginners
about
lambdas
and
all
the
syntax,
all
right,
comma.
B
So
it's
not
gonna
compile.
It's
probably
gonna.
Give
me
an
all
for
error
with
no
beginners
gonna
understand
and
then
this
overloaded
thing
so
said:
it's
not
standardized
yet,
so
you
have
to
copy
something
off
the
internet
and
C++
17.
It
will
look
something
like
this
so
suddenly,
I'm
a
beginner
I
need
to
understand:
variadic
templates
pack,
expansion
for
multiple
inheritance
pack,
expansion
and
using
declarations
and
very
addict
template
class
deduction
guides
like
beginners
shouldn't,
be
anywhere
near
this
code.
They
shouldn't
even
know
it
exists.
B
B
Language-Based
variants
are
clear
and
user-friendly,
so
where
is
in
C++?
We
have
a
library
type
for
expressing
a
variant
in
Russ
we
have
a
language
construct
for
expressing
variants,
and
this
is
called
enum,
so
I
can
have
an
animal
and
it
can
be
a
cat
or
a
dog,
and
then
I
have
some
variable
of
type.
Animal
and
I.
Have
this
nice
pattern
matching
syntax.
So
if
you're
familiar
with
functional
programming
languages,
this
is
trying
to
do
kind
of
the
same
thing.
B
So
here
we
just
say
we
match
against
a
and
if
there's
a
cat,
then
we
put
Captain.
If
it's
dog
the
print
off,
we
don't
have
to
deal
with
all
the
crazy
stuff
we
had
to
in
C++
and
what's
more
these
enumerator
variants,
they
don't
have
to
be
just
simple
tags.
They
can
be
whatever
we
want.
We
can
store
string
in
them.
They
can
have
named
fields
like
a
struct
and
then
we
can
pack
a
match
on
them.
B
So
I
mean
say
if
I've
got
a
page
load
and
print
that
if
I've
got
a
taste
well
that
has
a
string,
so
I
can
get
access
to
the
string.
If
it's
a
struct
I
can
do,
structure
I
can
get
all
the
information
I
want
by
pattern.
Matching
I'm
sure
you
know.
Even
if
you
do
not
know
rust.
If
you
look
at
this
code,
you
can
get
a
fairly
reasonable
idea
of
what
it's
doing.
If
you
look
at
this
and
you
don't
know
what
plate
you've
got
no
chance
so.
B
E
B
So
the
comment
is
you
the
types
in
the
varying?
Are
they
don't
have
the
same
kind
of
identity?
Semantics
that
you
do
here
so
where
is
in
in
Ross
you
could
you
could
have
a
paste
which
has
a
string
and
you
could
have
I
know
a
cut
which
has
a
string
that
you
could
have
whatever
else.
We
show
that
string
in
C++,
you
couldn't
just
say:
stick
variant,
stood
strings
to
strings,
just
dream,
it
doesn't
make
sense.
You'd
have
to
have
some
kind
of
like
strong
type
yeah
thing,
yeah.
B
B
Only
so
I
can
happily
have
a
function
which
returns
a
state
vector
parameterize
by
some
type
t
I
Karen
have
a
function
which
takes
us
to
vector
and
I'm
gonna
call
them
like
sir,
so
I
specify
I
want
to
make
a
vector
int,
do
it
and
then
I
can
say,
take
a
vector
and
it
will
deduce
the
type
spawn.
So
this
is
all
this
is
all
fine.
It
works
very
well,
it
does
what
you'd
expect
most
of
the
time
so
you're
not
overloading
on
certain
things.
B
It's
mostly
okay,
set
of
templates,
very
simple,
static,
polymorphism
work
and
then
traits
for
polymorphism
also
kind
of
work
in
very
much
the
same
way.
So
we
can
have
a
vector
I'm
trying
to
tries
by
some
teeth
and
then
we
can
make
a
vector
of
T's
and
we
can
take
a
vector
of
T's
and
it
all
looks
I
minus
some
syntactical
differences
is
pretty
much
the
same.
What
you'd
expect
so
this
book
work,
constrains
templates
will
make
you
cry
blunt.
B
So,
back
to
a
printable
example,
we
have
two
types
which
can
be
printed
and
then
we
have
some
kind
of
function
which
requires
the.
What
have
you
pass
to?
It
is
printable.
No,
these
are
not
joined
by
any
inheritance
hierarchy
or
anything
like
that.
They're
just
types-
and
we
just
say
I,
don't
care
what
type
you
are.
As
long
as
you
implement
this
interface,
then
it's
fine
by
me.
B
So
one
way
we
can
express
things
in
C++
is
a
static
asset,
so
we
can
sit
assert
that
for
whatever
T
we're
using
T's
printable
and
if
it's
not
we'll
get
a
reasonably
clear
error
message
saying
well,
if
T
must
be
printable,
you
did
something
wrong
and
I'll
tell
you
where
you
did
something.
One
major
problem
with
this
is
the
constraint
on
the
type
is
not
in
the
declaration
or
the
function.
B
So
what
I
mean
is
I
look
at.
Do
then
print
it
takes
a
T,
it
returns
a
void.
I,
don't
know
anything
about
what
this
function
requires
of
the
types
I'm
passing
in
here
I
have
to
look
at
the
definition
in
order
to
know
that.
So
that's
a
problem:
it's
not
documented
I
can
write
documentation
for
it.
But
surely
we
all
know
the
problems
that
are
inheriting
that
it's
one
possibility
is
we
can
use
enable
a
yay
hands
up
if
you
think
this
is
clear,
understandable
code,
no
hands
yeah.
B
So
this
is
something
in
C++,
which
is
essentially
major
hack,
which
allows
us
to
conditionally
disable
function.
Overloads
I
could
tell
you
how
it
works
and
had
to
implemented
I'm
not
going
to
suffice
to
say
this
does
a
thing
and
you
never
know
what
to
know
about
it.
If
you
don't
need
another
major
problem
is
I
haven't
shown
you
the
definition
for
its
printable
yeah
I'm
going
to
this
is
one
possibility
and
C++
17
and
yeah
unless
you're
a
magic
programming
expert,
and
you
have
no
idea
what
this
does
like.
B
B
B
D
B
B
D
B
The
question
is
really
in
the
C++
version:
you
could
have
inheritance
hierarchy,
the
the
entire
point.
Is
you
don't
want
an
inheritance
hierarchy,
so,
for
example,
this
could
be.
This
could
be
anything.
This
could
be
is
implementable.
You
can't
have
a
negative
heritage
hierarchy
from
end
appears.
Then
you
won't
work
on
and
primitive
types.
You
just
want
to
take
anything,
and
as
long
as
it
conforms
to
some
interface,
then
it
will
work.
Yes,.
B
B
D
B
Questions
with
C++
concepts
and
then
we
write
in
standing
library.
The
answer
is
pretty
much
yes,
they're
big
and
reserved
the
STD
namespace,
and
so
the
ranges.
Technical
specification
is
the
main
paper
which
is
outlining
kind
of
higher
concepts
should
look
like
and
in
the
future
version
of
the
standard.
There's
still
a
lot
of
work
to
be
done
there
we're
still
fiddly.
So
you
know
rusts
an
iterator
concept,
which
is
quite
different
from
C++.
E
But
choose
I
mean
I
could
see
the
traits
there's
much
less
kind
of
hardly
definition.
It
easily
had
things
in
people
from
the
other
line.
Look
I
thought
that
would
just
be
so
much
easier
and
languages
like
scum.
A
functional
programming
give
you
this
notion
that
you'd
to
pass
around
a
little
closure
and
build
up
Steven
that
closure
recursively
yep
and
that
becomes
easier
to
evolve.
You
can
get
it
so
far
as
to
change
larvae,
just
changing
the
content
of
the
cogent
parameter
and
I'm
interested,
particularly
the
example
of
scallop.
E
The
skull
tries
to
be
very
opportunity
with
treats
get
quite
a
tea
together,
careful
which
features
of
scholarly
switch.
Otherwise
new
things
start
to
happen
just
find
by
yourself
TV.
You
suddenly
slip
something
on
everything
checks,
your
kudos
yep,
it's
the
same
weird
behavior,
you're,
fast
situation
treat
seems
to
me,
maybe
the
roots
to
boobs
getting
better.
Yes,.
B
Functionality
like
traits
and
trademark
Jets,
will
be
very,
very
influential
for
other
programming
languages
and
we
look
at
C++
and
is
trying
to
accept
a
lot
of
the
kind
of
changes
which
Russells
be
making
it's
moving
away
from
exception,
based
error
handling,
it's
trying
to
get
more
functional
programming,
oriented
style
and
a
lot
of
this.
It's
looking
at
rust
and
seeing
how
it's
taken
those
binary
imperative
and
programming
paradigm
and
adapted
it
for
safety
and
for
usability
and
for
express
ability
and
I
think
a
lot
of
languages.
F
A
B
Specialists,
don't
know
how
the
traits
are
implemented.
Some
can
feel
free
to
correct
me
on
this
I.
Don't
know
very
much
about
the
details,
so
the
traits
themselves
are
just
compiled
and
features
the
trait
objects
implement
and
essentially
a
virtual
dispatch
table
inside
the
trade
object
itself.
So
it's
not
stored
as
part
of
the
object
which
you're
sent
to
type
arisen.
It's
stored
as
part
of
the
typewriter
object
itself,
so
it's
kind
of
separates
those
concepts
orders
with
C++.
B
As
soon
as
you
have
inheritance
and
virtual
functions
and
you're
dynamically
allocating
things,
then,
suddenly
you
have
a
virtual
dispatch
table,
even
if
you
didn't
want
one
like
unless
the
compiler
can
do
federalize
everything
we're
getting
that
draft.
But
yes,
so
it's
stored
as
part
of
the
implementation
of
the
trade
object
rather
than
as
part
of
the
earth
and
the
type
itself
yeah
other.
H
C
H
B
Yes,
yes,
so
the
the
color
was
for
the
old
o-type,
which
I
had
at
the
start
here.
I
could
generate
a
wrapper
class
around
this,
which
does
kind
of
a
similar
thing,
and
there
are
very,
very
many
problems
with
that.
One
is
as
soon
as
we
start
scaling
this
up
and
using
other
libraries
using
lots
of
components
from
libraries.
I
have
to
implement
this
for
every
single
one
of
them
too.
B
It's
very,
very
difficult
to
maintain
all
of
the
same
kind
of
value
semantics
and
like
no
except
specifications,
context
for
specifications
and
all
of
the
all
of
the
operations
which
were
we're
trying
to
use.
So
as
soon
as
you
write
wrapper
types,
you
need
to
completely
understand
things
like
perfect
forwarding,
no
expect
propagation
context
for
propagation
and
those
are
really
advanced
concepts
unless
you
understand
all
of
them.
You're
gonna
get
something
wrong
and
some
use
case
is
not
going
to
work
quite
as
efficiently
or
it's
gonna
break
completely.
B
C
B
B
So
as
a
Sabratha
thrusts,
macro
system
is
very,
very
different
from
C++
ASIMO's
plazas
macro
system
is
just
like
token,
pasta,
I
have
a
token
I,
don't
know
it
is
I'm.
Just
gonna
paste
it
around,
and
you
know.
Flavor
and
Russ
macro
system
is
more
kept
on
the
way
to
Lisp
macros.
It
doesn't
go
the
entire
way.
It
has
its
own
kind
of
language
for
doing
abstract,
syntax
tree
and
manipulation.
B
So
you
can
match
on
how
your
code
actually
is
interpreted
by
the
compiler,
and
then
you
can
generate
code
based
on
that,
so
ruts
macros
allow
you
to
generate
code
based
on
and
some
tactical
constructs,
which
is
a
very
powerful
and
technique
and
will
reduce
a
lot
of
boilerplate,
which
C++
tends
to
do
with
horrible
macros
or
ridiculous
template
hackery,
okay,
cool!
That's
all
the
time
we
have
left.
So
thanks
very
much
for
all
your
questions
and
see
you
later.