API

Tip: This documentation is also available in JSON format at /api.json.


base64#

base64/decode#

(decode s & [strict?])

Decodes a Base64 string. Optional strict? flag validates characters.

Example:

(decode "SGVsbG8=") ; => "Hello"

base64/decode-url#

(decode-url s & [strict?])

Decodes a URL-safe Base64 string. Adds padding automatically.

Example:

(decode-url "SGVsbG8") ; => "Hello"

base64/encode#

(encode s)

Encodes a string to Base64.

Example:

(encode "Hello") ; => "SGVsbG8="

base64/encode-url#

(encode-url s)

Encodes a string to URL-safe Base64 (no padding).

Example:

(encode-url "Hello") ; => "SGVsbG8"

core#

%#

(% dividend divisor)

Return the remainder of dividend / divisor.

*#

(* & xs)

Returns the product of all elements in xs. All elements in xs must be numbers. If xs is empty, return 1.

**#

(** a x)

Return a to the power of x.

*assert*#

Controls whether assert expands to a runtime check. When logical false at macroexpansion time, assert expands to nil and performs no runtime check, matching Clojure's compile-time *assert* semantics. Defaults to true. To disable globally, set the core binding before compilation via PHP: \Phel::addDefinition("phel\\core", "*assert*", false).

*build-mode*#

Set to true when a file is being built/compiled, false otherwise.

*file*#

*file*

Returns the path of the current source file.

Example:

(println *file*) ; => "/path/to/current/file.phel"

*hierarchy*#

Global hierarchy for keyword/symbol taxonomies.

*ns*#

*ns*

Returns the namespace in the current scope.

Example:

(println *ns*) ; => "my-app\core"

*program*#

The script path or namespace being executed.

+#

(+ & xs)

Returns the sum of all elements in xs. All elements xs must be numbers. If xs is empty, return 0.

-#

(- & xs)

Returns the difference of all elements in xs. If xs is empty, return 0. If xs has one element, return the negative value of that element.

->#

(-> x & forms)

Threads the expr through the forms. Inserts x as the second item in the first form, making a list of it if it is not a list already. If there are more forms, insert the first form as the second item in the second form, etc.

->>#

(->> x & forms)

Threads the expr through the forms. Inserts x as the last item in the first form, making a list of it if it is not a list already. If there are more forms, insert the first form as the last item in the second form, etc.

/#

(/ & xs)

Returns the nominator divided by all the denominators. If xs is empty, returns 1. If xs has one value, returns the reciprocal of x.

<#

(< a & more)

Checks if each argument is strictly less than the following argument.

Example:

(< 1 2 3 4) ; => true

<=#

(<= a & more)

Checks if each argument is less than or equal to the following argument. Returns a boolean.

<=>#

(<=> a b)

Alias for the spaceship PHP operator in ascending order. Returns an int.

=#

(= a & more)

Checks if all values are equal (value equality, not identity).

Example:

(= [1 2 3] [1 2 3]) ; => true

>#

(> a & more)

Checks if each argument is strictly greater than the following argument.

Example:

(> 4 3 2 1) ; => true

>=#

(>= a & more)

Checks if each argument is greater than or equal to the following argument. Returns a boolean.

>=<#

(>=< a b)

Alias for the spaceship PHP operator in descending order. Returns an int.

NAN#

Constant for Not a Number (NAN) values.

NaN?#

(NaN? x)

Checks if x is not a number. Alias for nan?, matching Clojure's NaN?.

abs#

(abs x)

Returns the absolute value of x. Throws InvalidArgumentException if x is not a number, matching Clojure rather than PHP's permissive abs(null) => 0 / abs("abc") coercions.

Example:

(abs -5) ; => 5

aclone#

(aclone arr)

Returns a shallow copy of a PHP array. The returned array is a distinct value — mutating the copy via php/aset does not affect the original, and vice versa. Matches Clojure's aclone for .cljc interop; raises InvalidArgumentException on non-array inputs since Phel's persistent collections are already immutable and don't need cloning.

Example:

(aclone (object-array 3)) ; => a fresh PHP array [nil, nil, nil]

add-watch#

(add-watch variable key f)

Adds a watch function to a variable. The watch fn is called when the variable changes with four arguments: key, ref, old-value, new-value.

Example:

(add-watch my-var :logger (fn [key ref old new] (println old "->" new)))

all?#

(all? pred coll)

Returns true if predicate is true for every element in collection, false otherwise.

Example:

(all? even? [2 4 6 8]) ; => true

ancestors#

(ancestors tag)

Returns the set of all transitive ancestors of tag, or nil.

and#

(and & args)

Evaluates expressions left to right, returning the first falsy value or the last value.

Example:

(and true 1 "hello") ; => "hello"

apply#

(apply f expr*)

Calls the function with the given arguments. The last argument must be a list of values, which are passed as separate arguments, rather than a single list. Apply returns the result of the calling function.

Example:

(apply + [1 2 3]) ; => 6

argv#

Vector of user arguments passed to the script (excludes program name). Use program to get the script path or namespace.

array-map#

Constructs a map from the given key/value pairs. If any keys are equal, later values replace earlier ones, as if by repeated assoc. Phel has no distinct array-map type, so the result is the same persistent map as hash-maparray-map exists for .cljc interop with Clojure sources.

Example:

(array-map :a 1 :b 2) ; => {:a 1 :b 2}

as->#

(as-> expr name & forms)

Binds name to expr, evaluates the first form in the lexical context of that binding, then binds name to that result, repeating for each successive form, returning the result of the last form.

assert#

(assert expr & [message])

Throws an exception if expr is falsy. Optional message string. Used for precondition checking in application code. When *assert* is logical false at macroexpansion time, assert expands to nil and performs no runtime check.

assoc#

(assoc ds key value & more)

Associates one or more key-value pairs with a collection. Additional key-value pairs beyond the first are applied in order. Throws if an odd number of extra arguments is provided.

Example:

(assoc {:a 1} :b 2) ; => {:a 1 :b 2}
(assoc {:a 1} :b 2 :c 3) ; => {:a 1 :b 2 :c 3}

assoc!#

(assoc! tcoll key value & more)

Associates one or more key-value pairs with a transient collection, mutating it in place. Works on transient hash-maps and transient vectors. Variadic forms apply each key-value pair in order. Raises InvalidArgumentException when tcoll is not a supported transient collection or when an odd number of extra arguments is provided. Matches Clojure's assoc! semantics.

Example:

(persistent! (assoc! (transient {}) :a 1 :b 2)) ; => {:a 1 :b 2}

assoc-in#

(assoc-in ds [k & ks] v)

Associates a value in a nested data structure at the given path.

Creates intermediate maps if they don't exist.

Example:

(assoc-in {:a {:b 1}} [:a :c] 2) ; => {:a {:b 1 :c 2}}

associative?#

(associative? x)

Returns true if x is an associative data structure, false otherwise.

Associative data structures include vectors, hash maps, structs, and PHP arrays (both indexed and associative), matching Clojure's Associative protocol.

Example:

(associative? [1 2 3]) ; => true

atom#

(atom value)

Creates a new atom with the given value.

Atoms provide a way to manage mutable state. Use reset! to set a new value and swap! to update based on the current value.

Example:

(def counter (atom 0))

atom?#

(atom? x)

Returns true if the given value is an atom.

binding#

(binding bindings & body)

Temporary redefines definitions while executing the body. The value will be reset after the body was executed.

bit-and#

(bit-and x y & args)

Bitwise and.

bit-clear#

(bit-clear x n)

Clear bit an index n.

bit-flip#

(bit-flip x n)

Flip bit at index n.

bit-not#

(bit-not x)

Bitwise complement.

bit-or#

(bit-or x y & args)

Bitwise or.

bit-set#

(bit-set x n)

Set bit an index n.

bit-shift-left#

(bit-shift-left x n)

Bitwise shift left.

bit-shift-right#

(bit-shift-right x n)

Bitwise shift right.

bit-test#

(bit-test x n)

Test bit at index n.

bit-xor#

(bit-xor x y & args)

Bitwise xor.

boolean#

(boolean x)

Coerces x to a boolean. Returns false if x is nil or false, true otherwise.

Example:

(boolean nil) ; => false

boolean?#

(boolean? x)

Returns true if x is a boolean, false otherwise.

butlast#

(butlast coll)

Returns all but the last item in coll.

Example:

(butlast [1 2 3 4]) ; => [1 2 3]

byte#

(byte x)

Coerces x to a signed 8-bit integer in the range -128..127. Decimal values are truncated toward zero (as in Clojure on the JVM). Values outside the range or non-numeric inputs raise InvalidArgumentException. Phel has no dedicated byte type, so the result is a plain PHP int — byte exists for .cljc interop with Clojure sources.

Example:

(byte 127) ; => 127
(byte 1.9) ; => 1
(byte -128) ; => -128

case#

(case e & pairs)

Evaluates expression and matches it against constant test values, returning the associated result.

Example:

(case x 1 "one" 2 "two" "other") ; => "one" (when x is 1)

cat#

(cat rf)

A transducer that concatenates the contents of each input into the reduction.

catch#

(catch exception-type exception-name expr*)

Handle exceptions thrown in a try block by matching on the provided exception type. The caught exception is bound to exception-name while evaluating the expressions.

Example:

(try (throw (php/new \Exception "error")) (catch \Exception e (php/-> e (getMessage))))

char#

(char x)

Coerces x to a single-character string representing the given Unicode code point. Accepts a non-negative integer (the code point, converted via mb_chr) or a single-character string, which is returned as-is. Phel has no dedicated char type — character literals such as \A are already single-character strings — so the result is always a plain string. Matches Clojure's char for .cljc interop; raises InvalidArgumentException on negative ints, non-single-character strings, and all other inputs.

Example:

(char 65) ; => "A"
(char 32) ; => " "
(char \A) ; => "A"

char?#

(char? x)

Returns true if x is a single-character string, false otherwise. Phel has no dedicated character type — character literals such as \A are already single-character strings — so char? is true for any string of length 1 (UTF-8 counted). Matches ClojureScript's char? for .cljc interop; Clojure/JVM's char? tests for the distinct Character type, which does not exist here.

Example:

(char? \A) ; => true
(char? "a") ; => true
(char? "ab") ; => false

coerce-in#

(coerce-in v min max)

Returns v if it is in the range, or min if v is less than min, or max if v is greater than max.

coll?#

(coll? x)

Returns true if x is a persistent collection — vector, list, hash-map (including sorted-map), struct, set (including sorted-set), or lazy-seq — and false otherwise. Strings, numbers, nil, booleans, keywords, symbols, and plain PHP arrays are not considered collections, matching Clojure's IPersistentCollection membership.

Example:

(coll? [1 2 3]) ; => true
(coll? "abc") ; => false

comment#

(comment &)

Ignores the body of the comment.

comp#

(comp & fs)

Takes a list of functions and returns a function that is the composition of those functions.

compact#

(compact coll & values)

Returns a lazy sequence with specified values removed from coll. If no values are specified, removes nil values by default.

Example:

(compact [1 nil 2 nil 3]) ; => (1 2 3)

compare#

(compare x y)

Wrapper for PHP's spaceship operator (php/<=>). Returns an integer less than, equal to, or greater than zero when x is less than, equal to, or greater than y, respectively.

compile#

(compile form)

Returns the compiled PHP code string for the given form.

complement#

(complement f)

Returns a function that takes the same arguments as f and returns the opposite truth value.

completing#

(completing f & args)

Takes a reducing function f of 2 args and returns a fn suitable for transduce by adding a 1-arity (completion) that calls cf (default: identity).

concat#

(concat & colls)

Concatenates multiple collections into a lazy sequence.

Example:

(concat [1 2] [3 4]) ; => (1 2 3 4)

cond#

(cond & pairs)

Evaluates test/expression pairs, returning the first matching expression.

Example:

