Arc Forumnew | comments | leaders | submit | almkglor's commentslogin
4 points by almkglor 6151 days ago | link | parent | on: Getting (re)started

Other than arcfn, no, this is the only one.

And as for my fork of Arc, Arc-F, yes, most definitely this is the only one.

-----

2 points by almkglor 6151 days ago | link | parent | on: Remove lib/spec.arc - license violation

Huh. Probably will also require some hackery on the git-side too, because it would be probably revertible and thus the modified versions can still be accessed. LOL.

-----


Much of the base system of Arc expects some Unixisms. In fact, much of the base system of PG's original ArcN expects a mostly BSDisms, and it's really the Anarki fork which supports mostly Linux.

As an example, much of the code assumes that the path separator character is "/", but I gather from mzscheme documentation that Mac OS uses ":". Also, bits and pieces of the Arc system use /dev/urandom.

So mostly I suspect the problems you encounter(ed) are from Arc's assumption of Unix-likeness which might not be available on OS X (not sure however; I don't have access to a real Mac)

Edit: Oh and yes: the first thing you want to do is switch to Anarki, which is more likely to work on a random, non-PG system.

-----

1 point by niels_olson 6151 days ago | link

OS X is based on BSD. As for the path thing, wow, that threw me. Not sure what that might apply to. Here's are my PATH entries on a SuSE box and my Macbook, respectively. They're both POSIX compliant.

niels@suse:~> echo $PATH /home/niels/bin:/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/X11R6/bin:/usr/games:/opt/kde3/bin:/usr/lib/jvm/jre/bin:/usr/lib/mit/bin:/usr/lib/mit/sbin:.:/home/niels/myscripts:/myscripts

osx:~ niels$ echo $PATH /Users/niels/Desktop/LearningPython/arc2:/Users/niels/Desktop/LearningPython/MzSchemeV352/bin:/Library/Frameworks/Python.framework/Versions/Current/bin:/sw/bin:/sw/sbin:/opt/local/bin:/opt/local/sbin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin:/usr/X11R6/bin

I guess, for starters, I need to figure out how to set up BIND to route news.localhost to a local directory, and figure out which directories the various bits of MzScheme and Arc should be applied to. My biggest frustation right now is figuring out the syntax for BIND.

-----

1 point by almkglor 6151 days ago | link

I got that bit about Mac: http://download.plt-scheme.org/doc/103p1/html/mzscheme/node1... . However, the newer PLT docs here: http://docs.plt-scheme.org/reference/Manipulating_Paths.html say that apparently Mac OS X is now quite sensible.

Windows internally implicitly supports / as an alias of \.

