Author Topic: Well tested common functions library - should we have it?  (Read 16519 times)

0 Members and 1 Guest are viewing this topic.

divtiply

  • Guest
Well tested common functions library - should we have it?
« on: December 06, 2013, 08:53:31 AM »
Whe are reinventing the wheel, again and again. It's not bad - we are learning.
The bad is that some of common functions are implemented wrongly or not time effective.
For example, ymg's ceil/floor functions [http://www.theswamp.org/index.php?topic=45379.msg505421#msg505421]:

Code - Auto/Visual Lisp: [Select]
  1. ;; Ceiling function, Returns the smallest integer not less than x.            ;
  2. (defun ceil (x) (if (minusp x)(fix x)(1+ (fix x))))
  3. ;; Floor function, Returns the largest integer not greater than x.            ;
  4. (defun floor (x) (if (minusp x)(1- (fix x))(fix x)))

are little bit wrong, because:
Code - Auto/Visual Lisp: [Select]
  1. (ceil 1) => 2
  2. (floor -1) => -2

Correct implementation is:

Code - Auto/Visual Lisp: [Select]
  1. (defun floor (num)
  2.   (if (zerop (- num (setq num (fix num))))
  3.     num
  4.     (if (minusp num) (1- num) num)))
  5.  
  6. (defun ceiling (num)
  7.   (if (zerop (- num (setq num (fix num))))
  8.     num
  9.     (if (minusp num) num (1+ num))))

So, should we make a library with a well tested, speed effective functions?

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: Well tested common functions library - should we have it?
« Reply #1 on: December 06, 2013, 09:06:04 AM »
So, should we make a library with a well tested, speed effective functions?

http://autocad.xarch.at/stdlib/html/

 :-)

divtiply

  • Guest
Re: Well tested common functions library - should we have it?
« Reply #2 on: December 06, 2013, 09:09:56 AM »
http://autocad.xarch.at/stdlib/html/

Same as ymg's implementation error in std-floor/std-ceiling.
So it is not well tested ;)))

LE3

  • Guest
Re: Well tested common functions library - should we have it?
« Reply #3 on: December 06, 2013, 09:21:21 AM »
An ex-lisper comment:

In all my past years spent (20+-) in the autolisp/vlisp world --- the only way or form I have seen to adopt a function as standard it is when these are added into the autolisp core. Anything out it will be way too difficult - will only be part of anyone's personal functions arsenal. Have seen so many try-outs -- ALL have failed.

Let see if this time not.


LE!

divtiply

  • Guest
Re: Well tested common functions library - should we have it?
« Reply #4 on: December 06, 2013, 09:25:22 AM »
I'll give you a bit, tell me should I continue?

