Arc Forumnew | comments | leaders | submit | best commentslogin
6 points by jsgrahamus 3546 days ago | link | parent | on: Hosting Arc app on Heroku?

Heroku allows for custom buildpacks.

Also found this article, which may be helpful:

https://lexi-lambda.github.io/blog/2015/08/22/deploying-rack...

6 points by zck 3682 days ago | link | parent | on: pg recommending Clojure

I'm pretty sure he's always said Arc is a work in progress, and is not ready for full-fledged production use. I don't think he's ever recommended it to others.

I'm sure part of that is that he doesn't right now want to deal with people making requests for it. And having a userbase would mean that.

6 points by rocketnia 4399 days ago | link | parent | on: A working Arc in Javascript?

This might be exactly what you're looking for:

http://smihica.github.io/arc-js/

The creator (smihica, Shin Aoyama) hasn't come to the forum yet, but their work is impressive. Just look at that REPL start up in under a second! On my machine anyway. :)

Thanks to svetlyak40wt for discovering this project 80 days ago (http://arclanguage.org/item?id=18355). It was in active development then, and it's still active now.

---

The primary spark that led me to make Rainbow.js was a desire to respond constructively to threads like this one.

Using Rainbow was a side effect because I wanted to wow people with the execution speed, which conanite had already meticulously worked on in Rainbow. This was still tied into the desire to help those forum threads along: Between speed and portability, what possible excuse could there be not to use it? ^_^

Once I committed to particular technical goals involving consistency with Rainbow, the 20,000 lines of code were basically predetermined. It's kind of unfortunate that it would fail to be helpful in threads like this one, but it's not all a loss.

The secondary spark that led me to make Rainbow.js was that I wanted to get the hang of using JavaScript, after having worked mostly in Arc for a few years. That goal was met. :)


Short answer: to reproduce the exact example you have...

  arc> (n-of 3 (range 0 9))
  ((0 1 2 3 4 5 6 7 8 9) (0 1 2 3 4 5 6 7 8 9) (0 1 2 3 4 5 6 7 8 9))
Long answer:

Depends on what you're trying to do. :)

I could sit here and rattle off builtin Arc helper functions & macros, but there's a bigger lesson to be learned here about functional programming. Specifically, the list comprehensions you naturally gravitate towards are just syntactic sugar for the famous map & filter higher-order functions (https://en.wikipedia.org/wiki/Map_(higher-order_function) & https://en.wikipedia.org/wiki/Filter_(higher-order_function)).

In Python (at least in Python 2.x, where map and filter return lists instead of generators), the equivalence looks like this:

  [expr_involving_x for x in xs]      == map(lambda x: expr_involving_x, xs)
  [x for x in xs if expr_involving_x] == filter(lambda x: expr_involving_x, xs)
For example,

  >>> [x + 1 for x in [1,2,3]] == map(lambda x: x + 1, [1,2,3])
  True
  >>> [x for x in [1,2,3] if x == 2] == filter(lambda x: x == 2, [1,2,3])
  True
You can apply these transformations recursively until you remove the list comprehension notation altogether. E.g.,

  [x + 1 for x in [1,2,3] if x == 2] -> map(lambda x: x + 1, [x for x in [1,2,3] if x == 2])
                                     -> map(lambda x: x + 1, filter(lambda x: x == 2, [1,2,3]))
Nested comprehensions have a transformation rule, too, but it's somewhat more complicated:

  [expr_involving_y for x in xs for y in expr_involving_x] == sum([[expr_involving_y for y in expr_involving_x] for x in xs], [])
For example,

  >>> [y+1 for x in [1,2,3] for y in [x+1,x+2,x+3]] \
  ... == sum([[y+1 for y in [x+1,x+2,x+3]] for x in [1,2,3]], []) \
  ... == sum([map(lambda y: y+1, [x+1,x+2,x+3]) for x in [1,2,3]], []) \
  ... == sum(map(lambda x: map(lambda y: y+1, [x+1,x+2,x+3]), [1,2,3]), [])
  True
So, list comprehensions are just a way of saying the same things as higher-order functions. Arc generally favors the higher-order function flavor of this idiom. map is still called map, filter is called keep, and Python's sum(..., []) is spelled (apply join ...):

  arc> (map (fn (x) (+ x 1)) (list 1 2 3))
  (2 3 4)
  arc> (keep (fn (x) (is x 2)) (list 1 2 3))
  (2)
  arc> (apply join (map (fn (x) (map (fn (y) (+ y 1)) (list (+ x 1) (+ x 2) (+ x 3)))) (list 1 2 3)))
  (3 4 5 4 5 6 5 6 7)
