diff --git a/common.scad b/common.scad
index 653e900..4ca337e 100644
--- a/common.scad
+++ b/common.scad
@@ -312,38 +312,67 @@ function get_height(h=undef,l=undef,height=undef,dflt=undef) =
     assert(num_defined([h,l,height])<=1,"You must specify only one of `l`, `h`, and `height`")
     first_defined([h,l,height,dflt]);
 
-// Function: get_named_args(positional, named, _undef)
+// Function: get_named_args()
 // Usage:
 //   function f(pos1=_undef, pos2=_undef,...,named1=_undef, named2=_undef, ...) = let(args = get_named_args([pos1, pos2, ...], [[named1, default1], [named2, default2], ...]), named1=args[0], named2=args[1], ...)
 // Description:
 //   Given the values of some positional and named arguments,
-//   returns a list of the values assigned to named arguments,
-//   in the following way:
-//    - All named arguments which were explicitly assigned in the
-//    function call take the value provided.
-//    - All named arguments which were not provided by the user are
-//    affected from positional arguments; the priority order in which
-//    these are assigned is given by the `priority` argument, while the
-//    positional assignation is done in the order of the named arguments.
-//    - Any remaining named arguments take the provided default values.
-//  If only k positional arguments are used, then the k named values
-//  with lowest 'priority' value (among the unassigned ones) will get them.
-//  The arguments will be assigned in the order of the named values.
-//  By default these two orders coincide.
+//   returns a list of the values assigned to named parameters.
+//   in the following steps:
+//   - First, all named parameters which were explicitly assigned in the
+//      function call take their provided value.
+//   - Then, any positional arguments are assigned to remaining unassigned
+//     parameters; this is governed both by the `priority` entries
+//     (if there are `N` positional arguments, then the `N` parameters with
+//     lowest `priority` value will be assigned) and by the order of the
+//     positional arguments (matching that of the assigned named parameters).
+//     If no priority is given, then these two ordering coincide:
+//     parameters are assigned in order, starting from the first one.
+//   - Finally, any remaining named parameters can take default values.
+//     If no default values are given, then `undef` is used.
+//   .
+//   This allows an author to declare a function prototype with named or
+//   optional parameters, so that the user may then call this function
+//   using either positional or named parameters. In practice the author
+//   will declare the function as using *both* positional and named
+//   parameters, and let `get_named_args()` do the parsing from the whole
+//   set of arguments.
+//   See the example below.
+//   .
+//   This supports the user explicitly passing `undef` as a function argument.
+//   To distinguish between an intentional `undef` and
+//   the absence of an argument, we use a custom `_undef` value
+//   as a guard marking the absence of any arguments
+//   (in practice, `_undef` is a random-generated string,
+//   which will never coincide with any useful user value).
+//   This forces the author to declare all the function parameters
+//   as having `_undef` as their default value.
 // Arguments:
 //   positional = the list of values of positional arguments.
-//   named = the list of named arguments; each entry of the list has the form [passed-value, default-value, priority], where passed-value is the value that was passed at function call; default-value is the value that will be used if nothing is read from either named or positional arguments; priority is the priority assigned to this argument.
-//   _undef = the default value used by the calling function for all arguments (default is some random string that you will never use). (this is *not* undef, or any value that the user might purposely want to use as an argument value).
+//   named = the list of named arguments; each entry of the list has the form `[passed-value, <default-value>, <priority>]`, where `passed-value` is the value that was passed at function call; `default-value` is the value that will be used if nothing is read from either named or positional arguments; `priority` is the priority assigned to this argument (lower means more priority, default value is `+inf`). Since stable sorting is used, if no priority at all is given, all arguments will be read in order.
+//   _undef = the default value used by the calling function for all arguments. The default value, `_undef`, is a random string. This value **must** be the default value of all parameters in the outer function call (see example below).
 //
-//
-//
-// Examples:
-//   function f(arg1=_undef, arg2=_undef, arg3=_undef, named1=_undef, named2=_undef, named3=_undef) = let(named = get_named_args([arg1, arg2, arg3], [[named1, "default1"], [named2, "default2"], [named3, "default3"]])) named;
-//   echo(f()); // ["default1", "default2", "default3"]
-//   echo(f("given2", "given3", named1="given1")); // ["given1", "given2", "given3"]
-//   echo(f("given1")); // ["given1", "default2", "default3"]
-//   echo(f(named1="given1", "given2")); // ["given1", "given2", "default3"]
-//   echo(f(undef, named1="given1", undef)); // ["given1", undef, undef]
+// Example: a function with prototype `f(named1,< <named2>, named3 >)`
+//   function f(_p1=_undef, _p2=_undef, _p3=_undef,
+//              arg1=_undef, arg2=_undef, arg3=_undef) =
+//      let(named = get_named_args([_p1, _p2, _p3],
+//          [[arg1, "default1",0], [arg2, "default2",2], [arg3, "default3",1]]))
+//      named;
+//   // all default values or all parameters provided:
+//   echo(f());
+//   // ["default1", "default2", "default3"]
+//   echo(f("given2", "given3", arg1="given1"));
+//   // ["given1", "given2", "given3"]
+//   
+//   // arg1 has highest priority, and arg3 is higher than arg2:
+//   echo(f("given1"));
+//   // ["given1", "default2", "default3"]
+//   echo(f("given3", arg1="given1"));
+//   // ["given1", "default2", "given3"]
+//   
+//   // explicitly passing undef is allowed:
+//   echo(f(undef, arg1="given1", undef));
+//   // ["given1", undef, undef]
 
 // a value that the user should never enter randomly;
 // result of `dd if=/dev/random bs=32 count=1 |base64` :
