ghoetker
2018-6-4 15:56:05

May I please get some help with the following? It is probably obvious, but I can’t wrap my head around it.

I have two lists, keep-list and discard-list. I want a proceedure to move an item from one list to the other. The order of items within a list is inconsequential, each item is unique and I’m moving items one at a time. After each movement of an item, I want to display each list as it currently stands in a GUI (thanks to prior help, I have that part working). This may be followed by either moving another item between lists or taking a different action with the content of each list as input.

I’ve tried the following, but the lists remain unchanged outside of the move-from-to procedure. Clearly, I’m missing something, as I thought the effect set! would reach beyond the procedure.

Recognizing that mutating lists isn’t horribly Rackety, I’m almost sure this is possible. What would the right approach be?

Thank you!

#lang racket

(define (move-from-to from-list to-list item)
  (set! from-list (remove item from-list))
  (set! to-list (cons item to-list))
  (printf "from-list in function is ~a\n" from-list)
  (printf "to-list in function is ~a\n" to-list))

(define keep-list (list "a" "b" "c"))
(define discard-list (list "x" "y" "z"))

(move-from-to keep-list discard-list "c")
;==> from-list in function is (a b).  Looking good.
;==> to-list in function is (c x y z). Looking good.

(printf "keep-list outside function is ~a\n" keep-list)
;==> keep-list outside function is (a b c). Grr!

(printf "discard-list outside function is ~a\n" discard-list)
;==> discard-list outside function is (x y z). Grr!

lexi.lambda
2018-6-4 16:01:55

@ghoetker When you mutate from-list and to-list, that just modifies the bindings inside the move-from-to function, not keep-list or discard-list.


lexi.lambda
2018-6-4 16:03:12

This is the same as in most other programming languages. Assigning to a procedure argument doesn’t have any effects outside the procedure.


lexi.lambda
2018-6-4 16:04:13

In C terminology, set! updates what a variable points at, but it doesn’t change the value referenced by the pointer, nor does it affect any other variables that point at the same thing.


lexi.lambda
2018-6-4 16:04:31

Generally, avoid set!. You can probably accomplish what you want without it.


lexi.lambda
2018-6-4 16:05:03

For example, you could implement move-from-to as a function that returns two new lists instead of trying to update the old lists.


ghoetker
2018-6-4 16:24:18

@lexi.lambda Thank you very much. With your first hint, I was able to write a more specific procedure. Given that I only have two lists, this is manageable.

But, I’m still struggling with your closing comment. It understand what you mean and how to return two lists, but not how I would apply that to my current issue. I want to have a list of items displayed as choices in keep-list-box, and a second list displayed as choices in the discard-list-box ("keep" and "discard" happen after all of this). Even with a procedure two lists, I still end up needing to set the "keep-list" to one of the returned lists, putting me back in the same situation. Clearly, I'm missing a critical link here. Is the nature of my confusion clear enought that someone can help me resolve it? If it were easy to ask a list-box to return the choices it contains as a list, I see how I could grab that list, process it, and then(send keep-list-box set (process old-choices-from-keep-list-box)). But, the only way I've found to grab that list is to loop through the choices--seems inefficient, especially for a 5000 item list. Thank you.(define (move-from-keep-to-discard item) (set! keep-list (remove item keep-list)) (set! discard-list (cons item discard-list)) (printf "keep-list in function is ~a\n" keep-list) (printf "discard-list in function is ~a\n" discard-list))`


lexi.lambda
2018-6-4 16:25:35

Ah, you’re using racket/gui. That library is especially imperative. Maybe my comment doesn’t apply.


mishraantash34
2018-6-4 18:09:21

there’s a error showing render: is expected to return a scene, but it returned (make-game #<image> #<image>)


haymail
2018-6-4 18:16:14

@haymail has joined the channel


haymail
2018-6-4 18:20:49

Hi! I’ve built a chart using pict. lines go from labels to corresponding chunks of the chart using pin-line. It’s great, but pin-line draws a new version of the chart with the line. I need to do this eight times. I know I shouldn’t have eight functions, each using the chart drawn from the previous one, but that’s why I’m a beginner. What’s a more elegant way to approach this?


lexi.lambda
2018-6-4 18:22:00

for/fold ?


haymail
2018-6-4 18:23:35

That looks like it’ll do. Thank you!


joslarki
2018-6-4 18:45:36

@joslarki commented on @mishraantash34’s file <https://racket.slack.com/files/UB0K36KLK/FB0LLK81E/trying_to_move_a_ufo_in_y-axis_and_tank_in_x-axis.txt|trying to move a ufo in y-axis and tank in x-axis>: big-bang expects render to return a world, and it looks like your world is a number (tick handler is add1, main is called with 2) but render is returning a game struct


joslarki
2018-6-4 18:46:01

@joslarki commented on @mishraantash34’s file <https://racket.slack.com/files/UB0K36KLK/FB0LLK81E/trying_to_move_a_ufo_in_y-axis_and_tank_in_x-axis.txt|trying to move a ufo in y-axis and tank in x-axis>: err I mean image not world for your render function


joslarki
2018-6-4 18:48:32

@joslarki commented on @mishraantash34’s file <https://racket.slack.com/files/UB0K36KLK/FB0LLK81E/trying_to_move_a_ufo_in_y-axis_and_tank_in_x-axis.txt|trying to move a ufo in y-axis and tank in x-axis>: So you could try using overlay instead of make-game, in your render function. that’ll at least get something running. unsure of your goal, but you might want to make your world something that holds the necessary tank and ufo information instead of just numbers. does that help?


mishraantash34
2018-6-4 18:52:51

thanks that will help me a lot


haymail
2018-6-4 19:17:08

@lexi.lambda If you know of any additional for/fold learning resources, I’d be grateful. It’s a challenge for me to wrap my head around it just looking the explanation in the docs. Here’s a bit more context: (define (create-l-connector source label dest) (pin-line source label rc-find dest lc-find #:line-width 1 #:color "gray")) (define chart1 (create-l-connector chart-with-all-labels label-approved sub-approved)) (define chart2 (create-l-connector chart1 label-rejected sub-rejected)) (define chart3 (create-l-connector chart2 label-deleted sub-deleted)) (define chart4 (create-l-connector chart3 label-adjustments-required sub-adjustments)) This results in the following type of chart:


haymail
2018-6-4 19:17:24

lexi.lambda
2018-6-4 19:20:03

@haymail this should work (define (create-l-connector source label dest) (pin-line source label rc-find dest lc-find #:line-width 1 #:color "gray")) (for/fold ([chart chart-with-all-labels]) ([(label sub) (in-hash (hash label-approved sub-approved label-rejected sub-rejected label-deleted sub-deleted label-adjustments-required sub-adjustments))]) (create-l-connector chart label sub))


samth
2018-6-4 19:20:24

(for/fold ([chart chart-with-all-labels]) ([label (list label-approved label-rejected label-deleted label-adjustments-required)] [sub (list sub-approved sub-rejected sub-deleted sub-adjustments)]) (create-l-connector chart label sub))


samth
2018-6-4 19:20:31

or what Alexis said


haymail
2018-6-4 19:20:34

haha


lexi.lambda
2018-6-4 19:20:36

that works too :)


haymail
2018-6-4 19:22:44

Now I understand how it works since I know the parts :slightly_smiling_face: Thanks!