Arc Forumnew | comments | leaders | submit | chandler's commentslogin
3 points by chandler 6127 days ago | link | parent | on: New version

What you're proposing is an alternate non-parenthetical syntax (i.e. x.y.z => (x y z)). Careful! Down this road lies ruin.

-----

4 points by EliAndrewC 6127 days ago | link

While I agree that this shouldn't be abused, I'm not actually proposing this syntax; Arc already lets you say cut.x.1.3 as an alternative to (cut x 1 3).

I suspect that the only time I'd ever want to chain together several different things with . is when I'm doing list slices. Which is why I'd like the x.1.3 syntax to work, since in my opinion cut.x.1.3 is a lot uglier, perhaps enough that I'd rather not do it.

-----

3 points by chandler 6136 days ago | link | parent | on: Two brief ideas

Regarding question two:

I've been pleasantly surprised by how easy it is to read the arc code; and this is without ever starting the interpreter (the 350/372 lag is a killer for me, as I have quite a few apps written for 372). As a bit of background, I'm pretty familiar with scheme itself, and I tend to use mzscheme (both for its wealth of libraries and cross-platform stability). I've also written a fair share of elisp over the years, and can dork my way through other peoples CL code.

At a superficial level, I like the combination of lisp-1 and t/nil; if it manages to avoid scheme's overboard strictness, all the better ( (cdr ()) throws an exception, rather than returning (); substrings, indexing, etc all need to be exact, or an error is thrown). I also really like the if-over-cond replacement.

One thing I've found is that the terseness and paren reduction make it easy to use Arc (the language) to sketch out functions in (say) html edit boxes and paper; I definitely like the "feel" of the written code. As an example, yesterday I found myself sketching out a clojure-style generic function interface, to describe (e.g.) the Arc + operater within Arc itself:

  ;; defg(eneric), this is a "switching" function:
  (defg + args
    (if (no args)                  'zero
        (all 'num (map type args)) 'nums
                                    (type:car args)))

  ;; defa(dd-method), this defines specialized functions:
  (defa + 'zero () 0)
  (defa + 'nums args (apply num-plus args))
  (defa + 'table args (apply merge-tables args))
  (defa + 'default args (apply concat (map str args)))
The Arc language itself seems to lend itself to impromptu sketches like the above, without having to necessarily fire up emacs for paren-counting and fuzzy-complete.

-----

4 points by chandler 6136 days ago | link | parent | on: Is Arc good for big projects?

As far as I can tell, having a purely closure-based module system won't actually solve the lisp-1 redefinition problem; to use your module system, some manner of compile-time token capture is necessary. Essentially, the problem is:

  (= my-module
     (let obj (table)
       (= (obj 'rem-xs) (fn (s) (rem #\x s)))
       ...
       obj))

  ((my-module 'rem-xs) "abcxdefxghi") ;; => "abcdefghi"
Now, suppose I redefine "rem" at the toplevel to be like the BASIC rem, or a remark function that ignores its parameters:

  (def rem args
    nil)

  ((my-module 'rem-xs) "abcxdefxghi") ;; => nil
I think Arc uses a lexical scope, so this problem shouldn't show up in the following example:

  (aload 'my-module)

  (let rem (fn args nil)
    ((my-module 'rem-xs) "abcxdefxghi"))

  ;; => "abcdefghi"
However, you would need to be careful when attempting some kind of dynamic import:

  (let rem (fn args nil)
    (aload 'my-module)
    ((my-module 'rem-xs) "abdxdefxghi"))

  ;; => nil
I think the former (though not latter) problem can be mitigated by shadowing all functions/globals you want to stay invariate, as in:

  (= my-module
     (with (rem rem
            table table
            fn fn
            obj (table))
       (= (obj 'rem-xs) (fn (s) (rem #\x s)))
       ...
       obj))

  ((my-module 'rem-xs) "abcxdefxghi") ;; => "abcdefghi"
However, as you can imagine, this will get unwieldy fairly quickly (like you, I've downloaded the arc0.tar file, but not actually bothered to downgrade my copy of plt-372; i.e., I'm not sure how canonical the provided arc snippets are).

Of course the ignored caveat is this: so many bloggers are up in arms over this point, it's presupposed that being able to change core library functions is a defacto terrible thing--at work, where we have a massive C/C++ codebase running on some unmaintained, sourceless, legacy APIs, being able to (for example) add/fix methods in some of the base classes would be a significant time-saver.

I think Arc as-is makes it a bit too easy to shoot yourself in the foot; however, I'm firmly in the camp that being able to update core functionality should be allowable.

Also, for better or worse, look at emacs: a massive, mature system that contains no module/namespace system, no closures, and, due to its dynamic scope, would fail each of the above examples. I'm not saying I hope Arc emulates these (lack of) features, however, it's still proof that they're not necessary for large, real-world (whatever that means) projects.

-----

3 points by cpfr 6136 days ago | link

The big problem is def and =s update a global symbol table. They are not like Scheme and define. If def obeyed local scoping rules and could be shadowed, the problem is shadowing has to be done explicitly. That is why this is painful and unwieldy. Ultimately, this needs to be fixed or Arc will be needlessly crippled.

-----