
Ask HN: How do you learn by doing? - lignux
Basically the title. I know the best way to learn some new programming language is by making something i am interested in, but every time i try this approach i feel my code is &quot;hacked&quot; together for example: I need something, i google how to do that something in X language, read the code and try to understand it and then just copy it.<p>After a while i feel like i have learned nothing or just so little that i lose interest.<p>Am i doing this wrong? What is your approach for learning something new?
======
ChicagoBoy11
I would invert your process. The idea that the best way to learn is by doing
is correct; however, if you just decide on "I want to make my own Facebook"
when your level of knowledge is at "Hello World," you are going to have a bad
time.

As a learner/worker/human being, the ideal place to be is what is called a
state of "flow", where the challenges you have in front of you are neither too
trivial but also not too insurmountable. You want something to challenge you
but also not something that will leave you completely lost.

So, my advice is to just flip your process. Take whatever you are learning --
be it through a book, a tutorial you are following, etc. -- and then once you
feel confident you've learned some discrete new chunk of skill, try making
something on your own that leverages it. But just something that you feel
could be accomplished with roughly the skillset which you now believe you
have. The best projects follow the mold of "I'm pretty sure I could do [x]
now, but I'm not sure."

For instance, if you are learning some framework like Angular, a bad place to
start would be "I want to make a real-time chat app". But as you are working
through a tutorial, once you learn how to just literally put a stateless
component on the screen, you might get to a stage where you feel comfortable
just putting another one on the screen that does something slightly
differently. Sweet, you got that down. Then, later on, you'll be introduced to
managing routes; so if the tutorial you are following is a simple app that
shows phones and details of the phones, make one that can show books and a
collection of reviews of the books and maybe a link to where you could buy it
on Amazon. And on and on and on...

In this way, you are always checking for understanding by doing and can figure
out where your knowledge is poor, but never dabbling into things that you have
no proper mental scaffolding for which just turns into copying and pasting
code you don't understand.

~~~
sitkack
Came to say the same thing.

Flow [1]

Proper task breakdown, constant self reflection on what you know and what you
don't know. This is _harder_ at the beginning that it is after you have some
context.

Design the smallest possible experiment to understand a concept, even simpler
than that. The goal is understanding, not the complexity of the task. These
can take from 5 minute to 4 hours or longer.

Integration and unit tests are excellent (or an analog in the non-computer
domain you are trying to master). You need to prove to yourself that the
knowledge is correct.

Seek peers and exposure to new ideas, techniques, context. You need to be
continually building context, otherwise you won't know how to process or
anchor new information.

Also take a look at some books on learning theory by Piaget [2] [3], Papert
[4]

