Mercurial > repos > other > SevenLanguagesInSevenWeeks
annotate 2-Io/day3-DSL.io @ 47:409249712590
Add final experimentation and note about DSL
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 22 Sep 2017 19:48:13 +0100 |
parents | eac30c1b92da |
children |
rev | line source |
---|---|
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
1 # Creating a simple "domain-specific language" |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
2 # (Except it's not really - it's just a little extension to support |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
3 # the "{ key:value[, key:value[…]] }" format of specifying dictionaries) |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
4 |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
5 # Because this is a string then we can do it at any time! |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
6 OperatorTable addAssignOperator(":", "atPutThing") |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
7 |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
8 # curlyBrackets is an automatically invoked function from the parser whenever |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
9 # it encounters curly brackets. |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
10 # This is hidden black magic that you need to know about to override it. |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
11 # It appears to call the method for all of the content within the brackets. |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
12 curlyBrackets := method( |
44
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
13 # Create a map |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
14 map := Map clone |
44
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
15 # Foreach arg that got passed (each comma-separated line within the brackets) |
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
16 # then run that on the map |
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
17 # Note: It isn't clear why ":" operates on the map at this point |
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
18 # The book says "we'll execute `map atPutThing(a, b)`" but why? |
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
19 # Colon was originally on a string, not the map, so how does it know to invoke on the map? |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
20 call message arguments foreach(arg, |
44
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
21 # Based on the following println then it is already "atPutThing(a, b)" by this point |
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
22 # but the ordering still doesn't make sense. |
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
23 # See also http://iolanguage.org/guide/guide.html#Syntax-Operators |
45
8a2451a7b86e
Add another thought about how the ":" operator works
IBBoard <dev@ibboard.co.uk>
parents:
44
diff
changeset
|
24 # |
8a2451a7b86e
Add another thought about how the ":" operator works
IBBoard <dev@ibboard.co.uk>
parents:
44
diff
changeset
|
25 # It *might* be a side-effect of how addAssignOperator works and then the map hijacks |
8a2451a7b86e
Add another thought about how the ":" operator works
IBBoard <dev@ibboard.co.uk>
parents:
44
diff
changeset
|
26 # the values, but that isn't clear from the book OR the documentation! |
44
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
27 #arg println |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
28 map doMessage(arg) |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
29 ) |
44
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
30 # Return the map (last line's return is the return) |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
31 map |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
32 ) |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
33 |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
34 Map atPutThing := method( |
44
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
35 # Call the standard method |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
36 self atPut( |
44
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
37 # And pull the call args to pass through |
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
38 # NOTE: arg 1 has its quotes stripped automatically because it's a number |
6347bacb3be7
Add more notes about the DSL while I think about it
IBBoard <dev@ibboard.co.uk>
parents:
43
diff
changeset
|
39 # or some other magic! |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
40 call evalArgAt(0) asMutable removePrefix("\"") removeSuffix("\""), |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
41 call evalArgAt(1) |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
42 ) |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
43 ) |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
44 |
46
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
45 # Note: Trailing commas break things in COMPLETELY CRYPTIC WAYS |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
46 # This is because we use doString, which executes it as a program, |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
47 # BUT the stack trace doesn't make this clear, so you end up chasing |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
48 # bugs in ENTIRELY THE WRONG PART OF THE CODE. |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
49 # Eval considered harmful. |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
50 the_string := "{ |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
51 \"foo\": \"12345\", |
46
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
52 \"bar\": \"7890\" |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
53 }" |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
54 |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
55 phoneNumbers := doString(the_string) |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
56 phoneNumbers keys println |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
57 phoneNumbers values println |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
58 |
46
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
59 # It feels like implementing something like this should work, |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
60 # but it doesn't because "Number does not respond to ':'" |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
61 # because we assigned ":" as an assignment operator (like :=) |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
62 # and not as a normal operator, although it's then EVEN LESS CLEAR |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
63 # how the code in curlyBrackets works |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
64 # Also, Io Language docs are poor and don't make it clear how to: |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
65 # a) define a range that works; or |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
66 # b) do ANYTHING with the OperatorTable |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
67 Number atPutThing := method( |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
68 call println |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
69 return Range (call target) to(call evalArgAt(1)) |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
70 ) |
eac30c1b92da
Add more notes and try to understand the operators
IBBoard <dev@ibboard.co.uk>
parents:
45
diff
changeset
|
71 |
47
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
72 |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
73 # But presumably this will break, because there's no "atPutThing" method |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
74 a := 1 |
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
75 b := 5 |
47
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
76 #range := a : b |
43
d2764720ea17
Add the Day 3 'Domain Specific Language'
IBBoard <dev@ibboard.co.uk>
parents:
diff
changeset
|
77 # Yep - "Exception: Number does not respond to ':'" |
47
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
78 # So you've got to be careful for reusable operators |
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
79 |
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
80 # We can't even define the method and have it Just Work™. |
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
81 # I know officially give up. This is undocumented and unclear. |
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
82 # |
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
83 #atPutThing := method(start, end, |
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
84 # return Range(start) to(end) |
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
85 #) |
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
86 # |
409249712590
Add final experimentation and note about DSL
IBBoard <dev@ibboard.co.uk>
parents:
46
diff
changeset
|
87 #range : 1 3 |