I’m going back to the idea of treating each langauge in a separate post. Hopefully this will make the comments a bit more manageable (especially since I cross posted the last one onto my erlang blog as well).

## Housekeeping

There were several factor related comments on the last post that I wanted to address before I moved on to section 1.1.7.

AnonymousIs Factor “done”? Seems like it’s still very much a work in progress.Can you comment on your choice of Factor and what has made it enjoyable for you?

Anonymous is right, Factor isn’t done yet. It **is** getting close though, and for what I’m doing, it seems to be “done enough”. I’m using it because I’ve been thinking about learning a stack based language for a while, just to learn to think a little bit differently. So far, it’s fun because it’s doing just that.

And the related:

Ed BoraskyFactor? What does Factor have that Forth doesn’t have? At least Forth has an ANS standard and some vendors and a few thousand person-decades of programmer experience.

Ed, I think the big thing that drew me to Factor over Forth was an active Factor community that I sort of tripped over. Sometimes, it’s the squeaky wheel that draws a user.

The last two weren’t specifically related to Factor, but did show better ways of solving exercise 1.3 (without resorting to lists), so I worked up a factor solution in their vein:

```
: min ( a b -- a b ) 2dup <
[ swap ] when ;
: top-two ( a b c -- d e ) min rot min -rot ;
: sum-of-squares ( a b -- c ) sq swap sq + ;
: sum-squares-of-larger ( x,y,z -- x ) top-two sum-of-squares ;
```

I agree that this is a much better way of solving the problem.

## SICP 1.1.7

Okay, on to some code. I’m going to use the built-in `sq` and `abs` words from now on. There’s no sense in continuing to use mine when there’s a perfectly good version of the word already there. SICP built a series of procedures to find square roots using Newton’s method: sqrt, sqrt-iter, improve, average, and good-enough?. I rewrote these into the following Factor:

```
: average ( a b -- c ) + 2 /f ;
: improve-guess ( num guess -- guess ) dup swapd /f average ;
: good-enough? ( num guess -- ? ) sq - abs 0.001 < ;
: sqrt-iter ( num guess -- guess )
2dup good-enough?
[ ]
[ swap dup swapd swap improve-guess sqrt-iter ] if ;
: sqrt ( num -- root ) 1.0 sqrt-iter ;
```

These are nice and fairly concise, but sqrt-iter seems pretty ugly. I checked back in with the good folks on #concatenative (who have been immensely helpful) and they agreed, saying “`swap dup swapd swap` is a code smell”. They pointed out the `dupd` word, which does the same thing. so a better version of sqrt-iter would be:

```
: sqrt-iter ( num guess -- guess )
2dup good-enough?
[ ]
[ dupd improve-guess sqrt-iter ] if ;
```

Which can be improved still further into:

```
: sqrt-iter ( num guess -- guess )
2dup good-enough?
[ dupd improve-guess sqrt-iter ] unless ;
```

I’m sure there are ways this could be improved yet further. Leave me a comment with your ideas. I’ll try to post my Ruby version tomorrow and Erlang on Thursday.

## No comments:

Post a Comment