[1]
[https://en.wikipedia.org/wiki/Flow_(psychology)](https://en.wikipedia.org/wiki/Flow_\(psychology\))

[2] [http://viking.coe.uh.edu/~ichen/ebook/et-
it/cognitiv.htm](http://viking.coe.uh.edu/~ichen/ebook/et-it/cognitiv.htm)

[3]
[https://en.wikipedia.org/wiki/Constructivism_(philosophy_of_...](https://en.wikipedia.org/wiki/Constructivism_\(philosophy_of_education\))

[4] [https://tltl.stanford.edu/content/seymour-papert-s-legacy-
th...](https://tltl.stanford.edu/content/seymour-papert-s-legacy-thinking-
about-learning-and-learning-about-thinking)

------
bjourne
> read the code and try to understand it and then just copy it.

That's not learning by _doing_ that's learning by _copying_. :) I don't think
learning by copying works which is why your approach is flawed.

Next time try this instead. Google it, find some code, read it and try to
understand it like you do now. Then _don 't copy it_. Instead open it in a
text editor window and in another you rewrite the code. If you don't know how
to rewrite it, just do it character by character.

Now you might say "that's just a slower form of copy-paste!" but no, it is
not. After a few times trying this, you will see why it isn't. It is the
method I use and it works for me.

~~~
hfsktr
Even when I'm copying code I do it by hand[0]. Even though they might work I
treat most stack overflow examples as 'really good pseudo-code'.

[0] it's always something short.

------
ci5er
For myself, decades ago, my learn-as-you-go project was a distributed
rendering system. Here's what worked about it:

    
    
      - Ray-tracing (for example) is easy to reason about in an object oriented fashion (this was before functional was all the rage)
      - You're never done. There are always new lighting models, surface models (shaders), geometries, optimizers to add
      - Each module, pretty quickly, gives you visible results.
      - Because it's modular, there's lots of opportunity for incremental refactoring of modules and for re-implementation of modules in new languages
      - It could be part of a (much) larger ecosystem. Maybe you want to add water - oceans are fun. To add robot simulators, you need a physics engine. To which you can add ML to generate and optimize controllers to have the robot hit goals. etc. etc.
    

In this case, I had to learn numerical methods (for both rigid-body physics
and monte carlo), various rendering techniques, how to implement shading
languages, distributed algorithms, managing distributed clusters, FPGAs
(before GPUs were cheaply available), etc., etc.

I'm not suggesting a rendering test-bed specifically, but unbounded problems
that can be modularized where you always have a list of "next modules" is one
way to have an ever-green project you are always adding things too --
sometimes (but not necessarily) in new languages, using new development
paradigms. For me, agent-based computational economics, various physics-
related simulations (in general), machine-learning around robotics (control
systems) and that rendering test-bed were my "domains" of experimentation. For
you, it could well be just about anything else.

------
shakna
I don't make a project I'm interested in.

I make the same project every time I pick up a new language.

It lets me pick up the differences quickly, when all the logic basically stays
the same.

~~~
meekins
This! Porting a small application that you already know well to a new language
or stack is an excellent excercise. But IMO it's also useful to read some
introductionary texts and existing code on the target platform while doing
that to see if there's some useful idioms and practices you can benefit from -
especially if the languages follow the same paradigm. There's quite little use
in just writing the existing code in a new syntax.

------
brudgers
If it were natural language rather than a programming language, ability to
write something that works after a few hours study would be a significant
accomplishment. Non-trivial understanding of any programming language simply
takes time.

Anyway, most code is just hacked together because writing working code is
hard.

[http://norvig.com/21-days.html](http://norvig.com/21-days.html)

------
Johnny_Brahms
My son, a classical musician, got a lot better at maths by solving (and
understanding) the first 400 project euler problems over 2 years.

I just pointed him to the relevant passages in my old text books, and he more
or less did it himself. I helped him with one of the harder ones he had been
banging his head against, but that was more of a language problem than not
understanding.

I am pretty darn impressed.

~~~
andrei_says_
Why did he take that project on? What was his motivation?

It is my firm belief that intrinsic motivation (curiosity, interest and
enthusiasm) is the only truly sustainable approach.

Could you elaborate?

~~~
Johnny_Brahms
He was on trial in an orchestra 1.5h away and needed something to do. I had
just finished my last problem from the most recent batch and he got curious.
He's the only one in the family that isn't a maths person,not because he
wasn't but because his life brought him elsewhere. Now he had the time and was
bored out of his mind.

He had just started programming (scheme, as his old man:) ) and wanted
something to do.

~~~
andrei_says_
Sounds great. Another proof that stereotypes and sound bites are simply
prolefeed.

------
andrei_says_
I learned ruby by doing simple exercises. Basically tinkering and getting a
feel of how things work.

Think of learning as an interactive loop: you try something and see the
outcome. Like, if you're learning to throw a baseball, you try a million of
small adjustments until your body-mind gets a feel of the movement and the
associated outcome (read The Inner Game Of Tennis).

Similarly, when programming, your mind starts thinking and imagining in the
constructs it experienced and internalized. Getting a feel of these constructs
and patterns is the result of using them enough times to build things or solve
puzzles.

If you want to get a feel of ruby, I recommend going through the exercises
here:

[https://github.com/JoshCheek/ruby-
kickstart](https://github.com/JoshCheek/ruby-kickstart)

The videos are optional, just download the repo, set up ruby and rspec, open
your favorite text editor and you're set.

------
rkv
\- Look at "skeleton" or "boilerplate" projects on GitHub. Don't copy the
first one you find, make sure you review a handful and study how people are
using the language and eventually make your own. Bonus if the project is from
a contributor of the language.

\- Some languages and frameworks have a "best practices" guide.

\- RTFM!

\- Iterate. Your first attempt will always feel hacky. Revisit it after more
studying and practice.

------
itamarst
The problem is that creating a new project from scratch is _not_ the best way
to learn a new language.

Here's how I would do it:

1\. Skim an introductory book. This will give you an overview of language
features, syntax and libraries. And when you get stuck on something confusing
you'll have some vague memory of "oh, chapter 7 covered that feature, let me
look it up."

2\. Read some well-commented, good code in the language in a problem domain
your understand. E.g. if you're backend web developer find a web framework
which is similar to one you've used in a language you know.

3\. Modify some existing code in the language. This means you'll be able to
tell if the code runs, you'll have examples to work off of, a testing setup
you can hook in to, and so on.

4\. Write some new code in a highly structured way where there are pre-
existing examples for the task you're doing. E.g. use a high-level framework,
or write a middleware plugin.

5\. After all that you might be ready to make something completely from
scratch.

------
samayshamdasani
I completely understand where you are coming from. Often, I do the same.
However, I feel like copying the code by typing it after understanding what
every single line means is when you're actually learning. I built a site to
teach people to code this way ([https://enlight.ml](https://enlight.ml)). If
you want to learn by doing (it is one of the best ways to learn), you must
understand and be able to reproduce it before copying it down.

------
eb0la
Try disconnecting from the internet.

I learnt a lot of python because I disconnected the wifi and used offline
documentation.

Online documentation / sites like stackoverflow are great when you need
information with _very_ narrow scope. Great for getting the job done; but not
for learning / understanding / memory retention.

When you need to learn something you have to see the whole picture. For that
there is nothing better than books or offline documentation.

------
saluki
First off do you know the basics? HTML/CSS and Ruby or PHP are you creating
web apps in an existing framework or just getting started.

If you're just getting started it helps a lot to have a handle on html/css,
javascript, jQuery and ruby/PHP before diving in to a framework for web app
related stuff.

So if you need to take some time and learn HTML/CSS and some
javascript/jQuery.

I would learn languages in this order HTML/CSS, javascript, jQuery, PHP/MySQL,
then Rails or Laravel, then Vue,React, etc. if you're interested in web apps.

My first go at learning Rails was too early and I had a difficult time and
gave up.

After creating a web app from scratch, writing a basic login, CRUD and
learning the inner workings of a basic web application I gave rails another go
and it clicked and went smoothly.

The first time I didn't understand the basics of a web application and had a
difficult time knowing what rails was doing or what to do next.

So I think it depends on what level you are at.

As far as cutting and pasting, when you're learning cutting and pasting is
fine, even as an advanced programmer you're always going to be learning and
looking at what others have done as a starting point.

When you cut and paste you'll usually be modifying it to make it do what you
want. So take a little extra time and research what it's doing till you
understand it so you can use it again and understand what it does/can/can not
do.

Choose something you'll use not a straight copy paste tutorial. Choose
something with the basics of a web application, you can follow tutorials for
that but add in something unique that you'll have to create from scratch. This
is where the learning takes place.

So maybe an app you can login to and track your lego star wars collection, or
an app you and your friends can log in to and have your own private twitter or
social network. Maybe something that connects to an api of a service you use.
Sign up for Stripe and create something with a billing/subscription component.

Just build one part of it at a time. Set a goal, this evening or this weekend
I'm going to build this part and have it up and running.

Good luck, enjoy learning something new, Happy Holidays.

------
aisofteng
Stop copying code. That's lazy and ineffective. If that hasn't occurred to
you, perhaps evaluate your work ethic.

Would you learn math by copying and pasting from a solutions manual? Would you
learn to write fiction by copy pasting others' short stories?

You won't learn to write code without writing code.

------
demolish
tutorials never worked for me, far too boring

was much easier to just find existing codebases and tinker with some
functionality of them to learn, while asking those more experienced to clarify
anything i couldn't figure out with a bit of trial and error/looking up usage
of similar code elsewhere within the codebase

personally, i learned c++/lua (though im not by any means 'advanced' in them)
from an mmo server emulator since it was easy to see how gameplay was affected
and compare expected vs intended results

also im barely awake rn so this comment probably makes zero sense

------
PaulHoule
Learning by doing and reading books go together like peanut butter and jelly.

~~~
jstimpfle
As a german I couldn't tell whether that means they go together or not.

But of course there is a Wikipedia page:
[https://en.wikipedia.org/wiki/Peanut_butter_and_jelly_sandwi...](https://en.wikipedia.org/wiki/Peanut_butter_and_jelly_sandwich)

------
krivx
It doesn't sound like you are iterating on this. Look at the code you are not
happy with. What is wrong? Can you fix it? If so, try to do those things next
time. Don't stop the process.

------
adamnemecek
Read code for popular open source projects written in the language.

~~~
afarrell
Do you know of a good way to find projects for this and learn to navigate
their structure? I tried doing this when I was at MIT, but found that unless I
already had the problem it was trying to solve in my head (as in, "I've spent
a bunch of time trying to design an approach to this. Let's see how Flask does
it") It was hard to follow.

~~~
adamnemecek
I had the same issue for the longest time and the only advice I can give is to
keep trying. One thing that I noticed helped a lot is to pick a random popular
github project (popularity does correlate with code quality to some extent)
and try to make a simple change in 30 minutes (or some limited amount of
time). You might fail the first couple of times but keep trying.

