Readit News logoReadit News
sgk284 · 7 years ago
Liam, this is incredible!

I thought it might be useful for you to incrementally see how someone in industry would review or change this code, so here's a little code review via video: https://youtu.be/UkVOrcS--04

We very incrementally build up to the final code, which can be found here: https://gist.github.com/stevekrenzel/b490564bf1c7f98e232a6c8...

Hope you find it helpful!

liamilan · 7 years ago
Thanks Steve!

I watched your video and although I don't understand everything, I learned a lot. Separating my program into functions is a good idea. Your video clarified the map function for me.

Through your video, I understood that I was running code multiple times, when it only needs to run once (how I parsed my rules was one of these instances that you went over in your video), so thanks for pointing that out.

Again, thank you so much for taking the time to review my code. I really enjoyed your feedback.

giancarlostoro · 7 years ago
> Again, thank you so much for taking the time to review my code. I really enjoyed your feedback.

Whatever you do, hold on to that. Never be mad about feedback just try your best to understand it, and if it's wrong explain yourself without getting frustrated, this is worth more than a dozen senior developers who explode at feedback (I would argue they're junior developers :) and you will have a wonderful career. Also look for good mentors, and don't be afraid to ask questions about direct feedback, if you didn't understand something he said just ask (this becomes an immediate learning opportunity and you will be better off for it), even if he doesn't get to answer, someone else might. This is a field where learning is endless, you will always learn something new as a software developer, new platforms are made all the time to be programmed on / with.

Having soft skills[0] will be the biggest asset you can have as a software developer, whether you do it for money or just for fun, if you have to collaborate in the open you will need to communicate with others. Nothing breaks a team like terrible communication and someone who rejects feedback out of pride.

[0]: https://en.wikipedia.org/wiki/Soft_skills

sgk284 · 7 years ago
So glad to hear, Liam! Was a pleasure to put it together.

Good luck, and feel free to reach out if you get stuck on anything.

nkoren · 7 years ago
This whole interaction is really reaffirming my faith in humanity. You guys are awesome!

Liam -- this response is just as impressive as the code that you wrote. You're obviously very smart, but that isn't good enough on its own. I've seen very-smart people who aren't open to critique, who get defensive rather than take the opportunity to learn new things. They don't get very far in life. On the other hand, the attitude you're showing here is tremendously valuable, and will serve you incredibly well throughout life. Never let yourself grow out of it!

hashbig · 7 years ago
If you would start a channel where you review code of random public repos I would definitely subscribe. Well done.
Jach · 7 years ago
Drive-by code reviews (and maybe other types of annotated "audits", like for security bugs) would be a nice feature source repo sites might consider adding one day. It seems like a missing practice in open source development, code reviews (if any) are done by active developers once on check-in/merge acceptance. But as we see here code reviews can be a useful way to pay it forward too, not just new code / issue fixes, and done out-of-band there's no pressure to bow to the reviewer just to get something in; you can just have conversations and learn things.

The video format is a nice twist, in my distributed teams sometimes we've done "code review meetings" for some changes that are rather involved to capture some of the benefits of in-person / video code reviews.

sgk284 · 7 years ago
Thanks for the kind words! Will definitely consider.
unit91 · 7 years ago
Seconded. Do it. :-)
windlessstorm · 7 years ago
Let us know here if you are planning to do it :)
irmis · 7 years ago
Just registered to +1 this
priv7 · 7 years ago
+1 Please and thank you
fernandopj · 7 years ago
+1 count me in
magicduck · 7 years ago
+1
kenmendin · 7 years ago
+1
cardimart · 7 years ago
+1
ghoshbishakh · 7 years ago
+1
lynxaegon · 7 years ago
+1
dylandavidson · 7 years ago
+1, reminds me of Destroy All Software
SmallDeadGuy · 7 years ago
Instead of this:

    (rule & (1 << i)) === 0 ? 0 : 1
You could just do:

    (rule >> i) & 1
Otherwise it was a good review! I'd probably also extract parts of this long line so it's not as cumbersome to read:

    return state.map((item, i) =>
        rules[((state[i - 1] || 0) * 4) + (item * 2) + (state[i + 1] || 0)]
    );
