From: Karol Skocik
Subject: Help with a setfing value in structure
Date: 
Message-ID: <1146090852.617776.115090@v46g2000cwv.googlegroups.com>
Hi,
  I hope somebody helps me with following problem:
I have a structure :

(defstruct ssr-block core in out)

and I can have a array of such structures, called ssr.
To save some keystrokes I have a function :

(defun ssr-core (ssr index) (ssr-block-core (aref ssr index)))

The problem is that I can not use the function ssr-core
to set value of the core slot in the structure which is on
the index in array called ssr.

I can get the value with no problem :

GI> (ssr-core (make-array 10 :initial-element #s(ssr-block :core 10))
3)
10

But when I try to change the value of core like this :

GI> (setf (ssr-core (make-array 10 :initial-element #s(ssr-block :core
10)) 3) 20)

; in: LAMBDA NIL
;     (FUNCALL #'(SETF GI::SSR-CORE) #:G1346 #:G1348 #:G1347)
; ==>
;   (SB-C::%FUNCALL #'(SETF GI::SSR-CORE) #:G1346 #:G1348 #:G1347)
;
; caught STYLE-WARNING:
;   undefined function: (SETF SSR-CORE)

;
; caught STYLE-WARNING:
;   This function is undefined:
;     (SETF SSR-CORE)
;
; compilation unit finished
;   caught 2 STYLE-WARNING conditions

The function (SETF SSR-CORE) is undefined.
   [Condition of type UNDEFINED-FUNCTION]

Restarts:
  0: [ABORT-REQUEST] Abort handling SLIME request.
  1: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread"
{ABBAA51}>)

Backtrace:
  0: ("bogus stack frame")
  1: (SB-INT:EVAL-IN-LEXENV (SETF (SSR-CORE (MAKE-ARRAY 10
:INITIAL-ELEMENT #) 3) 20) #<NULL-LEXENV>)

I am using SBCL 9.10 on Gentoo Linux x86

Karol

From: Deon Garrett
Subject: Re: Help with a setfing value in structure
Date: 
Message-ID: <87fyk0uecm.fsf@clapton.csm.astate.edu>
"Karol Skocik" <············@gmail.com> writes:

> Hi,
>   I hope somebody helps me with following problem:
> I have a structure :
>
> (defstruct ssr-block core in out)
>
> and I can have a array of such structures, called ssr.
> To save some keystrokes I have a function :
>
> (defun ssr-core (ssr index) (ssr-block-core (aref ssr index)))
>
> The problem is that I can not use the function ssr-core
> to set value of the core slot in the structure which is on
> the index in array called ssr.

you can define the function with defsetf, but what you really want here is
the :conc-name option of defstruct.

(defstruct (ssr-block (:conc-name ssr-)) core in out)

(let ((foo (make-ssr-block :core 1 :in 2 :out 3)))
  (format t "~a ~a ~a~%" (ssr-core foo) (ssr-in foo) (ssr-out foo))
  (setf (ssr-core foo) 99)
  (format t "~a ~a ~a~%" (ssr-core foo) (ssr-in foo) (ssr-out foo)))

will print

1 2 3
99 2 3
From: Carl Taylor
Subject: Re: Help with a setfing value in structure
Date: 
Message-ID: <MaU3g.50261$az4.32105@bgtnsc04-news.ops.worldnet.att.net>
"Karol Skocik" <············@gmail.com> wrote in message 
·····························@v46g2000cwv.googlegroups.com...
> Hi,
>  I hope somebody helps me with following problem:
> I have a structure :
>
> (defstruct ssr-block core in out)
>
> and I can have a array of such structures, called ssr.
> To save some keystrokes I have a function :
>
> (defun ssr-core (ssr index) (ssr-block-core (aref ssr index)))
>
> The problem is that I can not use the function ssr-core
> to set value of the core slot in the structure which is on
> the index in array called ssr.
>
> I can get the value with no problem :
>
> GI> (ssr-core (make-array 10 :initial-element #s(ssr-block :core 10))
> 3)
> 10
>
> But when I try to change the value of core like this :
>
> GI> (setf (ssr-core (make-array 10 :initial-element #s(ssr-block :core
> 10)) 3) 20)

So it looks like you're trying to change all 10 instances of core to the 
same new value.  Pascal has given you code for that. If you ever want to 
control the settings of the slots of specific individual structures in the 
array, this should handle that situation.

(defstruct ssr-block core in out)
(defparameter *ssr* (make-array 10 :initial-element (make-ssr-block)))
(pprint *ssr*)

(defun set-ssr-core (index value)
  (let ((work-struct (copy-ssr-block (aref *ssr* index))))
    (setf (ssr-block-core work-struct) value)
    (setf (aref *ssr* index) work-struct)))

(set-ssr-core 2 123)
(set-ssr-core 7 666)
(pprint *ssr*)

Carl Taylor
From: Karol Skocik
Subject: Re: Help with a setfing value in structure
Date: 
Message-ID: <1146116124.602106.173280@i39g2000cwa.googlegroups.com>
Thanks a lot you for all your replies.
However, there is still one point which I can't understand :

Why this works :

GI> (let ((ssr (make-array 10 :initial-element #s(ssr-block :core 3))))
      (dotimes (i 10)
	(setf (aref ssr i) (make-ssr-block :core i)))
      (pprint ssr)
      (setf (ssr-block-core (aref ssr 2)) 66)
      (pprint ssr))



#(#S(SSR-BLOCK :CORE 0 :IN NIL :OUT NIL) #S(SSR-BLOCK :CORE 1 :IN NIL
:OUT NIL)
  #S(SSR-BLOCK :CORE 2 :IN NIL :OUT NIL) #S(SSR-BLOCK :CORE 3 :IN NIL
:OUT NIL)
  #S(SSR-BLOCK :CORE 4 :IN NIL :OUT NIL) #S(SSR-BLOCK :CORE 5 :IN NIL
:OUT NIL)
  #S(SSR-BLOCK :CORE 6 :IN NIL :OUT NIL) #S(SSR-BLOCK :CORE 7 :IN NIL
:OUT NIL)
  #S(SSR-BLOCK :CORE 8 :IN NIL :OUT NIL) #S(SSR-BLOCK :CORE 9 :IN NIL
:OUT NIL))
#(#S(SSR-BLOCK :CORE 0 :IN NIL :OUT NIL) #S(SSR-BLOCK :CORE 1 :IN NIL
:OUT NIL)
  #S(SSR-BLOCK :CORE 66 :IN NIL :OUT NIL)
  #S(SSR-BLOCK :CORE 3 :IN NIL :OUT NIL) #S(SSR-BLOCK :CORE 4 :IN NIL
:OUT NIL)
  #S(SSR-BLOCK :CORE 5 :IN NIL :OUT NIL) #S(SSR-BLOCK :CORE 6 :IN NIL
