Arc Forumnew | comments | leaders | submit | conanite's commentslogin
7 points by conanite 6081 days ago | link | parent | on: Where are we going?

I know, it's 87 days later, sometimes I take my time ... this article stirred me from some months of guilty inaction so I took another look at rainbow (arc in java).

The latest checkin supports complex numbers and a little bit of trigonometry, and it also goes faster, yippee! I was planning to use arc to play with fractals (ergo need for complex numbers) when I have a bit of spare time. This checkin makes rainbow a fairly complete implementation of arc, so if you're interested in trying out arc but need some of that ready-made java library goodness, rainbow might be your thing.

It's at http://github.com/conanite/rainbow/tree/master and I'll document the trig functions and other features if anyone's interested. Anyone? Hello?

-----

2 points by shader 6080 days ago | link

Nice to see that someone is still here ;)

So, how much of the java libs does rainbow have access to? And do you think that it could be used for web serving on a shared host? (I know, I've been asking that question too much lately)

-----

3 points by conanite 6079 days ago | link

rainbow has various low-level functions for interfacing with java, including

  java-new (class . args)
  java-invoke (obj method . args)
  java-implement (class strict . functions)
so technically you can access any java library you want from your arc code as long as it's in your classpath. Ultimately though it's prettier to hide these calls behind macros or functions in arc so your code is more expressive. I've done this a little for swing (java's desktop UI library) - for example there are event handler macros like

  on-key (component (var) . body)
  on-scroll (component (var) . body)
where "body" is event handler code. From the perspective of the calling code, there's no way to tell it relies on java behind the scenes.

Java objects have the arc type 'java-object

  (type some-big-java-object)
  -> java-object
