Implementing targets as separate components
#11
Closed
opened 5 years ago by kdsch
·
5 comments
Loading…
Reference in New Issue
There is no content yet.
Delete Branch '%!s(<nil>)'
Deleting a branch is permanent. It CANNOT be undone. Continue?
I'm learning Pollen to ditch Hugo and every static site generator that frustrates me. I am somewhat familiar with Scheme, but a newcomer to Racket, especially the module system.
I've done the fourth tutorial, on multiple output targets. I understand that
pollen.rkt
defines a module that resolves Pollen tags. The tutorial uses branching expressions within tag functions to implement different targets.I want to make the implementation choice at the module level rather than in the tag functions. In other words: separate targets into different components. I think of a Pollen document as requiring an interface, with the current poly target controlling which implementation is used. However, I'm not skilled enough in Racket to do this.
Here’s one way to do it, putting each set of format-specific tag functions in its own source file, and then stitching everything together with a couple macros.
Here’s another way, using classes and inheritance.
Some have suggested that units are a possibility, but I don’t recall seeing a working example.
Thanks @mbutterick!
For what it’s worth, some time ago I looked into using units for this purpose. The problems I bumped into were
At the time I couldn’t determine how to conditionally call
define-values/invoke-unit/infer
since it is a top-level form [edit: maybe rather, module level?]. With a better understanding of macros, this may not be an obstacle anymore.More crucially, it doesn’t appear that
(current-poly-target)
will return anything but'html
at expansion time.@otherjoel Good to know.
I tried using units today. I found that
define-values/invoke-unit/infer
expects identifiers, which implies converting symbols (targets) into identifiers. This conversion would have to happen at run time, as the target varies at run time. I'm guessing this is a contradiction; I don't think identifiers can be created at run time. Whereas, macros can create them at compile time.Recalling the notion of message passing I encountered in SICP, I experimented with that approach.
This seems to have taken me a bit farther, but I'm now violating contracts in
txexpr
. Seems like a basic error, but I'm not sure what's going on, as the implementation didn't do this before.where
resume.poly.pm
containsThe problem was too many variadic functions. After fixing that, the message-passing style more or less does what I want.