Related
I have started experimenting with Clojure, and I am impressed by what it can do. However, I don't think I have really 'got' functional programming design. My background is in Smalltalk, and that colours how I think about design. I would like to really understand how FP differs from OO, and one approach would be to have a good side-by-side comparison of a solution.
I don't think the problem needs to be that complex. Maybe it is would be enough to show how FP would implement the typical bank account problem?
Does anyone know of a suitable resource?
I think that most books on Clojure will have something like a simple bank account program, which I view as a little database in which states get updated. For example, Halloway and Bedra's Programming Clojure has a program that keeps track of music recordings. When you read through a description of that program, you'll immediately see how to map it into an OO solution. However, I don't think you're going to "get" FP from such a simple example. Programming Clojure also has functional snake game. You could compare that to an OO snake game. (I'm not promoting Programming Clojure; it's a worthwhile book but I think it has a number of flaws. It just happens to be the Clojure book that I know best. A lot of people seem to like it, though.)
I'd suggest another strategy, maybe as a supplement to yours, for grokking FP: Read something introductory that immerses you in an FP worldview. My favorite is Friedman and Felleisen's The Little Schemer. It uses Scheme, not Clojure, but the ideas translate. There is a Clojure website devoted to it, but I recommend working through the original book in the way that it recommends, covering parts of the page as you go. I think the book that gave me an understanding of parts of FP that go beyond The Little Schemer, extending to much of what you find in the Clojure world, was Bird's Introduction to Functional Programming using Haskell. I feel funny suggesting a Haskell book, though. Why not a Clojure book? Well, maybe one of the Clojure books will have the same effect of giving you a pure baptism in the FP Way of Thinking, but the Clojure books I've read (P.C, The Joy of Clojure), though very good books, are somehow less immersive--maybe because they're more practical. On the other hand, P.C (and probably some other Clojure books) is (are) largely targeted toward OO programmers, so that might actually be what you want.
A few random observations on Clojure from a Smalltalker's perspective.
The Clojure data structures will remind you of Smalltalk's collection classes, but immutability/persistence takes a bit of getting used to.
You already use do and its relatives to abbreviate control structure. You'll find that the sequence library (map, reduce, and the rest), with laziness offer you another level of power and concision.
You're already used to writing your code in little pieces. The pieces will get smaller and there will be more of them.
But
Clojure is less pure than Smalltalk: not everything is an object.
Nothing like the wonderful Smalltalk browser is standard.
If you like Smalltalk, you'll love Clojure.
I want to use Clojure's Core.logic. However, I want to also understand how it works. Is there a concise explanation of it somewhere? (Like implementing a metacircular evaluator?)
Thanks!
core.logic is an implementation of miniKanren - originally written and designed in Scheme by Dan Friedman, William Byrd, Oleg Kiselyov and others. It is an attempt to embed Prolog-style relational programming within Lisp.
If you want to understand how it works you'll need to read the first three chapters of William Byrd's dissertation: https://scholarworks.iu.edu/dspace/bitstream/handle/2022/8777/Byrd_indiana_0093A_10344.pdf?sequence=1
The Reasoned Schemer also covers the unifier in detail. However the much more subtle goal portion of miniKanren isn't given a comprehensive treatment - you'll need to look at Byrd's dissertation for that.
Even then, as with meta-circular interpreters - many insights cannot be gained without trying to implement the system yourself in a variety of programming languages.
You can also see David's talk on core.logic from the Strange Loop 2012.
And for very light introduction to the topic see also: sokuza-kanren
I've been doing C++ for 3-4 months in a local college and I'm doing extra reading / learning using Accelerated C++ and so far, I've "finished" it. Now, I'm wondering which book to get next that'll help me code better in C++.
I've looked around and found this: The Definitive C++ Book Guide and List
I'm sorry if this question may seem stupid for most of you here but I'm a bit tight in cash and I would really want to invest in something that's "right" for me at this time.
Right now, I only know the basics of stuff like (classes, templates, STL, iterators, dynamic memory management).
Do you have any suggestions? Should I focus on STL or templates..? Or should I read something like The C++ Programming language?
If you haven't yet read Stroustrup's books, they are definitely a good read. There's nothing quite like reading about the language from the person who designed it.
Whenever I learn a new language, I always try to find the canonical reference material written by the language designer or somebody very close to them.
In addition to reading Stroustrup's books (suggested by another answer here), I'd suggest his two FAQs as a great starting point:
Bjarne Stroustrup's FAQ
C++ Style and Technique FAQ
They both link to further reading material.
These two, along with the C++ FAQ Lite, are required reading for new programmers at my workplace.
Once you're even a bit more comfortable, consider jumping in to the community: subscribe to something like the boost mailinglists, watch the blogs of big name figures like Herb Sutter, read Alexandrescu's Guru of the Week articles. You may feel like you're in over your head (I still do often after many years of reading the lists) but you'll learn a ton, especially watching the language grow and evolve. (And this stuff is free!)
You can get more understanding from watching how a language changes over time, and how people actually use it, than you can from a million hours of memorizing the standard. (Not that shelling out a few bucks to have a copy of the ISO/IEC standard around is a bad idea, mind -- great for reference from time to time.)
As for books:
after the Stroustrup books,
start with the Meyers ("Effective") books.
I'd also recommend C++ Coding Standards -- a great amount of work went into gathering the "common sense" of the users of the language in this book.
Then if you want to blow your mind you can look at Modern C++ Design or some of the fun template metaprogramming resources...
Above all, just stay connected and interested. Mailinglists, blogs, websites, academic papers, magazines, whatever -- choose what suits you best, don't expect to follow everything all the time, but keep your ears and eyes open; find aspects that interest you and follow them!
The C++ Programming Language would give you the best overview of the language. It sounds like you have that but the section on object oriented programming is worthwhile. I'd probably spend more time learning about object oriented programming at this point than more specific C++ features.
A book like "Code Complete" might be a good choice for you.
I feel like you can probably make more progress learning to program by tackling real programming problems, rather than reading another book.
I certainly don't discount the value of books as a programming resource but I do think there is no better way to learn a programming language than writing real code. Given your financial constraints, you have the additional motivation that writing code is free.
Concentrating on a particular part of the language or a pattern for programming might be interesting, but a specific problem to solve will give you context that, in my opinion, is a more powerful learning mechanism.
Of course, you can't write code in a vacuum. You have already read Accelerated C++ which will probably give you more than enough to get started writing code, but there are also a whole pile of resources on the net that will help (StackOverflow is a great place to start).
Tutorials for Win32
Online C resources
VC6 Tutorial
These are my favorite:
Effective C++ - Scott Meyers
C++ Standard Library Tutorial and Reference - Nicolai Josuttis
I might suggest a library card, or hanging out and reading Border's, to make sure the books are helpful for you.
a Good book for templates - C++ Templates by David Vandevoorde, Nicolai M. Josuttis
Learn STL more and more, there is a
lot more to learn.
learn Boost. This would change how
you think about programming in C++.
If you want to go very deep, read Stroustrup's papers. Select a paper now and then, print it, read it carefully. Stroustrup is an excellent writer. reading his papers would make you a superior C++ programmer for sure.
My favorite list is :
A History of C++: 1979-1991, A
History of C++: 1979-1991. After
I read those papers I loved C++.
What is Object-Oriented
Programming?
Why C++ isn't just an
Object-Oriented Programming
Language.
Sixteen Ways to Stack a Cat.
This is a jewel that everyone ought
to read :)
If you don't want to spend money, you should learn multi-threaded programming. The basics are already in the books you have, and described in API documentation. Try to actively create a program with many threads that communicate back and forth, and then multiply the number of threads to see if you've made a good design.
You'll want to read up on Semaphores, Mutexes, and Critical Sections.
I take three approaches to multi-threaded programming:
Use a PostMessage style communication between threads
Pass thread-safe objects between threads through which data is stored and relayed
Initialize a thread on start-up, let it run on its own, and then retrieve the data at the end of the run
If you're ready to spend money, I would recommend Design Patterns as a good next-read. It's more generic, and you'll find some of the ideas make sense.
I think you started out with just the right book! For those who didn't know, this book starts with STL at the beginning and leaves pointers for the end. Most programmers learn C first, and consequently have a forever distorted view of what C++ can be.
It might be really interesting for you to now read 'The C Programming Lanugage' by Kernigan & Richie at this point. This is probably a necessity if you want to understand the mindset behind most C/C++ code in the world today.
But more important than your next programming book is to find a medium-sized program you really want to write, and go after it. Use all kinds of reference materials for the project. Incorporate a boost library or two in your program.
If you are tight on cash, read How to Think Like a Computer Scientist. Also read the FAQ lite.
I have been learning C++ for three months now and in that time created a number of applications for my company. I consider myself fairly comfortable with C++ / MFC and STL, however I don't just want to be an OK programmer, I want to be a good programmer. I have a few books on best practices but I was wondering if anyone could suggest reading materials that helped them and any disciplines which should be encouraged?
Thanks!
I would start with the Pragmatic Programmer, Code Complete, Refactoring and Design Patterns.
For C++, Scott Meyers books are very good, and will help take you to the next level.
If you don't already have it C++ by Bjarne Stroustrup, 3rd Edition
Uhm... Teach Yourself Programming in Ten Years (Peter Norvig)
3 months into c++ and you're already comfortable with it? Sheesh, I've been learning c# for over a year and have taken numerous Microsoft courses and I'm nowhere near comfortable with it.
That being said, you'll hear Code Complete tossed about as a very good book. I'm in the process of reading it now.
Marshall Cline's C++ FAQ Lite.
Herb Sutter's Exceptional C++.
Large Scale C++ Software Design by John Lakos gives guidance on design methods that will make your C++ more maintainable. It is pretty hefty but you can dip in and still get some benefits.
Somewhat off-topic: rather than suggesting books to learn, I'd like to mention some broad topics to consider.
Threading. This one is not much in demand if you use MFC, but in many other areas it's indispensable. The mechanics of threading APIs are easy to pick up, but learning all the corner cases takes a lot of time and practice.
Closures, Map-Reduce and other lisp-like techniques. Find out what they are, why they are not supported in C++, and how they are imitated in C++ (functors, and many other cases of stateful callback objects). For this I actually have a book: "Structure and Interpretation of Computer Programs".
Command Line. This gives you an idea on when not to code your own programs. Command line would be Unix command line - I don't know about MS's latest experimentation in this are, but cmd.exe is awful. Get Cygwin and start experimenting.
Scripting languages. This gives you an idea on when not program in C++. My favorite is Perl, but many people say Python, Ruby and whatnot. Hey, learn XSLT if you're so inclined!
I am sure I left out other areas. I'll mark this as Community Wiki - feel free to add.
Good blogs:
Guru of the Week, and all the books by Herb Sutter. Those will give you quite a lot to chew already.
Modern C++ Design by Alexandrescu if you want to get a good feel for what you don't yet know, and probably don't want to know.
Code Kata's for practice!
I have read several (not complete but some parts) of oreilly books on VB.net they are quite good, but if you want to be pro and have the time...
You can try out MSDN forums, help other people and discuss with them hard and complex problems, I think it's the best way..
learn another language. even if you won't use it, it's great for mind-opening.
I'd advice Lua, Scheme and Python. but almost anything else would do. (the most different from C, the best)
Josuttis and Vandevoorde - Templates: The Complete Guide
As I see, nobody mentioned Bruce Eckel brilliant books "Thinking in C++". IMHO, it`s one of the best books to start your C++ development from. From my point of view, first volume is more helpful that the second, but both of them worth reading.
http://www.amazon.com/Thinking-C-Introduction-Standard-One/dp/0139798099/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1227890306&sr=8-1
I lot of folks can suggest more modern, up-to-date books. But I still recommend The Annotated C++ Reference Manual by Margaret A. Ellis & Bjarne Stroustrup.
The ARM was published back in '90. It's become somewhat outdated with respect to templates. STL is (obviously) absent. (Though the website at sgi.com does a good job of covering STL!)
However, the ARM is dirt cheap (used). (Shipping will exceed the cost of the book.) Its signal-to-noise ratio remains off the scale. It's very good at digging into C++'s dirty areas, explaining what was done & why.
I still use it as a reference. I rank it up there with K&R.
Dietel/Dietel "How to program C++"... I still have this book on my desk (10 years in).. Every once and a while I re-read a chapter. I'd definatly get the Code Complete, as other have suggested. Infact read that first.
To get a better understanding of object orientation, spend some time in a Smalltalk. Squeak is a free download. Then read Richard P. Gabriel's Patterns of Software and thereafter his Objects have Failed.
Thinking in C++ - Bruce Eckel
Symfonia C++ Standard - Jerzy Grębosz
If you do nothing else, program.
When you are not doing that read about programming and when something strikes you as interesting, go implement something with that knowledge. I've found that this is the only way to really set the principals.
Staying up to date on blogs can be fun, but it is scattered knowledge. It seems to distract more than help. But combined with google and a desire to research something specific can really cough up tons of information. But dont' just subscribe to alot of rss feeds and expect to get better.
I think really studying specific topics helps expand your ability. Research topics that intrigue you, meet people doing things like you (conferences, user groups, irc, facebook, stackoverflow, etc) and above all practice your art.
You can check out the Boost library and a number of the books written about it. While this may not have been what you had in mind, IMO, the Boost libraries are examples of well-designed modern C++ libraries that use the features of the language in pretty much the way they should be used to create among the most effective solutions for their problem domain. Granted of course, there are bizarre libraries like preprocessor and MPL which make you wonder if you'll ever have any use for them, but they're all round quite good. From my own experience, exploring the library and its literature has given me insight into how C++ can be used effectively.
Boost
Beyond the C++ Standard Library: An Introduction to Boost
I find myself attached to a project to integerate an interpreter into an existing application. The language to be interpreted is a derivative of Lisp, with application-specific builtins. Individual 'programs' will be run batch-style in the application.
I'm surprised that over the years I've written a couple of compilers, and several data-language translators/parsers, but I've never actually written an interpreter before. The prototype is pretty far along, implemented as a syntax tree walker, in C++. I can probably influence the architecture beyond the prototype, but not the implementation language (C++). So, constraints:
implementation will be in C++
parsing will probably be handled with a yacc/bison grammar (it is now)
suggestions of full VM/Interpreter ecologies like NekoVM and LLVM are probably not practical for this project. Self-contained is better, even if this sounds like NIH.
What I'm really looking for is reading material on the fundamentals of implementing interpreters. I did some browsing of SO, and another site known as Lambda the Ultimate, though they are more oriented toward programming language theory.
Some of the tidbits I've gathered so far:
Lisp in Small Pieces, by Christian Queinnec. The person recommending it said it "goes from the trivial interpreter to more advanced techniques and finishes presenting bytecode and 'Scheme to C' compilers."
NekoVM. As I've mentioned above, I doubt that we'd be allowed to incorporate an entire VM framework to support this project.
Structure and Interpretation of Computer Programs. Originally I suggested that this might be overkill, but having worked through a healthy chunk, I agree with #JBF. Very informative, and mind-expanding.
On Lisp by Paul Graham. I've read this, and while it is an informative introduction to Lisp principles, is not enough to jump-start constructing an interpreter.
Parrot Implementation. This seems like a fun read. Not sure it will provide me with the fundamentals.
Scheme from Scratch. Peter Michaux is attacking various implementations of Scheme, from a quick-and-dirty Scheme interpreter written in C (for use as a bootstrap in later projects) to compiled Scheme code. Very interesting so far.
Language Implementation Patterns: Create Your Own Domain-Specific and General Programming Languages, recommended in the comment thread for Books On Creating Interpreted Languages. The book contains two chapters devoted to the practice of building interpreters, so I'm adding it to my reading queue.
New (and yet Old, i.e. 1979): Writing Interactive Compilers and Interpreters by P. J. Brown. This is long out of print, but is interesting in providing an outline of the various tasks associated with the implementation of a Basic interpreter. I've seen mixed reviews for this one but as it is cheap (I have it on order used for around $3.50) I'll give it a spin.
So how about it? Is there a good book that takes the neophyte by the hand and shows how to build an interpreter in C/C++ for a Lisp-like language? Do you have a preference for syntax-tree walkers or bytecode interpreters?
To answer #JBF:
the current prototype is an interpreter, and it makes sense to me as we're accepting a path to an arbitrary code file and executing it in our application environment. The builtins are used to affect our in-memory data representation.
it should not be hideously slow. The current tree walker seems acceptable.
The language is based on Lisp, but is not Lisp, so no standards compliance required.
As mentioned above, it's unlikely that we'll be allowed to add a full external VM/interpreter project to solve this problem.
To the other posters, I'll be checking out your citations as well. Thanks, all!
Short answer:
The fundamental reading list for a lisp interpreter is SICP. I would not at all call it overkill, if you feel you are overqualified for the first parts of the book jump to chapter 4 and start interpreting away (although I feel this would be a loss since chapters 1-3 really are that good!).
Add LISP in Small Pieces (LISP from now on), chapters 1-3. Especially chapter 3 if you need to implement any non-trivial control forms.
See this post by Jens Axel Søgaard on a minimal self-hosting Scheme: http://www.scheme.dk/blog/2006/12/self-evaluating-evaluator.html .
A slightly longer answer:
It is hard to give advice without knowing what you require from your interpreter.
does it really really need to be an interpreter, or do you actually need to be able to execute lisp code?
does it need to be fast?
does it need standards compliance? Common Lisp? R5RS? R6RS? Any SFRIs you need?
If you need anything more fancy than a simple syntax tree walker I would strongly recommend embedding a fast scheme subsystem. Gambit scheme comes to mind: http://dynamo.iro.umontreal.ca/~gambit/wiki/index.php/Main_Page .
If that is not an option chapter 5 in SICP and chapters 5-- in LISP target compilation for faster execution.
For faster interpretation I would take a look at the most recent JavaScript interpreters/compilers. There seem to be a lot of thought going into fast JavaScript execution, and you can probably learn from them. V8 cites two important papers: http://code.google.com/apis/v8/design.html and squirrelfish cites a couple: http://webkit.org/blog/189/announcing-squirrelfish/ .
There is also the canonical scheme papers: http://library.readscheme.org/page1.html for the RABBIT compiler.
If I engage in a bit of premature speculation, memory management might be the tough nut to crack. Nils M Holm has published a book "Scheme 9 from empty space" http://www.t3x.org/s9fes/ which includes a simple stop-the-world mark and sweep garbage collector. Source included.
John Rose (of newer JVM fame) has written a paper on integrating Scheme to C: http://library.readscheme.org/servlets/cite.ss?pattern=AcmDL-Ros-92 .
Yes on SICP.
I've done this task several times and here's what I'd do if I were you:
Design your memory model first. You'll want a GC system of some kind. It's WAAAAY easier to do this first than to bolt it on later.
Design your data structures. In my implementations, I've had a basic cons box with a number of base types: atom, string, number, list, bool, primitive-function.
Design your VM and be sure to keep the API clean. My last implementation had this as a top-level API (forgive the formatting - SO is pooching my preview)
ConsBoxFactory &GetConsBoxFactory() { return mConsFactory; }
AtomFactory &GetAtomFactory() { return mAtomFactory; }
Environment &GetEnvironment() { return mEnvironment; }
t_ConsBox *Read(iostream &stm);
t_ConsBox *Eval(t_ConsBox *box);
void Print(basic_ostream<char> &stm, t_ConsBox *box);
void RunProgram(char *program);
void RunProgram(iostream &stm);
RunProgram isn't needed - it's implemented in terms of Read, Eval, and Print. REPL is a common pattern for interpreters, especially LISP.
A ConsBoxFactory is available to make new cons boxes and to operate on them. An AtomFactory is used so that equivalent symbolic atoms map to exactly one object. An Environment is used to maintain the binding of symbols to cons boxes.
Most of your work should go into these three steps. Then you will find that your client code and support code starts to look very much like LISP too:
t_ConsBox *ConsBoxFactory::Cadr(t_ConsBox *list)
{
return Car(Cdr(list));
}
You can write the parser in yacc/lex, but why bother? Lisp is an incredibly simple grammar and scanner/recursive-descent parser pair for it is about two hours of work. The worst part is writing predicates to identify the tokens (ie, IsString, IsNumber, IsQuotedExpr, etc) and then writing routines to convert the tokens into cons boxes.
Make it easy to write glue into and out of C code and make it easy to debug issues when things go wrong.
The Kamin Interpreters from Samuel Kamin's book Programming Languages, An Interpreter-Based Approach, translated to C++ by Timothy Budd. I'm not sure how useful the bare source code will be, as it was meant to go with the book, but it's a fine book that covers the basics of implementing Lisp in a lower-level language, including garbage collection, etc. (That's not the focus of the book, which is programming languages in general, but it is covered.)
Lisp in Small Pieces goes into more depth, but that's both good and bad for your case. There's a lot of material on compiling and such that won't be relevant to you, and its simpler interpreters are in Scheme, not C++.
SICP is good, definitely. Not overkill, but of course writing interpreters is only a small fraction of the book.
The JScheme suggestion is a good one, too (and it incorporates some code by me), but won't help you with things like GC.
I might flesh this out with more suggestions later.
Edit: A few people have said they learned from my awklisp. This is admittedly kind of a weird suggestion, but it's very small, readable, actually usable, and unlike other tiny-yet-readable toy Lisps it implements its own garbage collector and data representation instead of relying on an underlying high-level implementation language to provide them.
Check out JScheme from Peter Norvig. I found this amazingly simple to understand and port to C++. Uh, dunno about using scheme as a scripting language though - teaching it to jnrs is cumbersome and feels dated (helloooo 1980's).
I would like to extend my recommendation for Programming Languages: Application and Interpretation. If you want to write an interpreter, that book takes you there in a very short path. If you read through writing the code you read and doing the exercise you end up with a bunch of similar interpreters but different (one is eager, the other is lazy, one is dynamic, the other has some typing, one has dynamic scope, the other has lexical scope, etc).