Mathematica core programming has not changed much during the years. So, if someone has an interest in learning how to effectively program in Mathematica, older books - even those dating back to version 2.2! - can be of use.
Personally, I believe one of the best books in this sense is
Thomas B. Bahder
Mathematica Programming for Scientists and Engineers
Addison Wesley, 1995
It is a 1995 book, aimed at version 2.2 (version 3 was still in the works).
Nonetheless this is one of the best references for mathematica core programming that I have read. Ever.
The only parts of the book that did not age well, obviously are those relating to graphics and import but that should not be a reason to shun this book. The following chapters
Ch1 The Building blocks
Ch2 Working with Lists
Ch4 Scoping Constructs
Could make their own book with the title: "Pure Mathematica in a nutshell".
The other chapters on Symbolic and Numerical computations (including those on matrices, ODEs and PDEs) exemplify the application of the basic core notion to actual computing. The part I like the most is the way Bahder uses pattern matching to shape function calls in order to make them very general.
This book really show the giant leap between procedural programming and functional/rule-based programming.
I am not sure this book is still in print; after having read it many (too many :-) ) years ago, I recently acquired a used copy from the Am[censored] marketplace for 15 bucks. It would be nice if this book could be made available as "Power Programming in MMA" was, because it deserves greater visibility.