Arc Forumnew | comments | leaders | submitlogin
2 points by akkartik 3711 days ago | link | parent | on: Passing values up the line

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.

2 points by akkartik 3711 days ago | link | parent | on: Passing values up the line

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.

3 points by jsgrahamus 3711 days ago | link | parent | on: pg recommending Clojure

Perhaps it is because of the larger community backing Clojure?
2 points by jsgrahamus 3711 days ago | link | parent | on: Passing values up the line

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 jsgrahamus 3711 days ago | link | parent | on: Passing values up the line

Here you go:

  (def get-next-row (board-size diagonals result total)
       (with (column (len result) finished nil new-diagonals nil row (car (rev result)))
         (while (and (~ finished) (~ (> (++ row) board-size)))
	        (if (~ (mem row result))
	  	  (do
		    (= new-diagonals (calculate-diagonals board-size column row))
		    (if (and (~ (mem (car new-diagonals) diagonals))
			     (~ (mem (car (rev new-diagonals)) diagonals)))
		      (do
		        (= finished t)
		        (= result (rev (cons row (cdr (rev result)))))
		        (for i 1 2 (push (pop new-diagonals) diagonals)))))))
         (list diagonals result (if finished row nil) total)))
2 points by jsgrahamus 3711 days ago | link | parent | on: Passing values up the line

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.

Ideas?

Thanks, Steve

---

  (def nqueens (board-size)
    (with (diagonals nil finished nil jsg 0 result '(0) row nil total 0)
	  (while (~ finished)
	         (let (diagonals2 result2 row2 total2)
		   (get-next-row board-size diagonals result total)
	           (if row2
		      (if (is (len result2) board-size)
                        (do
			  (let (diagonals3 result3 total3)
			    (print-result diagonals2 result2 total2)
			    (do
			      (= diagonals2 diagonals3)
			      (= result2 result3)
			      (= total2 total3))))
		        (= result2 (goto-next-column result2)))
		      (if (is (len result2) 1)
		        (= finished t)
		        (let (diagonals3 result3) 
		          (goto-previous-column diagonals2 result2)
			  (= diagonals2 diagonals3)
	  		  (= result2 result3))))
		   (= diagonals diagonals2)
		   (= result result2)
		   (= row row2)
		   (= total total2)))
	  (string "Number of results: " total)))
3 points by akkartik 3712 days ago | link | parent | on: Passing values up the line

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.
3 points by zck 3712 days ago | link | parent | on: Passing values up the line

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?
2 points by akkartik 3712 days ago | link | parent | on: Passing values up the line

Can you show the other functions like get-next-row? Thanks.
6 points by zck 3713 days ago | link | parent | on: pg recommending Clojure

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.

3 points by zck 3717 days ago | link | parent | on: How Lisp is going to save the world!

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.
1 point by kinnard 3717 days ago | link | parent | on: How Lisp is going to save the world!

This is awesome.
2 points by waterhouse 3719 days ago | link | parent | on: Multiple Return Values

The corresponding macro in Common Lisp has an 18-character name.

  ; SBCL
  * (destructuring-bind (x y) '(1 2) (+ x y))
  3
  ; Arc
  arc> (let (x y) '(1 2) (+ x y))
  3
1 point by akkartik 3719 days ago | link | parent | on: ASK: Emacs inferior-arc on Windows

Are you able to get inferior-lisp working on Windows? Maybe the appropriate forum could help with any gotchas there?

If you do figure this out don't forget to come back and tell us!

1 point by zck 3720 days ago | link | parent | on: ASK: Emacs inferior-arc on Windows

Oh, weird. Then I'm less able to help you, as I don't have a Windows computer. Sorry about that.
2 points by archie 3721 days ago | link | parent | on: ASK: Emacs inferior-arc on Windows

Hmmm, interesting. But I don't have any problem on my linux machine, only Windows is problematic. Here's mine .emacs setup on linux:

  (add-to-list 'load-path "~/.racket/6.4/pkgs/anarki/extras")
  (autoload 'arc-mode "arc"
    "Major mode for editing Arc." t)
  (add-to-list 'auto-mode-alist '("\\.arc$" . arc-mode))
  (setq arc-program-name "~/.racket/6.4/pkgs/anarki/arc -n")
  (add-hook 'inferior-arc-mode-hook
  	    (lambda ()
	      (set (make-local-variable 'comint-use-prompt-regexp) t)
	      (set (make-local-variable 'comint-prompt-read-only) t)))
2 points by zck 3722 days ago | link | parent | on: ASK: Emacs inferior-arc on Windows

Ah, sorry I missed that. Right now (on Linux), I'm not even getting as far as you are. Upon M-x run-arc, I'm getting this error:

    emacs: /home/zck/programs/arc/arc3.1/arc.sh: Exec format error

    Process arc exited abnormally with code 126
3 points by archie 3722 days ago | link | parent | on: ASK: Emacs inferior-arc on Windows

No answer, huh? It's really an annoying problem...
2 points by jsgrahamus 3722 days ago | link | parent | on: Multiple Return Values

Makes sense. Thanks.

It really does force me to think a different way. Painful sometimes, too.

1 point by akkartik 3722 days ago | link | parent | on: Multiple Return Values

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.
2 points by jsgrahamus 3722 days ago | link | parent | on: Multiple Return Values

Why avoid = in lisp/arc?
3 points by jsgrahamus 3722 days ago | link | parent | on: Multiple Return Values

And, of course, the "regular" form of arc has no parentheses:

  arc> (let hat 5 (prn "hat = " hat))
  hat = 5
  "hat = "
  arc>
2 points by jsgrahamus 3722 days ago | link | parent | on: Multiple Return Values

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.
2 points by zck 3722 days ago | link | parent | on: Multiple Return Values

I'll explain a little further, because Arc's let is unusual. Unlike most Lisps, the variable-value pairs are not themselves enclosed in parentheses.

In this code:

    (let (latitude longitude) (func1 a b c)
We're not binding latitude to the value of longitude, but binding that whole thing to the return value of (func1 a b c).

A simpler example:

    (let (name score) '("Steve Wiebe" 1064500)
      (prn name " was the first person to score over a million points in Donkey Kong, with a score of " score))
This prints:

    Steve Wiebe was the first person to score over a million points in Donkey Kong, with a score of 1064500
2 points by akkartik 3722 days ago | link | parent | on: Multiple Return Values

  (let (latitude longitude)  (func1 street-number street city state)
     (make-map latitude longitude)
     (func2 latitude)
     (func3 longitude))
2 points by akkartik 3722 days ago | link | parent | on: Multiple Return Values

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.
2 points by jsgrahamus 3722 days ago | link | parent | on: Multiple Return Values

So say you have some variables to capture the return from one function so you can feed it into another 1 or more functions:

  (with (latitude 0 longitude 0
     result (func1 street-number street city state))
     (= latitude (pop result))
     (= longitude (pop result))
     (make-map latitude longitude)
     (func2 latitude)
     (func3 longitude))
Is there a better way of capturing the results of one function?
2 points by jsgrahamus 3722 days ago | link | parent | on: Multiple Return Values

Thanks. So, how do you get the 2 results from func1 into latitude and longitude?
3 points by akkartik 3723 days ago | link | parent | on: Multiple Return Values

The most elegant approach is to keep your func1 unchanged and call it like this:

  (let (latitude longitude) (func1 a b c)
    ..)
In general you want to try to avoid = in Lisp..
2 points by hjek 3724 days ago | link | parent | on: NEWBIE:: new to Lisp, new to Arc.

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
More