Function: majutsu-template--apply-lambda

majutsu-template--apply-lambda is a natively compiled function defined in majutsu-template.el.

Signature

(majutsu-template--apply-lambda LAMBDA-NODE ARG-NODES)

Documentation

Apply LAMBDA-NODE to ARG-NODES by compile-time substitution.

Source Code

;; Defined in /nix/store/jagqw3nms546pad0gxi5f3wsckk6pji7-emacs-packages-deps/share/emacs/site-lisp/majutsu-template.el
(defun majutsu-template--apply-lambda (lambda-node arg-nodes)
  "Apply LAMBDA-NODE to ARG-NODES by compile-time substitution."
  (let ((params (majutsu-template--lambda-params lambda-node)))
    (unless (= (length params) (length arg-nodes))
      (user-error "majutsu-template: lambda expects %d arguments, got %d"
                  (length params) (length arg-nodes)))
    (when-let* ((expected-types (majutsu-template--type-ref-lambda-arg-types
                                 (majutsu-template-node-type lambda-node))))
      (cl-loop for expected in expected-types
               for arg in arg-nodes
               do (unless (majutsu-template--node-satisfies-type-p arg expected)
                    (user-error "majutsu-template: lambda expects %S, got %S"
                                expected (majutsu-template-node-type arg)))))
    (if-let* ((body-form (plist-get (majutsu-template-node-props lambda-node) :body-form)))
        (let* ((arg-type (and (= (length arg-nodes) 1)
                              (majutsu-template-node-type (car arg-nodes))))
               (specialized (and arg-type
                                 (majutsu-template--specialize-lambda-node lambda-node arg-type)))
               (specialized-body-form (and specialized
                                           (plist-get (majutsu-template-node-props specialized) :body-form))))
          (if specialized-body-form
              (let* ((self-type (car (or (majutsu-template--type-ref-lambda-arg-types
                                          (majutsu-template-node-type specialized))
                                         '(Unknown))))
                     (self-type (unless (memq (majutsu-template--type-ref-base-type self-type)
                                              '(Unknown Template))
                                  self-type))
                     (bindings (cl-mapcar (lambda (param arg)
                                            (majutsu-template--make-binding
                                             :name param
                                             :type (majutsu-template-node-type arg)
                                             :node arg))
                                          params arg-nodes)))
                (majutsu-template--call-with-lambda-capture
                 specialized
                 (lambda ()
                   (majutsu-template--call-with-bindings
                    bindings
                    (lambda ()
                      (majutsu-template--call-with-self-binding
                       (car arg-nodes)
                       self-type
                       (lambda ()
                         (majutsu-template--sugar-transform specialized-body-form))))))))
            (cl-loop with result = (majutsu-template--lambda-body lambda-node)
                     for param in params
                     for arg in arg-nodes
                     do (setq result (majutsu-template--substitute-var result param arg))
                     finally return result)))
      (cl-loop with result = (majutsu-template--lambda-body lambda-node)
               for param in params
               for arg in arg-nodes
               do (setq result (majutsu-template--substitute-var result param arg))
               finally return result))))