You might think Arc's preference for these comes from Lisp dialects naturally eschewing specialized syntax. But, Arc does like syntactic shortcuts; just ones that apply more generally to functions, like bracket notation (e.g., [+ _ 1]) and ssyntax (e.g., ~f and f:g come up a lot in higher-order calls).

It's also interesting to note that due to the previous rules, you can easily write a macro that turns list comprehensions into the equivalent chain of higher-order function calls.

There are many Arc builtins that can help build lists, too. They're all defined in Arc itself, so just take a look through arc.arc to figure out how they work. Functions I spy that may help for list building (list of lists or otherwise): rem, mappend, trues, firstn, nthcdr, cut, tuples, pair, n-of, bestn, split, retrieve, dedup, reduce, rreduce, range, ... Really just depends on what you're looking to do!


Two more metrics:

		Source/Medium - Visits
 	
	1.	(direct) / (none) - 1,240
	2.	google / organic - 1,130
	3.	en.wikipedia.org / referral - 695
	4.	nicholasblee.com / referral - 167
	5.	arclanguage.org / referral - 129
	6.	tryarc.org / referral - 114
	7.	arcueid-arc.org / referral - 61
	8.	reddit.com / referral - 49
	9.	news.ycombinator.com / referral - 45
	10.	lambda-the-ultimate.org / referral - 37

		Landing Page - Visits
 	
	1.	/site/arclanguagewiki/ - 1,811
	2.	/site/arclanguagewiki/getting-started/install-arc - 617
	3.	/site/arclanguagewiki/more/avl-trees - 487
	4.	/site/arclanguagewiki/getting-started/tutorial - 310
	5.	/site/arclanguagewiki/home - 160
	6.	/site/arclanguagewiki/arc-3_1/known-bugs-and-gotchas - 155
	7.	/site/arclanguagewiki/more/list-of-languages-with-s-expression-sugar - 80
	8.	/site/arclanguagewiki/getting-started/installing-emacs - 64
	9.	/site/arclanguagewiki/more/keyword-arguments - 31
	10.	/site/arclanguagewiki/arc-3_1/optimizations - 27


For the me the number that stands out is:

   arclanguage.org / referral - 129
That's a paltry 129 coming from what should be the mother lode.

So here is my appeal, pg, if you are listening:

Please update these two pages - http://www.arclanguage.org/install and http://www.arclanguage.org/ - just that wee bit, and put a link to https://sites.google.com/site/arclanguagewiki/. It would make quite a difference to the Arc community, and take only a few minutes of your time. Please?

6 points by thaddeus 5471 days ago | link | parent | on: Project to learn Arc

1&2.There are a few options:

There's an old anarki library you can use to download a webpage. The library can be seen here: http://github.com/nex3/arc/tree/arc2.master/lib/http-get/. However - I once used that library for my personal market scanner (downloads data for tens of thousands of stocks) and found it to be fragile. My suggestion is to use the 'system' command (http://files.arcfn.com/doc/os.html) in order to call 'curl' or 'wget'. See http://curl.haxx.se/ or http://www.gnu.org/software/wget/. These utilities auto-download the webpage for you.

3. You will then need to 'readfile', see http://files.arcfn.com/doc/io.html

4. You'll need to edit the data, then re-serve the page, in which case you use 'defop' (http://files.arcfn.com/doc/srv.html) or you can write the file out to your static directory.

[edit] #4: If you choose to use the static directory you may need to ensure arc is set up to serve out certain types of files (i.e. .js, etc). See http://arclanguage.org/item?id=10620. Anarki has already taken care of this, but arc proper has not.

6 points by waterhouse 5791 days ago | link | parent | on: Why make-br-fn?