Code - Auto/Visual Lisp: [Select]
  1.   (setq consp vl-consp)
  2.   (defun consp (obj)
  3.     (not (atom obj))))
  4.  
  5. (defun dotted-pair-p (obj)
  6.   (and (consp obj) (not (listp (cdr obj)))))
  7.  
  8. (if vl-list-length
  9.   (defun dotted-list-p (obj)
  10.     (and (consp obj)
  11.          (not (vl-list-length obj))))
  12.   (defun dotted-list-p (obj)
  13.     (and (consp obj)
  14.          (dotted-pair-p (last-pair obj)))))
  15.  
  16. (defun association-list-p (obj)
  17.   (and (consp obj)
  18.        (every 'consp obj)))
  19.  
  20. (setq first   (cond (vle-nth0)(car))
  21.       second  (cond (vle-nth1)(cadr))
  22.       third   (cond (vle-nth2)(caddr))
  23.       fourth  (cond (vle-nth3)(cadddr))
  24.       fifth   (cond (vle-nth4)((lambda (list) (car (cddddr list)))))
  25.       sixth   (cond (vle-nth5)((lambda (list) (cadr (cddddr list)))))
  26.       seventh (cond (vle-nth6)((lambda (list) (caddr (cddddr list)))))
  27.       eighth  (cond (vle-nth7)((lambda (list) (cadddr (cddddr list)))))
  28.       ninth   (cond (vle-nth8)((lambda (list) (car (cddddr (cddddr list))))))
  29.       tenth   (cond (vle-nth9)((lambda (list) (cadr (cddddr (cddddr list))))))
  30.       rest    cdr)
  31.  
  32. (if vle-sublist
  33.   (defun nthcdr (n lst)
  34.     (vle-sublist lst n 0))
  35.   (defun nthcdr (n lst)
  36.     (nth n (list nil)) ; parameter validation
  37.     (while (and lst (not (zerop n)))
  38.       (setq n (1- n)
  39.             lst (cdr lst)))
  40.     lst))
  41.  
  42. (if vle-sublist
  43.   (defun firstn (n lst)
  44.     (vle-sublist lst 0 n))
  45.   (defun firstn (n lst / out)
  46.     (nth n (list nil)) ; parameter validation
  47.     (while (and lst (not (zerop n)))
  48.       (setq n (1- n)
  49.             out (cons (car lst) out)
  50.             lst (cdr lst)))
  51.     (reverse out)))
  52.  
  53. (if vle-sublist
  54.   (defun lastn (n lst)
  55.     (vle-sublist lst (- (length lst) n) 0))
  56.   (defun lastn (n lst / out)
  57.     (nth n (list nil)) ; parameter validation
  58.     (setq lst (reverse lst))
  59.     (while (and lst (not (zerop n)))
  60.       (setq n (1- n)
  61.             out (cons (car lst) out)
  62.             lst (cdr lst)))
  63.     out))
  64.  
  65. (defun last-pair (lst)
  66.   (while (consp (cdr lst))
  67.     (setq lst (cdr lst)))
  68.   lst)
  69.  
  70. (if vle-remove-last
  71.   (setq butlast vle-remove-last)
  72.   (defun butlast (lst)
  73.     (reverse (cdr (reverse lst)))))
  74.  
  75. (if vle-sublist
  76.   (defun butlastn (n lst)
  77.     (vle-sublist lst 0 (- (length lst) n)))
  78.   (defun butlastn (n lst)
  79.     (reverse (nthcdr n (reverse lst)))))
  80.  
  81. (defun ldiff (lst sublst / out)
  82.   (while (and lst (not (eq lst sublst)))
  83.     (setq out (cons (car lst) out)
  84.           lst (cdr lst)))
  85.   (reverse out))
  86.  
  87. (if vle-sublist
  88.   (setq sublist vle-sublist)
  89.   (defun sublist (lst start len)
  90.     (firstn len (nthcdr start lst))))
  91.  
  92. (if vle-sublist
  93.   (defun split-at (n lst)
  94.     (cons (vle-sublist lst 0 n) (vle-sublist lst n 0)))
  95.   (defun split-at (n lst / out)
  96.     (nth n (list nil)) ; parameter validation
  97.     (while (and lst (not (zerop n)))
  98.       (setq n (1- n)
  99.             out (cons (car lst) out)
  100.             lst (cdr lst)))
  101.     (cons (reverse out) lst)))
  102.  
  103. (defun split-at-first (item lst / out)
  104.   (while (and lst (not (equal item (car lst))))
  105.     (setq out (cons (car lst) out)
  106.           lst (cdr lst)))
  107.   (cons (reverse out) lst))
  108.  
  109. (defun split-at-last (item lst / out1 out2)
  110.   (setq out1 (reverse lst))
  111.   (while (and out1 (not (equal item (car out1))))
  112.     (setq out2 (cons (car out1) out2)
  113.           out1 (cdr out1)))
  114.   (if out1
  115.     (cons (reverse (cdr out1)) (cons (car out1) out2))
  116.     (list lst)))
  117.  
  118. (defun split-if (pred lst / out)
  119.   (while (and lst (not (apply pred (list (car lst)))))
  120.     (setq out (cons (car lst) out)
  121.           lst (cdr lst)))
  122.   (cons (reverse out) lst))
  123.  
  124. (defun split-if-not (pred lst / out)
  125.   (while (and lst (apply pred (list (car lst))))
  126.     (setq out (cons (car lst) out)
  127.           lst (cdr lst)))
  128.   (cons (reverse out) lst))
  129.  
  130. (defun partition (pred lst / out1 out2)
  131.   (foreach x lst
  132.     (if (apply pred (list x))
  133.       (setq out1 (cons x out1))
  134.       (setq out2 (cons x out2))))
  135.   (cons (reverse out1) (reverse out2)))
  136.  
  137. (if vl-list-length
  138.   (setq list-length vl-list-length)
  139.   (defun list-length (lst / len)
  140.     (setq len 0)
  141.     (while (and lst (listp (setq lst (cdr lst))))
  142.       (setq len (1+ len)))
  143.     (if (null lst) len)))
  144.  
  145. (defun revappend (lst obj)
  146.   (while lst
  147.     (setq obj (cons (car lst) obj)
  148.           lst (cdr lst)))
  149.   obj)
  150.  
  151. (defun unfold (p f g seed / lst)
  152.   (while (not (apply p (list seed)))
  153.     (setq lst (cons (apply f (list seed)) lst)
  154.           seed (apply g (list seed))))
  155.   (reverse lst))
  156.  
  157. (defun fold (fn init lst)
  158.   (foreach x lst
  159.     (setq init (apply fn (list x init))))
  160.   init)
  161.  
  162. (defun reduce (func lst)
  163.   (fold func (car lst) (cdr lst)))
  164.  
  165.   (setq every vl-every)
  166.   (defun every (pred lst / res)
  167.     (while (and (setq res (apply pred (list (car lst))))
  168.                 (setq lst (cdr lst))))
  169.     res))
  170.  
  171.   (setq some vl-some)
  172.   (defun some (pred lst / res)
  173.     (while (and (setq res (not (apply pred (list (car lst)))))
  174.                 (setq lst (cdr lst))))
  175.     (not res)))
  176.  
  177. (if vl-member-if
  178.   (setq member-if vl-member-if)
  179.   (defun member-if (pred lst)
  180.     (while (and lst (not (apply pred (list (car lst)))))
  181.       (setq lst (cdr lst)))))
  182.  
  183. (if vl-member-if-not
  184.   (setq member-if-not vl-member-if-not)
  185.   (defun member-if-not (pred lst) ; aka drop-while
  186.     (while (and lst (apply pred (list (car lst))))
  187.       (setq lst (cdr lst)))))
  188.  
  189.   (setq position vl-position)
  190.   (defun position (item lst / n)
  191.     (setq n 0)
  192.     (while (and lst (not (equal item (car lst))))
  193.       (setq n (1+ n)
  194.             lst (cdr lst)))
  195.     (if lst n)))
  196.  
  197. (defun position-if (pred lst / n)
  198.   (setq n 0)
  199.   (while (and lst (not (apply pred (list (car lst)))))
  200.     (setq n (1+ n)
  201.           lst (cdr lst)))
  202.   (if lst n))
  203.  
  204. (defun position-if-not (pred lst / n)
  205.   (setq n 0)
  206.   (while (and lst (apply pred (list (car lst))))
  207.     (setq n (1+ n)
  208.           lst (cdr lst)))
  209.   (if lst n))
  210.  
  211. (defun count (item lst / cnt)
  212.   (setq cnt 0)
  213.   (foreach x lst
  214.     (if (equal item x)
  215.       (setq cnt (1+ cnt))))
  216.   cnt)
  217.  
  218. (defun count-if (pred lst / cnt)
  219.   (setq cnt 0)
  220.   (foreach x lst
  221.     (if (apply pred (list x))
  222.       (setq cnt (1+ cnt))))
  223.   cnt)
  224.  
  225. (defun count-if-not (pred lst / cnt)
  226.   (setq cnt 0)
  227.   (foreach x lst
  228.     (or (apply pred (list x))
  229.         (setq cnt (1+ cnt))))
  230.   cnt)
  231.  
  232. (defun subst-if (new pred lst)
  233.   (mapcar (function (lambda (x) (if (apply pred (list x)) new x)))
  234.           lst))
  235.  
  236. (defun subst-if-not (new pred lst)
  237.   (mapcar (function (lambda (x) (if (apply pred (list x)) x new)))
  238.           lst))
  239.  
  240. (if vle-subst-nth
  241.   (defun subst-nth (new n lst)
  242.     (vle-subst-nth lst n new))
  243.   (defun subst-nth (new n lst)
  244.     (setq lst (split-at n lst))
  245.     (if (cdr lst)
  246.       (append (car lst) (cons new (cddr lst)))
  247.       (car lst))))
  248.  
  249. (if vle-subst-nth
  250.   (defun subst-first (new old lst)
  251.     (setq n (position old lst))
  252.     (if n
  253.       (vle-subst-nth lst n new)
  254.       lst))
  255.   (defun subst-first (new old lst)
  256.     (setq lst (split-at-first old lst))
  257.     (if (cdr lst)
  258.       (append (car lst) (cons new (cddr lst)))
  259.       (car lst))))
  260.  
  261. (defun subst-last (new old lst)
  262.   (setq lst (split-at-last old lst))
  263.       (if (cdr lst)
  264.         (append (car lst) (cons new (cddr lst)))
  265.         (car lst)))
  266.  
  267.   (setq remove vl-remove)
  268.   (defun remove (item lst)
  269.     (apply 'append (subst nil (list item) (mapcar 'list lst)))))
  270.  
  271. (if vl-remove-if
  272.   (setq remove-if vl-remove-if)
  273.   (defun remove-if (pred lst)
  274.     (apply 'append
  275.            (mapcar (function (lambda (x) (or (apply pred (list x)) (list x))))
  276.                    lst))))
  277.  
  278. (if vl-remove-if-not
  279.   (setq remove-if-not vl-remove-if-not)
  280.   (defun remove-if-not (pred lst)
  281.     (apply 'append
  282.            (mapcar (function (lambda (x) (if (apply pred (list x)) (list x))))
  283.                    lst))))
  284.  
  285. (if vle-remove-nth
  286.   (setq remove-nth vle-remove-nth)
  287.   (defun remove-nth (n lst)
  288.     (setq lst (split-at n lst))
  289.     (append (car lst) (cddr lst))))
  290.  
  291. (if vle-remove-first
  292.   (setq remove-first vle-remove-first)
  293.   (defun remove-first (item lst)
  294.     (setq lst (split-at-first item lst))
  295.     (append (car lst) (cddr lst))))
  296.  
  297. (if vle-remove-last
  298.   (setq remove-last vle-remove-last)
  299.   (defun remove-last (item lst)
  300.     (setq lst (split-at-last item lst))
  301.     (append (car lst) (cddr lst))))
  302.  
  303. (defun insert (new n lst)
  304.   (setq lst (split-at n lst))
  305.   (append (car lst) (cons new (cdr lst))))

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Well tested common functions library - should we have it?
« Reply #5 on: December 06, 2013, 10:19:00 AM »
The only way that is "wrong" is one that doesn't work.  The shortest path is not the only way forward.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: Well tested common functions library - should we have it?
« Reply #6 on: December 06, 2013, 03:19:02 PM »
I'll give you a bit, tell me should I continue?
The fact that Reini Urban's project was abandoned more than 10 years ago (and not picked up by 'the community') should make you think, but is in itself no reason to stop working on your project.

