
Practicing Elixir or any programming language - ericdouglas
https://ericdouglas.github.io/2017/08/24/practicing-the-elixir-language/
======
Touche
I always find it interesting how people learn so differently. Personally, I
learn a language by building something in it. I want a _feel_ for it, before
digging deep and learning about theory. I only do that stuff _much_ later,
after I'm relatively proficient in the language.

This is probably why I wasn't very good at picking up musical instruments. I
was never satisfied learning at a slow pace and only being able to play
"twinkle twinkle little star". Programming is perfect for me because you can
build things before you really know what you are doing.

~~~
pdgonzalez872
Spoken languages are like that too. A 3 year old doesn't know what verbs are.
They just speak.

Another interesting thing is how people forget their path to personal journey
regarding learning. "I did `y`, but you should do `x` because now that I look
back I should have done `x`." "But, but, you did `y`! "Yes, but `x` is the way
to go."

You mentioned musical instruments: great topic. The very best musicians have
always been around music, sometimes not even being able to read music. There
is no clear path, the only clear thing about this is the time + effort
regarding learning something well: just have to put in the time.

~~~
lillesvin
> Spoken languages are like that too. A 3 year old doesn't know what verbs
> are. They just speak.

Not sure how you meant this to be understood, but a 3 year old definitely
knows that there are different word classes that behave differently. They
don't know that they're called verbs, nouns, adjectives, etc. but they do
correctly (to a large enough extent) use grammar applying specifically to the
different word classes.

------
gfodor
personally i think algorithm or hacker rank-like problems are probably a poor
way to actually pick up a new language.

pass one for me is usually "read all the books that are needed to cover the
main parts of the language, toolchain, frameworks, idioms, etc and make sure
to type in the code as you go." for elixir this means all the pragprog books
and probably one book on OTP/beam.

second pass is once that surface level knowledge has been exposed and digested
immediately start trying to solve real problems with the thing, using said
books and code written above, in addition to language docs, as a primary
reference, the internet (stack overflow, etc) as a secondary reference only
when absolutely necessary.

if you don't have the first part of dedicated learning and wide exposure
(without a motivating problem per se) you inevitably end up doing the lazily
evaluated "stack overflow driven development" since you haven't been exposed
to the breadth of the language, frameworks, etc systematically. in other
words, you don't know what you don't know. the first part also sets you up to
have some working examples you built yourself (with the help of books and
documentation) as handy references that you are comfortable with since you've
been in that code.

if you don't have the second part of solving a real problem you never actually
form the skills that come from applying the tool to a real problem with no
hand holding.

i think academic algorithmic problems are kind of the worst of both worlds.
they don't really give you a systematic way of being exposed to the APIs and
language quickly, and they also aren't real motivating problems so you end up
probably only really learning a narrow scope of things that are practically
useful for building stuff.

~~~
ericdouglas
> "if you don't have the first part of dedicated learning and wide exposure
> (without a motivating problem per se) you inevitably end up doing the lazily
> evaluated "stack overflow driven development" since you haven't been exposed
> to the breadth of the language, frameworks, etc systematically. in other
> words, you don't know what you don't know."

Totally agree. I'm doing exactly this. But instead of only read books and type
the code, I'm also after each section of the resource (doc || book),
practicing code challenges :)

