summaryrefslogtreecommitdiffhomepage
path: root/paren.html.markdown
blob: 701cadfd3ceb1595f4822e5ecc7684791584f967 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
---

language: Paren
filename: learnparen.paren
contributors:
  - ["KIM Taegyoon", "https://github.com/kimtg"]
  - ["Claudson Martins", "https://github.com/claudsonm"]
---

[Paren](https://bitbucket.org/ktg/paren) is a dialect of Lisp. It is designed to be an embedded language.

Some examples are from <http://learnxinyminutes.com/docs/racket/>.

```scheme
;;; Comments
# comments

;; Single line comments start with a semicolon or a sharp sign

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 1. Primitive Datatypes and Operators
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Numbers
123 ; int
3.14 ; double
6.02e+23 ; double
(int 3.14) ; => 3 : int
(double 123) ; => 123 : double

;; Function application is written (f x y z ...)
;; where f is a function and x, y, z, ... are operands
;; If you want to create a literal list of data, use (quote) to stop it from
;; being evaluated
(quote (+ 1 2)) ; => (+ 1 2)
;; Now, some arithmetic operations
(+ 1 1)  ; => 2
(- 8 1)  ; => 7
(* 10 2) ; => 20
(^ 2 3) ; => 8
(/ 5 2) ; => 2
(% 5 2) ; => 1
(/ 5.0 2) ; => 2.5

;;; Booleans
true ; for true
false ; for false
(! true) ; => false
(&& true false (prn "doesn't get here")) ; => false
(|| false true (prn "doesn't get here")) ; => true

;;; Characters are ints.
(char-at "A" 0) ; => 65
(chr 65) ; => "A"

;;; Strings are fixed-length array of characters.
"Hello, world!"
"Benjamin \"Bugsy\" Siegel"   ; backslash is an escaping character
"Foo\tbar\r\n" ; includes C escapes: \t \r \n

;; Strings can be added too!
(strcat "Hello " "world!") ; => "Hello world!"

;; A string can be treated like a list of characters
(char-at "Apple" 0) ; => 65

;; Printing is pretty easy
(pr "I'm" "Paren. ") (prn "Nice to meet you!")

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 2. Variables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; You can create or set a variable using (set)
;; a variable name can use any character except: ();#"
(set some-var 5) ; => 5
some-var ; => 5

;; Accessing a previously unassigned variable is an exception
; x ; => Unknown variable: x : nil

;; Local binding: Use lambda calculus! 'a' and 'b' are bound to '1' and '2' only within the (fn ...)
((fn (a b) (+ a b)) 1 2) ; => 3

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Collections
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Lists

;; Lists are vector-like data structures. (Random access is O(1).)
(cons 1 (cons 2 (cons 3 (list)))) ; => (1 2 3)
;; 'list' is a convenience variadic constructor for lists
(list 1 2 3) ; => (1 2 3)
;; and a quote can also be used for a literal list value
(quote (+ 1 2)) ; => (+ 1 2)

;; Can still use 'cons' to add an item to the beginning of a list
(cons 0 (list 1 2 3)) ; => (0 1 2 3)

;; Lists are a very basic type, so there is a *lot* of functionality for
;; them, a few examples:
(map inc (list 1 2 3))          ; => (2 3 4)
(filter (fn (x) (== 0 (% x 2))) (list 1 2 3 4))    ; => (2 4)
(length (list 1 2 3 4))     ; => 4

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 3. Functions
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Use 'fn' to create functions.
;; A function always returns the value of its last expression
(fn () "Hello World") ; => (fn () Hello World) : fn

;; Use parentheses to call all functions, including a lambda expression
((fn () "Hello World")) ; => "Hello World"

;; Assign a function to a var
(set hello-world (fn () "Hello World"))
(hello-world) ; => "Hello World"

;; You can shorten this using the function definition syntactic sugar:
(defn hello-world2 () "Hello World")

;; The () in the above is the list of arguments for the function
(set hello
  (fn (name)
    (strcat "Hello " name)))
(hello "Steve") ; => "Hello Steve"

;; ... or equivalently, using a sugared definition:
(defn hello2 (name)
  (strcat "Hello " name))

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 4. Equality
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; for numbers use '=='
(== 3 3.0) ; => true
(== 2 1) ; => false

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 5. Control Flow
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Conditionals

(if true               ; test expression
    "this is true"   ; then expression
    "this is false") ; else expression
; => "this is true"

;;; Loops

;; for loop is for number
;; (for SYMBOL START END STEP EXPR ..)
(for i 0 10 2 (pr i "")) ; => prints 0 2 4 6 8 10
(for i 0.0 10 2.5 (pr i "")) ; => prints 0 2.5 5 7.5 10

;; while loop
((fn (i)
  (while (< i 10)
    (pr i)
    (++ i))) 0) ; => prints 0123456789

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 6. Mutation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Use 'set' to assign a new value to a variable or a place
(set n 5) ; => 5
(set n (inc n)) ; => 6
n ; => 6
(set a (list 1 2)) ; => (1 2)
(set (nth 0 a) 3) ; => 3
a ; => (3 2)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 7. Macros
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Macros let you extend the syntax of the language.
;; Paren macros are easy.
;; In fact, (defn) is a macro.
(defmacro setfn (name ...) (set name (fn ...)))
(defmacro defn (name ...) (def name (fn ...)))

;; Let's add an infix notation
(defmacro infix (a op ...) (op a ...))
(infix 1 + 2 (infix 3 * 4)) ; => 15

;; Macros are not hygienic, you can clobber existing variables!
;; They are code transformations.
```