Comment

Comment by mickeyp

But functional programming and OOP are intrinsically the same, but expressed using different primitives.

The thing that empowers first-class functions and closures (lexical binding) is the exact same method by which encapsulation works, even if the latter opts for heap vs stack. The fundamentals are the same.

Here's a simple one in Emacs Lisp:

    (defmacro send (object method &rest args)
      "Sends a METHOD to an OBJECT with ARGS."
      `(funcall ,object ',method ,@args))

    (defun make-animal (name)
      ;; 'hunger' is entirely private (encapsulated)
      (let ((hunger 5))
        ;; here's our lambda using lexical binding
        (lambda (method &rest args)
          (cond
           ((eq method 'get-name) name)
           ((eq method 'feed) 
            (setq hunger (max 0 (1- hunger)))
            "Yum!")
           (t (error "Animal does not understand: %s" method))))))

    (let ((good-boy (make-animal "Rex")))
      ;; "call" (via our macro) the "get-name" method; then feed. hunger does down 1.
      (send good-boy get-name)
      (send good-boy feed)
      ;; pretty-print the "object" good-boy
      (pp good-boy))

    ;; this is the state of it after the two calls.
    #[(method &rest args)
      ((cond ((eq method 'get-name) name)
             ((eq method 'feed) (setq hunger (max 0 (1- hunger))) "Yum!")
             (t (error "Animal does not understand: %s" method))))
      ((hunger . 4) (name . "Rex"))]
parent mickeyp 2 months ago

Discussion

Live from the official Hacker News API

A modern reader for Hacker News · SvelteKit + Skeleton