Structure and Interpretation of Computer Programs

Harold Abelson

Mentioned 9

Structure and Interpretation of Computer Programs has had a dramatic impact on computer science curricula over the past decade. This long-awaited revision contains changes throughout the text. There are new implementations of most of the major programming systems in the book, including the interpreters and compilers, and the authors have incorporated many small changes that reflect their experience teaching the course at MIT since the first edition was published. A new theme has been introduced that emphasizes the central role played by different approaches to dealing with time in computational models: objects with state, concurrent programming, functional programming and lazy evaluation, and nondeterministic programming. There are new example sections on higher-order procedures in graphics and on applications of stream processing in numerical programming, and many new exercises. In addition, all the programs have been reworked to run in any Scheme implementation that adheres to the IEEE standard.

More on Amazon.com

Mentioned in questions and answers.

It wasn't that long ago that I was a beginning coder, trying to find good books/tutorials on languages I wanted to learn. Even still, there are times I need to pick up a language relatively quickly for a new project I am working on. The point of this post is to document some of the best tutorials and books for these languages. I will start the list with the best I can find, but hope you guys out there can help with better suggestions/new languages. Here is what I found:

Since this is now wiki editable, I am giving control up to the community. If you have a suggestion, please put it in this section. I decided to also add a section for general be a better programmer books and online references as well. Once again, all recommendations are welcome.

General Programming

Online Tutorials
Foundations of Programming By Karl Seguin - From Codebetter, its C# based but the ideas ring true across the board, can't believe no-one's posted this yet actually.
How to Write Unmaintainable Code - An anti manual that teaches you how to write code in the most unmaintable way possible. It would be funny if a lot of these suggestions didn't ring so true.
The Programming Section of Wiki Books - suggested by Jim Robert as having a large amount of books/tutorials on multiple languages in various stages of completion
Just the Basics To get a feel for a language.

Books
Code Complete - This book goes without saying, it is truely brilliant in too many ways to mention.
The Pragmatic Programmer - The next best thing to working with a master coder, teaching you everything they know.
Mastering Regular Expressions - Regular Expressions are an essential tool in every programmer's toolbox. This book, recommended by Patrick Lozzi is a great way to learn what they are capable of.
Algorithms in C, C++, and Java - A great way to learn all the classic algorithms if you find Knuth's books a bit too in depth.

C

Online Tutorials
This tutorial seems to pretty consise and thourough, looked over the material and seems to be pretty good. Not sure how friendly it would be to new programmers though.
Books
K&R C - a classic for sure. It might be argued that all programmers should read it.
C Primer Plus - Suggested by Imran as being the ultimate C book for beginning programmers.
C: A Reference Manual - A great reference recommended by Patrick Lozzi.

C++

Online Tutorials
The tutorial on cplusplus.com seems to be the most complete. I found another tutorial here but it doesn't include topics like polymorphism, which I believe is essential. If you are coming from C, this tutorial might be the best for you.

