TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: Grrr1337 on October 23, 2020, 01:51:25 PM

Title: DisEval
Post by: Grrr1337 on October 23, 2020, 01:51:25 PM
Hey guys,
Although I've seen this sub of Lee Mac through the years -

Code - Auto/Visual Lisp: [Select]
  1. ;; Active Document  -  Lee Mac
  2. ;; Returns the VLA Active Document Object
  3.  
  4. (defun LM:acdoc nil
  5.   (LM:acdoc)
  6. )

I was recently inspired by MP's sub from this thread (http://www.theswamp.org/index.php?topic=56320.0) -

Code - Auto/Visual Lisp: [Select]
  1.   (list 'defun 'mp-get-owner '( object / owner )
  2.     (list 'vl-catch-all-apply
  3.       (list 'function
  4.         (list 'lambda nil
  5.           (list 'setq 'owner
  6.             (list
  7.               'vla-objectidtoobject
  8.               (list 'vla-get-ownerid 'object)
  9.             )
  10.           )
  11.         )
  12.       )      
  13.     )
  14.     'owner
  15.   )
  16. )

Got me thinking, did he first wrote the sub and then refactored it manually to be used with eval, or maybe he have already automated the refactoring part?  :thinking:
Despite my accumulation of LISP writing experience I would struggle to refactor any code in order to disevaluate it.

So I played the last few days and I'm sharing with you my DisEval sub:
Code - Auto/Visual Lisp: [Select]
  1. ;; DisEval - (Inverse evaluator)
  2. ;; Grrr [21.10.2020]
  3. (defun _DisEval ( f / _dottedpair-p diseval )
  4.  
  5.   ; _$ (_dottedpair-p '(-4 . "OR>")) >> T
  6.   ; _$ (_dottedpair-p '(1 2 3)) >> nil
  7.   ; _$ (_dottedpair-p "ABC") >> nil
  8.   ; _$ (_dottedpair-p nil) >> nil
  9.   (defun _dottedpair-p ( x )
  10.     (and (vl-consp x) (vl-catch-all-error-p (vl-catch-all-apply (function length) (list x))))
  11.   )
  12.  
  13.   (defun diseval ( f / x )
  14.     (setq x (if (listp f) (car f) f))
  15.     (cond
  16.       ( (not f) f)
  17.       ( (_dottedpair-p f)
  18.         f
  19.       )
  20.       ( (atom x)
  21.         (append
  22.           (list
  23.             (cond
  24.               ((null x) x)
  25.               ((numberp x) x)
  26.               ((eq t x) x)
  27.               ( (read (strcat "'" (vl-prin1-to-string x))) )
  28.             ); cond
  29.           ); list
  30.           (diseval (if (listp f) (cdr f)))
  31.         )
  32.       )
  33.       ( (listp x)
  34.         (append
  35.           (list
  36.             (
  37.               '((xx)
  38.                 (cond
  39.                   ( (_dottedpair-p xx)
  40.                     (list 'cons (car xx) (cdr xx))
  41.                   )
  42.                   ( (cons 'list xx) )
  43.                 )
  44.               )
  45.               (diseval x)
  46.             )
  47.           )
  48.           (diseval (if (listp f) (cdr f)))
  49.         )
  50.       ); (listp x)
  51.     ); cond
  52.   ); defun
  53.  
  54.   (if (vl-consp f) (cons 'list (diseval f)))
  55. ); defun _DisEval

Sample usage:
Code: [Select]
(_DisEval
  '(defun AcDoc nil
    (vla-get-ActiveDocument (vlax-get-acad-object))
  )
)
>> (LIST (QUOTE DEFUN) (QUOTE ACDOC) nil (LIST (QUOTE vla-get-ActiveDocument) (LIST (QUOTE vlax-get-acad-object))))
>> Pretty-printed:
(LIST 'DEFUN 'ACDOC nil
  (LIST 'vla-get-ActiveDocument (LIST 'vlax-get-acad-object))
)

Code: [Select]
(_DisEval
  '(LM:ssget "\nSelect lines, arcs and/or polylines to extend: "
    '("_:L"
      (
        (-4 . "<OR")
        (0 . "LINE,ARC")
        (-4 . "<AND")
        (0 . "LWPOLYLINE")
        (-4 . "<NOT")
        (-4 . "&=") (70 . 1)
        (-4 . "NOT>")
        (-4 . "AND>")
        (-4 . "<AND")
        (0 . "POLYLINE")
        (-4 . "<NOT")
        (-4 . "&=") (70 . 87)
        (-4 . "NOT>")
        (-4 . "AND>")
        (-4 . "OR>")
      )
    )
  )
)
>>
(LIST 'LM:SSGET
  '"\nSelect lines, arcs and/or polylines to extend: "
  (LIST 'QUOTE
    (LIST '"_:L"
(LIST
(CONS -4 "<OR")
        (CONS 0 "LINE,ARC")
        (CONS -4 "<AND")
        (CONS 0 "LWPOLYLINE")
        (CONS -4 "<NOT")
        (CONS -4 "&=")
        (CONS 70 1)
        (CONS -4 "NOT>")
        (CONS -4 "AND>")
        (CONS -4 "<AND")
        (CONS 0 "POLYLINE")
        (CONS -4 "<NOT")
        (CONS -4 "&=")
        (CONS 70 87)
        (CONS -4 "NOT>")
        (CONS -4 "AND>")
        (CONS -4 "OR>")
      )
    )
  )
)

You can also perform nested DisEval-uations on any code and then nestedly evaluate it:
Code: [Select]
_$ (eval (eval (eval (eval (eval (_DisEval (_DisEval (_DisEval (_DisEval '(ssget "_:L-I" '((0 . "CIRCLE")(8 . "0"))))))))))))
<Selection set: 2f>

Code: [Select]
_$ ( (lambda (n c / r ) (setq r c) (repeat n (setq r (_DisEval r))) r) 5
    '(defun AcDoc nil
      (vla-get-ActiveDocument (vlax-get-acad-object))
    )
  )
