Skip to content

Instantly share code, notes, and snippets.

@gsrai
Last active November 20, 2020 11:54
Show Gist options
  • Save gsrai/3946bf0acd0b67d722149368926ca76b to your computer and use it in GitHub Desktop.
Save gsrai/3946bf0acd0b67d722149368926ca76b to your computer and use it in GitHub Desktop.

Are decorators just higher order functions?

a HOF is just a function which takes a function as an argument. Alternatively, it’s a function which returns a new function. In both cases it’s a higher-order function. There is another case when you define a function which returns a function. This could be a middleware in Clojure’s Ring or a Python decorator:

def my_decorator(func):
    def wrapper():
        print("Something is happening before the function is called.")
        func()
        print("Something is happening after the function is called.")
    return wrapper

@my_decorator
def say_whee():
    print("Whee!")

def do_twice(func):
    def wrapper_do_twice(*args, **kwargs):
        func(*args, **kwargs)
        func(*args, **kwargs)
    return wrapper_do_twice

@do_twice
def greet(name):
    print(f"Hello {name}")

say_whee()
greet("World")
(defn some-hof [func]
	(fn []
		(println "Something is happening before the function is called.")
		(func)
		(println "Something is happening after the function is called.")))

(defn do-twice [func]
	(fn [& args]
		(apply func args)
		(apply func args)))

(defn say-whee []
	(println "Whee!"))

((some-hof say-whee))
((do-twice say-whee))
((->> say-whee do-twice some-hof))

I would argue that higher order functions are better as it doesn't mutate the original function, e.g. wrapping say-whee with two decorators rather than composing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment