Arc Forumnew | comments | leaders | submit | best commentslogin
10 points by absz 6582 days ago | link | parent | on: When is the next Arc-version coming out PG?

I had been under the impression that it was supposed to last for one hundred years, not languish for one hundred years, but I suppose I might have misread something :/

cough hundred-year language cough
10 points by garnet7 6151 days ago | link | parent | on: Arc 3.1 (works on latest MzScheme)

Docs can make or break a free software project.
9 points by pg 6198 days ago | link | parent | on: New Features

That's actually one of the things I'm working on next.
9 points by pg 6331 days ago | link | parent | on: Arc presentation

I don't know what exactly agile developers would care about, but the guiding principle of Arc is to make programs short. Partly because that's what programming languages are for, but also because programs are meant to be changed, and shorter programs are easier to change. The latter part sounds like it should be relevant to them.
9 points by stefano 6434 days ago | link | parent | on: Where are we going?

> These are just bugs

This is one reason why it is important for you to be here: some simple things like the problem with 'splice are clearly bugs, but other things are not. For example, the fact that '(1 . 2 . 3) reads as '(2 1 3) is just something drained accidentaly from mzscheme's reader or is part of Arc? Since you've written Arc, you're the only one to really know this. We can only suppose.

9 points by almkglor 6435 days ago | link | parent | on: Where are we going?

I get this feeling that Arc is the language that is just going on by momentum.

Further, I don't think Arc, PG version, is as well-designed as you think.

