aimode.news
Published on

Adding dollar sign (apply) to nix

Authors

Adding dollar sign (apply) to nix

3 minutes read

This post is very low quality for comedic effect.

A detailed list of instructions

Take one nix, apply this patch[1]:

What does this do? It adds a new token $

to the nix languages parser and exposes it as __dollar

, essentially by copying the way this works for __lessThan

.

Hack on your nix:

nix develop

./bootstrap.sh

./configure $configureFlags --prefix=$(pwd)/outputs/out

make -j $NIX_BUILD_CORES

outputs/out/bin/nix repl

Now in the nix repl

that just opened:

nix-repl> __dollar = x: y: builtins.foldl' (a: b: a b) x y

This makes $

an infix operator that’s essentially just a generic apply.

Now just create a toy example to demonstrate:

nix-repl> concat = x: y: z: (x + y + z)

nix-repl> concat $ ["literally" " " "dollar sign"]

And your repl will say:

"literally dollar sign"

Tadaa! That’s all it takes to add the $

operator to nix, just like Haskell.

The end $\text{\(^ヮ^)/}$

↩diff --git a/src/libexpr/parser.y b/src/libexpr/parser.y index 201370b90..4b26af623 100644 %left AND %nonassoc EQ NEQ %nonassoc '<' '>' LEQ GEQ +%nonassoc '$' DOL %right UPDATE %left NOT %left '+' '-' | expr_op LEQ expr_op { $$ = new ExprOpNot(new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__lessThan")), {$3, $1})); } | expr_op '>' expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__lessThan")), {$3, $1}); } | expr_op GEQ expr_op { $$ = new ExprOpNot(new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__lessThan")), {$1, $3})); } + | expr_op '$' expr_op { $$ = new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__dollar")), {$1, $3}); } + | expr_op DOL expr_op { $$ = new ExprOpNot(new ExprCall(makeCurPos(@2, data), new ExprVar(data->symbols.create("__dollar")), {$3, $1})); } | expr_op AND expr_op { $$ = new ExprOpAnd(makeCurPos(@2, data), $1, $3); } | expr_op OR expr_op { $$ = new ExprOpOr(makeCurPos(@2, data), $1, $3); } | expr_op IMPL expr_op { $$ = new ExprOpImpl(makeCurPos(@2, data), $1, $3); } diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index ddf529b9e..00622a142 100644 .fun = prim_lessThan, }); +static void prim_dollar(EvalState & state, const PosIdx pos, Value * * args, Value & v) +{ + state.forceValue(*args[0], pos); + state.forceValue(*args[1], pos); + // pos is exact here, no need for a message. + CompareValues comp(state, noPos, ""); + v.mkBool(comp(args[0], args[1])); +} + +static RegisterPrimOp primop_dollar({ + .name = "__dollar", + .args = {"e1", "e2"}, + .doc = R"( + Just like haskell :) + )", + .fun = prim_dollar, +}); + /************************************************************* * String manipulation

Adding dollar sign (apply) to nix | aimode.news