Arc Forumnew | comments | leaders | submit | shader's commentslogin
1 point by shader 6008 days ago | link | parent | on: (draft) Using Git Commits for Hacks

I would think that Git's concept of branches might be more useful for separate libraries than individual commits, but I could be wrong.

-----

1 point by CatDancer 6008 days ago | link

Branches are useful for developing libraries and for following along library development. It was a pain trying to pull in different libraries from different repositories by referencing them by branch name, at least the way I was doing it.

-----

2 points by shader 6011 days ago | link | parent | on: New Version of Arc

How hard do you think it's going to be to integrate the changes with Anarki? Is it even worth it?

-----

2 points by rntz 6010 days ago | link

I've already pushed arc3.tar to anarki's "official" branch and merged the changes into "stable". Merging them into the master branch may prove more difficult and tedious, but I think it can be done.

-----

1 point by CatDancer 6010 days ago | link

Hmm, as an interim step you could make a macro called "set" which you loaded after Arc and before Anarki. That way you could try out Anarki with arc3 and get things working before going on to do all the tedious renaming.

-----

1 point by rntz 6010 days ago | link

The trouble is, I wouldn't know where to start with testing anarki as a whole. There's just too many different parts, because anarki has so many things:

- Forks and compilers (arc2c, arc-f)

- Pet projects and examples (LightMakesRight, wiki-arc)

- Utility libraries (lib/util, defpat, settable-fn)

- Extensions to arc (help strings, function signatures, compilation)

- Bugfixes to arc (making 'atomic work even on exception throw)

I think I can probably update the latter three, but the former will just have to rely on whoever contributed them. Perhaps it's time for a new anarki - throw out the unmaintained cruft and try and separate changes to core arc functionality (bugfixes, extensions) from additions/libraries from standalone projects.

-----

2 points by thaddeus 6010 days ago | link

I don't know why you would want to.

From my cursory look, pg has fixed many if not most of the core issues that anarki resolved. (ie cut fn not handling -1, providing a static directory for files to be published, added some basic math functions - sin cos etc..).

I would suggest starting a new branch with arc3 and if the libraries from anarki are still relevant then people will incrementally add them. This way were not integrating a bunch of code just because it's there - even though it's no longer useful.

+ just because you make them work with core arc3 files doesn't mean there will not be conflicts - as example the int function in the anarki math.arc library conflicts with news.arc only (as pg added an int function).

T.

-----

1 point by rntz 6010 days ago | link

Some of the things anarki adds that are not in arc3 are tremendously useful. For example, help strings and the 'help macro to access them, and similarly, the ability to call up any function or macro's source with 'src.

I do think the idea of integrating anarki code incrementally is probably the right way to do it. To this end, I've forked anarki's "official" branch (http://github.com/rntz/arc), and I've been applying CatDancer's "minimum-distance-from-arc" patching philosophy (http://catdancer.github.com/sharing-hacks.html). We'll see how many things from anarki I end up converting this way.

-----

1 point by shader 6006 days ago | link

When you're done with you're patching process (I wouldn't mind helping) we should probably merge it back into nex3's copy, as his has public commit access.

-----

2 points by CatDancer 6010 days ago | link

One approach is to only port over things that you personally use and care about; and let other people port over things they care about. That's a pretty good filter for separating out the important from the unimportant.

-----

4 points by shader 6011 days ago | link | parent | on: New Version of Arc

Say, would you mind giving us a preliminary change list?

-----

5 points by thaddeus 6011 days ago | link

Here's for hoping the super talented Ken Shirriff will publish a similar write up to his arc2 post.

http://arcfn.com/2008/02/whats-new-in-arc2.html

-----

3 points by pg 6011 days ago | link

I don't have such a list myself. Your best bet is to diff the source files.

-----

4 points by rntz 6010 days ago | link

Here's the diff: http://www.rntz.net/files/arc2to3.patch

Just giving it a preliminary look over, it seems like you changed 'set to 'assign. Any reason for this in particular, pg? It seems like it changes a lot of code, and as 'set is fairly common, it kind of goes against the philosophy of short names for common operators.

-----

2 points by CatDancer 6010 days ago | link

"set" actually wasn't common at all; in arc2 it is used only a handful of times in arc.arc, mostly to implement "=".

-----

2 points by rntz 6010 days ago | link

Eh, when I think about code use, I usually think about anarki — which is probably the problem itself, now that I think about it.

    $ find anarki/ -name '*.arc' -print0 | xargs -0 grep "[(']set[[:space:])]" | wc -l
    180
It's not so many uses that it's impossible to update. Many if not most of these uses could admittedly be replaced with '=, and arguably this was the correct thing to do in the first place. It just seems like an odd decision, and I'm wondering if there's any specific reason for it.

-----

3 points by CatDancer 6010 days ago | link

In my opinion "set" is a better name for what "assert" used to do, and I think "set" was available since it was being used for a low-level operation for which in user code "=" is a better and shorter name.

Also, don't forget http://www.paulgraham.com/arc0.html:

"I worry about releasing it, because I don't want there to be forces pushing the language to stop changing. Once you release something and people start to build stuff on top of it, you start to feel you shouldn't change things. So we're giving notice in advance that we're going to keep acting as if we were the only users. We'll change stuff without thinking about what it might break, and we won't even keep track of the changes."

-----

1 point by shader 6011 days ago | link | parent | on: Step Three of Installing Arc

As far as I know, windows is not officially supported. I think I've gotten it to work on windows before, but you might have some trouble with file system differences, etc.

However, the place to type that in is a command line window in the folder arc was unzipped to.

So for example:

1) Type Windows Key-R to bring up run window 2) Type in "cmd", and hit enter to bring up command prompt 3) Use the "cd" command followed by the directory path of your arc installation. 4) Execute "mzscheme -m -f as.scm" to start arc.