@@ -366,7 +395,8 @@ function get_named_args(positional, named,_undef=_undef) =
         // those elements which have no priority assigned go last (prio=+∞):
         prio = sortidx([for(u=unknown) default(named[u][2], 1/0)]),
         // list of indices of values assigned from positional arguments:
-        assigned = sort([for(i=[0:1:n_positional-1]) prio[i]]))
+        assigned = [for(a=sort([for(i=[0:1:n_positional-1]) prio[i]]))
+          unknown[a]])
     [ for(e = enumerate(named))
       let(idx=e[0], val=e[1][0], ass=search(idx, assigned))
         val != _undef ? val :
diff --git a/mutators.scad b/mutators.scad
index 46b05e8..f704bdc 100644
--- a/mutators.scad
+++ b/mutators.scad
@@ -67,17 +67,17 @@ module bounding_box(excess=0) {
 // Function&Module: half_of()
 //
 // Usage: as module
-//   half_of(v, [cp], [s]) ...
+//   half_of(v, <cp>, <s>) ...
 // Usage: as function
-//   half_of(v, [cp], p, [s])...
+//   half_of(v, <cp>, p, <s>)...
 //
 // Description:
 //   Slices an object at a cut plane, and masks away everything that is on one side.
 //   * Called as a function with a path in the `p` argument, returns the
-//   intersection of path `p` and given half-space.
+//       intersection of path `p` and given half-space.
 //   * Called as a function with a 2D path in the `p` argument
-//   and a 2D vector `p`, returns the intersection of path `p` and given
-//   half-plane.
+//       and a 2D vector `p`, returns the intersection of path `p` and given
+//       half-plane.
 //
 // Arguments:
 //   v = Normal of plane to slice at.  Keeps everything on the side the normal points to.  Default: [0,0,1] (UP)
@@ -121,7 +121,7 @@ module half_of(v=UP, cp, s=1000, planar=false)
 function half_of(_arg1=_undef, _arg2=_undef, _arg3=_undef, _arg4=_undef,
     v=_undef, cp=_undef, p=_undef, s=_undef) =
     let(args=get_named_args([_arg1, _arg2, _arg3, _arg4],
-        [[v,undef,0], [cp,0,2], [p,undef,1], [s,1e4,3]]),
+        [[v,undef,0], [cp,0,2], [p,undef,1], [s, 1e4]]),
         v=args[0], cp0=args[1], p=args[2], s=args[3],
         cp = is_num(cp0) ? cp0*unit(v) : cp0)
     assert(is_vector(v,2)||is_vector(v,3),
@@ -160,12 +160,12 @@ function half_of(_arg1=_undef, _arg2=_undef, _arg3=_undef, _arg4=_undef,
 // Function&Module: left_half()
 //
 // Usage: as module
-//   left_half([s], [x]) ...
-//   left_half(planar=true, [s], [x]) ...
+//   left_half(<s>, <x>) ...
+//   left_half(planar=true, <s>, <x>) ...
 // Usage: as function
-//   left_half([s], [x], path)
-//   left_half([s], [x], region)
-//   left_half([s], [x], vnf)
+//   left_half(<s>, <x>, path)
+//   left_half(<s>, <x>, region)
+//   left_half(<s>, <x>, vnf)
 //
 // Description:
 //   Slices an object at a vertical Y-Z cut plane, and masks away everything that is right of it.
@@ -197,7 +197,7 @@ module left_half(s=1000, x=0, planar=false)
 function left_half(_arg1=_undef, _arg2=_undef, _arg3=_undef,
     x=_undef, p=_undef, s=_undef) =
     let(args=get_named_args([_arg1, _arg2, _arg3],
-    [[x, 0,1], [p,undef,0], [s, 1e4,2]]),
+    [[x, 0,1], [p,undef,0], [s, 1e4]]),
         x=args[0], p=args[1], s=args[2])
     half_of(v=[1,0,0], cp=x, p=p);
 
@@ -209,6 +209,7 @@ function left_half(_arg1=_undef, _arg2=_undef, _arg3=_undef,
 //   right_half([s], [x]) ...
 //   right_half(planar=true, [s], [x]) ...
 //
+//
 // Description:
 //   Slices an object at a vertical Y-Z cut plane, and masks away everything that is left of it.
 //
@@ -239,7 +240,7 @@ module right_half(s=1000, x=0, planar=false)
 function right_half(_arg1=_undef, _arg2=_undef, _arg3=_undef,
     x=_undef, p=_undef, s=_undef) =
     let(args=get_named_args([_arg1, _arg2, _arg3],
-    [[x, 0,1], [p,undef,0], [s, 1e4,2]]),
+    [[x, 0,1], [p,undef,0], [s, 1e4]]),
         x=args[0], p=args[1], s=args[2])
     half_of(v=[-1,0,0], cp=x, p=p);
 
@@ -281,7 +282,7 @@ module front_half(s=1000, y=0, planar=false)
 function front_half(_arg1=_undef, _arg2=_undef, _arg3=_undef,
     x=_undef, p=_undef, s=_undef) =
     let(args=get_named_args([_arg1, _arg2, _arg3],
-    [[x, 0,1], [p,undef,0], [s, 1e4,2]]),
+    [[x, 0,1], [p,undef,0], [s, 1e4]]),
         x=args[0], p=args[1], s=args[2])
     half_of(v=[0,1,0], cp=x, p=p);
 
@@ -323,7 +324,7 @@ module back_half(s=1000, y=0, planar=false)
 function back_half(_arg1=_undef, _arg2=_undef, _arg3=_undef,
     x=_undef, p=_undef, s=_undef) =
     let(args=get_named_args([_arg1, _arg2, _arg3],
-    [[x, 0,1], [p,undef,0], [s, 1e4,2]]),
+    [[x, 0,1], [p,undef,0], [s, 1e4]]),
         x=args[0], p=args[1], s=args[2])
     half_of(v=[0,-1,0], cp=x, p=p);
 
