DISABLE FDs (REMOVE ME).
[jackhill/mal.git] / chuck / notes.md
1 # Step 1
2
3 - What if I don't have an OOP language?
4 - types.qx could be more prominently mentioned...
5 - A table with all types and suggested object names would be hugely
6 useful
7 - Same for a list of all errors and their messages
8 - Mention return types and argument types consistently
9 - More on int/float and their grammar (int is mentioned implicitly in
10 the ASCII art, nothing on signs or bases or their lack of)
11 - Note that a string must be parsed for the `print_readably` thing to
12 work and mention how one could do that (like, by using a `read` or
13 `eval`-like thing or alternatively, chopping off the surrounding
14 quotes and doing the inverse transformation of the printing)
15 - How is an atom printed?
16
17 # Step 2
18
19 - What if my language doesn't support lambdas, let alone passing
20 around named functions? Ideally write something about
21 implementing/using functors/delegates or replacing that namespace
22 with a big switch as with VHDL. Another problem is that if you
23 choose a different solution in step 4, step 2 could end up no longer
24 functional...
25 - What kind of error (read: what message?) is raised when no value can
26 be looked up for the symbol? Is it arbitrary? Do I need to extend
27 my error handling to allow for format strings?
28 - It would be worth a mention that you should extend the printer to
29 handle "native" functions (or in oldtimey terms, subrs)
30
31 # Step 3
32
33 - You should modify both eval_ast *and* EVAL
34 - Suggest the trick with destructuring the AST into `a0`, `a1`,
35 etc. variables for easier access. Perhaps this can be used to clear
36 up the general language used with AST manipulation (like, first
37 parameter and second list element)?
38 - What does def! return? Emacs Lisp for instance returns the symbol
39 whereas the tests suggest the value should be returned instead...
40
41 # Step 4
42
43 - "Implement the strings functions"
44 - The "no closures" paragraph isn't quite clear. Asides from that, do
45 native functions don't really need to be wrapped the same way as the
46 `fn*` objects, just introduce another type (like, a Subr and a Func
47 type) and do a check before applying the arguments to it
48 - Why does the guide say that the first argument of `count` can be
49 treated as list, yet there's a test performing `(count nil)` and
50 expecting zero as result?
51 - Does it make sense to compare, say, atoms in `=`?
52
53 # Step 5
54
55 - "This is especially important in Lisp languages because they tend to
56 prefer using recursion instead of iteration for control structures."
57 <- I'd argue it's less of a lisp thing (see everything else related
58 to CL) and more a thing functional programming proponents have
59 considered more elegant than introducing iteration constructs (see
60 haskell, ocaml, erlang)
61 - It's not really clear that the TCO change for `let*` involves the
62 form you'd normally pass to `EVAL` to become the new `ast`. I had to
63 reread this a few more times to understand that the "second `ast`"
64 is actually its third argument...
65 - Where did the check for `do` not being broken by TCO go?
66 - What's the deal with the `quux/tests/step5_tco.qx` file?
67
68 # Step 6
69
70 - "The closure calls the your EVAL function […]."
71 - I still don't have any closures. How the heck do I implement
72 `eval`? What about `swap!`?
73 - It would be useful to mention that `swap!` sort of requires
74 implementing `apply` first...
75
76 # Step 7
77
78 - Why the scare quotes for splicing?
79 - "Before implementing the quoting forms, you will need to implement
80 some supporting functions in the core namespace:" should be one list
81 item
82 - "this function takes a list as its second parameter and returns a
83 new list that has the first argument prepended to it." reads backwards
84 - The quasiquote paragraph is hard to read
85 - It's rather confusing to refer to the argument of `ast` and to an
86 `ast` parameter, perhaps name the latter a form?
87 - What could also help would be a visualization of the four
88 conditionals:
89 - \`42, \`()
90 - \`~foo
91 - \`(~@foo) and more
92 - \`(42 ~@foo) and everything else
93 - Mal/mal is inconsistently capitalized
94 - "Expand the conditional with reader `read_form` function to add the
95 following four cases" is again weird, better refer to the
96 `read_form` function in reader.qx
97 - "concat should support concatenation of lists, vectors, or a mix or
98 both." <- "or a mix or both" is redundant
99
100 # Step 8
101
102 - "In the previous step, quoting enabled some simple manipulation [of]
103 data structures"
104 - The macroexpand function step refers to call/apply, it's unclear how
105 to proceed if you don't have such a thing
106 - How should the exception for invalid `nth` access look like? Also,
107 why is it an exception and not an error like with the reader?
108 - How can `first` take a list (or vector), but work on `nil`?
109 - The description of `rest` is inconsistent with the tests
110 - "In the main program, use the rep function to define two new control
111 structures macros."
112 - Why does the definition of `cond` use `throw` although it's only
113 introduced in the next chapter?
114
115 # Step 9
116
117 - It's not really clear that you really just have a `try*` special
118 form, with `catch*` merely existing inside it...
119 - Another thing to clarify is that the exception value is a string
120 containing the message you'd see (unless you're using `throw`)
121 - Generally, it would be better to explain the general exception
122 handling mechanism (with some examples), then showing how one
123 implements it for both languages with and without exceptions
124 - Another way than using a global variable is introducing an error
125 type next to the other MAL types and checking whether something a
126 function returned is one, although the hint about returning one at
127 each use of `EVAL` still stands...
128 - Shouldn't either trick be mentioned at the beginning, simply because
129 you'll need it in a language without exceptions to do error handling?
130 - Why this bizarre treatment for `keyword`? Why is there no test for
131 it?
132 - Is there a test for whether hash maps deduplicate identical keys
133 when using `hash-map` or `assoc`?
134 - What exactly are keys the specification for `dissoc`, `get` and
135 `contains?` are speaking of? Can I assume these are either strings
136 or keywords?
137 - Why is it not documented that `get` may take `nil` instead of a map?
138 - Perhaps it's worth adding more tests involving symbols to ensure
139 that functions using apply internally don't evaluate their args?
140
141 # Step A
142
143 - "Add meta-data support to mal functions." <- Shouldn't you mention
144 that this involves implementing `with-meta` and `meta`?
145 - "TODO. Should be separate from the function macro flag." <- Why is
146 this even related?
147 - It would be worth to mention that `with-meta` shall clone its
148 argument to avoid one of the more sneaky test failure reasons
149 - "The value of this entry should be a mal string containing the name
150 of the current implementation."
151 - "When the REPL starts up (as opposed to when it is called with a
152 script and/or arguments), call the rep function with this string to
153 print a startup header: `"(println (str \"Mal
154 [\" *host-language* \"]\"))".`" <- proof that you better quote these
155 because the asterisks just disappear...