------
jmcgough
I actually really enjoy doing katas on
[https://www.codewars.com/](https://www.codewars.com/), especially when I'm
ramping up on a language.

You solve a short problem, and then immediately see how other people solved
it. I'll frequently write something and then see a solution that uses a
library function I wasn't aware of, or a solution that's similar but better
follows the language conventions.

It's really helpful to solve something short and get immediate feedback on it.
You aren't learning how to write big programs with the language, but it's
still useful at first.

~~~
digitalzombie
I do that with Exercism and Elixir. It's pretty awesome.

~~~
jmcgough
been meaning to try exercism for a while, thanks for the reminder

------
sbuttgereit
I learn programming languages today the way I learned my first one. I have
(what is now an ancient) copy of the old DEC book, "101 BASIC Computer Games"
and I port some of those games to the new language. Sometimes I add bells and
whistles and it's not porting attempting to be true to the original; but they
offer small enough problems to get at least the syntax under my fingers and
some of the larger ones can start to give me a sense of how I'll need to think
should I try something serious.

And the first language I learned was... well BASIC... but it was on the VIC-20
& later C-64; but that still required a translation as the PDP-11 BASIC was
rather different that was was on the Commodore machines.

------
onkarshedge
I would like to mention [http://exercism.io](http://exercism.io) . It has unit
tests written also

~~~
rmetzler
Yes, I've used exercism to broaden my knowledge and I've recommended the site
to friends and colleagues who wanted to learn programming.

You mentioned tests: on exercism you don't write unit tests by yourself, the
tests are only for you to check your solution. It certainly helps to see how
tests can be written in any language, but you aren't forced into a strict TDD
style.

The best feature on exercism for me is to be able to see the other solutions
and learn from them.

~~~
ericdouglas
In HR you can see other solutions as well

------
minikomi
For Clojure I'd recommend ...
[http://www.4clojure.com/](http://www.4clojure.com/)

Follow some of the top-code-golfers, get all the tests passing, and then
marvel at how concise other people were able to make their solutions. Fun and
educational.

Edit: bonus, got nerdsniped.. Clojure solution -
[https://gist.github.com/minikomi/4e42de3643118b5381c4d7e70a1...](https://gist.github.com/minikomi/4e42de3643118b5381c4d7e70a179095)

------
midgetjones
Great article, thanks!

I'm not an expert Alchemist by any means, but whenever I see a `cond`, I try
to see if it can be refactored out using pattern matching (after I was picked
up on the same thing during an interview!)

    
    
       defp formatted_hour("AM", "12"),  do: "00"
       defp formatted_hour("AM", hours), do: hours
       defp formatted_hour("PM", "12"),  do: "12"
       defp formatted_hour("PM", hours), do: 12 + String.to_integer(hours)

~~~
hokiewv
I agree though one thing I would caution is it is good practice to always
return the same type from a function even though it is an untyped language.
The whole thing can be boiled down even more if pattern matching is used in
parsing the initial string.

    
    
      def convert(<<h::bytes-size(2)>> <> ":" <>
                  <<m::bytes-size(2)>> <> ":" <>
                  <<s::bytes-size(2)>> <> <<period::bytes-size(2)>>) do
       "#{formatted_hour(h,period)}:#{m}:#{s}"
      end
    
      defp formatted_hour(hours,"PM"), do: "#{String.to_integer(hours) + 12}"
      defp formatted_hour("12","AM"), do: "00"
      defp formatted_hour(hours, "AM"), do: hours

~~~
midgetjones
Good point! If you're going to pattern match in the initial string then who
even needs the second function?

    
    
        def convert("12:" <> <<m::bytes-size(2)>> <> ":" <> <<s::bytes-size(2)>> <> "AM") do
          "00:#{m}:#{s}"
        end
    
        def convert(<<h::bytes-size(2)>> <> ":" <> <<m::bytes-size(2)>> <> ":" <> <<s::bytes-size(2)>> <> "PM") do
          h = 12 + String.to_integer(h)
          "#{h}:#{m}:#{s}"
        end
    
        def convert(<<h::bytes-size(2)>> <> ":" <> <<m::bytes-size(2)>> <> ":" <> <<s::bytes-size(2)>> <> "AM") do
          "#{h}:#{m}:#{s}"
        end
    
    

Whether that's an improvement or not is another matter :)

~~~
ericdouglas
Crazy stuff! :D

I'm wondering how our future-self would feel about such cleverness haha

------
PaulRobinson
I am a fan of [http://www.rubykoans.com](http://www.rubykoans.com) for Ruby. I
am thinking about developing something similar using the Go playground for
that language, and maybe an alternative for Rust.

Where I'd want to stretch it is some data structure and algorithm exercises,
maybe even some design patterns. I'd love to be able to have a common
environment where I can start to learn any one of multiple languages using
similar exercises.

~~~
robohoe
I would love something like that for Go. Just recently completed Python Koans
and it was a good way to get into TDD.

------
keithnz
for me, when I'm learning some new language or tech I start off with whatever
basic info / tutorials that are available, play around with a few mini
projects (like algorithms), but the most important thing, LET OTHER PEOPLE SEE
YOUR CODE, for me that often involved trying to answer questions on
stackoverflow and posting on codereview, for instance when I was learning
ramda I posted a simple solution for fizzbuzz -
[https://codereview.stackexchange.com/questions/108449/fizzbu...](https://codereview.stackexchange.com/questions/108449/fizzbuzz-
in-javascript-using-ramda) for review and followed up on other peoples
variations and it helped a lot.

when I thought I was too rusty on regex I went and tried to answer as many
regex questions on stackoverflow

The great thing about stackoverflow is it presents real world problems that
are often not straightforward. Even if you can't solve it, someone else more
than likely will and you will have an "aha!"

------
lifeisstillgood
So his approach is to go through hackerrank exercises to learn the language.

Anyone familiar with hackerrank able to comment on that vs say project Euler?

~~~
mattferderer
I would say that Hacker Rank helps with learning syntax of a language. I'm not
sure if it helps greatly with learning how to implement framework type ideas
or large programs.

Hacker Rank is best at teaching algorithms & problem solving. I did a couple
the other day & at first I thought they looked difficult. After breaking them
down & thinking about them, they surprisingly weren't all that hard.

~~~
lifeisstillgood
The very definition of software :-)

------
TurboHaskal
I don't practice nor learn languages. I prefer concepts. I get "the book",
skip the very first chapters that only talk about syntax, go straight for the
unique features that make the language interesting (for a Clojure book, I'd go
straight to protocols, agents, etc.), wrap my head around them and then maybe
skim a popular repo hoping to read some idiomatic code.

------
paultopia
Semi-OT, but I really want to steal whatever slick CSS you used to get that
full page load then slam-in sidebar.

~~~
spyhi
Here is a link to the actual CSS used on the blog post.
[https://github.com/ericdouglas/ericdouglas.github.io/blob/ma...](https://github.com/ericdouglas/ericdouglas.github.io/blob/master/css/main.css)

I'm gonna try pointing to the relevant CSS, but be warned, I am not a CSS
wizard. I am also probably not a smart man, posting about CSS on HN while not
being a wizard.

The relevant classes seem to be .sidebar, .sidebar-toggle, .motion-element,
and .posts-expand, the last of which seems to control the transforms and
durations. This is where my knowledge breaks down, since I'm not sure how they
.sidebar or .motion-element trigger .posts-expand or any of the other
animation CSS. Hopefully someone can help fill in the rest! ¯\\_(ツ)_/¯

------
oldandtired
How hard is it to design your page without javascript needing to be enabled?

I now can't be bothered to see what you have to say. It is not worth my while.

~~~
rkangel
That 'reveal' is definitely overkill - in a world where shaving off 10s of
milliseconds in load time helps engagement, adding 100s of milliseconds of
unnecessary pause before content does seem a little silly.

That said, 'has javascript' is a reasonable assumption for most websites these
days. Most people outside the HackerNews echo chamber wouldn't dream of
turning it off, but then I suppose this blog _is_ aimed at the HackerNews
audience (among others).

~~~
ericdouglas
Thanks for your comment. I'll fix this.

------
smegel
> Why algorithms?

> Because this kind of problem is an interesting way to put yourself searching
> all the API of the language in order to solve the challenge in the more
> elegant/concise way you currently can.

Bullcrap. APIs are either going to be irrelevant for solving an algorithm, or
will simply do the job for you. "Implementing an algorithm" usually means
writing it from scratch using simple data structures, primitives and basic
flow control constructs.

~~~
ericdouglas
I agree with you.

But I believe that solving this kind of challenges forces one in a good way to
know more about what the language has to offer, while keeping motivated to
learn its constructs before being able to create real apps.

The goal is practicing a new language.

~~~
paultopia
I'm using the [cryptopals
challenges]([https://cryptopals.com/](https://cryptopals.com/)) to learn java
ATM, seems like a good approach because they pretty quickly force you to do
stuff that expose important parts of the language ("how do I get bytes out of
a string?" "how do I do i/o?" "how do I xor two strings?" "how do I find a
crypto library and use it?")

I think this kind of thing is more useful than hackerrank or euler-style
problems, at least if you're learning a language in a paradigm you already
know? If you can hack together a binary search in one functional language you
can probably do it in another one pretty easily. Though might be more
challenging moving from one paradigm to another.