Some random questions and remarks:
1.
Why look at CL? And if you are going to do that, why not make the (some) function really compatible.
2.
Consistent naming scheme? You now have predicate functions with names that do not end in '-p'.
3.
You are using vle-* functions. You should be aware that a non BricsCAD user may have loaded the complete vle-extension.lsp file. Which would result in a strange situation I think.
4.
Have you ever used the (tenth) function? Would some sort of (SafeNth) function not be more useful?
5.
You should be aware that writing code is but one part of the project. Testing, documentation, examples and maintenance are also required.
6.
Is the speed of the functions important? Or are you striving for 'elegant' code? See example below.

Code: [Select]
;;; (setq partLst '("a" "b" "c" "d" "e" "f" "g" "h" "i" "j" "k" "l" "m" "n" "o" "p" "q" "r" "s" "t" "u" "v" "w" "x" "y" "z"))
;;; (setq testLst (append partLst partLst '(0) partLst partLst))


;;; (KGX_BenchMark '((vl-some 'numberp testLst) (divtiply_some 'numberp testLst) (roy_some_1 'numberp testLst) (roy_some_2 'numberp testLst)) 5000)

    ; Benchmarking .......... elapsed milliseconds / relative timing <5000 iterations>

      ; (VL-SOME 'NUMBERP TESTLST) ............ 16 / 8.81 <fastest>
      ; (ROY_SOME_2 'NUMBERP TESTLST) ......... 63 / 2.24
      ; (ROY_SOME_1 'NUMBERP TESTLST) ......... 93 / 1.52
      ; (DIVTIPLY_SOME 'NUMBERP TESTLST) ..... 141 / 1.00 <slowest>

Code - Auto/Visual Lisp: [Select]
  1. ; Code taken from the (some) function in divtiply's code)
  2. (defun divtiply_some (pred lst / res)
  3.   (while
  4.     (and
  5.       (setq res (not (apply pred (list (car lst)))))
  6.       (setq lst (cdr lst))
  7.     )
  8.   )
  9.   (not res)
  10. )
  11.  
  12. ; Some improvements:
  13. (defun roy_some_1 (pred lst / res)
  14.   (setq pred (eval pred))
  15.   (while
  16.     (and
  17.       (not (setq res (pred (car lst))))
  18.       (setq lst (cdr lst))
  19.     )
  20.   )
  21.   res
  22. )
  23.  
  24. ; With additional speed improvement based on Reini Urban's (std-%setnth):
  25. (defun roy_some_2 (pred lst / res)
  26.   (setq pred (eval pred))
  27.   (while
  28.     (and
  29.       (cadddr lst)
  30.       (not
  31.         (setq res
  32.           (or
  33.             (pred (car lst))
  34.             (pred (cadr lst))
  35.             (pred (caddr lst))
  36.             (pred (cadddr lst))
  37.           )
  38.         )
  39.       )
  40.     )
  41.     (setq lst (cddddr lst))
  42.   )
  43.   (if (not res)
  44.     (while
  45.       (and
  46.         (car lst)
  47.         (not (setq res (pred (car lst))))
  48.       )
  49.       (setq lst (cdr lst))
  50.     )
  51.   )
  52.   res
  53. )

divtiply

  • Guest
Re: Well tested common functions library - should we have it?
« Reply #7 on: December 06, 2013, 04:03:19 PM »
Code: [Select]
; Some improvements:
Thanks Roy!
That's why I've started this topic. Together it's easy to improve common code.
2. Consistent naming scheme? You now have predicate functions with names that do not end in '-p'.
Which?
« Last Edit: December 06, 2013, 04:20:57 PM by divtiply »

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Well tested common functions library - should we have it?
« Reply #8 on: December 06, 2013, 04:41:53 PM »
I have only played with AutoLisp here and there, but I will write the section on variable naming standards.

1. Do NOT be descriptive.
2. Try to keep variable names 3 letters or less.
3. Try to use a lower case 'l' as frequently as possible('l' is not the number one it is lowercase 'L'). 


Done.

divtiply

  • Guest
Re: Well tested common functions library - should we have it?
« Reply #9 on: December 06, 2013, 04:48:29 PM »
1. Do NOT be descriptive.
2. Try to keep variable names 3 letters or less.
3. Try to use a lower case 'l' as frequently as possible('l' is not the number one it is lowercase 'L'). 

You prefer names like list-to-search-within instead of lst?

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Well tested common functions library - should we have it?
« Reply #10 on: December 06, 2013, 04:56:24 PM »
Hi divtiply,

That was not directed toward you or any code you posted. It was a joke from a non-lisper who is not familiar with the language or the conventions and seeing snippets of code with 'a', 'l', etc... as variables.
 

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Well tested common functions library - should we have it?
« Reply #11 on: December 06, 2013, 06:18:53 PM »
Hi divtiply,

That was not directed toward you or any code you posted. It was a joke from a non-lisper who is not familiar with the language or the conventions and seeing snippets of code with 'a', 'l', etc... as variables.
 

Brought a smile to my face, at least.   :-D
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

danallen

  • Guest
Re: Well tested common functions library - should we have it?
« Reply #12 on: December 06, 2013, 07:05:16 PM »
does anyone have routines from Looking Glass Microproducts? I had collected some from the very old cad shack website and it was very useful for learning and putting together my own routines. (also probably was not legitimately shared though... :-(

An ex-lisper comment:

In all my past years spent (20+-) in the autolisp/vlisp world --- the only way or form I have seen to adopt a function as standard it is when these are added into the autolisp core. Anything out it will be way too difficult - will only be part of anyone's personal functions arsenal. Have seen so many try-outs -- ALL have failed.

Let see if this time not.


LE!

LE3

  • Guest
Re: Well tested common functions library - should we have it?
« Reply #13 on: December 06, 2013, 08:22:59 PM »
does anyone have routines from Looking Glass Microproducts? I had collected some from the very old cad shack website and it was very useful for learning and putting together my own routines. (also probably was not legitimately shared though... :-(

Oh!
The old master Phil Kreiker --- I remember those on cadence magazine? if my 1/4 brain cell left still is working.... I am sure he wrote the 'painter' or match properties --- too btw.

did a quick search and yes he had a section on cadalyst magazine named THE CAD COOKBOOK  - so maybe if they are still available do a search on the cadalyst site.
« Last Edit: December 06, 2013, 08:39:15 PM by LE »

ymg

  • Guest
Re: Well tested common functions library - should we have it?
« Reply #14 on: December 07, 2013, 02:50:55 AM »
Quote
For example, ymg's ceil/floor functions [http://www.theswamp.org/index.php?topic=45379.msg505421#msg505421]:

divtiply,

Thanks for the attribution, but these function were actually taken from std-math. http://autocad.xarch.at/stdlib/STDMATH.LSP

However I should have tested.  (Post has been updated)

And by the way Floor and Ceiling are applicable to real numbers not to integers as shown in your example.

ymg
« Last Edit: December 07, 2013, 05:24:54 AM by ymg »