Arc Forumnew | comments | leaders | submitlogin
2 points by almkglor 5892 days ago | link | parent

> I could just read all the Arc source code and try to remember everything, but I don't have enough time.

This is what I do every week.

LOL.

I need a girlfriend wahahahahahaha

As an aside, I've been forking Arc to include the symbol-based packages, and the 'interface thing is a rather nice documentation in and of itself: it's kinda like a summary of the functions available, sort of like a "table of contents".



2 points by stefano 5892 days ago | link

I'm looking forward to see your fork released! Have you introduced any relevant incompatibility with Anarki?

-----

5 points by almkglor 5892 days ago | link

Yes, off the top of my head: 'each on tables gives you the cons pair (k . v), instead of just values. passing strings to 'map for third->inf arguments no longer infects the output type; rather, the output type is always the type of the second argument.

t and nil are now boolean types, not symbols. Sorry. It's hard to reason about them with the newfangled type-based methods if they're symbol types instead of booleans.

Also, because of contexting, asv.arc will have to be rewritten so that it unpackages symbols in (defop ...) and related forms. If it's not rewritten, you'll have to use example.com/%3CUser%3Cyour-page instead of example.com/your-page . I think most asv-based applications will work properly if asv.arc is modded thus.

Also, most of your source files will probably need something like:

  (in-package my-file)
  (using <arc>v3)
You can leave that out but that means you'd be putting stuff in the <User> package, which is supposedly for exploratory scratch purposes (if your source is scratch, well then leave it out by all means ^^).

Note that <arc>v3 does not even include all arc functions (for example <arc>v3-thread, which includes the threading stuff). There are some rationales for not including everything in <arc>v3, most notably for bits and pieces that are reasonably hard for other implementations, such as threads.

Also, the fork is somewhat slower, especially for function calls T.T . So far I haven't experienced particularly serious slowdowns (due to some serious crazy optimizations in ac.scm that were mostly inspired by my experimentations with implementing the SNAP interpreter).

However the fork does have nice advantages. For example, it has generic functions with methods. So far it's just the ordinary dispatch-on-first-argument-type but I hope to expand that in the future to create full-blown generic functions with dispatch-on-any-combination-of-argument-type.

Also, it's now much easier to integrate your own types into the base arc.arc . For example you can create your own sequence types which will work with 'map, 'join etc. Those functions will even return your type, i.e. map on your type will return the same type. Generic programming FTW!

And of course, packages, whose integration was the biggest headache in the fork T.T . Largely because I decided that everything that gets passed to the compiler should already be in packages; this includes fn -> <axiom>fn etc.

It can be launched from any directory, and will remain in that directory when you program, unlike Anarki which always cd's to the installation directory (but it will auto-search the installation directory for any 'load calls you make)

Slated for future is also a way to define ssyntax that works only within the scope of a package, meaning using your own ssyntax in one package won't affect another package.

-----

2 points by stefano 5891 days ago | link

I thought it was just about packages, but it is a much larger change! Well done! We really needed something new. I'll now look into integrating pack.arc with your package system.

-----

1 point by almkglor 5890 days ago | link

Thanks. You may wish to look through lines 381-383ish on ac.scm, which is the bit which calls 'require when you're trying to (using ...) some package.

I think pack.arc is nice enough to integrate into ac.scm and arc.arc (at the very least the package loading part; you can probably still retain the bit that creates packages into pack.arc, since it'll probably be used rarely enough)

Also, it might make sense to use the same context object for each file in a pack.

-----

1 point by stefano 5890 days ago | link

> you can probably still retain the bit that creates packages into pack.arc

Yes. I've written that part (defproject and related functions) as a base for a not-yet-written Arc IDE.

-----

1 point by bOR_ 5891 days ago | link

  "t and nil are now boolean types, not symbols. Sorry. It's hard to reason about them with the newfangled type-based methods if they're symbol types instead of booleans."
It's a bit hard for me to understand the consequences of this, and as you seem to be sorry about the change, I assume there are some consequences worth noting. Could you elaborate?

-----

1 point by almkglor 5891 days ago | link

It has to do with overloading 'car and 'cdr.

'car and 'cdr are now overloadable - see for example lazy-scanner.arc in arc-f/lib .

However classically (car nil) => nil and (cdr nil) => nil.

So basically we have something like this:

  (def car (x)
    (err "can't apply 'car to object" x))

  (defm car ((t x cons))
    ...some scheme-side code....)

  (defm car ((t x bool))
    (if x
        (err "attempt to scan t")
        nil))
Of course we could probably still retain t and nil as symbols. However the user might want to define iterating over symbols for some arcane purpose (exploratory, exploratory...). If 'nil is a symbol, the user has to specifically check for the nil symbol when overloading 'car for symbols.

The reason I'm sorry is really because I'm not 100% sure it's the Right Thing (TM), and because I really had to go on with Arc-F instead of dithering over 'nil.

-----

1 point by cchooper 5890 days ago | link

Of course, you still have the problem that nil is both a boolean and list :)

