It doesn't handle use of complex expressions in functional position very well - no matter how long they are, it prints them on one line. An example is the source code for 'each:
But yes, that is exactly the fix, and also why I wrote it that way. Unfortunately, I'm beginning to think that the order of the function arguments could have been planned a bit better. All of those numbers can be rather confusing.
Feel free to push it to anarki's master branch, which is for the moment still arc2-based. I haven't yet ported the extended make-br-fn form to arc3, so I'll have to do that before I can forward-port this to arc3.
Which branch should I be working on if I want to port things to arc3? So that we can eventually move Anarki's master branch over to arc3? is it arc3.master? arc3.extras? You seem to have a separate branch for the help stuff. Is that just temporary while you try and get it to work?
http://arclanguage.org/item?id=9777 explains the details. In brief, hacks should be made relative to the official branch, and then tagged appropriately and merged into arc3.master when they're finished.
The branch for help is not really temporary. I already have 'help, 'src, etc. working. It's there because it's a pretty large subsystem and it's useful to have a branch to track changes.
I'm not 100% sure what that means. I understood that I should co the origin/official branch, make the code I'm porting work with that, but I don't get what I'm supposed to do next. Make a commit, tag it, and merge it over? stash the changes, co arc3.master, apply the stash, make a commit and tag it?
As for the help branch, am I right in understanding that it's just for keeping track of the development of the help tools, and that master also contains all of the changes?
Checkout official (`git checkout official`). Now, switch to a temporary branch (`git checkout -b tmp`). Make your changes. Check that everything works. Commit the changes (`git add ...; git commit -m "..."`). Tag it (`git tag shader.ppr.0`). Then checkout arc3.master and merge in your tag (`git checkout arc3.master; git merge shader.ppr.0`). (At this point the temporary branch can be deleted.)
That's the simple way to do it, anyway. You can in fact make changes which are "relative to" official even if you actually do the work in a temporary branch derived from arc3.master, by using git rebase or git cherry-pick, and I'd highly recommend learning how to use these and other advanced git commands. Also, if you want or need other hacks, you can merge them in after switching to a temporary branch but before making your changes.
And yes, the arc3.master branch does contain all the changes in the arc3.help branch; whenever I change the help branch I merge it into the master branch as well. Note, however, that the reverse is not true - the help branch contains only the modifications needed to get the help system working, and not the other changes in the arc3.master branch.
Does git not check out tags unless they are requested? Otherwise wouldn't all of those changes stay on the official branch as well? Though I suppose the official branch won't be pushed to by most people, it would still clutter the local version, wouldn't it?
Using publisher rather than author as the prefix for a patch makes sense. However, upon reflection, I'm not going to rename the tags I published to anarki from "anarki.hack.0" to "rntz.hack.0"; I think using "anarki" as the publisher makes as much sense as using "anarki" as the author. In particular, if I publish a patch as, say "rntz.simplify-halve.0", then it would be rude for someone else to publish a patch as "rntz.simplify-halve.1", because they're not me. So they'd have to do it as, say, "johndoe.simplify-halve.0". But this destroys the sense of progression, from release 0 to release 1. It's the difference between contributing to a project and forking it. By saying that a patch is published by "anarki", a publicly-writable project, I'm inviting people to improve it and release it under the same moniker - the same way anarki itself, a publicly writable community repository, allows people to improve on the works of others. So I think using "anarki" as a community label for publishing patches is still a legitimate idea, because it stands for a useful distinction.
I think there's no problem with that as long as you have some mechanism that helps people not publish hacks out of Anarki that end up with the same label.
For example, I haven't tried it, but if git prevents me by default (if I don't use a force option or something) from pushing a tag to a repository that already has that tag, and you're using tags for the label, then that would do the trick.
I've pushed this hack (along with some other initial work on updating anarki) to my fork of anarki's official branch (http://github.com/rntz/arc) under the tag `rntz.$.0'. (Note that merely git clone'ing that repo won't get you this hack; I'm organizing my work along the lines of CatDancer's "Sharing arc hacks", and it's published as a tag only thus far.)
DRY (Don't Repeat Yourself). I'm generalizing an existing function. Doing it this way keeps the code shorter, and in the event that 'ac-qq1 has a bug, then 'ac-qqx probably does too, and if I do it this way then when I (or someone else) tries to merge fixes for 'ac-qq1 they'll get a conflict indicating that they need to modify the fixes for 'ac-qqx rather than having it silently succeed, leaving bugs in 'ac-qqx.
Er, note that I said stable and official branches, not to the master branch. The master branch is what most people using anarki use. The official branch just tracks pg's released arc tarballs. The stable branch incorporates bugfixes and some simple additions (the arc.sh script). (If you knew all this already, and were just asking whether merging with the stable branch worked, yeah, it should just work.)
Switching over the entire master branch is essentially impossible, as has been discussed before... although there aren't many incompatible changed between arc2 and arc3, there are enough, and moreover, there are enough differences between arc2 and anarki that integrating the changes to arc3 wholesale into anarki is difficult. Anarki simply has so much in it - bugfixes, hacks, additions, libraries, pet projects, and even reimplementations.
The solution to this is for people to port the parts they care about separately. That way, the best parts of anarki will get ported and the cruft that no-one is maintaining will be expunged. I'm working on the help/documentation subsysem at the moment, and after that, the ability to define call behavior for tagged objects, and the many extra functions and macros anarki adds. I'll probably be making a post sometime soon about what I see as the way to move forward, but for now, anarki's master branch is unchanged.
Hmm. Have you started a new branch that is the official target, so that we're all working together instead of separately as we port our favorite things over?
I wouldn't mind helping you with the help/documentation stuff as I wrote some of it (src and the current version of fns), and it's probably my favorite part as well. Right now I'm a bit busy working on a new and improved ppr so that the src function actually returns reasonable looking source code ;)
I have been thinking about a new way to do the source code storage for src. I noticed that every time scheme makes a lambda, it remembers where in the code it was created. That means that the information about where the source is is associated with the lambda object, not the name. What if we modified the way that ac-fn worked, so that it associated each fn with its source code? That way all procedures, macros included, would have their source code available for inspection.
That's the idea, the hard part is making it work, and making it work without leaving the old definitions behind when the lambda no longer exists (temporary code, etc.) Any ideas? Maybe we could use vectors like the tag system? That would make it easy to look them up in a table, but doesn't fix the problem of garbage collection. Also, hacking it on at such a low level means that it probably captures the state of the source code after all of the macro expansions, so it may not be such a good idea after all.
the hard part is making it work, and making it work without leaving the old definitions behind when the lambda no longer exists
I don't know about the first part, but for the second, what you want is a weak hash table (http://download.plt-scheme.org/doc/372/html/mzscheme/mzschem...) with the lambda's stored as the keys. The weak hash table holds the keys "weakly", which means it doesn't prevent the keys (the lambda's) from being garbage collected, and when they are garbage collected, the related value is dropped from the table.
This... isn't really an explanation. Lexical bindings of things are also determined at compile time - just not the values they'll be bound to. So you can't have a locally-bound macro, but you can let locally-bound symbols shadow macros, and there's no real reason not to.
(If that first sentence doesn't seem to make any sense to other readers: What variable or relative stack position a variable will be stored in in C is determined at compile time, but the value is not. Obviously the backend isn't the same here, but the same concept holds, at least the way arc is currently implemented; in particular, there is a parameter to 'ac that indicates what symbols are lexically and locally bound. In Python, on the other hand, the local environment is accessible at runtime, so lexical bindings are not always determinable at byte-compilation-time.)
Doing symbol macros by hijacking the ssyntax-expansion process seems hackish, and I'm not sure if it would work. Multibyte ssyntaxes could be interesting, though.
In arc3, pr."foo" and a!(b c) complain about bad ssyntax, so that bug at least has been squashed. Making them do "the right thing" would be pretty cool but would require some hacking of the reader - at the moment, ssyntaxes aren't expanded by the reader but by the arc compiler, which compiles symbols with ssyntax in them into special forms, so for example:
arc> 'foo.bar
foo.bar
arc> '|foo.bar|
foo.bar
If you wanted to handle ssyntaxes that weren't just special symbols correctly, you'd need to hack on the reader, which would change the above behavior to:
arc> 'foo.bar
(foo bar)
arc> '|foo.bar|
foo.bar
This might break some code, although probably not any code distributed with arc itself.
It doesn't seem too bad, hackwise, though I think it might have issues with layering new definitions on top of old ones if there isn't a way to remove them from the list.
What code would having that improved reader break?
Any code that relied on the ability to represent the symbol whose name is "foo.bar" (or any symbol containing a dot) as 'foo.bar rather than needing to wrap it in pipes as '|foo.bar|.
Anarki has a very similar thing, lib/dynvar.arc, authored by yours truly. It defines 'let* and 'with* and 'withs* (by analogy with the corresponding lexically-binding forms) instead of just 'dynamic, and 'dynvar instead of 'declare-dynamic, although the semantics differ a little - my forms can be used with any variable, and essentially amount to setting a given place within the dynamic extent of a certain region of code and resetting it afterwards, hence the threadsafety issues; and 'dynvar sets a variable to a thread-local cell. So it separates the issue of threadsafety from that of dynamic scope, which may or may not be handy.
There is a small bug in the code as written - it uses 'protect instead of scheme's 'dynamic-wind, so a multiply-resumed continuation could break it.
You may be interested in my "autocall" patch, that I'm renaming to "defvar" and will be writing some documentation for soon. It extends the Arc compiler to allow you to provide your own implementation for a global variable, so that you can type "a" instead of "(a)".
Sounds vaguely similar to symbol macros, which are a more general facility in which you can make a given symbol expand to arbitrary code (rather than just the invocation of a given symbol). I'd be more interested in seeing a hack to implement those in arc; you can do some interesting things with them
In this case, I honestly don't find that writing the extra parens is much of a bother to me (and I have used dynvars quite a bit in one of my projects) - it actually helps remind me "oh hey, this is a dynamic variable". It's like an enforced naming convention; "(foo)" is just as succinct as 'foo, really.
Edit: dammit, that's supposed to be 'foo surrounded by stars - the CL dynamic variable naming convention. Unfortunately it's misinterpreted as italics. Is there some way around this?
pg's convention in the arc code is to just have one star after the name, instead of one on either side. Less typing, and it doesn't conflict with italics ;)