GameMonkey Script

GameMonkey Script Forums
It is currently Thu Jul 18, 2019 5:18 pm

All times are UTC




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: GM and Data Query
PostPosted: Tue Jun 16, 2009 1:00 pm 
Offline

Joined: Thu Jan 01, 2004 4:31 pm
Posts: 307
I've been using LINQ a bit recently and in doing so it reminded me of a scripting environment I was working on years ago in that everything could be queries in sets.

I've noticed that Python has some data query behaviours and have been recently been considering adding something to GameMonkey Script.

Given a table of data items (be it a table of tables, or a table of your own entity types), you want to iterate over them to find all items that match a specific criteria.

In this example, it's a list of RPG entities which have a name, some hitpoints and a class identifier.

Code:
entities = {
    { name = "test1", hp = 10, class = "wizard" },
    { name = "test2", hp = 20, class = "warrior" },
    { name = "test3", hp = 30, class = "wizard" }
};


Now imagine you wanted to retrieve all items into a new table that had say less than 25 hit points... in normal GM you'd have to foreach over them and insert the items into a new table.

With some more query-like iteration syntax we could simplify this, maybe with something like this:

Code:
results = from(ent in entities; if(ent.hp <= 25));


Which would populate a table with each matching entity.

Or imagine you just wanted to iterate over them, how about something like:

Code:
from(ent in entities; if(ent.hp <= 25))
{
  print(ent.name, "is low on health");
}


You could combine the selective part using normal conditions, so:

Code:
injuredWarriors = from(ent in entities; if(ent.hp <= 25 && ent.class == "warrior"));


With this, you'd probably add "inrange", "exists" and other such keywords. The concept could probably be extended to allow "joins" across tables, but I'm not sure how that would look, maybe something like:

Code:
from(ent in entities join i in items on ent.inventory_id == i.id; if(i.name == "crossbow")
{
  print(ent.name, "has a crossbow");
}


As a general principle, is this something that could be used in GM, or does it exist in the realm of functional/non-C like languages only?


Top
 Profile  
Reply with quote  
 Post subject: Re: GM and Data Query
PostPosted: Wed Jun 17, 2009 3:32 am 
Offline

Joined: Fri Jan 14, 2005 2:28 am
Posts: 439
ideally, i'd prefer an extension to the foreach if possible, rather than allocating and building new tables, support modifiers to the foreach queries.

Code:
foreach(ent in entities where ent.hp < 25) {}


Top
 Profile  
Reply with quote  
 Post subject: Re: GM and Data Query
PostPosted: Wed Jun 17, 2009 7:19 am 
Offline

Joined: Thu Jan 01, 2004 4:31 pm
Posts: 307
foreach was my original choice actually, but I wondered if adding it to that operator would overcomplicate/confuse people. I like the ability to grab data into another table, but acknowledge that it might not be the best way to do it. How about adding in the "into" keyword so that the results are pushed into a table?

Code:
foreach(into res; ent in entities; if(ent.class == "wizard"));


Top
 Profile  
Reply with quote  
 Post subject: Re: GM and Data Query
PostPosted: Wed Jun 17, 2009 1:34 pm 
Offline

Joined: Mon Dec 15, 2003 1:38 pm
Posts: 708
My thought is that if the result is a new table, you are only saving a small amount of syntax on wrapping a template or inline style function. eg.
Code:
// Example data
entities = {
    { name = "test1", hp = 10, class = "wizard" },
    { name = "test2", hp = 20, class = "warrior" },
    { name = "test3", hp = 30, class = "wizard" }
};

// Wrapper for foreach plus filter
foreachfiltered = function(a_table, a_filter)
{
  result = {};
  foreach( ent in a_table )
  {
    if( a_filter(ent) )
    {
      result[ tableCount(result) ] = ent;
    } 
  };
  return result;
};

// Ok, rather ugly inlined function
result = foreachfiltered(entities,
                   function(a_entity) { if (a_entity.class == "wizard" ) { return true; } return false; } );

// Dump results
foreach( ent in result )
{
  print("ent.class", ent.class); 
};

// With some effort the wrapper could be implemented to look like:
//
// result = foreachfiltered(entities, `a_element.class == "wizard"` );
//
// Filters could be cached for efficiency.

My preference is toward DrEvil's suggested syntax, or one of your earlier ones without table populating. I don't know what limitations could or should exist.


Top
 Profile  
Reply with quote  
 Post subject: Re: GM and Data Query
PostPosted: Wed Jun 17, 2009 11:06 pm 
Offline

Joined: Fri Jan 14, 2005 2:28 am
Posts: 439
I would support the additional stuff in a more readable syntax, like at the end of the statement. I kinda like the 'where' example I gave, as it is easier to read than remembering the x 'argument' of the foreach (seperated by ;) is the condition, some other one is the table destination, etc.

IMO it flows off the tongue a bit better to read it like a sentence

Code:
foreach(ent in entities where (ent.hp < 25) into tbl) {}


it would seem odd to me that additional optional parameters would come in front of the normal stuff.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC


Who is online

Users browsing this forum: No registered users and 1 guest


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
cron
Powered by phpBB® Forum Software © phpBB Group