00:00:15.360
okay um thanks for
00:00:17.840
coming my name's Tom anabo I'm normally
00:00:20.640
known as Tom and not Thomas but I always
00:00:22.680
feel I need to be formal um as Sarah
00:00:26.119
said I'm J molad and I'll also point out
00:00:29.519
that uh Charlie and I are doing a j Ruby
00:00:32.960
talk after lunch I don't have the
00:00:35.320
details on the screen but I should have
00:00:37.320
put that there uh I've been using Ruby
00:00:39.840
and Java a very long time I'm also kind
00:00:42.600
of a fan of rust now and if you're an
00:00:46.440
employer looking to hire me um I'm
00:00:49.920
looking for a job so there's my LinkedIn
00:00:53.719
link all right so what's an esoteric
00:00:56.120
programming language Wikipedia has a lot
00:00:58.920
to say but we're not going to read that
00:01:02.320
all right I'm going to break it down to
00:01:03.800
two sentences it's a programming
00:01:05.840
language that's typically hard to use or
00:01:08.960
understand and you're going to consider
00:01:11.600
the language weird in comparison to a
00:01:13.840
traditional programming
00:01:17.520
language the language we're going to be
00:01:19.439
looking at today is
00:01:21.280
p it's known it's named after this guy
00:01:25.119
uh there's one of his more famous pieces
00:01:28.040
on the right he unfortunately um didn't
00:01:32.479
have a great fashion sense later in life
00:01:36.119
uh so we'll remember him by this photo
00:01:39.399
he's pretty cool he's somewhere between
00:01:42.360
George Clinton and time traveling
00:01:45.040
hipster and if you want to go and waste
00:01:47.960
five or 10 minutes of your life but be
00:01:50.079
somewhat entertained look up time
00:01:52.079
traveling
00:01:53.360
hipster narrator he's not a time
00:01:58.159
traveler so uh
00:02:00.360
P it's an image-based language just like
00:02:02.399
small
00:02:03.759
talk well no not really it's literally
00:02:06.799
an image so uh if you run P it on this
00:02:10.720
image it's going to display P it to the
00:02:15.040
screen it's also a funge Fung is just
00:02:17.920
languages that involve coordinate
00:02:22.120
systems it's stack
00:02:26.959
based uh the unit the primary unit of
00:02:30.800
things is a codal this is a n byn set of
00:02:34.120
pixels this one is 10
00:02:38.519
by1 uh adjacent colas are made into
00:02:41.840
groups so in the upper Le hand corner we
00:02:44.239
have a 3X3
00:02:50.319
group there's a direction pointer this
00:02:52.800
indicates the flow of the program as it
00:02:55.319
moves through the image uh it's all P
00:02:59.120
programs start by by executing in the
00:03:00.519
upper left hand corner of the image and
00:03:03.080
it uh is set to right
00:03:08.400
initially uh there's another concept
00:03:10.640
called a codal Chooser where it's either
00:03:14.040
set to left or
00:03:15.560
right and so the navigation is the
00:03:18.879
direction pointer will move through a
00:03:20.640
group and try to enter the next group
00:03:23.319
and at the most extreme Edge the codal
00:03:25.519
Chooser will say should I go at the left
00:03:28.560
side or the right side of the that
00:03:32.200
edge so uh here's Just A visual
00:03:35.680
representation if the direction pointer
00:03:37.640
is right and the col choosers left we're
00:03:40.040
going to go from the blue to the dark
00:03:41.840
blue square or
00:03:44.840
group at
00:03:46.599
a but if the Cal choosers is right we're
00:03:49.760
just going to go in at B it's pretty
00:03:52.599
simple okay harder
00:03:56.239
example if the direction pointer is
00:03:58.239
right and the C choosers is left
00:04:00.720
uh we're going to go and enter into this
00:04:02.720
green group but had it been right it's
00:04:06.120
going to go into this dark blue
00:04:09.959
group uh P programs have six different
00:04:13.000
colors and each of those colors have
00:04:15.200
three different shades light normal and
00:04:19.759
dark and when you transition from one
00:04:22.919
group to the next group you go and
00:04:25.080
reference this table to figure out what
00:04:26.759
operation to
00:04:28.560
perform uh we have some stack
00:04:31.720
operations we have
00:04:34.080
math
00:04:36.680
inequalities input and
00:04:38.840
output and then we have two Special
00:04:41.320
Operations one is pointer which allows
00:04:44.240
you to programmatically change the
00:04:45.759
direction pointer and switches the same
00:04:48.360
thing for the codal
00:04:51.520
Chooser so when I say one shade darker
00:04:54.160
and this is how it's written in the pet
00:04:55.919
speec uh it makes sense that light blue
00:04:58.800
to Blue is one shade darker and blue to
00:05:02.639
dark blue is one shade but it also is
00:05:05.199
that a dark blue to light blue is one
00:05:06.720
shade darker so don't get too hung up on
00:05:10.360
the word it's just a
00:05:14.880
circle similarly for uh Hue changes
00:05:19.639
again it's just a circle all these are
00:05:21.960
examples of the Divide operation um but
00:05:25.560
if you go to Red you just go around the
00:05:27.000
circle too and that's it that's green
00:05:31.440
okay so now we're just going to go
00:05:32.520
through a program to get an
00:05:34.840
idea of uh how it works in practice so
00:05:38.720
as I said we start in the upper leftand
00:05:41.000
corner because the direction pointers
00:05:43.319
and the direction pointer is Right C
00:05:45.000
choos is left so we enter into the dark
00:05:47.880
blue uh group at that upper point where
00:05:51.319
the arrow
00:05:52.360
is and we look it up oh it's one shade
00:05:55.160
darker so we're going to do a push and
00:05:57.720
we're going to end up pushing nine
00:05:59.199
because
00:06:00.280
we use the size of the group that we're
00:06:02.479
leaving as the value to
00:06:07.360
push okay so now at step two we run into
00:06:10.280
black it's not one of the six colors
00:06:12.720
it's an impassible color in fact if you
00:06:16.360
actually exit off the side of the image
00:06:18.639
it's equivalent to running into black so
00:06:20.440
you can just kind of pretend to all pit
00:06:23.240
programs are just lined with a black
00:06:26.319
border and so when this happens you do
00:06:29.280
this
00:06:30.800
algorithm so for up to eight times you
00:06:33.440
flip between the codal Chooser and you
00:06:36.000
just rotate the direction pointer
00:06:37.880
clockwise and try to find another place
00:06:40.120
to
00:06:41.680
go um if you can find it in eight moves
00:06:44.880
that's how a p program
00:06:48.080
terminates okay so Cal choos it goes
00:06:50.120
from left to right and we move in and
00:06:53.039
We're Off to the Races we're still
00:06:56.639
executing okay uh we'll go to the next
00:06:59.240
special
00:07:00.280
thing we're now in this uh little
00:07:02.879
L-shaped green group and uh we're moving
00:07:06.720
down and I promise you that is white it
00:07:11.440
does not look white but for the sake of
00:07:13.440
this talk it is really
00:07:15.400
white um in the case of white though you
00:07:17.879
just kind of slide through to the next
00:07:21.599
thing all right so that's the basic
00:07:24.960
rules of
00:07:26.120
PE and I'm sure everyone's going to run
00:07:28.440
off and make their own program
00:07:30.960
if you want to run them you can go and
00:07:32.879
install R pit this is my implementation
00:07:35.160
of the pit language it will run in C
00:07:38.039
Ruby or J Ruby but if you want to use
00:07:40.960
the uh graphical
00:07:43.280
debugger then you have to use J Ruby and
00:07:46.159
that's using a j j Ruby Library called
00:07:49.120
Java FX which is pretty
00:07:52.560
sweet okay so a few example programs to
00:07:55.240
kind of wet the appetite for writing
00:07:56.800
your own P programs the first one is cow
00:08:00.159
say I am just executing this off the
00:08:04.520
internet and when you run it uh it
00:08:07.240
prompts you for some text and then the
00:08:10.319
cow goes and repeats it it's pretty
00:08:14.159
cute this one's kind of mind-blowing
00:08:17.080
someone figured out how to go and uh
00:08:20.080
make two programs in one image by
00:08:22.479
changing the codal size so it just
00:08:24.840
prints two different things
00:08:30.720
this is my favorite um as I say you
00:08:34.000
enter a p program by going to the upper
00:08:35.839
lefthand corner the first thing you hit
00:08:37.320
is this red line which is half the
00:08:41.399
image's size so you push that onto the
00:08:43.800
stack then you go and find the circle
00:08:46.680
and you push that and that's the area of
00:08:48.480
the
00:08:49.160
circle area
00:08:51.160
over R 2 right and you get this perfect
00:08:54.800
Pi
00:08:56.320
number so I should I should point out
00:08:59.160
that
00:09:00.279
there are no floating point in P so
00:09:03.440
pretend there's a period there um but
00:09:06.079
this is actually a better approximation
00:09:07.839
than at least one States legal
00:09:09.800
definition of Pi so there's
00:09:14.680
that okay so now I'm done talking about
00:09:17.040
P at the language I'm going to talk
00:09:18.640
about
00:09:21.079
um implementing it
00:09:23.839
myself I just ported it from
00:09:28.120
python yeah so uh porting is hard uh
00:09:32.519
Python and Ruby are not identical
00:09:33.959
languages so there's different
00:09:36.360
idms porting code you make lots of like
00:09:39.040
stupid mistakes where you just do the
00:09:40.959
wrong thing and there were no tests I
00:09:43.320
say few tests but there were none
00:09:47.079
so what you do is you generate a
00:09:49.959
debugging uh output that's similar to
00:09:52.000
another P implementation figure out
00:09:54.440
what's wrong and then and then fix it I
00:09:57.120
was comparing against npit which is
00:10:00.200
kind of the the best P implementation at
00:10:03.480
least for
00:10:05.760
now okay so I I made a graphical
00:10:08.399
debugger so let's take a look at
00:10:10.920
that all right so I'm going to start by
00:10:13.480
hitting step oh wait I got to start it
00:10:16.000
though all
00:10:17.320
right so I hit step once I hit step
00:10:20.839
again now I'm going to go and set a
00:10:24.839
breakpoint then I'll resume it gets
00:10:27.800
there pretty quickly then I look at the
00:10:30.040
stack yeah that's what I expected then I
00:10:32.920
keep running
00:10:35.120
it you can see it bouncing
00:10:38.399
around so uh the fun thing about this
00:10:41.079
video is it gives you the illustration
00:10:42.920
of that that I'm going to try to move
00:10:45.600
stuff eight times and then terminate so
00:10:47.959
if you look at that green upside down T
00:10:50.320
it's surrounded by black and so it did
00:10:53.480
the eight different changes and then
00:10:55.279
said I'm out of here
00:11:01.079
okay so I quite literally ported The
00:11:04.040
Interpreter I don't expect you to read
00:11:06.360
that um or I'm not sure if you can even
00:11:08.639
read it um but it's almost all in one
00:11:12.360
method it's kind of what I call code
00:11:14.760
shouter there's just way too much stuff
00:11:16.600
in a
00:11:17.839
method
00:11:20.160
so it has a mixture of concerns it's
00:11:23.360
continuously reparsing and changing that
00:11:26.880
direction pointer and Cal Chooser uh
00:11:30.920
and that's
00:11:32.600
invariant logic so we need to fix that
00:11:37.440
uh like the shortlived mcdlt we have to
00:11:39.920
keep the hot side hot and the cold side
00:11:42.519
cold does anyone remember
00:11:45.959
mcdlt all right all right we got a few
00:11:48.320
people I thought you know sometimes they
00:11:50.880
put this stuff in for me
00:11:55.160
so um but in all programming languages
00:11:59.279
you translate the text of your language
00:12:01.160
I shouldn't say all nearly all languages
00:12:03.279
you translate the text into a data
00:12:05.440
structure it's almost universally uh an
00:12:08.519
abstract syntax tree so here's a snippet
00:12:11.560
of Ruby uh when this gets parsed it'll
00:12:14.519
construct a wild node and then there'll
00:12:17.480
be a Boolean node for the test and then
00:12:19.480
there will be a call node with the puts
00:12:21.079
in it and so forth now most languages
00:12:24.360
and matz even mentioned this in his
00:12:25.839
keynote this morning uh the interpreter
00:12:29.600
that you make will actually be attached
00:12:31.079
to this tree so every one of these nodes
00:12:33.279
will have their own execute method so
00:12:35.800
when you're actually execute a while
00:12:38.040
node you'll just call execute on the
00:12:39.639
wild node it'll do the test it'll
00:12:41.800
execute the body and so
00:12:43.920
forth so that's what we're going to do
00:12:46.240
now and and RP
00:12:48.160
it but uh it has all sorts of weird
00:12:52.279
abilities to like fold back in on itself
00:12:55.199
so we can't really do a tree so we're
00:12:57.760
going to make an abstract syntax group
00:12:59.199
graph
00:13:00.720
instead every note is going to be the
00:13:03.399
operation we perform so if you
00:13:05.720
remember in the early examples where we
00:13:08.120
went from Blue to dark blue it was a
00:13:09.920
push so we' create a push node and
00:13:14.160
pretty much every operation that was in
00:13:16.199
that table will become its own
00:13:18.160
node uh we have to create some new nodes
00:13:21.079
to keep track of when the direction
00:13:22.480
pointer and coer changes so that'll go
00:13:25.360
into the graph as
00:13:27.880
well and then and then the algorithm is
00:13:30.120
we're going to just strip out the
00:13:31.320
execution from the original code shouter
00:13:33.920
and make it into a
00:13:35.360
visitor and for every possible
00:13:37.519
transition from one group to the next
00:13:39.199
group we're going to add it to a work
00:13:40.880
list so uh for the pointer
00:13:44.160
operation that can potentially go four
00:13:46.720
different transitions so we just add
00:13:48.360
them in there and we just process this
00:13:50.519
thing until we have a complete
00:13:55.000
graph and now here's what the graph
00:13:57.440
interpreter looks like uh we start at
00:13:59.279
the entry part of the graph and then
00:14:02.320
I'll just bring the push up again for
00:14:04.480
that example program the first thing we
00:14:06.160
had execute is is push and then when it
00:14:09.480
finishes it Returns the next node to
00:14:11.639
execute and if it returns nil program's
00:14:15.000
done
00:14:17.079
simple ah okay
00:14:19.440
so uh The Benchmark for the rest of this
00:14:22.199
is going to be a prime number
00:14:24.079
detector when you run at a prompts for a
00:14:26.360
number and it tells you whether it's a
00:14:27.680
prime or not and it's got a nice little
00:14:29.880
face on
00:14:32.279
it and I couldn't think of a number to
00:14:34.519
use so I'm going back I'm going way back
00:14:38.360
uh
00:14:39.680
8675309 does anyone use this number
00:14:42.480
whenever you have to do a fake phone
00:14:44.480
number okay more people than knew the
00:14:46.800
mcdlt reference that's good uh this is
00:14:50.120
from the song Jenny it's her phone
00:14:52.519
number and it's forever etched in my
00:14:57.480
brain Okay so when I run the original
00:15:00.320
interpreter it takes about 147 seconds
00:15:02.959
and now with the new graph interpreter
00:15:05.279
it doubled in speed effectively getting
00:15:08.000
rid of that constantly reparsing the
00:15:09.959
image to navigate is a pretty good
00:15:13.240
payback so
00:15:14.880
good but we want to make it faster now
00:15:17.680
so let's get away from the abstra syntax
00:15:20.240
graph and go to a list of
00:15:23.440
instructions and these list of
00:15:25.279
instructions will mostly be the same
00:15:27.040
that the operations in the original
00:15:29.720
table but because we have these weird
00:15:33.120
jumps and flow control changes we need
00:15:35.240
to actually add branches and
00:15:38.639
jumps uh and so now what we're getting
00:15:41.160
to at this point is we're going to
00:15:43.399
convert this graph into a single
00:15:45.519
sequence of text with instructions so
00:15:49.160
I'm effectively making a simple
00:15:51.440
programming
00:15:55.000
language uh here's a translation from uh
00:15:58.800
the dupe operation in the graph where we
00:16:02.399
just take the top element of the stack
00:16:04.319
and duplicate it and now for uh the new
00:16:09.399
IR instructions I'm going to actually
00:16:11.000
make three instructions where I pop the
00:16:13.920
top element and I just push it
00:16:15.920
twice for
00:16:18.920
reasons and so now we end up with a
00:16:21.079
single list of instructions and this is
00:16:22.959
pretty easy to read and it's a lot
00:16:24.680
easier than reading a gif image so if we
00:16:28.440
look at the GRE green underline here uh
00:16:31.399
jump to test end towards the bottom what
00:16:34.480
that will do is it'll look for the label
00:16:36.319
test to end and execute that instruction
00:16:42.240
next and if we look at our new
00:16:44.360
interpreter uh we now have this
00:16:46.360
instructions list that's indexed with
00:16:49.240
this program
00:16:50.680
counter and it gets the instruction it
00:16:53.720
executes it and if flow control changes
00:16:57.360
it uh return something that we can then
00:17:00.519
use to look up in a jump table for the
00:17:02.800
next index that we should execute from
00:17:05.880
and if not it Just increments the
00:17:07.480
program counter and does the next
00:17:11.559
instruction uh
00:17:14.240
oh well I did actually add more
00:17:17.439
instructions than their originally nodes
00:17:19.520
so I think this is sort of to be
00:17:21.720
expected and I'm actually trying to
00:17:24.199
massage this in a way where I can
00:17:26.559
do common well-known optimization ations
00:17:29.919
uh things that if youd taken a
00:17:31.840
compiler's class uh you would have it in
00:17:34.880
your textbook or you look up on
00:17:38.400
Wikipedia uh
00:17:40.400
and I did the dupe thing for a reason
00:17:43.799
for the first
00:17:45.480
optimization which is to do a simple
00:17:47.600
pull
00:17:48.679
optimization so with the pull
00:17:52.280
optimizations you take one set of
00:17:54.440
instructions and you look for a pattern
00:17:57.120
that makes it better generally faster in
00:18:01.000
this case I'm using a very specific one
00:18:03.240
uh if you see a push followed by a pop
00:18:05.720
you can eliminate both of those and just
00:18:08.240
make it into an
00:18:11.880
assignment and uh you can see here if
00:18:15.320
there's multiple of them it's almost
00:18:16.919
kind of like
00:18:17.840
a Russian nesting doll where the push
00:18:22.320
one V1 equals pop will just become an
00:18:25.679
assignment but then once you do that
00:18:27.320
then you can all already see that but
00:18:29.120
you can do it again for push two and
00:18:32.240
V2 and so now if you can imagine that
00:18:35.679
the next instruction after this is going
00:18:37.240
to be an arithmetic
00:18:39.559
operation uh we can do another
00:18:41.400
optimization called constant propagation
00:18:44.120
where we can just get rid of V1 and V2
00:18:47.159
and make that math 1 plus
00:18:49.120
two and now you're looking at that and
00:18:51.280
you're thinking H why would I do 1 plus
00:18:54.440
two I can just constant fold that into a
00:18:57.480
single assignment because I know 1 plus
00:18:59.840
2 equals
00:19:03.400
3 and all these optimizations keep
00:19:05.919
stacking on each other and luckily P
00:19:09.280
uses tons of pushes and
00:19:11.200
Pops so I was able to reduce the number
00:19:13.880
of instructions from 197 down to
00:19:17.120
76 now it's four time four and a half
00:19:19.559
times faster than the original it's more
00:19:22.120
than twice as fast as the graph
00:19:23.640
interpreter
00:19:25.120
so hooray me
00:19:31.080
anyone remember Slap
00:19:32.880
Chop okay that's more
00:19:35.919
modern all right so the last thing that
00:19:38.280
I'm going to do is I'm going to try to
00:19:39.440
get rid of most of The Interpreter
00:19:41.480
overhead uh as I said we're constantly
00:19:45.640
accessing stuff out of an
00:19:47.520
array uh we're incrementing this program
00:19:51.559
counter and recalling execute I mean
00:19:54.679
what we're doing here is
00:19:56.679
we're simulating a machine
00:20:00.000
and that's not very
00:20:02.679
fast and we're going to solve this by
00:20:04.840
transpiling to
00:20:06.520
Ruby uh we still unfortunately because
00:20:09.000
of the complexity of the language have
00:20:10.559
branches and jumps so we will still have
00:20:13.679
to emulate the machine a little bit but
00:20:16.960
everything else can just become
00:20:18.640
transpiled lines of Ruby and then we get
00:20:21.159
rid of the overhead of
00:20:24.120
that so I don't expect anyone to read
00:20:27.120
that at all um but for the both the
00:20:30.880
optimizations and for uh this
00:20:34.360
transpiling I made a control flow graph
00:20:37.080
the important thing here is you can see
00:20:38.799
all these little lines pointing between
00:20:40.679
boxes this is all the places where flow
00:20:44.559
changes and if we zoom in a little bit
00:20:47.080
on one uh I gave each one a somewhat
00:20:51.440
random name I think that 4012 is its
00:20:54.480
object
00:20:55.520
ID but um if we look at how we trans
00:20:58.960
pilot uh V1 equals NN for numeric
00:21:04.240
input uh we just print out prompting for
00:21:06.960
the number and then we get it from the
00:21:09.039
io and convert it to an integer the
00:21:11.600
pushes are pretty obvious what's
00:21:13.039
happening here and then the very last
00:21:15.679
line is the next method that we have to
00:21:19.840
execute so now if we look at this
00:21:21.919
version of The Interpreter uh we're
00:21:24.720
basically just sending to all these
00:21:26.159
generated
00:21:27.360
methods and and they just uh um return
00:21:30.640
the next method to
00:21:31.960
execute so some people might be
00:21:35.559
wondering why don't you just call re 404
00:21:39.600
in this method instead of returning it
00:21:42.000
and it's because we don't have an
00:21:44.039
infinite stack in Ruby but that would
00:21:46.480
have been way faster if that would have
00:21:48.159
worked and probably would have worked
00:21:49.960
for a small number of P programs
00:21:53.120
but uh this was kind of an unexpected
00:21:56.000
thing for me uh once I they started
00:21:59.080
transpiling into Ruby I started getting
00:22:00.679
all these ideas and like duh I've been
00:22:04.279
using Ruby for a couple decades I know
00:22:06.559
Ruby really well and uh I also got to
00:22:09.760
use profiler and I was
00:22:11.799
like really surprised that something I
00:22:14.200
thought was fast wasn't fast so this
00:22:17.480
this was an unexpected joy in
00:22:20.360
this okay so now when I did that now
00:22:23.679
it's 70 times faster there's other
00:22:26.400
things that I could have done but I
00:22:27.880
already spent way way too much time
00:22:30.960
doing this
00:22:33.279
so I'm gonna declare Victory right
00:22:37.799
here uh but I want to do uh a couple of
00:22:41.600
conclusions uh the first one is I think
00:22:44.480
it's really important to study different
00:22:46.760
languages so if you're someone who's
00:22:49.640
learning a language and you decide to
00:22:51.240
use a language that isn't very different
00:22:52.720
from yours you're not going to get a lot
00:22:55.080
of insights so I recommend like learning
00:22:59.080
a radically different language I'm not
00:23:01.039
saying you should learn pit although you
00:23:02.960
all know pit now but um you know learn
00:23:07.159
something like prologue prologue is a
00:23:09.240
declarative logic based language it was
00:23:11.880
pretty transformative to me in college
00:23:14.400
when I learned it because I thought
00:23:16.240
everything was going to be like Pascal
00:23:17.960
or
00:23:19.080
C Pascal might date me a little bit but
00:23:22.360
um but yeah get away from something
00:23:24.480
familiar and don't even don't even spend
00:23:27.480
a ton of time on it just spend a few
00:23:29.120
days on it just get some appreciation
00:23:30.880
that there's different ways of doing
00:23:32.400
things I think as time goes on all the
00:23:35.039
programming languages are starting to
00:23:36.200
look more and more
00:23:38.840
alike uh I think this is a pretty good
00:23:41.440
example that uh when you're an uncertain
00:23:44.799
ground you just need to translate what
00:23:46.679
you're doing into something
00:23:48.440
familiar once I
00:23:50.520
actually made the abstract syntax graph
00:23:53.640
then I'm like well naturally I can make
00:23:55.320
this into instructions and then once I
00:23:57.039
made it into instructions there's just
00:23:58.760
tons of things I could do but when I was
00:24:00.880
looking at that original interpreter I'm
00:24:03.240
like there was I had no ideas on how to
00:24:05.960
improve it if I would have made it nice
00:24:08.240
and clean it would have ran way slower
00:24:11.600
so Ruby and rails we have tons of tools
00:24:16.000
so this this
00:24:17.520
isn't as applicable but P had no tools
00:24:21.720
for me so I had to make
00:24:23.440
everything so graph fiz was the most
00:24:25.919
useful thing that control flow graph
00:24:28.159
that I showed I was constantly looking
00:24:30.480
at those seeing how my results had
00:24:32.360
changed and that was super useful had I
00:24:35.120
not had that tool I would have been
00:24:37.000
pretty lost the graphical debugger I
00:24:41.399
made it was a total waste of time but I
00:24:45.960
had a lot of fun writing it so you know
00:24:49.039
take what you can get right I had to
00:24:51.480
make an assembler for the IR so I could
00:24:53.360
actually test
00:24:54.880
it I made an asky image format so that I
00:24:57.880
could actually use a text editor to make
00:24:59.559
my my P programs because who wants to
00:25:02.640
use paint or you know some program like
00:25:06.679
that uh but there were many others and
00:25:10.399
the last and possibly uh best thing to
00:25:14.200
know is 8675309 is not just a phone
00:25:17.799
number it's also a prime
00:25:23.240
number so thank you
00:25:33.799
again looking for
00:25:35.559
work and uh I think I have like four
00:25:39.320
minutes for
00:25:42.279
questions if anyone wants to ask
00:25:44.399
questions I'll answer can p do anything
00:25:47.480
like change the colors of the of the
00:25:49.919
program now there are a bunch of people
00:25:52.760
who have extended p in weird ways
00:25:55.080
they've added more colors so they could
00:25:56.480
add more operations I I think someone
00:25:58.919
made like uh some TCP server
00:26:03.520
somehow
00:26:05.480
so I wouldn't be surprised if someone
00:26:07.760
made a self-modifying program so that
00:26:10.480
would be like the ultimate and lispy
00:26:13.039
right data is the code but I'm not aware
00:26:17.320
of that
00:26:19.799
specifically can QR codes be P programs
00:26:24.320
well it's not one of the six colors that
00:26:26.760
do anything so you could do something
00:26:30.360
with it but it would just instantly
00:26:32.360
terminate cuz if it's black and white
00:26:36.000
it'll make well let's just pretend that
00:26:38.600
the there's no border it would just move
00:26:41.320
around the white do the eight thing and
00:26:42.720
then eventually stop might run a very
00:26:44.960
long it might run
00:26:46.240
infinitely because oh no it's gonna it's
00:26:48.720
gonna
00:26:49.520
stop because white just slides through
00:26:51.640
and Black's gonna go nope it's going to
00:26:53.760
rotate yeah
00:26:57.240
yep man we could really go places with P
00:27:04.559
it there should be and another problem I
00:27:08.480
ran into with pet as an implementation
00:27:10.760
is there's
00:27:12.240
like 20 P programs on the planet and and
00:27:17.200
about eight of them don't do it
00:27:19.600
right there there was a rata and then
00:27:22.000
they updated the pet
00:27:23.960
speec for something where there's 20
00:27:26.120
programs on the planet and uh um so half
00:27:30.320
the programs don't
00:27:32.000
work and and if you use npit which is
00:27:35.679
the implementation I was talking about
00:27:37.279
earlier they actually have a flag to
00:27:39.399
specify I wanted to use 1.1 of pit so
00:27:43.279
yeah there's there's at least three
00:27:45.039
different versions of P
00:27:46.880
now okay well thank you thank you Tom