so defcall is defined to invoke 'java-invoke - you should almost never need to use 'java-invoke directly. In other words,

  (some-big-java-object 'equals another-big-java-object)
results in the call

  (java-invoke some-big-java-object 'equals another-big-java-object)
which, naturally, results in a call equivalent to

  someBigJavaObject.equals(anotherBigJavaObject);
Strings, numbers, booleans and lists automatically convert to and from arc types. Here's a longer example:

  arc> (set foo (java-new "java.util.HashMap"))
  {}
  arc> foo
  {}
  arc> (type foo)
  java-object
  arc> (foo 'put 'bar "toto")
  nil
  arc> foo
  {bar=toto}
  arc> (foo 'keySet)
  [bar]
  arc> (type (foo 'keySet))
  java-object
  arc> (foo 'getClass)   
  class java.util.HashMap
  arc> 

As for serving on a shared host - I switched from java to ruby a while ago precisely because it's a pain to use java on a shared host - and most java hosting plans offer a shared tomcat (tomcat: popular java app server) instance, so even then you couldn't use arc's webserver natively. You could implement the necessary servlet interfaces in arc and then package it like a java web app and tomcat would deploy it. So at least the logic of your app would be written in arc. If you want to try this, I'll be happy to help.

-----

1 point by shader 6078 days ago | link

Nice to know that java isn't too hard to access, not that I expected it to be.

As for hosting, I'm currently using dreamhost. They provide support for python and perl via fastcgi, so I've been looking for a lisp option that could leverage that. Most of them don't have much in the way of libraries. And I like arc. So the option of using arc with java libs seems like a plus. How hard do you think it would be to write arc's web tools based off of fcgi? Unfortunately I don't even know what it takes to run rainbow via the jvm on a server, but I would presume that it's possible.

-----

1 point by rincewind 6077 days ago | link

Have you thought about interop with Clojure?

-----

1 point by conanite 6077 days ago | link

Not yet :)

but theoretically you could host a bunch of languages in a single jvm instance - and have arc, clojure, jruby, jython, and javascript (via rhino) all calling each other in a big polyglotfest. Java 6 includes a scripting framework ( https://scripting.dev.java.net/ ) that standardises the way a jvm hosts a ScriptEngine. I haven't looked at this yet at all but it's on my todo list.

-----

1 point by CatDancer 6078 days ago | link

web serving on a shared host

what's your project?

how much do you want to pay for hosting?

-----

1 point by shader 6077 days ago | link

Nothing too complicated or high volume. Our church website and a realtor's website, currently in php. We've been working on a design for a quasi-framework, and were hoping to do it in lisp. Currently my host is dreamhost, which pretty much permits anything, and has shell access. If I could use an fcgi interface, I'm pretty sure it would work. Which lisp / web framework do you recommend?

-----

3 points by CatDancer 6077 days ago | link

How much are you paying for DreamHost? The cheapest Linode (http://www.linode.com/) plan is $20/month. Download and unpack MzScheme, fire up Arc, and you're up and running. Sounds to me quicker and easier than messing around with fcgi, unless there's something about your situation that I'm not realizing.

If you want your two web sites to be running with different domain names (www.mychurch.org, www.terrificrealtor.com), you have a couple options: you can run Apache (or any other HTTP server that can forward requests) in front of Arc, and be running two Arc processes, one for each site. Or you could hack Arc (or ask a hacker here to hack Arc for you) to look at the "Host" header.

Which lisp / web framework do you recommend?

Well, I use Arc myself, simply because I can use any language I want, and I like Arc. What I'd recommend for you would depend on what your goal was. If you want a powerful programming environment that will enable you to implement your two sites quickly and easily without having to do any Linux system administration, I'd recommend taking a look at AppJet (http://appjet.com/).

-----

2 points by revorad 6078 days ago | link

Hey thanks for that, conanite. I just posted the link on HN. Could you please answer this question? - http://news.ycombinator.com/item?id=446346

-----

1 point by conanite 6077 days ago | link

Hey, thanks for that, revorad! It looks like stefano got there before me ... but yes, it's a complete arc, with ccc and tail-call optimisation. Unfortunately the JVM doesn't do this stuff natively so there's a whole arc VM running inside the jvm which as you can imagine slows things down a bit.

-----

0 points by ltol 6073 days ago | link

Bug report: "Rainbow" poor name. Please fix.

-----

1 point by absz 6073 days ago | link

I have to say that I like the name; it's also a multilingual pun, which gives it major bonus points (http://arclanguage.org/item?id=5785).

-----

1 point by ltol 6073 days ago | link

Pun was clear. Merit of French less so. Problem with name: Hard to google.

-----

4 points by conanite 6073 days ago | link

> Hard to google

True. When I search for "rainbow lisp", google asks me did I mean "rainbow lips". Rainbow's github page is the 6th result for "arc rainbow", alone among many discussions of the shape of the multicoloured atmospheric phenomenon.

Once we've taken over the world, I think it will get better.

> Merit of French

I happen to live in france. It was a convenient pun. No other reason, especially not love of the language that I haven't got to grips with even after nine years of living here.

-----

3 points by conanite 6081 days ago | link | parent | on: Auto-format function for arc code

pprint.arc might have what you're looking for - routines for pretty-printing. It's at the top level of the arc distribution.

-----

1 point by thaddeus 6080 days ago | link

That did the trick (I figured this must have been done a million times before) :)

Thanks. T.

-----

3 points by conanite 6094 days ago | link | parent | on: This would make my programs shorter.

"Paul Graham is doing Arc. Why can’t I have fun too?" (p.4)

oh-oh, the floodgates are open. One day, there will be as many lisps as there are lisp programmers. Which is not necessarily a bad thing. It might even be inevitable.

-----

1 point by maxharris 6094 days ago | link

This is off-topic.

(And Otter doesn't seem to be going anywhere - no website, no new information for about a year and a half.)

What do you think about the content posted at the top of this page?

-----

4 points by conanite 6093 days ago | link

I don't get the difference between foo[bar] and foo.bar ... why not use only one? Doesn't the context determine whether you're setting or retrieving a value?

  (= foo[bar] "value")
vs

  (prn foo[bar])
At least, arc makes no distinction:

  (= foo (table))
  (= foo!bar 123)
  (prn foo!bar)
does what you would expect. But it's true that arc syntax for accessing nested tables

  foo!bar
is awkward, in particular because it can't be chained. There's no syntax for

  ((foo 'bar) 'toto)
because

  foo!bar!toto
expands to

  (foo 'bar 'toto)
and that throws an error. I may well be missing some tricks, but deeply nested structures appear to be difficult to use in Arc, and it would be great to fix this. It would be great to write something like

  foo[bar][toto]
And arc's exclamation marks suck as syntax: they make the code look way too urgent and excited.

-----

6 points by skenney26 6093 days ago | link

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))))

-----

2 points by conanite 6114 days ago | link | parent | on: Connect to running instance?

start-stop-daemon will start a process that will stay running after you quit your shell

-----


(shameless plug) rainbow does!! :))

http://arclanguage.org/item?id=6975

-----

1 point by almkglor 6262 days ago | link

^^nice

Although it might be better to make a thread pool, where each Arc-side thread is a "task" (which will reschedule itself until it ends), much like how Erlang does it and how SNAP will eventually do it. This will allow you to easily launch and destroy thousands of Arc-side threads on a machine with far fewer cores.

Of course there's the minor problem of I/O then... you'll have to use nonblocking I/O in the VM and emulate blocking I/O on the Arc-side by setting up a poll for the Arc-side task.

-----


I don't know anything about how CL works but from your description it sounds like CL reads and compiles the whole file in one pass, whereas arc reads forms one by one, compiles each, and evals the result. Arc's 'load is based (indirectly) on 'sread which is scheme's 'read, which reads one expression at a time from the given input-port. Hence macro definitions at the beginning of the file are available for compilation into functions later in the same file.

This is the essence of Arc's 'load:

  (w/infile f file
    (whilet e (read f)
      (eval e)))
hth

-----

1 point by almkglor 6262 days ago | link

Note by the way that this is the problem that macros in arc2c face: in a single compilation unit, a function defined earlier must be callable from a macro actually used later ^^. Also, to preserve as much of Arc's semantics as possible, a macro could be redefined in a single compilation.

^^

SNAP would sidestep this largely by simply using bits of arc2c only as part of eval - basically eval is simply:

  (def eval (e)
    ((to-free-fun:bytecode-compile:arc2b-compile e)))
... where arc2b-compile is the bits of arc2c modified to emit the bytecode as a list of symbolcodes, bytecode-compile accepts that list and returns an opaque abstract bytecode-sequence object, and to-free-fun creates a free function (one without any closed variables, i.e. all free variables are globals).

So SNAP will compile expressions one at a time.

However arc2c reads the entire compilation as one big expression, hence the difficulty. It may be possible to modify it so that it compiles files one expression at a time though; possibly this could be done by targeting to a bytecode, and then writing a bytecode-to-c transformer, but it loses some global optimizations (oh well).

-----

1 point by stefano 6262 days ago | link

Right. It is as if the basic compilation unit for Arc were the expression, not the file. While this doesn't create problems for an interpreted implementation, this seems an efficency killer for native code compilers.

-----


Saving client state in closures/continuations is a continuous source of contention. Here's an old discussion: http://arclanguage.org/item?id=1455 , and a more recent one: http://arclanguage.org/item?id=7338

I like the "It's hard to beat closures for elegance" argument, but I haven't really tried the arc way for web apps yet. It's also true that over time we see higher-level languages win out over their lower-level counterparts despite initial objections about performance. So it might be that closures win eventually over initial objections about scalability. But I like readable urls, http://example.com/a?fn=fkg34lk doesn't really tell me anything.

-----

4 points by almkglor 6268 days ago | link

maybe something related to http://decenturl.com/ might help: http://www.reddit.com/r/programming/info/5zcbl/comments/

Edit: It might be useful to add an optional parameter in some of the link-creating stuff where the programmer can add some sort of "hint" which the base system will use, so instead of http://example.com/a?fn=fkg34lk you get http://example.com/a?fn=voteup_fkg34lk

Or possibly just "make it long" and just have the base system add a number if the id clashes: http://example.com/a?fn=voteup-maybe-something-related-to-3

So yes: closure links per se don't prevent decent url's, naive implementations of closure links do.

-----

1 point by conanite 6270 days ago | link | parent | on: A native Arc compiler for Linux

awesome, congratulations. I'll have to fire up my linux machine and give it a shot!

-----

1 point by stefano 6269 days ago | link

Thank you :)

What OS do you use? If it's unix compatible there are chances to get the compiler to work. If it's windows, I don't know. There exist gcc for windows, but I don't know if it has the following linux functions: dlopen, mmap, open, read, write. Obviously the windows equivalent of these functions exist, but I don't have a windows machine, so I can't develop the windows port.

-----

2 points by conanite 6272 days ago | link | parent | on: Python-like modules

speaking of gensyms, is there a reason uniq isn't defined in arc? one less axiom? (on a related note, I don't know why sig is defined in ac.scm, it doesn't seem to be otherwise referenced there)

-----

1 point by absz 6272 days ago | link

Because if/when we have real gensyms, where if we have

  arc> (= gs (uniq))
  gs2003
then (is gs 'gs2003) returns nil, instead of t (which it currently does), we won't be able to define uniq in Arc. It's another datatype (the "uninterned symbol"), and thus it needs an axiom. The axiom could be something besides uniq (string->uninterned-symbol, for instance, or usym) if (isnt (usym "foo") (usym "foo")).

-----

1 point by conanite 6272 days ago | link

Aha. So uniq in its current form is really 'kinda-uniq. How important is it that gensyms aren't equal to each other? I mean, if "everyone knows" /gs[0-9]+/ is "reserved" for gensyms, then all we need do is not make symbols matching that pattern. Thus is the language minimaler.

I'm just being lazy. It can't be that difficult to implement ...

-----

2 points by absz 6271 days ago | link

For now, it's not: see http://arclanguage.org/item?id=7529 . Thanks to mzscheme, it's a one-line change :)

And does that really make the language more minimal? If we leave uniq as it is, we could move it to arc.arc, but we have the axiom that symbols of the form /gs\d+/ are forbidden; if we change uniq, uniq is an axiom, but we don't have to worry about formats.

-----

2 points by stefano 6271 days ago | link

Even if Arc were not based on mzscheme the change would be minimal: it takes exactly the same operations as creating a normal symbol, with the difference that it doesn't have to be interned.

-----

2 points by conanite 6271 days ago | link

"doesn't have to be", or must not be interned? I'm thinking the latter, if the point is to guarantee that no other symbol shall be equal to a gensym ...

-----

3 points by stefano 6270 days ago | link

You're right: it must not be interned.

-----

2 points by conanite 6275 days ago | link | parent | on: Help w/ continuations

This Sam Ruby article helped me a lot with continuations:

http://www.intertwingly.net/blog/2005/04/13/Continuations-fo...

A continuation behaves just like a one-arg function except it never returns to its caller. It returns to the point where it was created. This might upset the flow of the app server. Also, the app server relies on redirecting stdout to the network socket, and jumping to a saved continuation appears to restore stdout to whatever it was for that continuation.

I wonder if arc is intended to support full re-callable continuations - official arc only references 'ccc once, in the 'point macro, which is only used for 'catch. And the intent of 'catch (i think) is only to provide an escape mechanism, not a re-callable continuation.

I'm guessing that official arc uses ccc in a limited way because (I read somewhere that) arc was originally built on Common Lisp, not Scheme, and CL doesn't support full continuations. But I might be completely wrong. And maybe ccc is one of the reasons arc switched to scheme. Somebody on this forum knows the truth ...

-----

2 points by tokipin 6273 days ago | link

i'm currently writing a blog post featuring Arc's ccc, and all signs point to it being a 100% implementation. this shouldn't be too surprising since (i believe) the compiler transforms the Arc code to CPS

i don't know what the OP is asking exactly, but the answer is likely yes. i implemented coroutines, so these more straightforward things should be no problem

i talk about it a bit on the blog post, but the problem with continuations is the freaken name. it sounds like some sophisticated thing, when in fact all it is is marking the next instruction. for example:

  (ccc func)
obviously you're using ccc here because you want to go back to it later. perhaps you want to go back to it from within 'func'. in other words, so that 'func' effectively has the ability to arbitrarily return:

  (ccc [do (stuff...)
        (if blah (_ bleh)) ; early return
        (do more stuff)])
but what if control returned right back precisely to ccc? then the whole form would be executed again. see how that would be a problem? so ccc doesn't mark the "current" spot. it marks the next spot so you don't get stuck in an infinite loop

and because it's the next spot, and because you can call _ as a function, they refer to it with the holistic name "continuation," instead of "the spot after the ccc"

they could have just as easily made the primitive be mark-the-current-spot, a la:

  (ccc [= spot _])
but while making mark-the-current-spot with ccc is easy, the converse isn't, nor would mark-the-current-spot necessarily be the most common use form (the impetus for call/cc might have been to give scheme the ability to return)

-----

1 point by absz 6273 days ago | link

Actually, arc just compiles everything down to Scheme; Scheme, of course, has full continuation support, and thus so does Arc.

That's a nice explanation of continuations, but one comment: I think (if I remember what I read correctly) that writing ccc in terms of mark-the-current-spot (or perhaps get/cc, or gcc :P) is actually impossible, but I could be wrong. The other advantage of ccc is that every flow control construct can be simulated using it (including, but not limited to, C's return).

-----

2 points by tokipin 6273 days ago | link

> I think (if I remember what I read correctly) that writing ccc in terms of mark-the-current-spot (or perhaps get/cc, or gcc :P) is actually impossible, but I could be wrong.

that's the short-term conclusion i came to when i was fidding with it. i didn't exactly prove it was the case though so i was being safe

-----

1 point by almkglor 6273 days ago | link

You might also want to mention continuation guards and dynamic-wind (which is partially exposed as 'protect in Arc).

-----

2 points by stefano 6274 days ago | link

This is one of the few cases where it would be better to have some specifications other than the source code itself. A compliant implementation should support full continuations, because one could write programs that rely on ccc and those programs would work on ArcN.tar.

-----

2 points by almkglor 6273 days ago | link

> This is one of the many cases

fixed that for you ^_^ \/

For example, consider the minor problem of macros such as 'w/infile:

  (restartable
    (pr "Press enter to begin processing the file")
    (readline)
    (w/infile p "thefile.txt"
      (whilet l (readline p)
        (when (is l "foo\n")
              (prn "A \"foo\" was found in the file!")
              (prn "Please correct these errors first")
              (restart)))
      (prn "finished processing!")))
The point is that 'restart is really a continuation bound to the beginning of the 'restartable form. Obviously 'w/infile and related forms must trap continuations; the mzscheme implementation uses 'dynamic-wind, exposed as the 'protect function.

This is one of the many cases where having an explicit specification would have been nice, because this would have required some code digging. What, exactly, is 'protect intended to do?

-----

2 points by stefano 6273 days ago | link

The problem is increased by the fact that the official arc implementation drains entire constructs (such as 'dynamic-wind) from the underlying scheme. How should we consider them when writing an alternative implementation? Are they intended to have the identical behavior of the corresponding scheme constructs? An official test suite would be really helpful and would solve most of the problems.

-----

1 point by antiismist 6274 days ago | link

Thanks for the pointer. Looks like ccc is not going to help me here

-----

More