Another useful tutorial, C++ Annotation. In Ubuntu family you can get the ebook on multiple format(pdf, txt, Postscript, and LaTex) by installing c++-annotation package from Synaptic(installed package can be found in /usr/share/doc/c++-annotation/.

Books
The C++ Programming Language - crucial for any C++ programmer.
C++ Primer Plus - Orginally added as a typo, but the amazon reviews are so good, I am going to keep it here until someone says it is a dud.
Effective C++ - Ways to improve your C++ programs.
More Effective C++ - Continuation of Effective C++.
Effective STL - Ways to improve your use of the STL.
Thinking in C++ - Great book, both volumes. Written by Bruce Eckel and Chuck Ellison.
Programming: Principles and Practice Using C++ - Stroustrup's introduction to C++.
Accelerated C++ - Andy Koenig and Barbara Moo - An excellent introduction to C++ that doesn't treat C++ as "C with extra bits bolted on", in fact you dive straight in and start using STL early on.

Forth

Books
FORTH, a text and reference. Mahlon G. Kelly and Nicholas Spies. ISBN 0-13-326349-5 / ISBN 0-13-326331-2. 1986 Prentice-Hall. Leo Brodie's books are good but this book is even better. For instance it covers defining words and the interpreter in depth.

Java

Online Tutorials
Sun's Java Tutorials - An official tutorial that seems thourough, but I am not a java expert. You guys know of any better ones?
Books
Head First Java - Recommended as a great introductory text by Patrick Lozzi.
Effective Java - Recommended by pek as a great intermediate text.
Core Java Volume 1 and Core Java Volume 2 - Suggested by FreeMemory as some of the best java references available.
Java Concurrency in Practice - Recommended by MDC as great resource for concurrent programming in Java.

The Java Programing Language

Python

Online Tutorials
Python.org - The online documentation for this language is pretty good. If you know of any better let me know.
Dive Into Python - Suggested by Nickola. Seems to be a python book online.

Perl

Online Tutorials
perldoc perl - This is how I personally got started with the language, and I don't think you will be able to beat it.
Books
Learning Perl - a great way to introduce yourself to the language.
Programming Perl - greatly referred to as the Perl Bible. Essential reference for any serious perl programmer.
Perl Cookbook - A great book that has solutions to many common problems.
Modern Perl Programming - newly released, contains the latest wisdom on modern techniques and tools, including Moose and DBIx::Class.

Ruby

Online Tutorials
Adam Mika suggested Why's (Poignant) Guide to Ruby but after taking a look at it, I don't know if it is for everyone. Found this site which seems to offer several tutorials for Ruby on Rails.
Books
Programming Ruby - suggested as a great reference for all things ruby.

Visual Basic

Online Tutorials
Found this site which seems to devote itself to visual basic tutorials. Not sure how good they are though.

PHP

Online Tutorials
The main PHP site - A simple tutorial that allows user comments for each page, which I really like. PHPFreaks Tutorials - Various tutorials of different difficulty lengths.
Quakenet/PHP tutorials - PHP tutorial that will guide you from ground up.

JavaScript

Online Tutorials
Found a decent tutorial here geared toward non-programmers. Found another more advanced one here. Nickolay suggested A reintroduction to javascript as a good read here.

Books
Head first JavaScript
JavaScript: The Good Parts (with a Google Tech Talk video by the author)

C#

Online Tutorials
C# Station Tutorial - Seems to be a decent tutorial that I dug up, but I am not a C# guy.
C# Language Specification - Suggested by tamberg. Not really a tutorial, but a great reference on all the elements of C#
Books
C# to the point - suggested by tamberg as a short text that explains the language in amazing depth

ocaml

Books
nlucaroni suggested the following:
OCaml for Scientists Introduction to ocaml
Using Understand and unraveling ocaml: practice to theory and vice versa
Developing Applications using Ocaml - O'Reilly
The Objective Caml System - Official Manua

Haskell

Online Tutorials
nlucaroni suggested the following:
Explore functional programming with Haskell
Books
Real World Haskell
Total Functional Programming

LISP/Scheme

Books
wfarr suggested the following:
The Little Schemer - Introduction to Scheme and functional programming in general
The Seasoned Schemer - Followup to Little Schemer.
Structure and Interpretation of Computer Programs - The definitive book on Lisp (also available online).
Practical Common Lisp - A good introduction to Lisp with several examples of practical use.
On Lisp - Advanced Topics in Lisp
How to Design Programs - An Introduction to Computing and Programming
Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp - an approach to high quality Lisp programming

What about you guys? Am I totally off on some of there? Did I leave out your favorite language? I will take the best comments and modify the question with the suggestions.

Java: SCJP for Java 6. I still use it as a reference.

Haskell:

O'Reilly Book:

  1. Real World Haskell, a great tutorial-oriented book on Haskell, available online and in print.

My favorite general, less academic online tutorials:

  1. The Haskell wikibook which contains all of the excellent Yet Another Haskell Tutorial. (This tutorial helps with specifics of setting up a Haskell distro and running example programs, for example.)
  2. Learn you a Haskell for Great Good, in the spirit of Why's Poignant Guide to Ruby but more to the point.
  3. Write yourself a Scheme in 48 hours. Get your hands dirty learning Haskell with a real project.

Books on Functional Programming with Haskell:

  1. Lambda calculus, combinators, more theoretical, but in a very down to earth manner: Davie's Introduction to Functional Programming Systems Using Haskell
  2. Laziness and program correctness, thinking functionally: Bird's Introduction to Functional Programming Using Haskell

Some books on Java I'd recommend:

For Beginners: Head First Java is an excellent introduction to the language. And I must also mention Head First Design Patterns which is a great resource for learners to grasp what can be quite challenging concepts. The easy-going fun style of these books are ideal for ppl new to programming.

A really thorough, comprehensive book on Java SE is Bruce Eckel's Thinking In Java v4. (At just under 1500 pages it's good for weight-training as well!) For those of us not on fat bank-bonuses there are older versions available for free download.