Probably so that it can be changed more easily (by redefining 'make-br-fn rather than hacking the reader).

  ;arc.arc from Anarki
  (mac make-br-fn (body) `(fn (_) ,body))
I recall at one point people talking about making brackets work so that, for example, [+ _x _y _z] = (fn (_x _y _z) (+ _x _y _z)). It would extract all arguments from the body beginning with _, alphabetize them, and insert them into the argument list. I don't know if Anarki actually did this, but I do believe it accepted [+ _1 _2 _3 ...] at one point.

See also: http://arclanguage.org/item?id=1227, http://arclanguage.org/item?id=8947, http://arclanguage.org/item?id=8617

6 points by akkartik 5822 days ago | link | parent | on: Anaphoric Local Scope

"I still think that the bug in akkartik code is a result of too complicated one liner."

I'll make 2 objections to that:

a) That particular case was not a bug, but a performance issue.

b) The response to bugs isn't a more verbose formulation. Verbosity has its own costs to pay. Patterns that you could see in a single screen can no longer fit side by side, which can cause their own bugs.

If one-liners are to be avoided, you could just replace the call to reduce in your example with an explicit loop. But that's a bad idea, right?

Imagine a program where "x += 1" should really be "x += 2". Saying "x += 2 // always make sure we're adding 2 to x." doesn't seem like the appropriate response. The appropriate response is practices like automated tests and 5 whys (http://en.wikipedia.org/wiki/5_Whys, http://www.startuplessonslearned.com/2008/11/five-whys.html)

---

Perhaps you're finding right-to-left hard to read. Stick with it; you'll find that it becomes easier to read with practice. Many of us started out with similar limitations. It's like learning to ride a bicycle; I can't explain why it was hard before and isn't anymore, but vast numbers of people had the same experience and you will very probably have it too. As you read more code you'll be able to read dense one-liners more easily. There is indeed a bound on how dense a line should be, but this example is nowhere near it.

Further reading: http://www.paulgraham.com/power.html, http://www.paulgraham.com/head.html, http://www.paulgraham.com/popular.html section 3 "Brevity"

6 points by fallintothis 5822 days ago | link | parent | on: Anaphoric Local Scope

The first problem is that it is a one liner and some times they hide nasty bugs

As a corollary to "sometimes code hides nasty bugs". ;)

One-liners aren't intrinsically bug-prone. I'd even argue that they're often less buggy, just because there's less code to get wrong. Akkartik's problem is actually an example: the issue was data structure choice, and the fixed code was still one line.

The second is that it is in a reverse order

Depends on who you ask. Nested function calls read fine to me, but people have built entire languages to avoid them (e.g., http://factorcode.org/).

The last problem is that it is hard to debug.

Not if you have something like erp: http://arclanguage.org/item?id=8726.

  arc> (let results '((ex1 (1 0 1)) (ex2 (1 1 1)) (ex3 (0.5 0.7 1)))
         (erp:/ (erp:reduce + (erp:alref results 'ex1)) 3))
  (alref results (quote ex1)): (1 0 1)
  (reduce + (erp:alref results (quote ex1))): 2
  (/ (erp:reduce + (erp:alref results (quote ex1))) 3): 2/3
  2/3
What do you think?

From what I can tell, your macro is essentially aand (note that prn will return the item it printed).

  (let results '((ex1 (1 0 1)) (ex2 (1 1 1)) (ex3 (0.5 0.7 1)))
    (aand (alref results 'ex1)
          (prn it)
          (reduce + it)
          (prn it)
          (/ it 3)
          (prn it)))
Are there any cases where it's much different?

In general, I think erp is more useful. You should give it a try!


If you look at the Arc compiler around line 448 in ac.scm from Arc 3.1, you can see that the first thing it does it is check whether the "fn" in the first position of a "call" form is a macro:

  (define (ac-call fn args env)
    (let ((macfn (ac-macro? fn)))
      (cond (macfn
             (ac-mac-call macfn args env))
that's why an identifier being a macro takes precedence over an identifier being a lexical variable.

But you can easily change it. The "lex?" function will tell you whether an identifier is a lexical variable at that point. So you can change the test in the cond for "macfn" to something like "(and macfn (not (and (symbol? fn) (lex? fn env))))" and an identifier being a lexical will take precedence over an identifier being a macro.

6 points by fallintothis 5996 days ago | link | parent | on: Some Arc questions from a beginner

1.

  arc> (when nil (prn "I will not get evaluated, because this is a macro."))
  nil
  arc> (def when2 (test . body) (if test (do body)))
  #<procedure: when2>
  arc> (when2 nil (prn "I get evaluated anyways, because this is a function call."))
  I get evaluated anyways, because this is a function call.
  nil
in is an interesting case, because it's a macro for efficiency reasons: it expands into simpler code with fewer function calls than, say, a call to some. This is kind of how Arc does function inlining, rather than making a compiler infer it. See http://en.wikipedia.org/wiki/Inline_function.

2. Different strokes for different folks, I guess. I don't think I've ever used the f argument of pair, myself. You can accomplish your goal with

  arc> (map [apply + _] (pair '(1 3 5 7 9)))
  (4 12 9)
though that's inefficient.

3. The comment above the definition of join says

  ; Rtm prefers to overload + to do this
Rtm is Robert Morris, who plays a role in Arc's implementation / design. This would indicate that Paul Graham (the "main" designer of Arc) prefers to use join, but is unsure which is best.

4. Ah, but then you'd lose information. e.g., the definition of mem is

  (def mem (test seq)
    (let f (testify test)
      (reclist [if (f:car _) _] seq)))
Here, we want to return the entire sublist, not just the car, but we want to apply f specifically to the car of the sublist. So, we don't want to make reclist only work on the car, since we'd lose said sublist. That is, the current mem behavior is

  arc> (mem 5 '(8 6 7 5 3 0 9))
  (5 3 0 9)
But by adding car to reclist, we'd only be able to do something like

  arc> (mem 5 '(8 6 7 5 3 0 9))
  5
5. Tail calls should be recognizable in the call-graph of the code. For example, the mutually recursive functions

  (def even/r (n)
    (if (is n 0)
        t
        (odd/r (- n 1))))

  (def odd/r (n)
    (if (is n 0)
        nil
        (even/r (- n 1))))
involve tail recursion, even though neither even/r nor odd/r call themselves directly. Since the function in loop is a tail call (the ,gfn call is the last function before a return), it should still be optimized. Someone please correct me if I'm wrong.

6. No significance aside from naming conventions: asterisks follow the names of global variables.

6 points by absz 6107 days ago | link | parent | on: What I really dislike about arc...

Just some thoughts on your thoughts:

(1) This one I think is the right decision. The real constructor is, after all, cons; and in fact, (is (type:cons 'a 'b) 'cons) but (isnt:alist:cons 'a 'b), since cons is more generic. Being a list is a property that certain sets of cons cells have, but it isn't their type.

(2) Again, I think this is the right decision. The point of obj is to be convenient in the simple case where you're building an object-like hash table: one with fixed fields and changing contents. I feel that table should probably take arguments like obj but without quoting (so that (obj a 1 b 2) would be (table 'a 1 'b 2)), but obj is still handy to have around.

(3) Ah, car/cdr versus first/rest. There's not really anything I have to add to this one, other than that I like the conciseness and composability. I've also seen fst and rst proposed, so that you can do frst for first:rest; make of that what you will.

(4) Yes, this is annoying. The rationale is the same as in the obj case, but I very often want to compare to non-symbols.

(5) If we accept that association lists are really just lists which have a certain structure, then we can't use special syntax, etc., as that already means something for lists. What if you have (= a '((1 a) (2 b))); would a.1 be a (since it's an association list) or b (since that's element 1 of the list)? I would also argue that the point of association lists is to be lists with special structure; if you want something like that that's its own type, that's what tables are for.

(6) I haven't really used deftem, but it does define a template; you create them using inst. On the other hand, obj creates the table right there.

I should say, by the way, that I don't think Arc is a perfect language by any means. Its bizarre naming conventions come to mind, for instance. But I happen to think many of these are non-issues (though I would be perfectly open to being convinced otherwise).

6 points by pg 6133 days ago | link | parent | on: Ask PG: Rewrite the arc compiler in arc?

It's not an explicit goal, but I'd consider it, sure.
6 points by drcode 6145 days ago | link | parent | on: Question: What are Arc's strengths?

1. Brevity is top priority. If you learn all the arc functions there are lots of clever commands that anticipate common programming idioms and allow you to write very pithy code.

2. Encourages 50:50 mix of functional and imperative code for what each does best- See the accum command for an example. (If you implement this in clojure, be sure to use the new transients feature http://clojure.org/transients)

3. The design of the web server is elegant (though still somewhat alpha)

4. Call/cc is available (this is the one thing you won't be able to implement in clojure, unless you're some kind of super-guru :-)

5. Intrasymbol syntax is a really promising idea that still needs to be fleshed out a bit.

6. Simplicity- The code behind arc (i.e. the files ac.scm and arc.arc) are, by design, is extremely simple (much simpler than clojure)

IMHO, the value of arc to someone not interested specifically in language design is lower now that Clojure is available. Clojure took many good ideas from arc and expanded on them in a way that really cut into arc's value proposition.

I still think pg's rule of "brevity, brevity, brevity" is the right approach in the long run- Hopefully someone will find time to take the best of these two Lisp dialects and create a new language in the future that rethinks "brevity" in terms of the ideas behind Clojure. (I'm think it'll take more than just a library of macros and functions to do this)

6 points by kens 6147 days ago | link | parent | on: Arc 3.1 (works on latest MzScheme)

Thanks for fixing this! This was definitely not a trivial undertaking.

Now I can run Arc on the ARM-based SheevaPlug. (mzscheme 4.x has been ported to the ARM processor but mzscheme 372 had not.)

6 points by rntz 6152 days ago | link | parent | on: Arc 3.1 (works on latest MzScheme)

Diff available here: http://www.rntz.net/files/arc3.1.patch

It seems that plt4's immutable conses have been worked around via low-level pointer hacking. I can only hope this doesn't introduce subtle bugs, but given that Eli Barzilay seems to work on plt scheme, hopefully this is not the case.

I've pushed the changes to anarki's "official" branch.


The multiple '=s are unnecessary:

    (= rbrackify (brackify "(" ")")
       cbrackify (brackify "{" "}")
       sbrackify (brackify "[" "]"))
7 points by fallintothis 6158 days ago | link | parent | on: Starting up with Arc

The link to "Other Versions" on PLT's main download page is a bit non-obvious, but it's there: http://download.plt-scheme.org/all-versions.html

I'm guessing v372 for Ubuntu probably works on Debian, since they're largely similar. If it doesn't, I've been running v360 on squeeze and haven't noticed any issues with arc3. Failing either of these, you could build v372 yourself.

Once MzScheme is installed, there's not much to do about Arc that's not already on http://www.arclanguage.org/install. You might consider aliasing it in your .bashrc (or whatever), and I recommend using rlwrap. e.g.,

  alias arc='cd ~/arc3; rlwrap mzscheme -m -f as.scm'
Good luck!
6 points by projectileboy 6188 days ago | link | parent | on: New: inc, expanded range

That's sweet. One thing I'm appreciating about Clojure is the way Rich bent over backwards to make almost any traversable data accessible as a "sequence", effectively creating a single function library for dealing with lists, XML data, regular expressions, etc.
6 points by pg 6215 days ago | link | parent | on: Arc Logo

Would you like it better if I told you I went to art school?
7 points by miked 6216 days ago | link | parent | on: Arc Logo

Since the name "Arc" is derived (according to a PG essay) from "arch", and since both start with the letter "A", why not modify an "A" to make it look a bit more like an arch? Simple and evocative.
6 points by pg 6216 days ago | link | parent | on: Arc Logo

The red and blue bits together make a lowercase a. The white rectangle is supposed to represent a keystone.
7 points by rntz 6217 days ago | link | parent | on: New Version of Arc

'med doesn't use its optional 'test argument. It is:

    (def med (ns (o test >)) ((sort > ns) (round (/ (len ns) 2))))
It probably should be:

    (def med (ns (o test >)) ((sort test ns) (round (/ (len ns) 2))))
6 points by kens 6229 days ago | link | parent | on: Last call for Arc bugs

Currently, ensure-dir and date use system to run Unix commands. It would be much more portable if they used mzscheme operations instead. This has caused me trouble not only on Windows, but different versions of Linux. And I think make-temporary-file could replace /dev/urandom.
6 points by CatDancer 6243 days ago | link | parent | on: Request for Bugs

date only works if you have the right operating system:

  arc> (date)
  date: 1241536295: No such file or directory
  Error: "make-string: expects argument of type <non-negative exact integer>; given -1"
a patch is available at http://catdancer.github.com/date.html
6 points by CatDancer 6243 days ago | link | parent | on: Request for Bugs

atomic stops being atomic if an exception is thrown inside its body:

  (errsafe (atomic (/ 1 0)))

  (= x 0)

  (thread
    (atomic
     (= x 1)
     (sleep .5)
     (= x 2)))

  (atomic:repeat 5
    (prn x)
    (sleep .2))
  0
  1
  1
  2
  2
  nil
a patch is available at http://catdancer.github.com/atomic-fix.html
6 points by rntz 6306 days ago | link | parent | on: Intuitive hygienic macros

This is long overdue, but I've finally posted an explanation of the implementation of my hygienic macro system for arc (http://arclanguage.org/item?id=8599). It's written from a general lisper's perspective, because the principles involved aren't arc-specific. It doesn't yet cover the modifications to the internals of ac.scm.

Don't interfere in other's personal life.

If you can, work and help others, otherwise shut your mouth.


Isn't that the right direction, away from Java & COBOL ?
6 points by skenney26 6361 days ago | link | parent | on: This would make my programs shorter.

I agree that the exclamation marks aren't that useful.

Here's a macro that might be useful for digging down into a nested table:

  (mac dig args
   `(,@(reduce list args)))

  arc> (= x (table))
  #hash()
  arc> (= (x 'y) (table))
  #hash()
  arc> (= ((x 'y) 'z) 0)
  0
  arc> x
  #hash((y . #hash((z . 0))))
  arc> (dig x 'y 'z)
  0
  arc> (= (dig x 'y 'z) 1)
  1
  arc> x
  #hash((y . #hash((z . 1))))
More