Alternatively, if you're using Vista (not sure about XP), you can Shift-Right Click in a explorer window, and click the dropdown item "Open Command Window Here" to do the same thing as the first three steps.

I hope that helps.

-----

1 point by PebblesRox 6007 days ago | link

Thank you for your help. I tried to follow these directions, but it didn't work. I'm not sure I understand them correctly. Steps 1 and 2 are fine, but maybe I didn't do step 3 or 4 the right way. Here's what happened:

I have a folder with MzScheme in it and a folder with arc3 in it. I entered "cd" and the directory of the arc3 folder: "cd C:\Program Files\Arc\arc3" and then I hit enter. The next line looked like this:

    C:\Program Files\Arc\arc3>
so I typed in "mzscheme -m -f as.scm" and pressed enter. This message appeared: 'mzscheme' is not recognized as an internal or external command, operable program, or batch file.

Do I need to be more specific with my directory path? Is there a file inside the arc3 folder that I need to name? Or am I not executing "mzscheme -m -f as.scm" when I type it in?

-----

1 point by shader 6007 days ago | link

Ok, so the problem is that windows doesn't know where to find mzscheme.

To rectify the situation, you could either type in the full path to mzscheme instead of just it's name, or you could add it to your PATH variable (that's where windows looks to locate programs when you type them in on the command line)

Here's how to do that temporarily:

  PATH=%PATH%;<insert mzscheme path here>
Again, that's PATH=%PATH%, followed by a semicolon and then the path to mzscheme. Unfortunately, this is a temporary fix that will only last as long as that command window.

To make it permanent: right click on "Computer" and go to properties. Somewhere there should be an Advanced Settings link, which should pop up a new window. Click the Environment Variables button, and edit the PATH variable (either for your user or the whole system). Add a semicolon, and then paste in the path to the mzscheme executable.

Hopefully that works for you ;)

-----

1 point by PebblesRox 6007 days ago | link

Oh, yes! I got the arc prompt. Thank you for your help :)

-----

2 points by shader 6014 days ago | link | parent | on: Any other arc news forums out there?

I've got a news forum running, but it's on a very small box so I don't know if I want to drive much traffic to it ;)

At any rate, I'm interested in getting an FCGI interface for arc so that I can host it on Dreamhost. They don't support scgi or a network daemon, so I can't use mod_proxy. If anyone is interested in helping, let me know ;)

-----


There was one attempt a while ago to get mysql to work with arc.

As for using arc as an cgi script, it has a rather slow load time. If you are loading for every request it will be quite slow. That's one reason that arc includes it's own web server.