Of course, as many ppl have already mentioned, Josh Bloch's Effective Java v2 is an essential part of any Java developer's library.

Let's not forget Head First Java, which could be considered the essential first step in this language or maybe the step after the online tutorials by Sun. It's great for the purpose of grasping the language concisely, while adding a bit of fun, serving as a stepping stone for the more in-depth books already mentioned.

Sedgewick offers great series on Algorithms which are a must-have if you find Knuth's books to be too in-depth. Knuth aside, Sedgewick brings a solid approach to the field and he offers his books in C, C++ and Java. The C++ books could be used backwardly on C since he doesn't make a very large distinction between the two languages in his presentation.

Whenever I'm working on C, C:A Reference Manual, by Harbison and Steele, goes with me everywhere. It's concise and efficient while being extremely thorough making it priceless(to me anyways).

Languages aside, and if this thread is to become a go-to for references in which I think it's heading that way due to the number of solid contributions, please include Mastering Regular Expressions, for reasons I think most of us are aware of... some would also say that regex can be considered a language in its own right. Further, its usefulness in a wide array of languages makes it invaluable.

C: “Programming in C”, Stephen G. Kochan, Developer's Library.

Organized, clear, elaborate, beautiful.

C++

The first one is good for beginners and the second one requires more advanced level in C++.

I know this is a cross post from here... but, I think one of the best Java books is Java Concurrency in Practice by Brian Goetz. A rather advanced book - but, it will wear well on your concurrent code and Java development in general.

C#

C# to the Point by Hanspeter Mössenböck. On a mere 200 pages he explains C# in astonishing depth, focusing on underlying concepts and concise examples rather than hand waving and Visual Studio screenshots.

For additional information on specific language features, check the C# language specification ECMA-334.

Framework Design Guidelines, a book by Krzysztof Cwalina and Brad Abrams from Microsoft, provides further insight into the main design decisions behind the .NET library.

For Lisp and Scheme (hell, functional programming in general), there are few things that provide a more solid foundation than The Little Schemer and The Seasoned Schemer. Both provide a very simple and intuitive introduction to both Scheme and functional programming that proves far simpler for new students or hobbyists than any of the typical volumes that rub off like a nonfiction rendition of War & Peace.

Once they've moved beyond the Schemer series, SICP and On Lisp are both fantastic choices.

For C++ I am a big fan of C++ Common Knowledge: Essential Intermediate Programming, I like that it is organized into small sections (usually less than 5 pages per topic) So it is easy for me to grab it and read up on concepts that I need to review.

It is a must read for me the night before and on the plane to a job interview.

C Primer Plus, 5th Edition - The C book to get if you're learning C without any prior programming experience. It's a personal favorite of mine as I learned to program from this book. It has all the qualities a beginner friendly book should have:

  • Doesn't assume any prior exposure to programming
  • Enjoyable to read (without becoming annoying like For Dummies /
  • Doesn't oversimplify

For Javascript:

For PHP:

For OO design & programming, patterns:

For Refactoring:

For SQL/MySQL:

  • C - The C Programming Language - Obviously I had to reference K&R, one of the best programming books out there full stop.
  • C++ - Accelerated C++ - This clear, well written introduction to C++ goes straight to using the STL and gives nice, clear, practical examples. Lives up to its name.
  • C# - Pro C# 2008 and the .NET 3.5 Platform - Bit of a mouthful but wonderfully written and huge depth.
  • F# - Expert F# - Designed to take experienced programmers from zero to expert in F#. Very well written, one of the author's invented F# so you can't go far wrong!
  • Scheme - The Little Schemer - Really unique approach to teaching a programming language done really well.
  • Ruby - Programming Ruby - Affectionately known as the 'pick axe' book, this is THE defacto introduction to Ruby. Very well written, clear and detailed.

When implementing a needle search of a haystack in an object-oriented way, you essentially have three alternatives:

1. needle.find(haystack)

2. haystack.find(needle)

3. searcher.find(needle, haystack)

Which do you prefer, and why?

I know some people prefer the second alternative because it avoids introducing a third object. However, I can't help feeling that the third approach is more conceptually "correct", at least if your goal is to model "the real world".

In which cases do you think it is justified to introduce helper objects, such as the searcher in this example, and when should they be avoided?

To quote the great authors of SICP,

Programs must be written for people to read, and only incidentally for machines to execute

I prefer to have both methods 1 and 2 at hand. Using ruby as an example, it comes with .include? which is used like this

haystack.include? needle
=> returns true if the haystack includes the needle

Sometimes though, purely for readability reasons, I want to flip it round. Ruby doesn't come with an in? method, but it's a one-liner, so I often do this:

needle.in? haystack
=> exactly the same as above

If it's "more important" to emphasise the haystack, or the operation of searching, I prefer to write include?. Often though, neither the haystack or the search is really what you care about, just that the object is present - in this case I find in? better conveys the meaning of the program.

I've always been a largely independent learner gleaning what I can from Wikipedia and various books. However, I fear that I may have biased my self-education by inadvertent omission of topics and concepts. My goal is to teach myself the equivalent of an undergraduate degree in Computer Science from a top university (doesn't matter which one).

