Take the Arc Challenge
paulgraham.com
paulgraham.com
When I look at something like
(defop said req
(aform [w/link (pr "you said: " (arg _ "foo"))
(pr "click here")]
(input "foo")
(submit)))
what I see is more or less ordinary lisp that uses a library to solve an issue with applications that rely on http. I'm sure plenty of us could do the equivalent with the appropriate Python/Perl/Php/Ruby library, but then the obvious criticism would be that you're not really comparing lanugages. You would be comparing libraries.Plenty of examples over here: http://arclanguage.com/item?id=722
Is it really the case that when you boil it down, Arc (language+libraries) is about making small web programs? If not, why this challenge and if so I suspect it won't live up to the 100-year idea.
Suppose instead of being a temporary state of affairs, YC/Arc news were to support cross-forum discussions. How simple would that be to support in Arc as it is today? I.e. no fair adding something like (crosspost) to the core libraries.
I'll eventually post some comparisons of the same programs in Arc and other Lisp dialects.
How would you, in your favorite language, implement a program that displays GDP information for every country for years from 1970-2007 using a nice graph. Countries should be selectable using a fancy popup menu that displays country name and country shape...
Using Mathematica 6:
MenuView[Row[{Rasterize[
Show[CountryData[#, "Shape"], ImageSize -> {40, 40}],
Background -> None], #}] ->
Dynamic[DateListPlot[CountryData[#, {{"GDP"}, {1970, 2005}}]]] & /@
CountryData[], ImageSize -> Automatic]I'm sure someone has addressed this very well, but I'm not sure where to look. Anyone happen to know?
No. Web app prototypes do that sort of thing all the time. For production web apps, the problem ends up including such confounding factors as meeting accessibility policy, making the HTML surrounding the form elements match what a web designer came up, etc. The more web development work I do, the more wary I am of any system that writes HTML for me. Inevitably the system ends up putting too many constraints on what HTML can be output.
Witness the ASP.NET framework, which writes lots of HTML for you. Unlike Arc it was written with the best practices of the time in mind, but it's aged badly as the web has grown and changed. Doing accessible, cross-browser, standards-based work in ASP.NET today involves a certain amount of fighting the framework which offsets the initial productivity gains.
I understand that Arc is intended for exploratory work and rapid prototyping. But that's exactly why the Arc challenge is meaningless. We're being asked to compare Arc to languages that provide -- dare I say it -- a great deal more flexibility and expressive power when it comes to outputting HTML.
So here's my challenge: Take a sample Arc application and modify it to replace tables with appropriate block elements that have designer-specified IDs and classes. Use <label> elements for each input if you aren't already. Replace a few regular submit buttons with image buttons or vice versa. Reorder some elements, and throw a few more arbitrary containers in here and there. Compare that process against a conventional language and let's see where we get.
In my line of work, that kind of scut work is absolutely part of prototyping. Before I can build the real thing my prototype has to be approved by people who have a hard time looking past even minor visual inconsistencies with what they're used to. For that reason I'm very wary of any design that makes fine-grained control of HTML any harder than it has to be, and I've come to value clean view/everything else separation even in early prototypes.
I suspect that Arc is much more appealing to people who don't live with such constraints.
I think you're confusing types of software with organizations that sponsor them.
Arc certainly wasn't designed for use in the sort of environment where programs are 10% functionality and 90% the embodiment of the random bureaucratic processes of the organization paying for them. More for the opposite end of the spectrum, in fact. That's where you need power.
That said, if you care to make your challenge a precise one, it's likely I (or someone else) would try implementing it in Arc, if only out of curiosity.
Every time I've let somebody else's tools write HTML for me, it's caused me grief. Either because the tool author had an agenda that was at odds with my needs (Microsoft), because of bugs in the tool (everyone), or because the problem set shifted since the tool was written as browsers and techniques changed (everyone). Likewise, I'm wary of entertwining HTML output with the rest of the program the way Arc does because it makes it too much work to change things down the line.
It would be interesting to write a templating system that separates HTML output without making Arc programs take much longer to write. I suspect that it could be done, but it's not entirely clear to me what shape it would take. If done right it would give users the option to leverage Arc's existing HTML output functions where desired. I'll have to play with it.
A great, usable prototype :)
if ($S['foo']) echo "you said {$S['foo']}";
elseif (PtoS('foo')) link('said','click here');
else form('foo');
For me, making programs short is not a design goal. But if it would, I would do it like above. My framework then would include this functionality: S[] contains all session variables
P[] contains all posted variables
PtoS copies an entry from P to S. Returns false if P was not set.
link() prints a link
form() shows a form with the given fields. target is the current url.But adding primitives has a cost too. You could just have let, or you could have a let for one value, one for more values, one for more values initialized as nil, or as 0, or as an empty string, etc.
In Ruby I write expressions like this a lot: condition ? string : "" I'd like to say: condition &&? string
This would make my applications shorter, but, I claim, less readable and no more powerful.
To measure power, it is not enough to look at succinctness - you must hold something else constant too.
(condition && string).to_s
(string if condition).to_s
both work (though the first fails when passed false instead of nil.) I use something similar in quick-and-dirty Ruby shell scripts: n_to_generate = (ARGV.shift || "0").to_iTo be more specific here are three attributes that seem to aid frictionless flow. (perhaps in order of importance) -
--> Expressiveness -- i.e. simple, explicit and unambiguous abstractions.
--> Obviousness and readability. -- i.e. no need to decipher tokens, and the code structure illuminates the intention and flow of the process.
--> Terse. -- i.e. apart from the obvious benefit of requiring less work it also helps me 'keep the whole program in my head'.
There's nothing wrong with brevity of course, but when pursued for it's own sake it seems to be counter productive, in that when you focus on terseness alone there can be a tendency to ride roughshod over the more important attributes: expressiveness and obviousness. You then end up with code that's not as enjoyable to create and whose beauty is lost, except perhaps initially to it's creator.
BTW Paul, this is a great first shot, so a big thank you. I, for one, am routing for Arc to be a widespread success, if only so I can do most of what I need to do in a language that I really enjoy.
* On Flow -> http://www.life2point0.com/2006/06/the_little_book.html
The idea is that by ensuring the progression of long code becoming shorter, and by upholding his second principle (axiomaticity), he is making sure that the code he does factor out will be useful to future programmers. He is removing the need to write common boilerplate code -- and giving the ability to remove boilerplate code to all programmers.
And that supports the idea that PG likes about Lisp -- that the language evolves with the program. The reason it seems to only be good for web programs is that his principle application is a web program. If he were to work on some other kind of program, say a word processor, you would see different kinds of abstractions.
The point is that the language can be adapted to ANY kind of application. That is what he is aiming for. And that's why he doesn't want you to have to count library import statements. He wants to compare the code you have to write repeatedly, not the once-off code. He is claiming that the code you have to write repeatedly indicates how expressive a language is. If you have to repeat yourself, then the language does not adequately represent the abstraction you want to capture.
That's what _On Lisp_ is about. That's what basically all of his Lisp essays are about. Paul Graham is aiming for brevity so that he knows that any programmer can make their program brief by evolving the language. Brevity is a sign of a tight fit between language and the concepts expressed in the program.
The other problems people talk about (make this refactorable, etc. etc.) are essentially problems which arise when we transition from a small code base to a large one. And to have any insight about that, I suspect we will actually need to first build something truly large in Arc. Without doing that, arguments from both sides will just be fanciful and sensationalistic blog crud.
New languages are designed so that we can think differently. Let's first try to honestly think about such an artifact and see if we can express it easily using Arc. Hack first, folks, then talk.
(define-entry (said)
(define (page . s) `((html (body ,@s))))
(page
(form/cont:
(@@: (cont (entry-lambda (:keyword foo)
(page (a/cont: (@@: (cont (entry-lambda () (page "You said: " foo))))
"click here")))))
(input: (@: (name "foo")))
(input: (@: (type "submit"))))))
I'm defeated. I admit Arc is quite optimized for web app, at least.Now, beyond a certain point, optimization becomes specialization. It's like compression. The more you know about the domain, the shorter you make the frequent patterns, and the net amount of code gets smaller. But how do you know you're not overspecializing?
Some of Lispers, including me, have this fear for overspecialization. Reading arc does have an effect to cure that. I see some nice abstractions in arc which I'd like to steal from.
I'm more curious, though, to see wider range of applications in arc and how the core abstractions will live up.
(btw, Paul, if you read this could you reset my password in Arc forum and send it to shiro@acm.org?)
Paul, out of curiosity, what are those serious mistakes?
http://en.wikipedia.org/wiki/Id_Tech_4
Take the Java Challenge (entries will be judged by quarterly revenue, rather than fewness of lines)
Now, lisp /scheme is really great at making DSLs. This example makes me think that Arc isn't a new all-purpose language, but rather a DSL language that can easily be modified to withstand criticism. "It doesn't have feature x!!!" ...2 weeks later... "Well, it does now."
I'm not saying that DSLs are insignificant, or that Arc's creation was trivial, but when examples like this are used, it feels more like a framework than a new paradigm. I think most Python/Ruby/Haskell/(modern language) hackers could fairly easily implement a library to do what Arc does in about as many lines, but they wouldn't call it a new language.
what percentage or time developing an app do you guys spend typing? For me it is quite low but maybe i'm not a superhacker or i just type fast
A short, hideous girl (Arc)? I wouldn't hit it.
I'm sticking to the short and beautiful (Python/Ruby).