@@ -357,7 +358,7 @@ module bottom_half(s=1000, z=0)
 function right_half(_arg1=_undef, _arg2=_undef, _arg3=_undef,
     x=_undef, p=_undef, s=_undef) =
     let(args=get_named_args([_arg1, _arg2, _arg3],
-    [[x, 0,1], [p,undef,0], [s, 1e4,2]]),
+    [[x, 0,1], [p,undef,0], [s, 1e4]]),
         x=args[0], p=args[1], s=args[2])
     half_of(v=[0,0,-1], cp=x, p=p);
 
@@ -391,7 +392,7 @@ module top_half(s=1000, z=0)
 function right_half(_arg1=_undef, _arg2=_undef, _arg3=_undef,
     x=_undef, p=_undef, s=_undef) =
     let(args=get_named_args([_arg1, _arg2, _arg3],
-    [[x, 0,1], [p,undef,0], [s, 1e4,2]]),
+    [[x, 0,1], [p,undef,0], [s, 1e4]]),
         x=args[0], p=args[1], s=args[2])
     half_of(v=[0,0,1], cp=x, p=p);
 
diff --git a/vnf.scad b/vnf.scad
index 95396f5..a75a36c 100644
--- a/vnf.scad
+++ b/vnf.scad
@@ -829,14 +829,14 @@ module vnf_validate(vnf, size=1, show_warns=true, check_isects=false) {
 
 // Section: VNF transformations
 //
+
 // Function: vnf_halfspace(halfspace, vnf)
 // Usage:
 //   vnf_halfspace([a,b,c,d], vnf)
 // Description:
 //   returns the intersection of the VNF with the given half-space.
 // Arguments:
-//   halfspace = half-space to intersect with, given as the four
-//   coefficients of the affine inequation a*x+b*y+c*z+d ≥ 0.
+//   halfspace = half-space to intersect with, given as the four coefficients of the affine inequation a\*x+b\*y+c\*z≥ d.
 
 function _vnf_halfspace_pts(halfspace, points, faces,
   inside=undef, coords=[], map=[]) =
@@ -861,7 +861,7 @@ function _vnf_halfspace_pts(halfspace, points, faces,
     // termination test:
     i >= len(points) ? [ coords, map, inside ] :
     let(inside = !is_undef(inside) ? inside :
-        [for(x=points) halfspace*concat(x,[1]) >= 0],
+        [for(x=points) halfspace*concat(x,[-1]) >= 0],
         pi = points[i])
     // inside half-space: keep the point (and reindex)
     inside[i] ? _vnf_halfspace_pts(halfspace, points, faces, inside,
@@ -871,10 +871,10 @@ function _vnf_halfspace_pts(halfspace, points, faces,
       each if(j!=undef) [f[(j+1)%m], f[(j+m-1)%m]] ]),
     // filter those which lie in half-space:
         adj2 = [for(x=adj) if(inside[x]) x],
-        zi = halfspace*concat(pi, [1]))
+        zi = halfspace*concat(pi, [-1]))
     _vnf_halfspace_pts(halfspace, points, faces, inside,
         // new points: we append all these intersection points
-        concat(coords, [for(j=adj2) let(zj=halfspace*concat(points[j],[1]))
+        concat(coords, [for(j=adj2) let(zj=halfspace*concat(points[j],[-1]))
             (zi*points[j]-zj*pi)/(zi-zj)]),
         // map: we add the info
         concat(map, [[for(y=enumerate(adj2)) [y[1], n+y[0]]]]));
@@ -950,7 +950,4 @@ function vnf_halfspace(_arg1=_undef, _arg2=_undef,
         loops=[for(p=paths) if(p[0] == last(p)) p])
     [coords, concat(newfaces, loops)];
 
-//
-//
 // vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
-//