For example: "code is spec". Apparently the code itself is to be the specification for the language. However, this brings up some questions: for example, does the fact that (ssplit '(1 2 3) 0) return ((1) (2 3)) part of the specification, or is that a bug? http://www.arclanguage.org/item?id=8450 .

Or how about the cute little fact that the PG 'map function can be safely recontinued when you capture the continuation in the mapping function if the given structure is a list, but is not safely recontinuable if the given structure is a string? Is this a deliberate design decision, an oversight, or something you don't specify and so any other implementation can do what they want?

And while tagging allows the programmer to arbitrarily create new types, those new types don't get along well with the builtin functions. I can't build a vector type in PG Arc that will work with the builtin functions. I can't build a quaternion type which I can multiply with a scalar number using '* .

These are design points which have been belabored for years; Brooks in 1975 attacked using "implementation as spec", pointing out that it limits future implementations by forcing them to always use the old implementation, for example.

9 points by jimbokun 6435 days ago | link | parent | on: Where are we going?

Your mantra in your role running Y-Combinator is "make something people want."

Is Arc exempt from that?

9 points by drcode 6496 days ago | link | parent | on: Things to know before learning Arc?

none.

Arc is, arguably, simpler than either Scheme or Common Lisp. The only reason for learning these other languages first, in my opinion, would be because of the greater availability of teaching materials.

In fact, if there's any language I'd recommend learning before arc it would be Haskell. You'll enjoy arc much more if you have a good understanding of functional programming first. The best way to do that (although a pretty hardcore way) is to learn Haskell.

9 points by stefano 6537 days ago | link | parent | on: A native Arc compiler for Linux

As you will see from the link, the compiler is still far from being complete, but is has macros and it can compile itself. I know that this project is quite overlapping with arc2c (it generates assembly instead of C), but I started the project from scratch to learn more about compilers and not to build a full-blown Arc system. This is why the name is "Not Yet an Arc Compiler" -- I don't know if it will ever be Arc compatible, but I hope one day it will be :)

I briefly tried porting Arc to the new PLT Scheme earlier, and ran into problems. I have some suggestions at http://arclanguage.org/item?id=7057

As for lojic's question about why not just use PLT Scheme? That's a very good question. Personally, I find Arc has a lot of negatives compared to PLT Scheme, and the only positive I see is the macro system isn't confusing like Scheme's. Arc also provides the excitement of exploring new territory, but I think I've about exhausted that.

What about the rest of you? Why use Arc instead of Scheme? (Maybe this should be a top-level question?)

9 points by almkglor 6594 days ago | link | parent | on: (delist somelist)

  (apply map + your-expression)

MzScheme has mzc, which does bytecode compilation. You can create something like standalone executables by embedding a copy of MzScheme into the module you're compiling. See http://download.plt-scheme.org/doc/372/html/mzc/ for more details.

Using some work done on Anarki (http://github.com/nex3/arc/blob/dca901c0cb59ebb533a511df3a84... and http://github.com/nex3/arc/blob/dca901c0cb59ebb533a511df3a84...), you could throw together something like:

test.arc

  (prn "Hello, world")
arc-exe-init.scm

  (module arc-exe-init mzscheme
    (provide (all-from-except mzscheme read read-syntax)))
test.arc.scm

  (module test.arc "arc-exe-init.scm"

    (require "ac.scm")
    (namespace-require "ac.scm")
    (require "brackets.scm")
    (use-bracket-readtable)

    (aload "arc.arc")
    (aload "libs.arc")

    (aload "test.arc") ; or the output of (acompile "test.arc") could work
  )
Then

  $ mzc --exe test test.arc.scm
  mzc version 360, Copyright (c) 2004-2006 PLT Scheme Inc. 
  [output to "test"]
  $ ./test
  Hello, world
The results you get hardly seem worth the effort. With this, you'd still need to distribute with some form of ac.scm et al.

  $ mv test ~/Desktop/
  $ cd ~/Desktop/
  $ ./test
  default-load-handler: cannot open input file: "~/Desktop/ac.scm" (No such file or directory; errno=2)

   === context ===
  #f::352: loop
There are probably smarter ways of compiling that don't have this hang-up, but in the end you'll still have kind of a large binary with MzScheme embedded.

If you just want the Scheme equivalent of Arc code, Arc already compiles down to Scheme. To get this compiled version (even if you can't run it directly without loading ac.scm, brackets.scm, arc.arc, and libs.arc):

  $ cat test.arc
  (prn "Hello, world")
  $ mzscheme -m -f as.scm
  Use (quit) to quit, (tl) to return here after an interrupt.
  arc> :a
  > (acompile "test.arc")
  Hello, world
  #t
  > ^D
  $ cat test.arc.scm
  (ar-funcall1 _prn "Hello, world")

There are two classes of people: people who want to pay you, and people who don't.

Consider focusing all your attention on people who want to pay you. How can you make it really easy for them to pay? What do they want, and how can you do more of that for them? How do you find more people who want to pay you, how do you let them know you exist? Is your app so great that the people who want to pay you are telling their friends who want to pay you?

People who don't want to pay you don't make any difference whether they're using your service or not (you're not getting any money from them either way), unless there are so many of them that it's costing you something in server load or your time, in which case you can do something about it based in the specific pattern of abuse that you're getting.

It think that trying to force people who don't want to pay you to pay you is probably wasted effort, they'll just go away and not pay someone else :-)

8 points by lg 6217 days ago | link | parent | on: New Version of Arc

hmm, this bit me... can't use each within an afn because each uses afn internally, and it leaks the 'self binding into the body. I changed it to use an rfn with a uniq name and it works.
8 points by pg 6218 days ago | link | parent | on: New Version of Arc

Oops, should have mentioned you have to use MzScheme v372.

Arc has mutable conses, so it would have been hard to make it work with versions of MzScheme after they switched to making lists immutable.

8 points by CatDancer 6333 days ago | link | parent | on: Arc presentation

The first thing that comes to my mind is more of a philosophy rather than a feature. One of the Agile principles is don't implement things until you need them... no speculative development: the tenth principle down in http://agilemanifesto.org/principles.html reads "Simplicity--the art of maximizing the amount of work not done--is essential." The XP process implements this with its rule that you only write code to implement the current iteration, no writing code to implement features that you "know" will be coming in future iterations.

When I first read the Arc web server code (srv.arc) I was astonished at how simple the code was.

srv.arc doesn't do everything I want, but other web frameworks don't do everything I want either. And I've found it much easier to hack srv.arc to do what I want, precisely because it isn't massively bloated with "framework" stuff, stuff that we imagine we'd need to write a web application, but we don't actually need or it turns out we need in some other way when we actually write an application.

Showing off how easy srv.arc is to hack is a great example of the Agile simplicity principle. Need to get a servlet to output a custom header? Plow through the documentation to find the right addHeader() invocation and what object to call it on. Need to get Arc to output a custom header? (prn "My-header: foo")


Gee, man, it was just a friendly question. I don't think any reasonable people here actually expect Paul to prioritize hacking over his wife and baby.

Your comment sounds a lot like what I'd expect on comp.lang.lisp. I get what you were trying to express, but please tone it down a little.

8 points by skenney26 6361 days ago | link | parent | on: This would make my programs shorter.

Why not just 'hash? Using 'hash would also help to distinguish hash-tables from html-tables in html.arc
8 points by CatDancer 6377 days ago | link | parent | on: Ask Arc: does code have to be text?

If you'd like to use some symbols for particular functions, you don't need an IDE... or anyone's permission :-)

  arc> (= ¬ no)
  #<procedure: no>
  arc> (¬ t)
  nil
  arc>
8 points by jimbokun 6435 days ago | link | parent | on: Where are we going?

Perl, Python, and Ruby are successively closer approximations of Common Lisp.

I admire the ideas behind Clojure because it makes a different set of design decisions from Common Lisp. This seems to have even gotten the attention of Common Lisp developers, and those guys are pretty hard to impress.

The focus on immutability, literals for data structures other than lists that share a common "seq" interface, first class functions and closures, multi-methods without OO, lazy sequences, and full fledged macros hit an interesting sweet spot that is not touched by any other language I know. Mr. Hickey has managed to put all of those things together in a way that strengthen, reinforce, and complement one another. That is an impressive feat of language design.

My point is that Clojure is not "just" popular. By making unique decisions about the semantics of the language, and not just improving the syntax over the semantics of an existing language, Clojure may very well be one of those languages whose ideas remain influential long after it stops being popular.

(I'm curious, does Arc innovate in terms of its semantics being significantly different than its predecessors? It seems to have the goal of taking existing Lisp paradigms and making it possible to express them more succinctly. But I might be missing something important.)

So, even by the criteria you put forth, Clojure might be a language worth watching.

8 points by pg 6435 days ago | link | parent | on: Where are we going?

These are just bugs. Good design doesn't equal not having bugs. If it did, someone who merely patched bugs in a system would be a great designer.
8 points by SwellJoe 6435 days ago | link | parent | on: Where are we going?

Perl had the popularity Arc could have had. Then Python did, then Ruby.

I will point out that Perl still has the popularity. Python and, particularly, Ruby have dramatically fewer developers and lines of code than Perl. But, then, Perl has fewer developers and lines of code than PHP. So, unless PHP is the exception that proves the rule, the popularity argument is obviously moot. But, I do think there's something to be said for pragmatism. While Perl (or Python, Ruby, etc.) has its flaws, it also has a vast community of people working on solving them...will Perl 6 be ready before arc is usable for a similarly wide array of problems? Seems pretty likely.

8 points by projectileboy 6435 days ago | link | parent | on: Where are we going?

This is just one guy's opinion, and I'm hardly a 133t Lisp hax0r. But I'm not a part of this community to ride the next big wave. I'm here because I'm tired of the next big waves, because they almost always suck. I'm here because I want to be able to latch on to something that actually provides me with some small measure of joy, and that has a chance of having some real, lasting impact.
8 points by rincewind 6510 days ago | link | parent | on: Improve this function?

  (def rec-avg (lst)
     (if acons.lst
         (/ (apply + (map rec-avg lst)) len.lst)
         lst))
8 points by almkglor 6558 days ago | link | parent | on: Response to the Arc Challenge

> But there's a bigger question: ever since I started writing web apps, I've heard the mantra "keep no state on the server". Arc's continuation or closure thing looks like it's totally breaking the rules. "What about scalability!!", as we say in javaland. So someone's got it all wrong, and why doesn't Hacker News fall over more often?

As far as I know Hacker News is only one server. Presumably it's pretty well tuned, and besides, there may be lots of hackers there, but I'm sure the readership is much less than, say, friendster, which I'm sure has to solve larger scalability problems.

This may also very well be the reason why Yahoo rewrote Viaweb ^^

> the server needs to store 30 separate closures

Closures are cheap ^^. For example in arc2c, a closure has one cell (cell=4 bytes for 32bit, 8 bytes for 64bit) for type, one cell for length, one cell for function, and one additional cell for each captured variable. Often the captured variables are just one or two, so on a 64-bit system you're looking at 40 bytes for each closure.

On the other hand a string might take up just as much space, and would result in not-so-clear code.


Well, since I voted for the basic library with sin, cos, pi, gcd, etc, I felt obligated to implement a basic math library with sin, cos, pi, gcd, closely related fucntions, and everything I needed or thought I'd need to implement those.

Implementations guaranteed not to be optimally efficient:

Edit: Fixed a mistake in bringing out-of-period numbers into period in sin and cos

  (= pi 3.141592653589793238)
  (= 2*pi (* 2 pi))
  
  (def signum (n)
    (if (> n 0)
        1
      (< n 0)
        -1
        0))
  
  (def floor (x)
    (if (< x 0)
      (- (trunc x) 1)
      (trunc x)))
  
  (def ceil (x)
    (if (< x 0)
      (trunc x)
      (+ (trunc x) 1)))
  
  (defmemo fac (n)
    (if (is n 0)
      1
      (* n (fac (- n 1)))))
  
  ;Existing mod only accepts integers. Left intact as "modulo"
  ;This mod copies the behavior of Ruby's mod
  (def mod (dividend divisor)
    "Returns the remainder from dividing dividend by divisor.
    Adds divisor once more if they are of different signs so that the result is always of the same sign as divisor."
    (if (is divisor 0)
          (error "modulo undefined for 0")
        (isnt (signum dividend) (signum divisor))
          (+ divisor (- dividend (* divisor (trunc (/ dividend divisor)))))
          (- dividend (* divisor (trunc (/ dividend divisor))))))
  
  (def sin (x)
    "Returns the sine of x in radians."
      (let x (let red (mod x 2*pi)
                (if (> (abs red) pi)
                  (- red (* (signum red) 2*pi))
                   red))
         ;Taylor polynomial; 0.0 is to cast to float
         (- (+ 0.0 x (/ (expt x 5) (fac 5)) (/ (expt x 9) (fac 9)))
             (/ (expt x 3) (fac 3)) (/ (expt x 7) (fac 7)))))
              
  (def cos (x)
    "Returns the cosine of x in radians."
       (let x (let red (mod x 2*pi)
                 (if (> (abs red) pi)
                   (- red (* (signum red) 2*pi))
                   red))
         ;Taylor polynomial
         (- (+ 1.0 (/ (expt x 4) (fac 4)) (/ (expt x 8) (fac 8)))
             (/ (expt x 2) (fac 2)) (/ (expt x 6) (fac 6)))))
  
  (def tan (x)
    "Returns the tangent of x in radians."
    ;Lazy definition
    (/ (sin x) (cos x)))
  
  (def int? (x)
    "Returns whether x is an integer"
    (is (mod x 1.0) 0.0))
  
  (defmemo prime (n)
    "Returns the nth prime. 2 is the 0th prime."
    (if (< n 0)
          nil
        (is n 0)
          2
          (let prev-primes (map prime (range 0 (- n 1)))
              ((afn (i)
                  (if (no (breakable:each p prev-primes ;Each always returns nil, so a break returns t
                              (if (int? (/ i p))
                                (break t))))
                        i
                        (self (+ i 1))))
                (+ 1 (last prev-primes))))))
      
  
  (def prime-factorization (n)
    "Returns a list each prime up to the greatest prime in n paired with the power of that prime in n.
    E.g.: (prime-factorization 20) returns ((2 2) (3 0) (5 1)).
    Use (reduce * (map [apply expt _] ...)) to change a prime factorization into the number."
    (rev:accum keep
      (let p-ord 0
        (while (> n 1)
            (with (p (prime p-ord)
                    pow 0)
              (until (isnt (mod n p) 0)
                (++ pow)
                (zap [/ _ p] n))
              (keep (list p pow)))
            (++ p-ord)))))
  
  (def gcd (x y)
    "Returns the greatest common divisor of x and y."
      (reduce * (map [apply expt _]
          (map (fn (a b)
                    (list (car a) (min (cadr a) (cadr b))))
            (prime-factorization x) (prime-factorization y)))))
  
  (def lcm (x y)
    "Returns the least common multiple of x and y."
    (/ (* x y) (gcd x y)))

Like this:

  (def foo args
    (prn args))

  (foo)
  => nil

  (foo 1)
  => (1)

  (foo 1 2)
  => (1 2)

I use Arc because:

1) It's different and I like to try different languages

2) Very compact syntax

3) I think it has a lot of space for evolution.

8 points by almkglor 6574 days ago | link | parent | on: Qi's Amazing Macros

  (load "foo.arc" your-macro-expander-here)
Anarki only
More