Smalltalk (presumably) has a form of logical branching in it somewhere. To finish the if, just pick one.
For a satisfying conclusion, you want to use one that doesn't already look like an if statement.
It uses dynamic binding.
In Java it would look like something this (but it's less useful without proper closures):
abstract class Bool {
void ifTrue(Runnable f, Runnable g);
}
class True extends Bool {
void ifTrue(Function f, Function g) {
f.run();
}
}
class False extends Bool {
void ifTrue(Function f, Function g) {
g.run();
}
}
Then, given a variable Bool b;
the if-then-else becomes b.ifTrue(new Runnable() {
public void run() {
System.out.println("It's true!");
}
}
, new Runnable() {
public void run() {
System.out.println("Not true!");
}
}
);
It's a bit more verbose, though...(define (my-if cond t f) (if cond (t) (f)))
(my-if #t (lambda () ....) (lambda () ....))
The trickyness about if lies in the order of argument evaluation. If you ignore that, then it is relatively easy to implement if in any reasonable language. Even C (I had to leave out the function pointer types, as I haven't worked with c in a few years, and forget the syntax):
void my_if(bool cond, t, f) { if(cond) { t(); } else { f(); } }
void if_true() { ... } void if_false() {
}
my_if(true, if_true, if_false);
Point being, I think redxaxder may have been coming from a scheme background, realizing that if needs to be a builtin. It would indeed be fancy to be able to implement an if that doesn't rely upon other logical branching, though!