Arc Forumnew | comments | leaders | submitlogin
3 points by zck 3149 days ago | link | parent

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?


3 points by akkartik 3149 days ago | link

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.

-----

2 points by jsgrahamus 3148 days ago | link

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.

-----

2 points by akkartik 3148 days ago | link

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.

-----

2 points by jsgrahamus 3147 days ago | link

Thanks, makes sense.

-----