Help me refactoring following funcion. It was growing and growing, and now I can barely navigate across it.
(defun merge-lambs (name ls)
(let* ((a (unisym))
(ms (make-hash-table :test 'equal)) ; methods
(mm nil) ; multimethod
(vars nil) ; object variables
(w (unisym)) ; wild
(wild nil)
(h (unisym))
(init (unisym))
(vs nil)
(close (has-arrow? (rhd ls)))
(used-vars (make-hash-table :test 'equal))
)
(unless close (setf name nil))
($map (fn (l)
(setf l ($split #'arrow? l))
(when (> (len l) 1)
(setf l (lst (1st l)
(fold (2nd l)
(fn (a b) (st ($$a $"|" $$b)))
(drop 2 l)))))
(if (< (len l) 2)
(let ((x (lhd l)))
(setf l (if (equal (2nd x) ":")
(st ($(lhd x) $(drop 2 x)))
(st ($nil $x))))
(let ((x (lhd l)))
(cond ((stringp x)
(if (gethash x used-vars)
(error "redeclaration of `~a`" X)
(setf (gethash x used-vars) t)))
((unesc? x) (setf l (st ($nil $(expand-set (2nd x) (2nd l))))))
))
(setf (gethash "Var" ms) (st ($$(gethash "Var" ms) $l)))
)
(let* ((l (st ($(lhd l) (_ do $$(ltl l)))))
(hd (lhd (lhd l)))
(n hd))
(if (fn-sym? hd)
(setf l (st ($(ltl (lhd l)) $$(ltl l))))
(setf n "?"))
(setf l (st ((|[]| $(lhd l)) $$(ltl l))))
(setf (gethash n ms) (st ($l $$(gethash n ms)))))
)
nil)
ls)
(setf vars (gethash "Var" ms))
(remhash "Var" ms)
(maphash (fn (hd ls)
;;(setf ls (rev ls))
(let* ((x (chain-lambs a ls nil))
(*checked-lst-method* (if (string= hd "?") nil hd))
(y (when *checked-lst-method*
(chain-lambs a ls nil))))
(setf (gethash hd ms) (cons x y))))
ms)
(setf wild (car (gethash "?" ms)))
(remhash "?" ms)
(maphash (fn (k v) (setf vs (st (($k $(cdr v) (_ fn ($a) $(car v))) $$vs))))
ms)
(setf mm (if (= (hash-table-count ms) 0)
wild
(st (_ let (($w (_ fn () $wild)) ($h (_ host (aref $a 0))))
(_ if (_ host (stringp $h))
$(search-method h ($map #'rtl vs) (st (_ host (topject (|@| $name) $a))))
(_ host (funcall $w)))))))
(when name (setf mm (st (_ host (block $name ($"@" $mm))))))
(setf mm (st (_ fn ($a) $mm)))
(when name (setf mm (st (_ name $name $mm))))
(when vars
(let ((vi (st (_ do $$($map (fn (v) (if (1st v)
(st (_ set $$v))
(2nd v)))
vars)))))
(setf mm (if close
(st (_ do (_ set $init (_ fn $(when name (lst name))
$vi))
$mm))
vi))))
(unless (= (hash-table-count ms) 0)
(setf mm (st (_ let ($$($map (fn (v) (lst (lhd v) nil)) vs))
(_ do $$($map (fn (v) (st (_ set $(1st v) $(3rd v)))) vs)
$mm)))))
(let ((vars (keep #'1st vars)))
(when vars
(setf mm (st (_ let $($map (fn (v) (st ($(1st v) n))) vars)
$mm)))))
(when name
(setf mm (st (_ let (($name $nil))
(_ do (_ set $name $mm)
$name)))))
(when (and vars close)
;; generate call to init closure
(let ((tmp (unisym)))
(setf mm (st (_ let (($init $nil))
(_ let (($tmp $mm))
(_ do (_ host (funcall $init $$(when name (lst tmp))))
$tmp)))))))
mm))
Name:
Anonymous2013-03-22 19:19
what the fuck does it even do
Name:
Anonymous2013-03-22 19:22
>>2
it combines several defun into one pattern-matching multimethod, which also acts as an object, while topject is a default `sink` object, where all unhandled defuns go.
Lisp | Haskell
-------------------------------|------------------------------------
map - '(1 2 3 4 5) | map (-) [1,2,3,4,5,6]
(-1 -2 -3 -4 -5) | No instance for (Show (a -> a))
| arising from a use of `print'
|
map - | map negate
invalid number of arguments: 1 | No instance for (Show ([a] -> [a]))
Backtrace: | arising from a use of `print'
0: (map #<function>) |
1: (eval '(map -)) |
>>29 http://www.haskell.org/haskellwiki/Show_instance_for_functions
... It doesn't answer the question of why it can't at least show the type of the function (e.g. Num a => a -> a)...
Actually, import Data.Typeable
instance (Show x, Show a, Typeable x, Typeable a) => Show (x -> a) where
show = ("<function> :: " ++) . show . typeOf
>>22 >>20 specifically mentioned sbcl, and defining a non-standard map in CL (or any LISP intended for real work, unlike Scheme) is just asking for problems.
Name:
Anonymous2013-03-22 23:21
>>22
And message-passing achieves very succinct syntax, like for example a list delegating all unhandled messages to its elements. So Xs+1 can add 1 to every element of the, either consing or destructively.
Name:
Anonymous2013-03-22 23:25
>>25
Nope. Map is overused function, so defining it like (defmacro m (xs as &body body) `(mapcar (lambda ,as ,@body) ,xs)) can safe you a lot of typing
>>44
That was pretty bad. It's also how /prog/ was at the very beginning, looking way back in the post list. It was awful. Namedropping everywhere and questions answered in the third paragraph of the programming tutorial they aren't actually reading.
>>47
>le /e/gin implyin/g/ /G/ROSENBER/G/ XDDDDDDDDDDDDDD LE /G/ENTOO FACE
Name:
Anonymous2013-03-23 12:41
>>13 LISP code was supposed to be more concise and used more small functions that did one thing
Actually, no. Lisp allows easily fitting whole program into a single function, which is near impossible in C/C++/Java. Just consider LABELS macro, which acts as a local toplevel.
>>50 Common Lisp is designed with that in mind. Other Lisps are more rigid, and while not disallowing anything completely, force your hand towards functional style, like Scheme and (furthermore) Clojure.
>>44
Well thanks, but /g/ is certainly not what i am looking for.
Name:
Anonymous2013-03-23 17:35
I only know scheme, so I don't understand shit of what it does. But why don't you start chopping the deeper branches of your code into their own definitions and think up names for them? That would give somewhat more clearity.
Name:
Anonymous2013-03-23 17:40
Wtf is this for demon code:
; setf! - a polymorphic generic setter
(define-macro (setf! F V)
; symbol->string chopping off a trailing -ref if any
(define (-ref-less sym)
(let* ((str (symbol->string sym)) (suffix "-ref")
(s-pos (- (string-length str) (string-length suffix))))
(if (negative? s-pos) str
(let loop ((i 0))
(cond
((>= i (string-length suffix)) (substring str 0 s-pos))
((char=? (string-ref suffix i) (string-ref str (+ i s-pos)))
(loop (+ 1 i)))
(else str))))))