We take the Arc Challenge

Philippe Marschall pointed me to the Arc Challenge:

Write a program that causes the url said (e.g. http://localhost:port/said) to produce a page with an input field and a submit button. When the submit button is pressed, that should produce a second page with a single link saying "click here." When that is clicked it should lead to a third page that says "you said: ..." where ... is whatever the user typed in the original input field. The third page must only show what the user actually typed. I.e. the value entered in the input field must not be passed in the url, or it would be possible to change the behavior of the final page by editing the url.

The solution in Arc consists of 23 parse tree nodes:

	(defop said req
	  (aform [w/link (pr "you said: " (arg _ "foo"))
	            (pr "click here")]
	     (input "foo")
	     (submit)))

My solution in Seaside only requires 14 parse tree nodes:

	| something |
something := self request: 'Say something'.
self inform: 'Click here'.
self inform: something

The running application can be tested below:

Say something

 

Obviously people will argue that I didn’t exactly play with the rules. In the second step I don’t use a link, but a submit button. You are right. Unfortunately Seaside doesn’t provide a ready-made page that uses a link to proceed. However, and in my opinion this is far more important, the data is not passed through hidden post fields or through the URL. There is no way to fake the output of the last step.

Another important point is readability. Read the Smalltalk code from top to bottom. I reads like english prosa and it simply does what it says. Without bells and whistles. And – does your framework support the back button as well? Does it also prevent you from XSS attacks?

Posted by Lukas Renggli at 6 February 2008, 8:40 pm with tags seaside link

Comments

Nice.

Posted by Esteban A. Maringolo at 6 February 2008, 10:51 pm link

Your code doesn’t do the same thing as the Arc code. It uses a library call to render the first form, whereas the Arc code renders it explicitly.

Posted by Dan at 7 February 2008, 1:35 am link

The Arc code doesn’t render it explicitly either. I don’t see any HTML in the Arc code. The Arc Challenge uses Arc library routines to do exactly what was specified in the Arc Challenge, and the code would be larger if there were a minor variation in the specifications.

If I were to write something as small as possible in Ruby or Forth or something else, with my own libraries as part of the language, then I can definitely stipulate a range of "must do" along with very tiny code. "Must accept Unicode answers".

I think the Arc Challenge is disingenious in an almost Microsoftian way. Those who understand programming don’t get the point, and those who don’t understand programming will just be PG fanboys.

Posted by steve at 7 February 2008, 1:43 am link

"Your code doesn’t do the same thing as the Arc code. It uses a library call to render the first form, whereas the Arc code renders it explicitly." - uh, I don’t see anything "explicit" in the Arc code. Just a function call. That’s the problem with this "contest"... it all depends on what you call a library. We could do a single line that calls a library that does the whole thing.

Posted by Randal L. Schwartz at 7 February 2008, 1:44 am link

Yeah, granted the Arc code uses a library too, but I could also write a C implementation that uses a library that does the whole thing in 1 LOC. Would that indicate that C is more succinct than SmallTalk?

The point is to compare different languages using very similar if not identical libraries. Comparing different languages that use different libraries doesn’t prove much.

Posted by Dan at 7 February 2008, 1:58 am link

Dan, that’s right. Now apply that exact same logic to Arc, and you will see the problem. The "Arc Challenge" is meaningless, and parse tree nodes is an invalid metric.

Posted by steve at 7 February 2008, 2:12 am link

In Run BASIC (implemented on top of Seaside) the code looks like this:

	input "Say something"; something$
	cls
	link #continue, "Click here", [continue]
	wait
	[continue]
	cls
	print something$

Now, granted this isn’t exactly equivalent to the ARC example it is close in spirit. ;-)

Posted by Carl Gundel at 7 February 2008, 5:31 am link

Didn’t you miss the "said" url?

Posted by Julio Nobrega at 7 February 2008, 4:16 pm link

@Julio Nobrega: I could move this blog-post to the URL /said and then the application would appear at that place. For obvious reasons I prefer to keep my post in /blog/take-the-arc-challenge.

Posted by Lukas Renggli at 7 February 2008, 4:29 pm link

@Lukas Renggli: You missed the ’you said :’ part on page three ;) But it is impressive how short your implementation in smalltalk is. Anyway it is just another my language/OS/prgram-is-better thing, but you didn’t start it.

Posted by Jan Schmidt at 8 February 2008, 11:56 am link

Ok, that would then look like ...

	| something |
something := self request: 'Say something'.
self inform: 'Click here'.
self inform: 'You said: ' , something

... and have two more parse tree nodes :-)

Posted by Lukas Renggli at 8 February 2008, 12:09 pm link

The "Click here" bit in the middle is supposed to be a link. Does that increase the number of parse tree nodes?

Posted by Christopher Atkins at 8 February 2008, 10:05 pm link

If you really wanted the middle step to be a link, you’d have to write a library method to do it. First the component class

WAComponent subclass: #ACLinkConfirmation
instanceVariableNames: 'message'
classVariableNames: ''
poolDictionaries: ''
category: 'ArcChallenge'

with the actual method that does the link stuff

renderContentOn: html
html anchor
callback: [ self answer ];
with: self message

some accessors (left out), can be generated with the refactoring browser

Then the method that uses this component:

confirmWithLink: aString
self call: (ACLinkConfirmation message: aString)

And finally update the example

	| something |
something := self request: ''.
self confirmWithLink: 'Click here'.
self inform: something

Doesn’t really change anything.

Posted by Philippe Marschall at 10 February 2008, 3:19 pm link

I’m certainly biased but what I find nice is the simplicity, the small size and the fact it reads like english... I really think that if you want a specific task (process) done in web app style, seaside is a very good choice ! I don’t regret learning (with) this old language... ’).

(youGuys are: #impressive and: [ me lovingEvent: (MyEncounterWith: Smalltalk) ]) "print as true :) "

Posted by cdrick at 11 February 2008, 9:37 pm link