00:00:10.080
i'm nick
00:00:11.280
and i'm a first time speaker so let's
00:00:13.040
all collectively pretend like i know
00:00:14.400
what i'm about to do and i'm going to
00:00:16.800
talk about things i've learned from
00:00:18.000
other programming languages
00:00:19.680
because in my career i've learned a lot
00:00:23.279
i've worked in a lot of different
00:00:24.880
languages i think this is all of them
00:00:26.960
but don't quote me on that
00:00:29.679
and the first thing to note is just that
00:00:31.840
each
00:00:32.719
language has a different way that it
00:00:35.280
approaches thinking about code and this
00:00:37.280
comes from both the structure of the
00:00:38.480
language itself as well as the way that
00:00:40.399
communities have created the libraries
00:00:42.879
that you then end up using when you are
00:00:44.800
working in that language and so
00:00:48.480
it guides your thinking it helps you to
00:00:50.000
explore different ways to contemplate
00:00:53.039
how to write code how to organize your
00:00:54.800
thinking and all of that learning is
00:00:57.039
expressible in any other language i mean
00:00:59.440
that's part of what makes during
00:01:00.719
complete right
00:01:02.559
so
00:01:03.520
this is really about hey we can look at
00:01:05.600
some feature of another language some
00:01:07.280
way that some other language likes to
00:01:09.040
think and then how can we apply that
00:01:11.360
thinking either directly or as
00:01:12.960
inspiration for something to do in ruby
00:01:16.240
so i'm going to talk about four specific
00:01:18.320
things uh current functions in
00:01:20.159
javascript companion objects from scala
00:01:22.960
interfaces from java and beans from
00:01:25.759
javaspring framework unless you think
00:01:27.439
i'm a java fan going no
00:01:31.280
so current functions
00:01:33.920
i'm glad you got that
00:01:35.920
so canonically current functions are
00:01:37.920
just a function that returns a function
00:01:39.360
this is a very straightforward
00:01:40.640
javascript example where we're rewriting
00:01:43.280
the addition operation as create
00:01:45.600
functions
00:01:47.200
this can very directly be translated to
00:01:49.040
ruby using procedures
00:01:50.880
but we also have this neat little thing
00:01:53.119
called dot curry
00:01:54.960
all this is saying is hey i'm a function
00:01:56.560
that takes two parameters and you have
00:01:58.320
one and then later you can give another
00:02:01.680
so i first learned about curried
00:02:03.920
functions when i need to detain callback
00:02:05.759
hell i'm gonna blaze through the
00:02:06.960
javascript because we're here for the
00:02:08.319
ruby
00:02:09.280
uh so this is a big chunk of javascript
00:02:11.840
that goes through a directory and
00:02:14.000
creates a bunch of uh different images
00:02:16.959
preserving aspect ratio
00:02:19.040
and we're gonna recompose it into a much
00:02:21.120
prettier current function setup so the
00:02:23.680
first thing that i did is i pulled out
00:02:25.920
the
00:02:26.800
the bit that gets the aspect ratio
00:02:29.280
into its own function
00:02:31.599
placed it there
00:02:33.440
then i pulled out the bit that does the
00:02:35.200
image resizing
00:02:40.160
placed it there and now at the bottom
00:02:41.840
i've got this really handy little block
00:02:43.440
of code that really eloquently describes
00:02:45.200
everything that i'm doing all of my code
00:02:47.040
blocks are named right read directly for
00:02:49.680
each file get the aspect ratio for each
00:02:52.319
width resize
00:02:53.840
much more
00:02:55.280
legible than before so now for the ruby
00:02:57.920
example that you're all here for
00:02:59.920
uh so this is before currying we're
00:03:01.920
going to move a bunch of objects from
00:03:03.680
one location to another in s3 now
00:03:06.080
ironically
00:03:07.519
when i carry it it gets a lot bigger so
00:03:09.840
what do we get from this and don't worry
00:03:12.000
if you can't read all the stuff i'm
00:03:13.200
going to go through each piece of this
00:03:14.640
code
00:03:15.760
so the first thing that this lets us do
00:03:17.280
is let's let's let's us slice up our
00:03:20.159
code in a really novel way we can kind
00:03:22.000
of pull out little steps so what i'm
00:03:24.480
doing here is i'm building a couple of
00:03:25.920
different iterators that i can then pick
00:03:28.000
up and carry around and do anything with
00:03:30.560
so that's what i mean by pull out the
00:03:32.000
middle slice
00:03:34.560
and then that lets me recompose
00:03:37.360
my code in terms of functions right
00:03:39.040
we're all used to dot chains or mixins
00:03:41.360
but this kind of lets me do it with
00:03:42.879
functions as well i can do this
00:03:44.319
composition step right so i can take my
00:03:46.400
iterator from before and i combine it
00:03:48.640
with a little slice of computation to do
00:03:50.640
the copying and i get my resulting
00:03:53.439
code
00:03:55.519
one of the things that i really value
00:03:57.360
from doing this is when i stick to a
00:03:59.599
very functional style
00:04:01.840
i have a very clear description of all
00:04:04.480
of the dependencies that my code has
00:04:07.040
both in terms of literally the client
00:04:08.959
but also in the information that i'm
00:04:10.640
going to need to use to do what i'm
00:04:12.319
about to do because i can just look at
00:04:14.000
the function signature there's nothing
00:04:16.160
in there that doesn't come from those
00:04:18.479
two
00:04:19.440
parameter lists
00:04:22.079
this then of course makes it really easy
00:04:23.759
to do dependency injection because all
00:04:25.280
my dependencies are parameters
00:04:28.800
and that then has the further on effects
00:04:30.880
that it's really easy to test each
00:04:32.400
function because we have no need for
00:04:33.840
state
00:04:35.280
and i found that when i go to write my
00:04:37.759
tests i just go down my library file
00:04:40.560
write a function or two write a test for
00:04:42.560
test or two for each function by the end
00:04:44.240
of it i've got 90 to 95 percent test
00:04:46.400
coverage without ever having to think
00:04:48.160
about it
00:04:49.600
right so just to right we slice up the
00:04:52.720
code in a different way we can compose
00:04:54.560
my functions we can clear we have very
00:04:56.960
clear dependencies which makes it easy
00:04:58.639
to do dependency injection which makes
00:05:00.479
it easy to do tests uh and it makes it
00:05:02.960
easy to get full test coverage
00:05:05.440
uh any quick questions about complaint
00:05:08.240
about code functions
00:05:10.400
all good sweet all right companion
00:05:12.720
objects
00:05:14.400
this is a concept from scala so we have
00:05:16.560
kind of a singleton object that's the
00:05:18.639
same name as a class
00:05:20.960
and this is a core language feature in
00:05:23.199
scala
00:05:24.479
and they have a bunch of special
00:05:25.759
relationships and the one i'm going to
00:05:27.120
point out here is that they can access
00:05:29.600
each other's private aspects be those
00:05:32.080
member functions or variables
00:05:35.039
so we can kind of pull this off into
00:05:36.720
ruby using introspection
00:05:39.199
but that's not great
00:05:42.160
so instead what i ended up doing when i
00:05:44.080
beat my head against the wall for a
00:05:45.199
while i was like how can i take
00:05:46.240
inspiration from this what can i do i
00:05:47.680
really like this pattern it feels good
00:05:49.280
what am i going to do with it i end up
00:05:50.880
doing this kind of stuff uh so i've got
00:05:52.960
some module and i've got some
00:05:54.160
boilerplate at the bottom lets me handle
00:05:55.919
the new while having the names be the
00:05:58.080
same uh and then i've got this struct
00:06:01.120
and i'm extending with the module
00:06:04.960
so what does this let us do uh so this
00:06:07.280
is again an example of moving around
00:06:09.280
files on s3 and again i'm going to go
00:06:11.440
through each block of code in this so
00:06:13.600
don't worry if
00:06:15.840
right so the first thing and it's
00:06:17.840
fitting that i learned scala within the
00:06:19.759
context of apache spark which is a
00:06:21.360
distributing computing thing because the
00:06:23.360
first thing i think this lets us do is
00:06:25.039
really cleanly separate the data that
00:06:27.120
we're going to use to do our computation
00:06:29.520
from the state of that computation right
00:06:32.240
so the struct between the prefix the
00:06:34.319
toke the bucket the prefix and the
00:06:36.080
continuation token for the pagination
00:06:38.800
uh that's all the information that we
00:06:40.319
need to actually do the computation but
00:06:42.880
independent of that is the state of the
00:06:44.639
iterator and because i've got them
00:06:46.319
separated
00:06:47.520
it's really easy to hand that around and
00:06:49.120
get along with my clones
00:06:52.080
so the next thing it lets us do is this
00:06:53.680
really appealing to me at least split
00:06:56.639
for my statics and my methods where i
00:06:58.639
can put all of my transformations in one
00:07:00.960
place and i can put all my actions in
00:07:03.120
another
00:07:04.160
so i've got on the left here under
00:07:05.520
transformations the pagination action
00:07:07.919
right i'm transforming my iterator into
00:07:10.000
the next page but then the action of
00:07:12.319
each iterator is the classic each
00:07:16.479
uh the next thing that i've been calling
00:07:18.479
it dependency application because in my
00:07:20.160
mind it feels sort of like the inverse
00:07:22.000
of dependency injection but i can take
00:07:24.319
any data structure that represents this
00:07:26.479
computation that has these little bits
00:07:28.479
of data and i can apply these functions
00:07:30.800
and run with it so it kind of feels like
00:07:32.960
i'm applying the dependencies to some
00:07:36.319
data
00:07:37.599
so again what this lets us do
00:07:40.000
we can distribute our computing easier
00:07:42.000
because we can separate the data that
00:07:44.000
we're using to compute from the state of
00:07:46.160
that computation we can separate our
00:07:48.479
actions and our transformations
00:07:50.800
and we can
00:07:52.000
apply our code to any piece of data and
00:07:55.120
that last one has been particularly
00:07:56.639
useful again in testing
00:07:58.479
because i can just write down the state
00:08:00.160
that i want to start from and go from
00:08:02.000
there
00:08:04.080
right interfaces
00:08:08.000
some of you are older like me
00:08:10.479
all right so uh interfaces do show up in
00:08:12.800
other places i think canonically they
00:08:14.800
started as abstract classes in c plus
00:08:16.720
plus but whoopty do all we're doing is
00:08:18.720
we're describing all the things you're
00:08:19.919
going to use
00:08:21.360
uh
00:08:22.479
descendants of the class to do
00:08:25.120
in one place but we're not actually
00:08:26.639
going to describe any of the code that
00:08:28.479
does it
00:08:29.680
so in ruby we can pull that off by
00:08:31.840
raising exceptions but again
00:08:33.919
not very satisfying
00:08:35.599
so what i've ended up doing is i've
00:08:37.519
started wrapping all of my dependencies
00:08:40.640
and this is inspired by the interface
00:08:42.320
pattern even if it's not directly the
00:08:44.080
interface pattern so here's a snippet of
00:08:46.080
an s3 wrapper again
00:08:48.320
gives us an iterator for the bucket
00:08:49.680
items gives us a function for moving
00:08:52.320
and
00:08:53.600
here's a real world example uh from a
00:08:55.839
chatbot hobby project i've got where i'm
00:08:58.160
interacting with dialogflow and
00:08:59.680
dialogflow for a lot of valid reasons
00:09:02.240
but still painful reasons has these
00:09:04.240
deeply nested complex data structures
00:09:06.399
that it thinks in and so in order to do
00:09:08.240
the request i have to build all this
00:09:10.240
data structure when really all i want to
00:09:12.640
do is say how do i respond when a
00:09:14.720
stranger says hello
00:09:17.680
so
00:09:18.560
what does this pattern let us do
00:09:20.959
it lets us write our own domain specific
00:09:22.640
language because i can say the action
00:09:24.800
that i care about instead of
00:09:27.120
what the library code likes to think in
00:09:31.120
uh it makes it easy to list every action
00:09:34.720
every interaction that i'm having with
00:09:36.320
my dependency because it's only in one
00:09:38.399
file in one class so i can just search
00:09:40.560
through that class for every instance of
00:09:42.560
my client and i can mock that
00:09:46.240
it also means that i can easily think in
00:09:48.640
the data structures that i want to think
00:09:50.480
in this is a sort of same thing but
00:09:52.399
different for
00:09:53.760
the
00:09:55.040
domain specific language except of
00:09:56.720
course it's about the data instead of
00:09:58.080
the functions right so instead of
00:09:59.600
thinking in the detect intent request i
00:10:01.200
can think in terms of a string and it
00:10:02.560
makes the rest of my code a lot simpler
00:10:06.560
uh so like i said
00:10:09.279
we get to write our own domain specific
00:10:10.959
language we get to clearly list every
00:10:12.959
action that the code performs we get to
00:10:14.880
easy that lets it makes it a lot easier
00:10:17.120
for us to mock our tests and then the
00:10:18.959
rest of our code gets to think how we
00:10:20.800
like to think instead of how the library
00:10:22.240
we're working with
00:10:24.000
any quick questions
00:10:27.040
blazing through my talk
00:10:29.200
all right object graph uh so this one's
00:10:31.279
a little wacky uh it's one of the harder
00:10:33.680
ones to think about because it's a
00:10:35.360
framework
00:10:36.480
not a core language thing so the spring
00:10:39.680
boot framework lets us do this wacky
00:10:42.000
thing where we can define components we
00:10:43.760
can define configurations and then what
00:10:45.839
the framework's going to do is it's
00:10:47.680
going to stitch these two together and
00:10:49.440
it is kind of rails-like in that sense
00:10:51.600
so what i've got here on the left is
00:10:52.959
i've got these functions that define the
00:10:54.800
various dependencies and on the right
00:10:57.040
yeah
00:10:57.920
i've got the place where those
00:10:59.120
dependencies get used and the spring
00:11:01.040
boot framework will actually take each
00:11:02.800
of those beans and it'll inject it into
00:11:06.079
the parameter list for that and just
00:11:08.320
call it uh it's kind of wacky to think
00:11:10.480
about and it turns into a graph
00:11:13.440
so theoretically
00:11:15.519
we could create some sort of auto wire
00:11:18.320
system using the new type system
00:11:21.279
because it is available at runtime we
00:11:23.680
can use any of our classic ruby
00:11:25.680
introspection tricks uh and of course
00:11:27.839
this is very similar to the rail style
00:11:29.920
naming conventions even if it is forking
00:11:31.920
off of a fundamentally different set of
00:11:33.839
operations
00:11:35.279
and what this really lets us do this is
00:11:37.360
the thing i'm a big fan of is separating
00:11:40.000
the what from the web so i've got one
00:11:42.880
place where i'm defining all of my
00:11:44.399
actions right in this case the wrapper
00:11:46.079
that's why i presented these two
00:11:47.200
together because they really work hand
00:11:48.560
in hand so each of my wrappers defines
00:11:50.720
the different things i might do with
00:11:52.480
this stuff
00:11:53.760
but
00:11:54.560
uh my top level code defines when all of
00:11:57.680
those things happen
00:12:00.079
similarly
00:12:01.360
i've now got a graph of how all my
00:12:03.440
pieces connect
00:12:04.800
of course drawing that graph with pencil
00:12:06.959
and paper might be challenging but
00:12:08.160
that's why we have code
00:12:10.959
uh so just to repeat
00:12:13.600
when we think in terms of an object
00:12:14.880
graph we're really thinking in terms of
00:12:16.399
separating what we're doing from when
00:12:18.639
we're doing it right you can think of a
00:12:20.079
graph with the nodes and little things
00:12:21.680
that step in
00:12:23.279
and then we've got one place or more
00:12:25.120
than one if you've got script code here
00:12:26.639
and there
00:12:27.519
where our top level code shows how
00:12:29.279
everything connects
00:12:32.000
so here's a real world example putting
00:12:34.240
everything together so this is a hobby
00:12:35.839
project by the way i highly recommend
00:12:37.519
hobby projects because it's the only
00:12:38.800
time you get to write perfect code and
00:12:40.240
once you know what perfect code looks
00:12:41.600
like
00:12:42.560
of course it's in the ibb holder once
00:12:44.000
you know what perfect code looks like
00:12:45.360
it's a lot easier to do it anywhere else
00:12:47.920
so this is a hobby project that connects
00:12:50.320
air table is a contact list transcribes
00:12:52.800
a conversation with a bot to slack and
00:12:54.880
of course it's a chat bot uh we can see
00:12:57.360
i'm using a bunch of the different
00:12:58.639
features in here
00:13:00.720
and all of this code is a lot easier to
00:13:02.639
read than trying to cram everything that
00:13:04.560
each of these steps does into
00:13:07.040
the endpoint handler right
00:13:09.839
uh yeah
00:13:12.399
so
00:13:14.480
what i told you we talked about carried
00:13:16.079
functions and how they let us slice up
00:13:18.320
computation steps in novel ways and i
00:13:20.560
really am a big fan of that thing that i
00:13:22.079
talked about where you slice out the
00:13:23.440
middle because usually it's pretty hard
00:13:25.279
to
00:13:26.079
pull apart your code when it's nested
00:13:28.399
like that because like how do you how do
00:13:29.839
you get the middle out well curried
00:13:31.360
functions is a great way to do that
00:13:33.360
companion objects which give us a lot of
00:13:35.200
inspiration for separating
00:13:37.360
our data and our state our actions and
00:13:39.440
our transformations
00:13:41.279
which is just i don't know it's an
00:13:42.800
easier way to think about to communicate
00:13:44.720
the code that we're working with
00:13:46.320
interfaces and all the advantages that
00:13:47.920
wrapping things uh gives us and beams
00:13:50.880
the separation of what and when
00:13:54.480
so we have a lot of time for q a
00:13:57.360
so
00:13:59.120
who's got questions
00:14:07.519
um
00:14:09.760
thanks this is uh interesting talk but
00:14:11.760
the thing that um i'm a little worried
00:14:13.440
about is it's not very idiomatic ruby uh
00:14:15.920
what you're showing up there um i think
00:14:18.079
you have a mix of ideas from different
00:14:19.440
languages
00:14:20.959
um but you can do a lot of things like
00:14:22.959
what you're saying in ruby
00:14:25.519
without all the complexity you have in
00:14:27.040
there for for instance on some of those
00:14:28.880
slides right you're using class
00:14:30.079
variables
00:14:31.839
which are really dangerous right because
00:14:33.519
if you get into inheritance right and
00:14:34.959
you have subclasses right if that
00:14:36.240
subclass changes that class variable
00:14:37.760
it's going to it's going to mutate the
00:14:39.120
variable in the superclass so there's a
00:14:41.279
lot of dangers in that code
00:14:43.199
yeah well so one of the things to note
00:14:45.040
is it's challenging to find toy examples
00:14:47.680
that will fit on a slide
00:14:50.320
okay that's that's fair
00:14:52.560
um
00:14:53.839
the other thing i was a little worried
00:14:54.959
about too is you're talking about how
00:14:57.360
you're trying to compose things right
00:14:58.639
using dependency injection
00:15:00.480
but in the classes that you're showing
00:15:02.079
in the code there
00:15:03.360
you don't actually inject anything
00:15:04.800
through the object itself so you have
00:15:06.079
like a class
00:15:07.519
and you have a method
00:15:09.199
and you're just putting methods within
00:15:10.639
the class but there's no state or any
00:15:12.959
kind of constructor that you're
00:15:13.920
constructing the object on and so in
00:15:15.680
object-oriented programming right you
00:15:17.120
want to have an object has a constructor
00:15:18.800
you inject your dependencies right and
00:15:20.240
you call those so
00:15:22.560
kind of feels like what you're asking
00:15:23.600
about is
00:15:25.120
how does this relate to
00:15:27.279
when we should do object-oriented versus
00:15:29.360
functional programming
00:15:31.360
and ironically or interestingly that's
00:15:33.360
one of my favorite interview questions
00:15:35.120
whenever i'm interviewing anybody
00:15:36.399
regardless of which side of the aisle
00:15:37.839
i'm on i will ask what is your
00:15:40.000
understanding of these two things and
00:15:41.120
when you should you use either so
00:15:42.959
interestingly uh
00:15:45.279
this top pattern which is actually just
00:15:47.120
the builder pattern right where i've got
00:15:48.560
the incoming message and i'm
00:15:49.600
constructing other things that's what
00:15:51.279
happened when i spent a while trying to
00:15:53.440
figure out how to use curried functions
00:15:56.079
in my project so that goes back to the
00:15:58.399
thinking that regardless of whether or
00:16:00.480
not we actually take the construct from
00:16:03.360
another language
00:16:04.880
the encouragement to think in this
00:16:06.880
different way can give us new insight
00:16:08.720
into how to write our own code
00:16:10.720
there's also a few places where
00:16:13.120
trying to apply one thing from one
00:16:15.199
language to ruby never resulted in a
00:16:17.519
useful pattern but did result in a
00:16:19.360
deeper insight for how ruby itself
00:16:21.680
functions and that sort of goes back to
00:16:23.680
the i know there's a number of talks
00:16:25.120
here that are about things you really
00:16:26.880
shouldn't do with ruby but you can and
00:16:30.240
again playing around with a language in
00:16:32.320
that way does a
00:16:33.839
huge benefit for your understanding of
00:16:36.880
the deeper ways that language works as
00:16:38.720
well as may yield some useful patterns
00:16:41.199
for how to organize your code
00:16:43.680
yeah that makes sense oh i asked one
00:16:45.279
more question i promise not to hug
00:16:47.279
the time
00:16:49.120
the one thing i want to ask you
00:16:50.720
have you looked at dry rb because some
00:16:52.639
of the functional set uh aspects that
00:16:54.720
you're trying to do here um is great i
00:16:57.040
like where you're going with this but
00:16:58.480
you might want to reach for dry rb
00:17:00.000
actually to give you some of that
00:17:01.839
like dependency injection uh being able
00:17:04.160
to have like a monadic pattern right so
00:17:05.760
you can have just a success or a result
00:17:07.280
type thing like
00:17:08.559
you're kind of scratching the surface
00:17:09.760
here uh but if you bring in dry rb you
00:17:11.679
would actually get a lot of super power
00:17:13.360
with that so what i'm hearing is
00:17:14.559
encouragement to check out dry.rb which
00:17:17.120
i haven't checked out before uh
00:17:19.439
one of the reasons why i've worked in a
00:17:20.720
lot of different languages is i keep
00:17:22.319
trying to work for ruby shops and not
00:17:24.079
succeeding
00:17:25.199
uh how has learning ruby affected you
00:17:27.679
the way you write other programming
00:17:28.960
languages
00:17:30.000
yeah thank you for asking that uh i had
00:17:32.480
a like a list of ten things
00:17:34.720
in the talk proposals when they said
00:17:36.000
pick three
00:17:37.600
uh but it turned out two of them were
00:17:39.120
linked uh so ruby i feel like
00:17:42.160
really what ruby taught me is the code
00:17:43.679
can be beautiful which is really sappy
00:17:45.919
but then what happens is i write code
00:17:47.760
that i'm really deeply unsatisfied with
00:17:49.440
like uh this is third or fourth rewrite
00:17:52.080
of the same code base and i kept being
00:17:53.840
unsatisfied with it because it didn't
00:17:55.600
feel beautiful and then once i got it to
00:17:58.160
the point that it was beautiful
00:17:59.919
everything made so much more sense and
00:18:02.000
so ruby kind of taught me on a deep
00:18:03.919
level that if it's not aesthetically
00:18:06.080
pleasing there's a better way to do it
00:18:07.600
and once i get to the better way i'm
00:18:08.799
like yeah yeah this makes way more sense
00:18:11.520
yeah i'm curious what are your
00:18:13.120
experiences um you know on a larger team
00:18:16.080
getting them on board with some of these
00:18:18.240
new patterns and really novel ways of
00:18:20.640
thinking through ruby or another code
00:18:23.360
yeah so
00:18:25.600
one of the big things that happens is
00:18:26.799
just people have inertia
00:18:28.400
and that inertia comes from
00:18:30.480
hey i've already got a plan for how i'm
00:18:31.919
doing this next step uh i've got
00:18:34.000
pressure from my manager to accomplish
00:18:35.919
this thing i've got pressure from
00:18:37.039
product on the timeline
00:18:38.720
uh so it generally ends up being more
00:18:40.720
like planting seeds that then come to
00:18:42.320
fruition later that said um this
00:18:45.280
particular bit the what from the when
00:18:47.520
so my current gig is i'm doing a lot of
00:18:49.679
support engineering and we have to do a
00:18:51.440
lot of fixing our systems when they
00:18:53.440
break so we've got a lot of utility
00:18:55.039
scripts and it was really useful and was
00:18:58.080
really easy to get a bunch of my more
00:19:00.240
junior programmers
00:19:02.320
on board and contributing to these tools
00:19:04.799
when i separated the library code from
00:19:07.120
the script code and then the script code
00:19:09.200
which is breaking all the time because
00:19:10.640
we're not the core engineering teams the
00:19:12.320
core engineering team changed the system
00:19:14.080
the script breaks but the script then
00:19:16.240
functions like documentation in fact the
00:19:18.799
first generations of the script were
00:19:20.320
literally taking the run books
00:19:22.640
and turning them into code
00:19:24.480
and so i took you know this step this
00:19:26.000
step this step and i define that step in
00:19:27.600
the library and then i put it in the
00:19:28.960
thing now you can just
00:19:30.480
read the code and say okay i got to do
00:19:32.640
this step then this step then this step
00:19:34.240
then this step
00:19:35.679
without having to get into the weeds or
00:19:37.760
getting distracted by the weeds of how
00:19:39.520
each of those steps are accomplished
00:19:41.679
so just by way of encouragement i've
00:19:44.000
done a lot of bad things for
00:19:45.200
reprogramming language over the years
00:19:47.039
you can probably find that all over the
00:19:48.320
place but a lot of the things that have
00:19:50.400
been done that you say these are
00:19:51.919
anti-patterns these don't make sense
00:19:53.760
eventually those ended up getting merged
00:19:55.280
language so by way of encouragement
00:19:57.280
please do experiment please do try new
00:19:59.440
things give those ruby bug tracker a lot
00:20:01.600
of times you'd be surprised in the
00:20:02.960
language i'll say it one time this is
00:20:04.799
all magic and then matt's merges it and
00:20:06.480
i had to recant my entire talk like i
00:20:08.159
don't have any magic anymore quit
00:20:09.440
stealing all my thunder here but
00:20:12.000
as far as functional patterns i'd be
00:20:13.840
very interested in this kind of my
00:20:15.600
question what you think of stuff like
00:20:17.440
raptors a lot of this isolate object
00:20:19.360
space and what that might kind of evolve
00:20:20.799
ruby into over the years to be honest i
00:20:23.280
don't really know what rector means the
00:20:24.720
word i kind of want to crack a joke
00:20:26.159
about monads and endo functors without
00:20:28.159
knowing what any of the words mean so
00:20:29.919
racter is ruby actor model kind of based
00:20:32.159
on erlang where you have isolate state
00:20:34.960
you can't really do anything with it and
00:20:37.360
there's a very real chance where we end
00:20:38.880
up going into deep functional land
00:20:40.400
because of that because there's no way
00:20:41.760
to use object-oriented kind of stateful
00:20:43.679
stuff in there
00:20:45.200
so my understanding is
00:20:47.440
basically one of the major advantages of
00:20:49.280
functional programming is the ease with
00:20:50.880
which it does concurrency because of its
00:20:53.120
restrictions on how you're modifying
00:20:55.039
state
00:20:56.000
um
00:20:56.960
and so
00:20:58.400
but also some of the the experience that
00:21:00.080
i've had trying to build larger
00:21:01.679
functional programming
00:21:03.840
projects
00:21:06.480
some things don't fit
00:21:08.640
into the functional programming
00:21:11.440
idiom
00:21:12.559
well and it can get really confusing
00:21:14.480
trying to think about certain things
00:21:16.400
when you're trying to wedge them into
00:21:17.760
that so that's where the diversity of
00:21:19.440
thought patterns i think really comes in
00:21:21.600
in handy
00:21:23.360
my brain's poking at me and saying go
00:21:24.880
back to the scala companion object with
00:21:26.720
that sort of novel combination of
00:21:29.760
i've got my pure functions but then i've
00:21:32.000
also got my data in my state
00:21:34.799
and how that interacts with the
00:21:36.559
distributed computing
00:21:38.480
so
00:21:39.520
hi there
00:21:40.480
i just have one question so being a
00:21:42.559
polyglot have you found another language
00:21:44.640
that's as ergonomic as ruby scala
00:21:48.880
it's the only one that feels like ruby
00:21:51.440
um
00:21:53.120
it's got a lot of
00:21:54.480
a lot of things that i i didn't realize
00:21:56.080
that i loved about ruby until i noticed
00:21:58.159
that they were also in scala like um one
00:22:00.880
of the novel things
00:22:02.960
the
00:22:04.159
code
00:22:05.200
like when you're in a class definition
00:22:07.600
the code that you're writing is the same
00:22:09.280
kind of code as the code that's inside
00:22:11.280
of a function definition
00:22:12.880
contrast that with like c plus when
00:22:14.960
they're very different kinds of code uh
00:22:17.200
and scala is one of the few other
00:22:18.480
languages that i've noticed i mean i
00:22:20.159
know java is the same way it's not java
00:22:22.640
javascript's the same way python's the
00:22:24.159
same way but scala is one of the other
00:22:25.520
languages that i've noticed that
00:22:28.240
is also the case and is actually used by
00:22:30.559
the community
00:22:32.720
um i'm new to ruby and one of the things
00:22:34.720
i've been very impressed by is pry
00:22:37.520
i was curious if you your thoughts on
00:22:40.960
like debugging and all these other
00:22:42.799
languages and how they compare
00:22:44.720
to movie
00:22:46.960
yeah uh
00:22:48.720
compiling languages do have a bit of a
00:22:50.960
advantage with your debugging tools
00:22:55.520
but
00:22:57.280
then you don't get things like your
00:22:59.280
rebel console
00:23:00.559
so one of the
00:23:01.760
one of the things that i like about some
00:23:02.799
of the patterns that i've used here is
00:23:05.679
when i want to debug what i generally
00:23:07.520
find myself doing is rather than putting
00:23:09.440
in like a price statement somewhere in
00:23:11.120
my codebase
00:23:12.400
i'll actually
00:23:13.760
use the code to set up an environment
00:23:15.600
and just play around with the grapple
00:23:16.799
console
00:23:20.240
in terms of i mean so like javascript
00:23:23.919
all the scripting languages kind of have
00:23:25.280
the same kind of tooling for their
00:23:27.919
debuggers you'll stick some statement in
00:23:29.919
somewhere that drops you into rebel
00:23:31.200
console in your local uh scope
00:23:33.679
uh and then all the kapow languages have
00:23:36.240
something that's a more formalized set
00:23:37.679
of tools for debugger where you can put
00:23:40.000
in the the breakpoint statements and the
00:23:41.840
like uh and then of course they they
00:23:44.159
cross
00:23:45.600
so there are there's tooling in
00:23:48.880
scripting languages that lets you drop
00:23:50.320
in break points and then in recent years
00:23:53.919
uh particularly with the advent of
00:23:55.919
jupiter notebooks people have started
00:23:57.840
adding in rapple consoles so you can do
00:24:00.559
c plus from
00:24:02.799
the same sort of thing as irb
00:24:05.279
uh instead of having to compile your
00:24:07.279
whole thing you can write a chunk of
00:24:08.720
code compile and link it write a chunk
00:24:10.720
of code compile and link it well um we
00:24:13.120
can call it there
00:24:16.720
thank you for coming to my talk