## How do I pop PAIRS off an array to pass to a function?

If you have any questions, remarks, ... if you need help... its here...

### How do I pop PAIRS off an array to pass to a function?

I need to pop immutable pairs from an array onto the stack as two numbers each and apply those to another two numbers for a function that takes four numbers. Then do the same for the next pair in the array. I probably need to write myFunc to create a mutable array of pairs that are the sum of myCoord and myPairs (I don't know how yet!) For example:

tvar: myPairs
[[0,0],[-1,0],[-1,1]] to myPairs

: myfunc(x y s t -- )
for now just print the numbers
;

: ?OutOfBounds ( x y -- flag)
check to see if x,y coordinates are within a boundary -- arbitrary for now.
;

// #myfunc myPairs apply
// Each pair in MyPairs are applied to #myFunc as two numbers from an array of pairs.

tvar: myCoord
[4,4] to myCoord

: foo ( )
iftrue: (not (?outofbounds))
[ myCoord [#myFunc myPairs apply]
[ return ]
]
;

I hope this make's sense.
bobgillies

Posts: 60
Joined: 24 Jan 2017 06:26

### Re: How do I pop PAIRS off an array to pass to a function?

Ok, I found out how to pick at Pair off an array.

3 myPairs at .s

[-1, 1]

But I still don't know the word to put the -1 and 1 on the stack?
Like this:

-1 1
bobgillies

Posts: 60
Joined: 24 Jan 2017 06:26

### Re: How do I pop PAIRS off an array to pass to a function?

Geez, I can also use #at.
bobgillies

Posts: 60
Joined: 24 Jan 2017 06:26

### Re: How do I pop PAIRS off an array to pass to a function?

Yes, you can use #at, or you can use :
- #first to push the first element of a list and #second the retrieve the second one.

Otherwise :

1) unless this is a factor, I don't understand why #myfunc does not takes 2 pairs as parameters instead of four numbers.
If I had to write it, I made it take 2 pairs as paramters and let it do the job with those two pairs.

2) Yes #apply allows to apply #myFunc on each element into the receiver.

3) What is the result of myfunc. Is there a result ? Does it leaves something on the stack ?

4) As for #foo, well... this code won't work.
What if #foo is supposed to do ?
But if you want to send 2 pairs (or four numbers to #myFunc for each pair into an array, you can write :

Code: Select all
`: foo   #[ dup ?outOfBounds ifFalse: [ myCoord myFunc ] ]    myPairs apply;`

or, using the #forEach syntax and not a block :

Code: Select all
`: foo| p |   myPairs forEach: p [      p outOfBound? ifFalse: [ p myCoord myFunc ]      ];`

Or (as an advanced code...), use #applyIf, that applies only if a condition if true

Code: Select all
`: foo   myPairs applyIf( #[ outOfBounds not ], #[ myCoord myFunc ] );`

btw, If #foo does not have parameters, ( and ) and not required (and should not be here, I think.

Franck
Franck

Posts: 155
Joined: 29 Oct 2014 19:01

### Re: How do I pop PAIRS off an array to pass to a function?

I've come across situation that I don't understand. I've previously loaded the Object class Matrix and their methods from another part of this board. First some code:

tvar: searchArea

[[-1,0],[-1,1],[0,1],[1,1],[1,0],[1,-1],[0,-1],[-1,-1]] to searchArea

When I type in this snippet of forth words at the REPL, I get the correct result:

4 searchArea at 1 over at swap 2 swap at
>1 1

But here's an exception that's returned when I've coded this snippet as a colon definition.

: test ( n a -- x y) at 1 over at swap 2 swap at ;

4 searchArea test
>[stdin:1:17] ExRuntime : String null does not understand method <#at>

Why the different behaviors between typing in words at the REPL as opposed to being defined as a colon definition?

Bob
bobgillies

Posts: 60
Joined: 24 Jan 2017 06:26

### Re: How do I pop PAIRS off an array to pass to a function?

Whhooppsie. I forget to place the parameters back on the stack:

: test ( n a -- x y)
n a at 1 over at swap 2 swap at
;

This works.
bobgillies

Posts: 60
Joined: 24 Jan 2017 06:26

### Re: How do I pop PAIRS off an array to pass to a function?

Franck wrote:

1) unless this is a factor, I don't understand why #myfunc does not takes 2 pairs as parameters instead of four numbers.
If I had to write it, I made it take 2 pairs as paramters and let it do the job with those two pairs.

3) What is the result of myfunc. Is there a result ? Does it leaves something on the stack ?

4) As for #foo, well... this code won't work.
What if #foo is supposed to do ?
But if you want to send 2 pairs (or four numbers to #myFunc for each pair into an array, you can write :

btw, If #foo does not have parameters, ( and ) and not required (and should not be here, I think.

Franck

Hi Franck, thank you for the points. In answer to your questions you posed:

#1. I'll try your suggestion. I'm still investigating how I'll factor sections of the code in places.
#2. My myFunc is still at it's embryonic stage. It's the heart of the process and will be looped. I'm still not sure yet if what parameters it will ultimately take or leave on the stack. I'm trying to abstain from using global variables (tvar: ) but will have to till I get my stack juggling in focus.
#4. Foo is pre-embryonic stage and I'm still figuring out in the logic which functions that do something go somewhere in some type of loop or list processing. I was seeking answers before even knowing the questions I should be asking!

Basically I'm looking at all the Higher Functions (map, apply ,etc) to see which HF would be bested suited for what is essentially an array scanning algorithm. I've very interest in apply with conditions, but I'm still groking the concept(s).

I'm pretty much a neophyte in coding matters. Self taught in fact. The last time I did anything substantial was F79 standard stuff in the 80's!
bobgillies

Posts: 60
Joined: 24 Jan 2017 06:26

### Re: How do I pop PAIRS off an array to pass to a function?

bobgillies wrote:Whhooppsie. I forget to place the parameters back on the stack:

: test ( n a -- x y)
n a at 1 over at swap 2 swap at
;

This works.

If you use parameters just to push them back on the stack, it is better to not declare them.

Code: Select all
`: test         \ n a -- x y   at 1 over at swap 2 swap at  ;`

Even if you declare #test like that, you can still call it both way :
Code: Select all
` 1 [ [ 1, 2 ], { 3, 4 ] testtest(1, [ [ 1, 2 ], { 3, 4 ])`

If you want to retrieve items of the pair, you can just use #first and #second :
Code: Select all
`: test         \ n a -- x y   at dup first swap second  ;`

Or just use #items (push items of a collection on the stack)

Code: Select all
`: test         \ n a -- x y   at items  ;`

Franck
Franck

Posts: 155
Joined: 29 Oct 2014 19:01

### Re: How do I pop PAIRS off an array to pass to a function?

Items. That's the word I needed!

Regards,
Bob
bobgillies

Posts: 60
Joined: 24 Jan 2017 06:26