This is IMO true and has been of concern to me; I've tried to ameliorate this by adding packages and 'symeval to Arc-F, but I'm not 100% sure that those aren't just hacks to get around the weakness of the core design ^^
Personally I'd volunteer to take the lead, really fork Arc, and go on with Arc-F. Unfortunately, I'm not at all experienced in actually launching and maintaining a website. Worse, Arc-F can't host news.arc (or a ported version) yet; I'm somewhat redesigning the Arc server because of the lousy and inconsistent design, but I'm kinda stuck on how to handle the continuation server functions bit, which strike me as the dirtiest bits of the Arc Server.
The last alternative - let Arc die - is something we should seriously consider though. Clojure is gaining the popularity that Arc could have had. Like Arc it's a redesigned Lisp (fn and new ssyntax, anyone?); unlike Arc, it wasn't hyped very much for >6 years, its maintainer is still visibly leading the language, and it runs on the JVM. The only advantage of Arc that I see is that it supports both imperative and functional paradigms - and some might argue that this isn't actually an advantage.
Letting Arc die would hurt me a lot, though. Other than the original writers of Arc, I can probably reasonably claim to have made the largest contribution to Anarki (many of the docstrings in the Anarki arc.arc, for example, were by me).
Oh honestly. Perl had the popularity Arc could have had. Then Python did, then Ruby. The fact that the "winner" keeps changing shows that it doesn't matter which one you beat.
I've long since stopped worrying about other languages. If they're genuinely better, they deserve to win. And if they merely have "momentum," they'll ultimately be superseded, just like every other language du jour before them.
I get this feeling that Arc is the language that is just going on by momentum.
Further, I don't think Arc, PG version, is as well-designed as you think.
For example: "code is spec". Apparently the code itself is to be the specification for the language. However, this brings up some questions: for example, does the fact that (ssplit '(1 2 3) 0) return ((1) (2 3)) part of the specification, or is that a bug? http://www.arclanguage.org/item?id=8450 .
Or how about the cute little fact that the PG 'map function can be safely recontinued when you capture the continuation in the mapping function if the given structure is a list, but is not safely recontinuable if the given structure is a string? Is this a deliberate design decision, an oversight, or something you don't specify and so any other implementation can do what they want?
And while tagging allows the programmer to arbitrarily create new types, those new types don't get along well with the builtin functions. I can't build a vector type in PG Arc that will work with the builtin functions. I can't build a quaternion type which I can multiply with a scalar number using '* .
These are design points which have been belabored for years; Brooks in 1975 attacked using "implementation as spec", pointing out that it limits future implementations by forcing them to always use the old implementation, for example.
If arc is continuing by momentum, it's a very different kind of momentum than the momentum languages like Java, Python and Perl survive on. They have momentum in that they have many large and complex libraries and programs written in them which are being actively used to the point where rewriting said software in another language is no small task; and hence most people are interested, not in making a new and better language, but in making the old language better.
Arc has none of this. The reason why it continues is because the people using it are enamored of it for its own sake, not because they depend on it. This is both a blessing and a curse. A blessing, because it means Arc is free to change and improve; a curse, because it means Arc is incomplete and a moving target.
This is one reason why it is important for you to be here: some simple things like the problem with 'splice are clearly bugs, but other things are not. For example, the fact that '(1 . 2 . 3) reads as '(2 1 3) is just something drained accidentaly from mzscheme's reader or is part of Arc? Since you've written Arc, you're the only one to really know this.
We can only suppose.
Perl, Python, and Ruby are successively closer approximations of Common Lisp.
I admire the ideas behind Clojure because it makes a different set of design decisions from Common Lisp. This seems to have even gotten the attention of Common Lisp developers, and those guys are pretty hard to impress.
The focus on immutability, literals for data structures other than lists that share a common "seq" interface, first class functions and closures, multi-methods without OO, lazy sequences, and full fledged macros hit an interesting sweet spot that is not touched by any other language I know. Mr. Hickey has managed to put all of those things together in a way that strengthen, reinforce, and complement one another. That is an impressive feat of language design.
My point is that Clojure is not "just" popular. By making unique decisions about the semantics of the language, and not just improving the syntax over the semantics of an existing language, Clojure may very well be one of those languages whose ideas remain influential long after it stops being popular.
(I'm curious, does Arc innovate in terms of its semantics being significantly different than its predecessors? It seems to have the goal of taking existing Lisp paradigms and
making it possible to express them more succinctly. But I might be missing something important.)
So, even by the criteria you put forth, Clojure might be a language worth watching.
Perl had the popularity Arc could have had. Then Python did, then Ruby.
I will point out that Perl still has the popularity. Python and, particularly, Ruby have dramatically fewer developers and lines of code than Perl. But, then, Perl has fewer developers and lines of code than PHP. So, unless PHP is the exception that proves the rule, the popularity argument is obviously moot. But, I do think there's something to be said for pragmatism. While Perl (or Python, Ruby, etc.) has its flaws, it also has a vast community of people working on solving them...will Perl 6 be ready before arc is usable for a similarly wide array of problems? Seems pretty likely.
One pattern that I observe - you respond only to those points that rebuff you. Rather than proposing solutions and/or accepting that you have been less than clear about your plans for Arc (especially as this is a real community now and not your personal pet project), you have been exceedingly discourteous to your fellow Arc-enthusiasts. I feel sorry for them and happy for myself that I am not part of this farce.
Funny thing is, when I read your essays a couple of years back, I did respect you. Reading stuff like this kind of erodes that dramatically. Good luck pg.
Clojure is on my list. When (if) I give up on Arc It will be the next language I'll learn and use. A lot of libraries from the start. Good performance (the JVM is fast once started). And, most importantly, Rich Hickey follows the language and promotes it. Arc had the great advantage that it had a community of users from the beginning. After its launch, a lot (relatively) of people were already using it. Despite this advantage, Arc hasn't reached the popularity that Clojure has today. Arc had the possibility of being a great language. That possibility has been wasted.
If you want to fork arc, you'd better change its name to break with the past. Make something new. I like the ideas behind snap. I only wonder how much time it would take to have a usable system. Sadly, I'm not able to really help :(
Just in general - is there anything in arc which gives it a big edge to programmers when compared to clojure?
Here are some of the differences, but I can't tell if one of them is crucial. I listed three below for which I've no clue what the impact is.
http://clojure.org/lisps
* The read table is currently not accessible to user programs
* Keywords are not Symbols
* Symbols are not storage locations (see Var)
* immutable data and first-class functions
* *first* is clojure's *car* ;)
> Just in general - is there anything in arc which gives it a big edge to programmers when compared to clojure?
Mutation. It's one thing to allow functional programming. It's another thing to force it.
The only thing constant is change.
> * The read table is currently not accessible to user programs
Neither does Arc, although Anarki does allow redefining of 'ssyntax and 'ssexpand, which almost gives you the same thing.
IMO not giving access to the read table is a good thing. There are very subtle problems with this, starting with: the read table affects all code loaded after the readtable modification.
It affects them whether or not the code was written by you, and whether or not it was written with that readtable definition in mind.
This can cause unfortunate library breakage when two libraries try to modify the same readtable entry; the poor user is thus left at the mercy of which library loaded last.
In fact Arc-F has revoked Anarki's feature which allows 'ssyntax and 'ssexpand to be modified; redefine them all you want, Arc-F will use the built-in traditional 4 ssyntaxes : ~ ! .
HOWEVER, there are currently two reserved context metacommands which will eventually allow ssyntax redefinition at the level of the individual file: 'import-ssyntax and 'interface-ssyntax.
The important thing is that they are context-based, and because they are context-based, they are not global and they will (in general) affect only one loaded file.
> * Keywords are not Symbols
Unimportant - salt to taste.
> * Symbols are not storage locations (see Var)
> * immutable data
Oh, Clojure is not quite completely immutable. Clojure has refs, and they can be mutated within the context of a 'dosync form. Kind of like the Haskell "do" syntax. It's more that Clojure defaults to immutability, and has special syntax to define portions that are imperative.
Arc3F has a launcher script for Linux which is supposed to work with any sufficiently Unix-like system (it's tested and works with GNU/Linux, specifically Ubuntu Hardy Heron; AFAIK the others here don't have problems, so it'll probably work with a large enough percentage of GNU/Linux systems). It also has a launcher batch file which is supposed to work with Windows; eds and b0R_ report that they have managed to run Arc3F with that batch file.
You are not supposed to use mzscheme -m -f with Arc3F, although I haven't actually tried; it might work.
2. Arc3F is the latest (and so far, only) version of Arc-F. Arc-F is a fork of Arc I created, featuring some neat stuff, particularly packages. The page you linked to is the Anarki repository, which contains a very modified version of Arc2.
3. When we say "Arc2" or "ArcN", we refer to the official PG release. Anarki is the community's repository of Arc, and the community version of Arc that is based on the latest ArcN. Arc-F is a more recent fork of Arc; it includes a full-fledged symbol-based package system and a partially rewritten standard library.
4. None at all. Anarki accepts all patches. Arc-F accepts all patches too, but Arc-F has very much larger differences to ArcN than Anarki.
5. None from me, I'm afraid; I'm a VIM guy ^^
6. Download rlwrap. You should be able to get it by:
sudo apt-get rlwrap
If you have rlwrap installed and use the arc.sh launcher, or the arc-f/arc launcher script, the launcher script will automatically use rlwrap.
Why does the link near the top of the forum (subj: "Arc3F Released..." (http://arclanguage.org/item?id=8270)) link to the Anarki online repo, instead of some Arc3F repo?
BTW, how do I use the arc.sh launcher? I don't see that file anywhere in my arc2 distribution.
> Why does the link near the top of the forum (subj: "Arc3F Released..." (http://arclanguage.org/item?id=8270)) link to the Anarki online repo, instead of some Arc3F repo?
The Anarki repository was first set up early this year by nex3 on his own server. It was set up such that everyone can write to it - no credentials needed, just clone the repository and you can start pushing on the Anarki repository.
Some time after that he decided to move the repository onto github.com. Even on github.com, the Anarki repository is still fully open.
However, none of the rest of us can figure out how to make our own github-based repositories fully open (i.e. publicly writeable).
I'll probably move Arc-F into its own repository if and when I figure out how to make it fully open.
> how do I use the arc.sh launcher?
It's on the Anarki distribution. The Arc-F distribution is just "arc" without the .sh . ArcN does not have a launcher.
Odd about the github setup issue. Guess I don't quite understand. Seems like someone could just email nex3 or someone at github to get the correct config incantations...
Also, it's confusing that the Description of the project at github doesn't say "The community's extended version of Paul Graham's Brand New Lisp". Currently, it looks like that's where pg keeps the source.
I'm sort of around-ish. I don't really do anything with Arc anymore, but I occasionally browse the forums (e.g. now). I'll certainly reply to any direct questions.
> However, none of the rest of us can figure out how to make our own github-based repositories fully open (i.e. publicly writeable).
The easiest way to host a open source repository is probably http://repo.or.cz/, which allows setting up a "mob" user to allow wiki-style pushing like we currently have under Anarki. Obviously the same is possible in github, but I don't know how to set it up.
> Arc's lack of support for binary data is making it tricky.
Err, Anarki and Arc-F have 'readb and 'writeb functions for this - don't they work with binary data?
>
1. provide a means to load modules
2. make sure they only get loaded once
4. avoid changing the global namespace
5. keep each module in a safe and clean execution environment (isolation from other modules)
6. be recursive (modules can load sub-modules without disturbing other modules)
7. allow modules to export an interface
11. specify dependencies between modules.
Arc-F's package system does the above.
8. allow modules to declare variables with module-only scope
Technically doesn't do this, but globals are named with a module-specific name.
9. give the user of the module a way to 'include' features from the module (that is, map them into its own namespace)
Somewhat gives this with the (import ...) metacommand, but this particular metacommand is not very user friendly.
10. not get in the way of other module systems, or even multiple instances of the same module system
Well, Arc-F's packages are pervasive and affect everything. LOL.
One thing I have problems with is that symbols in arc-f don't have the most obvious string representation: e.g. (string 'type) ==> "<arc>type", (string 'atype) ==> "<User>atype". This gives me quite a few troubles while developing artk (http://github.com/stefano/artk/) because it heavily relies on the string representation of symbols to make a bridge between Arc and the TCL interpreter. As a consequence I have to use a lot the 'unpkg function.
The problem I'm having with binary is where to store it once I've read it. You can put characters in a string, but where can you put binary data? Currently I'm using a list of bytes, which is ok but might be a little RAM intensive for large files.
General computer philosophy.. shouldn't the structures that work well with CPU's be present in the language, and used by the language, but not neccesarily accessible by humans, and the structures that work well with humans be the ones that are accessible to humans.
So while anarki might need to support arrays internally for efficiency, they need not neccesarily be part of the language as far as the users can tell.
If the above is true, then right now the implementation of things that are efficient for the language when it wants to communicate with the cpu are of a lower priority than the things that are efficient for the communication between the user and the language.
I think we can have the best of both worlds. I would love Arc to have an intelligent compiler that figures out the best representation for your data, but I would also like access to the low-level data types.
Why? Because Lisp is supposed to be a reprogrammable programming language, where the user can do anything the compiler can do. If the user has access to the underlying bits and bytes, then they can implement new representations of high-level structures, rather than relying on the compiler writer. In fact, I would argue that Arc should only provide low-level structures in the axioms, and then high-level ones can be implemented on top.
If I wanted to represent a matrix of objects.... say a world populated by virtual creatures... I might prefer to predefine the size of the world and identify creature locations using numeric coordinates. I might then want to use an array of arrays to represent the world ^^. I might even abstract away the position of an object using a "location" type composed of a pair of numeric coordinates and a reference to the world, then have "north" and "east" etc. functions to get locations in those directions. Then I might get the reference or set the reference of a location object and thus query and/or change the state of the creatures in that world.... ^^
In Arc-F for example I might use:
(using <vector>v2) ; vector and vector-of
(def make-world (xwidth yheight)
(apply vector
(w/collect:for i 0 (- xwidth)
(collect:vector-of yheight nil))))
; create a location type
(def location (world x y)
(annotate 'location
(list world x y)))
(defcall location (r)
(let (world x y) r
(world.x y)))
(defm sref ((t loc location) val)
(let (world x y) (rep loc)
(sref world.x val y)))
; 0---> INF
; |
; |
; v
; INF
(def south (loc (o step 1))
(err "'north and 'south expect a location"))
(defm south ((t loc location) (o step 1))
(let (world x y) (rep loc)
(location world x (+ y step))))
(def north (loc (o step 1))
(south loc (- step)))
(def east (loc (o step 1))
(err "'east and 'west expect a location"))
(defm east ((t loc location) (o step 1))
(let (world x y) (rep loc)
(location world (+ x step) y)))
(def west (loc (o step 1))
(east loc (- step)))
I should put some more work into it. The good news is that I just found a nice and simple editor that plays well with arc-f on windows (LispIDE - http://www.daansystems.com/lispide/)
btw. arc-f arc.bat doesn't play nice yet with "Program Files" type of directories. Works fine in C:\arc-f.
Got this error:
> default-load-handler: cannot open input file: "C:\Program" (The system cannot find the file specified.; errno=2)
We could give only lists to the user, and implement them internally as arrays when they are frequently used with indexed access and with lists when they are mainly used with car/cdr. Not an easy thing to implement, though.
I made a suggested implementation of lists as unrolled lists which preserves the use of 'scdr on the Arc Forum a long time ago. http://arclanguage.com/item?id=4146 . Basically it would be effectively arrays.
The problem with the proposed implementation however is that the "cons pointer" is a data structure of at least two cells (a pointer to the root of the underlying array, which includes a pointer to the cdr-table somewhere, and a pointer to the actual entry within the array).
However recently I thought of a method by which all that is necessary would be a (probably tagged) pointer to the actual entry within the array. This would require tagged pointers (i.e. no Boehm-Weiser!).
Basically we would define a tagged pointer type which, when found in a list-as-array, would not be a valid 'car of that entry, but rather would be a pointer to an object containing the real 'car and 'cdr for that object. It might be possible to also use a tagged pointer (potentially the same tag, but say with a null pointer) to denote the end of a list.
Let's call this invalid tag a "NON_CAR_TAG", and let's call the tag for a pointer to an array-as-list-cons-cell a "CONS_ARRAY"
Basically a (list 1 2 3 4) would be represented with the array:
[0] INTEGER(1) // tagged with an INTEGER
[1] INTEGER(2)
[2] INTEGER(3)
[3] INTEGER(4)
[4] NON_CAR_TAG( NULL ) // null pointer
A 'cons object would either be a (potentially nontagged) pointer to a real cons cell, or a CONS_ARRAY() tagged pointer to an entry in an array such as the above.
Now suppose we have the operation (= foo (list 1 2 3 4)). 'foo would then contain a CONS_ARRAY() tagged pointer to the above. Suppose the pointer to the above array is 0xDEADBEE0. 'foo would then be CONS_ARRAY(0xDEADBEE0).
Now suppose that a cell is exactly 16 bytes (just an example for easier reasoning). So (cdr foo) would be CONS_ARRAY(0xDEADBEF0), (cdr:cdr foo) would be CONS_ARRAY(0xDEADBF00), etc. Basically, 'cdr would first check if the input is a CONS_ARRAY() tagged pointer, and just add 0x10 (or the cell size). If the resulting address points to an entry that happens to be NON_CAR_TAG(NULL), it should return a NILOBJ, otherwise it returns the result of the addition.
Now, suppose we then do (scdr (cdr foo) 42). 'scdr should first detect if the the pointer it is given is a CONS_ARRAY() tagged pointer. If so, it determines if the value being pointed to is a NON_CAR_TAG() or not. If it's a NON_CAR_TAG(), it gets the underlying cons cell pointed to by the NON_CAR_TAG and modifies that. Otherwise, it allocates a new cons cell, populates it with the existing 'car and the new 'cdr, tags the cons cell pointer with NON_CAR_TAG(), and replaces the entry:
+---------> CONS: A INTEGER(2)
[0] INTEGER(1) | D INTEGER(42)
[1] NON_CAR_TAG( * )
[2] INTEGER(3)
[3] INTEGER(4)
[4] NON_CAR_TAG(NULL)
Note however that it has a drawback that l.index is still O(N) T.T
I could, if only I could figure out how to automatically give write access to the repository to everyone, the way Anarki is always write-accessible to everyone. T.T Bit of a hassle to have people request for access and then have to grant it to them.
Somewhat annoying, as doing a 'diff' is probably not enough.
It'll also become slightly messy if pg's statement from a month ago becomes true, and there will be new versions of arc coming out in october / november. If we pick up features from different versions of arc, would the changes compared to arc2, as well as the changes compared to arc3 need to be documented.
I guess the value of forcing good documentation of the changes is that it becomes easier for pg to distill a new arc version out of the mutants that the community is spawning, as they'll have their features well documented.