This repository has been archived by the owner on Jan 16, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 12
/
006infix
106 lines (77 loc) · 2.76 KB
/
006infix
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
--- Infix operators
Unlike other Lisps, Wart supports infix operators.
3 + 1
=> 4
You don't need spaces around infix ops.
3+1
=> 4
Infix ops don't compromise homoiconicity; Wart parses them into Lisp forms so
your macros don't have to worry about them:
'a+b
=> (+ a b)
Infix ops are always left-associative.
'a+b+c
=> (+ (+ a b) c)
Range comparisons are convenient as long as they return the last arg on
success (because of left-associativity) and pass nils through:
'(a > b >= c)
=> (>= (> a b) c) # watch out if b is nil!
(nil < 34)
=> nil # should always be nil
(34 < nil)
=> nil # should always be nil
You can mix infix ops with regular prefix Lisp:
'(a + (f b))
=> (+ a (f b))
'(fib n-1)
=> (fib (- n 1))
Operator precedence is not hardcoded. Instead, there is just one rule:
operators surrounded by whitespace have lower precedence than operators that
are not.
'(n * n-1)
=> (* n (- n 1))
You can create your own infix ops:
def (a <> b)
(not (a = b))
(1 <> 2)
=> 1
To permit arbitrary infix ops, Wart makes them distinct from regular symbols.
The sets of 'infix chars' and 'symbol chars' are disjoint. This implies that
Wart won't let you define some traditional Lisp names that you might be used
to:
'*global*
=> ((* global) *) # probably not what you want
'uppercase-char-p
=> (- uppercase (- char p)) # probably not what you want
'(char> a "p")
=> ((> char a) "p") # probably not what you want
To create multi-word symbols, use underscores or camelCase. I'm trying out
capitalizing globals.
While regular symbols can't be used in infix mode, infix ops can be used like
regular symbols.
(+ 4 2)
=> 6
To use an infix op in a higher-level function, wrap it in parens:
(map ++ '(1 2 3))
Error: can't increment map
(map (++) '(1 2 3)) # hello haskell!
=> (2 3 4)
In addition to the usual arithmetic, Wart defines a few standard infix ops:
a.b # => (a b) unless a and b are all digits; 2.4 is a number
(a -> f) # => (f a)
f:g # => (compose f g)
~f # => (complement f)
Prefix can also be combined with infix, and has highest-precedence because of
the default left-associativity:
~f.b # => ((complement f) b)
Infix operators can coexist with paren-insertion:
a +
b+c * d
=>
(+ a (* (+ b c) d))
However, if your infix expressions need multiple lines, ask if they're worth
doing in infix. The following is actually harder to read in infix:
(* some_function.some_argument
(+ some_other_function.some_other_argument
some_random_constant))
I prefer to use infix only for simple expressions with short variable names.