to

    return state.map((item, i) => {
        const prevItem = state[i - 1] || 0;
        const nextItem = state[i + 1] || 0;
        return rules[(prevItem << 2) | (item << 1) | nextItem];
    });
It also uses bitwise operations instead of arithmetic, even though they are equivalent in this context, simply because we are effectively operating on arrays of bits.

sgk284 · 7 years ago
Thanks for the edits! I can't change the video, but did mention that both of those lines are a little clunky. I did update the gist though! Much cleaner.
DonHopkins · 7 years ago
I like to break expressions across multiple lines, and line up any patterns that are repeated, so your eye can easily scan up and down and obviously see what's the same, and what's different.

For example, instead of:

    var length = Math.sqrt((x * x) + (y * y));
You can go:

    var length = Math.sqrt((x * x) +
                           (y * y));
That way you can see the similarity of squaring x, and squaring y. But breaking up the multiplications because they repeat the x's and y's would be taking it too far -- it always requires balance and thinking about how can I communicate my intent and the SHAPE of the problem I'm solving.

You can also use indentation and formatting to bring out and make obvious other two-dimensional patterns and regularities, especially with two-dimensional cellular automata and graphics code.

There are some examples of that technique in my 2D cellular automata machine code. (There's a lot of code, so don't be overwhelmed, since I've been working on that since around 1985 or so. So never give up and just stick to it! You don't need to understand the code, which is pretty esoteric, just notice the patterns.)

https://github.com/SimHacker/CAM6/blob/master/javascript/CAM...

                        // Load the right two columns of the 3x3 window.
                        n  = cells[cellIndex - nextCol - nextRow];  ne = cells[cellIndex - nextRow];
                        c  = cells[cellIndex - nextCol          ];  e  = cells[cellIndex          ];
                        s  = cells[cellIndex - nextCol + nextRow];  se = cells[cellIndex + nextRow];
[...]

                            // Scroll the 3x3 window to the right, scrolling the middle and right
                            // columns to the left, then scooping up three new cells from the right
                            // leading edge.
                            nw = n;  n = ne;  ne = cells[cellIndex + nextCol - nextRow];
                            w  = c;  c =  e;  e  = cells[cellIndex + nextCol          ];
                            sw = s;  s = se;  se = cells[cellIndex + nextCol + nextRow];
[...]

                            var sum8 =
                                    (nw & 1) + (n & 1) + (ne & 1) +
                                    (w  & 1) +           (e  & 1) +
                                    (sw & 1) + (s & 1) + (se & 1);
[...]

                                var tableIndex =
                                    (((c         >> plane) & 0x03) <<  0) |
                                    (((e         >> plane) & 0x03) <<  2) |
                                    (((w         >> plane) & 0x03) <<  4) |
                                    (((s         >> plane) & 0x03) <<  6) |
                                    (((n         >> plane) & 0x03) <<  8) |
                                    (((cellX             ) & 0x01) << 10) |
                                    (((cellY             ) & 0x01) << 11) |
                                    (((phaseTime         ) & 0x01) << 12) |
                                    (((plane     >> 1    ) & 0x03) << 13);
[...]

When the sub-expressions won't fit on one line, you can still use indentation to help the reader understand the spatial patterns:

                            error +=
                                (nw * kernelBytes[4 - kernelDown - kernelRight]) +
                                    (n  * kernelBytes[4 - kernelDown]) +
                                        (ne * kernelBytes[4 - kernelDown + kernelRight]) +
                                (w  * kernelBytes[4 - kernelRight]) +
                                    (c  * kernelBytes[4]) +
                                        (e  * kernelBytes[4 + kernelRight]) +
                                (sw * kernelBytes[4 + kernelDown - kernelRight]) +
                                    (s  * kernelBytes[4 + kernelDown]) +
                                        (se * kernelBytes[4 + kernelDown + kernelRight]) +
                                frob;
