Arc Forumnew | comments | leaders | submit | almkglor's commentslogin
2 points by almkglor 6162 days ago | link | parent | on: Referential transparency

Why not just mod 'mac to something like (docstring extraction and name redefinition elided):

  (mac mac (name args . body)
    `(set ,name
       (annotate 'mac
         (fn ,(cons 'expansion-context args)
           ,@body))))
Then insert stuff in Scheme-side 'ac to use (apply macro the-free-list-or-whatever (cdr ex)) instead of (apply macro (cdr ex))

That way macros that need it can get it, while macros which don't need it can ignore it.

We can potentially define 'expansion-context as a table or function, and potentially we could allow an implementation to have expansion-context!line, say provide line number etc. information so that the macro can give decent error messages. Of course if we have a dorky backend (like mzscheme) then we can just have it return expansion-context!line as nil, because it can't somehow extract line numbers, but for implementations that can, then good.

edit: Oh and ye: the 'ac compiler on scheme-side really does keep a list of bound variables ^^

-----

1 point by almkglor 6162 days ago | link | parent | on: Looking for advice

I suggested adding "interfaces" to packages. So A might require <B>v1, while C requires <B>v1-modified. At the very least, loading C would fail if the copy of B available on the user's machine is the original that does not provide <B>v1-modified.

OF course, it still requires that the modified B provide the semantics for the original B so that it provides <B>v1 seamlessly.

-----

3 points by almkglor 6163 days ago | link | parent | on: Looking for advice

An alternative method of distributing individual libraries other than by dumping them all on Anarki.

Say we make a convention that we can make a new post on arclanguage.com with the post title "<library>my-library" in order to define a new library called "my-library". Library code must be indented by two spaces as normal to differentiate commentary on the library from the library code itself.

Then when 'require can't find my-library on the local copy, it uses http-get, trawls through http://www.google.com/search?q=site:arclanguage.com+%22<... , and searches for the newest post on arclanguage.com, downloads it, then parses out the library code.

LOL.

That would be cool, but probably stupid.

Basically, a really nice way to package and distribute individual libraries, a really nice way to specify dependencies.

-----

1 point by stefano 6163 days ago | link

With pack.arc you can pack a library in a directory, and then you can distribute that directory and put it wherever you like. I don't like too much the method of abusing the forum to distribute libraries. I would really like an ad-hoc application (maybe at arclanguage.org/libs), so that if require doesn't find a lib it tries to install it from arclanguage.org/libs?name=my-lib or something similar. As of today, dependencies are already handled, but the needed package must be in the search path of pack.arc.

-----

2 points by almkglor 6162 days ago | link

But that requires PG to actually do something ^^

-----

2 points by stefano 6162 days ago | link

That's the problem. Has anyone a web site where to put a shared library db?

-----

1 point by almkglor 6164 days ago | link | parent | on: Referential transparency

Well, I think it's an example of the problem I pointed out here: http://snapvm.blogspot.com/2008/07/symeval.html

-----

1 point by xrchz 6164 days ago | link

I think you're right.

-----

2 points by almkglor 6164 days ago | link | parent | on: Referential transparency

Well, I did propose a hackish extension, 'symeval, some time back. I should probably push the extension onto Anarki. T.T

  (= pusher cons)
  ; push is defined in arc.arc
  (mac my-push (e l)
    `(symeval!pusher ,e ,l))
  (let pusher (fn (x ls) (+ ls (list x)))
    (prn (my-push 'a '(b c d)))
    (prn (pusher 'd '(a b c))))
Basically symeval is a non-overrideable special form (on the same level as 'set, 'if, etc.)

http://snapvm.blogspot.com/2008/07/symeval.html

-----

1 point by xrchz 6164 days ago | link

I think 'symeval is a possible solution to this problem, and I'm glad somebody thought of it before me. But the question is why you wouldn't use 'symeval on every free variable in your macro template, just in case some newbie decides to let bind one of your "global but internal" names. If you did use 'symeval everywhere (or automatically) you would have something closer (but still a poor approximation) to scheme's hygienic macro system. I think the automatic solution to be found there is more interesting.

-----

2 points by rincewind 6163 days ago | link

I tried that. It doesn't work without knowing which variables are local and arc currently has no way of finding out, what the binding forms are, because all macros are unhygienic.

