ruricolist / serapeum

Utilities beyond Alexandria
MIT License
420 stars 41 forks source link

Expand WITH-BOOLEAN #105

Closed phoe closed 2 years ago

phoe commented 2 years ago

Please let me know if the implementation is to your liking, and if boolean-{if,when,unless} are sane operator names. I kinda don't think so, but backwards compatibility.

One idea is to introduce with-branching + branch-{if,when,unless} as new operators, and then possibly reimplement with-boolean in terms of with-branching, but it will require your approval.

REFERENCE.md is not yet updated; do you have anything that updates it automatically based on docstrings, or should I edit all the missing line numbers manually?

ruricolist commented 2 years ago

You don't need to touch reference.md; there's a GitHub action that updates it after a push to master.

The only change I would like to see to the implementation is that where it checks *boolean-bypass* it should also check if space>speed in the environment. There's already policy> for that so it would just look like (or *boolean-bypass* (policy> env 'space 'speed)).

Re-implementing with-boolean in terms of new operators makes sense. I need to think a bit more about the names, though. What would you think about with-compiler-branching, compiler-if etc. (by analogy to pre-ANSI CL compiler-let)?

phoe commented 2 years ago

OK, that makes sense - thanks, I won't touch the reference.

A bit of context regarding naming: the original name I came up with was actually with-compile-time-branching, before someone suggested to me that it should be with-macroexpand-time-branching because the compiler doesn't really do anything there and it might give the wrong vibe. Then another complaint came that the names are too long and therefore with-branching would be preferable, and I thought there was a point. And so I kept that one as my personal local optimum.

I was interested in the name compiler-foo family name, but it seems that they give a wrong vibe too - compiler-let works in a quirky way that involves dynamic bindings, whereas nothing in the current implementation is dynamic and communication occurs only via the lexical environment.

phoe commented 2 years ago

Pushed the policy check.

phoe commented 2 years ago

Thanks! Updated my README with a mention of Serapeum.

ruricolist commented 2 years ago

Incidentally I added macrolet bindings so within a with-boolean form you can use :if, :when, and :unless as shorthand for boolean-if etc.

phoe commented 2 years ago

AFAIK LispWorks will choke on keywords being used to name any sort of definitions, at least global ones; can you check if that's the case with local ones too?

phoe commented 2 years ago

Hmm - local ones seem to be OK, even by default. LW 7.1.2 Personal tells me:

CL-USER 1 > (macrolet ((:if () 42))
              (:if))
42

CL-USER 2 > (defmacro :if () 42)

Error: Defining macro :IF visible from package KEYWORD { *handle-warn-on-redefinition* is :ERROR }
  1 (continue) Define it anyway.
  2 (abort) Return to top loop level 0.

Type :b for backtrace or :c <option number> to proceed.
Type :bug-form "<subject>" for a bug report template or :? for other options.

CL-USER 3 : 1 > :c 1
:IF

CL-USER 4 > (:if)
42
ruricolist commented 2 years ago

I did also check that it works with LW Personal. I'm not sure about older versions, though, which is why I'm not planning on switching over internally for now. Right now it's more meant as a convenience for people using Serapeum.