But that would probably be more readable if I used intermediate variables for the kernelBytes[...] expressions, gave them descriptive names matching their corresponding directions, and lined up all their calculations so you could see the similarities and differences, because right now all the kernleBytes[4 +/- kernelDown +/- kernelRight] expressions are jumbled around horizontally, when they could be lined up nicely by themselves if they weren't interleaved with the n/s/e/w/ne/nw/sw/se multiplications. (I'll leave that improvement as an exercise for the reader. ;)

The point is you want to vertically line up as many of the repeated letters and symbols in nice neat columns as possible, so that your eye can easily see which are the same, and the ones that aren't stand out obviously so you can ignore all the same things and focus on the differences. (Which are typically variations like +/-, sin/cos, x/y/z, -1/0/1, nw/n/ne/w/c/e/sw/s/se, and longer series of names and numbers. Whatever changes should stick out visually, and be lined up and grouped together so your eyes can scan over them!)

That not only helps other people understand your code, but it also helps you be sure that you wrote the right thing, what you actually meant, instead of making an easy to miss typo.

The difficulty of reading you own code, which is HARD even for professional programmers, is that you usually see what you MEANT to write, not what you actually wrote. That's why it's so important to get other people to read your code, and to read other people's code, like pair programming and code reviews, or even explaining it to a duck.

https://en.wikipedia.org/wiki/Rubber_duck_debugging

It takes a lot more effort and concentration to slow down and look at what's actually there, instead of what you want to be there. (That's true for many aspects of life...)

navinsylvester · 7 years ago
Nice of you Steve.

Liam - whatever Steve suggested are very good pointers but please remember you are getting accolades here because you cared to publish your code. Don't hesitate to publish your initial version without any hesitation in future also.

krat0sprakhar · 7 years ago
Kudos for taking the time for doing this! It's places like these where the HN community really shines.

Thanks a lot!

sgk284 · 7 years ago
Thanks! I really enjoyed making it. HN has been such a huge part of my life over that last ~10 years that it's truly the least I could do.
ronilan · 7 years ago
Steve, it is outstandingly awesome that you did this and also how you did this! Thanks.
sgk284 · 7 years ago
Thank you, much appreciated!
kyberias · 7 years ago
Incredible code review!

I wish this inspires clever people to produce huge amounts of parody-videos "refactoring" the same piece of code. :)

earthscienceman · 7 years ago
I'm a long time coder and still liked watching your video just for watching someone else work in emacs. How do you get emacs to highlight all occurrences of map? Was it a keybinding for "highlight-phrase"?
sgk284 · 7 years ago
Thanks, glad you enjoyed it! And like another person already responded, this is vim with a split pane where the right pane is a `:terminal` (a relatively new feature of vim... though prior to that I would have just used tmux).

Highlighting searches is enabled with `:set hlsearch`, and you can search for whatever word is under the cursor with ``. So I just type and it highlights all of the matching words. Nothing too magical!

jstimpfle · 7 years ago
This is vim.
LifeQuestioner · 7 years ago
I'm subscribing to you, just incase you do more video's on code reviews.
sramam · 7 years ago
Congratulations!

I showed your project to my 12 year old son who has just started to learn programming (in JS no less!) and his jaw dropped.

In addition to being a programmer, you are now a role-model. Really well done.

liamilan · 7 years ago
Thanks a ton!

Tell your son that it took me a while, and a lot of work, but it feels great to finish something (there are a lot of projects that I don't finish...).

I began learning using Scratch a long time ago. They even featured me last year (the project was a solar system in which I used sine and cosine to calculate the rotation of the planets). I then used blocklike.js to move to JS.

I watch a lot of YouTube videos. I like The Coding Train, Carykh, and Code Bullet, and I get a lot of my ideas from their projects.

samstave · 7 years ago
Startup Idea: Start a slack/discord group for aspiring students between the ages of [pick your age range, say (8-18)] and start a mentoring/support group with these like-minds...

You'll learn, build relationships and some of you will go off and found companies together.

FactolSarin · 7 years ago
> there are a lot of projects that I don't finish...

You and me both. :)

sramam · 7 years ago
sine and cosine last year? Now I want to know what your parents are feeding you!!! ;)
rothron · 7 years ago
I've got a 10 year old who's been making a lot of stuff in Scratch since he was 6. I've been trying to think of how to phase him over to less limited languages and wasn't aware of blocklike.js, so thank you for that idea.