To that end, I've purchased and started reading a few academic textbooks:

As well as a few textbooks I have left over from classes I've taken at a mediocre-at-best state university:

My questions are:

  • What topics aren't covered by this collection?
  • Are there any books that are more rigorous or thorough (or even easier to read) than a book listed here?
  • Are there any books that are a waste of my time?
  • In what order should I read the books?
  • What does an MIT or Stanford (or UCB or CMU ...) undergrad learn that I might miss?

Software engineering books are welcome, but in the context of academic study only please. I'm aware of Code Complete and the Pragmatic Programmer, but I'm looking for a more theoretical approach. Thanks!

I think you can use most of the other books for reference and just absorb Programming Pearls in its entirety. Doing so would make you better than 90% of the programmers I've ever met.

The "Gang of Four" Design Patterns book. The Design Patterns course I took in college was probably the most beneficial class I've ever taken.

First, I wouldn't worry about it. But if you'd like a book to learn some of the abstract CS ideas, I'd recommend The Turing Omnibus or Theoretical Introduction to Programming.

If I were deciding between hiring two programmers and neither had much experience, but one had a CS degree and the other didn't, I'd hire the one with the CS degree. But when you get to comparing two programmers with a dozen years of experience, the degree hardly matters.

Even i'm in the same plane: studying computer science in my free time after work; These are some of the books i have in my shelf right now

  1. Applying UML and patterns - Larman
  2. Introduction to algorithms - Cormen
  3. Discrete mathematics and its applications - Rosen
  4. Software Engineering
  5. Advanced Programming in the UNIX Environment

Will udpate this list further as soon as i finish them... :-)

File Structures: An object oriented approach with C++

A lot of good info about block devices and file structuring which you won't find in any of the books you listed. It got a few critical reviews on Amazon because people didn't like his code examples, but the point of the book is to teach the concepts, not give cut and paste code examples.

Also make sure to get a book on compilers

Biggest two omissions I see:

For operating systems I prefer the Tanenbaum instead of the Silberschatz but both are good:

And about the order, that would depend on your interests. There aren't many prerequisites, automata for compilers is the most obvious one. First read the automata book and then the dragon one.

I don't know all the books you have, but the ones I know are good enough so that may mean the others are decent as well.

You are missing some logic and discrete math books as well.

And let's not forget some database theory books!

I just came across an idea in The Structure And Interpretation of Computer Programs:

Data is just dumb code, and code is just smart data

I fail to understand what it means. Can some one help me to understand it better?

This is one of the fundamental lessons of SICP and one of the most powerful ideas of computer science. It works like this:

What we think of as "code" doesn't actually have the power to do anything by itself. Code defines a program only within a context of interpretation -- outside of that context, it is just a stream of characters. (Really a stream of bits, which is really a stream of electrical impulses. But let's keep it simple.) The meaning of code is defined by the system within which you run it -- and this system just treats your code as data that tells it what you wanted to do. C source code is interpreted by a C compiler as data describing an object file you want it to create. An object file is treated by the loader as data describing some machine instructions you want to queue up for execution. Machine instructions are interpreted by the CPU as data defining the sequence of state transitions it should undergo.

Interpreted languages often contain mechanisms for treating data as code, which means you can pass code into a function in some form and then execute it -- or even generate code at run time:

