I have the follow function:
(define (seg-name seg val) (if val (nth-set 0 seg val)) (seg 0))
I want to be able to:
(set 'seg '("NM1" "85" "DEF"))
(println (seg-name seg)) ;; "NM1"
(seg-name seg "HL2")
(println (seg-name seg)) ;; "HL2" ---- that's what I want
(println (seg-name seg)) ;; "NM1" ---- is what I actually get
Is there any way to accomplish this? nth-set is a destructive operation, however, it appears to only be working on "seg" inside of the function, not the "seg" in the parent namespace.
Any thoughts?
Ok, I figured out this to make things work, but not sure if it's the right or best or even only way to do it:
(define-macro (seg-name seg val)
(if val (nth-set 0 (eval seg) val))
((eval seg) 0))
yes, you can do it that way, but you can also package your list into a name space and then pass it by reference:
(set 'seg:seg '("NM1" "85" "DEF"))
(define (seg-name s val)
(if val (nth-set (s 0) val)) (s 0))
> (seg-name seg "NEW-NAME")
"NEW-NAME"
> seg:seg
("NEW-NAME" "85" "DEF")
> (seg 0)
"NEW-NAME"
> (seg 1)
"85"
>
this works when using set-nth/nth-set with implicit indexing as in: (s 0)
Lutz
My understanding - which may be unreliable - is this. Your seg inside the function is a local symbol, which masks any global symbol with the same name, so you can't access it. To safely get a symbol into a function definition, make sure it stays unevaluated until the function runs:
(define (seg-name _seg _val)
(if _val
(nth-set 0 (eval _seg) _val)
((eval _seg) 0)))
(set 'seg '("NM1" "85" "DEF"))
(println (seg-name 'seg))
;-> NM1
(seg-name 'seg "HL2")
(println (seg-name 'seg))
;-> HL2
There's more about this in the manual under Passing objects by reference... Lutz shows a better way to do it, of course :-)
Yes this is all correct. With your last example we have now all three methods together to pass by reference:
(1) pass parameter as a quoted symbol into a 'define' function (cormullions example)
(2) pass parameter as an un-quoted symbols into 'define-macro' function (jermyc example)
(3) package data in namesspace using default symbol i.e. pass 'foo' 'foo:foo' and use implicit indexing (lutz example, see manual for variations)
Lutz