What is the best way to define and initialize a Table?

162 Views Asked by At

In Python, we can do this.

board = {'us': {'name': 'USA', 'govern': 'good'}, 
         'canada': {'name': 'Canada', 'govern': 'good'},
         'uk': {'name': 'UK', 'govern': 'good', 'recruit': 3},
         'spain': {'name': 'Spain', 'govern': 'good', 'schengen': True, 'recruit': 2},
         'france': {'name': 'France', 'govern': 'good', 'schengen': True, 'recruit': 2},
         'italy': {'name': 'italy', 'govern': 'good', 'schengen': True} }

to create a dictionary of name value pairs for easy lookup. Can I the the same in Stanza language, like:

deftype Countries <: Table<String,Table<String,?>>  
; value could be anything. we see Int|String|True|False here
    
val board : Countries = to-table( "us" => ( "name" => "USA", "govern" => "good" ), ....)

?

2

There are 2 best solutions below

0
On

I kind of come up with a solution:

defpackage labyrinth :
   import core
   import collections

deftype Countries <: HashTable<String,?>

defn print-deep ( xs : HashTable<String,?> ) :
   for x in xs do :
      val k = key(x)
      val v = value(x)
      print("%_ => " % [k])
      match(v):
         (v: HashTable<String,?>) : (print("[ "), print-deep(v), println("]"))
         (v) : ( print(v), print(", ") )

defn to-hashtable ( t : HashTable<String,?>, kvs : Tuple<KeyValue<?,?>> ) -> False :
   for kv in kvs do :
      val k = key(kv)
      val v = value(kv)
      match(k) :
         (k : String) : 
            if v is Tuple<?> :
               var d : HashTable<String,?> = HashTable<String,?>()
               to-hashtable(d, v)
               set(t, k, d)
            else :
               t[k] = v               
  

defn to-countries ( kvs : Tuple<KeyValue<String,?>> ) -> HashTable<String,?> :
   val t : HashTable<String,?> = HashTable<String,?>()
   to-hashtable(t, kvs)
   t
   
   
defn test () -> HashTable<String,?> :
   val c : Tuple<KeyValue<String,?>> = 
   [ "us" => ["name" => "us", "govern" => "good"]
     "canada" => [ "name" => "Canada" "govern" => "good" ]
     "uk" => [ "name" => "UK" "govern" => "good" "recruit" => 3 ]
     "spain" => [ "name" => "Spain" "govern" => "good" "schengen" => true "recruit" => 2 ]
     "france" => [ "name" => "France" "govern" => "good" "schengen" => true "recruit" => 2 ]
     "italy" => [ "name" => "italy" "govern" => "good" "schengen" => true ]
   ]
   val countries = to-countries(c)
   countries
   
   
val board = test()
print-deep(board)
6
On

The closest data structure to a python dictionary in stanza is Hashtable, from collections. You can do something like :


; to-hashtable<K,V> can be found in collections, too!
val board = to-hashtable<String, HashTable<String, ?>> $ [
  "us" => to-hashtable<String, ?> $ [
    "name" => "USA"
  ],
  "fr" => to-hashtable<String, ?> $ [
    "name" => "France"
  ]
  ; .. etc ... 
]

println(board["us"])

This will output :

HashTable(
  "name" => "USA")

deftype Countries <: Table<...> doesn't create an alias for Table, it declares a new type. In order to use it like a table, you would need to implement the required methods for Table.


But normally we like to add more type information, not less!

defenum Government : 
  Democracy
  Republic
  Monarchy  

defstruct Country :
  name:String,
  gov:Government
  ; ... etc ... 

val board = to-hashtable<String,Country> $ [
  "us" => Country(name, gov) where : 
    val name = "USA"
    val gov  = Republic
  "fr" => Country(name, gov) where : 
    val name = "France"
    val gov  = Republic
]