learnxinyminutes-docs/whip.html.markdown

240 lines
6.5 KiB
Markdown
Raw Normal View History

2013-07-31 11:46:16 +04:00
---
language: whip
contributors:
- ["Tenor Biel", "http://github.com/L8D"]
2015-10-18 10:51:31 +03:00
- ["Saurabh Sandav", "http://github.com/SaurabhSandav"]
2013-07-31 11:46:16 +04:00
author: Tenor Biel
author_url: http://github.com/L8D
filename: whip.lisp
---
Whip is a LISP-dialect made for scripting and simplified concepts.
It has also borrowed a lot of functions and syntax from Haskell(a non-related language).
These docs were written by the creator of the language himself. So is this line.
2013-08-01 22:24:23 +04:00
```scheme
; Comments are like LISP. Semi-colons...
2013-07-31 11:46:16 +04:00
; Majority of first-level statements are inside "forms"
; which are just things inside parens separated by whitespace
not_in_form
(in_form)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 1. Numbers, Strings, and Operators
; Whip has one number type (which is a 64-bit IEEE 754 double, from JavaScript).
3 ; => 3
1.5 ; => 1.5
; Functions are called if they are the first element in a form
(called_function args)
; Majority of operations are done with functions
2014-08-13 05:35:42 +04:00
; All the basic arithmetic is pretty straight forward
2013-07-31 11:46:16 +04:00
(+ 1 1) ; => 2
(- 2 1) ; => 1
(* 1 2) ; => 2
(/ 2 1) ; => 2
; even modulo
(% 9 4) ; => 1
; JavaScript-style uneven division.
(/ 5 2) ; => 2.5
; Nesting forms works as you expect.
(* 2 (+ 1 3)) ; => 8
; There's a boolean type.
true
false
2014-08-13 05:35:42 +04:00
; Strings are created with ".
2013-07-31 11:46:16 +04:00
"Hello, world"
; Single chars are created with '.
'a'
; Negation uses the 'not' function.
(not true) ; => false
(not false) ; => true
; But the majority of non-haskell functions have shortcuts
; not's shortcut is a '!'.
(! (! true)) ; => true
; Equality is `equal` or `=`.
(= 1 1) ; => true
(equal 2 1) ; => false
2014-08-13 05:35:42 +04:00
; For example, inequality would be combining the not and equal functions.
2013-07-31 11:46:16 +04:00
(! (= 2 1)) ; => true
; More comparisons
(< 1 10) ; => true
(> 1 10) ; => false
; and their word counterpart.
(lesser 1 10) ; => true
(greater 1 10) ; => false
; Strings can be concatenated with +.
(+ "Hello " "world!") ; => "Hello world!"
; You can use JavaScript's comparative abilities.
(< 'a' 'b') ; => true
; ...and type coercion
(= '5' 5)
; The `at` or @ function will access characters in strings, starting at 0.
(at 0 'a') ; => 'a'
(@ 3 "foobar") ; => 'b'
; There is also the `null` and `undefined` variables.
null ; used to indicate a deliberate non-value
undefined ; user to indicate a value that hasn't been set
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2015-10-18 10:51:31 +03:00
; 2. Variables, Lists, and Dicts
2013-07-31 11:46:16 +04:00
; Variables are declared with the `def` or `let` functions.
2014-08-13 05:35:42 +04:00
; Variables that haven't been set will be `undefined`.
2013-07-31 11:46:16 +04:00
(def some_var 5)
; `def` will keep the variable in the global context.
2015-10-18 10:51:31 +03:00
; `let` will only have the variable inside its context, and has a weirder syntax.
2013-07-31 11:46:16 +04:00
(let ((a_var 5)) (+ a_var 5)) ; => 10
(+ a_var 5) ; = undefined + 5 => undefined
; Lists are arrays of values of any type.
; They basically are just forms without functions at the beginning.
(1 2 3) ; => [1, 2, 3] (JavaScript syntax)
2013-08-01 22:24:23 +04:00
; Dictionaries are Whip's equivalent to JavaScript 'objects' or Python 'dicts'
2013-07-31 11:46:16 +04:00
; or Ruby 'hashes': an unordered collection of key-value pairs.
{"key1" "value1" "key2" 2 3 3}
2013-07-31 11:46:16 +04:00
; Keys are just values, either identifier, number, or string.
(def my_dict {my_key "my_value" "my other key" 4})
; But in Whip, dictionaries get parsed like: value, whitespace, value;
; with more whitespace between each. So that means
{"key" "value"
2013-07-31 11:46:16 +04:00
"another key"
1234
2013-07-31 11:46:16 +04:00
}
; is evaluated to the same as
{"key" "value" "another key" 1234}
2013-07-31 11:46:16 +04:00
2013-08-01 22:24:23 +04:00
; Dictionary definitions can be accessed used the `at` function
; (like strings and lists.)
2013-07-31 11:46:16 +04:00
(@ "my other key" my_dict) ; => 4
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; 3. Logic and Control sequences
2014-08-13 05:35:42 +04:00
; The `if` function is pretty simple, though different than most imperative langs.
2013-07-31 11:46:16 +04:00
(if true "returned if first arg is true" "returned if first arg is false")
; => "returned if first arg is true"
; And for the sake of ternary operator legacy
; `?` is if's unused shortcut.
(? false true false) ; => false
; `both` is a logical 'and' statement, and `either` is a logical 'or'.
(both true true) ; => true
(both true false) ; => false
(either true false) ; => true
(either false false) ; => false
; And their shortcuts are
; & => both
; ^ => either
(& true true) ; => true
(^ false true) ; => true
;;;;;;;;;
; Lambdas
; Lambdas in Whip are declared with the `lambda` or `->` function.
; And functions are really just lambdas with names.
2014-06-21 14:10:34 +04:00
(def my_function (-> (x y) (+ (+ x y) 10)))
; | | | |
2013-07-31 11:46:16 +04:00
; | | | returned value(with scope containing argument vars)
; | | arguments
; | lambda declaration function
; |
2014-08-13 05:35:42 +04:00
; name of the to-be-declared lambda
2013-07-31 11:46:16 +04:00
(my_function 10 10) ; = (+ (+ 10 10) 10) => 30
2015-10-18 10:51:31 +03:00
; Obviously, all lambdas by definition are anonymous and
2014-08-13 05:35:42 +04:00
; technically always used anonymously. Redundancy.
2013-07-31 11:46:16 +04:00
((lambda (x) x) 10) ; => 10
;;;;;;;;;;;;;;;;
; Comprehensions
; `range` or `..` generates a list of numbers for
; each number between it's two args.
(range 1 5) ; => (1 2 3 4 5)
(.. 0 2) ; => (0 1 2)
; `map` applies it's first arg(which should be a lambda/function)
; to each item in the following arg(which should be a list)
(map (-> (x) (+ x 1)) (1 2 3)) ; => (2 3 4)
; Reduce
(reduce + (.. 1 5))
; equivalent to
((+ (+ (+ 1 2) 3) 4) 5)
; Note: map and reduce don't have shortcuts
; `slice` or `\` is just like JavaScript's .slice()
; But do note, it takes the list as the first argument, not the last.
(slice (.. 1 5) 2) ; => (3 4 5)
(\ (.. 0 100) -5) ; => (96 97 98 99 100)
2015-10-18 10:51:31 +03:00
; `append` or `<<` is self explanatory
2013-07-31 11:46:16 +04:00
(append 4 (1 2 3)) ; => (1 2 3 4)
(<< "bar" ("foo")) ; => ("foo" "bar")
; Length is self explanatory.
(length (1 2 3)) ; => 3
(_ "foobar") ; => 6
;;;;;;;;;;;;;;;
; Haskell fluff
; First item in list
(head (1 2 3)) ; => 1
; List from second to last elements in list
(tail (1 2 3)) ; => (2 3)
; Last item in list
(last (1 2 3)) ; => 3
; Reverse of `tail`
(init (1 2 3)) ; => (1 2)
; List from first to specified elements in list
(take 1 (1 2 3 4)) ; (1 2)
; Reverse of `take`
(drop 1 (1 2 3 4)) ; (3 4)
; Lowest value in list
(min (1 2 3 4)) ; 1
; Highest value in list
(max (1 2 3 4)) ; 4
; If value is in list or object
(elem 1 (1 2 3)) ; true
(elem "foo" {"foo" "bar"}) ; true
(elem "bar" {"foo" "bar"}) ; false
2013-07-31 11:46:16 +04:00
; Reverse list order
(reverse (1 2 3 4)) ; => (4 3 2 1)
; If value is even or odd
(even 1) ; => false
(odd 1) ; => true
; Split string into list of strings by whitespace
(words "foobar nachos cheese") ; => ("foobar" "nachos" "cheese")
; Join list of strings together.
(unwords ("foo" "bar")) ; => "foobar"
(pred 21) ; => 20
(succ 20) ; => 21
```
For more info, check out the [repo](http://github.com/L8D/whip)