diff --git a/examples/99bottles.ark b/examples/99bottles.ark index 03f599f99..6e54da720 100644 --- a/examples/99bottles.ark +++ b/examples/99bottles.ark @@ -1,21 +1,25 @@ # Lyrics from the song: -# +# # 99 bottles of beer on the wall # 99 bottles of beer # Take one down, pass it around # 98 bottles of beer on the wall -# +# # 98 bottles of beer on the wall # 98 bottles of beer # Take one down, pass it around # 97 bottles of beer on the wall - - -(let arg (if (>= (len sys:args) 1) (toNumber (@ sys:args 0)) nil)) -(let i (if (nil? arg) 100 arg)) +(let arg + (if (>= (len sys:args) 1) + (toNumber (@ sys:args 0)) + nil)) +(let i + (if (nil? arg) + 100 + arg)) (mut n i) (while (> n 1) { - (print (str:format "{} Bottles of beer on the wall\n{} bottles of beer\nTake one down, pass it around" n n)) - (set n (- n 1)) - (print (str:format "{} Bottles of beer on the wall." n))}) + (print (str:format "{} Bottles of beer on the wall\n{} bottles of beer\nTake one down, pass it around" n n)) + (set n (- n 1)) + (print (str:format "{} Bottles of beer on the wall." n)) }) diff --git a/examples/ackermann.ark b/examples/ackermann.ark index 879145214..f652e592a 100644 --- a/examples/ackermann.ark +++ b/examples/ackermann.ark @@ -6,16 +6,15 @@ # Due to its definitions in terms of extremely deep recursion, it can be used as a # benchmark of a compiler's ability to optimize recursion, which is the reason why # we are using this function to benchmark the language. - (let ackermann (fun (m n) { - (if (> m 0) - # then - (if (= 0 n) - # then - (ackermann (- m 1) 1) - # else - (ackermann (- m 1) (ackermann m (- n 1)))) - # else - (+ 1 n))})) + (if (> m 0) + # then + (if (= 0 n) + # then + (ackermann (- m 1) 1) + # else + (ackermann (- m 1) (ackermann m (- n 1)))) + # else + (+ 1 n)) })) (print "Ackermann-Péter function, m=3, n=6: " (ackermann 3 6)) diff --git a/examples/blockchain.ark b/examples/blockchain.ark index 04af95fe5..59b23ab77 100644 --- a/examples/blockchain.ark +++ b/examples/blockchain.ark @@ -7,88 +7,97 @@ # define what an ArkCoin block is (let make:block (fun (index timestamp data previous_hash) { - (let hash (hash:sha256 (+ (toString index) (toString (math:floor timestamp)) (json:toString data) previous_hash))) - (print "made block " hash) - (fun (&index ×tamp &data &previous_hash &hash) ())})) + (let hash (hash:sha256 (+ (toString index) (toString (math:floor timestamp)) (json:toString data) previous_hash))) + (print "made block " hash) + (fun (&index ×tamp &data &previous_hash &hash) ()) })) -(let make:block:fromJSON (fun (data) - (make:block (json:get data "index") - (json:get data "timestamp") - (json:get data "data") - (json:get data "hash")))) +(let make:block:fromJSON (fun (data) (make:block (json:get data "index") (json:get data "timestamp") (json:get data "data") (json:get data "hash")))) # generate genesis block -(let make:genesis_block (fun () - (make:block 0 (time) (json:fromList [ - "type" "Genesis block" - "proof-of-work" 1 - ]) "deadbeef"))) +(let make:genesis_block (fun () (make:block 0 (time) (json:fromList ["type" "Genesis block" "proof-of-work" 1]) "deadbeef"))) # let the user add their miner address if we can't find it -(let miner_address (if (not (io:fileExists? "miner.address")) +(let miner_address + (if (not (io:fileExists? "miner.address")) (input "miner address> ") (io:readFile "miner.address"))) (io:writeFile "miner.address" miner_address) + # this node's blockchain copy -(mut blockchain (list (make:genesis_block))) +(mut blockchain [(make:genesis_block)]) + # storing the transactions that this node has (mut nodes_transactions []) + # storing the url data of every other node in the network so we can talk with them (mut peer_nodes []) + # magic number for the proof of work (let magic 12) (let find_new_chains (fun () { - (print "finding new chains") - - # get the blockchains of every other node - (mut other_chains []) - (list:forEach peer_nodes (fun (url) { - (let cli (http:client:create url 80)) - (let tmp (http:client:get cli "/")) - (if (not (nil? tmp)) - { - (let content (make:block:fromJSON (json:fromString (@ tmp 1)))) - (set other_chains (append other_chains content))}) - (del cli)})) - other_chains })) - -(let verify_proof_of_work (fun (proof last_proof) - (and (> proof last_proof) (= 0 (mod proof magic)) (= 0 (mod proof last_proof))))) + (print "finding new chains") + + # get the blockchains of every other node + (mut other_chains []) + + (list:forEach + peer_nodes + (fun (url) { + (let cli (http:client:create url 80)) + (let tmp (http:client:get cli "/")) + + (if (not (nil? tmp)) { + (let content (make:block:fromJSON (json:fromString (@ tmp 1)))) + (set other_chains (append other_chains content)) }) + (del cli) })) + other_chains })) + +(let verify_proof_of_work (fun (proof last_proof) (and (> proof last_proof) (= 0 (mod proof magic)) (= 0 (mod proof last_proof))))) (let verify_chain (fun (chain) { - (print "verifying chain") + (print "verifying chain") - (mut previous nil) - (mut ok? true) - (list:forEach chain (fun (block) { - # no need to continue checking the blocks if a block wasn't ok - (if (and ok? (not (nil? previous))) - (set ok? (verify_proof_of_work (json:get block.data "proof-of-work") (json:get previous.data "proof-of-work")))) - (set previous block)})) - ok? })) + (mut previous nil) + (mut ok? true) + + (list:forEach + chain + (fun (block) { + # no need to continue checking the blocks if a block wasn't ok + (if (and ok? (not (nil? previous))) + (set ok? (verify_proof_of_work (json:get block.data "proof-of-work") (json:get previous.data "proof-of-work")))) + (set previous block) })) + ok? })) (let consensus (fun () { - (print "consensus running") + (print "consensus running") + + (let other_chains (find_new_chains)) - (let other_chains (find_new_chains)) - # if our chain isn't longest, then we store the longest - (list:forEach other_chains (fun (chain) { - (if (and (< (len blockchain) (len chain)) (verify_chain chain)) - (set blockchain chain))}))})) + # if our chain isn't longest, then we store the longest + (list:forEach + other_chains + (fun (chain) { + (if (and (< (len blockchain) (len chain)) (verify_chain chain)) + (set blockchain chain)) })) })) (let proof_of_work (fun (last_proof) { - (print "proof of work being generated") + (print "proof of work being generated") - (mut inc (+ 1 last_proof)) - # keep incrementing until it's equal to a number divisible by 12 and - # the proof of work of the previous block in the chain - (while (not (and (= 0 (mod inc magic))) (= 0 (mod inc last_proof))) - (set inc (+ 1 inc))) - inc })) + (mut inc (+ 1 last_proof)) + + # keep incrementing until it's equal to a number divisible by 12 and + # the proof of work of the previous block in the chain + (while (not (and (= 0 (mod inc magic))) (= 0 (mod inc last_proof))) + (set inc (+ 1 inc))) + inc })) (let srv (http:server:create)) -(http:server:post srv "/transaction" (fun (request) { +(http:server:post + srv + "/transaction" + (fun (request) { (print "posting block " request) # on each post request, extract transaction data @@ -100,69 +109,60 @@ (print (str:format "AMOUNT: {}" (json:get new "amount"))) # return value - [200 "transaction submission successful" "text/plain"]})) + [200 "transaction submission successful" "text/plain"] })) -(http:server:get srv "/blocks" (fun (_) { +(http:server:get + srv + "/blocks" + (fun (_) { (print "fetching blocks") (consensus) (mut to_send []) - (list:forEach blockchain (fun (data) { - (set to_send (append to_send (json:fromList [ - "index" data.index - "timestamp" data.timestamp - "data" data.data - "hash" data.hash])))})) + + (list:forEach + blockchain + (fun (data) { + (set to_send (append to_send (json:fromList ["index" data.index "timestamp" data.timestamp "data" data.data "hash" data.hash]))) })) (mut str (toString (@ to_send 0))) - (list:forEach (tail to_send) (fun (e) - (set str (+ str ", " (toString e))))) - [200 (+ "{\"chain\": [" str "]}") "application/json"]})) + (list:forEach + (tail to_send) + (fun (e) + (set str (+ str ", " (toString e))))) + [200 (+ "{\"chain\": [" str "]}") "application/json"] })) -(http:server:get srv "/mine" (fun (data) { +(http:server:get + srv + "/mine" + (fun (data) { (print "mining block") (print (type data)) - (if (not (nil? data)) - (print (http:params:toList data))) + + (if (not (nil? data)) (print (http:params:toList data))) (set data "") (let last_block (@ blockchain -1)) (let last_proof (json:get last_block.data "proof-of-work")) + # find the proof of work for the current block being mined # the program will hang here until a new proof of work is found (let proof (proof_of_work last_proof)) + # once we have the proof of work, we can mine a block so we reward the miner by adding a transaction - (set nodes_transactions (append nodes_transactions (json:fromList - [ - "from" "network" - "to" miner_address - "amount" 1]))) + (set nodes_transactions (append nodes_transactions (json:fromList ["from" "network" "to" miner_address "amount" 1]))) (print "make block") + # gather the data needed to create a new block - (mut new_block (make:block - (+ 1 last_block.index) - (time) - (json:fromList - [ - "proof-of-work" proof - "transactions" nodes_transactions - "content" data ]) - last_block.hash)) + (mut new_block (make:block (+ 1 last_block.index) (time) (json:fromList ["proof-of-work" proof "transactions" nodes_transactions "content" data]) last_block.hash)) (set blockchain (append blockchain new_block)) + # empty transactions list (set nodes_transactions []) - [ - 200 - (+ "{" - "\"index\": " (toString new_block.index) "," - "\"timestamp\": " (toString new_block.timestamp) "," - "\"data\": " (toString new_block.data) "," - "\"hash\": \"" (toString new_block.hash) "\"" - "}") - "application/json"]})) + [200 (+ "{" "\"index\": " (toString new_block.index) "," "\"timestamp\": " (toString new_block.timestamp) "," "\"data\": " (toString new_block.data) "," "\"hash\": \"" (toString new_block.hash) "\"" "}") "application/json"] })) (print "Listening on localhost:80 for miner " miner_address) (http:server:listen srv "localhost" 80) diff --git a/examples/callbacks.ark b/examples/callbacks.ark index 1930413a7..b76b738c8 100644 --- a/examples/callbacks.ark +++ b/examples/callbacks.ark @@ -1,29 +1,34 @@ # a function which just prints its argument (let egg (fun (bar) (print bar))) + # the data we're going to give to this function (let data ["Iron Man" "is" "Tony Stark"]) + # a list of function call which should be executed later on (mut callbacks []) (print "Data: " data) (print "Generating callbacks") (mut acc 0) + # here we are filling the list callbacks (while (!= acc (len data)) { - (mut d (@ data acc)) - # by putting in it closures that captured d, an element of `data` - # and call the function egg on it - (set callbacks (append callbacks (fun (&d) (egg d)))) - (set acc (+ 1 acc))}) + (mut d (@ data acc)) + + # by putting in it closures that captured d, an element of `data` + # and call the function egg on it + (set callbacks (append callbacks (fun (&d) (egg d)))) + (set acc (+ 1 acc)) }) # then we reset the accumulator (set acc 0) (while (!= acc (len callbacks)) { - # we print what was stored in the closure using dot notation - (mut stored (@ callbacks acc)) - (print "stored: " stored.d) - # and then we call the closure itself (be careful: (@ callbacks acc) only returns the callback, - # thus we need to put it in another pair of parens to call the callback) - (puts "Calling callback number " acc ": ") - ((@ callbacks acc)) - (set acc (+ 1 acc))}) + # we print what was stored in the closure using dot notation + (mut stored (@ callbacks acc)) + (print "stored: " stored.d) + + # and then we call the closure itself (be careful: (@ callbacks acc) only returns the callback, + # thus we need to put it in another pair of parens to call the callback) + (puts "Calling callback number " acc ": ") + ((@ callbacks acc)) + (set acc (+ 1 acc)) }) diff --git a/examples/closures.ark b/examples/closures.ark index f818e5632..cd9d23e9d 100644 --- a/examples/closures.ark +++ b/examples/closures.ark @@ -1,15 +1,15 @@ # Inspired by # Closures and object are equivalent: http://wiki.c2.com/?ClosuresAndObjectsAreEquivalent - # this will construct a closure capturing the 3 arguments, plus a function to set the age (let create-human (fun (name age weight) { - # functions can be invoked in the closure scope - (let set-age (fun (new-age) (set age new-age))) + # functions can be invoked in the closure scope + (let set-age (fun (new-age) + (set age new-age))) - # the return value, our closure - # the &name notation is used in the argument list to explicitly capture - # a variable (using deep copy) - (fun (&set-age &name &age &weight) ())})) + # the return value, our closure + # the &name notation is used in the argument list to explicitly capture + # a variable (using deep copy) + (fun (&set-age &name &age &weight) ()) })) # we create 2 humans using such construction, just a nice function call (let bob (create-human "Bob" 0 144)) @@ -17,30 +17,29 @@ # using the dot notation on a closure object, we can have a **read only** access to its fields (print "Bob's age: " bob.age) + # and even call the captured functions, which will enter the closure, and be given a **read write** access # meaning that, even if the fields are read only (eg, we can not do (set bob.age 14)), the "object" can be modified (print "Setting Bob's age to 10") (bob.set-age 10) + # the age changed (print "New age: " bob.age) # but john age didn't change, because we created 2 separated closures (print "John's age, didn't change: " john.age) - - # Another example to simulate a python range(x, y) - # this function will return a closure capturing the number given # and modifying its value each time we'll call the closure, returning # the new number (let countdown-from (fun (number) - (fun (&number) { - (set number (- number 1)) - number }))) + (fun (&number) { + (set number (- number 1)) + number }))) (let countdown-from-3 (countdown-from 3)) -(print "Countdown " (countdown-from-3)) # 2 -(print "Countdown " (countdown-from-3)) # 1 -(print "Countdown " (countdown-from-3)) # 0 +(print "Countdown " (countdown-from-3)) # 2 +(print "Countdown " (countdown-from-3)) # 1 +(print "Countdown " (countdown-from-3)) # 0 diff --git a/examples/collatz.ark b/examples/collatz.ark index 2828e7ab1..917a223ac 100644 --- a/examples/collatz.ark +++ b/examples/collatz.ark @@ -1,23 +1,22 @@ # If the number is even, divide it by two. # If the number is odd, triple it and add one. - (let get? (fun (seq idx default) - (if (> (len seq) idx) - (@ seq idx) - default))) + (if (> (len seq) idx) + (@ seq idx) + default))) (let n (toNumber (get? sys:args 0 "10"))) (let collatz (fun (num) - (if (= 0 (mod num 2)) - (math:floor (/ num 2)) - (math:floor (+ 1 (* 3 num)))))) + (if (= 0 (mod num 2)) + (math:floor (/ num 2)) + (math:floor (+ 1 (* 3 num)))))) (mut a_i n) (mut iterations 0) (while (!= 1 a_i) { - (print a_i) - (set a_i (collatz a_i)) - (set iterations (+ 1 iterations))}) + (print a_i) + (set a_i (collatz a_i)) + (set iterations (+ 1 iterations)) }) (print "Reached 1 in " iterations " iteration(s)") diff --git a/examples/counter.ark b/examples/counter.ark index 351c3f4d6..1fb4cb244 100644 --- a/examples/counter.ark +++ b/examples/counter.ark @@ -1,8 +1,8 @@ (puts "\t\tHello world\nHere is a counter: ") (mut i 0) (while (<= i 100) { - # puts doesn't put a \n at the end of the string - (puts "\rHere is a counter: " i "/100") - (set i (+ 1 i)) - # sleep for 50ms - (sys:sleep 50)}) + # puts doesn't put a \n at the end of the string + (puts "\rHere is a counter: " i "/100") + (set i (+ 1 i)) + # sleep for 50ms + (sys:sleep 50) }) diff --git a/examples/error.ark b/examples/error.ark index c166f9397..1e34b97cd 100644 --- a/examples/error.ark +++ b/examples/error.ark @@ -6,17 +6,16 @@ # the function which should do a "safe number inversion" (let invert (fun (x) { - (if (= x 0) - # then - (throw "cannot divide by zero") # the value we should return in case of an error - # else - (return (/ 1 x)))})) # the value returned if everything is ok (if (!= x 0)) + (if (= x 0) + # then + (throw "cannot divide by zero") + # the value we should return in case of an error + # else + (return (/ 1 x))) })) # the value returned if everything is ok (if (!= x 0)) # this function (try) is implemented in Exceptions.ark (in lib/std/) # and will check the return value of (invert 0) # if it's an error (seen by the use of throw), it will call the second function, # if it's a result, it will call the first # it works the same way as a try: { function then } catch { do_something } -(try (invert 0) - (fun (inverted) (print inverted)) - (fun (err) (print err))) +(try (invert 0) (fun (inverted) (print inverted)) (fun (err) (print err))) diff --git a/examples/factorial.ark b/examples/factorial.ark index 160e2b808..2831de7db 100644 --- a/examples/factorial.ark +++ b/examples/factorial.ark @@ -2,15 +2,16 @@ # we create a constant named fact, and put a function in it # taking a single argument, n (let fact (fun (n) { - (mut a 1) - (mut acc 2) - # then we use a loop (for loops doesn't exist in ArkScript) - (while (<= acc n) { - (set a (* a acc)) - # thus we need to increment the accumulator ourselves - (set acc (+ 1 acc))}) - # the return value - a })) + (mut a 1) + (mut acc 2) + + # then we use a loop (for loops doesn't exist in ArkScript) + (while (<= acc n) { + (set a (* a acc)) + # thus we need to increment the accumulator ourselves + (set acc (+ 1 acc)) }) + # the return value + a })) # then we call the function we just created (print "Factorial 6 (with loop and acc): " (fact 6)) diff --git a/examples/fibo.ark b/examples/fibo.ark index ed3dbd708..7d44e58b8 100644 --- a/examples/fibo.ark +++ b/examples/fibo.ark @@ -1,9 +1,9 @@ # an example of a classic recursive function (let fibo (fun (n) - (if (< n 2) - # then, its the last value evaluated in this case, thus it's the return value - n - # else, the last value evaluated in this branch as well - (+ (fibo (- n 1)) (fibo (- n 2)))))) + (if (< n 2) + # then, its the last value evaluated in this case, thus it's the return value + n + # else, the last value evaluated in this branch as well + (+ (fibo (- n 1)) (fibo (- n 2)))))) (print "Fibonacci 28: " (fibo 28)) diff --git a/examples/http.ark b/examples/http.ark index 93051300c..4f92218e4 100644 --- a/examples/http.ark +++ b/examples/http.ark @@ -5,48 +5,54 @@ (let server false) (if server - # then, server - { - # we can have only 1 server at a time - (let srv (http:server:create)) - # the handler answering requests on a given route, here /hi - (let f (fun (data) { - [ - 200 - (if (nil? data) - "hello world" - (+ "hello, " (toString (http:params:toList data)))) - "text/plain" - ]})) - # configure the route and the handler, we can also give a string instead of a function - (http:server:get srv "/hi" f) - (print "starting on localhost:80") - # make the server listen forever on the port 80 - (http:server:listen srv "localhost" 80)} - # else, client - { - # we give the website and the port - (let cli (http:client:create "monip.org" 80)) - - # we get a route on a given client - (mut output (http:client:get cli "/")) - # if we got nil, then we couldn't reach the destination - (if (nil? output) - (print "couldn't reach the server") - (print output)) - - # we can create multiple clients at the same time - (let cli2 (http:client:create "yahoo.com" 80)) - - (set output (http:client:get cli2 "/")) - # the function returns a list: [code content] - (print (@ output 0)) # status: 301 - - # follow redirections - (http:client:setFollowLocation cli2 true) - # and retry - (set output (http:client:get cli2 "/")) - # it should work now - (if (nil? output) - (print "error") - (print (@ output 0)))}) # status: 200 + # then, server + { + # we can have only 1 server at a time + (let srv (http:server:create)) + + # the handler answering requests on a given route, here /hi + (let f (fun (data) { + [ + 200 + (if (nil? data) + "hello world" + (+ "hello, " (toString (http:params:toList data)))) + "text/plain"] })) + + # configure the route and the handler, we can also give a string instead of a function + (http:server:get srv "/hi" f) + (print "starting on localhost:80") + + # make the server listen forever on the port 80 + (http:server:listen srv "localhost" 80) } + # else, client + { + # we give the website and the port + (let cli (http:client:create "monip.org" 80)) + + # we get a route on a given client + (mut output (http:client:get cli "/")) + + # if we got nil, then we couldn't reach the destination + (if (nil? output) + (print "couldn't reach the server") + (print output)) + + # we can create multiple clients at the same time + (let cli2 (http:client:create "yahoo.com" 80)) + + (set output (http:client:get cli2 "/")) + # the function returns a list: [code content] + (print (@ output 0)) + + # status: 301 + # follow redirections + (http:client:setFollowLocation cli2 true) + + # and retry + (set output (http:client:get cli2 "/")) + + # it should work now + (if (nil? output) + (print "error") + (print (@ output 0))) }) # status: 200 diff --git a/examples/macros.ark b/examples/macros.ark index 4a6dc1c9f..8e1695145 100644 --- a/examples/macros.ark +++ b/examples/macros.ark @@ -1,12 +1,11 @@ ($ suffix-dup (sym x) { - ($if (> x 1) - (suffix-dup sym (- x 1))) - ($symcat sym x)}) + ($if (> x 1) (suffix-dup sym (- x 1))) + ($symcat sym x) }) ($ partial (func ...defargs) { - ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) - (fun (bloc) (func ...defargs bloc)) - ($undef bloc)}) + ($ bloc (suffix-dup a (- ($argcount func) (len defargs)))) + (fun (bloc) (func ...defargs bloc)) + ($undef bloc) }) (let test_func (fun (a b c) (* a b c))) (let test_func1 (partial test_func 1)) @@ -23,12 +22,12 @@ (print "Using macro constant var=12: " var) ($if (= var 12) - (print "This was executed in a if macro, testing var == 12") - (print "You shouldn't see this")) + (print "This was executed in a if macro, testing var == 12") + (print "You shouldn't see this")) ($if (and true true) - (print "This was executed in a if macro, testing (and true true)") - (print "You shouldn't see this (bis)")) + (print "This was executed in a if macro, testing (and true true)") + (print "You shouldn't see this (bis)")) ($ defun (name args body) (let name (fun args body))) (defun a_func (a b) (+ a b)) @@ -46,48 +45,47 @@ (last 1 5 6 7 8) { - (print "Testing macros in scopes and macro shadowing") +(print "Testing macros in scopes and macro shadowing") - ($ test (+ 1 2 3)) - (print "(global) Reading macro 'test', expected 6, " test) +($ test (+ 1 2 3)) +(print "(global) Reading macro 'test', expected 6, " test) - ((fun () { - ($ test (- 1 2 3)) - (print "(sub scope) Reading macro 'test', expected -4, " test)})) +((fun () { + ($ test (- 1 2 3)) + (print "(sub scope) Reading macro 'test', expected -4, " test) })) - (print "(global) Reading macro 'test', expected 6, " test) - - { - ($ test 555) - (print "(subscope) Reading macro 'test', expected 555, " test) - ($ undef test) - (print "(subscope, undef test) Reading macro 'test', expected 6, " test) - ($ undef a)}} +(print "(global) Reading macro 'test', expected 6, " test) +{ + ($ test 555) + (print "(subscope) Reading macro 'test', expected 555, " test) + ($ undef test) + (print "(subscope, undef test) Reading macro 'test', expected 6, " test) + ($ undef a) } } (print "Demonstrating a threading macro") ($ -> (arg fn1 ...fn) { - ($if (> (len fn) 0) - (-> (fn1 arg) ...fn) - (fn1 arg))}) + ($if (> (len fn) 0) + (-> (fn1 arg) ...fn) + (fn1 arg)) }) (let filename "hello.json") (let f1 (fun (data) { - (print ">>f1 " data) - (+ data "-f1")})) + (print ">>f1 " data) + (+ data "-f1") })) (let f2 (fun (data) { - (print ">>f2 " data) - (+ data "-f2")})) + (print ">>f2 " data) + (+ data "-f2") })) (let f3 (fun (data) { - (print ">>f3 " data) - (+ data "-f3")})) + (print ">>f3 " data) + (+ data "-f3") })) (let f4 (fun (data) { - (print ">>f4 " data) - (+ data "-f4")})) + (print ">>f4 " data) + (+ data "-f4") })) (print "We expected calls to go like this: f1, f2, f3, f4") -(print (-> filename f1 f2 f3 f4)) # (f4 (f3 (f2 (f1 filename)))) +(print (-> filename f1 f2 f3 f4)) # (f4 (f3 (f2 (f1 filename)))) diff --git a/examples/more-or-less.ark b/examples/more-or-less.ark index 4b2b6c519..c06f792bc 100644 --- a/examples/more-or-less.ark +++ b/examples/more-or-less.ark @@ -4,22 +4,22 @@ (let number (mod (math:abs (random)) 10000)) (let game (fun () { - (let impl (fun (tries) { - (mut guess (toNumber (input "Input a numeric value: "))) + (let impl (fun (tries) { + (mut guess (toNumber (input "Input a numeric value: "))) - (if (< guess number) - { - (print "It's more than " guess) - (impl (+ tries 1))} - (if (= guess number) - { - (print "You found it!") - tries } - { - (print "It's less than " guess) - (impl (+ tries 1))}))})) + (if (< guess number) + { + (print "It's more than " guess) + (impl (+ tries 1)) } + (if (= guess number) + { + (print "You found it!") + tries } + { + (print "It's less than " guess) + (impl (+ tries 1)) })) })) - (let tries (impl 0)) - (print "You won in " tries " tries.")})) + (let tries (impl 0)) + (print "You won in " tries " tries.") })) (game) diff --git a/examples/quicksort.ark b/examples/quicksort.ark index a1eb5180b..f9ff9ca9a 100644 --- a/examples/quicksort.ark +++ b/examples/quicksort.ark @@ -1,53 +1,60 @@ (import std.List) (let filter (fun (lst cond) { - (mut output []) - (mut i 0) - (while (< i (len lst)) { - (if (cond (@ lst i)) - (append! output (@ lst i))) - (set i (+ 1 i))}) - output })) + (mut output []) + (mut i 0) + + (while (< i (len lst)) { + (if (cond (@ lst i)) (append! output (@ lst i))) + (set i (+ 1 i)) }) + output })) # a quicksort function in ArkScript, a lot smaller than its C++ version! # and according to me, a lot simpler to understand (let quicksort (fun (array) { - (if (empty? array) - # if the given list is empty, return it - [] - # otherwise, sort it - { - # the pivot will be the first element - (let pivot (head array)) - # call quicksort on a smaller array containing all the elements less than the pivot - (mut less (quicksort (filter (tail array) (fun (e) (< e pivot))))) - # and after that, call quicksort on a smaller array containing all the elements greater or equal to the pivot - (let more (quicksort (filter (tail array) (fun (e) (>= e pivot))))) - - (concat! less [pivot] more) - # return a concatenation of arrays - less })})) + (if (empty? array) + # if the given list is empty, return it + [] + # otherwise, sort it + { + # the pivot will be the first element + (let pivot (head array)) + + # call quicksort on a smaller array containing all the elements less than the pivot + (mut less (quicksort (filter (tail array) (fun (e) (< e pivot))))) + + # and after that, call quicksort on a smaller array containing all the elements greater or equal to the pivot + (let more (quicksort (filter (tail array) (fun (e) (>= e pivot))))) + + (concat! less [pivot] more) + # return a concatenation of arrays + less }) })) # an unsorted list to sort (let a [3 6 1 5 1 65 324 765 1 6 3 0 6 9 6 5 3 2 5 6 7 64 645 7 345 432 432 4 324 23]) -(let rep (if (>= (len sys:args) 1) (toNumber (@ sys:args 0)) 1)) +(let rep + (if (>= (len sys:args) 1) + (toNumber (@ sys:args 0)) + 1)) # a benchmarking function, to see the difference between C++ sort and ArkScript quicksort # obviously ArkScript will be a bit slower (let bench (fun (name code) { - (mut start (time)) + (mut start (time)) + + (mut i 0) - (mut i 0) - (while (< i rep) { - (code) - (set i (+ 1 i))}) + (while (< i rep) { + (code) + (set i (+ 1 i)) }) - (let t (/ (* 1000 (- (time) start)) rep)) - (print name " average: " t "ms") - t })) + (let t (/ (* 1000 (- (time) start)) rep)) + (print name " average: " t "ms") + t })) (print a) + # use a quoted argument to defer evaluation and be able to call it multiple times in a fresh context (let ark (bench "ark" (fun () (quicksort a)))) (let cpp (bench "cpp" (fun () (list:sort a)))) diff --git a/examples/sum_digits.ark b/examples/sum_digits.ark index 72e66c9b1..74b80ad2e 100644 --- a/examples/sum_digits.ark +++ b/examples/sum_digits.ark @@ -2,23 +2,27 @@ (import std.String) (let to-base (fun (n base) { - (let o (str:ord n)) - (let v (if (and (>= o 48) (<= o 57)) - (- o 48) - (if (and (>= o 97) (<= o 122)) - (- o 87) + (let o (str:ord n)) + + (let v + (if (and (>= o 48) (<= o 57)) + (- o 48) + (if (and (>= o 97) (<= o 122)) + (- o 87) (if (and (>= o 65) (<= o 90)) - (- o 55) - o )))) - (mod v base)})) + (- o 55) + o)))) + (mod v base) })) (let sum-digits (fun (n base) { - (let number (if (not (= "String" (type n))) (toString n) n)) - (list:reduce - (list:map number (fun (e) (to-base e base))) - (fun (a b) (+ a b)))})) + (let number + (if (not (= "String" (type n))) + (toString n) + n)) + + (list:reduce (list:map number (fun (e) (to-base e base))) (fun (a b) (+ a b))) })) -(print (sum-digits 1 10)) # 1 -(print (sum-digits 1234 10)) # 10 -(print (sum-digits "fe" 16)) # 29 -(print (sum-digits "f0e" 16)) # 29 +(print (sum-digits 1 10)) # 1 +(print (sum-digits 1234 10)) # 10 +(print (sum-digits "fe" 16)) # 29 +(print (sum-digits "f0e" 16)) # 29