Show us your Arc code 17 points by parenthesis 4378 days ago | 28 comments Post interesting little functions and macros for others to learn from, and/or improve on.

 12 points by icemaze 4378 days ago | link This one is my personal favorite:`````` (mac >> body `(let it ,(car body) ,(if (cdr body) `(>> ,@(cdr body)) 'it))) `````` It works a little bit like CL's let* but is anaphoric and it's much easier to read. It's a pipeline: each expression is evaluated and it is bound to the result for the next expression to use. Example:`````` (>> '(1 2 3 4 5) (keep odd it) ; -> (1 3 5) (map [* 4 _] it) ; -> (4 12 20) (cons 6 it) ; -> (6 6 14 22) (reduce + it)) ; -> 42 `````` It's very convenient sometimes. Plus, since most of Arc's functions have their main argument at the end (thanks devteam!) it could be modified so that it appends "it" to every expression in the body. This depends on how it's used in the real world.-----
 5 points by noahlt 4378 days ago | link Am I missing something, or is this just an easier way to write:`` (reduce + (cons 6 (map [* 4 _] (keep odd '(1 2 3 4 5)))))``-----
 3 points by icemaze 4378 days ago | link You are right: it just improves readability.-----
 1 point by ehird 4376 days ago | link Ridiculous:`````` (def ablast (l) (if (no (cdr l)) nil (cons (car l) (ablast (cdr l))))) (def replc (x y l) (if (atom l) (if (is x l) y l) (no l) nil (is x (car l)) (cons y (replc x y (cdr l))) (acons (car l)) (cons (replc x y (car l)) (replc x y (cdr l))) (cons (car l) (replc x y (cdr l))))) (mac imp body (if (no body) nil (replc 'it `(imp ,@(ablast body)) (last body))))``````-----
 3 points by sjs 4378 days ago | link I'm still digging through the source, haven't done any coding yet. But...There is a function called 'isnt' I did not see mentioned in the tutorial.`````` arc> (isnt 1 2) t `````` Also an 'empty' function that's true for nil, empty lists and strings.There's subseq, which is sort of like nthcdr but works on lists and strings (any sequence), and takes the seq before the n.`````` arc> (subseq "uh, hello world" 4) "hello world" arc> (subseq (coerce "uh, hello world" 'cons) 4 9) (#\h #\e #\l #\l #\o) `````` 'last' gets you the last value in a cons.`````` arc> (last '(fee fie foe fum)) fum `````` 'adjoin' inserts a value into a set, unless already present.`````` arc> (adjoin '(1 2) '((5 3) (1 2) (7 4))) '((5 3) (1 2) (7 4)) arc> (adjoin 1 '(2 3 4)) (1 2 3 4) `````` 'consif' conses a value if it's not nil.`````` arc> (consif 'sugar '(coffee cream)) (sugar coffee cream) arc> (consif nil '(coffee milk)) (coffee milk) `````` The complement of 'when', pg snuck 'unless' into the arc.arc excerpt at the end.Make sure you read *.arc after the tutorial to really get a feel for the language.-----
 4 points by rkts 4378 days ago | link I translated into Arc a little program I wrote a few months ago to compare the distribution of characters in Qwerty vs. Dvorak by hands, fingers, etc. It currently outputs text; the next step of course is to output HTML.http://benstoker.com/code/lytcmp.archttp://benstoker.com/code/lcex.txtGetting the program to work was a bitch as there doesn't seem to be any debugging support at all. Nevertheless, I'm extremely pleased with the language itself.The utility at the beginning reflects the only serious issue I ran into: objs don't seem to be able refer to themselves. I had to write a new obj macro that binds the current object to 'this'.Also, although it's not a serious problem, I'd love to be able to refer to obj fields with a simpler syntax, e.g. x.foo instead of (x 'foo). In particular, that quote before the field name is kind of a wart.-----
 5 points by simonb 4378 days ago | link From another thread:`````` (def strip (lst str) (rem [some _ lst] str)) arc> (strip "abc" "aghbcdt") "ghdt" arc> (strip "" "aghbcdt") "aghbcdt" arc> (strip () "aghbcdt") "aghbcdt" arc> (strip '(#\a #\t) "aghbcdt") "ghbcd"``````-----
 1 point by simonb 4378 days ago | link A tail recursive map1:`````` (def map1 (f xs (o acc)) (if (no xs) acc (map1 f (cdr xs) (cons (f (car xs)) acc)))) `````` Inspired by andf and orf (one predicate applied many operands):`````` (def orl (f) (fn xs (some f xs))) (def andl (f) (fn xs (all f xs))) `````` It would be interesting to see which is the more common case and change built-in predicates to except multiple operands accordingly.-----
 3 points by chaos 4378 days ago | link Because I'm reddit-damaged:`````` (def unfold (f x) (let res (f x) (if res (cons (car res) (unfold f (cdr res))) ()))) (def romanize (i) (let r '((M 1000)(CM 900)(D 500)(CD 400)(C 100)(L 50)(XL 40)(X 10)(IX 9)(V 5)(IV 4)(I 1)) (unfold (fn ((i . ((r n) . rst))) (if (is i 0) () (>= i n) (cons r (cons (- i n) `((,r ,n) . ,rst))) (cons "" (cons i rst)))) (cons i r)))) (apply string (romanize 999))``````-----
 1 point by parenthesis 4378 days ago | link `````` (def prime (n) (if (~isa n 'int) nil (< (= n (truncate n)) 2) nil (is n 2) t (multiple n 2) nil (with (div 3 lim (truncate (sqrt n)) result t) (while (and (or (~multiple n div) (= result nil)) (< div lim)) (++ div 2)) result)))``````-----
 1 point by parenthesis 4376 days ago | link -- Actually, spot the bug!-----
 5 points by rcoder 4378 days ago | link For those who want a slightly less-complete webapp to use as a sample:`````` (= fortune-bin-path* "/usr/games/fortune" page-title* "Read My Fortune") (def make-fortune-cookie () (tostring (system fortune-bin-path*))) (defop fortune req (whitepage (tag h1 (link page-title* "fortune")) (br 2) (tag pre (pr (make-fortune-cookie))) (br 2) (tag small (link "[made with arc]" "http://arclanguage.org/"))))``````-----
 1 point by albertcardona 4378 days ago | link For illustration, would you mind explaining how to connect this code to a web server.-----
 2 points by rcoder 4378 days ago | link You don't have to connect it. Copy the above into a file called 'fortune.arc' inside your Arc source code directory, then type the following from an Arc REPL:`````` (load "fortune.arc") (asv) `````` The 'asv' function spawns the built-in web server, as shown in the blog example.-----
 1 point by albertcardona 4375 days ago | link Sometimes the program fails with the error below, on clicking on the link. A blank webpage is shown. After F5 (refresh), all back to normal.Looks to me, that the system call fails because 'fortune' returns -1.`````` date: 1202019843: No such file or directory make-string: expects argument of type ; given -1 === context === subseq memodate srvlog gs899 handle-request-thread``````-----
 2 points by mdemare 4378 days ago | link List monad in Arc:`````` (def list-monad (seq . fns) (each f fns (= seq (apply join (map f seq)))) seq) (list-monad '(1 2 3 4 5) [list (- _ 1) _] [list (* 2 _) _])``````-----
 6 points by parenthesis 4378 days ago | link With this you can do things like (s ls -l) or (s clear) or (s mzscheme -m -f as.scm) etc..`````` (mac s args `(system ,(apply string (map [string _ " "] args))))``````-----
 2 points by chaos 4377 days ago | link Maybe I'm the last one to notice withs as let* replacement, maybe not.Simulated Annealing: http://dpaste.com/hold/33337/-----
 1 point by offby1 4377 days ago | link This is a tad bigger than "little", but I'm fond of it: http://polyglot-anagrams.googlecode.com/svn/trunk/arc/-----
 3 points by sjs 4378 days ago | link Standard stuff...`````` (= sum [apply + _]) (= prod [apply * _]) `````` I went to create a range function, but it was already there. It's like python's range:`````` arc> (range 37 42) (37 38 39 40 41 42) `````` There's also intersperse, familiar to Haskell coders, but only works on conses.`````` arc> (intersperse 0 '(42 21 7 1)) (42 0 21 0 7 0 1) `````` There is much more in arc.arc.-----
 3 points by fallintothis 4378 days ago | link range is useful, though I kept making the goof-up of trying to pass only one arg as in Python. So, I went ahead and changed it:`````` (let orig range (def range (x (o y)) (if y (orig x y) (orig 0 x)))) ;could be (orig 0 (- x 1)) to be even more Python-like `````` Come to think of it, you could instead do something like this to be the most like Python (whether or not that's a good thing):`````` (def range (start (o end) (o step 1)) (let test (if (positive step) >= <=) (when (no end) (= end start start 0)) (if (test start end) nil (cons start (range (+ start step) end step))))) arc> (range 10) (0 1 2 3 4 5 6 7 8 9) arc> (range 10 1) nil arc> (range 1 10) (1 2 3 4 5 6 7 8 9) arc> (range 1 10 2) (1 3 5 7 9) arc> (range 1 10 -2) nil arc> (range 10 1 -2) (10 8 6 4 2) arc> (range 10 1 -1) (10 9 8 7 6 5 4 3 2) `````` This same idea of having the "step" parameter maps nicely into subseq syntax in Python, as I noted in this thread: http://www.arclanguage.org/item?id=479-----
 1 point by icemaze 4378 days ago | link Everybody seems to be in love with the step parameter. Would it be such an improvement over (for instance):`````` (reverse (range 10)), or (map [* 2 _] (range 5)) ? `````` Do python guys use it that often?-----
 1 point by Xichekolas 4378 days ago | link Yeah I'd much rather compose functions than have extra parameters to remember... but I'm not a Python guy either.-----
 1 point by apgwoz 4378 days ago | link It's pretty inefficient to use reverse, if instead you can add an extra parameter, though I guess it's often negligible.-----
 1 point by mk 4378 days ago | link I think this is right.`````` arc> (def quadratic (a b c) (= minus-b (- 0 b)) (= radical (sqrt (- (* b b) (* 4 a c)))) (= divisor (* 2 a)) (= root1 (/ (+ minus-b radical) divisor)) (= root2 (/ (- minus-b radical) divisor)) (cons root1 root2))``````-----
 4 points by aidenn0 4378 days ago | link Playing around with strings-as-sequences I wrote the obligatory rot13:`````` (def rot13 (s) (with (a (coerce #\a 'int)) (map [coerce (+ a (mod (- (coerce _ 'int) a 13) 26)) 'char] s)))``````-----
 2 points by abstractbill 4378 days ago | link Pretty obvious, but I couldn't live without dolist:`````` (mac dolist ((iter seq) . body) `(map (fn (,iter) ,@body) ,seq))``````-----
 7 points by pg 4378 days ago | link I think each is what you want.-----