-----

2 points by almkglor 5890 days ago | link

Ah ah ah.... no! The cute thing is that a 'bool presents the "scanner abstraction". Basically, a scanner is anything that overloads the functions 'car, 'cdr, 'scanner, and 'unscan. Thus, you don't have to check for the type of an object: you just need to pass it through 'scanner. If 'scanner throws, it's not a "list". If 'scanner returns a value, you can be sure that it returns a value that will be legitimately passed to 'car and 'cdr.

From this point of view, a "list" is anything that happens to be a scanner.

So nil is a list. So are 'cons cells. So are anything that overloads 'scanner, 'unscan, 'car, and 'cdr.

Try:

  (using <lazy-scanner>v1)
...then play around with (lazy-scanner a d)

Or for a bit of ease of use generate an infinite list of positive integers (after doing the 'using thing):

  (generate [+ _ 1] 1)
Edit: to summarize: a list is not a cons cell. A cons cell is a list. ^^

-----

1 point by cchooper 5890 days ago | link

Ah...but...what if you want to define a generic function that operates differently on lists and bools (i.e. not a scanner, but a general generic function). I haven't had a close look at Arc-3F yet, so maybe I need to play around a bit more to uderstand what you're saying :)

-----

1 point by almkglor 5890 days ago | link

Well, a "list" is a "scanner". So your "not a scanner" doesn't make sense, at least from the point of view of Arc-F.

However if you mean "list" as in sequence of cons cells:

  (def works-on-cons-cells-and-bools (x)
    (err "this works only on cons cells and bools!"))
  (defm works-on-cons-cells-and-bools ((t x cons))
    (work-on-cons-cells x))
  (defm works-on-cons-cells-and-bools ((t x bool))
    (work-on-bool x))
Note that you can even define a unifying "type class" function which ensures that the given data is a cons cell or a bool, or is convertible to one (i.e. an analog to 'scanner). For example, you might want a "hooper" type class:

  (def hooper (x)
    (err "Not convertible to a bool or cons cell" x))
  (defm hooper ((t x cons))
    x)
  (defm hooper ((t x bool))
    x)
Then you can convert works-on-cons-cells-and-bools with the type class:

  (def work-on-hooper (x)
    (works-on-cons-cells-and-bools (hooper x)))
Then, someone can make a type which supports the "hooper" type class by either overloading hooper (and returning a true hooper), or overloading hooper and works-on-cons-cells-and-bools:

choice one:

  (defm hooper ((t x my-type))
    (convert-my-type-to-cons x))
choice two:

  (defm hooper ((t x my-type))
    x)
  (defm works-on-cons-cells-and-bools ((t x my-type))
    (work-on-my-type x))

-----

1 point by bOR_ 5890 days ago | link

in reply to the summary: nice.. some day I'll have to look into the bellow of the beast. Arc3F no longer has lists build up from cons?, or lists are build from cons which are a special kind of lists.

-----

2 points by almkglor 5890 days ago | link

Well, I prefer to think of cons-as-lists as one implementation of lists. It's possible to define alternative implementations of lists; all that is necessary is to define the overloads for 'car, 'cdr, 'scanner, and 'unscan. With generic functions in Arc-F, that is enough to iterate, cut, search, filter, join, map, and more on any list, regardless of whether it's made of 'cons cells or 'lazy-scanner objects.

-----