Alex Shinn <xxxxxx@gmail.com> writes: > On Tue, Sep 29, 2015 at 6:17 PM, Taylan Ulrich Bayırlı/Kammer > <xxxxxx@gmail.com> wrote: > > I find thunk arguments pretty weird. Continuation passing style is > great and all but it's not how we want to write our code, is it? > Returning multiple values is simpler. > > I prefer CPS to MV in general, especially since MV are broken in > Scheme. I don't see how MV are "broken." It just seems like slander used by those who dislike their semantics. :-) I use them in https://github.com/TaylanUB/scheme-bytestructures extensively and am grateful they're there, since otherwise I would need to wrap the data-flow between some procedures in a record type of which I'd be allocating a lot of instances, making performance suffer unless the host Scheme can optimize that. Or I could try restructuring the whole code, which at the moment is very clean. > Personal preferences aside, in this case, > > (hash-table-ref ht k (lambda () expr)) > > is shorter and cleaner than > > (receive (val found?) (hashtable-lookup ht k) > (if found? val expr)) Can you give a couple real-life examples on what 'expr' typically is? I'll base my judgment depending on that. Note by the way that returning a found? Boolean is more flexible. If your code should diverge entirely based on whether a value was found or not, then you are forced to write a whole body of code in the lambda operand to hash-table-ref and do a non-local exit at its end. Also, I just decided to make the 'default' argument to hashtable-ref optional, erroring when it's not there and when the lookup fails. That's probably a very common use-case, covering SRFI-69/125's possibility of doing: (hash-table-ref ht k error). Note also that there is hashtable-intern! for when you want to compute a default value for a key, but avoid doing that potentially heavy computation when there's already an association for the key. Given the above two use-cases, I only see one use-case remaining for the thunk, which is doing a nontrivial computation when no value was found but not putting the result into the hash table; for that case you indeed have to make your code marginally more verbose with receive/let-values and an if, but given the problem mentioned three paragraphs ago (the Boolean is more flexible), I see that as acceptable. > What's the advantage of splitting it to a different SRFI in this > case? > > Because it's hard enough to get hash tables right without it, > and there seem to be a lot of open issues with weak refs as > it is. Can you point out those issues? > Also, given hash-tables and weak refs/ephemerons separately, > you can always implement weak hash-tables by using a weak > pair as both key and value, and making the hash and equality > functions consider only the key of the pair. > > It thus seems preferable to leave these orthogonal concepts > separate for now. They might be orthogonal in some strict sense, but I wouldn't want us to end up in a situation like with call/cc and exceptions. (It used to be claimed that exceptions can be implemented with call/cc, which we found out to be impractical.) I will drop weak/ephemeral semantics once I know that there are issues with their current specification in SRFI-126 and that we can't solve those issues easily. > Fold is called sum here since it's unordered. > > That's a really confusing name. Recommendations welcome, but in any case users should be discouraged from seeing the procedure like a typical fold operation which has a specified order. The argument order is also different from a typical fold operation. Note that this was previously discussed in the "new names for some operations" thread of the SRFI-126 ML. Long story short, we really want to discourage coding patterns that lead to Heisenbugs. > Pop! does not behave like the SRFI-125 pop!, and a push! > equivalent for this pop! makes no sense (it's just set!). > > I don't like that definition of SRFI-125 pop!. > I've used push! but perhaps not often enough to include here. Oh, I just noticed that SRFI-125 and 126 pop! are now the same. It's unfortunate that their semantics differ from Gauche's hash-table-pop!, but really, this semantics is exactly what you would expect from something called hash-table-pop!. The procedure first came up in the "choose-and-remove! operation" thread and there was quick consensus on "pop!" being the proper name for it. The other push/pop could be called hash-table-push-value! and hash-table-pop-value!. If you have a strong opinion that these are commonly used operations, I can add them under misc. procedures. WDYT? > Inc!/dec! are pretty much just: > > (hashtable-update! ht k inc 0) > (hashtable-update! ht k dec 1) > > Since inc and dec are not defined (and are usually called add1 > and sub1), you have to write it out as a lambda. Either way, > these super common, I'd rather have them predefined. Add1 and sub1 are similarly trivial definitions, but if you say they're so common, then I have no problem adding them under misc. procedures. Will do in a moment. Taylan