Evaluate S-Expr with float output
S-expressions that output a float
- arg0
- arg1
- arg2
- arg3
- FLOAT
ComfyUI gives you plenty of single-operation math nodes, but when you need a compound formula - clamp this, scale that, add the two - you either chain five nodes or write a Python node. Eval Float Expr is the "write it once" option. You type a Lisp-style S-expression into the multiline expression input and get a FLOAT out.
S-expressions are just nested parentheses: (+ 1 2) is 1+2, (* 3 (+ 1 2)) is 9. The parser here (via the sexpdata library) evaluates them with a small set of operators that covers most workflow math:
+/add,-/sub,*/mul,//divint/floor(convert to integer),float(convert to float)up-boundandlow-bound- clamps. Note the argument order:(up-bound bnd value)returns the bound if the value exceeds it, otherwise the value.
The inputs that matter. Beyond the expression, there are four optional arg0 through arg3 inputs. These are the wildcard numeric slots - accept either an INT or a FLOAT - and they're referenced by name inside the expression. So you can wire a seed, a CFG value, or a denoise strength in from elsewhere in the graph and compute against them:
(low-bound 0.5 (up-bound 0.9 (* 2 arg0)))
That expression clamps 2 * arg0 to the range [0.5, 0.9] and hands the float downstream. The dynamic argument inputs borrow the pattern from Impact Pack's utility nodes, which is worth knowing - this is a small, honest implementation of a familiar idea.
Why you'd reach for it. Anything that wants a computed float - CFG, denoise, upscale factor, a strength that should scale with something else - where the intermediate math isn't worth a row of nodes. The up-bound/low-bound clamps are the standout: they're exactly the "don't let this slider go past 1.0" guard that normally needs two comparison nodes and a switch.
Gotchas:
- If the output type is FLOAT, the division
/returns a float; theint/flooroperator converts for you, but you'll want Eval Int Expr if your result feeds an integer input. - The operators are strict about argument counts:
subanddivtake exactly two arguments, and the evaluator asserts that.(sub 10 3 2)errors. - Unknown symbols are not auto-resolved -
arg0works because it's bound, butxin the expression raises a TypeError. Stick to literals and the arg slots. - No models, no memory, no side effects. It's a pure calculator, which is also why it's safe: nothing here touches your filesystem.
Install is the pack standard (Chaser's Custom Nodes, chaserhkj). ComfyUI Manager, search "Chaser's Custom Nodes", or:
cd ComfyUI/custom_nodes
git clone https://github.com/chaserhkj/ComfyUI-Chaser-nodes
then restart. No model downloads; the one notable dependency is sexpdata, which handles the parsing, plus the pack's usual jinja2/pyyaml/requests/av. The README's "use them at your own risk" framing applies to any personal node - for a well-tested little math evaluator, the risk is mostly that you'll write a Lisp expression wrong and wonder why the number looks odd.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| expression | STRING | — | |
| arg0opt | * | — | |
| arg1opt | * | — | |
| arg2opt | * | — | |
| arg3opt | * | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| FLOAT | FLOAT | — |