There's still other functions that are missing, such as goto-next-column, goto-previous-column, etc.
Anyways, I think you've gotten me to work on this problem as well :) I found it super hard when I solved it in C back in '97. Perhaps I should go back and see if I've gotten any better at programming.
Yeah, makes sense. However, let always creates a new binding and never modifies existing bindings. That's why it makes you indent its body to the right. Compare:
(= x 3 y 4)
(+ x y)
with:
(let (x y) '(3 4)
(+ x y))
The indentation is a hint that these are new x and y variables, compared to any earlier x and y variables.
Besides let there are indeed functions in Arc where you can pass lists or tables by reference (though not primitives like numbers or characters). However, it's usually a good idea to try to avoid these, again so you can practice a less imperative style of programming (http://arclanguage.org/item?id=19709). My usual approach is to first build a program with promiscuous copying everywhere, and then if it turns out to be too slow pick the 2% of cases that can speed it up a lot and make them destructive/call-by-reference, because the cost of doing so is that it makes the program harder to understand.
Thanks, I'm familiar with that practice. I'm also used to passing by reference so that changes made to the variable in the newer function get passed back to the calling function.
Here's a newer view. A number of variables (diagonals, result, row, total) get modified lower in the function. There must be a better way of updating those variables.
Ah, you're right. I think jsgrahamus might be expecting result to be modified by this line:
(let (diagonals result row) (get-next-row board-size diagonals result)
..)
But it just creates a new shadowing binding for result, which exists only for the lifetime of the let, and is lost once the let is finished. Think of let as pushing a new value for its variable(s) on a stack before running its body, then popping the new values off, leaving behind any preexisting values.
I'm pretty sure that what's going on is that you never set the top binding of result to anything else, so it's always the original value at the beginning of each while loop.
Consider this code:
arc> (let result 0 (let result 2 (= result 3)) result)
0
The top-level result is never updated. What part of your code are you expecting to update the value of result?
I'm pretty sure he's always said Arc is a work in progress, and is not ready for full-fledged production use. I don't think he's ever recommended it to others.
I'm sure part of that is that he doesn't right now want to deal with people making requests for it. And having a userbase would mean that.
Make sure to click on the blue flashing text; they're hyperlinks. Arc is discussed in the "Brevity Guild" section; the first of the three new Lisp guilds.
As long as you use '=' it's easy to keep programming C or MUMPS in Lisp. Avoiding '=' forces you to give up old habits and become fluent with (writing as well as reading) deeply nested calls, 'let' and recursion. Those are some big reasons to use Lisp rather than imperative languages. So if you don't use them you're missing out.
I thought that let looked odd, because I thought that with a let in arc, you had 1 variable/value pair. Thanks, zck, for pointing out the difference. And thanks, akkartik, for repeatedly telling me this.
My code snippet is doing that. The let is doing a sort of pattern matching and binding latitude to the first element of the result, and longitude to the second.
It's fine being new to stuff. If you try clicking the link, there's installation instructions there:
To download and build rainbow and open a REPL:
git clone git://github.com/conanite/rainbow.git
cd rainbow
ant
ant # yes, twice. The second time uses rainbow to generate optimisations of itself
cd src/arc
java -server -jar rainbow.jar