Having a lot of projects that you don't finish is completely normal, so don't worry about that.

flavio81 · 7 years ago
>I showed your project to my 12 year old son who has just started to learn programming (in JS no less!)

It would be much better if he would start with Scratch, Processing, Smalltalk, or even Python.

On JS he'll have to lose time coping with complicated build tools, horrible package system, async etc.

skeeterbug · 7 years ago
Is this serious? I started programming around 9 or 10 on a Commodore 64. I would go to the local library to get programming books for it. Now you can hit F12 in your browser and get a powerful console into JS. JS is fine, encourage the thirst for knowledge.
Jgoure · 7 years ago
This kid is practicing calculus at 12 years old. He will be able to handle a package manager.
sramam · 7 years ago
Isn't Liam's project proof that you don't need any complicated JS tooling?

A simple `node index.js` can go really far.

rymate1234 · 7 years ago
You need none of those things to get started with JS development

It’s still perfectly possible to just create a html document, shove in a script tag, and start developing

And if you want to use packages from the npm ecosystem you can easily use https://unpkg.com/

krapp · 7 years ago
The only thing you need to learn programming with JS is a text editor and some rudimentary HTML knowledge.

Everything else is unnecessary, at least as far as the programming language itself is concerned.

jacobolus · 7 years ago
Great work! I made a quick Observable notebook out of your code, in case anyone wants to see what it does without downloading or running it on their own machine:

https://beta.observablehq.com/@jrus/wolfram-cellular-automat...

crooked-v · 7 years ago
Dang, that's a neat tool. It's different enough from a Node environment, though, including some of the necessary rewrites of stuff, that I wonder if a "more Node-y" sandbox would be more useful for this particular case. An example: https://codesandbox.io/s/r0kwk0o28p (I tweaked the rule number, column width, and output to print to the page, but otherwise it's the same as the original.)
extremelearning · 7 years ago
Hi Jacob, I never got to thank you for doing the observableHQ notebook for my quasirandom sequencing. For your information, I have linked to it on many occasions which includes in my post "Unreasonable Effectiveness of Quasirandom Sequences" which is on front page of HN right now! :) https://news.ycombinator.com
scottmf · 7 years ago
Hey looks good :)! Just a few things you might not know about:

Google String.prototype.padEnd. It’s built in to JS and should be able to replace your zero fill function.

And instead of mutating the ruleSet array you should be able to use Array.prototype.map like this:

const ruleSet = zeroFill(8, rules.toString(2)) .split('') .reverse() .map(item => parseInt(item, 10));

And you can clone arrays like this, instead of using loops:

const oldArr = [...arr];

Also arrays are still mutable even if you assign them to const variables.

I’d offer more help but I’m on mobile. Sorry for the poor formatting. Hope this helps anyway. Good luck!

noobermin · 7 years ago
I think it is good he's learning to do the loops by hand first. It's good to have an understanding of algorithms first when learning to code.
sb8244 · 7 years ago
I second this. Knowing why something is better to use is most likely learned through doing it a worse way first.
taneq · 7 years ago
In fact this "you should never code FizzBuzz yourself, just use util.FizzBuzz(n) to print the first n iterations" mentality probably contributes to the surprising number of software developers who can't code.
crooked-v · 7 years ago
Though, keep in mind that some of this stuff (most notably the [...arr] syntax) won't work in old browsers if you make a web project (IE 11 is a big offender here). See https://caniuse.com/ for a useful source of info on what will work with what for stuff like that.