(cond (< x 0) "negative" (> x 0) "positive" "zero") ; => "negative", "positive", or "zero" depending on x

cond->#

(cond-> expr & clauses)

Takes an expression and a set of test/form pairs. Threads expr (via ->) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond-> threading does not short-circuit after the first true test expression.

Example:

(cond-> 1 true inc false (* 42) true (* 3)) ; => 6

cond->>#

(cond->> expr & clauses)

Takes an expression and a set of test/form pairs. Threads expr (via ->>) through each form for which the corresponding test expression is true. Note that, unlike cond branching, cond->> threading does not short-circuit after the first true test expression.

Example:

(cond->> [1 2 3] true (map inc) false (filter odd?)) ; => [2 3 4]

condp#

(condp pred expr & clauses)

Takes a binary predicate, an expression, and a set of clauses. Each clause takes the form of either: test-expr result-expr test-expr :>> result-fn For each clause, (pred test-expr expr) is evaluated. If it returns logical true, the clause is a match. If a binary clause is a match, result-expr is returned. If a ternary clause with :>> is a match, the result of (pred test-expr expr) is passed to result-fn and the return value is the result. If no clause matches, the default value is returned (if provided), otherwise an exception is thrown.

Example:

(condp = 1 1 "one" 2 "two" "other") ; => "one"

conj#

(conj)
(conj coll)
(conj coll value)
(conj coll value & more)

Returns a new collection with values added. Appends to vectors/sets, prepends to lists.

Example:

(conj [1 2] 3) ; => [1 2 3]

conj!#

(conj!)
(conj! tcoll)
(conj! tcoll value)
(conj! tcoll value & more)

Adds value to the transient collection tcoll, mutating it in place, and returns tcoll. The 'addition' may happen at different 'places' depending on the concrete transient type: transient vectors append at the tail, transient hash-sets add the element (no-op if already present), and transient hash-maps treat value as a [key value] pair (or an associative collection of entries). With zero arguments returns a new empty transient vector. With one argument returns tcoll unchanged. Variadic forms reduce conj! over the remaining values. Raises InvalidArgumentException when tcoll is not a transient collection. Matches Clojure's conj! semantics.

Example:

(persistent (conj! (transient [1 2]) 3)) ; => [1 2 3]

cons#

(cons x coll)

Prepends an element to the beginning of a collection.

Example:

(cons 0 [1 2 3]) ; => [0 1 2 3]

constantly#

(constantly x)

Returns a function that always returns x and ignores any passed arguments.

contains-value?#

(contains-value? coll val)

Returns true if the value is present in the given collection, otherwise returns false.

Example:

(contains-value? {:a 1 :b 2} 2) ; => true

contains?#

(contains? coll key)

Returns true if key is present in collection (checks keys/indices, not values).

Example:

(contains? [10 20 30] 1) ; => true

count#

(count coll)

Counts the number of elements in a sequence. Can be used on everything that implements the PHP Countable interface.

Works with lists, vectors, hash-maps, sets, strings, and PHP arrays. Returns 0 for nil.

Example:

(count [1 2 3]) ; => 3

counted?#

(counted? coll)

Returns true if coll can report its length in constant time — persistent vectors, lists, hash-maps (including sorted-map), structs, and sets (including sorted-set). Returns false for lazy sequences (counting them requires realizing the whole sequence), strings, numbers, nil, and every other non-counted type. Matches Clojure's counted? semantics, which mirror the clojure.lang.Counted marker interface.

Example:

(counted? [1 2 3]) ; => true
(counted? (range)) ; => false

csv-seq#

(csv-seq filename)
(csv-seq filename options)

Returns a lazy sequence of rows from a CSV file.

Example:

(take 10 (csv-seq "data.csv")) ; => [["col1" "col2"] ["val1" "val2"] ...]

cycle#

(cycle coll)

Returns an infinite lazy sequence that cycles through the elements of collection.

Example:

(take 7 (cycle [1 2 3])) ; => (1 2 3 1 2 3 1)

dec#

(dec x)

Decrements x by one.

declare#

Declare a global symbol before it is defined.

dedupe#

(dedupe & args)

Returns a lazy sequence with consecutive duplicate values removed in coll. When called with no args, returns a transducer.

Example:

(dedupe [1 1 2 2 2 3 1 1]) ; => (1 2 3 1)

deep-merge#

(deep-merge & args)

Recursively merges data structures.

def#

(def name meta? value)

This special form binds a value to a global symbol.

Example:

(def my-value 42)

def-#

Define a private value that will not be exported.

defexception#

(defexception name)

Define a new exception.

defexception*#

(defexception my-ex)

Define a new exception.

Example:

(defexception my-error)

definterface#

(definterface name & fns)

An interface in Phel defines an abstract set of functions. It is directly mapped to a PHP interface. An interface can be defined by using the definterface macro.

Example:

(definterface name & fns)

definterface*#

(definterface name & fns)

An interface in Phel defines an abstract set of functions. It is directly mapped to a PHP interface. An interface can be defined by using the definterface macro.

Example:

(definterface Greeter (greet [name]))

defmacro#

Define a macro.

defmacro-#

(defmacro- name & fdecl)

Define a private macro that will not be exported.

defmethod#

(defmethod multi-name dispatch-val & fn-tail)

Registers a method implementation for a multimethod.

multi-name is the name of the multimethod defined by defmulti. When extending a multimethod from a different namespace, fully qualify the multi-name (e.g. phel\test/assert-expr) so the methods table is resolved in the multimethod's home namespace. dispatch-val is the value that triggers this method. args and body define the function implementation.

Example:

(defmethod area :circle [{:radius r}] (* 3.14159 r r))

defmulti#

(defmulti name dispatch-fn)

Defines a multimethod. dispatch-fn is called on the arguments to produce a dispatch value, which is then used to select the appropriate method registered via defmethod.

If no method matches the dispatch value, the :default method is used (if defined), otherwise an error is thrown.

Example:

(defmulti area :shape)

defn#

Define a new global function.

defn-#

(defn- name & fdecl)

Define a private function that will not be exported.

defprotocol#

(defprotocol protocol-name & method-specs)

Defines a protocol with the given method signatures. Each method signature is a list of (method-name [args]).

Creates a dispatching function for each method that dispatches on the type of the first argument. Use extend-type to add implementations.

A :default type can be registered via extend-type as a fallback when no specific type implementation is found.

Example:

(defprotocol Stringable (to-string [this]))

defrecord#

(defrecord name fields & impls)

Defines a record type with the given fields, matching Clojure's defrecord.

Expands to a defstruct plus Clojure-style factory functions:

  • Name — positional constructor (from defstruct)
  • Name? — type predicate (from defstruct)
  • ->Name — positional factory, identical to Name
  • map->Name — map factory that takes {:field value ...}

An optional tail of protocol/method forms is spliced into an extend-type call, so inline protocol implementations work exactly like Clojure's defrecord body. Only Phel protocols are supported in the inline tail; PHP interface implementations remain on defstruct.

Example:

(defrecord Point [x y] Drawable (draw [this canvas] ...))

defstruct#

(defstruct name keys & implementations)

A Struct is a special kind of Map. It only supports a predefined number of keys and is associated to a global name. The Struct not only defines itself but also a predicate function.

defstruct*#

(defstruct my-struct [a b c])

A Struct is a special kind of Map. It only supports a predefined number of keys and is associated to a global name. The Struct not only defines itself but also a predicate function.

Example:

(defstruct point [x y])

deftype#

(deftype name fields & impls)

Defines a type with the given fields, matching Clojure's deftype syntax.

Expands to a defstruct plus a Clojure-style positional factory:

  • Name — positional constructor (from defstruct)
  • Name? — type predicate (from defstruct)
  • ->Name — positional factory, identical to Name

Unlike defrecord, no map->Name factory is generated.

An optional tail of protocol/method forms is spliced into an extend-type call. Only Phel protocols are supported in the inline tail.

Deviation from Clojure: Phel's deftype shares the map-backed defstruct infrastructure, so instances remain map-like (keys are accessible via get). Clojure's deftype produces a non-map type; if you need that semantic, use native PHP interop.

Example:

(deftype PointT [x y] Drawable (draw [this canvas] ...))

delay#

(delay & body)

Takes a body of expressions and yields a Delay object that will invoke the body only the first time it is forced (via force or deref/@), caching the result.

Example:

(def d (delay (println "computing") 42))

delay?#

(delay? x)

Returns true if x is a Delay.

deref#

(deref variable & args)

Returns the current value inside the variable.

With three arguments, and when variable is a PhelFuture, blocks for at most timeout-ms milliseconds waiting for the future to resolve. If the future has not completed within the timeout, returns timeout-val. The 3-arg form is only supported on PhelFuture.

Example:

(deref (atom 42)) ; => 42

derive#

(derive child parent)

Establishes a parent/child relationship between child and parent keywords in the global hierarchy. Throws on cyclic derivation.

Example:

(derive :square :shape)

descendants#

(descendants tag)

Returns the set of all descendants of tag, or nil.

difference#

(difference set & sets)

Difference between multiple sets into a new one.

disj#

(disj set)
(disj set k)
(disj set k & ks)

Returns a new set that does not contain the given key(s). Works on hash-sets and sorted-sets. Removing a non-existent key is a no-op. Returns nil when called on nil.

Example:

