help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

How to create a higher order function?


From: Marcin Borkowski
Subject: How to create a higher order function?
Date: Tue, 21 Sep 2021 06:10:50 +0200
User-agent: mu4e 1.1.0; emacs 28.0.50

Hi all,

assume that I want a function which "inverts" the meaning of a given
predicate.  Something that would turn `<' into `>=' etc.

Here's my first attempt (A):

--8<---------------cut here---------------start------------->8---
;;; -*- lexical-binding: nil; -*-
(defun negate (fun)
  "Try to return a function returning the logical opposite of FUN."
  (lambda (&rest args)
    (not (apply fun args))))
--8<---------------cut here---------------end--------------->8---

Of course, it doesn't work, since (under dynamic scope) it just creates
a function which uses a dynamic binding for `fun' (which is probably
nil).

So, here's a better (at least: working) version (B):

--8<---------------cut here---------------start------------->8---
;;; -*- lexical-binding: nil; -*-
(defun negate (fun)
  "Return a function returning the logical opposite of FUN."
  `(lambda (&rest args)
    (not (apply ,(symbol-function fun) args))))
--8<---------------cut here---------------end--------------->8---

It seems to work fine, even if it's a bit complicated.

Of course, the more obvious way to do it is to use the first definition
under lexical scope (C):

--8<---------------cut here---------------start------------->8---
;;; -*- lexical-binding: t; -*-
(defun negate (fun)
  "Try to return a function returning the logical opposite of FUN."
  (lambda (&rest args)
    (not (apply fun args))))
--8<---------------cut here---------------end--------------->8---

My question is: which of (B) and (C) is better?  (C) is definitely
simpler, and with lexical scope becoming the default (perhaps at some
point in time in the future) or the recommended (even now, I guess)
setting, is probably the way to go.  But maybe (B) is better under some
circumstances?  Is it faster?  (I don't think so, and my simple
benchmarks were inconclusive.)  Is it more memory-efficient?  (Could
be.)  Does it have any other advantage?

Disclaimer: I'd like to study the replies and put the answer on my blog
and in my book.  I'll give the credit where it's due, of course.

TIA,

--
Marcin Borkowski
http://mbork.pl



reply via email to

[Prev in Thread] Current Thread [Next in Thread]