:OUT NIL)
  #S(SSR-BLOCK :CORE 7 :IN NIL :OUT NIL) #S(SSR-BLOCK :CORE 8 :IN NIL
:OUT NIL)
  #S(SSR-BLOCK :CORE 9 :IN NIL :OUT NIL))
; No value

but simple replacement of (ssr-block-core (aref ssr 2)) with :

GI> (let ((ssr (make-array 10 :initial-element #s(ssr-block :core 3))))
      (dotimes (i 10)
	(setf (aref ssr i) (make-ssr-block :core i)))
      (pprint ssr)
      (setf (ssr-core ssr 2) 66)
      (pprint ssr))

; in: LAMBDA NIL
;     (SETF (GI::SSR-CORE GI::SSR 2) 66)
; --> LET* MULTIPLE-VALUE-BIND LET FUNCALL
; ==>
;   (SB-C::%FUNCALL #'(SETF GI::SSR-CORE) #:G6 #:G8 #:G7)
;
; caught STYLE-WARNING:
;   undefined function: (SETF SSR-CORE)

makes that problem? 
Karol
From: Pascal Costanza
Subject: Re: Help with a setfing value in structure
Date: 
Message-ID: <4bbp7tF107e38U1@individual.net>
Karol Skocik wrote:
> Thanks a lot you for all your replies.
> However, there is still one point which I can't understand :
> 
> Why this works :
> 
> GI> (let ((ssr (make-array 10 :initial-element #s(ssr-block :core 3))))
>       (dotimes (i 10)
> 	(setf (aref ssr i) (make-ssr-block :core i)))
>       (pprint ssr)
>       (setf (ssr-block-core (aref ssr 2)) 66)
>       (pprint ssr))
[...]

> but simple replacement of (ssr-block-core (aref ssr 2)) with :
> 
> GI> (let ((ssr (make-array 10 :initial-element #s(ssr-block :core 3))))
>       (dotimes (i 10)
> 	(setf (aref ssr i) (make-ssr-block :core i)))
>       (pprint ssr)
>       (setf (ssr-core ssr 2) 66)
>       (pprint ssr))
> 
> ; in: LAMBDA NIL
> ;     (SETF (GI::SSR-CORE GI::SSR 2) 66)
> ; --> LET* MULTIPLE-VALUE-BIND LET FUNCALL
> ; ==>
> ;   (SB-C::%FUNCALL #'(SETF GI::SSR-CORE) #:G6 #:G8 #:G7)
> ;
> ; caught STYLE-WARNING:
> ;   undefined function: (SETF SSR-CORE)
> 
> makes that problem? 

'setf is a predefined macro that analyzes its first parameter in order 
to determine what code to produce to actually perform an assignment.

For example, try this:

(macroexpand-1 '(setf (svref v 1) 42))

The result could be something like this:

(SYSTEM::SET-SVREF V 1 42)

This means that 'setf has some way of mapping 'svref to an internal 
set-svref function, for example via an internal table.

If you define a struct, that mapping is automatically created for you:

(defstruct person name)

For example this...

(macroexpand-1 '(setf (person-name p) "Dilbert"))

...could expand into something like that:

(internal::set-person-name p "Dilbert")


The problem in your example is that you haven't "announced" the mapping 
from (setf (ssr-core ...) ...) to some actual setter function.

There are several ways to do this, like with defsetf or with a defun on 
(setf ssr-core). With the original defstruct you were "just" lucky that 
defstruct automatically does that for you.


I hope this helps.


Pascal


-- 
3rd European Lisp Workshop
July 3-4 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/
From: Karol Skocik
Subject: Re: Help with a setfing value in structure
Date: 
Message-ID: <1146146091.243024.29590@g10g2000cwb.googlegroups.com>
Ok, I think I understand.
  Thanks
    Karol
From: Pascal Costanza
Subject: Re: Help with a setfing value in structure
Date: 
Message-ID: <4bac9qF10k165U1@individual.net>
Karol Skocik wrote:
> Hi,
>   I hope somebody helps me with following problem:
> I have a structure :
> 
> (defstruct ssr-block core in out)
> 
> and I can have a array of such structures, called ssr.
> To save some keystrokes I have a function :
> 
> (defun ssr-core (ssr index) (ssr-block-core (aref ssr index)))
> 
> The problem is that I can not use the function ssr-core
> to set value of the core slot in the structure which is on
> the index in array called ssr.

(defun (setf ssr-core) (new-value ssr index)
   (setf (ssr-block-core (aref ssr index)) new-value))


Pascal

-- 
3rd European Lisp Workshop
July 3-4 - Nantes, France - co-located with ECOOP 2006
http://lisp-ecoop06.bknr.net/