Search code examples
emacselispdestructuring

Is there an emacs lisp splat operator or another way of performing this type of operation?


I have an operator that operates on a list of variables like so:

(myfunc arg1 nil arg2 arg3)

I need to optionally (dependent on a boolean variable which we'll call my_bool) add an extra argument to this list so that the function call will look like this:

(myfunc arg1 nil arg2 added_argument arg3)

My first thought was to do this with an if block like so:

(myfunc arg1 nil arg2 (if mybool t nil) arg3)

but that will result in a nil if mybool is equal to nil which is not allowed by the function syntax.

My second thought was that maybe we could filter the list for nil and remove it, but we aren't able to because of the nil that occurs first (or rather I can't think of a way to, I'd be happy to be proven wrong, just looking for a solution).

My third thought was if we had a splat operator like Ruby's we could filter and then splat and all would be sorted out, so like so:

(myfunc arg1 nil (mysplat arg2 (filter (!= nil) (if mybool t nil)))) arg3)

but I haven't been able to find a splat operator (more technically a list destructuring operator) (P.S. the code above is approximate since it's a solution that doesn't work so I'm sure there .

So my problem is how to optionally add a single argument to a function call and not produce a nil as that argument if we do not.

Thanks in advance, sorry for my rookie emacs lisp skills :(.


Solution

  • You can use the splice operator ,@ inside backquotes:

    `(arg1 nil arg2 ,@(if my-bool (list added-argument) nil) arg3)
    

    That is, if my-bool is true, then splice the list created by (list added-argument) in the middle of the list, and otherwise splice in nil - which is the empty list, and therefore doesn't add any elements. See the Backquote section of the Emacs Lisp manual for more information.

    (And once you've created this list, it looks like you'll want to use apply to call myfunc with a variable number of arguments: (apply 'myfunc my-list))