(LIST
  'LIST
  (LIST 'QUOTE 'LIST)
  (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
  (LIST 'LIST
(LIST 'QUOTE 'LIST)
(LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
(LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
  )
  (LIST 'LIST
(LIST 'QUOTE 'LIST)
(LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
(LIST 'LIST
      (LIST 'QUOTE 'LIST)
      (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
      (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
)
(LIST 'LIST
      (LIST 'QUOTE 'LIST)
      (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
      (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'DEFUN))
)
  )
  (LIST 'LIST
(LIST 'QUOTE 'LIST)
(LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
(LIST 'LIST
      (LIST 'QUOTE 'LIST)
      (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
      (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
)
(LIST 'LIST
      (LIST 'QUOTE 'LIST)
      (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
      (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'ACDOC))
)
  )
  nil
  (LIST
    'LIST
    (LIST 'QUOTE 'LIST)
    (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
    (LIST 'LIST
  (LIST 'QUOTE 'LIST)
  (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
  (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
    )
    (LIST 'LIST
  (LIST 'QUOTE 'LIST)
  (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
  (LIST 'LIST
(LIST 'QUOTE 'LIST)
(LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
(LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
  )
  (LIST 'LIST
(LIST 'QUOTE 'LIST)
(LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
(LIST 'LIST
      (LIST 'QUOTE 'QUOTE)
      (LIST 'QUOTE 'vla-get-ActiveDocument)
)
  )
    )
    (LIST
      'LIST
      (LIST 'QUOTE 'LIST)
      (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
      (LIST 'LIST
    (LIST 'QUOTE 'LIST)
    (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
    (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
      )
      (LIST 'LIST
    (LIST 'QUOTE 'LIST)
    (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'LIST))
    (LIST 'LIST
  (LIST 'QUOTE 'LIST)
  (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
  (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
    )
    (LIST 'LIST
  (LIST 'QUOTE 'LIST)
  (LIST 'LIST (LIST 'QUOTE 'QUOTE) (LIST 'QUOTE 'QUOTE))
  (LIST 'LIST
(LIST 'QUOTE 'QUOTE)
(LIST 'QUOTE 'vlax-get-acad-object)
  )
    )
      )
    )
  )
)

Code: [Select]
_$ ( (lambda (n c / r ) (setq r c) (repeat n (setq r (eval r))) r) 7 ; try from 5 up to 7
  ( (lambda (n c / r ) (setq r c) (repeat n (setq r (_DisEval r))) r) 5
    '(defun AcDoc nil
      (vla-get-ActiveDocument (vlax-get-acad-object))
    )
  )
);; (lambda)
#<USUBR @0000001c064381b0 ACDOC>

You can also DisEval-uate and evaluate bunch of subs/code like so:
Code: [Select]
(mapcar 'eval
  (eval
    (eval
      (_DisEval
        '(list
          ;; Bunch of codes...
          (defun AcObj nil
            (vlax-get-acad-object)
          )
          (defun AcDoc nil
            (vla-get-ActiveDocument (vlax-get-acad-object))
          )
          (defun AlertHello nil
            (alert "Hello")
          )
          (defun SayHi nil
            (princ "Hi")
          )
          ;; ... bunch of codes
        ); list
      )
    )
  )
)

or like in this example that guarantees that it works properly -
Code: [Select]
(mapcar 'eval
  (eval
    (eval
      (_DisEval
        '(list
          ;; i.e. paste the whole lisp content from here:
          ;; http://www.lee-mac.com/lisp/html/2DProjectionV1-0.html
        ); list
      )
    )
  )
)


So in the end..
Code - Auto/Visual Lisp: [Select]
  1. _$ (_DisEval ;; Inspect 'n Pretty-print
  2.   '(defun mp-get-owner ( object / owner )
  3.     (vl-catch-all-apply
  4.       (function
  5.         (lambda nil
  6.           (setq owner
  7.             (vla-objectidtoobject
  8.               (vla-get-ownerid object)
  9.             )
  10.           )
  11.         )
  12.       )      
  13.     )
  14.     owner
  15.   )
  16. )
  17. >>
  18.   'DEFUN
  19.   'MP-GET-OWNER
  20.   (LIST 'OBJECT '/ 'OWNER)
  21.   (LIST
  22.     'VL-CATCH-ALL-APPLY
  23.     (LIST
  24.       'FUNCTION
  25.       (LIST
  26.         'LAMBDA
  27.         nil
  28.         (LIST
  29.           'SETQ
  30.           'OWNER
  31.           (LIST
  32.             'vla-ObjectIDToObject
  33.             (LIST 'vla-get-OwnerID 'OBJECT)
  34.           )
  35.         )
  36.       )
  37.     )
  38.   )
  39.   'OWNER
  40. )


Cheers!
(going back to my busy life, so sorry if I don't reply on time)
Title: Re: DisEval
Post by: JohnK on October 23, 2020, 02:44:16 PM
Pardon my ignorance but what is wrong with:
Code - Auto/Visual Lisp: [Select]
  1. (setq *acadobject*
  2.        (cond
  3.          (*acadobject*)
  4.          ((vlax-get-acad-object))) )

and on the lazy evaluation subject (I am unsure what "disevaluation" means) I've used a function I wrote a long time ago called "hook".
Code - Auto/Visual Lisp: [Select]
  1. (defun hook (func)
  2.   ;; hook
  3.   ;; this function will take an argument and turn it into a
  4.   ;; lambda expression to evaluate. (You can assign to a variable
  5.   ;; and exec it at a later time if you wish.)
  6.   ;;
  7.   ;; By: John (Se7en) K
  8.   ;;    (inspired by something I saw in one of
  9.   ;;     Vladimir Nesterovsky's procedures.)
  10.   ;;
  11.   ;; Ex: (hook '(+ 1 2))
  12.   ;;     > ((LAMBDA nil (+ 1 2)))
  13.   ;;    
  14.   (list (cons 'lambda (cons nil (list func)))) )

Code: [Select]
> Command: (setq a (hook '(+ 1 2)))
> ((LAMBDA nil (+ 1 2)))
>
> Command: (eval a)
> 3
>
> Command: (setq a (hook '(+ 1 2))
> (_>       b (hook '(+ 1 3))
> (_>       c (hook '(+ 1 4))
> (_>       d (hook '(+ 1 5))
> (_>       e (hook '(+ 1 6))
> (_>       f (hook '(+ 1 7)))
> ((LAMBDA nil (+ 1 7)))
>
> Command: (mapcar 'eval (mapcar 'eval '(a b c d e f)))
> (3 4 5 6 7 8)
Title: Re: DisEval
Post by: MP on October 23, 2020, 03:42:49 PM
Yours uses a global variable set to acadapp, the alternative would encapsulate acadapp without a global.
Title: Re: DisEval
Post by: JohnK on October 23, 2020, 03:57:27 PM
Sorry, running late!!


There is nothing wrong with global variables (in this respect) is there?

What would be the difference between a variable and a function (aren't they both "symbols" in AutoLisp)?

If defun-q is a list can you modify that defun-q list like any other list (were there any problems with modifying those defun-q lists and evaluations)?
Title: Re: DisEval
Post by: MP on October 23, 2020, 04:00:00 PM
Personal preference that’s presumably ok with the lisp police.
Title: Re: DisEval
Post by: Lee Mac on October 23, 2020, 05:39:55 PM
Whilst I applaud the code you have shared, note that quoting every nested expression in the supplied list is not quite achieving the same result as both mine & MP's example functions, in which certain specific expressions are evaluated immediately as part of the function definition (e.g. references to objects, such as the active document object), whilst others are evaluated when the function itself is evaluated.

Consider the difference in the result of the following function definitions, as may be illustrated through the use of defun-q:
Code - Auto/Visual Lisp: [Select]
  1. LM:ACDOC
  2. _$ LM:acdoc
  3. (nil #<VLA-OBJECT IAcadDocument 0000000028473118>)
  4.  
  5. ACDOC
  6. _$ acdoc
Title: Re: DisEval
Post by: JohnK on October 23, 2020, 05:43:51 PM
Personal preference that’s presumably ok with the lisp police.

I think the police are drunk now because some of my old code/methods were accused of being "too academic" (not fit for production) in the past [ "hygienic variables", "or is evil", "let", etc.] and was labeled as a heretic--this is way-out-there IMO. -i.e. I'd take the cond.
Title: Re: DisEval
Post by: ronjonp on October 23, 2020, 06:04:10 PM
FWIW I'd be inclined to use this over COND  :-)
Code - Auto/Visual Lisp: [Select]
  1. (or *acadobject* (setq *acadobject* (vlax-get-acad-object)))
Title: Re: DisEval
Post by: JohnK on October 23, 2020, 06:19:22 PM
*sigh* ...I'm beginning to think people believe "obfuscation" equals "better".
Title: Re: DisEval
Post by: MP on October 23, 2020, 07:09:54 PM
:o
Title: Re: DisEval
Post by: MP on October 23, 2020, 11:44:00 PM
... specific expressions are evaluated <at declaration time> ... whilst others are evaluated <at run time> ...

Exactamundo.

/AHF
Title: Re: DisEval
Post by: MP on October 24, 2020, 12:20:05 AM
Code: [Select]
(defun mp-get-owner-1 ( object / owner )
    (vl-catch-all-apply
        (function
            (lambda ( )
                (setq owner
                    (vla-objectidtoobject
                        (vla-get-activedocument (vlax-get-acad-object))
                        (vla-get-ownerid object)
                    )             
                )
            )
        )
    )
    owner
)

Code: [Select]
(defun mp-get-owner-2 ( object )
    (eval
        (list 'defun 'mp-get-owner-2 '( object / owner )
            (list 'vl-catch-all-apply
                (list 'function
                    (list 'lambda nil
                        (list 'setq 'owner
                            (list
                                'vla-objectidtoobject
                                (vla-get-activedocument (vlax-get-acad-object))
                                (list 'vla-get-ownerid 'object)
                            )
                        )
                    )
                )       
            )
           'owner
        )
    )
    (mp-get-owner-2 object )
)

Code: [Select]
(setq obj (vlax-ename->vla-object (car (entsel))))

(mp-benchmark
   '(
        (mp-get-owner-1 obj)
        (mp-get-owner-2 obj)
    )           
)

Elapsed milliseconds / relative speed for 32768 iteration(s):
(MP-GET-OWNER-2 OBJ).....1125 / 1.35 <35% faster>
(MP-GET-OWNER-1 OBJ).....1516 / 1.00 <slowest>

(did multiple tests, observed everything from 29-41% speed increase).

TLDR: Wifey says speed isn't everything.

An aside, I prefer encapsulating objects when applicable, eliminates superfluous processing and it's tidy; win.
Title: Re: DisEval
Post by: ronjonp on October 24, 2020, 12:35:50 AM
*sigh* ...I'm beginning to think people believe "obfuscation" equals "better".
It's not really that at all ... it's very legible to me  :? \disclaimeraside ... not catering to others.

Mute point really .. goes back to preference.
Quote
_$
Benchmarking ...................Elapsed milliseconds / relative speed for 65536 iteration(s):

    (OR *ACADOBJECT* (SETQ *ACADOBJECT* ...).....1344 / 1.06 <fastest>
    (SETQ *ACADOBJECT* (COND (*ACADOBJEC...).....1422 / 1.00 <slowest>

 
; 1 form loaded from #<editor "<Untitled-0> loading...">
_$
Title: Re: DisEval
Post by: ronjonp on October 24, 2020, 12:41:13 AM
Code: [Select]
(defun mp-get-owner-1 ( object / owner )
    (vl-catch-all-apply
        (function
            (lambda ( )
                (setq owner
                    (vla-objectidtoobject
                        (vla-get-activedocument (vlax-get-acad-object))
                        (vla-get-ownerid object)
                    )             
                )
            )
        )
    )
    owner
)

Code: [Select]
(defun mp-get-owner-2 ( object )
    (eval
        (list 'defun 'mp-get-owner-2 '( object / owner )
            (list 'vl-catch-all-apply
                (list 'function
                    (list 'lambda nil
                        (list 'setq 'owner
                            (list
                                'vla-objectidtoobject
                                (vla-get-activedocument (vlax-get-acad-object))
                                (list 'vla-get-ownerid 'object)
                            )
                        )
                    )
                )       
            )
           'owner
        )
    )
    (mp-get-owner-2 object )
)

Code: [Select]
(setq obj (vlax-ename->vla-object (car (entsel))))

(mp-benchmark
   '(
        (mp-get-owner-1 obj)
        (mp-get-owner-2 obj)
    )           
)

Elapsed milliseconds / relative speed for 32768 iteration(s):
(MP-GET-OWNER-2 OBJ).....1125 / 1.35 <35% faster>
(MP-GET-OWNER-1 OBJ).....1516 / 1.00 <slowest>

(did multiple tests, observed everything from 29-41% speed increase).

TLDR: Wifey says speed isn't everything.

An aside, I prefer encapsulating objects when applicable, eliminates superfluous processing and it's tidy; win.
I always wondered why you smart mother truckers did the fancy 'eval shite .. going to have to look into this closer. *beers*
Title: Re: DisEval
Post by: MP on October 24, 2020, 11:44:42 AM
smart

debatable

mother trucker

irrefutable

*beers*

*clank*
Title: Re: DisEval
Post by: ronjonp on October 25, 2020, 12:28:15 AM
smart

debatable

mother trucker

irrefutable

*beers*

*clank*
:-D
Title: Re: DisEval
Post by: Grrr1337 on October 25, 2020, 03:23:08 PM
Whilst I applaud the code you have shared, note that quoting every nested expression in the supplied list is not quite achieving the same result as both mine & MP's example functions, in which certain specific expressions are evaluated immediately as part of the function definition (e.g. references to objects, such as the active document object), whilst others are evaluated when the function itself is evaluated.

Consider the difference in the result of the following function definitions, as may be illustrated through the use of defun-q:
Code - Auto/Visual Lisp: [Select]
  1. ...

Thank you for pointing and explaining that out Lee!
Now I do remember the nostalgic confusion I got years ago when I was trying to understand the manual 'diseval-uation' technique:
where I thought the logic was that everything should be recursively 'quotted' and 'nestedly-list-capsulated', but then seeing
(vla-get-activedocument (vlax-get-acad-object)) within the body, instead of (list (quote vla-get-activedocument) (list (quote vlax-get-acad-object))) .
Completely forgot about this detail while writing the sub ^^.


*sigh* ...I'm beginning to think people believe "obfuscation" equals "better".

'obfuscation' is not the thing I'm after in this thread, although it resulted in such (if I remember there was a thread somewhere here related to protecting code with obfuscation).
Reason that I do not categorise it as such, was because of Roy's explanation (https://www.cadtutor.net/forum/topic/64397-understanding-lee-macs-coding/?tab=comments#comment-530537) :

Quote
Code: [Select]
(defun LM:acdoc nil
  (eval (list 'defun 'LM:acdoc 'nil (vla-get-activedocument (vlax-get-acad-object))))
  (LM:acdoc)
)
When first called, Lee's LM:acdoc function redefines itself. The new definition directly returns the active document object and is therefore a (minute) bit faster than the less complex function proposed by Aftertouch.


Code: [Select]
(setq obj (vlax-ename->vla-object (car (entsel))))

(mp-benchmark
  '(
    (mp-get-owner-1 obj)
    (mp-get-owner-2 obj)
  )           
)

Elapsed milliseconds / relative speed for 32768 iteration(s):
(MP-GET-OWNER-2 OBJ).....1125 / 1.35 <35% faster>
(MP-GET-OWNER-1 OBJ).....1516 / 1.00 <slowest>

(did multiple tests, observed everything from 29-41% speed increase).

TLDR: Wifey says speed isn't everything.

An aside, I prefer encapsulating objects when applicable, eliminates superfluous processing and it's tidy; win.

Thanks for providing a benchmark example, MP - helps me understand better what Roy ment back in 2017.

Still wondering were you encapsulating manually (thats the correct term, right: encapsulation?)
*Thinking that there could be a regex alternative to my suggestion*



Glad to see that ronjonp gained one more brain cell. :D

BTW I've modified it a bit to avoid quoting numbers or T symbols.
Title: Re: DisEval
Post by: JohnK on October 25, 2020, 06:56:48 PM
I agree the `encapsulated' version is tidy; no argument here about it's tidiness (however I would be careful using the term `encapsulating' in descriptions). I agree with it's tidiness because it's ready-to-ship-nature; in that, the author isn't subject to any previously defined wonky version. But I still believe it is more along the lines of obfuscation for that same reason (-e.g. if the code were adopted into a larger standard wholesale without an understanding into it's inner working). I'm not saying this a tempest-in-a-teacup just merely pointing out that you cannot pass this off as "best practices" without notice (take 10 minutes to describe your function instead of dropping it down as the latest fad). Explain the differences because there are some.

No `encapsulating' is not the proper term. Encapsulating a methodology reserved for OOP and classes; it has to do with public and private methods exposed to API users (getter's and setter's).

No, my arguments are not based in speed. Speed should be considered negligible on this level (speed considerations come into play more in operations and other larger tasks --these tasks are minor in the larger scheme of a procedure's operation).

My gripe is more about type-safety and obfuscation then anything. Adopting and perpetuating bad programming practice--especially under the guise of "better than"--is not good for anyone.
Title: Re: DisEval
Post by: VovKa on October 25, 2020, 07:35:58 PM
p.s.

self modifying functions will not work if compiled with option 'Optimize and link' set

p.p.s

a way around is to setq function to nil before redefining
Title: Re: DisEval
Post by: MP on October 25, 2020, 08:43:02 PM
p.s. self modifying functions will not work if compiled with option 'Optimize and link' set

p.p.s. a way around is to setq function to nil before redefining

That's good to know; thanks for tabling it.

No `encapsulating' is not the proper term. Encapsulating a methodology reserved for OOP and classes;

Sorry, this is nonsense, OOP does not enjoy exclusive rights to the word.

en·cap·su·late

enclose (something) in or as if in a capsule.

it has to do with public and private methods exposed to API users (getter's and setter's).

👇

... I went back to university a number of years ago and formally studied OOP technologies.

👨‍🎓

Adopting and perpetuating bad programming practice--especially under the guise of "better than"--is not good for anyone.

I won't blindly dismiss; will ruminate.
Title: Re: DisEval
Post by: JohnK on October 25, 2020, 09:56:49 PM
My statement wasn't about OOP owning a term. My statement was about what is and what isn't in other languages. ...I would call the `encapsulation method` a "MACRO". I don't agree with the `encapsulation` term because if we choose the generic definition of `encapsulate' to describe things we could use it to describe a vast number of things. -e.g. "(defun a () 1) 1 is now encapsulated". ...But overall, I like macros (who doesn't) but they are not encapsulation and they--like most things--have their limitations.

> ruminate
Okay. Sounds good but it wasn't that deep of a thought/statement. -i.e. Mixing types and returns is not a good habit to get into. Many languages now offer more type safety built in.
-e.g.
The statement:
(or <VARIABLE>
returns something different than:
(setq <VARIABLE>
And if [you] understand the differences and uses, then good; use the hell out of it. But teach others so they understand that. I tried.

> wrong about encapsulation
So if encapsulating isn't about classes and methods then what is it?
Title: Re: DisEval
Post by: Grrr1337 on October 27, 2020, 05:57:08 PM
I just made an assumption how one would call this nested-list-quoting technique in lisp, if it has any name afterall.
So I came up with 'disevaluation'.

Think we all know that encapsulation is related to function's scope (for semi-functional or fully-functional languages like JS and LISP)
or to classes 'n objects scope (for languages like Java/C#) when it goes for OOP.
The scoping technique for exposing or hiding public and private methods and properties (getters'n'setters) from some classes to be revealed in other classes would be known as 'encapsulation'.
In functional programming like LISP 'encapsulation' would be applied for declaring functions instead of classes, passing function calls instead of methods and passing variables instead of properties.

Code - Auto/Visual Lisp: [Select]
  1. (defun SpaghettiCode ( x / ravioli noodles meatballs )
  2.   ; Spaghetti Code inside, but all of the variables are declared in the parent function definition
  3.   ; assuming that this giant and very complex spaghetti code works without bugs and keeps all the variables and inner-function definitions local
  4.   ; it does something, it returns something, its bug-free, and the author is unknown
  5.   ; so its not worth it to spend time'n effort for reading and understanding the algorithm (we just use the parent function)
  6.   ; and we could say that this is an encapsulated code
  7.   (defun ravioli ..
  8.     (noodles (ravioli (meatballs ..)))
  9.   )
  10.   (defun noodles ..
  11.     (meatballs (ravioli ..))
  12.   )
  13.   (defun meatballs ..
  14.     (ravioli (noodles ..))
  15.   )
  16.   (ravioli (noodles x))
  17. ); defun SpaghettiCode
  18.  

Code - C#: [Select]
  1. namespace SpaghettiCode
  2. {
  3.   // declaring bunch of classes with chained getters'n'setters
  4.   // documenting what this assembly is all about and what are the exposed public methods and properties
  5.   // would we bother to understand the algorithm inside?
  6.   // we may care just about the functionality it provides
  7.   class ravioli
  8.   {
  9.     ..
  10.   }
  11.   class noodles
  12.   {
  13.     ...
  14.   }
  15.   class meatballs
  16.   {
  17.     ...
  18.   }
  19. }

I think we could say that a function/class is encapsulated when its scoped up to a level where its exposing just enough (meaning no redundant variables/properties/methods out of the main body).