Wow - the thread doubled in size overnight ;) <br><br><div class="gmail_quote">On Mon, Dec 6, 2010 at 9:39 AM, Robby Findler <span dir="ltr"><<a href="mailto:robby@eecs.northwestern.edu" target="_blank">robby@eecs.northwestern.edu</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">In other words, this seems like a step backwards from a "do I, as a<br>
client of the webserver, understand the API of the webserver and can I<br>
program to it?" perspective.<br></blockquote><div><br></div><div>This is why I said that having a default is good for users - and xexpr is a good default. The refactoring will obviously improve architecture of web-server and increase its utility, but many users will not likely tap into those utilities, and hence backward compatibility needs is high. Hence my original proposal of <font class="Apple-style-span" face="'courier new', monospace">web-server2,</font> but in lieu of the desire to keep web-server name and involve, the following signature will probably be what most users are willing to do to upgrade: </div>
<div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_quote"><div>Change from </div></div><div class="gmail_quote"><div><br></div></div>
<div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace">(require web-server) </font></div></div><div class="gmail_quote"><div><br></div></div><div class="gmail_quote"><div>To </div>
</div><div class="gmail_quote"><div><br></div></div><div class="gmail_quote">
<div><font class="Apple-style-span" face="'courier new', monospace">(require web-server/<compat-layer-here) </font></div></div></blockquote><div class="gmail_quote"><div><br></div><div>So if users can just do the above and keep every other code exactly the same, then the compatibility goal has been achieved, and the rest is to figure out how to get there. I think Jay's approach is quite close to what will work for everyone. Below are my 2 cents to help with the issues being raised, instead of raising more issues, hopefully. </div>
<div><br></div><div>1 - having implemented extension hooks in many of my packages, I've learned that extensions are hard to implement as a parameter in the presence of threads, especially if the extensions are done during module requirement time. Since each new thread will not do the module require process again, and they will end up with the values prior to the extension modules. So unless Jay takes care of the parameterizations somehow implicitly, the users will need to write their own parameterization code, which will be as much work as just calling make-xexpr-response if not more. </div>
<div><br></div><div>I would suggest making the extension mechanism global. As I mentioned earlier - all hooks should be registered during the module require time, and hence the side effect do not exist during the runtime. This is basically equivalent to define a new function, which is a side effect against the namespace table. </div>
<div><br></div><div>2 - extension/coercion can work within the confines of contract, via the following approach: </div><div><br></div><div>Provide two hooks - one for response-coercible?, and the other for any->response. </div>
<div><br></div><div>The response-coercible? hooks has the following definitions: </div><div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_quote">
<div><font class="Apple-style-span" face="'courier new', monospace">;; response-coercible?-hook (-> any/c any) </font></div></div><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace">(define (response-coercible? v) </font></div>
</div><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace"> (or (response? v) (response-coercible?-hook v))) </font></div>
</div></blockquote><div class="gmail_quote"><div><br></div><div>Also provide a way to set the response-coercible? hook, something like (define-reponse-coercible-hook ...) </div><div><br></div><div>The any->response hook is what has been discussed thus far: </div>
<div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace">;; any->response-hook: (-> any/c response?) </font></div>
</div><div class="gmail_quote">
<div><font class="Apple-style-span" face="'courier new', monospace">(define (any->response v) </font></div><div><font class="Apple-style-span" face="'courier new', monospace"> (if (response? v) </font></div>
<div><font class="Apple-style-span" face="'courier new', monospace"> v</font></div></div><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace"> (any->response-hook v)) )</font></div>
</div></blockquote><div class="gmail_quote"><div><br></div><div>Then the web-server's response output mechanism can simply have the following contract: </div>
<div><br></div></div><blockquote style="margin:0 0 0 40px;border:none;padding:0px"><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace">(-> response-coercible? any) </font></div>
</div></blockquote><div class="gmail_quote">
<div><br></div><div>3 - there are two ways to do the hooks here - one is to provide a dispatch table for multiple types, so the users do not have to handle their own dispatching based on the types, and the other is to delegate the responsibility of dispatching to people who need to customize these hooks. </div>
<div><br></div><div>The dispatching code will likely to impose a particular order of evaluation, and that can make some types difficult to discern apart (for example - xexpr vs string vs sxml), so this, and the fact that it is simpler (for now), might favor to delegate the dispatching to the users who customize. </div>
<div><br></div><div>Delegating away the dispatching table, the hooks are simply a field. </div><div><br></div></div><blockquote class="webkit-indent-blockquote" style="margin: 0 0 0 40px; border: none; padding: 0px;"><div class="gmail_quote">
<div><font class="Apple-style-span" face="'courier new', monospace">(define response-coercible?-hook default-response-coercible?-hook) </font></div></div><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace"><br>
</font></div></div><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace">(define (define-response-coercible-hook?! hook) </font></div></div><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace"> (set! response-coercible?-hook hook)) </font></div>
</div><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace"><br></font></div></div><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace">(provide/contract </font></div>
</div><div class="gmail_quote"><div><font class="Apple-style-span" face="'courier new', monospace"> (define-response-coercible?-hook! (-> (-> any/c any) any))) </font></div></div></blockquote><div class="gmail_quote">
<div><br></div><div>And the same with the <font class="Apple-style-span" face="'courier new', monospace">any->response-hook</font>. </div><div><br></div><div>4 - It's okay to push multiple hooks and the dispatching to users who wish to customize, since these users are likely wanting to control the dispatching to ensure a precise evaluation order - I know I will want to control that process myself. </div>
<div><br></div><div>For users who want custom behavior without the work - well, they can always wait for lib writers to come up with the hooks for them.</div><div><br></div><div>Hope the above sketch makes sense, the actual implementation to make it work will obviously differ from the above depending on other requirements Jay needs to satisfy. </div>
<div><br></div><div>My 2 cents. Cheers, </div><div>yc</div><div><br></div><div><br></div></div>