#!/usr/bin/perl
# Note that the above line explicitly defines the interpretive context for the
# rest of this file.  Without the context of a Perl interpreter, this script
# doesn't do anything.
sub foo {
    my ($expression) = @_;
    # $expression is just a string that happens to be valid Perl

    print "$expression = " . eval("$expression") . "\n";
}

foo("1 + 1 + 2 + 3 + 5 + 8");              # sum of first six Fibonacci numbers
foo(join(' + ', map { $_ * $_ } (1..10))); # sum of first ten squares

Some languages like scheme have a concept of "first-class functions", which means that you can treat a function as data and pass it around without evaluating it until you really want to.

The upshot is that the division between "code" and "data" is pretty much arbitrary, a function of perspective only. The lower the level of abstraction, the "smarter" the code has to be: it has to contain more information about how it should be executed. On the other hand, the more information the interpreter supplies, the more dumb the code can be, until it starts to look like data with no smarts at all.

One of the most powerful ways to write code is as a simple description of what you need: Data which will be turned into code describing how to get you what you need by the interpretive context. We call this "declarative programming".

For a concrete example, consider HTML. HTML does not describe a Turing-complete programming language. It is merely structured data. Its structure contains some smarts that let it control the behavior of its interpretive context -- but not a lot of smarts. On the other hand, it contains more smarts than the paragraphs of text that appear on an average web page: Those are pretty dumb data.

I am now several months into learning F# with the greatest asset for learning F# being translating the OCaml code in "Handbook of Practical Logic and Automated Reasoning" (WorldCat) by John Harrison, into F#.

With this being such an effective method of learning, I plan to translate the code in more books to F#, but books primarily focused on functional concepts or real world applications typically known for being written with a functional language such as AI, compilers, Theorem Provers and Reasoning Assistants.

While one would think that translating a program from one language to another might be a trivial task, in reality when doing such one runs into differences not only in the language but the environment and tools that must also be learnt and understood to do the translation. One is required to explore the depths of both languages and their environments that are not typically considered when just reading about it. For example in translating Ocaml to F# I learned top-level, ocamldebug and time travel, trace and wishing F# had this, camlp4 and how it doesn't exist in F#, exception handling performance differences, and type inference in a manner that forced me to understand the F# counterparts in ways I would not have by just experimenting or reading books with F#.

Do you know of any other books that use/include source code, preferably functional, that cover concept(s) of functional programming or are real world applications typically written in a functional language and that will help in learning functional programming by translating the source code to F#?

To keep this objective and not subjective, the answers must explain why it is important, and you must have used the book not just browsed the book. I am looking for answers from people who have been doing functional programming for years and have found working through such a book a key to their success with functional programming. Examples of answers:

EDIT

While I would like to hold off and wait for a better answer to accept, I have learned that after a few days on SO the views tail off considerably.

I find that both answers are great for anyone not familiar with the books and that if I didn't already know and have copies of most of the books I would seriously consider getting them.

Since PAD noted the more advanced books which is what I was after, I give him the accept vote. If could split the accept I would.

Considering the titles listed in your question you are already far ahead of basics. But talking of fundamentals I'd suggest considering:

