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.
In the definition of 'automaton, you have the macro call (mkrule _). I don't think you want 'mkrule to be a macro, because I don't think you actually care about the symbol _. The first thing I suggest is to replace "mac mkrule" with "def mkrule".
After this change, I'm still not quite sure what your code is trying to do (I haven't clicked your links yet), so I'll try some example cases:
For one thing, it looks like you might want that (car (1 (2 3) (4 5))) to be just 1. You can fix this by changing (car ,i) to ,(car i).
Since you end up with function calls like (3 (cdr str)), it looks like you're trying to make several functions under the same scope (using Anarki's 'withr/p), and it looks like 'str is a variable that contains the remaining inputs of the automaton.
In this case, I recommend changing `(list (cdr ,i) (fn ...)) so that it's (list (cdr i) `(fn ...)), since you probably didn't want that 'list symbol in the 'withr/p call.
To make this easy to test, here's the complete code, with Anarki's definition of 'withr/p and my updates to 'mkrule:
; a 'with that works for defining recursive fns
(mac withr/p (bindings . body)
" Scheme's 'letrec.
See also [[withr]] [[where]] "
`(let ,(map1 car bindings) nil
,@(map [cons 'assign _] bindings)
,@body))
(def mktransition (tn) (list (car tn) (list (last tn) '(cdr str))))
(def mktransitions (ts)
(accum accfn
(each x (map1 mktransition ts)
(accfn (car x))
(accfn (last x)))))
(def mkrule (r)
(let i r
(list (car i) `(fn (str)
(if (empty str) t
(case (car str)
,@(mktransitions (cdr i))))))))
(mac automaton (i r) `(withr/p ,(map1 [mkrule _] r) ,i))
Seems to work!
(= matches-aabb
(automaton step-a
(
(step-a
(a step-a)
(b step-b))
(step-b
(b step-b)))))
arc> (matches-aabb '(a a a a b b b b))
t
arc> (matches-aabb '(a a a a b b b b a))
nil
arc> (matches-aabb '(a a a a))
t
arc> (matches-aabb '(b b))
t
arc> (matches-aabb '())
t
arc> (matches-aabb '(b a))
nil
arc> (matches-aabb '(c))
nil
Now that I look at your Gist, I realize I could have saved myself some time figuring this out. :) I also realize you were aiming for a slightly different interface:
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.
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.
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.
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...)
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.
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?)
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.
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.
Good error reporting is pretty disagreeable to me, lol. :-p
I think Arc's main advantages over Scheme, once all the Arc-like naming conventions and macros are in place, are setforms, defcall (not in pg's Arc), and the ssyntaxes (a:b c), a.b, and a!b. Going by the examples, Rark has setforms, and its ability to unwrap data structures using function calls indicates defcall wouldn't be hard to add if it isn't there already, but I don't see anything about ssyntax. I've been meaning to download and run Rark to see if ssyntax support is actually there after all.
The abstract "Scheme" I'm talking about might have a certain advantage over Racket, but I might just be doing it wrong: Is possible to write a macro and use it in the same file? I've had to break my utilities into three files just to have multiple layers of macros. I'm interested in seeing whether Rark makes this any easier.
It's currently missing extensible setforms, but all the standard ssyntax and brackets should work. They're detected and expanded (awkwardly right now) at the reader level.
"If you looked at it closely, I made many changes in the spirit of getting something running that PG (and you!) would likely not agree with."
I didn't see the repo while it was online, but I've always looked forward to Arc (or at least Anarki) becoming usable as a Racket language at some point, even if it were an awkward fit. Just how disagreeable are we talking, here? :)
"But there's a reason lisp does seemingly the wrong thing. According to the spec, nconc skips empty arguments (http://www.lispworks.com/documentation/HyperSpec/Body/f_ncon...) Reading between the lines, I'm assuming this makes sense from a perspective in lisp where we communicate even with 'destructive' operations through their return value."
This isn't just an idiomatic thing. Since nil is immutable, (nconc a '(34)) couldn't change a if it tried.
And whereas Python's list.append() mutates a single object, Lisp operations like 'nconc and 'nreverse destructively create a whole tree of objects. Particularly in the case of 'nreverse, the new tree's root isn't specified to be any particular object the caller has seen before, so the caller has to get a reference to it somehow: as the return value.
Incidentally, the spec for 'nconc leaves less unspecified, so the programmer doesn't actually need to use the return value. Given a non-returning version, they can reconstruct a returning version like so:
Yes, I was phrasing it poorly. I meant that since just reusing the binding sometimes doesn't work, the idiom has evolved to always rebind. Even for non-nil lists, and even for destructive operations that are safe to just operate on like nconc. But I'm not a huge expert on what the idioms are :)
Both '= and 'def can modify a variable in the caller's local scope. This is something a normal function can't do.
(def my-len (lst)
; Introduce a local variable `n'.
(let n 0
(each element lst
; Modify that variable.
(= n (+ 1 n)))
n))
(Technically 'def only seems to be intended for the global scope. It prints a warning when the global variable is already bound, even if it actually modifies a local variable.)
---
"Is there a deeper reason for these irregularities, or is it just convenience?"
The syntax of languages like Arc, Lisp and Scheme is actually a bit more irregular than it looks: The code (a b c) usually means to do a function call, but this isn't true if "a" is the name of a special form or a macro. Special forms are how the language provides structured syntaxes other than function calls. Macros are user-defined special-form-like syntaxes that specify a way to translate ("macroexpand") their syntax into some already-supported code.
In Arc, both '= and 'def are macros provided with the language. They act as shorthand for using Arc's 'assign special form.
Kernel is a different kind of language. It goes back to lisp's roots a little, and lets users define syntaxes based on a way to interpret them at run time. Since the user can write their interpretation code however they want to, it's challenging to predict what these programs will do until they execute, which is why nobody (I think) has managed to write a good optimizing compiler for Kernel.
---
"Why are lists compared via `iso' but strings are compared via `is'?"
This is a very irregular part of Arc. You can compare lists using either operator, but 'iso does a deep comparison and 'is compares by reference. However, 'is actually special-cases strings and compares them by their contents, just like 'iso.
I think this choice was made because strings aren't usually modified. Arc lets you mutate a string if you really want to, but it's not a very commonly used feature.
---
"Is it because strings are a symbol but lists aren't?"
Technically, string and symbol are separate data types.
Technically, the empty list (nil) is a symbol. :)
If your point is that Arc's strings are interned like symbols, that's probably not true, since they're mutable. It's really an awkward special case in the language.
I've cast my vote for Rainbow. For the most part, I've only ever used Arc as a topic for discussion, as shallow inspiration (e.g. naming conventions), or as a platform for language-implementation-independent libraries I rarely used. But there have been two exceptions:
I briefly maintained my website's static site generator as an Arc+Penknife project. It could run on Arc 3.1, Anarki, and Rainbow, but I preferred to run it using Rainbow for speed.
At one point I wanted to fill a gap in our Arc-in-the-browser discussions, and I especially wanted to show there was no innate reason for ClojureScript to omit 'eval, so I spent a lot of effort porting and adapting Rainbow to make Rainbow.js. I figure this means I have a special investment in Rainbow, even if I don't run Rainbow or Rainbow.js for any serious business.
---
"Do people think I should add even deeper spin-offs like nulan and lathe and blade?"
Lathe and Blade shouldn't make it on this list.
Lathe is a suite of language-implementation-independent foundational Arc libraries, some of which specifically make it easier to write language-implementation-independent Arc code. I suppose you could program for Lathe as though it's an Arc platform, but that just means polyglot programming for several Arc platforms all at once.
Blade was a language project that never got off the ground, and it pretty much didn't have anything to do with Arc.
"I think we should make anarki the default; 3.1 has some bugs and gotchas. Even if the docs will only support arc 3.1 for starters, there's still value in combining them with anarki, I think."
Seems like you and I disagree about this at the moment. :)
---
"I love the favicon :)"
Eh? Isn't that the favicon that comes bundled with Arc? (Hmm, I see the "ref" pages have no favicon at all. O.o )
As opposed to the Arc 3.1 favicon, I prefer the version currently used here on arclanguage.org. Its colors seem to have been tweaked to address the blue-and-black contrast issue identified on the original logo thread: http://arclanguage.org/item?id=9438
"There's no value in being strictly compatible with an old, buggy release that never guaranteed compatibility in the first place. We should instead focus on a live version that's getting fixes over time, whether it's anarki or arc-nu or rainbow-js or something else."
If we agree it's a fix, then we can document it the correct way and just take note of which bugs exist in which implementations. Arc 3.1 is just one implementation for these purposes.
If someone wants a real reference implementation to test against, they can use a version of Arc that has relatively few bugs, such as Anarki's stable branch or your curated Arc repo.
Like you, I believe the Arc language should be free to change in ways that break existing code. However, I think some of the Arc community's most large-scale projects have been the multiple implementations of Arc, and I think that's worth representing on the website, even if the community evolves to have some other focus later on.
---
Speaking of choosing a canonical, main-documentation-worthy variant of Arc, I've always been reluctant to develop upon any existing implementation of Arc, due to licensing.
Now that I take yet another look at the Artistic License 2.0, I think it isn't nearly as complicated as I've interpreted it in the past. It's still odd, though: I think technically anyone can make closed-source products out of Arc, Anarki, Arc/Nu, Rainbow, Rainbow.js, Jarc, etc. as long as they give their source code to Paul Graham and Robert Morris in private (per section (4)(a)).
I'd prefer to use a more generic permissive license, something that obviously permits distribution of closed-source binaries, rather than being quasi-permissive depending on the participation of pg and rtm.
"Like you, I believe the Arc language should be free to change in ways that break existing code. However, I think some of the Arc community's most large-scale projects have been the multiple implementations of Arc, and I think that's worth representing on the website, even if the community evolves to have some other focus later on."
I'm not sure how to interpret this :) Were you suggesting that we should highlight things like arc-nu and arcueid? I'm totally supportive of that. It didn't occur to me to want incompatible variants to steal all the thunder from compatible variants -- especially since I would like to be utterly oblivious to compatibility :) Or did you mean something else?
(At the risk of unnecessarily repeating myself,) I am only opposed to linking flatly to http://ycombinator.com/arc/arc3.1.tar (die! die! :) without any provisos or qualifications. We already have a frontpage for arc3.1.tar; we don't need another.
"Were you suggesting that we should highlight things like arc-nu and arcueid?"
Well, I'm suggesting that they share documentation for their common features. If that sharing gives them more or less prominence on the site, I don't mind either way.
I think author intent matters here. If a new so-called "Arc implementation" comes along, sometimes it'll sacrifice improvements for the sake of compatibility (arcueid), and sometimes it'll sacrifice compatibility for the sake of improvements (Semi-Arc). I think this will correlate with our ability to share documentation between projects.
Jarc is an interesting case. It shows how subjective I am: Jarc changes the treatment of unbound variables to make it easier to call Java methods, but this doesn't affect most working Arc programs. Jarc doesn't support continuations, but it would if it could. I consider Jarc to be on the side of compatibility, but maybe only because I've found it easy to write Arc programs that work on Jarc despite these differences. Maybe I would have judged Semi-Arc the same way, if only my programs didn't rely on quite so much hygiene violation and ssyntax manipulation.
---
"I would like to be utterly oblivious to compatibility :) "
Yeah. Even though I recommend sharing documentation, I don't look forward to splitting hairs in what amounts to a standardization process.
I see it as work too. Maybe we should reject this rational thinking and focus on something we like.
Personally, I like the idea of jumping ship to Arc/Nu (or merging!). Then we can port the Arc/Nu compiler to Arc/Nu and extend it to compile itself to every platform; who needs other implementations? :-p As I understand it, Arc/Nu has a fully reorganized codebase and very few entrenched users, so it's reasonable to refactor it again and again.
Arc/Nu has a "3.1" folder and a "nu" folder, so the website could introduce the Arc 3.1 documentation as though it's really just documentation for a compatibility mode. ;) Meanwhile, anyone who has a passion for consistency can work on documenting this mode in the same way I described above. :-p
Come to think of it, I might just be outlining more and more work. If Arc/Nu somehow becomes a vibrant community project, it's design by committee, right? I'm going to get some sleep.
"Interesting, I hadn't paid attention to the licensing terms. I thought anybody could do anything with the code, period."
Whoops, you just reminded me it isn't that bad. :) Per (4)(b), a closed-source project (or a project under a different license) is just fine as long as it doesn't interfere with a separate Arc installation and it doesn't call itself "Arc."
Playing out some scenarios...
Theoretically, I could invoke (4)(b) to continue development of Rainbow.js under the MIT license plus a few restrictions. In particular, any forks of Rainbow.js could not be named "Arc" or interfere with Arc, but they could be named (and/or interfere with) "Rainbow" or "Rainbow.js."
Interestingly, the Artistic License 2.0 grants an explicit patent license for the Copyright Holder's patents, but not for the Contributors' patents. Not that this is necessarily a problem; I like the MIT license, but it doesn't specifically mention patents at all.
It seems like I'm now okay with AL2.0. Effectively the only thing it prohibits is using the name "Arc" without respecting the original creators. That condition would pretty much be ensured by trademark law anyway, if Arc were a product being sold.
P.S.: I'm not a lawyer. As if that weren't enough, I've demonstrated an ability to misunderstand this license over and over and over. :)
I like the idea of describing Arc 3.1 in the main docs. This way the docs can describe the Arc features people have already strived to keep consistent in projects like Jarc, Rainbow, Arcueid, and Arc/Nu. If other libraries or language variants need their own subpages, those can spring up as necessary. :)
---
A project like this should probably use an "arclanguage.github.io" repo rather than some other repo's gh-pages branch.[1]
The arcfn static site generator may lead to some hassle. The generated website artifacts need to be pushed to the master branch, so they'll be the first thing someone sees when they delve into the repo to make a wiki edit. GitHub goes out of its way to make it easy to edit a repo as though it's a wiki[2], but that method of update won't trigger a very expressive build language[3], let alone anything that supports an Arc-based generator. Unless we have another server that does builds in response to a GitHub post-receive hook[4], in which case why not host the website there instead?
To use a custom generator, or to use Jekyll directly... both of these choices seem to have problems.
Another option would be to do keep Arc code inside <script> tags and run it with something like Rainbow.js, but search engines probably wouldn't index any content generated this way.
Hopefully someone here will be more optimistic about these ideas than I am. ^_^
Thank you for your wonderful ideas, I learn more about github services. :)
Some quick thoughts:
Can we split arcfn docs into two parts: tutorial and reference.
The tutorial part can integrate with current Google Site wiki contents, and can be renderred by Jekyll so it can be more like a wiki.
And the reference part need to be generate locally and then push the static html to the repo.
All those two part can reside on "arclanguage.github.io" repo.
The repo structure may be like this:
arclanguage.github.io/
|-- index.html
|-- tutorial/ ; or move all stuffs to the top dir?
|-- docs/ ; static html. (reference instead of docs?)
|-- _docs/ ; source of docs
|-- anarki/
|-- jarc/
|-- ...
Also, we can use a post receive hooks to generate docs directly.