Author Topic: arguments and variables  (Read 4541 times)

0 Members and 1 Guest are viewing this topic.

curmudgeon

  • Newt
  • Posts: 194
arguments and variables
« on: June 23, 2011, 06:17:23 PM »
 :oops:
I thought I understood this, but I must have been mistaken.

Code: [Select]
(setq a '(0,0) b '(10,10))
(setq z a a b b z)

and !b returns (0,0), !a returns (10,10) as expected.

but I try to wrap it in a defun
Code: [Select]
(defun swp (x y / z)
(setq z x  x y  y z))

(swp a b)
!b returns (10,10)

I read the help files again, and even found Kenny's archived Set & Setq.
But, what is an argument good for if I can't pass a variable to the function through it?

Never express yourself more clearly than you are able to think.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: arguments and variables
« Reply #1 on: June 23, 2011, 06:23:34 PM »
You need to pass the variables quoted, e.g. (foo 'a 'b), and then use evaluate / set within the function to perform "the magic" (it currently does not).

Having said this just don't, it's argument passing masturbation, there are likely better ways to achieve what you need, we just need to clearly understand what the original need was that prompted the inquiry.

imo
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

curmudgeon

  • Newt
  • Posts: 194
Re: arguments and variables
« Reply #2 on: June 23, 2011, 06:39:56 PM »
Quote
it's argument passing masturbation
I like that.

I want to swap endpoints for a line, ent1:
(subst (cons 10 (cdr (assoc 11 ent1))) ent1)
and
(subst (cons 11 (cdr (assoc 10 ent1))) ent1)
but thought I would use a dummy variable to store the first while I overwrite it with the second.

boy, that was as clear as mud.

