Yes. Version 372 was the last version which supported set-car! and set-cdr! for regular cons cells, so Arc 3 was locked to that version. However, Arc 3.1 overcame this limitation by using pointer manipulation to mutate cons cells anyway. This would sometimes fail, but this Arc 3.1 bug has been fixed in Anarki and Arc/Nu.
The /install page on this forum still refers to Arc 3, so this version dependency is a frequent point of confusion.
I guess the moral of the story here is that ,(...) evaluates the entire sexp, and puts the value there.
Yup! If your quasiquoted expression only contains unquotes, the expansion is simple. Basically,
`(sexp1 sexp2 ... ,sexpn ...)
will expand into
(list 'sexp1 'sexp2 ... sexpn ...)
This also applies recursively, so that
`(sexp1 (subexpr1 ,subexpr2))
expands into
(list 'sexp1 (list 'subexpr1 subexpr2))
With unquote-splicing, you can think of quasiquote expanding into cons, so
`(sexp1 sexp2 ,@sexp3)
will expand into
(cons (list 'sexp1 'sexp2) sexp3)
If you're interested, I encourage you to look over my implementation of quasiquote in Arc. It's actually pretty simple (175 lines with comments), and might help clarify how quasiquotation works.
I'll have to do more reading about macros.
I think you seem to have the mental model for macros down. And I've always said that macros aren't that magical, because they fall out as a natural consequence of the language. Hell, here's a simple Arc "interpreter" that shows how macros are handled differently from functions:
(def interpret (expr)
(if (acons expr)
(let op (interpret (car expr))
(if (isa op 'mac) (interpret (apply (rep op) (cdr expr)))
(isa op 'fn) (apply op (map interpret (cdr expr)))
(eval expr))) ; punt on special forms (fn, if, etc.)
(maybe-lookup-name expr)))
(def maybe-lookup-name (expr)
(if (and (isa expr 'sym) (bound expr))
(eval expr)
expr))
Here, interpret is really just another name for eval. Macros are simply functions whose inputs are unevaluated code. They construct some other bit of unevaluated code, and that result gets evaluated.
Quasiquote is then just a nice way to construct lists, whether it's unevaluated code for a macro to return or whatever. Its syntax takes some getting used to, but it comes with practice. Happy hacking!
For some reason, I had in my head that, inside quasiquote in a macro, you need to unquote every variable you want to evaluate before returning the code to be executed. Note that all my examples have ,sym1 and ,sym2 (except fancy-combine4, but that's deliberately executing the code before the returned generated code).
I guess the moral of the story here is that ,(...) evaluates the entire sexp, and puts the value there. I'll have to do more reading about macros.
Assuming you're using 'GNU screen' you also have the option to re-attach to an existing session using the 'screen -r' command. Using 'screen -ls' will list out all the sessions should you not be sure, or have more than one.
That aside, most developers will do development changes on a local machine where they need not attach/reattach and this way you wouldn't need to troubleshoot your code and the host environment at the same time.
Then you create a stable deployment process. eg. Backup the old code, drop in the new code, re-attach to the existing session and either load your changes or restart the program if you're ok with some nominal downtime.
The error you're getting from fancy-combine2 is because you have a double-unquote. You neglected to remove the unquotes from sym1 and sym2. The correct form would be
It might help to have a user-land defined quasiquote macro, to see how it works. I implemented such a macro here: https://bitbucket.org/fallintothis/qq
Using qq.arc, we can see that my solution is to use this expression:
Hence, you get an error about unquote being undefined, because Arc doesn't actually define quasiquote or unquote as macros. They're just special identifiers that are basically parsed away before evaluation (assuming quasiquotes/unquotes are balanced). However, loading qq.arc defines an unquote macro, so instead of the error you had, you'll get this:
arc> (fancy-combine2 a b)
Error: "unquote not allowed outside of a quasiquote: a"
which makes it a bit more obvious what the error is.
Yup! I looked for it a bit, couldn't find it, tried to post the top-level website, got caught by the dup detector, and ended up posting the thread that brought it back to my attention :)
No problemo and yeah, in retrospect, I could have chosen better terminology and been much more descriptive, but that's one of the things you will enjoy about the arc forum... You just keep asking and, generally speaking, people are very helpful. After all, I learned how to program by just doing what you are, running the news app, reading the arc code and relying on this forum for help along the way.
I used the command
ps aux | grep 'news.arc'
and it returned only one copy running, but I suspect that's not right.
And your comment about multiple copies also got me thinking that from the main Arc directory to go into the Arc prompt maybe I shouldn't have been using
$ mzscheme -f as.scm
Was I supposed to use that just once to run news.arc for the first time?
Yeah these are good suggestions. The "address already in use" error suggests that you might have multiple copies of arc running, so that you're making changes to the wrong copy. Use the commands 'ps' and 'kill' to look for the other copies and stop them.
Hmmm it's been a really long time since I looked at the code, but I would try two things.
1. Enter this-site* at the prompt to confirm the change took place.
2. Abort the session, I.e such that the arc prompt is killed. Then goto the webpage and make sure its no longer running news (just to confirm the abort occurred and/or is not somehow running a past instance), then reload arc again.
I tried to put the entire expression into the arc> prompt and also tried to use simpler expressions, but I still can't get "My Forum" to change.
I've also reloaded news.arc several times and I'm not sure if it means anything, but when I go back to the arc> prompt and enter
arc> (load "news.arc")
I get
nil
and only after loading news.arc a second time I get the
"* redefining" messages
I remember that to run news.arc the first time I also used (nsv) so I tried that as well and for what is worth I got the following error:
rm: cannot remove ‘arc/news/story/*.tmp’: No such file or directory
load items:
user break
context...:
/home/ubuntu/arc/ac.scm:1031:20
gs1259
user break
context...:
/home/ubuntu/arc/ac.scm:1031:20
gs1259
Error: "tcp-listen: listen failed\n port number: 8080\n system error: Address already in use; errno=98"
arc>
Editing news.arc won't "reload" your changes. If you write the code to the file, it won't actually execute that code. Does that make sense?
You want to go back to the arc> prompt (where you started (nsv)) and do something to get that code to run. You could do this in a few ways. You could do:
arc> (load "news.arc")
which will reload the changes you saved to the news.arc file. It might look crazy, because it prints out a bunch of messages that look like
*** redefining logins-page
It'll do that because it's reloading the entirety (!) of news.arc, which includes a bunch of other code. Thus, there are warnings about "redefining" certain code. But as long as you didn't actually change the code in question, it should be fine.
At the end of the day, this is probably the best way to go, despite all the intimidating warning messages. Because if you edit the news.arc file, then the changes you make will be saved in case you ever need to restart the forum in the future.
But, for the sake of completeness, I'll explain how you can also just edit the variables by hand at the prompt. So, instead of changing news.arc to say
(= this-site* "Match Fixing Scandals"
site-url* "http://news.yourdomain.com/"
parent-url* "http://www.yourdomain.com"
favicon-url* ""
site-desc* "What this site is about." ; for rss feed
site-color* (color 180 180 180)
border-color* (color 180 180 180)
prefer-url* t)
and reloading news.arc, you could actually just put the entire thing above (called an expression) into the arc> prompt:
arc> (= this-site* "Match Fixing Scandals"
site-url* "http://news.yourdomain.com/"
parent-url* "http://www.yourdomain.com"
favicon-url* ""
site-desc* "What this site is about." ; for rss feed
site-color* (color 180 180 180)
border-color* (color 180 180 180)
prefer-url* t)
This will execute the code, thus modifying your settings.
You could also use simpler expressions---or, really, any Arc code you want. If you weren't a coder before, you are one now! :)
The expression above of the form (= a b c d ...) can be used to change the values of any number of variables (setting a to b, c to d, etc.), which will control how the site displays. So, you could do something like
One of these settings you'll want to change is buried deep inside of news.arc (about 400 lines down), so it's hard to spot. But, you can change these variables, too:
Koding is a website that provides a limited amount of FTP-accessible storage (I think around 4GB? Maybe 2GB?) and a limited VPN to use for Web development. I think it supports SSH access, but I've only used the in-browser shell. Last I checked, long-running processes don't survive between shell sessions.
On the other hand, it supports CGI-style websites based on PHP, Ruby, and some other languages. These pages can stay online forever.
Koding was previously open-signup under the name Kodingen, but it didn't have any support for shell access at that time. Nevertheless, I successfully ran shell commands via PHP and Ruby scripts, and this was enough to test out Racket and Arc programs.
Not too long ago I removed my Arc installation from my Koding account. Racket was taking up too much disk space, and http://tryarc.org was enough for me. :) I'm pretty sure the potential is still there if someone's interested.
Thanks! You're absolutely right, I've had every single one of these problems, I just never focused on them. But I'd often comment out a bunch of tests in the middle of debugging just one.
I'm going to have to go to bed soon, as I need to wake up in eight hours and twenty minutes, and I've promised myself I'm going to try to sleep enough, for once.
So I'll just explain what, in my mind, is the biggest difference -- how I want to use it. To run the anarki test-iso test, you execute the entire `(test-iso ..)` sexp. If you want to run a bunch of tests, you have to execute all the sexps.
That's kind of a hassle. Especially if you find a bug, have a bunch of tests that fail, then change a small thing in the function, and want to re-run all the tests.
In my unit-test.arc, all you have to do is call `(run-suites suite-name)`, and it'll run as many tests as you've got in `suite-name`. You don't have to copy a bunch of sexps into the repl or reload the file (and what if you want to run a subset of a file? You can't). Also -- and this is one of the features I'm currently working on (https://bitbucket.org/zck/unit-test.arc/issue/21/after-runni...), what if you run one hundred tests at once? Do you really want to parse -- with your eyes, like a bloody scribe -- every single line of output to find the seven tests that broke? And when you then make a fix, you're not going to want to parse them again, so you'll only run the seven that failed before. So if you broke something else, you won't find that out.
So, what falls out of my desire to run a set of tests easily and repeatably, and have summarized output? Some sort of grouping, with a single point of entry to run the tests -- that is to say, test suites.
Please correct me if I've missed any feature of Anarki's test framework. I did read its code and try it, but I didn't look into other files for supporting functionality.
That makes sense :) I'd love to hear more about what's fiddly about the existing version (I have different versions at http://github.com/akkartik/arc, etc.) and why you need the features (suites, nested suites, failure messages, anything else?)
Please let me know what you think -- email in profile, comment here, open bitbucket tickets, find me on the street^1, etc.
[1] Actually, after writing this, I read your profile, and found you're in Hacker School. I'm in nyc too -- we should meet up sometime. Shoot me an email.
Sweet. I had been wanting to play around with the unit test code too -- i'm excited to see what you've put together.
The oauth utility is also for the LISP contest -- we'll see how far I get over the next few weeks.
Either way I'm planning on uploading a few bits and pieces to Anarki or my own repos over the next couple of weeks. (spent some time on anarki's web.arc, the state machine stuff, oauth, some lazy evaluation stuff, etc...)
Honestly, there are some fiddly bits about the unit test framework I don't like, but mainly I wanted to write one.
I actually applied with it for Lisp In Summer Projects (http://lispinsummerprojects.org/), which is why I haven't announced it -- you're supposed to do the work yourself, without help. And people here like to help out and post code. :-p
Luckily, at this point it's got the main features I want, so I can actually use it.
Did you mean in some other language? It's easy to build a test harness, it's usually the first thing I do with a new language, and invariably just a few lines of code.
(It's not a normal C++ project. I use readable diff directives inside :(..) to add the test harness to the skeleton program at https://github.com/akkartik/wart/blob/cc70d66ee6/literate/00.... But now that this is done, any function I write with 'test_' is automatically run in test mode. Look at the makefile to see how I do that with minimal code.)
Anyways, tell me what language and I'm sure we can get you quickly past this hurdle.
Good luck. I could use one -- I've wanted to use it with Twitter for a while. I started writing one myself, then realized I needed a unit test framework, so I've been working on that. Oh, the perils of a language lacking libraries.
Would you like some help? As long as it's free software, I'd love to assist.