example:

  (let list '(foo bar) (do (prn list)))
    |    |   unbound    |    |    |
   mac   |             mac   | function 
      function            function

  =>(let (global list) '(foo bar) (do ((global prn) (global list))))
We know that let binds its first argument and aif binds self, but since macros are turing-complete, this cannot be automatically inferred.

-----

1 point by almkglor 6162 days ago | link

expand any macros in sub-expressions, then look at them. That's the advantage of avoiding "first-class macros", whatever their imagined advantages might be. ^^

-----

1 point by xrchz 6164 days ago | link

is it really true that 'set and 'if (and 'symeval...) are completely non-overrideable in arc? is that a convention or something enforced?

-----

1 point by almkglor 6162 days ago | link

It's enforced. For example, you can assign a macro to 'if, but it'll never be used: 'eval will always interpret 'if in its sense, and will never look at your macro.

-----

2 points by almkglor 6166 days ago | link | parent | on: Restart Points in arc/lisp

@drcode & stefano: I somehow doubt that "whole interpreter environment may be saved to a file and loaded back" can be implemented with continuations.

Well, maybe, but we'd probably need 1) destructurable functions (so we can serialize functions), 2) some way of iterating over global variables, 3) a decent sense of 'eq?, one which returns false for distinct mutable strings, preferably in an easy eq?-key-compare association table (so we can properly/easily serialize recursive structures).

Arc-on-mzscheme actually maintains a table of globals that have been ever assigned, together with the last known arc-side assignment (IIRC it actually keeps two copies of the global, one in the table and one in the actual mzscheme global variable space).

edit:

@lboard: I also somehow doubt you want to save the whole interpreter environment; probably you just want something like this:

  (mac restartable body
    `(*restartable-f (fn (restart) ,@body)))
  (def *restartable-f (bf)
    (bf (point ret (afn () (ret self)))))
Usage:

  (restartable
    (initialize-me)
    (while foo
      (if
        (some-event)
          (do-something)
        (some-error-occured)
          (restart))))
Note that 'restart is a local above, so if you need to use functions:

  (def my-do-something (restart)
    (if
      (some-event)
        (do-something)
      (some-error-occured)
        (restart)))

  (restartable
    (initialize-me)
    (while foo
      (my-do-something restart)))
This is the "continuation" solution that stefano and drcode are referring to; in general you probably want this, not necessarily saving the whole interpreter state.

-----

1 point by drcode 6165 days ago | link

you're right- I may not have thought about some of the details involved in this.

-----


Doesn't mzscheme already properly support:

   #hash((a . 1) (b . 2))

?

-----

2 points by absz 6166 days ago | link

Yes, but Arc (or at least Anarki) does not:

  arc> #hash((a . 1) (b . 2))
  Error: "Type: unknown type #f"
We can, however, read it in, but this doesn't work either, since it creates immutable hash tables:

  arc> (= h (read "#hash((a . 1) (b . 2))"))
  #hash((b . 2) (a . 1))
  arc> h!b
  2
  arc> (= h!b 3)
  Error: "hash-table-put!: expects type <mutable hash-table> as 1st argument,
  given: #hash((b . 2) (a . 1)); other arguments were: b 3"
Fixing these would probably be worthwhile.

-----

1 point by stefano 6166 days ago | link

You're right! I didn't know it.

-----

2 points by almkglor 6166 days ago | link | parent | on: Packaging libraries

How about integrating 'require and/or load with this? BTW good work!

-----

1 point by stefano 6166 days ago | link

Seems a good idea. When require sees a string it would have its standard behavior, and when it sees a symbol it loads it as a packaged library. I'll add it. I'd also like to integrate it with a namespace system, but there is none yet. You've been working on a system based on symbols, right? What's its current state? Is it usable?

-----

2 points by almkglor 6165 days ago | link

It'll end up forking Arc I'm afraid: I'm doing the system in the scheme side. I've gotten the translation up, but I'm still testing it. ^^

-----

3 points by stefano 6165 days ago | link

> It'll end up forking Arc

This is becoming unavoidable. This is really a pity, but the official Arc development is simply too slow (assuming it is moving, a quite optimistic assumption).

-----

1 point by almkglor 6161 days ago | link

Integrating it into my forked Arc, but sadly something is interacting badly with the compiler and some macro is getting stuck in an infinite loop (which, if I don't catch with a ^C early enough, will force me to actually restart my computer T.T), probably from an incorrect compile. I'm debugging it currently >.<

-----

2 points by almkglor 6160 days ago | link

Debugged! Now I just need to rewrite bits and pieces of arc.arc to clean it up and make it follow a more "axiomatic" path that will allow you to do neat things, like define how (+ (your-type 1 2) 42) will be (and adding hacks into ac.scm so that the axiomatic path isn't so slow).

-----

1 point by stefano 6165 days ago | link

Integration done and on Anarki. Now (require 'mylib) loads 'mylib and (require "file.arc") loads, as usual, "file.arc".

-----


As fallintothis mentioned, destructuring assignment conflicts, badly, with 'scar/scdr and 'sref assignment.

> Something that should be researched is if having an array type is not a premature optimization.

It is. Lua-like array+hashtable implementations should be standard stuff for dynamic languages already IMO.

-----

2 points by almkglor 6167 days ago | link | parent | on: Pipe operator

Avoiding apply:

  (def >> (parm . args)
    ((afn (parm args)
       (if (no args)
           parm
           (self ((car args) parm) (cdr args))))
     parm args))

-----

4 points by rincewind 6167 days ago | link

Avoiding re-inventing rreduce:

  (def >> args
     (rreduce (fn (a b) a.b) rev.args))

-----

3 points by almkglor 6167 days ago | link

Avoiding rev:

  (def >> args
    ; throw an error here so that user won't get
    ; mysterious errors in the 'reduce part
    (if (no args)
      (err "'>> requires at least one argument"))
    (reduce (fn (a b) b.a) args))

-----

More