Skip to main content

Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
TagsGame Engines
(1 edit)

I found a bit of behavior I found unintuitive and wanted to highlight it, since it took me a bit of time to understand and work around. Apologies if this is already a known factor.

First: The empty list () evaluates to false.

But also: !() evaluates to false.

I think what’s happening here is that !, as a unary operator, is propagated to every element of the list. For the empty list, the result of that operation is the empty list. The reason this came up is because I was trying to test for the presence of a value in a Decker grid, like so:

extract where index=idx from grid.value

This returns a list that contains the value of the first column where index=idx if it exists and an empty list if it doesn’t. I only wanted to take action if there was no entry, so I tried to negate it like so…

if !(extract where index=idx from grid.value)
 # do something
end

…which didn’t work. So now I’m using my workaround:

if extract where index=idx from grid.value
 0 # essentially a no-op here
else
 # do something
end

…which does work.

If I understand correctly, you should be able to do this more straightforwardly with

if grid.value[idx]
 # ...
end

Indexing a table with a number fetches the corresponding row of the table as a dictionary, which will be "truthy" so long as the table has at least one column. If the row does not exist, indexing in this manner will result in nil, which is a "falsey" value:

t:insert a b with 11 22 33 44 55 66 end 
# +----+----+
# | a  | b  |
# +----+----+
# | 11 | 22 |
# | 33 | 44 |
# | 55 | 66 |
# +----+----+
t[2]
# {"a":55,"b":66}
t[-1]~nil
# 1
t[3]~nil
# 1

Another approach would be to use the "count" operator to determine the number of rows in the table, and compare that to "idx":

count t
# 3

Does that help at all?

(+1)

It doesn’t, but only because I simplified the example in my comment. I’m actually testing based on a column value, and I probably should have called my fake column “id” instead of “index”. In that case, a little testing in the listener gave me a workable pattern like the one you suggested. For example, testing if a row with id=5 exists looks like:

if 5 in grid.value.id
 # ...
end

…which looks much better, but unfortunately, my actual grid is using a compound key. Consider:

t:insert page id text with 1 1 "frst" 1 2 "scnd" 2 1 "pg2" end
# +------+------+------+
# | page |  id  | text |
# +------+------+------+
# |    1 |    1 | frst |
# |    1 |    2 | scnd |
# |    2 |    1 | pg2  |
# +------+------+------+

And what I want to do is check to see if a given entry is the last entry for that page, which I’m doing by checking to see if the entry afterwards exists. So:

p:1
i:2
if extract where page=p where id=i+1 from t
 0
else
 # this executes, as page 1 id 3 is not in the table
end

i:1
if extract where page=p where id=i+1 from t
 0
else
 # this doesn't, as page 1 id 2 is in the table
end

Maybe there’s a cleaner way to do this, but if there is, I haven’t found it yet.

Well, you can apply the "join" operator to a pair of lists to zip them together into tuples:

t.page join t.id
# ((1,1),(1,2),(2,1))

You can use the "in" operator to search for a tuple, but you'll have to enlist the tuple and then unpack the result from a count-1 list to avoid searching for individual components of the tuple in the zipped list:

(1,2) in t.page join t.id
# (0,0)
first (list 1,2) in t.page join t.id
# 1
first (list 1,3) in t.page join t.id
# 0