mirror of
https://github.com/kanaka/mal.git
synced 2024-09-20 10:07:45 +03:00
3.3 KiB
3.3 KiB
Step 1
- What if I don't have an OOP language?
- types.qx could be more promently mentioned...
- A table with all types and suggested object names would be hugely useful
- Same for a list of all errors and their messages
- Mention return types and argument types consistently
- More on int/float and their grammar (int is mentioned implicitly in the ASCII art, nothing on signs or bases or their lack of)
- Note that a string must be parsed for the
print_readably
thing to work and mention how one could do that (like, by using aread
oreval
-like thing or alternatively, chopping off the surrounding quotes and doing the inverse transformation of the printing) - How is an atom printed?
Step 2
- What if my language doesn't support lambdas, let alone passing around named functions? Ideally write something about implementing/using functors/delegates or replacing that namespace with a big switch as with VHDL. Another problem is that if you choose a different solution in step 4, step 2 could end up no longer functional...
- What kind of error (read: what message?) is raised when no value can be looked up for the symbol? Is it arbitrary? Do I need to extend my error handling to allow for format strings?
- It would be worth a mention that you should extend the printer to handle "native" functions (or in oldtimey terms, subrs)
Step 3
- You should modify both eval_ast and EVAL
- Suggest the trick with destructuring the AST into
a0
,a1
, etc. variables for easier access. Perhaps this can be used to clear up the general language used with AST manipulation (like, first parameter and second list element)? - What does def! return? Emacs Lisp for instance returns the symbol whereas the tests suggest the value should be returned instead...
Step 4
- "Implement the strings functions"
- The "no closures" paragraph isn't quite clear. Asides from that, do
native functions don't really need to be wrapped the same way as the
fn*
objects, just introduce another type (like, a Subr and a Func type) and do a check before applying the arguments to it - Why does the guide say that the first argument of
count
can be treated as list, yet there's a test performing(count nil)
and expecting zero as result? - Does it make sense to compare, say, atoms in
=
?
Step 5
- "This is especially important in Lisp languages because they tend to prefer using recursion instead of iteration for control structures." <- I'd argue it's less of a lisp thing (see everything else related to CL) and more a thing functional programming proponents have considered more elegant than introducing iteration constructs (see haskell, ocaml, erlang)
- It's not really clear that the TCO change for
let*
involves the form you'd normally pass toEVAL
to become the newast
. I had to reread this a few more times to understand that the "secondast
" is actually its third argument... - Where did the check for
do
not being broken by TCO go? - What's the deal with the
quux/tests/step5_tco.qx
file?
Step 6
- "The closure calls the your EVAL function […]."
- I still don't have any closures. How the heck do I implement
eval
? What aboutswap!
? - It would be useful to mention that
swap!
sort of requires implementingapply
first...