Arc (programming language)
This page was last modified on 8 June 2016, at 21:48.
|Designed by||Pol Gramm и Robert Moris|
|License||Perl Foundation's Artistic License 2.0|
Arc is a Lisp dialect which is developed by Paul Graham and Robert Morris. Basically Arc can be defined as severely simplified version of Lisp with a powerful marco support which allows to do any Lisp styled «dirty hacks».
In 2001, Paul Graham announced that he was working on a new dialect of Lisp named "Arc". Over the years since, he has written several essays describing features or goals of the language, and some internal projects at Y Combinator have been written in Arc, most notably the Hacker News web forum and news aggregator program. Arc itself is written in Racket.
In the essay Being Popular Graham describes a few of his goals for the language. While many of the goals are very general ("Arc should be hackable," "there should be good libraries"), he did give some specifics. For instance, he believes that it is important for a language to be terse:
"It would not be far from the truth to say that a hacker about to write a program decides what language to use, at least subconsciously, based on the total number of characters he'll have to type. If this isn't precisely how hackers think, a language designer would do well to act as if it were."
He also stated that it is better for a language to only implement a small number of "axioms", even when that means the language may not have features that large organizations want, such as object-orientation (OO). In fact, Graham feels that OO is not useful as its methods and patterns are just "good design", and he sees the language features used to implement OO as partially mistaken. At Arc's introduction in 2008, Graham stated one of its benefits was its brevity.
A controversy among Lisp programmers is whether, and how much, the S-expressions of the language should be complemented by other forms of syntax. Graham feels that additional syntax should be used in situations where pure S-expressions would be overly verbose, saying, "I don't think we should be religiously opposed to introducing syntax into Lisp." Graham also feels that efficiency problems should be solved by giving the programmer a good profiler.
Programs in Arc
Arc programs consist of expressions. The basic expressions are numbers and strings. The are the results of the same expressions.
arc> 25 25 arc> "foo" "foo"
Some expressions can construct lists by being placed into brackets. When such list is evaluated all list elements are evaluated in left-to-right order and after that they are passed to first element (presumably to a function). The list result is the function return result.
arc> (+ 1 2) 3
In this example +, 1 and 2 are evaluated consequently. Result is function + applied to 1 and 2. 1 and 2 are passed to + function which returns 3. 3 is the evaluation result.
Since expression rules and their evaluation are recursive the programs can be as complicated as needed.
arc> (+ (+ 1 2) (+ 3 (+ 4 5))) 15
The + disposition before the arguments is a feature which allows to pass as many arguments to this funtion as needed.
arc> (+) 0 arc> (+ 1) 1 arc> (+ 1 2) 3 arc> (+ 1 2 3) 6
It is very convenient for code generation what is a quite common practice in Arc.
Such Lisp dialects as Arc have a data type which absents in the most of languages - symbols. Symbol is not the value of the same symbol as it works with numbers and strings. Symbols return the value which has been assigned to them.
If foo is assigned 13 then foo returns 13 but not foo:
arc> (= foo 13) 13 arc> foo 13
Evaluation can be aborted by adding an apostrophe before the expression.
arc> 'foo foo
Although arguments are evaluated in left-to-right order it does not cause foo evaluation error because there are operators which break the normal expression evalutaion order and = is one of them. The first argument is not evaluated. If you put an apostrophe before the list, the result is the list itself.
arc> (+ 1 2) 3 arc> '(+ 1 2) (+ 1 2)
The first expression returns 3. The second returns the list beacuse it is blocked by an apostrophe which contains + 1 2.
A list can be constructed by cons operator which returns a list with the new element in beginning:
arc> (cons 'f '(a b)) (f a b)
Wherein the original list is not changed.
arc> (= x '(a b)) (a b) arc> (cons 'f x) (f a b) arc> x (a b)
A free list is represented by nil symbol which evaluates itself by definition. Thus it is possible to create a list with a single element:
arc> (cons 'a nil) (a)
Operators car and cdr
A list can be split using car and cdr operators which return list head and list tail respectively:
arc> (car '(a b c)) a arc> (cdr '(a b c)) (b c)
A list can be created by list operator which calls cons for all elementes in a row.
arc> (list 'a 1 "foo" '(b)) (a 1 "foo" (b)) arc> (cons 'a (cons 1 (cons "foo" (cons '(b) nil)))) (a 1 "foo" (b))
Just like in Common Lisp assignment in Arc is also applicable for both variables and structure constituents. Therefore it can be used for list changing:
arc> x (a b) arc> (= (car x) 'z) z arc> x (z b)
You can define new operators using def operator which has following arguments - function name, identifier list, function body. These expressions will be evaluated in turn on call.
Here is a function example which takes two numbers and calculates an average value:
arc> (def average (x y) (/ (+ x y) 2)) #<procedure: average> arc> (average 2 4) 3
Operators let and with
There are 2 operators which are used for local variables definition: let and with. First is used for defining a single variable.
arc> (let x 1 (+ x (* x 2))) 3 arc> (with (x 3 y 4) (sqrt (+ (expt x 2) (expt y 2)))) 5
Basic conditional operatorl is if. Just like = and def it does not evaluate all the argument values. If 3 have been passed then it evaluates first and in true case it evaluates the second and so on. The return value is the last true value.
arc> (if (odd 1) 'a 'b) a arc> (if (odd 2) 'a 'b) b
If the third argument if is missing then it is considered that it has nil value.
arc> (if (odd 2) 'a) nil
If with 4 and more inserted arguments is equivalent to several inserted if.
(if a b c d e)
Is equivalent to:
(if a b (if c d e))
Operators or, and
Operators or, and represent conditional operators because they do not evaluate their arguments if it is unnecessary.
arc> (and nil (pr "you'll never see this")) nil
Standart comparison operator is called is. It returns true if its arguments are identical and in string case it returns true if they consist of the same symbols.
arc> (is 'a 'a) t arc> (is "foo" "foo") t arc> (let x (list 'a) (is x x)) t arc> (is (list 'a) (list 'a)) nil