00:00:13.759
uh hi I'm Craig today I'm going to talk
00:00:15.599
about uh laziness and functional
00:00:17.640
programming in Ruby um if you want to
00:00:20.800
add me I'm on Twitter and Ruby social in
00:00:23.960
frequently uh links up at the top uh
00:00:26.880
short URL on the slides if you want to
00:00:29.359
read along if you want to look at them
00:00:31.040
later uh you can hit P to see the
00:00:33.120
presenter notes that I'm looking at um
00:00:35.480
they've got some extra links resources
00:00:37.320
and some things I don't have time to
00:00:38.600
cover and uh I took that picture this
00:00:40.920
morning from the hotel much better than
00:00:43.719
the AI
00:00:46.160
picture um who knows who Larry wall is
00:00:49.719
all right uh Larry wall is a creator of
00:00:51.840
Pearl and the language formerly known as
00:00:54.280
Pearl six
00:00:56.000
Raku um so this is a quote from him uh
00:00:59.120
the three chief of a programmer are
00:01:01.079
laziness and patience and
00:01:04.199
hubus uh I I identify with Larry's
00:01:07.240
description my wife's therapist says I'm
00:01:09.000
a sloth and I've embraced that label U
00:01:12.159
so we have a few sloths around the house
00:01:15.119
uh so let's start with a definition of
00:01:16.720
laziness my definition is delaying
00:01:19.439
computation until the result of the
00:01:21.280
computation is
00:01:23.159
needed um so I of see code like this in
00:01:25.920
a rails controller and this is the kind
00:01:28.280
of code that prompted this this talk um
00:01:31.360
why do we need to set the current user
00:01:32.960
account before everything
00:01:34.960
else well we don't uh rails requests are
00:01:38.680
synchronous there is no ahead of time uh
00:01:41.640
you only need to compute things before
00:01:42.960
they're used and I'm going to argue that
00:01:44.320
you should compute things right before
00:01:45.960
they used um so this code is more lazy
00:01:49.399
uh it waits to do the computation until
00:01:51.079
it's
00:01:52.840
needed um we could also compute the
00:01:55.360
value in the initializer uh especially
00:01:58.079
if it's always needed uh we're still
00:02:00.200
worrying about the thing before we need
00:02:02.640
it um and I contend that this mindset is
00:02:05.960
is harmful it's a hold over from
00:02:08.160
procedural code um at least in this case
00:02:11.160
though we're at least thinking of the
00:02:12.280
current account as a property of that
00:02:14.000
object instead of an action that needs
00:02:16.160
to be
00:02:17.560
done uh the original code did have one
00:02:20.080
advantage and it only computed the value
00:02:21.720
once but that's easily solved with
00:02:25.599
memorization um so what is this line
00:02:28.000
telling us when we read it it's says we
00:02:30.280
need to set the current account before
00:02:31.640
anything else but but that's it's a lie
00:02:33.840
we can forget about the current account
00:02:35.360
until we we we we need to use it
00:02:38.319
actually so and if we named it well we
00:02:40.800
probably never really need to look at at
00:02:42.879
how it's implemented um so controller
00:02:45.519
before filters are still useful but they
00:02:48.319
need to be used as a filter and um for
00:02:50.720
interrupting a request before we
00:02:52.400
actually start doing anything usually
00:02:54.239
that's going to be authentication or
00:02:56.560
authorization um note that instance
00:02:58.599
variables in rails controller also get
00:03:00.400
copied to the view in some weird way but
00:03:02.560
I recommend against that too uh we can
00:03:04.840
pass the locals to render um we can
00:03:07.440
label Lems helper methods uh I prefer
00:03:10.360
the the decent exposure gem which uh uh
00:03:14.200
is more uh the Clara of in in what we're
00:03:17.560
passing on to the from the controllers
00:03:19.720
to the
00:03:20.720
Views uh so let's get the memorization a
00:03:23.239
little
00:03:24.319
deeper um before we memorize we should
00:03:27.159
make sure that it makes sense to
00:03:28.319
memorize something and to memorize
00:03:30.879
something we want it to be item potent
00:03:32.599
we want it to produce the same result
00:03:34.400
when it's called multiple times with the
00:03:35.959
same arguments that's item potency um
00:03:39.200
and we want to make sure it's pure it
00:03:40.439
doesn't have any side effects so in the
00:03:42.400
example here 2 time three is always
00:03:44.239
going to give six so it's item potent um
00:03:47.280
and there's no side effects but if we
00:03:49.120
call time. now that's not itm potent it
00:03:52.000
gives us a different result every time
00:03:54.079
and it's actually uh accessing the
00:03:56.400
outside world and if we're doing a puts
00:03:58.920
or a gets we're also talking to the
00:04:00.840
inside to the outside
00:04:03.920
world so we have an idiom in Ruby uh for
00:04:08.760
memorization um so memorization caches
00:04:11.799
the result of the computation so we
00:04:13.319
don't have to compute it again so the or
00:04:16.359
equals operator assigns a variable uh
00:04:20.079
assigns to the variable if the variable
00:04:22.040
is not already nil or false otherwise it
00:04:26.520
assigns the value on the right hand side
00:04:29.440
um undefined variables if you remember
00:04:31.759
start as
00:04:33.759
nil um so the basic Ruby memorization
00:04:37.759
idium doesn't handle nil or false that's
00:04:40.160
rarely a concern we rarely have
00:04:42.160
something that's that's true false or
00:04:45.080
some other value um and nil is usually
00:04:48.600
the the failure it's usually very quick
00:04:51.360
and it might even tell us that we should
00:04:52.680
try
00:04:53.520
again um it's also not thread safe who
00:04:57.240
here does anything that needs to be
00:04:58.680
thread safe
00:05:00.639
all right oh that's a few more than that
00:05:02.639
that's
00:05:03.919
good um so here's a longer version of
00:05:08.720
memorization um it's a bit idiomatic um
00:05:12.039
that does handle nil and false and it's
00:05:14.039
also good if your method is more than
00:05:15.800
one line long um so it uses Ruby's
00:05:19.319
defined construct which is a long story
00:05:22.440
in itself um but it does the trick right
00:05:26.440
here um so rails used to come with the
00:05:28.960
memo was memorized gem built in um but
00:05:32.160
it was deprecated way back in reals
00:05:34.360
3.2 um you could you could Define your
00:05:37.199
your function and then say memoize this
00:05:41.199
function um So Def finded function
00:05:45.680
actually Returns the name of that method
00:05:48.560
um as a symbol and we can use that as
00:05:51.280
the argument to memoize so we can
00:05:52.720
actually shorten it here and here I
00:05:54.880
actually used the Ruby 3.0 short method
00:05:57.639
definition syntax and so we got got one
00:06:00.120
line there just to Define that that
00:06:01.759
simple
00:06:02.960
method um so to me this this reminds me
00:06:06.319
of uh type qualifiers or attributes in
00:06:10.039
cc++ if you are familiar with those
00:06:13.039
things like const or static or extern or
00:06:17.720
volatile um so I like the memoized gem
00:06:21.880
and um so memo is an extraction of that
00:06:26.800
that lets us keep using it um and it
00:06:29.840
even works for methods to take arguments
00:06:31.960
and the idiom for that is is a little
00:06:34.120
bit more complex uh it's in my notes
00:06:36.280
here if you want to take a look um this
00:06:38.680
is possibly out of date it hasn't been
00:06:40.280
updated for a while and it hasn't been
00:06:42.240
tested on more recent
00:06:44.960
review um memorizable is another popular
00:06:48.000
gem uh written from scratch uh it's
00:06:50.520
written by Dan Cub who's uh I consider
00:06:53.280
to be a leader in the functional
00:06:54.960
programming uh branch of the Ruby
00:06:57.120
Community uh it's more up to date and
00:06:59.319
it's mutation tested um that verifies
00:07:02.199
that all possible code paths have been
00:07:04.560
covered by tests which pretty amazing
00:07:06.919
actually um Danon seems to do that with
00:07:10.160
all his code even Royal's code and
00:07:11.680
that's that's impressive um and it shs
00:07:14.039
all the code that's actually there is
00:07:17.840
necessary um Ruby 32 introduced a data
00:07:21.560
class uh it's much like a struct it's
00:07:23.680
except it's immutable and there's no
00:07:25.160
Setters and no
00:07:26.879
behaviors so we can define a data class
00:07:30.400
with the Define and a list of fields
00:07:32.800
that go into that data class so here
00:07:35.240
we've got a we create a class called
00:07:37.240
person uh that has a name and an age and
00:07:40.520
we can create a new instance with new
00:07:42.120
just passing the fields values by name
00:07:44.759
pretty standard
00:07:46.080
there um and we can subclass that data
00:07:48.759
CL class this is my preferred style um
00:07:51.960
because it's consistent I can see that
00:07:53.479
this a class just like any other class
00:07:55.120
it starts with cl the word class um uh
00:07:59.240
this does have one major downside
00:08:00.759
there's actually an anonymous class
00:08:02.680
between the the data class that we
00:08:05.120
Define there and person class uh pretty
00:08:08.560
minor probably not going to bother
00:08:10.120
anybody um you'll only see it if you
00:08:12.120
look at person. ancestors
00:08:15.440
there uh and we can we can override the
00:08:18.680
initializer if if it's class um in this
00:08:21.639
example we're going to normalize the
00:08:23.080
name and age because we want names to be
00:08:25.440
capitalized and ages to be integers
00:08:28.319
right um or we can pass a block to data
00:08:32.519
defying um and add and override methods
00:08:36.240
uh there's a minor downside to this that
00:08:39.200
person is not defined until you're
00:08:41.959
outside of that
00:08:43.360
Doe um but hardly anybody uses it
00:08:47.000
usually would use self instead of person
00:08:48.959
there uh the bigger downside is
00:08:51.040
forgetting that
00:08:53.000
do uh unless you're an Elixir program
00:08:55.279
where you're used to forgetting the do's
00:08:56.600
and adding the dos and figuring it out
00:08:59.240
um um so data class also allows us to
00:09:01.800
use square brackets instead of
00:09:03.680
new um I find this is kind of maybe an
00:09:06.760
upside um because value objects are
00:09:10.160
visibly distinct from mutable objects in
00:09:12.240
this
00:09:13.839
case and uh it's immutable uh why don't
00:09:17.160
we make a good constant then
00:09:20.320
right um so domain driven design is a
00:09:23.480
great book it's one of my top 10 uh
00:09:26.079
programming books by Eric Evans it tells
00:09:28.920
us how to divide up code
00:09:30.959
cleanly and he divides objects into
00:09:33.399
three different categories we've got
00:09:35.200
value objects which have IM mutable
00:09:37.040
State no Behavior entities which have
00:09:39.760
identity like the ship
00:09:41.680
athus um and they have mutable State and
00:09:44.959
then we have service objects the things
00:09:46.320
that sort of coordinate the other things
00:09:48.920
um and if you're used to an actor model
00:09:50.800
that would be an
00:09:52.959
actor uh value objects are easier to
00:09:55.760
reason about because they don't have any
00:09:57.000
state changes they don't have any side
00:09:58.600
effects they're easier to test we don't
00:10:00.839
need to set up a state we just we don't
00:10:03.440
need to check any state changes we just
00:10:05.920
give an input get an output um so what
00:10:09.320
is this Behavior Behavior to me is
00:10:12.320
changing an object State having a side
00:10:14.680
effect or interacting somehow with the
00:10:16.399
outside
00:10:17.360
world
00:10:20.040
um and methods included in value object
00:10:22.880
should just transform the inputs which
00:10:25.200
are provided when you new up the object
00:10:27.760
into outputs and they should be purified
00:10:31.160
functions uh which brings us to
00:10:32.959
functional programming uh is Ruby
00:10:35.639
objectoriented or is it functional it's
00:10:38.600
both right um so Ruby's functional
00:10:41.560
programming is most commonly used with
00:10:42.959
enumerables
00:10:44.279
so we've got an array or a hash and a
00:10:47.040
range uh map is a a functional concept
00:10:51.000
and it just transforms the
00:10:53.320
data U but Ruby is also a procedural
00:10:56.279
language um here the each indicates that
00:10:59.519
we have some procedural code because
00:11:01.720
it's side effects are its only reason
00:11:03.560
for being each doesn't actually return
00:11:05.279
anything so we have to mutate
00:11:08.240
why so both of these return the same
00:11:10.680
results right uh the second example
00:11:12.839
doesn't mutate in any state uh doesn't
00:11:16.240
mutate anything really um so we don't
00:11:18.800
have to wonder if something else is
00:11:20.240
modifying why uh we don't have to worry
00:11:22.839
about side effects so we can reason
00:11:24.320
about this code more efficiently more
00:11:27.279
easily um Ruby has quite a few methods
00:11:30.560
that mutate data in place um uh we can
00:11:35.000
still mutate contents of arrays and
00:11:37.120
hashes we do that a lot we M tend to
00:11:39.120
mutate active record objects a lot um
00:11:41.959
but note that we don't use these very
00:11:43.639
much anymore we don't do map bang and
00:11:45.560
sort bang and shove it back into X um by
00:11:49.079
the way Phoenix Elixir doesn't mutate
00:11:50.920
their domain objects they actually send
00:11:53.040
a change request to the database instead
00:11:55.040
of like hey here's the change object
00:11:57.160
figure it out yourself
00:11:59.560
um so that provides immutability
00:12:01.120
benefits to to almost all your domain
00:12:04.839
objects um so we've had lazy in
00:12:08.040
numerator since Ruby
00:12:09.800
2.0 uh this is sort of the traditional
00:12:12.480
definition of lazy lazy evaluation and
00:12:15.440
this is a little different than my
00:12:16.519
earlier definition and it's focused more
00:12:18.440
on
00:12:22.040
Expressions uh so the top code here will
00:12:24.279
run forever it will never finish the
00:12:26.079
select and get to the first uh the
00:12:28.440
bottom code will stop after returning
00:12:29.959
the the first five odd
00:12:34.120
numbers um The Lazy returns an
00:12:36.639
enumerator lazy object it's a special
00:12:38.760
kind of enumerator where it collects the
00:12:42.079
blocks and doesn't run them until you
00:12:43.760
need a
00:12:46.079
result so I was looking for examples and
00:12:48.839
all the examples I could find online
00:12:50.440
were using range and I'm like oh man I
00:12:53.360
need to find an example H I wonder if
00:12:55.560
active record can be lazy and I'm like
00:12:58.800
oh
00:12:59.800
active record is already lazy in its own
00:13:01.839
way so it uses something underneath
00:13:03.800
called active relation
00:13:05.920
a um and because it doesn't
00:13:09.480
actually uh execute the query until you
00:13:12.120
ask for the results so here until you
00:13:14.480
call the 2A it doesn't actually do
00:13:16.279
anything it just collects up all the
00:13:18.279
steps it needs
00:13:20.320
to um so it uses a relational algebra
00:13:24.519
using the Builder pattern to build up
00:13:26.120
the query so all Returns the relation
00:13:29.240
and then where adds a new relation onto
00:13:31.760
that um order returns a new relation
00:13:34.519
that's built on those two and then 2A
00:13:37.760
takes that query that's built up and
00:13:41.079
runs it and Returns the result as an
00:13:47.519
array um so object Durning program tells
00:13:51.320
us to tell don't ask an object should
00:13:54.320
contain everything it needs to do
00:13:55.680
something we just tell it to do that
00:13:57.680
thing we don't ask if for information
00:13:59.720
and do something with that
00:14:01.240
information um so all procedural code
00:14:03.920
can actually be see is telling we we
00:14:05.600
tell the computer how to do
00:14:08.279
something so here the system monitoring
00:14:11.560
checks the temperature and sends alarm
00:14:13.240
when
00:14:14.560
necessary um we don't really want to do
00:14:17.399
that in the other way uh we don't want
00:14:20.279
to create a system monitoring and then
00:14:22.639
have someone else know well what's the
00:14:24.759
temperature that we should monitor and
00:14:26.839
what should we do when it happens
00:14:31.199
um but you can't tell an immutable
00:14:33.160
object to do anything you can't tell it
00:14:34.720
to change itself uh you don't want it to
00:14:37.079
tell it to interact with the outside
00:14:38.639
world um but you can ask it to give you
00:14:40.800
a new object and you can persist that
00:14:43.240
new object if you want um here you know
00:14:46.959
I didn't have a first name I gave it a
00:14:49.720
first name and her last name and I have
00:14:51.560
a method called full name that just
00:14:53.320
takes those inputs and creates a
00:14:55.240
separate output that's always the same
00:14:57.600
and I might have a spouse and be able to
00:14:59.839
get the full name from that and if I
00:15:01.600
want to change my name uh I create a new
00:15:04.440
object and maybe I persist that object I
00:15:06.360
don't actually uh mutate the Craig
00:15:10.639
constant
00:15:12.920
itself so who's seen this talk
00:15:15.839
boundaries by Gary burnhard great talk I
00:15:18.920
put it on yearly
00:15:20.399
rotation um so he talks about a
00:15:24.199
functional core and an imperative shell
00:15:28.120
so basically uh your code in the small
00:15:31.199
should be functional and then he calls
00:15:34.160
it
00:15:35.480
um um an imperative shell around that
00:15:38.920
which interacts with the outside world
00:15:41.000
so do as much as you can with with
00:15:43.319
functional objects functional data
00:15:46.000
structures um and then you can do that
00:15:49.000
persistence layer and a layer
00:15:53.480
above
00:15:55.040
so uh in my abstract I talked about
00:15:57.680
better Styles better code but what does
00:15:59.560
it mean for code and styles to be better
00:16:02.639
uh we often talk about readability um
00:16:05.199
but it's really about whether it's easy
00:16:07.480
to understand and to
00:16:09.360
maintain how how easily can someone
00:16:12.079
understand the code and make changes to
00:16:13.600
that
00:16:15.440
code but what we really what we really
00:16:17.839
care is how is it how easy is it change
00:16:20.480
change our code because our code is
00:16:22.040
always changing it's always
00:16:25.040
evolving um I'm REM reminded about this
00:16:27.880
quote from Kent Beck make the change
00:16:29.759
easy then make the easy change
00:16:32.720
everything we're doing when we're coding
00:16:34.319
should be making the change
00:16:37.160
easy um there's also a social aspect to
00:16:40.480
what's what's better what we consider
00:16:42.279
better for example we don't use four
00:16:44.000
Loops in Ruby anymore right uh we use
00:16:46.920
each or we use
00:16:48.639
map um so I use this in the code above
00:16:53.720
and um you notice I put the private
00:16:55.759
right next to the definition to make it
00:16:57.399
obvious instead of having a block of
00:17:00.240
well all the private ones are down here
00:17:02.120
all the public ones are up there I can
00:17:04.600
move this code without caring about oh I
00:17:07.120
put it in the wrong spot who's put it in
00:17:08.880
the wrong spot before I've put a public
00:17:10.959
thing in private and I put a private
00:17:12.280
thing in public like why don't we just
00:17:14.559
put it right there uh it makes it easier
00:17:16.839
for us uh warning rubocop does not like
00:17:19.480
this though um so uh short methods are
00:17:23.360
more readable um so I tend to refactor
00:17:26.199
relentlessly uh try to get oneline
00:17:28.360
methods like this so I'm trying to
00:17:31.360
optimize my style for readability and
00:17:33.880
error
00:17:37.520
avoidance um so thinking back to Larry
00:17:40.440
Wall's
00:17:41.640
quote um I was reminded by this quote
00:17:44.240
from the edile manifesto Simplicity the
00:17:46.960
art of maximizing the amount of not work
00:17:48.919
not done is
00:17:51.760
essential so I love tdd I like this
00:17:56.240
thing called readme driven development
00:17:58.360
tdd has these offshoots bdd and
00:18:00.679
acceptance test driven development
00:18:02.799
there's even things called Data driven
00:18:04.240
and model driven development and
00:18:06.000
probably worth looking into I thought
00:18:08.280
well maybe laziness driven development
00:18:10.320
should be a
00:18:11.720
thing so I Googled to see if it already
00:18:14.120
existed and I found this lazy manifesto.
00:18:17.440
Org the manifesto for lazy product
00:18:20.559
development and you know he talks about
00:18:22.600
Simplicity and quality um I like that he
00:18:25.799
talks about keeping slack um that
00:18:27.960
ensures that we can unexpected events if
00:18:30.880
your team is all full of work and you
00:18:33.440
all of a sudden surprise them with new
00:18:34.880
work all that other work all your plans
00:18:37.159
are going to go to hell right it's just
00:18:40.240
slack time is actually
00:18:42.120
important um and you know you can use
00:18:44.960
that slack time to experiment or to add
00:18:48.480
work that we didn't expect um I like
00:18:51.000
this focus on Simplicity and
00:18:54.480
quality um so some of the principles
00:18:57.039
here are the lazy Manifesto
00:18:59.559
uh work hard only if it makes work
00:19:01.159
easier and safer uh doing nothing is
00:19:03.840
always an option I love that one um
00:19:07.159
minimize backlog items but keep the
00:19:09.320
value of the
00:19:10.559
backlog um increasing velocity is not
00:19:14.240
always a good
00:19:15.360
thing um eliminate tasks to generate no
00:19:18.480
value rearrange tasks to find find the
00:19:21.240
problems early so if you've done a lot
00:19:24.440
of work and you turns out that you've
00:19:25.840
gone down the wrong way it would have
00:19:27.919
been better to figure that out earlier
00:19:29.960
right um simplify all tasks
00:19:33.720
automation um find laser ways
00:19:36.880
capabilities over capacities what are we
00:19:39.880
capable of doing not what do we have
00:19:42.200
room to
00:19:43.120
do and get help from others so I thought
00:19:46.760
well that's not quite what I'm looking
00:19:48.600
for um but it's pretty close so here's
00:19:51.760
my take um let's prefer outcomes versus
00:19:55.720
output and how much work we've done um
00:19:58.919
um let's focus on business value versus
00:20:01.520
productivity and let's work on
00:20:03.320
Effectiveness versus efficiency we can
00:20:05.440
be very efficient in building the wrong
00:20:07.039
thing but what's the point of that
00:20:10.400
um so one of the key indicators that
00:20:13.240
you're probably doing right is Happy
00:20:14.720
developers by the
00:20:16.159
way um we want to do less work but still
00:20:18.640
make the customers
00:20:20.559
happy so lean Kon talks about waste it
00:20:24.360
tells us to eliminate waste where where
00:20:26.159
do we find waste Lane says that all work
00:20:28.799
in progress is waste because if you need
00:20:30.480
to deliver today we can't use that it's
00:20:33.039
still work in
00:20:34.280
progress um every time we change task we
00:20:37.840
have to go through a contact switch in
00:20:39.360
our mental state there's this concept of
00:20:42.039
maker time versus manager time makers
00:20:45.039
need long blocks of time to get into
00:20:47.240
flow to to get all that context in their
00:20:50.080
head managers have short blocks of time
00:20:52.440
to answer questions if you try to fit
00:20:55.200
maker time into manager time it's not
00:20:57.200
going to work well
00:20:59.159
uh can we agree most meetings are a
00:21:00.720
waste of
00:21:02.159
time um my my suggestion is
00:21:05.480
collaboration and work on things instead
00:21:07.240
of talking about things um unused
00:21:10.720
features probably cost more time more
00:21:12.400
than bugs we have the developer time but
00:21:14.919
we also have the carrying cost like
00:21:16.559
every time you run CI it has to test
00:21:19.760
that stuff that you're not even using uh
00:21:22.039
had an example we're the CEO we spent
00:21:24.000
months on this feature no users ever
00:21:26.600
used it we can we could tell no ever
00:21:28.679
users were ever going to use it it just
00:21:30.640
it's what he wanted um unnecessary code
00:21:34.559
testing and documentation I will say
00:21:37.440
testing is usually necessary um for
00:21:40.799
Automation and for documentation
00:21:42.360
purposes because the documents what the
00:21:44.960
code is supposed to do uh but
00:21:47.039
occasionally we'll have some tests that
00:21:48.600
really aren't useful it's okay to throw
00:21:50.520
those
00:21:52.720
away um when we think longterm we make
00:21:55.640
better decisions right um we often do
00:21:58.159
the wrong things we don't take this time
00:21:59.880
to understand our problems we build the
00:22:01.440
wrong thing we just don't do a good
00:22:03.799
job so take the time to do things right
00:22:06.559
do them well um collaboration impair
00:22:10.120
programming reduce waste we don't spend
00:22:11.919
that time waiting for answers uh we got
00:22:14.919
more eyes to catch mistakes we're
00:22:16.600
building on each other's
00:22:18.520
ideas um automation uh my role in
00:22:21.600
automation is automate when the cost of
00:22:23.520
not doing so outweighs the cost of doing
00:22:25.679
it uh same for documentation testing
00:22:29.360
abstraction keep your yagy in mind you
00:22:32.200
ain't going to need it uh stick with the
00:22:34.400
rule of three if you haven't done it
00:22:35.760
three times probably not time to
00:22:37.320
automate
00:22:39.120
yet um think about the next person who
00:22:41.720
has to read this code code is liability
00:22:44.600
it has to be read and maintained and
00:22:46.600
updated uh optimized for the reader's
00:22:49.240
time it's likely future you um always be
00:22:53.600
kind to Future you I know past me was a
00:22:56.520
jerk his code is terrible
00:22:59.440
um but save time by making sure future
00:23:01.760
you can understand it make sure to
00:23:03.279
document why you did things the way you
00:23:05.120
are I can see what the code does but why
00:23:07.520
is it doing that way what were the
00:23:08.840
constraints I was thinking of um code is
00:23:11.760
not just a onetime cost it has to be
00:23:13.240
tested maintained readable um so we want
00:23:16.240
to minimize the amount of code we write
00:23:18.200
and
00:23:18.960
maintain uh we can use libraries and
00:23:21.120
Frameworks to off the load a lot of that
00:23:24.000
but those have some cost too updating
00:23:28.640
security issues um better abstractions
00:23:32.039
are uh a great way to write less code
00:23:34.840
and code this easier to understand don't
00:23:36.919
be lazy in our thinking be lazy in our
00:23:41.440
doing um so some takeaways uh functional
00:23:45.080
core versus imperative shell I think
00:23:47.600
that's probably where the industry is
00:23:49.159
going where it needs to go at least um
00:23:52.039
we need to think in the long term more
00:23:53.679
the short term remember the code is
00:23:55.919
always CH changing and we need to be
00:23:58.640
adapting to those
00:24:00.120
changes um delay work when necessary and
00:24:03.880
our real job is to learn um and I'm
00:24:06.840
reminded of lean's um last responsible
00:24:10.720
moment make decisions at the last
00:24:12.880
responsible moment add the code at the
00:24:14.799
last responsible
00:24:17.440
moment uh so that's it I've got some
00:24:20.120
resources here Gary barnhart's boundar
00:24:22.960
talk is probably where you should follow
00:24:24.880
up next uh documentation on the data
00:24:27.679
class and lazy
00:24:29.080
enumerators um domain driven design and
00:24:32.320
that lazing
00:24:33.720
Manifesto um I am looking for a job as a
00:24:36.559
principal software engineer I just
00:24:38.480
wrapped up a short-term contract and I'm
00:24:41.159
looking for a new good opportunity as a
00:24:43.000
player coach and I've got a lot of
00:24:45.480
experience I am very easy to find on the
00:24:48.360
internet if you can spell my name thank
00:24:51.159
you