Skip to content

Commit b0bc856

Browse files
authored
Merge pull request #173 from phel-lang/improve-docs
Add collapsible sections for PHP/Clojure comparisons
2 parents 6c4d2c5 + 6b9242d commit b0bc856

18 files changed

+1567
-90
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ node_modules/
99
npm-debug.log*
1010
yarn-debug.log*
1111
yarn-error.log*
12+
phel-error.log
1213

1314
.DS_Store
1415
Thumbs.db

content/documentation/arithmetic.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,24 @@ All arithmetic operators are entered in prefix notation.
1212
(+ 1 (* 2 2) (/ 10 5) 3 4 (- 5 6)) # Evaluates to 13
1313
```
1414

15+
{% php_note() %}
16+
Phel uses prefix notation (operator comes first) instead of PHP's infix notation:
17+
18+
```php
19+
// PHP - infix notation
20+
1 + (2 * 2) + (10 / 5) + 3 + 4 + (5 - 6);
21+
22+
// Phel - prefix notation
23+
(+ 1 (* 2 2) (/ 10 5) 3 4 (- 5 6))
24+
```
25+
26+
This allows operators to accept any number of arguments and eliminates operator precedence concerns.
27+
{% end %}
28+
29+
{% clojure_note() %}
30+
Arithmetic works exactly like Clojure—prefix notation with variadic support for most operators.
31+
{% end %}
32+
1533
Some operators support zero, one or multiple arguments.
1634

1735
```phel
@@ -34,6 +52,27 @@ Some operators support zero, one or multiple arguments.
3452
(/ 24 4 2) #Evaluates to 3
3553
```
3654

55+
{% php_note() %}
56+
Phel's variadic operators are more flexible than PHP's:
57+
58+
```php
59+
// PHP - requires at least two operands
60+
1 + 2 + 3 + 4 + 5;
61+
// Can't do this: +(); <- syntax error
62+
63+
// Phel - supports 0, 1, or many operands
64+
(+) # 0 (identity)
65+
(+ 1) # 1 (identity)
66+
(+ 1 2 3 4 5) # 15 (sum of all)
67+
```
68+
69+
**Useful patterns:**
70+
- `(+)` returns the additive identity (0)
71+
- `(*)` returns the multiplicative identity (1)
72+
- `(- x)` negates a number
73+
- `(/ x)` computes the reciprocal
74+
{% end %}
75+
3776
Further numeric operations are `%` to compute the remainder of two values and `**` to raise a number to the power. All numeric operations can be found in the API documentation.
3877

3978
Some numeric operations can result in an undefined or unrepresentable value. These values are called _Not a Number_ (NaN). Phel represents these values by the constant `NAN`. You can check if a result is NaN by using the `nan?` function.
@@ -44,6 +83,24 @@ Some numeric operations can result in an undefined or unrepresentable value. The
4483
(nan? NAN) # true
4584
```
4685