If you do web stuff (and you don't want to just say "no IE 11" - some people, and even some big companies, do that!), usually the easiest way to handle stuff like that is to use the newest syntax you're comfortable with, plus a tool like Babel that will produce a "time travel" version with older syntax that will work in all browsers.

throwaway2016a · 7 years ago
This project explicitly says Node. But in any case, these days I generally recommend using Babel to transpile the newer JS to browser friendly JS as the productivity and readability improvements in newer versions of JS are worth the effort to me to set up the babel build step.
erikpukinskis · 7 years ago
Good tips if you want your code to fail randomly on older devices.
Varcht · 7 years ago
Older devices running node?
coldtea · 7 years ago
Not even businesses doesn't (and shouldn't) care for older devices when it doesn't make economic sense -- even less so a fun learning project.
scottmf · 7 years ago
The code would fail to run on older devices without transpiling wnyway.
ninjakeyboard · 7 years ago
Good for you young jedi. I started coding around that age as well. I made the mistake of not going through comp-sci but have still been able to work for Google, publish books, lead teams and companies and products. You'll do just fine.

You have the ability to write some code! If you want to get a jumpstart, you should take the princeton algorithms course (for free!): https://www.coursera.org/learn/algorithms-part1

Or read the textbook by sedgewick that accompanies the course. https://algs4.cs.princeton.edu/home/

There is very little math in there - it may take some elbow grease and mentorship to help to convey some of the ideas - but I believe that you could implement and solve most everything in there. That was my path - I had a teacher at the age of 14 who would explain to me how different algorithms worked and I would go and implement them. Drawing a circle (in memory - it was in C!) or sorting a list (we did bubblesort first IIRC!)

I think you could do it! I believe in you! The course material is approachable - much more so than basically every other algorithms/data-structures material I've found. it may take you some time but you'll be soooo far ahead with your thinking about code.

If you ever start working with Object oriented languages like Java, another book that may help you when you've gone down the road a bit is the Head First Design Patterns book. http://shop.oreilly.com/product/9780596007126.do It's very easy to read, mostly pictures. It is made to be very easy to read (all of the books in that series are so look around at them.)

It's helpful to do both - code and also take in some material, but at 12 I imagine some of the material may be a bit daunting. You're doing really well - keep it up.

deepaksurti · 7 years ago
Liam, brilliant!

I am not saying you don't do this, but please please ensure you always sleep well, follow a good diet and go out and play.

Sometimes, computers make us give up good habits!

Kudos for your great work and keep learning, keep shipping!

shamdasani · 7 years ago
Woah - very cool! I'm a part of Hack Club (https://hackclub.com), which is a nonprofit worldwide network of high school coding clubs. Hack Club has an amazing community of young developers - I actually lead a Hack Club at my high school, and I definitely recommend that you join their slack (https://hackclub.com/slack_invite) to connect with other young makers!

By the way, I'm a 17 year-old developer (https://shamdasani.org), but I probably started ~14. My main project is Enlight (https://enlight.nyc) to teach others to code by building projects. If you'd like to contribute, that would be awesome - feel free to shoot me an email :)

zachlatta · 7 years ago
Hey Samay! To all in the thread, I started Hack Club and am happy to answer any questions about the org.

Liam, this is super cool. I also got started young and wish I had the skills to frontpage at 12 :-). Keep it up!

Would love to have you say hi in the Hack Club Slack. I'm @zrl.

fireattack · 7 years ago
rjplatte · 7 years ago
That's awesome. What resources did you use to learn Node and JS? Just looked at your code. Kid. You're a badass. Keep this up, you'll go places.
liamilan · 7 years ago
Thank you! I'm watching a lot of Youtube videos. This is how I got to cellular automata. My dad showed me git last week.
richardlblair · 7 years ago
> My dad showed me git last week.

Anyone else miss learning this quickly?

In all seriousness, congrats. Keep at it. There is always something else to learn. It's the career that never stops giving.

hobs · 7 years ago
That's pretty quick!

Do you have any plans for future projects? Maybe a simple place where you could chart your progress?

I think one of my favorite uses of cellular automata besides conway's game of life (if you are interested in it) is modeling simple fluid mechanics (water flowing from place to place) in games like dwarf fortress http://www.bay12games.com/dwarves/

rjplatte · 7 years ago
That's so freaking cool. Git rocks, and I remember how psyched I was when I learned about it. What's your next project?
lwansbrough · 7 years ago
> My dad showed me git

Cheater! :) Seriously though, great work. I started around your age (which I guess means I've been coding for half my life at this point.) Keep challenging yourself with new and interesting projects and you're going to learn a lot and have a lot of fun.