Note that Arc provides its own http-server which is not very directory-based (rather, something like http://example.com/login would be defined with a (defop login ....) form in the running Arc process), so I'm not sure why you're routing to a directory.

-----

3 points by absz 6151 days ago | link

The deal with path separators has to do with the difference between the classic Mac OS (9 and lower) and Mac OS X. Classic Macs used their own path system, which used :s as the path separator (e.g., ":Macintosh HD:Documents:Arc:tut.txt"). When the switch to OS X came, suddenly everything was based on Unix, so file paths became sane (e.g., "/Users/username/Documents/Arc/tut.txt" or even "~/Documents/Arc/tut.txt"). Nevertheless, in the name of backwards compatibility, many things still display paths in the old format, the GUI pretends that :s in file names are actually /s, and AppleScript deals natively with old-style filenames.

In a nutshell: OS X sane, Classic Macs crazy.

-----

1 point by niels_olson 6151 days ago | link

Re Anarki: yes, I've found arc2 doesn't work out of the box on CentOS 5, and my repos are botched (something to do with installing PHP 5 during initial install, I think, was what forced me to change something in the repos), so I need to fix the repos to install Git so then I can install Anarki.

I looked for git in the CentOS repos for hours and never found it. Yum swore up and down it couldn't find git. So I compiled it using these directions: http://el-studio.com/article/building-git-on-centos-5

-----

1 point by almkglor 6152 days ago | link | parent | on: Simple multimethods: lib/multi.arc

               ,(or default-method
                  `(err "no matching method found for multimethod:" ',name)))
Is this deliberate? It seems to me that the optional default-method argument is a default expression that will be evaluated, but without access to the arguments to the function.

-----

1 point by rntz 6152 days ago | link

I'm not sure exactly what you're getting at. Admittedly, what I did there is somewhat hackish (although my original method was worse). The default-method argument is just that: a default method which will be called (with the arguments to the multimethod) if no other method is found. But the expression that makes it up is only evaluated if necessary (lazily, in an 'or expression). So if it produces an error, then when that expression is evaluated, that is, if and only if we have failed to find a matching method, it produces an error; and since, in the macro itself, I know the name of the multimethod, I can substitute this into the default for 'default-method, and have nicer error messages.

-----

1 point by almkglor 6151 days ago | link

Ah sorry, misread the code, forgot the 'apply bit around the form.

-----

1 point by almkglor 6153 days ago | link | parent | on: Packaging libraries

Hmm. Would you mind giving a more overviewish summary of the library-packing system? You seem to have stuff like "defproject" in pack.arc ; what are the relationships between projects, libraries, and packages in your scheme?

Currently the (using ...) scheme in Arc-F assumes a package is a file is a library (and if the library is too large to fit in a single file, to have various "support packages" which are related to the main library package: i.e. lib.arc source contains '(using <lib/part1>v1), and there's a file in lib/part1.arc which contains the parts of the library.). I'm interested in your take on multi-file libraries.

Also, my scheme assumes one context object per source file. A context object is equivalent to the "current-package" variable ( s/"/* ) in CL, except you can arbitrarily create such objects, and they work monadically. What is your expectation on how the packaged libraries work?

-----

1 point by stefano 6151 days ago | link

> if the library is too large to fit in a single file, to have various "support packages" which are related to the main library package

No more. For simplicity now everything (even single files) are packaged in directories. A "library" (or "package") is a way to distribute some piece of code: everything is placed within a directory named libname.pack together with informations to load dependencies. You can load such a package and all its dependencies using a single command ('use, 'require or 'using). A "project" is a way to manage the development of such a library and is roughly a "make" for Arc. To define a project you would use the macro 'defproject, specifying a list of dependencies (single files or libraries) and a list of files composing the project. When loading a project through 'proj-load only modified files are loaded. When you have loaded a project you can build a packaged library using 'deliver-library. A proper directory will be created and populated with the relevant files. Project and libraries are independent of the namespace system. I've modified 'using to load a library using 'use if nothing else can be done, with the assumption that if such a library exists, it also defines its own namespace (e.g. (using <http-get>v1) loads the library named 'http-get, hoping that that library defines a namespace <http-get> with an interface v1.

-----

1 point by almkglor 6151 days ago | link

In the Arc-F packages/namespaces, dependencies are specified by the (using ...) metaform. Each package is conceptually a point where a library could be; if a library needs several files, each file is a package and there is a unifying file which depends on the other packages and specifies the interface.

I suppose my view of namespace-as-package is from the point of view that namespaces are the be-all and end-all of organizing libraries though. Hmm. I'll try a look-see at your pack.arc, although I think it would be nice if you could provide a few simple examples.

-----

1 point by stefano 6149 days ago | link

> dependencies are specified by the (using ...) metaform

Mmmm... I've been thinking about this. There seems to be some overlapping between your system and mine. I think pack.arc is better suited to extend a pure namespace system with a packaging/dependency system, whereas arc-f namespace system is meant to manage also dependencies.

To see a real usage of pack.arc you can look at my ftp library: http://github.com/stefano/ftp-client/tree/master It's not updated to work with arc-f (yet) but it shows how to use pack.arc: a proj.arc file for development and a automatically generated directory ftp-client.pack intended to be downloaded and copied within the search path by the end user.

-----

1 point by almkglor 6149 days ago | link

Yes. In fact I kind of rushed Arc-F a bit because I suspected that your pack.arc would overlap with the packages system in Arc-F, so I wanted to see what we could work out in order to reduce overlapping in this case.

Hmm. Project management? The Arc-F namespace system doesn't handle thinking in terms of "projects". And how about versioning? The "version" that is used in the Arc-F namespaces is more about the interface version, not necessarily the version of the actual library.

Also, I was also thinking that potentially a particular library may have multiple implementations, while those implementations share the same interface. For example, there is a reference implementation for vectors in lib/vector.arc, and (using <vector>v1) will acquire that vector interface. However, a different implementation of Arc-F - for example, arc2c - might provide a different version - in the case of arc2c, it might be a thin wrapper around a C array.

-----

1 point by stefano 6149 days ago | link

> how about versioning?

I will probably add it to pack.arc in the future. For the moment it wouldn't be very useful, since there are so few libraries and the ones that do exist are in early development stage. I'll put in pack.arc what I need now to help me develop and distribute libraries. Suggestions are always welcome of course.

The main overlapping between the two system seems to be the fact that 'using tries to load a file before importing its interface. I don't think this will create any conflict with pack.arc. I should also change its name: the term "package" is used both for "collection of files" (pack.arc) and "namespace" (arc-f).

Your example about arc2c arises a problem that Arc, in its original conception, wanted to solve: multiple implementations. Small little differences between implementations always end up hurting: for example ftp-client works with Anarki and doesn't work for Arc2 or Arc-F. There are too much implementation of Arc right now. I have nothing against arc-f, snap, arc2c, rainbow,... I like their existence and what they added (in particular arc-f), but a canonical implementation used by 99% of Arc developers should exist, and it should be "fast enough" (2x slower than python is my personal limit).

-----

1 point by almkglor 6148 days ago | link

How about project-based development then? Basically to keep related files together.

Personally I prefer a variety of smaller libraries whose components would then be composed by other libraries (which would end up being small too, because the functionality exists in other libraries).

My main design goal in Arc-F is to make the use of libraries - and in particular, the use of different libraries from different people with different design philosophies - as smooth as possible. Many of the additions in Arc-F (the ones that aren't packages) are actually subtly biased towards that main goal.

> (2x slower than python is my personal limit).

Hehehe. Looks like I'll need to start doing some teh lutimate leet hackage in the function dispatching code... Or alternatively start considering how to write an interpreter from scratch (which is a subgoal of SNAP, too) ^^

-----

1 point by stefano 6148 days ago | link

> How about project-based development then?

I don't quite understand that. With pack.arc development is project-based. Maybe we have different opinions of what a "project" is. To me, it is a directory with a file proj.arc describing the structure of the project (a 'defproject declaration).

> write an interpreter from scratch

Really difficult but really needed. The mzscheme dependency is quite big compared to how small as a language Arc is. The main efficency problem, as you said, is function dispatch, because we have to check if it is a function, a list, etc. One thing I don't like very much about SNAP is the dependency on the boost libraries: it is a huge dependency. Is it really needed?

Another problem with an interpreter from scratch is the GC: it is very difficult and time consuming to write an efficient, concurrent and stable GC. A good solution would be to use the Boehm-Weiser GC: it is easy to integrate in any interpreter (I don't know if it works with SNAP's process' model, though) and it is a really good GC. Even the mono project and gcj use it.

-----

2 points by almkglor 6147 days ago | link

> With pack.arc development is project-based.

Ah, right. Of course, that's why there's 'defproject, right?

> because we have to check if it is a function, a list, etc

As an idea: generally writes to global variables are much rarer than reads from global variables; in fact, practically speaking nearly every global variable is going to be a constant. We could move the cost of checking if a call is a function, a fake arc-f function, or a data structure to the writing of global variables rather than the read.

Basically calls where the expression in function position is a reference to a global variable are transformed to callsites which monitor that global. The callsite initially determines the type of the value in the global (or creates an error-throwing lambda if the global is still unbound) and determines the proper function to perform for that call (normal function call, or a list lookup, or a table lookup, etc). The callsite also registers its presence to the global.

If the global is written, the global also notifies all living callsites (we thus need weak references for this), which will then update themselves with the new value.

This is actually "for-free" in SNAP, because there's an overhead in reading globals (copying from the global memory-space to the process memory-space), and SNAP thus needs to monitor writes to globals so it can cache reads.

> One thing I don't like very much about SNAP is the dependency on the boost libraries: it is a huge dependency. Is it really needed?

The bits of boost I've used so far are mostly the really, really good smart pointers; while I've built toy smart pointer classes I'm not sure I'd want those toys in a serious project. Also, I intend to use boost for portable mutexes. Now if only boost had decent portable asynchronous I/O...

Alternatively we could wait a bit for C++0x, which will have decent smart pointers which I believe are based on boost.

> Boehm-Weiser GC: it is easy to integrate in any interpreter (I don't know if it works with SNAP's process' model, though)

Well, one advantage of the process-local model is that process-local memory allocations won't get any additional overhead when the interpreter is multithreaded; AFAIK any malloc() drop-in replacement either needs to be protected by locks in a multithreaded environment, or will do some sort of internal synchronization anyway. In effect we have one memory pool per process, allocating large amounts of memory from the system and splitting it up according to then needs of the process.

Since processes aren't supposed to refer to other process's memory, the Boehm-Weiser GC won't have anything to actually trace across allocated memory areas anyway.

And I probably should start using tagged pointers instead of ordinary pointers ^^. They're even implementable as a C++ class wrapping a union.

In any case a copying algorithm already exists because we need to copy messages across processes anyway: minor changes are necessary to extend it to a copying GC.

-----

3 points by almkglor 6153 days ago | link | parent | on: Simple multimethods: lib/multi.arc

Arc-f actually has clojure-style multimethods hidden somewhere (I invite you all to search for them!). However, there are very deep reasons why I did not encourage their use.

The most important is that the dispatcher function is a limiting factor. To be specific, the dispatcher function means that extending the function is limited to what the dispatcher expects.

If the dispatcher function expects exactly one argument, you cannot create a method with an optional argument. For instance, consider a shape rectangular-prism

  (= shape
     (obj shape 'rectangular-prism
          height 2
          width 3
          depth 4))

  (method area 'rectangular-prism (p (o face 'front))
    (case face
      front  (* p!width p!height)
      back   (* p!width p!height)
      left   (* p!height p!depth)
      right  (* p!height p!depth)
      top    (* p!width p!depth)
      bottom (* p!width p!depth)))
Unfortunately, because the dispatcher for 'area expects exactly one argument, you cannot extend 'area with a method that supports optional arguments.

I'll be putting up a more extensive rationale for why I decided not to use Clojure-style multimethods in Arc-F (despite already having implemented them), and would very much rather prefer to bash my head trying to implement CLOS-style multimethods.

-----

4 points by rntz 6152 days ago | link

It's true that if the dispatcher expects exactly one argument, you can't add optional arguments. The solution is very simple: don't make dispatchers which expect exactly n arguments. Make all your dispatchers take rest parameters which they ignore. In fact, 'multi-keyed already does exactly that, so if you used (multi-keyed area 'shape), your example would work exactly as expected. It's not a hard fix.

Regarding reasons for not implementing Clojure-style multimethods in Arc-F, how about this one: because you can implement them in plain old arc! Don't put stuff in Arc-F if it can be done in Arc or Anarki already. Interoperability is good - we don't need to fork the community as well as the language.

-----

1 point by almkglor 6152 days ago | link

> It's true that if the dispatcher expects...

It's not just the number of arguments. One advantage of CLOS-style multimethods is this:

  (def bam (a b)
    (err "collision type unknown!"))
  (defm bam ((t a ship) b)
    (destroy ship)
    (destroy b))
  (defm bam ((t a ship) (t b missile))
    (destroy ship)
    (destroy missile)
    (add-points missile!source))
Because of the computation of keys, you can't exactly implement the above using clojure-style multimethods without tricks like method bouncing.

Like I said: already implemented clojure-style multimethods. And tried it. So yes: I'll continue bashing my head implementing CLOS-style multimethods, because while clojure-style multimethods are cute, they're not good enough for all cases. Arguably neither are CLOS-style multimethods, but at least we have an alternative choice.

Edit:

Also, there's a good reason for implementing this in the scheme-side: efficiency. Your implementation of clojure-multimethods allocates a cons cell for each argument to the multimethod. The scheme-side implementation does not, because on the scheme-side I have access to the ar-funcall* functions.

Efficiency of course is not a concern, except when it is.

As an aside, there are several bits of Arc-F that look like they're implemented in Arc, but are actually implemented in the scheme-side. There's an Arc implementation of them in arc.arc, which is labeled as "IDEAL", while the actual binding to the scheme side is labeled as "REAL". For example, the basic compose function is actually implemented in the scheme-side, but there's a reference Arc implementation in arc.arc marked "IDEAL". The only reason they're on the scheme-side is due to efficiency. Ideally, they would be in Arc: realistically, they are better implemented in the base system.

-----

1 point by rntz 6152 days ago | link

This is true, and indeed I mentioned it in the OP; you can't do type-based dispatch with clojure-style multimethods except on exact matches. You also can't get method chaining. But clojure-style has the advantage of being damn simple, and easily permits dispatch based on non-type-based conditions. CLOS style has the advantage of being more flexible about dispatch and integrating well with OO methodologies.

I'm not trying to convince you that CLOS multimethods are bad or not to implement them; a full implementation for Arc or Arc-F would be _very cool_. CLOS is without a doubt my favorite thing about Common Lisp. But Clojure-style multimethods are not "cute" or useless. They're just not a universal panacea. Very little is.

-----

1 point by almkglor 6152 days ago | link

> "cute"

For me, cute means something really really nice, not necessarily useless. Like cute mature women, for example. Or better: cute girls, with guns. LOL.

Method chaining may require us to rethink PG's type system, at least if we want to handle a drop-down to a more generic type (which arguably is the more interesting bit about chaining). It's reasonably easy to drop from the "argument 2 matched type T" to "argument 2 matched no types", but how about when we want to drop from "argument 2 matched derived type D" to "argument 2 matched base type B"?

Waa.

We would have to have an operator which determines if D is derived from some random type B, and forcibly standardizing on it. This is going to make my head explode.

-----

3 points by almkglor 6153 days ago | link | parent | on: A thought: Arc <=> JS

It would be useful. I've had thoughts along these lines.

-----


It's a dependency on ./arc.sh

Specifically, arc.sh sets the environment variable "arc_dir" to the installation directory.

I would suggest making a batch file which sets the environment variable arc_dir properly before launching mzscheme -af as.scm ^^

Should probably be done correctly by providing an arc.bat I suppose, although the problem is always figuring out the installation directory... haven't hacked MSDOS batch files in a long time ^^

-----

3 points by eds 6154 days ago | link

Ok, I got arc3f to work with the following:

  C:\User\Programming\Arc\arc3f\arc-f>set arc_dir=C:\User\Programming\Arc\arc3f\arc-f

  C:\User\Programming\Arc\arc3f\arc-f>mzscheme -mf as.scm
  Compiling arc.arc...
  Use (quit) to quit, (tl) to return here after an interrupt.
  <User>tl:
Unfortunately, (having learned Unix shell scripting), I never bothered to learn Windows batch files.

Also of note, arc.sh doesn't work in Cygwin:

  $ sh arc.sh
  > default-load-handler: cannot open input file: "c:/cygdrive/c/User/Programming/Arc/arc3f/arc-f/as.scm" (The system cannot find the path specified.; errno=3)

-----

2 points by almkglor 6154 days ago | link

I pushed an untested arc.bat launcher on the anarki arc-f recently, although now that I've reviewed it it seems I used the wrong flag in the mzscheme invocation (-af instead of -mf). Could I ask you to check it out, and if so, could you check it out?

As for the cygwin stuff.... hmm. Maybe I should fix my broken WinXP machine...

-----

1 point by bOR_ 6152 days ago | link

   @echo off
   set arc_dir=C:\Program Files\ARCF
   mzscheme -mf "%arc_dir%\as.scm"
This one worked for me. I'm not sure if removing the [][]'s from the file and making it windows line breaks mattered, but at least I had to move some ""'s around to get it to work.

Now just trying to get the launch-an-arc-script script working (from outside the repl). The script that is elsewhere on the website works on linux, but not windows ;). Damn pipes.

-----

1 point by bOR_ 6150 days ago | link

  Use (quit) to quit, (tl) to return here after an interrupt.
  <User>tl: (load "arc-life.arc")
  Error: "reference to undefined identifier: __<arc>car_"

Hmm. I might be doing something wrong with trying to load an arc file in ARCF.

-----

2 points by almkglor 6150 days ago | link

Hmm. Looks like a bug in some macro in Arc-F. Will find. Off the top, I can't seem to find any problems; a file like this:

  (prn "foo")
...loads fine:

  Use (quit) to quit, (tl) to return here after an interrupt.
  <User>tl: (load "test.arc")
  foo
  nil
  <User>tl:
care to send me the source you have? almkglor@gmail.com

-----

1 point by eds 6151 days ago | link

That batch file works, thanks!

-----

1 point by almkglor 6151 days ago | link

Out of curiousity: does it work even if you're on a different hard drive/directory as the installation drive/directory? The intent of that batch file is to allow you to launch Arc from anywhere, while still (1) able to access the current directory and (2) able to load library files from the arc installation directory

-----

1 point by eds 6150 days ago | link

Yes, the batch file loads fine from another drive letter.

  E:\>"C:\User\Programming\Arc\arc3f\arc-f\arc.bat"
  Use (quit) to quit, (tl) to return here after an interrupt.
  <User>tl:
That said, I am not sure how to test that it can load files in both directories... especially with the new behavior of 'using.

-----

1 point by almkglor 6150 days ago | link

Try on different directory:

  E:\> copy con tmp.arc
  (prn "hello world!")
  ^Z                       <---- that's a control-Z
  E:\> "C:\User\Programming\Arc\arc3f\arc-f\arc.bat"
  Use (quit) to quit, (tl) to return here after an interrupt.
  <User>tl: (using <files>v1)
  t
  <User>tl: (ls)
  ("tmp.arc")       <--- you should get a list of files and stuff in the current directory, including tmp.arc
  <User>tl: (load "tmp.arc")
  hello world!
  nil
  <User>tl:

-----

1 point by eds 6142 days ago | link

Works perfectly :-)

-----


Anarki supports multiple arguments too:

  (map [* _1 _2] '(1 2 3) '(4 5 6))
Note that this is currently bugged in Arc-F though. Will fix ^^.

The auto-gensyms thing looks cute. It might be possible to hack something like that, although it would require modifying the axiomatic quasiquote operator.

Basically:

  `(let foo# ,foo
     (do-some foo# foo#))
=>

  (quasiquote (let (unquote-uniq foo) (unquote foo)
                (do-some (unquote-uniq foo) (unquote-uniq foo))))
Then quasiquote has to expand to scheme style:

  (let ((gensym012032 (gensym)))
    (quasiquote (let (unquote gensym012032) (unquote foo)
                  (do-some (unquote gensym012032) (unquote gensym012032)))))
The recur bit is a lot like (afn () ... self)

-----


It seems partly a problem with srv.arc, it seems it doesn't correctly use \r\n, only \n ~.~;

See in srv.arc:

    (def header ((o type textmime*) (o code 200))
      (string "HTTP/1.0 " code " " (statuscodes* code) "
    " serverheader* "
    Content-Type: " type "
    Connection: close"))
Inspecting the file, they seem to be \n's only, not \r\n

A second problem lies in 'readline:

    (def readline ((o str (stdin)))
      " Reads a string terminated by a newline from the stream `str'. "
      (awhen (readc str)
        (tostring
          (writec it)
          (whiler c (readc str) #\newline
            (writec c)))))
It has to do with the fact that it reads in a character, BUT DOESN'T CHECK THAT THAT FIRST CHARACTER IS A NEWLINE. The only check done is with the second character read.

Will fix.

-----

2 points by cchooper 6155 days ago | link

You fixed it! Thanks!

-----

More