A scripting language that takes the good parts of Perl (text processing, regex, pragmatism) and leaves behind the bad (line noise, TMTOWTDI, cryptic sigils).
Based on the interpreter from Thorsten Ball's "Writing an Interpreter in Go", but extended significantly.
go build -o pearl .# start the REPL
./pearl
# run a file
./pearl examples/hello.pearl
./pearl -f examples/text.pearl
# evaluate an expression
./pearl -e 'print("hello")'
# check syntax without running
./pearl -check -f myfile.pearllet name = "alice"
let age = 30
let pi = 3.14159
let active = true
let nothing = null
let x = 10
print("x is {x}")
print("x squared is {x * x}")
let fruits = ["apple", "banana", "cherry"]
let person = {"name": "bob", "age": 25}
print(fruits[0]) # apple
print(person["name"]) # bob
if x > 10 {
print("big")
} else {
print("small")
}
for item in items {
print(item)
}
for i in 0..10 {
print(i)
}
while x > 0 {
x = x - 1
}
fn greet(name, loud = false) {
if loud {
print("HELLO {upper(name)}!")
} else {
print("hello {name}")
}
}
greet("world")
greet("world", loud = true)
let text = "email me at bob@test.com"
# match check
if text ~ /\w+@\w+\.\w+/ {
print("found email!")
}
# extract groups
let m = match(text, /(\w+)@(\w+)\.(\w+)/)
print(m[1]) # bob
# replace
let clean = replace(text, /\w+@\w+\.\w+/, "[REDACTED]")
let result = " HELLO WORLD "
|> trim()
|> lower()
|> split(" ")
|> join("-")
# result is "hello-world"
let nums = [1, 2, 3, 4, 5]
let doubled = map(nums, fn(x) { x * 2 })
let evens = filter(nums, fn(x) { x % 2 == 0 })
let sum = reduce(nums, fn(a, b) { a + b }, 0)
len(s)- lengthupper(s),lower(s)- case conversiontrim(s),ltrim(s),rtrim(s)- whitespace removalsplit(s, delim)- split into arrayjoin(arr, delim)- join array into stringsubstr(s, start, len)- substringcontains(s, needle)- check if containsstarts_with(s, prefix),ends_with(s, suffix)replace(s, old, new),replace_all(s, old, new)repeat(s, n)- repeat n timesreverse(s)- reverse stringlines(s)- split by newlineschars(s)- split into charactersfind(s, needle)- find index
match(s, regex)- returns array of matches or nullmatch_all(s, regex)- returns all matchesregex(pattern)- compile a regex from string
len(arr)- lengthpush(arr, item),pop(arr)- end operationsshift(arr),unshift(arr, item)- start operationsslice(arr, start, end)- sub-arraysort(arr)- sort (returns new array)reverse(arr)- reverseunique(arr)- remove duplicatesflatten(arr)- flatten nested arrayscontains(arr, item)- check membershipfind(arr, item)- find index
map(arr, fn)- transform each elementfilter(arr, fn)- keep matching elementsreduce(arr, fn, init)- reduce to single value
keys(map)- get all keysvalues(map)- get all values
int(x),float(x),str(x)type(x)- get type as string
print(...)- outputrange(n)orrange(start, end)- create range
It's like Perl, but:
- No
$@%sigils - No
$_magic variable - No TMTOWTDI (there's more than one way to do it)
- Readable by default
- Good error messages
- One obvious way to do things
The gem, not the mess.