Arc Forumnew | comments | leaders | submit | raymyers's commentslogin
5 points by raymyers 6324 days ago | link | parent | on: premature optimizations in Arc

Most OO languages don't just "implicitly bind" self; self (or this) is usually a reserved word. A conflict with another variable is made impossible because you can't say "int this = 4" in Java or C++. As pointed out, Python already makes the binding explicit.

Further, let us imagine for a moment that lambda closures and class instances are ... different things.

-----


Hey look, another thing the interpreter sees as EOF. Other favorites include "\!" and ".a".

-----

5 points by raymyers 6325 days ago | link | parent | on: On the need for garbage collection

It's no laughing matter!

"Conses don't grow on trees" -- Gerald Sussman.

Oh wait... that's exactly where they grow, isn't it?

-----

3 points by raymyers 6326 days ago | link | parent | on: Arc and The Emperors Old Clothes

It's obvius he was being ironic to emphasize that care must be taken in language desingn.

-----

1 point by mecon 6322 days ago | link

It's just a typeo.

-----

8 points by raymyers 6326 days ago | link | parent | on: Modules : a proposition

Perhaps modules should be valid containers. Thus instead of introducing a new syntax foo@a, we can use (foo 'a) and foo!a using sugar already in place. (I realize I am not the first person to say that.) I also would not like having to use mdef and m= within a module. Ideally, I should just use def, mac, and = as normal and export the symbols I want visible from outside.

    (module foo (export a bar)
      (= a 'in-top)
      (def foo (x) (+ x 1))
      (def bar (x) (+ x 1))
      (pr a))
    (prn foo!a)
    (foo!bar 0)
    (= bar foo!bar) ; an import.
    (= a2 foo!a)    ; a qualified import.
This could all be implemented as an optional library, except for those pesky macros. And of course, we do need a module system with adequate macro support.

-----

1 point by sacado 6326 days ago | link

What about something like what you are proposing, but where you have to explicitly state when you use the module namespace, since we obviously can't overwrite = without sad effects ?

For example, let's take the $ symbol (another ugly one :) to mean "the current module". The above could be written :

  (module foo (export a bar)
      (= $!a 'in-top)
      (def $!foo (x) (+ x 1))
      (def $!bar (x) (+ x 1))
      (pr a))
    (prn foo!a)
    (foo!bar 0)
    (= bar foo!bar) ; an import.
    (= a2 foo!a)    ; a qualified import.
Advantages : - very simple - written in pure Arc (thus candidate to the core language)

Here's a macro implementing part of that behavior : (= $ nil) (= $path* '()) ; Current module hierarchy

  (mac module (name . body)
        (w/uniq old-$
                `(with (,old-$ $)
                        (= $ (table))
                        (push $ $path*)
                        ,@body
                        (pop $path*)
                        (if $path*
                                (= (,old-$ ',name) $) ; Put it in the parent
                                (= ,name $))          ; Put it in global namespace
                        (= $ ,old-$))))
It supports imbricated modules. To import a module, or do a qualified import, the classical table manipulation functions work.

  (module foo
    (module bar
      (= $!baz 'arc)))

  arc> foo
  #hash((bar . #hash((baz . arc))))
  arc> (= bar foo!bar)
  #hash((baz . arc))
  arc> bar!baz
  arc

-----

2 points by raymyers 6325 days ago | link

It sounds like several of us are working on different module ideas. How about we start throwing our prototypes in a `lib/module' directory on the git?

-----

1 point by almkglor 6325 days ago | link

Done, hacking off yours since it was already there ^^

-----

2 points by almkglor 6326 days ago | link

This requires us to have decent code-traversal.

Question (dunno the answer, not on my hacking computer): how will a macro receive the expression (foo:bar foo)? As (foo (bar foo))? as ((compose foo bar) foo)? As (|foo:bar| foo)? (|| is used to enclose a literal in symbols)

-----

1 point by sacado 6326 days ago | link

  arc> (macex 'foo:bar)
  foo:bar
Too bad :(

-----

3 points by cooldude127 6326 days ago | link

i like the looks of this. i fully support taking advantage of the simplicity arc already has.

-----

1 point by sacado 6326 days ago | link

There's a problem with using = and def. I tried it, but many parts of the core and libraries assume a unique namespace. As commands can have many side-effects, everything breaks easily.

But the idea of using tables is excellent.

-----

1 point by sacado 6326 days ago | link

Anyway, we must be able to access the global namespace too. If you overwrite = and def, you can't. Or you have to define g= and gdef :)

-----

4 points by almkglor 6326 days ago | link

Here's a different idea. Suppose that instead we build a basic modulesystem which transforms:

  (modules-base
     ;name of module.
     foo
     ;set of functions in this module
     (bar)
     ;set of module variables
     (nitz)
     ;set of functions from other modules
     ((module2 hmm niawniaw))
     (def bar (x) (hmm) (niawniaw) (do1 nitz (= nitz x))))
to:

  (= foo
     (with
        (bar nil nitz nil hmm module2!hmm niawniaw module2!niawniaw)
       (= bar (fn (x) (hmm) (niawniaw) (do1 nitz (= nitz x))))
       (fill-table (table) 'bar bar)))
Then we create another macro which simply scans through the code for (def ...) forms and transforms the following code:

   (module foo
     (use module2)
     (module-vars nitz)
     (def bar (x) (do1 nitz (= nitz x))))
to:

  (modules-base
     foo
     (bar)
     (nitz)
     ;gotten by taking (keys module2)
     ((module2 hmm niawniaw))
     (def bar (x) (do1 nitz (= nitz x))))
Weaknesses: (1) we can't make module-variables accessible outside. If we had access to environments, though, we could.

(2) macros are impossible as yet, whether shared or not. Possibly, we need macrolet, and adding some mechanism to store macros separately from the module table - possibly in a table-of-tables module-macros.

Implementation: simple scanning would be nice. However, modules-basic would be better implemented by a 'macrolet form.

Conclusion: We need macrolet.

-----

3 points by raymyers 6327 days ago | link | parent | on: Exemplary examples of LOOP

In cases anyone wants to take the efficiency thing seriously, this is what we are up against:

   http://paste.lisp.org/display/56189
And mind you, we don't even have one of those fancy-pants `goto' things.

-----

1 point by kennytilton 6327 days ago | link

That reminds me, I ended up reinventing Cells over the table in Arc because the real deal was so big it would have been a heckuva project, but I started on the actual code and... whoa! I have one chunk I found easiest to express as a very simple state machine using Common Lisp's tagbody/go and I had very little confidence in my conversion to a functional solution.

-----

2 points by raymyers 6327 days ago | link | parent | on: Map and Strings

You gave `map' strings as input, so it attempts to return a string. That means it is trying to map the output of `is' into the characters of a string, but t and nil aren't charactors.

  (def char-is (a b) (if (is a b) #\t #\f))
  (map char-is "abba" "abab")  =>  "ttff"
Common Lisp addresses this issue by having `map' take a result type as the first argument.

http://www.lisp.org/HyperSpec/Body/fun_map.html

-----

2 points by raymyers 6328 days ago | link | parent | on: Anarki Conventions

True. Anarki-only macros should probably be banished to the `lib' folder, so they have to be (require)'d before they start modify your code.

-----

2 points by nex3 6327 days ago | link

I'm not so sure about this. I think changes of the filling-up-namespace sort are reasonable, for the same reason being a Lisp-1 is reasonable: conflicts happen rarely in practice.

A better solution would be to try to ensure that only generally useful macros are added to arc.arc, and that they have names that are unlikely to be used as local variables. Or even better would be to make local variables shadow macros.

Consider this, though: "help" is defined as a macro. Some of the REPL-var code needs macros. The drop-into-scheme operator is a macro. I don't think we want to make people load a library file to use these.

I see the compatibility rule as more of a guideline - try not to break the functionality of stuff that already exists. But I don't think it should limit experimentation and exploration, including exploration of what's useful to have in arc.arc.

-----

2 points by raymyers 6327 days ago | link

OK, I'll backpedal a bit here. The last thing I want is to have to require "lib/help.arc" :). It should be easy to find out what macros have been added though -- as much for curiosity as for compatibility. I'll try and whip up a script tonight, unless someone beats me to it.

-----

4 points by raymyers 6327 days ago | link

Script complete. It crawls `arc.arc' and every file loaded by `libs.arc'. So now, if you type the following,

    (require "lib/new-macros.arc")
    (new-macros)
... you will discover that the non-Arc1 macros in Anarki are currently:

    ($ % % %% %%% breakable defsop help make-br-fn or= redef)

-----

1 point by nex3 6327 days ago | link

Most excellent. It's great to see how easy it is to analyze Arc code using Arc.

Anyway, of those, the only one I see potentially conflicting with a variable name is "breakable", and that seems quite unlikely.

-----

2 points by akkartik 6327 days ago | link

Great thread to see how y'all converged on a design decision after some back and forth.

-----

2 points by raymyers 6328 days ago | link | parent | on: Anarki Conventions

If anyone notices an issue regarding Anarki's compatibility with Arc, please note it in BUGS. Thanks :)

-----


I like that you added gaurd syntax.

    ;; foo [a,b] | a < b = True
    (p-m:def foo (,((a b) (< a b))) t)
    (foo '(1 2))  =>  t
But is there any way to test across parameters?

    ;; foo a b | a < b = True
    (p-m:def foo (a ,(b (< a b))) t)
    (foo 1 2)  =>  Error

-----

2 points by almkglor 6328 days ago | link

Not yet, although I'm working on it. The main problem is that currently, destructuring splits on the (car ...) and (cdr ...) of each list node in the pattern, something like this:

  ;a is the variable that contains the current list node of the function input
  ;p is the pattern
  `(and (acons ,a)
        ; this creates the test
        (let ,a (car ,a) ,(self a (car p)))
        (let ,a (cdr ,a) ,(self a (cdr p))))
Obviously, I'll need to resequence them - the cdr branch has to be physically located within the car branch, so that I can capture any variables in the created guards.

-----

2 points by almkglor 6328 days ago | link

  ,((a b) (< a b)))
LOL. I didn't even realize this was legal code. But mind you, Arc will be the one destructuring the pattern within the first element of ,(... ...), meaning it won't count the number of elements and all that. Hmm. Note sure if going recursive here is a good idea. Hmm.

-----

1 point by shader 6214 days ago | link

Um, how does that work?

-----

More