86+
{% php_note() %}
87+
NaN handling is similar to PHP:
88+
89+
```php
90+
// PHP
91+
is_nan(1); // false
92+
is_nan(log(-1)); // true
93+
is_nan(NAN); // true
94+
95+
// Phel
96+
(nan? 1) # false
97+
(nan? (php/log -1)) # true
98+
(nan? NAN) # true
99+
```
100+
101+
The `%` operator for remainder and `**` for exponentiation work like PHP's `%` and `**` operators.
102+
{% end %}
103+
47104
## Bitwise Operators
48105
49106
Phel allows the evaluation and manipulation of specific bits within an integer.
@@ -80,3 +137,31 @@ Phel allows the evaluation and manipulation of specific bits within an integer.
80137
(bit-test 0b1011 0) # Evaluates to true
81138
(bit-test 0b1011 2) # Evaluates to false
82139
```
140+
141+
{% php_note() %}
142+
Phel provides named functions for bitwise operations instead of PHP's operators:
143+
144+
```php
145+
// PHP bitwise operators
146+
0b1100 & 0b1001; // AND
147+
0b1100 | 0b1001; // OR
148+
0b1100 ^ 0b1001; // XOR
149+
~0b0111; // NOT
150+
0b1101 << 1; // Left shift
151+
0b1101 >> 1; // Right shift
152+
153+
// Phel named functions
154+
(bit-and 0b1100 0b1001)
155+
(bit-or 0b1100 0b1001)
156+
(bit-xor 0b1100 0b1001)
157+
(bit-not 0b0111)
158+
(bit-shift-left 0b1101 1)
159+
(bit-shift-right 0b1101 1)
160+
```
161+
162+
Phel also provides additional bit manipulation functions not available in PHP: `bit-set`, `bit-clear`, `bit-flip`, and `bit-test`.
163+
{% end %}
164+
165+
{% clojure_note() %}
166+
Bitwise operators work exactly like Clojure's—same function names and behavior for bit manipulation.
167+
{% end %}

content/documentation/basic-types.md

Lines changed: 106 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,38 @@ weight = 2
55

66
## Nil, True, False
77

8-
Nil, true and false are literal constants. In Phel, `nil` is the same as `null` in PHP. Phel's `true` and `false` are the same as PHP's `true` and `false`.
8+
Nil, true and false are literal constants.
99

1010
```phel
1111
nil
1212
true
1313
false
1414
```
1515

16+
In Phel, only `false` and `nil` are falsy. Everything else is truthy—including `0`, `""`, and `[]`.
17+
18+
```phel
19+
# Truthiness examples
20+
(if nil "yes" "no") # => "no" (nil is falsy)
21+
(if false "yes" "no") # => "no" (false is falsy)
22+
(if 0 "yes" "no") # => "yes" (0 is truthy!)
23+
(if "" "yes" "no") # => "yes" (empty string is truthy!)
24+
(if [] "yes" "no") # => "yes" (empty vector is truthy!)
25+
```
26+
27+
{% php_note() %}
28+
In PHP, `nil` is the same as `null`, and `true`/`false` are the same. However, truthiness works differently:
29+
30+
**PHP**: `0`, `""`, `[]`, `null`, and `false` are all falsy
31+
**Phel**: Only `false` and `nil` are falsy
32+
33+
This means `if (0)` in PHP is false, but `(if 0 ...)` in Phel is true!
34+
{% end %}
35+
36+
{% clojure_note() %}
37+
Truthiness is the same as Clojure—only `false` and `nil` are falsy.
38+
{% end %}
39+
1640
## Symbol
1741

1842
Symbols are used to name functions and variables in Phel.
@@ -26,7 +50,7 @@ my-module/my-function
2650

2751
## Keywords
2852

29-
A keyword is like a symbol that begins with a colon character. However, it is used as a constant rather than a name for something.
53+
A keyword is like a symbol that begins with a colon character. However, it is used as a constant rather than a name for something. Keywords are interned and fast for equality checks.
3054

3155
```phel
3256
:keyword
@@ -36,6 +60,35 @@ A keyword is like a symbol that begins with a colon character. However, it is us
3660
::
3761
```
3862

63+
Keywords are commonly used as map keys:
64+
65+
```phel
66+
# Map with keyword keys
67+
{:name "Alice" :email "[email protected]"}
68+
69+
# Accessing map values with keywords
70+
(get {:name "Alice" :age 30} :name) # => "Alice"
71+
(:name {:name "Alice" :age 30}) # => "Alice" (keywords are functions!)
72+
```
73+
74+
{% php_note() %}
75+
Keywords are like string constants, but more efficient for map keys. Use keywords instead of strings for map keys:
76+
77+
```phel
78+
# Less idiomatic:
79+
{"name" "Alice" "age" 30}
80+
81+
# Idiomatic:
82+
{:name "Alice" :age 30}
83+
```
84+
85+
Keywords are interned (only one instance exists in memory), making equality checks very fast.
86+
{% end %}
87+
88+
{% clojure_note() %}
89+
Keywords work exactly like in Clojure—they're interned, fast for equality checks, and self-evaluate.
90+
{% end %}
91+
3992
## Numbers
4093

4194
Phel supports integers and floating-point numbers. Both use the underlying PHP implementation. Integers can be specified in decimal (base 10), hexadecimal (base 16), octal (base 8) and binary (base 2) notations. Binary, octal and hexadecimal formats may contain underscores (`_`) between digits for better readability.
@@ -69,9 +122,7 @@ Phel supports integers and floating-point numbers. Both use the underlying PHP i
69122

70123
## Strings
71124

72-
Strings are surrounded by double quotes. They almost work the same as PHP double-quoted strings. One difference is that the dollar sign (`$`) must not be escaped. Internally, Phel strings are represented by PHP strings. Therefore, every PHP string function can be used to operate on the string.
73-
74-
Strings can be written over multiple lines. The line break character is then ignored by the reader.
125+
Strings are surrounded by double quotes. The dollar sign (`$`) does not need to be escaped.
75126

76127
```phel
77128
"hello world"
@@ -89,9 +140,28 @@ string."
89140
90141
"Hexadecimal notation is supported: \x41"
91142
92-
"Unicodes can be encoded as in PHP: \u{1000}"
143+
"Unicodes can be encoded: \u{1000}"
144+
```
145+
146+
String concatenation and conversion using `str`:
147+
148+
```phel
149+
(str "Hello" " " "World") # => "Hello World"
150+
(str "The answer is " 42) # => "The answer is 42"
151+
```
152+
153+
{% php_note() %}
154+
Phel strings are PHP strings internally, so you can use all PHP string functions:
155+
156+
```phel
157+
(php/strlen "hello") # => 5
158+
(php/strtoupper "hello") # => "HELLO"
159+
(php/str_replace "o" "0" "hello") # => "hell0"
93160
```
94161

162+
Strings work almost the same as PHP double-quoted strings, with one difference: the dollar sign (`$`) doesn't need escaping.
163+
{% end %}
164+
95165
## Lists
96166

97167
A list is a sequence of whitespace-separated values surrounded by parentheses.
@@ -118,17 +188,42 @@ A vector in Phel is an indexed data structure. In contrast to PHP arrays, Phel v
118188

119189
## Maps
120190

121-
A map is a sequence of whitespace-separated key/value pairs surrounded by curly braces, wherein the key and value of each key/value pair are separated by whitespace. There must be an even number of items between curly braces or the parser will signal a parse error. The sequence is defined as key1, value1, key2, value2, etc.
191+
A map is a sequence of whitespace-separated key/value pairs surrounded by curly braces. The sequence is defined as key1, value1, key2, value2, etc. There must be an even number of items.
122192

123193
```phel
124194
{} # same as (hash-map)
125195
{:key1 "value1" :key2 "value2"}
126-
{'(1 2 3) '(4 5 6)}
127-
{[] []}
128-
{1 2 3 4 5 6}
196+
197+
# Any type can be a key
198+
{'(1 2 3) '(4 5 6)} # Lists as keys
199+
{[] []} # Vectors as keys
200+
{1 2 3 4 5 6} # Numbers as keys
201+
202+
# Common pattern: keywords as keys
203+
{:name "Alice" :age 30 :email "[email protected]"}
204+
```
205+
206+
{% php_note() %}
207+
Unlike PHP associative arrays, Phel maps:
208+
- Can have **any type** as keys (not just strings/integers): vectors, lists, or even other maps
209+
- Are **immutable**: operations return new maps without modifying the original
210+
- Are **not** PHP arrays internally—they're their own data structure
211+
212+
```phel
213+
# PHP:
214+
$map = ['name' => 'Alice'];
215+
$map['name'] = 'Bob'; // Mutates in place
216+
217+
# Phel:
218+
(def map {:name "Alice"})
219+
(def new-map (assoc map :name "Bob")) # Returns new map
220+
# map is still {:name "Alice"}
129221
```
222+
{% end %}
130223

131-
In contrast to PHP associative arrays, Phel maps can have any types of keys.
224+
{% clojure_note() %}
225+
Maps work exactly like Clojure maps, including support for any hashable type as keys.
226+
{% end %}
132227

133228
## Sets
134229

0 commit comments

Comments
 (0)