Author Archive
Purpose-driven life
Warren, Rick. The Purpose-Driven Life. Grand Rapids, MI: Zondervan, 2002.
I am delighted to see a popular book that exhorts Christians to consider God first, and to remember that we are God’s and not our own. One of the overwhelming concerns of this book is countering self-centeredness and directing believers to God, and there are many helpful exhortations to this end. This is excellent.
However, there are some aspects of the book that I am concerned about:
- Scripture. The book seems to play fast and loose with Scripture. Most scripture quotations are given entirely out of context, and many are used to argue points they were not intended to make, or at least were not intended to make conclusively or universally.
- Holiness. God’s holiness is largely absent, while His love is heavily emphasized; this tends to give an inaccurate picture of God’s love. It’s not that the book doesn’t touch on sin and forgiveness; but it doesn’t convey the gravity of man’s sinful estate before a holy God. I would say that the true gospel seems almost absent.
- The gospel. Beyond that, the book declares hope to unbelievers before it has portrayed their helplessness and need for mercy. The hope that is thus declared is a very false and shallow hope. And when the book finally does answer “what must I do” (pp. 58-59), there is only very oblique mention of our need for forgiveness, mercy, redemption, etc. How sad that this crucial aspect of the cross should be so neglected! The salvation thus proclaimed cannot be genuine salvation.
- Sanctification. There is some imbalance between exhortation to obedience and faith, and a reminder that obedience and faith are empowered by the Spirit and grounded in the cross. Both are present, though the latter isn’t attested to nearly as much; this frequently lends the impression that obedience is to be in our own strength.
- Suffering. There is little mention of genuine suffering in this book. The apostle Peter goes so far as to say that “you were called for this purpose” — namely, to patiently and joyfully endure suffering for God’s glory. Without an acknowledgment that we are called to be united with Christ in suffering, receiving his strength and reflecting his glory, this book is missing a significant aspect of God’s purpose in our lives for displaying his glory and refining and proving our faith. This leaves Christians ill prepared to endure suffering in faith.
I fear that this book will serve to leave unbelievers empty-handed, looking to Jesus as a source of tranquility, happiness, satisfaction, and purpose — but not as a mediator, redeemer, or savior. I also fear that, by leaving the gospel and the cross behind the scenes, it may serve to subtly distract the church from that which is most important.
As an alternative to The Purpose-Driven Life, I highly recommend C. J. Mahaney’s The Cross-Centered Life.
You may also be interested in 9 Marks Ministries‘ very helpful reviews of The Purpose-Driven Life, The Purpose-Driven Church, and 40 Days of Purpose.
Rick Warren also has his own website related to the book.
Comfort and Joy
Discussion questions on chapters 7-8 of Christ Our Mediator, by C. J. Mahaney.
Summary
Chapter 7, What God Understands. Because of Jesus’s suffering, there is comfort to be found at the cross for the suffering Christian. The cross puts the degree of our suffering in perspective; our suffering, though very real, is light and momentary by comparison, for Jesus has suffered God’s full wrath for our sin. And as a result of His own suffering, Jesus understands our suffering intimately. But more than that, because He suffered for our sake, He brings real comfort to us in our own suffering: He intercedes for us before the Father, and He gives us the Holy Spirit.
Chapter 8, Assurance and Joy. Because of what Jesus has accomplished for us, there is joy to be found at the cross in the midst of our suffering as Christians. He suffered God’s wrath for our sake, to rescue us from that wrath and bring us mercy. All of our suffering is eclipsed by the staggering greatness of this gift, even moreso because we are entirely undeserving of God’s kindness. The cross assures us of God’s unfailing and personal love for us. The cross should be for us an unending source of “joy inexpressible and full of glory”.
Questions
- CJ quoted Spurgeon as writing that “we little know what we owe to our Savior’s prayers,” that not until heaven will we see the the full and amazing extent of Jesus’s intercession for us before the Father. Yet looking back even now, can you identify some specific ways in which it is clear that God has shown mercy and compassion to you in the midst of suffering? The goal here is both to build faith and also encourage thankfulness and praise.
- CJ describes a doctor dying of AIDS and writes that “Jesus was with [him and his wife]. That was all either of them needed to know. Because that is always enough. . . . He is always present. . . and that is sufficient.” What does it mean to say that Jesus is sufficient? ”We do not need anything other than Him, and we do not need anything more than Him.” How have you found this to be true in your life? How is Jesus present and sufficient for you here and now?
- Often we allow ourselves to be ruled by subjective feelings and appearances; we might feel that God has abandoned us, that He does not care or understand, or that a situation is insurmountable. When we are overwhelmed by feelings or appearances, the only counsel that the world has to offer is to convince ourselves we’re okay on the one hand, or on the other to grimly bear pain in our own strength. But for the Christian there are objective realities that bring genuine comfort and even joy in the midst of suffering. When we are tempted by subjective appearances to despair, what objective truths must we flee to as our anchor and hope? The gospel, the cross, the amazing and undeserved mercy God has shown us in our sin, God’s declaration of His eternal love, God’s faithfulness. . . When we are captivated by subjective appearances, why is it not only good, but right, to flee to the cross? By giving ourselves to subjectivity we are not merely misguided or short-sighted, but are living in unbelief.
- Read Habakkuk 3:17-19. In the midst of his trials, where was Habakkuk’s focus? In the God of his salvation. Why was this the right attitude for Habakkuk — and us — to have? God has proven His love (we can see this even more clearly than Habakkuk, since we look back on the cross); God’s kindness and salvation far outweigh our suffering; and we do not know better than God in His sovereignty, wisdom, and love. Does this attitude come naturally for Habakkuk, or us? Habakkuk struggled for three chapters, complaining to God, and only in the end came to realize what was most important. Likewise, in our suffering, we must exercise faith to have this outlook.
- CJ quotes Thomas Watson as writing that “your sufferings are not so great as your sins: put these two in the balance, and see which weighs heaviest.” When we consider the full weight of our sin, how does that put our suffering in perspective? First, we deserve far worse suffering. Second, God has been amazingly merciful to us. How should this provoke us to respond to suffering? With humility, gratefulness for mercy, joy.
- Read Galatians 2:20. CJ counsels us to flee to the cross as our only hope and the source of true joy. What encouragement can we draw from this verse in particular? Jesus is the source of our life; Jesus loves us personally; Jesus gave Himself for us personally. Why is Jesus’ personal love and sacrifice for us so amazing? First, God’s particular and personal love gives us great comfort and assurance: we haven’t stumbled upon His grace accidentally, but rather He set His love on us, individually. Second, the fact that He loved us beforehand, even knowing our sins, is humbling and amazing.
- God actually commands us to serve Him with joy (Ps. 100:2; Deut. 28:47-48). Obviously joy is not the fruit of a wooden obedience; CJ reminds us that our joy is found by seeing our savior and the cross with eyes of faith, exhorting us to “let the cross always be the treasure of your heart, your best and highest thought. . . and your passionate preoccupation.” What are some practical ways you have found helpful to keep the cross your “passionate preoccupation”? Study the gospels and epistles; study books on the cross; make the cross a regular subject of meditation, prayer, and song; . . .
- What are some of the many ways that considering the cross produces real joy? Name some specific ways the cross has brought comfort and joy to you in the past, or how it can bring comfort and joy to a present situation you are experiencing. This would be a good bridge to a time of spontaneous thanksgiving and praise in closing.
- Possible ways to close the meeting:
- End with a time of prayer or praise to allow for spontaneous expressions of gratitude and joy in the cross.
- Pray for those who are experiencing suffering, hardship, or trials.
- Pray for those who desire greater assurance. While a lack of assurance is usually a sign of looking for it in the wrong place (emotions or self-righteousness rather than Christ), God does give us assurance in His word and by His Holy Spirit.
Python odd word problem
I crafted this compact solution to Dijkstra’s OddWordProblem:
from sys import stdin, stdout
def even(char) : stdout.write(char); return select(even, 0, "");
def odd(char) : q = select(odd, 0, ""); stdout.write(char); return q
def select(fn, skipspace, prefix) :
char = stdin.read(1)
if char.isspace() and skipspace : return select(fn, 1, prefix)
elif char.isspace() : return 0
elif char.isalpha() : stdout.write(prefix); return fn(char)
elif char == "." : return 1
else : raise "Invalid input"
if not select(even, 1, "") :
while not select(odd, 1, " ") and not select(even, 1, " ") : pass
stdout.write(".")
Introduction to Pointers in C++
Originally written in February 1998. At least one person seems to have found it useful. It’s a little incomplete, because it doesn’t deal with malloc and free, nor with C++ references. If you find this useful, feel free to copy and pass along, with attribution. Thanks!
Basics
All data and code are stored in memory. The location in memory where they are stored is known as the address of that data or code. Usually they are accessed through variable names that represent them, such as counter, printf, etc. We can, however, also access data using its address, rather than a formal name. This is done using pointers, special variables which store the address of data. Following are several annotated examples of simple pointers at work.
int* x; // Declare x, a pointer to an integer. int y; // Declare y, an integer. float* r; // Declare r, a pointer to a float. float s; // Declare s, a float. x = &y; // x gets y's address -- it points to y. r = &s; // r gets s's address -- it points to s.
The next few are a tad trickier. We use the “*” to dereference the pointer. Basically, this means to access whatever it is the pointer is pointing to. You can think of it as counteracting the “*” used in the declaration of the pointer; they neutralize each other, making the result a regular variable.
*x = 15; // Set value pointed to by x -- y -- to 15. cout << *r; // Print value pointed to by r: s.
Complications
If it were that simple, of course, then nobody would have trouble with pointers. The fact of the matter is, however, that there are a number of complications — extensions to the idea of pointer — that can be hard to keep track of.
Pointers as Lists
The first is the idea of pointers being equivalent to lists. This is a crucial idea in C and C++. Essentially, instead of thinking of a pointer as pointing to a single variable, you can think of it as pointing to the first variable in a list of variables. Likewise, a list can be accessed without any subscripts to find the pointer to the first element in the list. It works like this:
int* x; int y[15]; x = new int[8]; // Allocate array of 8 integers. *y = 8; // Set first element of y-list to 8. x[3] = 7; // Set fourth element of x-list to 7.
Note how pointer notation can be used for the list y, and how list notation can be used for the pointer x.
This brings up a similar topic: pointer arithmetic. Since a pointer is a memory address, you might think that adding 1 to a pointer would simply make it point to the next byte of memory. The C compiler, however, is smarter than that; it realizes that you’re adding something to a pointer, you probably want to make it point to the next element of whatever you’re pointing at. So instead of adding whatever you specified to the pointer, it adds that times the size of the object the pointer points to. For example:
int* x = new int[8];
x++; // Add four to x pointer, to
// point at next integer.
x[0] = 5; // This was originally the second
// element in the array.
x--; // Subtract 4 again from pointer.
*(x + 2) = 6; // Set third element (second after the
// first) to 6.
cout << x[1]; // Will now print "5".
cout << x[2]; // Prints "6".
Pointers to Pointers (aka “The Middleman”)
Another pointer curiosity that C throws our way is pointers that point to other pointers. This may seem like a needless feature, but it comes in very handy when you have multidimensional data whose size you don’t know before-hand. You can then use these pointers to pointers to set up an arbitrary-sized multidimensional array.
It works like this: you can think of a pointer to a pointer as being essentially a list of lists. It’s kind of like the words in the dictionary: the first pointer tells you where to find each of the lists for the letters of the alphabet. Each letter is then itself a pointer that forms a list (by pointing to the first element) of all of the words beginning with that letter. If you add another dimension (and make a pointer to a pointer to a pointer), you can have each word also be a list, pointing to the first out of several different meanings for the word.
Here’s how it works in C++. The following program reads in a table of numbers and finds the average for each row and column. The first two numbers it reads in tell how many rows and columns there are. The rest of the numbers are the ones in the table.
#include <iostream.h>
void main(void)
{
int** table; // *Two*-dimensional pointer.
int rows, cols, i, j, sum; // Dimensions of table.
cin >> rows >> cols; // Find out the number of rows & cols.
// What we'd really like to do here is say:
// table = new int[rows][cols];
// Unfortunately, this doesn't work in C++, since it instead tries to set up
// a one-dimensional array like this:
// table = new int[rows * cols];
// And a one-dimensional array (a pointer to integers) is absolutely
// incompatible with a two-dimensional array (a pointer to a pointer to
// integers), so our program will crash. Note that the syntax above will
// work, however, in Java.
table = new (int*)[rows]; // Allocate the rows.
for(i = 0; i < rows; i++)
table[i] = new int[cols]; // Allocate each row's columns.
for(i = 0; i < rows; i++) // Find row sums.
{
sum = 0;
for(j = 0; j < cols; j++)
sum += table[i][j];
cout << "Row sum for row " << i << ": " << sum << endl;
}
for(j = 0; j < cols; j++) // Find column sums.
{
sum = 0;
for(i = 0; i < rows; i++)
sum += table[i][j];
cout << "Col sum for col " << j << ": " << sum << endl;
}
}
Notice how we had to explicitly allocate both dimensions of the array, starting with the first dimension, the rows; and then for each row we allocated its columns. You may be wondering why the outer dimension is allocated using “new (int*)[n]”, while the inner dimension is allocated using “new int[n]”. This is because each dimension but the last is a pointer to the next dimension. The final array dimension is obviously simply a list of integers, so in the inner loop we merely allocate a list of integers. The next dimension up, however, is not a list of integers; it’s a list of lists of integers. As such, each entry in this list will itself be a pointer to a list of integers — the final dimension. Therefore, the code allocating the outside dimension must allocate a list of pointers to integers.
If we had additional dimensions, for each column in each row we would then have to allocate the list of cells, and so forth. Here’s how a three-dimensional array allocation might look like. Assume that x, y, and z are the size of each array dimension. Notice how the outer dimension is now a list of (int**)’s — a list of lists of lists — and the second dimension is now the one that is (int*) — a list of lists — while the final dimension is still a list of integers.
int i, j;
int*** array3d;
array3d = new (int**)[x];
for(i = 0; i < x; i++)
{
array3d[i] = new(int*)[y];
for(j < 0; j < y; j++)
array3d[i][j] = new int[z];
}
Python persistence
I’ve implemented a rudimentary persistent object store in Python. It is implemented as a Python extension module that implements a set of persistent types: strings, integers, floats, lists, and dictionaries. Each of these are backed by the persistent object store, which is implemented using a memory-mapped file.
In addition, using a specially crafted Python base class for Python objects, Python objects may be stored in the object store (as dictionaries) and instantiated out of the object store.
The result is an persistent object graph (the root of which is a persistent dictionary) whose objects and attributes may be manipulated in-place using native Python syntax. Rudimentary locking is provided so that multiple Python threads / processes may concurrently manipulate the object store.
Details
Some aspects of this system are:
- It is a Python extension module written in C and C++.
- It is tested on Linux. It will likely work on *BSD systems, though it is possible that the location of the mapped storage may need to be moved.
- It is implemented in a hierarchical manner:
- A page manager handles the allocation of 4kB pages within a memory-mapped file. It is multi-process safe. It is, in a sense, a glorified sbrk() for a memory-mapped file.
- A heap manager abstracts the page manager’s services to manage the allocation and deallocation of arbitrary-sized storage segments within the memory-mapped file. It is essentially a malloc() and free() for a memory-mapped file. This is also multi-process safe.
- An object manager manages five new base types (persistent int, float, string, list, and dictionary) backed by persistent storage, using the heap manager’s services. It also provides rudimentary locking facilities for concurrency-safeness.
- The persist Python extension uses the object manager’s services to implement persistent types that mimic the equivalent Python types. Additionally, it has the ability to reinstantiate a Python object that was stored as a dictionary (using the appropriate Python base class). The object manager’s locking facilities are made available for application usage.
- Only one file may be mapped at a time (because it is mapped to a fixed logical address).
- It is available for use under the MIT license. Contact me if you are interested in using it.
Examples
Some examples of its use are a simple counter:
import persist root = persist.root() root.lockExcl() try : root['x'] += 1 # Increment counter except : root['x'] = 1 # First pass; initialize print "Content-type: text/html\n" print "<p>You are visitor " + str(root['x']) + " to visit this site!</p>" root.unlock()
and rudimentary objects:
import persist
from pbase import pbase
class person (pbase) :
def __init__(self, name = "", age = 0) :
pbase.__init__(self)
self.name = name
self.age = age
def printAge(self) :
print "<p>" + self.name + " is " + str(self.age) + " years old</p>"
root = persist.root()
root.lockExcl()
if not root.has_key('Joe') : # First time through
root['Joe'] = person('Joe', 27)
if not root.has_key('John') : # First time through
root['John'] = person("John", 29)
# On subsequent passes we will retrieve the objects stored on the first pass.
print "Content-type: text/html\n"
root['Joe'].printAge()
root['John'].printAge()
root.unlock()
The Puritans
Lloyd-Jones, The Puritans: Their Origins and Successors. Carlisle, PA: Banner of Truth, 1987.
These are a series of lectures Lloyd-Jones delivered at the Puritan Studies and Westminster Conferences. This was my first encounter with Lloyd-Jones, and I enjoyed it very much.
The burdens of Lloyd-Jones that stand out in my memory are:
- The stark difference between revival and revivalism, and a need to appeal to God to bring true revival.
- The need to avoid dead academic intellectualism in our study of the Puritans and our pursuit of God.
- The importance of full-bodied faith as opposed to mere intellectual assent to propositions.
- The role of the Holy Spirit in empowering, encouraging, and assuring believers, and the need to earnestly desire that.
- The need to break down barriers between Christians that are over unimportant matters (while upholding and defending those matters that are of vital importance).
- The need for continued fresh analysis and application of God’s word, rather than unthinking adherence to tradition and habit.
- The importance of ”application” in preaching.
Moderation
The devil has driven the pendulum far beyond its proper point of rest; and when he has carried it to the utmost length that he can, and it begins by its own weight to swing back, he probably will set in, and drive it with the utmost fury the other way; and so give us no rest; and if possible prevent our settling in a proper medium. What a poor, blind, weak and miserable creature is man, at his best estate! We are like poor helpless sheep; the devil is too subtle for us. What is our strength! What is our wisdom! How ready are we to go astray! How easily are we drawn aside into innumerable snares, while in the mean time we are bold and confident, and doubt not but we are right and safe! We are foolish sheep in the midst of subtle serpents and cruel wolves, and do not know it. Oh how unfit are we to be left to ourselves! And how much do we stand in need of the wisdom, the power, the condescension, patience, forgiveness, and gentleness of our good Shepherd!
— Jonathan Edwards, as quoted in Jonathan Edwards: A New Biography, p.246
Hosea
Discussion questions on Hosea. This material owes much to Phil Sasser, Mark Dever, and John Piper.
Summary
- Hosea and Gomer as a type for God and Israel. Israel’s odious sin, God’s judgment, and God’s loving restoration.
- God’s restraining love shown in pleading for Israel’s repentance, and prophesying and bringing judgment.
- God’s redeeming love shown in his promise to buy Israel back for himself.
- God’s restoring love shown in his promise to bring healing to Israel.
Our sin
- Phil talked about how the imagery of adultery reminds us how shocking sin is. Does this come as a surprise? Do you easily forget how personally our sins are taken by God?
- Phil. 3:13-14 cautions us to “[forget] what lies behind”. When we contemplate our sin we should not let ourselves become burdened by condemnation; Romans 8:1 comforts the Christian that there is no condemnation thanks to Jesus’s sacrifice.
At the same time, Eph. 2:11-13 calls us to “remember that [we] were separate from Christ” so that we may rejoice at having been brought near. And Paul recalls that he is “the worst of sinners” for the purpose of exulting in the grace and mercy he found in Christ (1 Tim. 1:12-17); he is moved by this consideration to proclaim that “to the King eternal, immortal, invisible, the only God, be honor and glory for ever and ever. Amen.”
- What good can we gain from considering our sin?
- A right notion of our humble position before God, “evangelical humiliation.”
- A right notion of our position relative to others (we have no advantage or merit, and cause only for compassion and not pride).
- A better understanding of the greatness of God’s love and mercy to us.
- What should a right understanding of the weight of our sin provoke in us?
- Humility.
- Contrition and repentance.
- Dever reminds us that Christians must be always confessing sin and repenting of it. Not that God’s mercy is unsure — but our hearts are wandering and need continuous examining.
- Phil reminds us to bring words of repentance, as in Hos. 14:2-3. Do you urgently confess to God your need for his mercy?
- Gratitude and joy.
- Are there any practical ways that you find helpful in cultivating a heart of humility and contrition before God?
God’s mercy and holy love
- God’s holy displeasure with sin is on display in Hosea, but so is his great redeeming love. What great hope and comfort can we take from Hosea?
- God’s love is jealous and holy; he desires to restrain his people from sin.
- We stand in the shadow of the cross; we have received this great promised redemption.
- What of the “healing” promised in 14:4? Sanctification; God has delivered us from bondage to sin! Phil reminded us that sin is no longer our master.
- We have no hope apart from God. But he is a sure hope.
- What should an understanding of God’s great mercy and love provoke in us?
- Phil reminded us that our love and devotion toward God must be pure and not mixed or half-hearted.
- The great price at which we were bought (1 Peter 1:17-19) should inspire much gratefulness and affection.
- We ought to be provoked to a similar self-giving love (1 John 4:10).
Closing
Possibly close with a quotation from Charles Simeon biography, on humility and enjoyment of God’s glory and love. Simeon says:
With this sweet hope of ultimate acceptance with God, I have always enjoyed much cheerfulness before men; but I have at the same time laboured incessantly to cultivate the deepest humiliation before God. . . . There are but two objects that I have ever desired for these forty years to behold; the one is my own vileness; and the other is, the glory of God in the face of Jesus Christ: and I have always thought that they should be viewed together; just as Aaron confessed all the sins of all Israel whilst he put them on the head of the scapegoat. The disease did not keep him from applying to the remedy, nor did the remedy keep him from feeling the disease. By this I seek to be, not only humbled and thankful, but humbled in thankfulness, before my God and Saviour continually.
Piper writes:
the remarkable thing about humiliation and adoration in the heart of Charles Simeon is that they were inseparable. Simeon was utterly unlike most of us today who think that we should get rid once and for all of feelings of vileness and unworthiness as soon as we can. For him, adoration only grew in the freshly plowed soil of humiliation for sin. So he actually labored to know his true sinfulness and his remaining corruption as a Christian.
For the Christian, contemplation of our sin brings not condemnation but tearful joy at the greatness of the mercy shown to us, and the awesome greatness of the holy giver of mercy!