1
1
mirror of https://github.com/kanaka/mal.git synced 2024-09-20 10:07:45 +03:00
mal/chuck/notes.md
Vasilij Schneidermann aa0ac94f0b Implement step 6
2016-07-30 00:50:43 +02:00

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 a read or eval-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 to EVAL to become the new ast. I had to reread this a few more times to understand that the "second ast" 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 about swap!?
  • It would be useful to mention that swap! sort of requires implementing apply first...