One common way of using arc is to run it behind an apache server with mod_proxy.

-----

1 point by justgord 6090 days ago | link

As an interim hack to get to postgres data, I'm currently using system to call the external psql command - less than ideal :[

<pre> (def sqltxt (sql) (system (string "psql -c " "\"" sql "\"" ))) </pre>

[ I guess opening a socket to the db server and parsing the resultset wouldn't be much harder if its text mode - could probably use the perl or ruby pglib as a guide, and port from that... ]

-----

2 points by shader 6090 days ago | link

Hmm. I would think that you wouldn't want to open a new psql connection every time you want to look something up.

How about running the system command in a thread, which redirects psql's stdin and stdout to named pipes so that another arc thread could read from it using file read commands? That would give you more persistence, so you wouldn't have to keep loading psql.

Also, have a look at lib/mysql-ffi.arc in anarki; supposedly it has a ffi for mysql, though I haven't really looked at it much myself.

-----

1 point by justgord 6090 days ago | link

yeah or theres the mz: extension to access one of mzschemes pgsql libs...

Sure its ugly/slow.. but allows me to prototype in the meantime.

Thanks for the mysql ref, I'll take a look.

-----

2 points by absz 6090 days ago | link

I can't help you with the SQL, but I can give you a formatting tip: to get

  code formatted like this,
surround your code block with a blank line on each side and indent each line of code by at least two spaces.

-----

2 points by justgord 6090 days ago | link

  (prn "thanks absz")

-----

1 point by shader 6102 days ago | link | parent | on: Alphabetical bracket fns

I found a bug, surprise surprise. Apparently it doesn't seem to count things bound before it in a withs as bound. I presume it is because the nested lets are not actually executed before the bound function is called in the macro expansion. Any ideas on how to get around that? This sounds like a good place for run-time macros ;) That, or a method of having code be more aware of its context; i.e. having the macro-expansion look to see if it was called inside of a form that would bind something (mainly fn). That sounds even harder.

So, apparently it works ok when called directly from the repl, but due to the compile time nature of macros it has trouble with being built into functions or called in other macros.

What does all of the auxiliary code for make-br-fn do? (all of the *mbr functions) They probably don't have much to do with this, but it seems like an awful lot of code just to implement make-br-fn.

-----

2 points by absz 6102 days ago | link

The auxiliary code is responsible for finding all the variables in the code and then finding all the _\d+s (and __) that occur free in the expression. It's probably bulkier than it needs to be---I wrote it with a decent amount of class experience in writing interpreters, but without any real-world experience. The big thing you seem to be missing is expand, which will macro-expand its argument. That would result in the following change:

  (mac make-br-fn (body)
    `(fn ,(unbound body) ,(expand body)))
(And ontree didn't exist when I was writing make-br-fn; that's a very convenient function :) )

-----

1 point by shader 6102 days ago | link

Indeed, ontree is helpful ;)

I've looked at expand; how does it help there? Is that necessary to expand macros inside a bracket function?

I still have no idea how to check binding at compile time; in theory it could know that it was inside a binding expression (fn) but I think that would take a lot of modification to the language, and probably isn't worth it, unless it allows other nifty features.

-----

1 point by absz 6102 days ago | link

Aha, I see. Yes, in this case, expand probably won't help. But it's actually conceptually simple to checking binding (without eval) at compile time; that's what make-br-fns does, after all. What you do is you run expand on the source tree, then just go through and check and see if it's within a fn. This is what all the auxiliary functions for make-br-fns are doing: checking to see what's in an argument list, seeing if variables used are in argument lists, etc. Obviously this breaks if you run, say, (eval '_2), but it works in other situations.

-----

2 points by shader 6102 days ago | link

Wait, how does it know what context it's run in? I can see checking if the symbol is bound underneath it, but what about checking to see if it is bound above? (i.e. br-fn inside a withs) How does that work?

-----

1 point by absz 6102 days ago | link

...Oh dear :-[ It doesn't, and I hadn't noticed that until right now. Apparently, it's not a problem, presumably because nobody ever declares variables called _1 :P Yeah, I don't see a feasible way to do that, unless make-br-fns produces something like

  (eval '`(fn ,(unbound body) ,body))
which is horribly inefficient and clunky.

-----

2 points by rntz 6101 days ago | link

Even the 'eval thing wouldn't work. 'eval evaluates its argument at top-level, so the function would no longer be lexically scoped within its environment. You wouldn't be able to write anonymous closures anymore, just anonymous toplevel functions. Moreover, 'bound checks whether its argument is bound at global scope.

-----

1 point by shader 6102 days ago | link

Unless there was a way for a function to examine its declaration environment. Then we could have a function that crawls up the tree looking for binding statements, and removing those from the list of unbound symbols. I just don't know how hard that would be to add. It could be useful for other things though, like better error messages. If the context were mutable, it could allow macros to do a) really cool things and b) likely very buggy things. But if people knew to expect it, it might be ok.

How would you implement a read-only context, visible during compile time? Is it even possible? In theory, the reader has already read in the other stuff, and parsed it into a list.

-----

1 point by rntz 6101 days ago | link

Allowing a macro to know what lexical variables are bound in its calling environment is perfectly possible, though it would require some modification to ac.scm. In order to translate arc symbols into mzscheme symbols, the compiler already keeps track of what variables are locally bound. So you'd need to modify the compiler so that this list gets passed in as a "hidden parameter" to macros, and make a special form to access it. However, I'd advise against implementing this, because there's an even more unsolvable problem. Even if you fixed it, the following would still break:

    (def square-thunkify (x) [square x])
    (def square (x) (* x x))
The intended meaning of [square x] here is (fn () (square x)). But because 'square is not bound at the time of [square x]'s macroexpansion, even if you did have the more "intelligent" version of 'make-br-fn, it would end up as (fn (square) (square x)). At present, of course, it ends up as (fn (square x) (square x)).

-----

1 point by shader 6101 days ago | link

Hmmm. So how about looking for only unbound single letter symbols? That would cut out all of the predefined functions, and still provide usability (I wasn't going to use it with anything more than x y z and a b c anyway.

If not, I guess there's no point in continuing to pursue this idea, is there ;)

-----

1 point by shader 6101 days ago | link

Maybe we could look at only single letter symbols, or symbols that start with _. That would give compatibility with (most) of the current uses; the only times that it wouldn't work would be when it was used in a function that had a single letter parameter. So, maybe I should just give up then ;) Even though I don't really like _1 _2, etc., I guess it's the most viable option.

-----

2 points by shader 6102 days ago | link | parent | on: Anonymous macros

> Are you thinking of a shortcut to macex, to expand expressions at runtime?

I guess so. I don't really know what I'm thinking, to be honest. I think that anon. macros would be useful in cases where you want a little bit of syntax modification, but not make a whole macro out of a function.

For instance, I have found it difficult to make a set of functions taking rest parms built on top of a base function that also takes rest parm. In order not to get the extra layer of cons around it, I end up having to make a macro for calling that base function, to splice the arguments into the list. Maybe I'm doing it wrong, and there's a better way, but it seems like it might be an application for a short anon. macro.

-----

3 points by cchooper 6101 days ago | link

Can't you just use apply?

-----

2 points by shader 6101 days ago | link

I think apply only works as long as there are no other arguments besides the rest arg. Otherwise you need to use macro with ,@. I think.

-----

2 points by absz 6101 days ago | link

That's not the case; apply doesn't care how many arguments the function takes. Take map (which takes a mandatory argument and a rest parameter) and map1 (which takes two mandatory arguments):

  arc> (help map)
  (from "arc.arc")
  [fn]  (map f . seqs)
   Applies the elements of the sequences to the given function.
      Returns a sequence containing the results of the function.
      See also [[each]] [[mapeach]] [[map1]] [[mappend]] [[andmap]]
      [[ormap]] [[reduce]] 
  arc> (map list '(1 2 3) '(4 5 6))
  ((1 4) (2 5) (3 6))
  arc> (apply map list '((1 2 3) (4 5 6)))
  ((1 4) (2 5) (3 6))
  arc> (apply map (list list '(1 2 3) '(4 5 6)))
  ((1 4) (2 5) (3 6))
  
  arc> (help map1)
  (from "arc.arc")
  [fn]  (map1 f xs)
   Return a sequence with function f applied to every element in sequence xs.
      See also [[map]] [[each]] [[mappend]] [[andmap]] [[ormap]] 
  arc> (map1 [* 2 _] '(1 2 3))
  (2 4 6)
  arc> (apply map1 (list [* 2 _] '(1 2 3)))
  (2 4 6)
As long as the last argument to apply is a list, you're golden.

-----

2 points by shader 6100 days ago | link

Interesting. I was wondering if that might be the case.

So I guess that we don't need an anon. macro for that ;)

I'm also wondering whether we would ever actually want an anonymous macro, since often they turn out to be so general purpose that you might want to make a utility out of it.

Does arc have symbol macros?

-----

4 points by absz 6100 days ago | link

I'm not really clear on what an anonymous macro would do. Transform code? If we're writing it in one place, we can just transform it right there. Can you give a usage example?

And no, Arc only has ordinary macros and ssyntax. Though actually---and this just occurred to me now---you can use ssyntax to create symbol macros. For instance, I have the following in a library file

  (= mac-seval $)
  
  (add-ssyntax-bottom
    @    (par apply R)
    $    (fn lists (apply map R lists))
    @    apply
    $    mac-seval)
The first two let me write (@func arg1 restargs) instead of (apply func arg1 restargs) and ($func xs) instead of (map xs). However, this $ makes the $ macro misbehave, and so I added ssyntax turning @ into apply and $ into the original $ macro. It turns out that this technique is fully generic, since ssyntax essentially does a find-and-replace on symbols:

  arc> (= defsym add-ssyntax-top)
  #3(tagged mac #<procedure>)
  arc> (defsym RANDOM (rand))
  t
  arc> RANDOM
  0.5548165450808223
  arc> RANDOM
  0.15745063842035198
  arc> (= things '(alpha beta gamma))
  (alpha beta gamma)
  arc> (defsym THING1 (car things))
  t
  arc> THING1
  alpha
  arc> (= THING1 'one)
  one
  arc> things
  (one beta gamma)
  arc> (defsym NOISY (do (prn 'HI) nil))
  t
  arc> NOISY
  HI
  nil
  arc> (car NOISY)
  HI
  nil

This is actually really nifty, even if it's an unintended side effect. On some level, though, I'm not fully convinced of the value of this---it seems a bit omnipresent. Then again, Common Lisp works fine with them, so perhaps they're fine for Arc too. Are there naming conventions for symbol macros in Common Lisp? I used capital letters above just because I wanted some distinguishing mark.

There are a couple of caveats: first, every time you run add-ssyntax-top, you'll add another entry to the ssyntax table instead of overwriting the old one, so redefinition will make ssyntax slower if it's done too much. Second, the five tokens R, r, L, l, and ... are all unavailable, even if quoted; they turn the given string into modifying ssyntax, not standalone ssyntax. Still, this is a new option I hadn't thought about yet.

-----

1 point by shader 6103 days ago | link | parent | on: Source table

What do you suggest we do about all of the foundation functions? Most are defined in scheme using xdef, some using set (def and mac). I could add hooks to those (especially xdef) but I don't know how well that would work.

Hard coding it probably isn't a good idea; the source would get out of date, and be hard to maintain. Besides, it violates the DRY principle.

Ideas?

-----

1 point by shader 6103 days ago | link | parent | on: Source table

Ok, I've pushed the source table.

Here's what I changed:

1) def and mac now add entries to a table named source*

2) there are now two macs fro accessing those entries: lsrc and src. lsrc returns the source as a list, so that you can modify it, etc. src pretty-prints lsrc, so that you can read it better from the repl.

3) I also changed fns so that it a) takes both arguments as optional and b) will accept symbols as arguments. Here's a few examples on how to use fns:

  arc> (fns)
  *returns the signatures of all macros and functions currently defined*
  arc> (fns f)
  *returns the signagures of all functions and macros beginning with f*
  arc> (fns nil [fancy-filter _ ])
  *returns the sigs of all fns and macs which pass fancy-filter.*
In the last form, the br-fn cannot reference the first argument.

It could possibly be modified so that it tests if the single argument is a function or a symbol, and if it is a function it treats it as the filter, otherwise it uses prefix with the string of the symbol.

-----

More