(disj #{1 2 3} 2) ; => #{1 3}

disj!#

(disj! tcoll)
(disj! tcoll value)
(disj! tcoll value & more)

Removes one or more elements from a transient set, mutating it in place. Raises InvalidArgumentException when tcoll is not a transient set. Matches Clojure's disj! semantics.

Example:

(persistent! (disj! (transient #{1 2 3}) 2)) ; => #{1 3}

dissoc#

(dissoc ds key)

Dissociates key from the datastructure ds. Returns ds without key.

Example:

(dissoc {:a 1 :b 2} :b) ; => {:a 1}

dissoc!#

(dissoc! tcoll)
(dissoc! tcoll key)
(dissoc! tcoll key & ks)

Dissociates one or more keys from a transient map, mutating it in place. Raises InvalidArgumentException when tcoll is not a transient map. Matches Clojure's dissoc! semantics.

Example:

(persistent! (dissoc! (transient {:a 1 :b 2}) :a)) ; => {:b 2}

dissoc-in#

(dissoc-in ds [k & ks])

Dissociates a value from a nested data structure at the given path.

Example:

(dissoc-in {:a {:b 1 :c 2}} [:a :b]) ; => {:a {:c 2}}

distinct#

(distinct & args)

Returns a lazy sequence with duplicated values removed in coll. When called with no args, returns a transducer.

Example:

(distinct [1 2 1 3 2 4 3]) ; => (1 2 3 4)

do#

(do expr*)

Evaluates the expressions in order and returns the value of the last expression. If no expression is given, nil is returned.

Example:

(do (println "Hello") (+ 1 2)) ; prints "Hello", returns 3

doall#

(doall coll)

Forces realization of a lazy sequence and returns it as a vector.

Example:

(doall (map println [1 2 3])) ; => [nil nil nil]

dofor#

(dofor head & body)

Repeatedly executes body for side effects with bindings and modifiers as provided by for. Returns nil.

dorun#

(dorun coll)

Forces realization of a lazy sequence for side effects, returns nil.

Example:

(dorun (map println [1 2 3])) ; => nil

doseq#

(doseq seq-exprs & body)

Alias for dofor.

dotimes#

(dotimes [binding n] & body)

Evaluates body n times with binding bound to integers from 0 to n-1. Returns nil.

Example:

(dotimes [i 5] (println i))

doto#

(doto x & forms)

Evaluates x then calls all of the methods and functions with the value of x supplied at the front of the given arguments. The forms are evaluated in order. Returns x.

double#

(double x)

Coerces x to a double. In PHP there is no distinction between float and double; both map to the same native PHP float type. Alias for float.

Example:

(double 1) ; => 1.0

double?#

(double? x)

Returns true if x is a floating-point number, false otherwise. Alias for float?, matching Clojure's double? naming. Since Phel uses PHP floats (IEEE 754 doubles) there is no separate single-precision float type.

drop#

(drop n & args)

Drops the first n elements of coll. Returns a lazy sequence. When called with n only, returns a transducer.

Example:

(drop 2 [1 2 3 4 5]) ; => (3 4 5)

drop-last#

(drop-last coll)
(drop-last n coll)

Drops the last n elements of coll. n defaults to 1 when omitted, matching Clojure's (drop-last coll) single-arity form. Returns an empty vector when coll is nil, matching Clojure's (drop-last n nil)() and aligning with drop/take, which also return an empty result on nil.

Example:

(drop-last [1 2 3 4 5]) ; => [1 2 3 4]
(drop-last 2 [1 2 3 4 5]) ; => [1 2 3]
(drop-last 5 nil) ; => []

drop-while#

(drop-while pred & args)

Drops all elements at the front of coll where (pred x) is true. Returns a lazy sequence. When called with pred only, returns a transducer.

Example:

(drop-while #(< % 5) [1 2 3 4 5 6 3 2 1]) ; => (5 6 3 2 1)

empty?#

(empty? x)

Returns true if x would be 0, "" or empty collection, false otherwise.

eval#

(eval form)

Evaluates a form and return the evaluated results.

even?#

(even? x)

Checks if x is even.

every?#

(every? pred coll)

Returns true if predicate is true for every element in collection, false otherwise. Alias for all?.

Example:

(every? even? [2 4 6 8]) ; => true

ex-cause#

(ex-cause ex)

Returns the cause of an exception, or nil.

ex-data#

(ex-data ex)

Returns the data map from an ex-info exception, or nil if not an ExInfoException.

ex-info#

(ex-info msg data)
(ex-info msg data cause)

Creates an exception with a message and a data map. Optionally takes a cause.

Example:

(throw (ex-info "Invalid input" {:field :email}))

ex-message#

(ex-message ex)

Returns the message of an exception.

extend-protocol#

(extend-protocol protocol-name & specs)

Convenience macro that extends a single protocol to multiple types. Alternates type-specs and method implementations.

Equivalent to multiple extend-type calls.

Example:

(extend-protocol Describable
  :string (describe [s] s)
  :int (describe [n] (str n)))

extend-type#

(extend-type type-spec & specs)

Extends a type with protocol method implementations.

type-spec can be:

  • nil for the nil type
  • a type keyword matching what type returns: :string, :int, :float, :boolean, :keyword, :symbol, :vector, :list, :hash-map, :set, :var, :function, :php/array
  • a symbol for struct names (resolved in current namespace)
  • a string for explicit PHP class names (cross-namespace structs)

Note: :struct and :php/object cannot be used as type-specs because protocol dispatch resolves these to their specific PHP class names. Use a struct symbol or PHP class name string instead.

Example:

(extend-type :string Stringable (to-string [s] s))

extends?#

(extends? protocol type-key)

Returns true if the given type-key has implementations for all methods of the protocol. type-key should match what protocol-type-key returns.

Example:

(extends? Stringable :string)

extreme#

(extreme order args)

Returns the most extreme value in args based on the binary order function.

false?#

(false? x)

Checks if value is exactly false (not just falsy).

Example:

(false? nil) ; => false

ffirst#

(ffirst coll)

Same as (first (first coll)).

file-seq#

(file-seq path)

Returns a lazy sequence of all files and directories in a directory tree.

Example:

(filter #(php/str_ends_with % ".phel") (file-seq "src/")) ; => ["src/file1.phel" "src/file2.phel" ...]

filter#

(filter pred & args)

Returns a lazy sequence of elements where predicate returns true. When called with pred only, returns a transducer.

Example:

(filter even? [1 2 3 4 5 6]) ; => (2 4 6)

finally#

(finally expr*)

Evaluate expressions after the try body and all matching catches have completed. The finally block runs regardless of whether an exception was thrown.

Example:

(defn risky-operation [] (throw (php/new \Exception "Error!")))
(defn cleanup [] (println "Cleanup!"))
(try (risky-operation) (catch \Exception e nil) (finally (cleanup)))

find#

(find pred coll)

Returns the first item in coll where (pred item) evaluates to true.

Example:

(find #(> % 5) [1 2 3 6 7 8]) ; => 6

find-hierarchy-method#

(find-hierarchy-method methods dispatch-val)

Finds the best matching method for dispatch-val using the global hierarchy. Returns the method function or nil. Used internally by defmulti.

find-index#

(find-index pred coll)

Returns the index of the first item in coll where (pred item) evaluates to true.

Example:

(find-index #(> % 5) [1 2 3 6 7 8]) ; => 3

first#

Returns the first element of a sequence, or nil if empty.

Example:

(first [1 2 3]) ; => 1

flatten#

(flatten coll)

Flattens nested sequential structure into a lazy sequence of all leaf values.

Example:

(flatten [[1 2] [3 [4 5]] 6]) ; => (1 2 3 4 5 6)

float#

(float x)

Coerces x to a float. In PHP there is no distinction between float and double; both map to the same native PHP float type. Delegates to PHP's floatval, so non-numeric strings return 0.0 and nil returns 0.0.

Example:

(float 1) ; => 1.0

float?#

(float? x)

Returns true if x is float point number, false otherwise.

fn#

(fn [params*] expr*)

Defines a function. A function consists of a list of parameters and a list of expression. The value of the last expression is returned as the result of the function. All other expression are only evaluated for side effects. If no expression is given, the function returns nil.

Example:

(fn [x y] (+ x y))

fn?#

(fn? x)

Returns true if x is a function, false otherwise.

fnil#

(fnil f & defaults)

Returns a function that replaces nil arguments with the provided defaults before calling f. The number of defaults determines how many leading arguments are nil-checked.

Example:

(let [safe-inc (fnil inc 0)] (safe-inc nil)) ; => 1

for#

(for head & body)

List comprehension. The head of the loop is a vector that contains a sequence of bindings modifiers and options. A binding is a sequence of three values binding :verb expr. Where binding is a binding as in let and :verb is one of the following keywords:

  • :range loop over a range by using the range function.
  • :in loops over all values of a collection (including strings).
  • :keys loops over all keys/indexes of a collection.
  • :pairs loops over all key-value pairs of a collection.

After each loop binding, additional modifiers can be applied. Modifiers have the form :modifier argument. The following modifiers are supported:

  • :while breaks the loop if the expression is falsy.
  • :let defines additional bindings.
  • :when only evaluates the loop body if the condition is true.

Finally, additional options can be set:

  • :reduce [accumulator initial-value] Instead of returning a list, it reduces the values into accumulator. Initially accumulator is bound to initial-value.

Example:

(for [x :in [1 2 3]] (* x 2)) ; => [2 4 6]

force#

(force x)

If x is a Delay, forces it and returns its cached value. Otherwise returns x.

Example:

(force (delay 42)) ; => 42

foreach#

(foreach [value valueExpr] expr*)
(foreach [key value valueExpr] expr*)

The foreach special form can be used to iterate over all kind of PHP datastructures. The return value of foreach is always nil. The loop special form should be preferred of the foreach special form whenever possible.

Example:

(foreach [x [1 2 3]] (println x))

format#

(format fmt & xs)

Returns a formatted string. See PHP's sprintf for more information.

frequencies#

(frequencies coll)

Returns a map from distinct items in coll to the number of times they appear.

Works with vectors, lists, sets, and strings.

Example:

(frequencies [:a :b :a :c :b :a]) ; => {:a 3 :b 2 :c 1}

full-name#

(full-name x)

Return the namespace and name string of a string, keyword or symbol.

function?#

Deprecated: 0.32.0 — Use fn? instead

(function? x)

Returns true if x is a function, false otherwise.

gensym#

(gensym)

Generates a new unique symbol.

get#

(get ds k & [opt])

Gets the value at key in a collection. Returns default if not found.

Example:

(get {:a 1} :a) ; => 1

get-in#

(get-in ds ks & [opt])

Accesses a value in a nested data structure via a sequence of keys.

Returns opt (default nil) if the path doesn't exist.

Example:

(get-in {:a {:b {:c 42}}} [:a :b :c]) ; => 42

get-validator#

(get-validator variable)

Returns the validator function of a variable, or nil.

group-by#

(group-by f coll)

Returns a map of the elements of coll keyed by the result of f on each element.

Example:

(group-by count ["a" "bb" "c" "ddd" "ee"]) ; => {1 ["a" "c"] 2 ["bb" "ee"] 3 ["ddd"]}

hash-map#

(hash-map :a 1 :b 2) ; => {:a 1 :b 2}

Creates a new hash map. If no argument is provided, an empty hash map is created. The number of parameters must be even. Shortcut: {}

Example:

(hash-map :name "Alice" :age 30) ; => {:name "Alice" :age 30}

hash-map?#

Deprecated: 0.32.0 — Use map? instead

(hash-map? x)

Returns true if x is a hash map, false otherwise.

hash-set#

(hash-set & xs)

Creates a new Set from the given arguments. Shortcut: #{}

Example:

(hash-set 1 2 3) ; => #{1 2 3}

id#

Deprecated: 0.32.0 — Use identical? instead

(id a & more)

Checks if all values are identical. Same as a === b in PHP.

identical?#

(identical? a & more)

Checks if all values are identical. Same as a === b in PHP.

identity#

(identity x)

Returns its argument.

if#

(if test then else?)

A control flow structure. First evaluates test. If test evaluates to true, only the then form is evaluated and the result is returned. If test evaluates to false only the else form is evaluated and the result is returned. If no else form is given, nil will be returned.

The test evaluates to false if its value is false or equal to nil. Every other value evaluates to true. In sense of PHP this means (test != null && test !== false).

Example:

(if (> x 0) "positive" "non-positive")

if-let#

(if-let bindings then & [else])

If test is true, evaluates then with binding-form bound to the value of test, if not, yields else

if-not#

(if-not test then & [else])

Evaluates then if test is false, else otherwise.

Example:

(if-not (< 5 3) "not less" "less") ; => "not less"

if-some#

(if-some bindings then & [else])

Binds name to the value of test. If test is not nil, evaluates then with binding-form bound to the value of test, if not, yields else. Unlike if-let, false and 0 are not treated as falsy — only nil triggers the else branch.

inc#

(inc x)

Increments x by one.

indexed?#

(indexed? x)

Returns true if x is an indexed sequence, false otherwise.

Indexed sequences include lists, vectors, and indexed PHP arrays.

Example:

(indexed? [1 2 3]) ; => true

inf?#

(inf? x)

Checks if x is infinite.

Example:

(inf? php/INF) ; => true

int?#

(int? x)

Returns true if x is an integer number, false otherwise. Alias for integer?.

Note that, unlike Clojure, Phel uses PHP integers and there is no distinction between standard and fixed-precision integers. Integer sizes are also limited by platform (see php/PHP_INT_MAX constant).

integer?#

(integer? x)

Returns true if x is an integer number, false otherwise.

interleave#

(interleave & colls)

Interleaves multiple collections. Returns a lazy sequence.

Returns elements by taking one from each collection in turn. Pads with nil when collections have different lengths. Works with infinite sequences.

Example:

(interleave [1 2 3] [:a :b :c]) ; => (1 :a 2 :b 3 :c)

interpose#

(interpose sep & args)

Returns elements separated by a separator. Returns a lazy sequence. When called with sep only, returns a transducer.

Example:

(interpose 0 [1 2 3]) ; => (1 0 2 0 3)

intersection#

(intersection set & sets)

Intersect multiple sets into a new one.

into#

(into to & rest)

Returns to with all elements of from added.

When from is associative, it is treated as a sequence of key-value pairs. Supports persistent and transient collections.

Example:

(into [] '(1 2 3)) ; => [1 2 3]

invert#

(invert map)

Returns a new map where the keys and values are swapped.

If map has duplicated values, some keys will be ignored.

Example:

(invert {:a 1 :b 2 :c 3}) ; => {1 :a 2 :b 3 :c}

isa?#

(isa? child parent)

Returns true if child equals parent, or child is a descendant of parent in the global hierarchy.

Example:

(do (derive :square :shape) (isa? :square :shape)) ; => true

iterate#

(iterate f x)

Returns an infinite lazy sequence of x, (f x), (f (f x)), and so on.

Example:

(take 5 (iterate inc 0)) ; => (0 1 2 3 4)

iteration#

(iteration step opts)

Creates a lazy sequence from successive calls to step. step is called with a key (starting with :initk) and returns a result. :kf extracts the next key, :vf extracts the value from the result. Terminates when the result is nil.

Options map keys: :kf — key function (default: identity) :vf — value function (default: identity) :initk — initial key (default: nil)

Example:

(iteration fetch-page {:kf :next-token :vf :items :initk nil})

juxt#

(juxt & fs)

Takes a list of functions and returns a new function that is the juxtaposition of those functions.

Example:

((juxt inc dec #(* % 2)) 10) => [11 9 20]

keep#

(keep pred & args)

Returns a lazy sequence of non-nil results of applying function to elements. When called with f only, returns a transducer.

Example:

(keep #(when (even? %) (* % %)) [1 2 3 4 5]) ; => (4 16)

keep-indexed#

(keep-indexed pred & args)

Returns a lazy sequence of non-nil results of (pred i x). When called with f only, returns a transducer.

Example:

(keep-indexed #(when (even? %1) %2) ["a" "b" "c" "d"]) ; => ("a" "c")

keys#

(keys coll)

Returns a sequence of all keys in a map.

Example:

(keys {:a 1 :b 2}) ; => (:a :b)

keyword#

(keyword x)

Creates a new Keyword from a given string.

Example:

(keyword "name") ; => :name

keyword?#

(keyword? x)

Returns true if x is a keyword, false otherwise.

kvs#

(kvs coll)

Returns a vector of key-value pairs like [k1 v1 k2 v2 k3 v3 ...].

Example:

(kvs {:a 1 :b 2}) ; => [:a 1 :b 2]

last#

(last coll)

Returns the last element of coll or nil if coll is empty or nil.

Example:

(last [1 2 3]) ; => 3

lazy-cat#

(lazy-cat & colls)

Concatenates collections into a lazy sequence (expands to concat).

Example:

(lazy-cat [1 2] [3 4]) ; => (1 2 3 4)

lazy-seq#

(lazy-seq & body)

Creates a lazy sequence that evaluates the body only when accessed.

Example:

(lazy-seq (cons 1 (lazy-seq nil))) ; => (1)

let#

(let [bindings*] expr*)

Creates a new lexical context with assignments defined in bindings. Afterwards the list of expressions is evaluated and the value of the last expression is returned. If no expression is given nil is returned.

Example:

(let [x 1 y 2] (+ x y)) ; => 3

letfn#

(letfn bindings & body)

Defines mutually recursive local functions.

bindings is a vector of function specs: (letfn [(f [params] body) (g [params] body)] expr) All function names are in scope within all function bodies and the body expression, enabling mutual recursion.

Example:

(letfn [(my-even? [n] (if (zero? n) true (my-odd? (dec n))))
        (my-odd? [n] (if (zero? n) false (my-even? (dec n))))]
  (my-even? 10))

line-seq#

(line-seq filename)

Returns a lazy sequence of lines from a file.

Example:

(take 10 (line-seq "large-file.txt")) ; => ["line1" "line2" ...]

list#

(list 1 2 3) ; => '(1 2 3)

Creates a new list. If no argument is provided, an empty list is created. Shortcut: '()

Example:

(list 1 2 3) ; => '(1 2 3)

list?#

(list? x)

Returns true if x is a list, false otherwise.

loop#

(loop [bindings*] expr*)

Creates a new lexical context with variables defined in bindings and defines a recursion point at the top of the loop.

Example:

(loop [i 0] (if (< i 5) (do (println i) (recur (inc i)))))

macroexpand#

(macroexpand form)

Recursively expands the given form until it is no longer a macro call.

macroexpand-1#

(macroexpand-1 form)

Expands the given form once if it is a macro call.

make-hierarchy#

(make-hierarchy)

Returns a new hierarchy map with no parent relationships.

map#

(map f & colls)

Returns a lazy sequence of the result of applying f to all of the first items in each coll, followed by applying f to all the second items in each coll until anyone of the colls is exhausted.

When given a single collection, applies the function to each element. With multiple collections, applies the function to corresponding elements from each collection, stopping when the shortest collection is exhausted.

Example:

(map inc [1 2 3]) ; => (2 3 4)

map-indexed#

(map-indexed f coll)

Maps a function over a collection with index. Returns a lazy sequence.

Applies f to each element in xs. f is a two-argument function where the first argument is the index (0-based) and the second is the element itself. Works with infinite sequences.

Example:

(map-indexed vector [:a :b :c]) ; => ([0 :a] [1 :b] [2 :c])

map?#

(map? x)

Returns true if x is a hash map, false otherwise.

mapcat#

(mapcat f & args)

Maps a function over a collection and concatenates the results. Returns a lazy sequence. When called with f only, returns a transducer.

Example:

(mapcat reverse [[1 2] [3 4]]) ; => (2 1 4 3)

max#

(max & numbers)

Returns the numeric maximum of all numbers.

max-key#

(max-key k x & more)

Returns the arg for which (k arg) is largest. On ties, returns the latest argument, matching Clojure semantics.

Example:

(max-key count "bb" "aaa" "b") ; => "aaa"

mean#

(mean xs)

Returns the mean of xs.

median#

(median xs)

Returns the median of xs.

memoize#

(memoize f)

Returns a memoized version of the function f. The memoized function caches the return value for each set of arguments.

Example:

(defn fact [n]
  (if (zero? n)
    1
    (* n (fact (dec n)))))
(def fact-memo (memoize fact))

memoize-lru#

(memoize-lru f)
(memoize-lru f max-size)

Returns a memoized version of the function f with an LRU (Least Recently Used) cache limited to max-size entries. When the cache exceeds max-size, the least recently used entry is evicted. This prevents unbounded memory growth in long-running processes.

Without arguments, uses a default cache size of 128 entries.

Example:

(defn fact [n]
  (if (zero? n)
    1
    (* n (fact (dec n)))))
(def fact-memo (memoize-lru fact 100))

merge#

(merge & maps)

Merges multiple maps into one new map.

If a key appears in more than one collection, later values replace previous ones.

Example:

(merge {:a 1 :b 2} {:b 3 :c 4}) ; => {:a 1 :b 3 :c 4}

merge-with#

(merge-with f & hash-maps)

Merges multiple maps into one new map. If a key appears in more than one collection, the result of (f current-val next-val) is used.

meta#

Gets the metadata attached to a value. For a quoted symbol ((meta 'foo)) the definition metadata registered via def is returned. For any other expression the value is looked up at runtime and its MetaInterface metadata returned.

min#

(min & numbers)

Returns the numeric minimum of all numbers.

min-key#

(min-key k x & more)

Returns the arg for which (k arg) is smallest. On ties, returns the latest argument, matching Clojure semantics.

Example:

(min-key count "bb" "aaa" "b") ; => "b"

name#

(name x)

Returns the name string of a string, keyword or symbol.

namespace#

(namespace x)

Return the namespace string of a symbol or keyword. Nil if not present.

nan?#

(nan? x)

Checks if x is not a number.

neg?#

(neg? x)

Checks if x is smaller than zero.

next#

Returns the sequence after the first element, or nil if empty.

Example:

(next [1 2 3]) ; => [2 3]

nfirst#

(nfirst coll)

Same as (next (first coll)).

nil?#

(nil? x)

Returns true if value is nil, false otherwise.

Example:

(nil? (get {:a 1} :b)) ; => true

nnext#

(nnext coll)

Same as (next (next coll)).

not#

(not x)

Returns true if value is falsy (nil or false), false otherwise.

Example:

(not nil) ; => true

not-any?#

(not-any? pred coll)

Returns true if (pred x) is logical false for every x in coll or if coll is empty. Otherwise returns false.

not-empty#

(not-empty coll)

Returns coll if it contains elements, otherwise nil.

not-every?#

(not-every? pred coll)

Returns false if (pred x) is logical true for every x in collection coll or if coll is empty. Otherwise returns true.

not=#

(not= a & more)

Checks if all values are unequal. Same as a != b in PHP.

ns#

(ns name imports*)

Defines the namespace for the current file and adds imports to the environment. Imports can either be uses or requires. The keyword :use is used to import PHP classes, the keyword :require is used to import Phel modules and the keyword :require-file is used to load php files.

Example:

(ns my-app\core (:require phel\str :as str))

number?#

(number? x)

Returns true if x is a number, false otherwise.

object-array#

(object-array size-or-seq)

Creates a PHP array of the given size initialized to nil, or a PHP array containing the elements of the given sequence. Matches Clojure's object-array for .cljc interop — in Phel the result is a plain PHP array (accessible via php/aget/php/aset) since PHP has no typed array distinction.

Example:

(object-array 3) ; => a PHP array [nil, nil, nil]
(object-array [1 2 3]) ; => a PHP array [1, 2, 3]

odd?#

(odd? x)

Checks if x is odd.

one?#

(one? x)

Checks if x is one.

or#

(or & args)

Evaluates expressions left to right, returning the first truthy value or the last value.

Example:

(or false nil 42 100) ; => 42

pairs#

(pairs coll)

Gets the pairs of an associative data structure.

Example:

(pairs {:a 1 :b 2}) ; => ([:a 1] [:b 2])

parents#

(parents tag)

Returns the set of immediate parents of tag in the global hierarchy, or nil.

parse-boolean#

(parse-boolean s)

Parses a string as a boolean. Returns true for "true", false for "false", nil otherwise.

Example:

(parse-boolean "true") ; => true

parse-double#

(parse-double s)

Parses a string as a float. Returns nil if parsing fails.

Example:

(parse-double "3.14") ; => 3.14

parse-long#

(parse-long s)

Parses a string as an integer. Returns nil if parsing fails.

Example:

(parse-long "123") ; => 123

partial#

(partial f & args)

Takes a function f and fewer than normal arguments of f and returns a function that a variable number of additional arguments. When call f will be called with args and the additional arguments.

partition#

(partition n coll)

Partitions collection into chunks of size n, dropping incomplete final partition.

Example:

(partition 3 [1 2 3 4 5 6 7]) ; => ([1 2 3] [4 5 6])

partition-all#

(partition-all n coll)

Partitions collection into chunks of size n, including incomplete final partition.

Example:

(partition-all 3 [1 2 3 4 5 6 7]) ; => ([1 2 3] [4 5 6] [7])

partition-by#

(partition-by f coll)

Returns a lazy sequence of partitions. Applies f to each value in coll, splitting them each time the return value changes.

Example:

(partition-by #(< % 3) [1 2 3 4 5 1 2]) ; => [[1 2] [3 4 5] [1 2]]

peek#

(peek coll)

Returns the last element of a sequence, or nil if empty or nil. Works on vectors, PHP arrays, lists, and lazy sequences.

Example:

(peek [1 2 3]) ; => 3

persistent#

(persistent coll)

Converts a transient collection back to a persistent collection.

Example:

(def t (transient {}))

persistent!#

(persistent! coll)

Converts a transient collection back to a persistent collection. Alias for persistent, matching Clojure's persistent! naming.

Example:

(persistent! (conj! (transient []) 1 2 3)) ; => [1 2 3]

phel->php#

(phel->php x)

Recursively converts a Phel data structure to a PHP array.

Example:

(phel->php {:a [1 2 3] :b {:c 4}}) ; => (PHP array ["a" => [1, 2, 3], "b" => ["c" => 4]])

php->phel#

(php->phel x)

Recursively converts a PHP array to Phel data structures.

Indexed PHP arrays become vectors, associative PHP arrays become maps.

Example:

(php->phel (php-associative-array "a" 1 "b" 2)) ; => {"a" 1 "b" 2}

php-array-to-map#

(php-array-to-map arr)

Converts a PHP Array to a Phel map.

Example:

(php-array-to-map (php-associative-array "a" 1 "b" 2)) ; => {"a" 1 "b" 2}

php-array?#

(php-array? x)

Returns true if x is a PHP Array, false otherwise.

php-associative-array#

(php-associative-array & xs)

Creates a PHP associative array from key-value pairs.

Arguments: Key-value pairs (must be even number of arguments)

Example:

(php-associative-array "name" "Alice" "age" 30) ; => (PHP array ["name" => "Alice", "age" => 30])

php-indexed-array#

(php-indexed-array & xs)

Creates a PHP indexed array from the given values.

Example:

(php-indexed-array 1 2 3) ; => (PHP array [1, 2, 3])

php-object?#

(php-object? x)

Returns true if x is a PHP object, false otherwise.

php-resource?#

(php-resource? x)

Returns true if x is a PHP resource, false otherwise.

pop#

(pop coll)

Removes the last element of the array coll. If the array is empty returns nil.

pop!#

(pop! tcoll)

Removes the last element from a transient vector, mutating it in place. Raises InvalidArgumentException when tcoll is not a transient vector. Matches Clojure's pop! semantics.

Example:

(persistent! (pop! (transient [1 2 3]))) ; => [1 2]

pos?#

(pos? x)

Checks if x is greater than zero.

print#

(print & xs)

Prints the given values to the default output stream. Returns nil.

(print-str & xs)

Same as print. But instead of writing it to an output stream, the resulting string is returned.

printf#

(printf fmt & xs)

Output a formatted string. See PHP's printf for more information.

println#

(println & xs)

Same as print followed by a newline.

protocol-type-key#

(protocol-type-key x)

Returns the dispatch key for protocol dispatch. Returns a type keyword for primitive types, or the PHP class name string for objects/structs.

Optimized to avoid the full type cond chain: checks scalars first (most common in tight loops), then objects.

push#

Deprecated: 0.25.0 — Use conj instead

(push coll x)

Inserts x at the end of the sequence coll.

put#

Deprecated: 0.25.0 — Use assoc instead

(put ds key value)

Puts value mapped to key on the datastructure ds. Returns ds.

put-in#

Deprecated: 0.25.0 — Use assoc-in instead

(put-in ds ks v)

Puts a value into a nested data structure.

quote#

(quote form)

Returns the unevaluated form.

Example:

(quote (+ 1 2)) ; => '(+ 1 2)

rand#

(rand)

Returns a random number between 0 and 1.

rand-int#

(rand-int n)

Returns a random number between 0 and n.

rand-nth#

(rand-nth xs)

Returns a random item from xs.

random-uuid#

(random-uuid)

Returns a random UUID v4 string.

Example:

(random-uuid) ; => "550e8400-e29b-41d4-a716-446655440000"

range#

(range & args)

Creates a lazy sequence of numbers. With no arguments returns an infinite sequence starting at 0. With one argument returns (0..n). With two (start..end). With three (start..end step). Note: the infinite sequence is bounded by PHP_INT_MAX.

Example:

(range 5) ; => (0 1 2 3 4)

re-find#

(re-find re s)

Returns the first match of pattern in string, or nil if no match. If the pattern has groups, returns a vector of [full-match group1 group2 ...].

Example:

(re-find #"\d+" "abc123def") ; => "123"

re-matches#

(re-matches re s)

Returns the match, if any, of string to pattern. If the pattern has groups, returns a vector of [full-match group1 group2 ...]. Returns nil if no match. Unlike re-find, the entire string must match.

Example:

(re-matches #"(\d+)-(\d+)" "12-34") ; => ["12-34" "12" "34"]

re-pattern#

(re-pattern s)

Returns a PCRE pattern string from s. If s is already delimited, returns it as-is. Otherwise wraps in / delimiters.

Example:

(re-pattern "\\d+") ; => "/\\d+/"

re-seq#

(re-seq re s)

Returns a sequence of successive matches of pattern in string.

Example:

(re-seq #"\d+" "a1b2c3") ; => ["1" "2" "3"]

read-file-lazy#

(read-file-lazy filename)
(read-file-lazy filename chunk-size)

Returns a lazy sequence of byte chunks from a file.

Example:

(take 5 (read-file-lazy "large-file.bin" 1024)) ; => ["chunk1" "chunk2" ...]

read-string#

(read-string s)

Reads the first phel expression from the string s.

realized?#

(realized? coll)

Returns true if a lazy sequence, delay, or future has been realized, false otherwise.

Example:

(realized? (take 5 (iterate inc 1))) ; => false

recur#

(recur expr*)

Internally recur is implemented as a PHP while loop and therefore prevents the Maximum function nesting level errors.

Example:

(loop [n 5 acc 1] (if (<= n 1) acc (recur (dec n) (* acc n))))

reduce#

(reduce f & args)

Reduces collection to a single value by repeatedly applying function to accumulator and elements. Respects early termination via (reduced val).

Example:

(reduce + [1 2 3 4]) ; => 10

reduced#

(reduced x)

Wraps x in a Reduced, signaling early termination from reduce/transduce.

reduced?#

(reduced? x)

Returns true if x is a Reduced value.

reify#

(reify & specs)

Creates an anonymous object implementing one or more protocols. Method bodies close over local bindings. Each instance carries its own captured state, so reify works correctly inside loops.

Syntax: (reify ProtocolName (method-name [this arg1] body) AnotherProtocol (another-method [this] body))

Example:

(reify Speakable (speak [this] "hello"))

remove#

(remove pred & args)

Returns a lazy sequence of elements where predicate returns false. Opposite of filter. When called with pred only, returns a transducer.

Example:

(remove even? [1 2 3 4 5 6]) ; => (1 3 5)

remove-watch#

(remove-watch variable key)

Removes a watch function from a variable by key.

rename-keys#

(rename-keys m kmap)

Returns the map with keys renamed according to kmap. Keys not present in kmap are left unchanged.

Example:

(rename-keys {:a 1 :b 2 :c 3} {:a :x :b :y}) ; => {:x 1 :y 2 :c 3}

repeat#

(repeat a & rest)

Returns a vector of length n where every element is x.

With one argument returns an infinite lazy sequence of x.

Example:

(repeat 3 :a) ; => [:a :a :a]

repeatedly#

(repeatedly a & rest)

Returns a vector of length n with values produced by repeatedly calling f.

With one argument returns an infinite lazy sequence of calls to f.

Example:

(repeatedly 3 rand) ; => [0.234 0.892 0.456] (random values)

reset!#

(reset! variable value)

Sets a new value on the given atom. Returns the new value.

Example:

(def x (atom 10))

resolve#

(resolve sym)

Resolves the given symbol in the current environment and returns a resolved Symbol with the absolute namespace or nil if it cannot be resolved.

Example:

(resolve 'map) ; => phel\core/map

rest#

(rest coll)

Returns the sequence after the first element, or empty sequence if none.

Example:

(rest [1 2 3]) ; => [2 3]

reverse#

(reverse coll)

Reverses the order of the elements in the given sequence.

Example:

(reverse [1 2 3 4]) ; => [4 3 2 1]

run!#

(run! f coll)

Calls (f x) for each element in coll for side effects. Returns nil.

Example:

(run! println [1 2 3])

satisfies?#

(satisfies? protocol x)

Returns true if x's type implements all methods of the given protocol.

Example:

(satisfies? Stringable "hello")

second#

(second coll)

Returns the second element of a sequence, or nil if not present.

Example:

(second [1 2 3]) ; => 2

select-keys#

(select-keys m ks)

Returns a new map including key value pairs from m selected with keys ks.

Example:

(select-keys {:a 1 :b 2 :c 3} [:a :c]) ; => {:a 1 :c 3}

seq#

(seq coll)

Returns a seq on the collection. Strings are converted to a vector of characters. Collections are unchanged. Returns nil if coll is empty or nil.

This function is useful for explicitly converting strings to sequences of characters, enabling sequence operations like map, filter, and frequencies.

Example:

(seq "hello") ; => ["h" "e" "l" "l" "o"]

seq?#

(seq? x)

Returns true if x is a seq (implements LazySeqInterface), false otherwise.

sequence#

(sequence xform coll)

Applies transducer xform to coll, returning a vector of results.

Example:

(sequence (comp (filter even?) (map inc)) [1 2 3 4 5]) ; => [3 5]

set#

(set coll)

Coerces a collection to a set. Returns a set containing the distinct elements of coll. For creating sets from arguments, use hash-set.

Example:

(set [1 2 3 2 1]) ; => #{1 2 3}

set!#

Deprecated: 0.32.0 — Use reset! instead

(set! variable value)

Sets a new value to the given variable.

Example:

(def x (var 10))

set-meta!#

Deprecated: 0.32.0 — Use with-meta instead Sets the metadata to a given object.

set-validator!#

(set-validator! variable f)

Sets a validator function on a variable. The validator is called before any state change with the proposed new value. If it returns a falsy value, an exception is thrown and the state is not changed. Pass nil to remove.

Example:

(set-validator! my-var pos?)

set-var#

(var value)

Variables provide a way to manage mutable state that can be updated with set! and swap!. Each variable contains a single value. To create a variable use the var function.

Example:

(def counter (var 0))

set?#

(set? x)

Returns true if x is a set, false otherwise.

shuffle#

(shuffle coll)

Returns a random permutation of coll.

Example:

(shuffle [1 2 3 4 5]) ; => [3 1 5 2 4] (random order)

slice#

(slice coll & [offset & [length]])

Extracts a slice of coll starting at offset with optional length.

Example:

(slice [1 2 3 4 5] 1 3) ; => [2 3 4]

slurp#

(slurp path & [opts])

Reads entire file or URL into a string.

Example:

(slurp "file.txt") ; => "file contents"

some#

(some pred coll)

Returns the first truthy value of applying predicate to elements, or nil if none found.

Example:

(some #(when (> % 10) %) [5 15 8]) ; => 15

some->#

(some-> x & forms)

Threads x through the forms like -> but stops when a form returns nil.

some->>#

(some->> x & forms)

Threads x through the forms like ->> but stops when a form returns nil.

some-fn#

(some-fn p & ps)

Takes a variadic set of predicates and returns a function f that, when called with any number of arguments, returns the first logical true value produced by applying any of the composing predicates to any of its arguments, and nil otherwise. The returned function short-circuits on the first truthy result: arguments after it are not inspected, and predicates after it are not tried. Predicates are consulted in the order supplied; for a given predicate, arguments are consulted left-to-right. Matches Clojure's some-fn semantics.

Example:

((some-fn even? nil?) 1 2) ; => true
((some-fn pos? even?) -3 -1) ; => nil

some?#

(some? x)
(some? pred coll)

With 1 arg, returns true if x is not nil (Clojure semantics). With 2 args, returns true if pred is true for at least one element in coll.

Example:

(some? 1) ; => true
(some? even? [1 3 5 6 7]) ; => true

sort#

(sort coll & [comp])

Returns a sorted vector. If no comparator is supplied compare is used.

Example:

(sort [3 1 4 1 5 9 2 6]) ; => [1 1 2 3 4 5 6 9]

sort-by#

(sort-by keyfn coll & [comp])

Returns a sorted vector where the sort order is determined by comparing (keyfn item).

If no comparator is supplied compare is used.

Example:

(sort-by count ["aaa" "c" "bb"]) ; => ["c" "bb" "aaa"]

sorted-map#

(sorted-map & xs)

Creates a new sorted map. Keys are in natural sorted order. The number of parameters must be even.

Example:

(sorted-map :c 3 :a 1 :b 2) ; keys iterate as :a :b :c

sorted-map-by#

(sorted-map-by comp & xs)

Creates a new sorted map using the given comparator for key ordering. The comparator takes two arguments and returns a negative integer, zero, or a positive integer.

Example:

(sorted-map-by (fn [a b] (compare b a)) :a 1 :b 2) ; keys iterate as :b :a

sorted-set#

(sorted-set & xs)

Creates a new sorted set. Elements are in natural sorted order.

Example:

(sorted-set 3 1 2) ; iterates as 1 2 3

sorted-set-by#

(sorted-set-by comp & xs)

Creates a new sorted set using the given comparator for element ordering.

Example:

(sorted-set-by (fn [a b] (compare b a)) 3 1 2) ; iterates as 3 2 1

sorted?#

(sorted? coll)

Returns true if coll is a sorted collection (sorted-map or sorted-set), false otherwise.

Example:

(sorted? (sorted-set 1 2 3)) ; => true

spit#

(spit filename data & [opts])

Writes data to file, returning number of bytest that were written or nil on failure. Accepts opts map for overriding default PHP file_put_contents arguments, as example to append to file use {:flags php/FILE_APPEND}.

See PHP's file_put_contents for more information.

split-at#

(split-at n coll)

Returns a vector of [(take n coll) (drop n coll)].

Example:

(split-at 2 [1 2 3 4 5]) ; => [[1 2] [3 4 5]]

split-with#

(split-with f coll)

Returns a vector of [(take-while pred coll) (drop-while pred coll)].

Example:

(split-with #(< % 4) [1 2 3 4 5 6]) ; => [[1 2 3] [4 5 6]]

str#

(str & args)

Creates a string by concatenating values together. If no arguments are provided an empty string is returned. Nil is represented as an empty string. Booleans are represented as "true" or "false" (matching Clojure semantics). Otherwise, it tries to call __toString.

str-contains?#

Deprecated: Use phel\str\contains?

(str-contains? str s)

Returns true if str contains s.

string?#

(string? x)

Returns true if x is a string, false otherwise.

struct?#

(struct? x)

Returns true if x is a struct, false otherwise.

subset?#

(subset? s1 s2)

Returns true if s1 is a subset of s2, i.e. every element in s1 is also in s2.

Example:

(subset? (hash-set 1 2) (hash-set 1 2 3)) ; => true

sum#

(sum xs)

Returns the sum of all elements is xs.

superset?#

(superset? s1 s2)

Returns true if s1 is a superset of s2, i.e. every element in s2 is also in s1.

Example:

(superset? (hash-set 1 2 3) (hash-set 1 2)) ; => true

swap!#

(swap! variable f & args)

Atomically swaps the value of the atom to (apply f current-value args).

Returns the new value after the swap.

Example:

(def counter (atom 0))

symbol#

(symbol name-or-ns & [name])

Returns a new symbol for given string with optional namespace.

With one argument, creates a symbol without namespace. With two arguments, creates a symbol in the given namespace.

Example:

(symbol "foo") ; => foo

symbol?#

(symbol? x)

Returns true if x is a symbol, false otherwise.

symmetric-difference#

(symmetric-difference set & sets)

Symmetric difference between multiple sets into a new one.

take#

(take n & args)

Takes the first n elements of coll. When called with n only, returns a transducer.

take-last#

(take-last n coll)

Takes the last n elements of coll.

Example:

(take-last 3 [1 2 3 4 5]) ; => [3 4 5]

take-nth#

(take-nth n & args)

Returns every nth item in coll. Returns a lazy sequence. When called with n only, returns a transducer.

Example:

(take-nth 2 [0 1 2 3 4 5 6 7 8]) ; => (0 2 4 6 8)

take-while#

(take-while pred & args)

Takes all elements at the front of coll where (pred x) is true. Returns a lazy sequence. When called with pred only, returns a transducer.

Example:

(take-while #(< % 5) [1 2 3 4 5 6 3 2 1]) ; => (1 2 3 4)

throw#

(throw exception)

Throw an exception.

Example:

(throw (php/new \InvalidArgumentException "Invalid input"))

time#

(time expr)

Evaluates expr and prints the time it took. Returns the value of expr.

to-array#

(to-array coll)

Returns a PHP array containing the elements of coll. Accepts any collection (vector, list, set, map, PHP array) or nil, which yields an empty PHP array. Matches Clojure's to-array for .cljc interop — in Phel the result is a plain PHP array since PHP has no Object[].

Example:

(to-array [1 2 3]) ; => a PHP array [1, 2, 3]
(to-array nil) ; => a PHP array []

to-php-array#

Creates a PHP Array from a sequential data structure.

transduce#

(transduce xform f & args)

Reduce with a transformation of f (xf). If init is not supplied, (f) will be called to produce it. f should be a reducing function that returns the initial value when called with no arguments.

Example:

(transduce (map inc) + [1 2 3]) ; => 9

transient#

(transient coll)

Converts a persistent collection to a transient collection for efficient updates.

Transient collections provide faster performance for multiple sequential updates. Use persistent to convert back.

Example:

(def t (transient []))

tree-seq#

(tree-seq branch? children root)

Returns a vector of the nodes in the tree, via a depth-first walk. branch? is a function with one argument that returns true if the given node has children. children must be a function with one argument that returns the children of the node. root the root node of the tree.

true?#

(true? x)

Checks if value is exactly true (not just truthy).

Example:

(true? 1) ; => false

truthy?#

(truthy? x)

Checks if x is truthy. Same as x == true in PHP.

try#

(try expr* catch-clause* finally-clause?)

All expressions are evaluated and if no exception is thrown the value of the last expression is returned. If an exception occurs and a matching catch-clause is provided, its expression is evaluated and the value is returned. If no matching catch-clause can be found the exception is propagated out of the function. Before returning normally or abnormally the optionally finally-clause is evaluated.

Example:

(try (/ 1 0) (catch \Exception e "error"))

type#

(type x)

Returns the type of x. The following types can be returned:

  • :vector
  • :list
  • :struct
  • :hash-map
  • :set
  • :keyword
  • :symbol
  • :var
  • :int
  • :float
  • :string
  • :nil
  • :boolean
  • :function
  • :php/array
  • :php/resource
  • :php/object
  • :unknown

underive#

(underive child parent)

Removes a parent/child relationship from the global hierarchy.

Example:

(underive :square :shape)

union#

(union & sets)

Union multiple sets into a new one.

unquote#

(unquote my-sym) ; Evaluates to my-sym
,my-sym          ; Shorthand for (same as above)

Values that should be evaluated in a macro are marked with the unquote function. Shortcut: ,

Example:

`(+ 1 ,(+ 2 3)) ; => (+ 1 5)

unquote-splicing#

(unquote-splicing my-sym) ; Evaluates to my-sym
,@my-sym                  ; Shorthand for (same as above)

Values that should be evaluated in a macro are marked with the unquote function. Shortcut: ,@

Example:

`(+ ,@[1 2 3]) ; => (+ 1 2 3)

unreduced#

(unreduced x)

If x is Reduced, returns the unwrapped value; otherwise returns x.

unset#

Deprecated: 0.25.0 — Use dissoc instead

(unset ds key)

Returns ds without key.

unset-in#

Deprecated: 0.25.0 — Use dissoc-in instead

(unset-in ds ks)

Removes a value from a nested data structure.

update#

(update ds k f & args)

Updates a value in a datastructure by applying f to the current value.

Example:

(update {:count 5} :count inc) ; => {:count 6}

update-in#

(update-in ds [k & ks] f & args)

Updates a value in a nested data structure by applying f to the value at path.

Example:

(update-in {:a {:b 5}} [:a :b] inc) ; => {:a {:b 6}}

update-keys#

(update-keys m f)

Returns a map with f applied to each key.

Example:

(update-keys {:a 1 :b 2} name) ; => {"a" 1 "b" 2}

update-vals#

(update-vals m f)

Returns a map with f applied to each value.

Example:

(update-vals {:a 1 :b 2} inc) ; => {:a 2 :b 3}

vals#

(vals coll)

Returns a sequence of all values in a map.

Example:

(vals {:a 1 :b 2}) ; => (1 2)

values#

Deprecated: 0.32.0 — Use vals instead

(values coll)

Returns a sequence of all values in a map.

Example:

(values {:a 1 :b 2}) ; => (1 2)

var#

Deprecated: 0.32.0 — Use atom instead

(var value)

Creates a new variable with the given value.

Example:

(def counter (var 0))

var?#

Deprecated: 0.32.0 — Use atom? instead

(var? x)

Checks if the given value is a variable.

vary-meta#

Returns an object with (apply f (meta obj) args) as its new metadata.

vec#

(vec coll)

Coerces a collection to a vector. For hash-maps and structs, entries are returned as 2-element [key value] vectors, matching Clojure.

Example:

(vec {:a 1 :b 2}) ; => [[:a 1] [:b 2]]

vector#

(vector 1 2 3) ; => [1 2 3]

Creates a new vector. If no argument is provided, an empty vector is created. Shortcut: []

Example:

(vector 1 2 3) ; => [1 2 3]

vector?#

(vector? x)

Returns true if x is a vector, false otherwise.

volatile!#

(volatile! val)

Creates a volatile mutable reference with initial value val. Use for transducer state that needs fast mutation without watches.

volatile?#

(volatile? x)

Returns true if x is a Volatile.

vreset!#

(vreset! vol val)

Sets the value of volatile vol to val. Returns val.

vswap!#

(vswap! vol f & args)

Applies f to the current value of volatile vol plus args, and sets the new value. Returns the new value.

when#

(when test & body)

Evaluates body if test is true, otherwise returns nil.

Example:

(when (> 10 5) "greater") ; => "greater"

when-first#

(when-first bindings & body)

Binds name to the first element of coll. When the collection is non-empty (first returns non-nil), evaluates body with the binding.

when-let#

(when-let bindings & body)

When test is true, evaluates body with binding-form bound to the value of test

when-not#

(when-not test & body)

Evaluates body if test is false, otherwise returns nil.

Example:

(when-not (empty? [1 2 3]) "has items") ; => "has items"

when-some#

(when-some bindings & body)

Binds name to the value of test. When test is not nil, evaluates body with binding-form bound to the value of test. Unlike when-let, false and 0 are not treated as falsy — only nil causes the body to be skipped.

with-meta#

Returns obj with the given metadata meta attached.

with-output-buffer#

(with-output-buffer & body)

Everything that is printed inside the body will be stored in a buffer. The result of the buffer is returned.

zero?#

(zero? x)

Checks if x is zero.

zipcoll#

(zipcoll a b)

Creates a map from two sequential data structures. Returns a new map.

Example:

(zipcoll [:a :b :c] [1 2 3]) ; => {:a 1 :b 2 :c 3}

zipmap#

(zipmap keys vals)

Returns a new map with the keys mapped to the corresponding values.

Stops when the shorter of keys or vals is exhausted. Works safely with infinite lazy sequences.

Example:

(zipmap [:a :b :c] [1 2 3]) ; => {:a 1 :b 2 :c 3}

debug#

debug/add-tap#

(add-tap f)

Register a global tap handler function.

Example:

(add-tap println)

debug/dbg#

(dbg expr)

Evaluates an expression and prints it with its result.

Example:

(dbg (+ 1 2))

debug/dotrace#

(dotrace name f)

Wraps a function to print each call and result with indentation.

Example:

(def add (dotrace "add" +))

debug/remove-tap#

(remove-tap f)

Unregister a global tap handler function.

Example:

(remove-tap println)

debug/reset-taps!#

(reset-taps!)

Clear all tap handlers.

Example:

(reset-taps!)

debug/reset-trace-state!#

(reset-trace-state!)

Resets trace counters to initial values.

Example:

(reset-trace-state!)

debug/set-trace-id-padding!#

(set-trace-id-padding! estimated-id-padding)

Sets the number of digits for trace ID padding.

Example:

(set-trace-id-padding! 3)

debug/spy#

(spy expr)
(spy label expr)

Evaluates an expression and prints it with an optional label.

Example:

(spy (+ 1 2))

debug/tap#

(tap value)
(tap value handler)

Prints a value and returns it unchanged. Useful in pipelines.

Example:

(-> 5 (tap) (* 2))

debug/tap>#

(tap> value)

Send a value to all registered tap handlers.

Example:

(tap> {:debug "some value"})

html#

html/doctype#

(doctype type)

Returns an HTML doctype declaration.

Example:

(doctype :html5) ; => "<!DOCTYPE html>\n"

html/escape-html#

(escape-html s)

Escapes HTML special characters to prevent XSS.

Example:

(escape-html "<div>") ; => "&lt;div&gt;"

html/html#

(html & content)

Compiles Phel vectors to HTML strings.

Example:

(html [:div "Hello"]) ; => "<div>Hello</div>"

html/raw-string#

(raw-string s)

Creates a new raw-string struct.

html/raw-string?#

(raw-string? x)

Checks if x is an instance of the raw-string struct.


http#

http/create-response-from-map#

Deprecated: Use response-from-map

http/create-response-from-string#

Deprecated: Use response-from-string

http/emit-response#

(emit-response response)

Emits the response by sending headers and outputting the body.

Example:

(emit-response (response-from-string "Hello World")) ; => nil

http/files-from-globals#

(files-from-globals & [files])

Extracts the files from $_FILES and normalizes them to a map of "uploaded-file".

Example:

(files-from-globals) ; => {:avatar (uploaded-file "/tmp/phpYzdqkD" 1024 0 "photo.jpg" "image/jpeg")}

http/headers-from-server#

(headers-from-server & [server])

Extracts all headers from the $_SERVER variable.

Example:

(headers-from-server) ; => {:host "example.com" :content-type "application/json"}

http/request#

(request method uri headers parsed-body query-params cookie-params server-params uploaded-files version attributes)

Creates a new request struct.

http/request-from-globals#

(request-from-globals)

Extracts a request from $_SERVER, $_GET, $_POST, $_COOKIE and $_FILES.

Example:

(request-from-globals) ; => (request "GET" (uri ...) {...} nil {...} {...} {...} {...} "1.1" {})

http/request-from-globals-args#

(request-from-globals-args server get-parameter post-parameter cookies files)

Extracts a request from args.

Example:

(request-from-globals-args php/$_SERVER php/$_GET php/$_POST php/$_COOKIE php/$_FILES) ; => (request "GET" (uri ...) {...} nil {...} {...} {...} {...} "1.1" {})

http/request-from-map#

(request-from-map {:method method, :version version, :uri uri, :headers headers, :parsed-body parsed-body, :query-params query-params, :cookie-params cookie-params, :server-params server-params, :uploaded-files uploaded-files, :attributes attributes})

Creates a request struct from a map with optional keys :method, :uri, :headers, etc.

Example:

(request-from-map {:method "POST" :uri "https://api.example.com/users"}) ; => (request "POST" (uri ...) {} nil {} {} {} [] "1.1" {})

http/request?#

(request? x)

Checks if x is an instance of the request struct.

http/response#

(response status headers body version reason)

Creates a new response struct.

http/response-from-map#

(response-from-map {:status status, :headers headers, :body body, :version version, :reason reason})

Creates a response struct from a map with optional keys :status, :headers, :body, :version, and :reason.

Example:

(response-from-map {:status 200 :body "Hello World"}) ; => (response 200 {} "Hello World" "1.1" "OK")

http/response-from-string#

(response-from-string s)

Create a response from a string.

Example:

(response-from-string "Hello World") ; => (response 200 {} "Hello World" "1.1" "OK")

http/response?#

(response? x)

Checks if x is an instance of the response struct.

http/uploaded-file#

(uploaded-file tmp-file size error-status client-filename client-media-type)

Creates a new uploaded-file struct.

http/uploaded-file?#

(uploaded-file? x)

Checks if x is an instance of the uploaded-file struct.

http/uri#

(uri scheme userinfo host port path query fragment)

Creates a new uri struct.

http/uri-from-globals#

(uri-from-globals & [server])

Extracts the URI from the $_SERVER variable.

Example:

(uri-from-globals) ; => (uri "https" nil "example.com" 443 "/path" "foo=bar" nil)

http/uri-from-string#

(uri-from-string url)

Create a uri struct from a string.

Example:

(uri-from-string "https://example.com/path?foo=bar") ; => (uri "https" nil "example.com" nil "/path" "foo=bar" nil)

http/uri?#

(uri? x)

Checks if x is an instance of the uri struct.


json#

json/decode#

(decode json & [{:flags flags, :depth depth}])

Decodes a JSON string to a Phel value.

Example:

(decode "{\"name\":\"Alice\"}") ; => {:name "Alice"}

json/decode-value#

(decode-value x)

Converts a JSON value to Phel format.

Example:

(decode-value [1 2 3]) ; => [1 2 3]

json/encode#

(encode value & [{:flags flags, :depth depth}])

Encodes a Phel value to a JSON string.

Example:

(encode {:name "Alice"}) ; => "{\"name\":\"Alice\"}"

json/encode-value#

(encode-value x)

Converts a Phel value to JSON-compatible format.

Example:

(encode-value :name) ; => "name"

json/valid-key?#

(valid-key? v)

Checks if a value can be used as a JSON key.

Example:

(valid-key? :name) ; => true

mock#

mock/call-count#

(call-count mock-fn)

Returns the number of times the mock was called.

Example:

(def my-mock (mock :result))

mock/called-once?#

(called-once? mock-fn)

Returns true if the mock was called exactly once.

Example:

(def my-mock (mock :result))

mock/called-times?#

(called-times? mock-fn n)

Returns true if the mock was called exactly n times.

Example:

(def my-mock (mock :result))

mock/called-with?#

(called-with? mock-fn & expected-args)

Returns true if the mock was called with the exact arguments.

Example:

(def my-mock (mock :result))

mock/called?#

(called? mock-fn)

Returns true if the mock was called at least once.

Example:

(def my-mock (mock :result))

mock/calls#

(calls mock-fn)

Returns a list of all argument lists the mock was called with.

Example:

(def my-mock (mock :result))

mock/clear-all-mocks!#

(clear-all-mocks!)

Clears the entire mock registry. Useful for cleanup between test suites in long-running processes.

Example:

(clear-all-mocks!) ; All mocks removed from registry

mock/first-call#

(first-call mock-fn)

Returns the arguments from the first call.

Example:

(def my-mock (mock :result))

mock/last-call#

(last-call mock-fn)

Returns the arguments from the most recent call.

Example:

(def my-mock (mock :result))

mock/mock#

(mock return-value)

Creates a mock function that returns a fixed value and tracks all calls.

Example:

(def my-mock (mock :return-value))

mock/mock-fn#

(mock-fn f)

Creates a mock function with custom behavior that tracks all calls.

Example:

(def my-mock (mock-fn (fn [x] (* x 2))))

mock/mock-returning#

(mock-returning values)

Creates a mock that returns different values for consecutive calls. After exhausting values, returns the last value.

Example:

(def my-mock (mock-returning [1 2 3]))

mock/mock-throwing#

(mock-throwing exception)

Creates a mock that throws an exception when called.

Example:

(def my-mock (mock-throwing (php/new \RuntimeException "API unavailable")))

mock/mock?#

(mock? f)

Returns true if the function is a mock.

mock/never-called?#

(never-called? mock-fn)

Returns true if the mock was never called.

Example:

(def my-mock (mock :result))

mock/reset-mock!#

(reset-mock! mock-fn)

Resets the call history of a mock without removing it from the registry. The mock can continue to be used and track new calls.

Example:

(def my-mock (mock :result))

mock/spy#

(spy f)

Wraps an existing function to track calls while preserving original behavior.

Example:

(def original-fn (fn [x] (* x 2)))

mock/with-mock-wrapper#

(with-mock-wrapper bindings & body)

Like with-mocks but for wrapped mocks (interop scenarios). Automatically resets the underlying mock even when wrapped in an adapter function.

Usage:

(with-mock-wrapper [fn-symbol underlying-mock wrapper-fn]
body...)

Multiple wrappers:

(with-mock-wrapper [service-a mock-a (fn [x] (mock-a (inc x)))
service-b mock-b (fn [y] (mock-b (dec y)))]
...)

Example:

(with-mock-wrapper [http mock-http identity] (http "test"))

mock/with-mocks#

(with-mocks bindings & body)

Temporarily replaces functions with mocks using binding. Automatically resets mocks after the body executes.

Works with inline mock creation:

(with-mocks [http-get (mock {:status 200})]
(http-get)
;; Mock is automatically reset after this block)

Also works with pre-defined mocks:

(let [my-mock (mock :result)]
(with-mocks [some-fn my-mock]
(some-fn)))

If you need to wrap the mock in a function (e.g., to adapt arguments), you'll need to manually reset:

(with-mocks [some-fn (fn [& args] (my-mock (transform args)))]
(some-fn)
(reset-mock! my-mock))

php#

php/->#

(php/-> object call*)
(php/:: class call*)

Access to an object property or result of chained calls.

Example:

(php/-> date (format "Y-m-d"))

php/::#

(php/:: class (method-name expr*))
(php/:: class call*)

Calls a static method or property from a PHP class. Both method-name and property must be symbols and cannot be an evaluated value.

Example:

(php/:: DateTime (createFromFormat "Y-m-d" "2024-01-01"))

php/aget#

(php/aget arr index)

Equivalent to PHP's arr[index] ?? null.

Example:

(php/aget (php/array "a" "b" "c") 1) ; => "b"

php/aget-in#

(php/aget-in arr ks)

Equivalent to PHP's arr[k1][k2][k...] ?? null.

Example:

(php/aget-in nested-arr ["users" 0 "name"])

php/apush#

(php/apush arr value)

Equivalent to PHP's arr[] = value.

Example:

(php/apush arr "new-item")

php/apush-in#

(php/apush-in arr ks value)

Equivalent to PHP's arr[k1][k2][k...][] = value.

Example:

(php/apush-in arr ["users"] {:name "Bob"})

php/aset#

(php/aset arr index value)

Equivalent to PHP's arr[index] = value.

Example:

(php/aset arr 0 "new-value")

php/aset-in#

(php/aset-in arr ks value)

Equivalent to PHP's arr[k1][k2][k...] = value.

Example:

(php/aset-in arr ["users" 0 "name"] "Alice")

php/aunset#

(php/aunset arr index)

Equivalent to PHP's unset(arr[index]).

Example:

(php/aunset arr "key-to-remove")

php/aunset-in#

(php/aunset-in arr ks)

Equivalent to PHP's unset(arr[k1][k2][k...]).

Example:

(php/aunset-in arr ["users" 0])

php/new#

(php/new expr args*)

Evaluates expr and creates a new PHP class using the arguments. The instance of the class is returned.

Example:

(php/new DateTime "2024-01-01")

php/oset#

(php/oset (php/-> object property) value)
(php/oset (php/:: class property) value)

Use php/oset to set a value to a class/object property.

Example:

(php/oset (php/-> obj name) "Alice")

repl#

repl/apropos#

(apropos search)

Returns a vector of symbols whose name contains the given search string. Searches across all loaded namespaces.

Example:

(apropos "map") ; => [phel\core/flat-map phel\core/map ...]

repl/build-facade#

repl/compile-str#

(compile-str s)

Compiles a Phel expression string to PHP code.

Example:

(compile-str "(+ 1 2)") ; => "(1 + 2)"

repl/dir#

(dir ns-str)

Prints all public definitions in the given namespace string.

Returns nil. Prints one name per line, sorted alphabetically.

Example:

(dir "phel\core")

repl/doc#

(doc sym)

Prints the documentation for the given symbol.

Example:

(doc map)

repl/eval-capturing#

(eval-capturing code-str)

Evaluates a string of Phel code while capturing stdout. Returns a hash-map with :value (the result), :out (captured stdout), :success (boolean), and :error (error message or nil).

Useful for nREPL and other tooling that needs to separate printed output from return values.

Example:

(eval-capturing "(do (println \"hello\") 42)") ; => {:value 42 :out "hello\n" :success true :error nil}

repl/eval-str#

(eval-str s)

Evaluates a string of Phel code and returns the result. If the string contains multiple expressions, returns the result of the last one.

Example:

(eval-str "(+ 1 2)") ; => 3

repl/find-fn#

(find-fn search)

Searches for functions whose name or docstring contains the search string. Returns a vector of maps with :ns, :name, :doc, :private, :min-arity, :max-arity, :is-variadic.

Example:

(find-fn "map") ; => [{:ns "phel\core" :name "map" ...} ...]

repl/get-source-code#

(get-source-code ns-str name-str)

Returns the source code of the definition identified by namespace and name strings, or nil if the source file cannot be found or metadata is missing.

Example:

(get-source-code "phel\core" "map")

repl/get-symbol-info#

(get-symbol-info ns-str name-str)

Returns a hash-map of structured metadata for the definition identified by namespace and name strings. Returns nil if no such definition exists.

Keys: :doc, :file, :line, :column, :end-line, :end-column, :private, :deprecated, :min-arity, :max-arity, :is-variadic, :ns, :name

Example:

(get-symbol-info "phel\core" "map")

repl/load-file#

(load-file path)

Loads and evaluates a Phel source file in the current REPL session. Reads the file content and evaluates it using the compiler, preserving the current REPL namespace context. Returns the result of the last expression.

Example:

(load-file "src/my-module.phel")

repl/loaded-namespaces#

(loaded-namespaces)

Returns all namespaces currently loaded in the REPL.

Example:

(loaded-namespaces) ; => ["phel\core" "phel\repl"]

repl/macroexpand#

(macroexpand form)

Recursively expands the given form until it is no longer a macro call. The form must be quoted to prevent evaluation, matching Clojure semantics.

Example:

(macroexpand '(when true 1 2))

repl/macroexpand-1#

(macroexpand-1 form)

Expands the given form once if it is a macro call. The form must be quoted to prevent evaluation, matching Clojure semantics.

Example:

(macroexpand-1 '(when true 1 2))

repl/macroexpand-1-form#

(macroexpand-1-form form)

Expands the given form once if it is a macro call. Takes a quoted form and returns the expanded form, or the original form unchanged if it is not a macro call. Uses the CompilerFacade to perform the expansion without going through analyze+emit.

Example:

(macroexpand-1-form '(defn foo [x] x))

repl/macroexpand-form#

(macroexpand-form form)

Recursively expands the given form until it is no longer a macro call. Takes a quoted form and returns the fully expanded form. Uses the CompilerFacade to perform the expansion without going through analyze+emit.

Example:

(macroexpand-form '(defn foo [x] x))

repl/ns-aliases#

(ns-aliases ns-str)

Returns a hash-map of {alias => namespace} for all require aliases in the given namespace string.

Example:

(ns-aliases *ns*) ; => {"repl" "phel\repl" ...}

repl/ns-list#

(ns-list)

Returns a sorted vector of all loaded namespace names, decoded to human-readable form (hyphens restored instead of underscores).

Example:

(ns-list) ; => ["phel\core" "phel\repl" ...]

repl/ns-publics#

(ns-publics ns-str)

Returns a hash-map of {name => value} for all public definitions in the given namespace string. Private definitions are excluded.

Example:

(ns-publics "phel\core") ; => {"map" <fn> "filter" <fn> ...}

repl/ns-refers#

(ns-refers ns-str)

Returns a hash-map of {name => source-namespace} for all referred symbols in the given namespace string.

Example:

(ns-refers *ns*) ; => {"doc" "phel\repl" ...}

repl/print-colorful#

(print-colorful & xs)

Prints arguments with colored output.

Example:

(print-colorful [1 2 3])

repl/println-colorful#

(println-colorful & xs)

Prints arguments with colored output followed by a newline.

Example:

(println-colorful [1 2 3])

repl/require#

(require sym & args)

Requires a Phel module into the environment.

Example:

(require 'phel\http :as http :refer [request]) ; => phel\http

repl/search-doc#

(search-doc search)

Searches docstrings across all loaded namespaces for the given string. Prints matching function names and their documentation.

Example:

(search-doc "reduce")

repl/source#

(source sym)

Returns the source code of the given symbol as a string, or nil if unavailable.

Example:

(source map)

repl/symbol-info#

(symbol-info sym)

Returns a hash-map of structured metadata for the given symbol, or nil if the symbol cannot be resolved.

Keys: :doc, :file, :line, :column, :end-line, :end-column, :private, :deprecated, :min-arity, :max-arity, :is-variadic, :ns, :name

Example:

(symbol-info map) ; => {:doc "..." :ns "phel\core" :name "map" ...}

repl/test-ns#

(test-ns ns-str)

Runs all tests in a given namespace from the REPL. Requires the namespace if not already loaded, finds all deftest definitions, runs them, prints results, and returns a hash-map with :pass, :fail, and :error counts. Preserves outer test state so it can be safely called during a test run.

Example:

(test-ns "phel-test\test\core")

repl/use#

(use sym & args)

Adds a use statement to the environment.

Example:

(use DateTime :as DT) ; => DateTime

str#

str/blank?#

(blank? s)

True if s is nil, empty, or contains only whitespace.

Example:

(blank? "   ") ; => true

str/capitalize#

(capitalize s)

Converts first character to upper-case and all other characters to lower-case.

Example:

(capitalize "hELLO wORLD") ; => "Hello world"

str/chars#

(chars s)

Returns a vector of characters from string s.

This is a convenience function for converting strings to character sequences. Properly handles multibyte UTF-8 characters.

Example:

(chars "hello") ; => ["h" "e" "l" "l" "o"]

str/contains?#

(contains? s substr)

True if s contains substr.

Example:

(contains? "hello world" "lo wo") ; => true

str/ends-with?#

(ends-with? s substr)

True if s ends with substr.

Example:

(ends-with? "hello world" "world") ; => true

str/escape#

(escape s cmap)

Returns a new string with each character escaped according to cmap.

Example:

(escape "hello" {"h" "H" "o" "O"}) ; => "HellO"

str/includes?#

(includes? s substr)

True if s includes substr.

Example:

(includes? "hello world" "world") ; => true

str/index-of#

(index-of s value & [from-index])

Returns the index of value in s, or nil if not found.

Example:

(index-of "hello world" "world") ; => 6

str/join#

(join separator & [coll])

Returns a string of all elements in coll, separated by an optional separator.

Example:

(join ", " ["apple" "banana" "cherry"]) ; => "apple, banana, cherry"

str/last-index-of#

(last-index-of s value & [from-index])

Returns the last index of value in s, or nil if not found.

Example:

(last-index-of "hello world world" "world") ; => 12

str/lower-case#

(lower-case s)

Converts string to all lower-case.

Example:

(lower-case "HELLO World") ; => "hello world"

str/pad-both#

(pad-both s len & [pad-str])

Returns a string padded on both sides to length len.

Example:

(pad-both "hello" 11) ; => "   hello   "

str/pad-left#

(pad-left s len & [pad-str])

Returns a string padded on the left side to length len.

Example:

(pad-left "hello" 10) ; => "     hello"

str/pad-right#

(pad-right s len & [pad-str])

Returns a string padded on the right side to length len.

Example:

(pad-right "hello" 10) ; => "hello     "

str/re-quote-replacement#

(re-quote-replacement replacement)

Escapes special characters in a replacement string for literal use.

Example:

(re-quote-replacement "$1.00") ; => "\$1.00"

str/repeat#

(repeat s n)

Returns a string containing n copies of s.

Example:

(repeat "ha" 3) ; => "hahaha"

str/replace#

(replace s match replacement)

Replaces all instances of match with replacement in s.

Example:

(replace "hello world" "world" "there") ; => "hello there"

str/replace-first#

(replace-first s match replacement)

Replaces the first instance of match with replacement in s.

Example:

(replace-first "hello world world" "world" "there") ; => "hello there world"

str/reverse#

(reverse s)

Returns s with its characters reversed.

Example:

(reverse "hello") ; => "olleh"

str/split#

(split s re & [limit])

Splits string on a regular expression, returning a vector of parts.

Example:

(split "hello world foo bar" #"\s+") ; => ["hello" "world" "foo" "bar"]

str/split-lines#

(split-lines s)

Splits s on \n or \r\n. Trailing empty lines are not returned.

Example:

(split-lines "hello\nworld\ntest") ; => ["hello" "world" "test"]

str/starts-with?#

(starts-with? s substr)

True if s starts with substr.

Example:

(starts-with? "hello world" "hello") ; => true

str/subs#

(subs s start & [end])

Returns the substring of s from start (inclusive) to end (exclusive).

Example:

(subs "hello world" 0 5) ; => "hello"

str/trim#

(trim s)

Removes whitespace from both ends of string.

Example:

(trim "  hello  ") ; => "hello"

str/trim-newline#

(trim-newline s)

Removes all trailing newline or return characters from string.

Example:

(trim-newline "hello\n\n") ; => "hello"

str/triml#

(triml s)

Removes whitespace from the left side of string.

Example:

(triml "  hello  ") ; => "hello  "

str/trimr#

(trimr s)

Removes whitespace from the right side of string.

Example:

(trimr "  hello  ") ; => "  hello"

str/upper-case#

(upper-case s)

Converts string to all upper-case.

Example:

(upper-case "hello World") ; => "HELLO WORLD"

test#

test/*testing-contexts*#

Stack of testing context strings, most recent first.

test/are#

(are argv expr & args)

Checks multiple assertions with a template expression. argv is a vector of template variables, expr is the assertion template, and the remaining args are partitioned by (count argv) to fill the template. Template variables are substituted lexically at macro-expansion time, so literal collection cells (e.g. (), [], {}) are preserved as data and are not evaluated as code.

Example:

(are [x y] (= x y)
  2 (+ 1 1)
  4 (* 2 2))

test/assert-expr#

(assert-expr & args)

test/assert-expr-methods#

test/deftest#

(deftest test-name & body)

Defines a test function.

Example:

(deftest test-add)

test/do-report#

(do-report m)

Add file and line information to a test result and call report. If you are writing a custom assert-expr method, call this function to pass test results to report.

Example:

(do-report {:state :pass :type :any :message "ok"})

test/get-stats#

(get-stats)

Returns the current test statistics as a hash-map with :failed and :counts keys.

Example:

(get-stats) ; => {:failed [] :counts {:failed 0 :error 0 :pass 0 :total 0}}

test/is#

(is form & [message])

Asserts that an expression is true.

Example:

(is (= 4 (+ 2 2)))

test/print-summary#

(print-summary)

Prints test results summary.

Example:

(print-summary)

test/report#

(report data)

Records test results and prints status indicators.

Example:

(report {:state :pass})

test/reset-stats#

(reset-stats)

Resets the test statistics to their initial state. Call this before running a new batch of tests to get fresh results.

Example:

(reset-stats)

test/restore-stats#

(restore-stats saved)

Restores test statistics from a previously saved state.

Example:

(restore-stats saved)

test/run-tests#

(run-tests options & namespaces)

Runs all tests in the given namespaces.

Example:

(run-tests {} 'my-app	est)

test/successful?#

(successful?)

Checks if all tests passed.

Example:

(successful?) # => true

test/testing#

(testing context & body)

Adds a testing context string. Used inside deftest to describe a group of assertions. The context string is prepended to failure messages for better diagnostics.

Example:

(deftest test-math
  (testing "addition"
    (is (= 2 (+ 1 1)))))