We show below an html highlighted version of the Goal file
found at
examples/lil.goal
in the repos.
/ Translation of Lil examples (as of 2024-09-12) from the manual:
/ https://beyondloom.com/decker/lil.html#lilthequerylanguage
/ For each example, the Lil version is written in a comment, followed by the
/ translation(s) in Goal, and then by the ouput (when appropriate).
(env"GOALLIB")or"GOALLIB"env"../lib"
import!"fmt math table" / assuming GOALLIB contains now goal's lib directory
pp:fmt.tbl[;0i-1;0i-1;"%.1f"] / pretty-printing function for tables
/ people.name:"Alice","Sam","Thomas","Sara","Walter"
/ people.age:25,28,40,34,43
/ people.job:"Developer","Sales","Developer","Developer","Accounting"
/ people:table people
people:..[
name:!"Alice Sam Thomas Sara Walter"
age:25 28 40 34 43
job:!"Developer Sales Developer Developer Accounting"
]
/ select from people
pp people
/ === Table 5x3 ===
/ name age job
/ -------- --- ------------
/ "Alice" 25 "Developer"
/ "Sam" 28 "Sales"
/ "Thomas" 40 "Developer"
/ "Sara" 34 "Developer"
/ "Walter" 43 "Accounting"
/ select name from people
pp(,"name")#people
pp people[;"name"]
/ === Table 5x1 ===
/ name
/ --------
/ "Alice"
/ "Sam"
/ "Thomas"
/ "Sara"
/ "Walter"
/ select firstName:name dogYears:7*age from people
pp people....[firstName:name;dogYears:7*age]
/ === Table 5x2 ===
/ firstName dogYears
/ --------- --------
/ "Alice" 175
/ "Sam" 196
/ "Thomas" 280
/ "Sara" 238
/ "Walter" 301
/ select name where name like "S*" from people
pp("name";..rx/^S/name)#people
pp("name";.."S*"%name)#people
/ === Table 2x1 ===
/ name
/ ------
/ "Sam"
/ "Sara"
/ select name index orderby name asc from people
pp(..x@<name)people[;"name"]..[index:!#name]
pp@|"index""name"!people..1(name@)\<name
/ === Table 5x2 ===
/ name index
/ -------- -----
/ "Alice" 0
/ "Sam" 1
/ "Sara" 3
/ "Thomas" 2
/ "Walter" 4
/ select name job by job orderby name asc from people
pp(..x@<%job)(..x@<name)"name""job"#people
/ === Table 5x2 ===
/ name job
/ -------- ------------
/ "Alice" "Developer"
/ "Sara" "Developer"
/ "Thomas" "Developer"
/ "Sam" "Sales"
/ "Walter" "Accounting"
/ select name job orderby (job join name) asc from people
pp(..x@<job)(..x@<name)"name""job"#people
/ === Table 5x2 ===
/ name job
/ -------- ------------
/ "Walter" "Accounting"
/ "Alice" "Developer"
/ "Sara" "Developer"
/ "Thomas" "Developer"
/ "Sam" "Sales"
/ select employed:(count name) job by job from people
pp table.join["job";table.by["job";{..[employed:=y]};people];people[;"job"]]
pp (..x@&employed)table.by["job";{..[employed:=y]};people]
pp people[;"job"]..[employed:(=q.by)q.by:%job] / original order
/ === Table 5x2 ===
/ job employed
/ ------------ --------
/ "Developer" 3
/ "Developer" 3
/ "Developer" 3
/ "Sales" 1
/ "Accounting" 1
/ select employed:(count name) job:(first job) by job from people
pp table.by["job";{..[employed:=y]};people]
pp people....[job:?job;employed:=%job]
/ === Table 3x2 ===
/ job employed
/ ------------ --------
/ "Developer" 3
/ "Sales" 1
/ "Accounting" 1
/ on avg x do (sum x) / count x end
/ select job:(first job) avg_age:avg[age] by job from people
pp table.by["job";....[avgage:math.avg'=age!y];people]
pp people....[job:?job;avgage:math.avg'=age!%job]
/ === Table 3x2 ===
/ job avgage
/ ------------ ------
/ "Developer" 33.0
/ "Sales" 28.0
/ "Accounting" 43.0
/ update job:"Engineer" where job="Developer" from people
pp people..[job[&job="Developer"]:"Engineer"]
/ === Table 5x3 ===
/ name age job
/ -------- --- ------------
/ "Alice" 25 "Engineer"
/ "Sam" 28 "Sales"
/ "Thomas" 40 "Engineer"
/ "Sara" 34 "Engineer"
/ "Walter" 43 "Accounting"
/ update manager:random[name] where job="Developer" from people
pp people..[manager:("";*1?name)job="Developer"]
/ === Table 5x4 ===
/ name age job manager
/ -------- --- ------------ -------
/ "Alice" 25 "Developer" "Sam"
/ "Sam" 28 "Sales" ""
/ "Thomas" 40 "Developer" "Sam"
/ "Sara" 34 "Developer" "Sam"
/ "Walter" 43 "Accounting" ""
/ jobs:extract first job by job from people
say$jobs:?people..job
/ "Developer" "Sales" "Accounting"
/ extract value orderby value asc from jobs
say$^jobs
/ "Accounting" "Developer" "Sales"
/ extract index orderby value asc from jobs
say<jobs
/ 2 0 1
/ extract value orderby index desc from jobs
say$|jobs
/ "Accounting" "Sales" "Developer"
/ extract list index by value from "ABBAAC"
say{=(!#x)!%x}@""\"ABBAAC"
/ (0 3 4
/ 1 2
/ ,5)
/ extract list value by floor index/3 from "ABCDEFGHI"
say-3$""\"ABCDEFGHI"
/ ("A" "B" "C"
/ "D" "E" "F"
/ "G" "H" "I")
/ extract first value by value from "ABBAAC"
say$?""\"ABBAAC"
/ "A" "B" "C"
/ extract a:first age b:last age orderby age asc from people
say((..x@<age)people)....[a:*age;b:*|age]
/ !["a" "b"
/ 25 43]
/ extract orderby value asc from "BEDAC"
say$^""\"BEDAC"
/ "A" "B" "C" "D" "E"
/ insert name job age with "John" "Writer" 32 end
pp@..[name:,"John";job:,"Writer";age:,32]
/ === Table 1x3 ===
/ name job age
/ ------ -------- ---
/ "John" "Writer" 32
/ insert name job age with "John" "Writer" 32 into people
pp people,'..[name:"John";job:"Writer";age:32]
/ === Table 6x3 ===
/ name age job
/ -------- --- ------------
/ "Alice" 25 "Developer"
/ "Sam" 28 "Sales"
/ "Thomas" 40 "Developer"
/ "Sara" 34 "Developer"
/ "Walter" 43 "Accounting"
/ "John" 32 "Writer"
/ jobs:insert job salary with
/ "Sales" 85000
/ "Developer" 75000
/ "Accounting" 60000
/ "Facilities" 50000
/ end
jobs:"job""salary"!+(
"Sales" 85000
"Developer" 75000
"Accounting" 60000
"Facilities" 50000
)
/ people join jobs
pp table.join["job";people;jobs]
/ === Table 5x4 ===
/ name age job salary
/ -------- --- ------------ ------
/ "Alice" 25 "Developer" 75000
/ "Sam" 28 "Sales" 85000
/ "Thomas" 40 "Developer" 75000
/ "Sara" 34 "Developer" 75000
/ "Walter" 43 "Accounting" 60000
/ guests:insert name with "Alice" "Joan" "Oscar" "Thomas" end
/ select a:name b:name_ where name < name_ from guests cross guests
pp(1;..a<b)#"a""b"!+,/{x,`´x}@!"Alice Joan Oscar Thomas" / same order
pp(1;..a<b)#"a""b"!{x@´!2##x}@!"Alice Joan Oscar Thomas" / odometer's order (more efficient)
/ === Table 6x2 ===
/ a b
/ ------- --------
/ "Alice" "Joan"
/ "Alice" "Oscar"
/ "Alice" "Thomas"
/ "Joan" "Oscar"
/ "Joan" "Thomas"
/ "Oscar" "Thomas"
/ "name" take people
pp(,"name")#people
/ === Table 5x1 ===
/ name
/ --------
/ "Alice"
/ "Sam"
/ "Thomas"
/ "Sara"
/ "Walter"
/ ("age","job") take people
pp"age""job"#people
pp people[;"age""job"] / same but reorder columns (if order were different)
/ === Table 5x2 ===
/ age job
/ --- ------------
/ 25 "Developer"
/ 28 "Sales"
/ 40 "Developer"
/ 34 "Developer"
/ 43 "Accounting"
/ 3 drop people
pp 3_'people
/ === Table 2x3 ===
/ name age job
/ -------- --- ------------
/ "Sara" 34 "Developer"
/ "Walter" 43 "Accounting"
/ (0,2,3) take people
pp people 0 2 3
/ === Table 3x3 ===
/ name age job
/ -------- --- -----------
/ "Alice" 25 "Developer"
/ "Thomas" 40 "Developer"
/ "Sara" 34 "Developer"
/ expenses:insert kind jan feb with
/ "tax" 11 55
/ "gas" 22 66
/ "power" 33 77
/ "food" 44 88
/ end
expenses:(!"kind jan feb")!+(
"tax" 11 55
"gas" 22 66
"power" 33 77
"food" 44 88
)
/ flip expenses
pp table.flip expenses
/ === Table 2x5 ===
/ key tax gas power food
/ ----- --- --- ----- ----
/ "jan" 11 22 33 44
/ "feb" 55 66 77 88
/ "key" drop flip expenses
pp (,"key")^table.flip expenses
/ === Table 2x4 ===
/ tax gas power food
/ --- --- ----- ----
/ 11 22 33 44
/ 55 66 77 88
/ denormal: select "with \"escapes":index "count":value from "ABC"
pp denormal:{..["with \"escapes":!#x;count:x]}@""\"ABC"
/ === Table 3x2 ===
/ with "escapes count
/ ------------- -----
/ 0 "A"
/ 1 "B"
/ 2 "C"
/ insert "pet name" "pet species" with
/ "Galena" "Chicken"
/ "Pippi" "Chicken"
/ "Chester" "Toad"
/ end
pp "pet name" "pet species"!+(
"Galena" "Chicken"
"Pippi" "Chicken"
"Chester" "Toad"
)
/ === Table 3x2 ===
/ pet name pet species
/ --------- -----------
/ "Galena" "Chicken"
/ "Pippi" "Chicken"
/ "Chester" "Toad"
/ select where column["with \"escapes"]>0 from denormal
pp(1;{x["with \"escapes"]>0})#denormal
/ === Table 2x2 ===
/ with "escapes count
/ ------------- -----
/ 1 "B"
/ 2 "C"
/ # Example from https://beyondloom.com/blog/rankingoffruits.html
/ fruits:insert name sales with
/ "Cherry" 22
/ "Lime" 5
/ "Durian" 97
/ "Banana" 12
/ "Apple" 1
/ end
fruits:..[name:!"Cherry Lime Durian Banana Apple"
sales:22 5 97 12 1]
/ select orderby sales desc where !name like "D*" from fruits
pp(..x@>sales)(0;.."D*"%name)^fruits
/ === Table 4x2 ===
/ name sales
/ -------- -----
/ "Cherry" 22
/ "Banana" 12
/ "Lime" 5
/ "Apple" 1