Richard Bird, Philip Wadler - Introduction to Functional Programming, 1st Ed ISBN:0134841891 (book's FP language is Miranda)

and all-times classic

Harold Abelson and Gerald Jay Sussman - Structure and Interpretation of Computer Programs, 2nd Ed ISBN:0262011530 (book's FP language is Scheme)

Integers can be used to store individual numbers, but not mathematical expressions. For example, lets say I have the expression:

6x^2 + 5x + 3

How would I store the polynomial? I could create my own object, but I don't see how I could represent the polynomial through member data. I do not want to create a function to evaluate a passed in argument because I do not only need to evaluate it, but also need to manipulate the expression.

Is a vector my only option or is there a more apt solution?

A simple yet inefficient way would be to store it as a list of coefficients. For example, the polynomial in the question would look like this:

[6, 5, 3]

If a term is missing, place a zero in its place. For instance, the polynomial 2x^3 - 4x + 7 would be represented like this:

[2, 0, -4, 7]

The degree of the polynomial is given by the length of the list minus one. This representation has one serious disadvantage: for sparse polynomials, the list will contain a lot of zeros.

A more reasonable representation of the term list of a sparse polynomial is as a list of the nonzero terms, where each term is a list containing the order of the term and the coefficient for that order; the degree of the polynomial is given by the order of the first term. For example, the polynomial x^100+2x^2+1 would be represented by this list:

[[100, 1], [2, 2], [0, 1]]

As an example of how useful this representation is, the book SICP builds a simple but very effective symbolic algebra system using the second representation for polynomials described above.

I've been reading Structure and Interpretation of Computer Programs. Lisp is teaching me to think in its way. As a java developer, I wish to learn clojure.

I know clojure is similar to lisp. So my question is, does learning Lisp help me learn clojure easily? Are there similar concepts in both languages?

Clojure share many similarities with other Lisps. SICP is a great book and although it focuses on Scheme a lot of what it teaches you will be directly relevant to Clojure.

If you lean one Lisp then it will be substantially easier to pick up another.

There are however a couple of things about Clojure that make it "different" that are worth noting:

  • It extends classic Lisp syntax with vectors [], hashmaps {} and sets #{} as well as the traditional lists ().
  • It is more of a functional programming language in style than most other Lisps - pretty much everything is immutable, sequences are lazy by default etc. In some ways Clojure feels quite strongly influenced by Haskell
  • Clojure embraces the Java platform in a big way - it runs on the JVM you can easily use Java libraries directly. As a result, although you don't strictly need to know Java to be effective in Clojure it helps to have an understanding of the Java ecosystem and tools.
  • The Clojure STM system / support for concurrency is very innovative and different. Worth watching this video: http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey

Here lately I've been tinkering around with my own languages as well as reading various writings on the subject.

Does anyone have any good advice on how, in C (or Assembler), do you program the concept of the Object Class and/or the concept of Generics into a language. (referring to the Java implementations of Object and Generics)

For instance, in Java all all classes extend Object. So how do you represent this at the C level? is it something like:

#include <stdio.h>

typedef struct {
  int stuff;
} Object;


typedef struct {
  int stuff;
  Object object;
} ChildClass;


int main() {
    ChildClass childClass;
    childClass.stuff = 100;
    childClass.object.stuff = 200;
    printf("%d\n", childClass.stuff);
    printf("%d\n", childClass.object.stuff);
}

And I'm not really even sure how to get started with implementing something like Generics. I also appreciate any valuable links regarding program langauge design. Thanks,

Take a look at Structure and Interpretation of Computer Programs by Abelson and Sussman. While it doesn't show how to do it in C, it does demonstrate how to create types at run time and how to build an object system on top of a language that doesn't provide native support. Once you understand the basic ideas, you should be able to use structs and function pointers to create an implementation. Of course, looking at the source code for a C++ preprocessor will also be instructive. At one time, C++ was just a preprocessor for a C compiler.

i have a two deep if statement and i'm wondering if i can condense to a single if stmt:

if ([[myScrollView.subviews objectAtIndex:k] isKindOfClass:[UILabel class]])
{
    if (((UILabel *)[myScrollView.subviews objectAtIndex:k]).tag >= i)
    {
        //code
    }
}

i'm not sure if i can make it into:

if ([[myScrollView.subviews objectAtIndex:k] isKindOfClass:[UILabel class]] && ((UILabel *)[myScrollView.subviews objectAtIndex:k]).tag >= i)

since the second if condition is dependent on the first (if it is not a UILabel and doesn't have a .tag value) can bad things happen?

As everyone has identified this is possible but readability is the main issue. Although the use of whitespace in suggestions is good

if ([[myScrollView.subviews objectAtIndex:k] isKindOfClass:[UILabel class]] 
&& ((UILabel *)[myScrollView.subviews objectAtIndex:k]).tag >= i)
{
    //code
}

I personally would still find I have to do a double take to understand what those statements are doing so sometimes it may be worth taking the readability a bit further

UILabel *label      = [myScrollView.subviews objectAtIndex:k]

BOOL isLabel        = [label isKindOfClass:[UILabel class]];
BOOL hasSuitableTag = label.tag >= i;

if (isLabel && hasSuitableTag) {
    //code
}

OR to keep the short circuit (Thanks @CocoaFu)

UILabel *label = [myScrollView.subviews objectAtIndex:k]

BOOL isLabel   = [label isKindOfClass:[UILabel class]];

if (isLabel && label.tag >= i) {
    //code
}

The result reads a bit more like english (if you expand it in your had) is a label and has a suitable tag. It may slightly longer but when your reading it back in a weeks time you'll appreciate the added typing.


Programs must be written for people to read, and only incidentally for machines to execute.

Abelson & Sussman, Structure and Interpretation of Computer Programs