When I was a teenager, I used to program in QBasic, assembler and C. I had tremendous fun: I was sitting at my computer yet creating universes.
In QBasic you would write a program, run it, and get to play with it immediately (I mostly wrote games). Because we only had a very old DOS computer without a graphics card and hard drive, the only other programming tool I had access to was a program called debug.com that allowed you to mess with the program memory, and enter your own assembly code (you had to do the assembling by yourself). It was oh so painful, but I learned how a CPU works. It also made me want to never translate assembly to binary ever again.
Once I could afford an old second-hand pentium 133 Mhz, I installed linux and started to learn C. I wanted to become a hacker, sp0k3 l1k3 th1s on IRC, and had tremendous fun learning about compilers and operating systems and memory layouts.
But in the early 2000s, a chance encounter on IRC changed my development career. A german programmer (hi forcer if you ever read this!) recommended I read this book called "Structure and Interpretation of Symbolic Programs", by Abelson, Sussman and Sussman. It is freely available online. It is a both a dry and formal book, and a very immediate book, because every code example is immediately executable. I dove right into it, and a few weeks later had built an obnoxious IRC bot to administer my channels. I later found some very clear lecture videos online, now available on MIT's youtube.
Things become really fun in the second chapter, where you build different mathematical algorithms. Who knew that a lot of differentiating and integrating was pretty much the manipulation of a fairly simple data structure! Coming from C, where even using an array is a painful and dangerous things, this concept of data structures and implementing them using functions was absolutely mind-shattering. Suddenly code was data and data was code.
By the third chapter, you implement stateful structures, a digital circuit simulator, infinite lazy streams, deal with concurrency at a symbolic level, all still just using Scheme, that minimalistic functional language. In the fourth chapter, the one that caused me the most problems at first, and completely shifted my brain, you implement a scheme interpreter in... scheme. And you then manipulate that interpreter in many interesting ways: probabilistic computations, logic programming, lazy evaluation. It shows you how easy these ideas are to actually implement, and how implementing them is the best way to learn how they work. This opened up an entire world to me. After this chapter, I was not intimidated by building my own languages, compilers, symbolic program manipulations, code generation. I knew there was a very elegant foundation that I could come back to.
In chapter five, you implement the culmination of all of this hard work: building a virtual machine, garbage collector, an efficient machine-optimized interpreter and finally a scheme compiler. In one book you went from what seems trivial functions to a full VM with compiler and garbage collector.
I am now not afraid to write functional code in the midst of a big mess of PHP. I am not afraid to introduce ideas from compiler theory, DSLs, interpreters, virtual machines into my day to day life, because I know how simple and elegant they can be expressed. It gives me the confidence to tackle daunting languages like Haskell, more experimental languages like Elm, or esoteric topics like formal theorem proving. It sheds light on the inner workings of many modern frameworks, not least React, which borrows a lot from functional programming and the concepts explored in this book.
None of this would have happened if I hadn't worked through SICP.
It really opened my eyes to the beauty of programming, and how effective understanding the elegant fundamentals can be.
Back in the days before the internet turned to the big ball of craziness it is nowadays, it was fairly easy (well, just as easy as you could get) to get started with Scheme. You would install guile, and emacs, and get rocking.
So what are you waiting for! Fire up your editor, go to SICP JS and change your life!
Do you have any books that changed your career? Do you think functionally, but write imperatively? How long did it take you to understand the meta-circulator evaluator? Do you think you could implement a garbage collector in just a few functions?