what I guess I ought to do is bite the bullet and (entdel (car (assoc -1 ent1))) and then
(entmake (list ( '(0 . "LINE")......(cons 10 (cdr (assoc 11 ent1))) (cons 11 (cdr (assoc 10 ent1)))...)




Never express yourself more clearly than you are able to think.

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: arguments and variables
« Reply #3 on: June 23, 2011, 06:43:10 PM »
I use this to 'permute' the values of two variables:

Code: [Select]
(defun _permute ( *a *b / c )
  (setq c (eval *a))
  (set *a (eval *b))
  (set *b c)
)

Requires quoted symbols, for example:

Code: [Select]
_$ (setq a 10 b 15)
_$ (_permute 'a 'b)
_$ a
15
_$ b
10

Why the asterisks? Because the quoted symbols cannot match the symbols used as arguments for the subfunction and using asterisks decreases this risk.

This operation always reminds me of indirect addressing - a mind-boggling concept in itself.

curmudgeon

  • Newt
  • Posts: 194
Re: arguments and variables
« Reply #4 on: June 23, 2011, 06:55:25 PM »
now I have it, thanks.
Never express yourself more clearly than you are able to think.

Jeff_M

  • King Gator
  • Posts: 4096
  • C3D user & customizer
Re: arguments and variables
« Reply #5 on: June 23, 2011, 07:00:45 PM »
For swapping line start/end points:
Code: [Select]
(setq ent1 (entget (entlast)))
(setq ent2 (subst (cons 10 (cdr (assoc 11 ent1))) (assoc 10 ent1) ent1))
(setq ent2 (subst (cons 11 (cdr (assoc 10 ent1))) (assoc 11 ent2) ent2))
(entmod ent2)

JohnK

  • Administrator
  • Seagull
  • Posts: 10648
Re: arguments and variables
« Reply #6 on: June 23, 2011, 07:04:17 PM »
Since we are "in theSwamp" let's just wade in waste deep and see if we cant stir up any gators.

Give this helper function a try (for getting to think more abstractly about your code).
Use the following code something like:

Code: [Select]
(let '((endpt (getpoint...))
       (stpt (getpoint...)))
      '(dosomething endpt stpt)
      )

Code: [Select]
(defun let ( bindings body / replace )
  ;; let
  ;; evaluate process with localized variables.
  ;;
  ;; Ported to AutoLisp By: John (Se7en) K
  ;;
  ;; Synopsis: let <bindings> <body>
  ;;
  ;;  (let '((a (+ 1 (* x y)))
  ;;         (b (- 1 y)))
  ;;     '(+ (* x (square a))
  ;;         (* y b)
  ;;         (* a b))
  ;;   )
  ;;  ~~>
  ;;  ((LAMBDA nil (+ (* X (SQUARE (+ 1 (* X Y))))
  ;;            (* Y (- 1 Y))
  ;;            (* (+ 1 (* X Y)) (- 1 Y)))))
  ;;
  ;;  ==> Evaluated value
  ;;
  ;; EX1:
  ;;  (setq x 5)
  ;;  (+ (let '((x 3))
  ;;          '(+ x (* x 10)))
  ;;   x)
  ;;
  ;;  ==> 38
  ;;
  ;; EX2:
  ;;  (setq x 2 y 4)
  ;;  (let '((x 3)
  ;;         (y (+ x 2)))
  ;;       '(* x y))
  ;;
  ;;  ==> 12
  ;;
  ;; EX3:
  ;;
  ;;    (let
  ;;      '((ss-vp
  ;;          (ssget "x"
  ;;                 (list '(0 . "VIEWPORT")
  ;;                       '(-4 . "/=")
  ;;                       '(68 . 1)
  ;;                       (cons 410 (getvar "ctab"))))))
  ;;      '((if (null ss-vp)
  ;;          (progn
  ;;            (alert "\n No VIEWPORTS in current layout")
  ;;            (princ) )
  ;;          ss-vp))
  ;;      )
    (eval
        (cons (append (list 'lambda (mapcar 'car bindings)) body)
              (mapcar 'cadr bindings))) )
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: arguments and variables
« Reply #7 on: June 23, 2011, 07:14:09 PM »
I like that.

most do, most won't admit it tho

I want to swap endpoints for a line, ent1:
(subst (cons 10 (cdr (assoc 11 ent1))) ent1)
and
(subst (cons 11 (cdr (assoc 10 ent1))) ent1)
but thought I would use a dummy variable to store the first while I overwrite it with the second.

boy, that was as clear as mud.

what I guess I ought to do is bite the bullet and (entdel (car (assoc -1 ent1))) and then
(entmake (list ( '(0 . "LINE")......(cons 10 (cdr (assoc 11 ent1))) (cons 11 (cdr (assoc 10 ent1)))...)

If I understand your need, a simplistic solution:

Code: [Select]
(defun _SwapEndpoints ( line_ename )
    (entmod
        (mapcar
            (function
                (lambda ( pair / key val )
                    (cond
                        ((eq 10 (setq val (cdr pair) key (car pair))) (cons 11 val))
                        ((eq 11 key) (cons 10 val))
                        (pair)
                    )
                )
            )
            (entget line_ename)
        )
    )
)

I use this to 'permute' the values of two variables:

Code: [Select]
(defun _permute ( *a *b / c )
  (setq c (eval *a))
  (set *a (eval *b))
  (set *b c)
)

Requires quoted symbols, for example:

Code: [Select]
_$ (setq a 10 b 15)
_$ (_permute 'a 'b)
_$ a
15
_$ b
10

Why the asterisks? Because the quoted symbols cannot match the symbols used as arguments for the subfunction and using asterisks decreases this risk.

Good stuff Lee but it requires the caller knows about _permute's implementation, i.e. the caller cannot pass a var named c, lest he not get what he expects. Probably better to name the local something like local_temp_variable to reduce the chance of a name collision. Having said that I'm still not an advocate of the use of set in this context as it can lead to woes for anyone trouble shooting the code down the road, particularity for those that didn't author the code originally.

This operation always reminds me of indirect addressing - a mind-boggling concept in itself.

My HP-41CX relied heavily on indirect addressing for its programming, loved that thing.
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: arguments and variables
« Reply #8 on: June 23, 2011, 07:45:40 PM »
Good stuff Lee but it requires the caller knows about _permute's implementation, i.e. the caller cannot pass a var named c, lest he not get what he expects. Probably better to name the local something like local_temp_variable to reduce the chance of a name collision. Having said that I'm still not an advocate of the use of set in this context as it can lead to woes for anyone trouble shooting the code down the road, particularity for those that didn't author the code originally.

Thanks Michael :-)  That's a good point about the local variable 'c', I'd certainly overlooked that. But I agree that the use of 'set' could be a nightmare to debug should something go wrong - an in-line 'setq' would be much more readable, and without the risk of using duplicate symbols.

Code: [Select]
(setq
    tmp  var1
    var1 var2
    var2 tmp
)

This operation always reminds me of indirect addressing - a mind-boggling concept in itself.

My HP-41CX relied heavily on indirect addressing for its programming, loved that thing.

Pointers must be a walk in the park for you  :lol:

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: arguments and variables
« Reply #9 on: June 23, 2011, 07:54:32 PM »
As for the task at hand, I would probably approach it this way:

Code: [Select]
(defun _SwapEnds ( line )
  ( (lambda ( elist ) (entmod (list (cons -1 line) (cons 10 (cdr (assoc 11 elist))) (cons 11 (cdr (assoc 10 elist))))))
    (entget line)
  )
)

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: arguments and variables
« Reply #10 on: June 23, 2011, 07:57:40 PM »
(Blackberry brevity)...

Consider (mapcar 'set '(a b) (list b a))

Should work, but I'm not at my computer to verify.

:)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

Lee Mac

  • Seagull
  • Posts: 12914
  • London, England
Re: arguments and variables
« Reply #11 on: June 23, 2011, 08:00:58 PM »
Consider (mapcar 'set '(a b) (list b a))

Should work, but I'm not at my computer to verify.

Indeed it does - great solution.

MP

  • Seagull
  • Posts: 17750
  • Have thousands of dwgs to process? Contact me.
Re: arguments and variables
« Reply #12 on: June 23, 2011, 08:08:07 PM »
Cool, thanks for letting me know Lee. :)
Engineering Technologist • CAD Automation Practitioner
Automation ▸ Design ▸ Drafting ▸ Document Control ▸ Client
cadanalyst@gmail.comhttp://cadanalyst.slack.comhttp://linkedin.com/in/cadanalyst

ronjonp

  • Needs a day job
  • Posts: 7529
Re: arguments and variables
« Reply #13 on: June 23, 2011, 08:24:24 PM »
(Blackberry brevity)...

Consider (mapcar 'set '(a b) (list b a))

Should work, but I'm not at my computer to verify.

:)

I like that  :-)

Windows 11 x64 - AutoCAD /C3D 2023

Custom Build PC

kdub_nz

  • Mesozoic keyThumper
  • SuperMod
  • Water Moccasin
  • Posts: 2140
  • class keyThumper<T>:ILazy<T>
Re: arguments and variables
« Reply #14 on: January 04, 2018, 01:05:38 AM »
(Blackberry brevity)...

Consider (mapcar 'set '(a b) (list b a))

Should work, but I'm not at my computer to verify.

:)

I like that  :-)




So do I.
and I know I'm late to the party.


Called Kerry in my other life
Retired; but they dragged me back in !

I live at UTC + 13.00

---
some people complain about loading the dishwasher.
Sometimes the question is more important than the answer.