Skip to content

Instantly share code, notes, and snippets.

@nubunto
Last active August 29, 2015 13:56
Show Gist options
  • Select an option

  • Save nubunto/9061440 to your computer and use it in GitHub Desktop.

Select an option

Save nubunto/9061440 to your computer and use it in GitHub Desktop.
A simple demonstration of why Lisp languages are AWESOME!
;; Let's assume you are coming from Javascript and wants to mess with Clojure.
;; In clojure, we can define functions and stuff in two ways: using the "def" function:
(def foo (fn [x] (* x 2)))
;; It assigns an anonymous function (the part after "fn") to the name "foo". This function is simple
;; and only multiplies it's argument by 2.
;; Or, you can use defn, like this:
(defn foo [x] (* x 2))
;; which is a macro (interesting subject) that expands to exactly that call above to "def".
;; but, you come from Javascript, and you believe "fn" and "defn" are not as succint as "function".
;; well, here comes the power! Macros let you get a hook on the compiler, and manipulate
;; code as data. That means that you can create your own syntax and extend the language
;; in order to abstract your thoughts and make things more readable.
;; So, you want this:
(def foo (function [x] (* x 2)))
;; to become this:
(def foo (fn [x] (* x 2)))
;; and this:
(function* foo [x] (* x 2))
;; to become this:
(defn foo [x] (* x 2))
;; and behold, it is possible:
;; we define a macro that receives the args (an vector) and the body (lists)
;; the backtick correctly builds up a list, which is the return of the macro,
;; and defines a function with "fn". In the backtick, arguments are not evaluated,
;; so we need to tell Clojure to evaluate things with the tilder.
;; The ~@ part breaks up the lists and evaluates them.
(defmacro function [args & body]
`(fn ~args ~@body))
(defmacro function* [name args & body]
`(def ~name (function ~args ~@body)))
;; code templates just... fucking rule!
;; now, just "function" up everything!
((function bar [vect] (map #(* % %) vect)) [2 4 6])
;; or, the equivalent to a function declaration:
(function* this-is-the-name [lst] (first lst))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment