openlang

age>=18=>allow and the Racket reader

Rule authors want to write age>=18=>allow, no spaces, no parentheses. Racket's default reader may hand that over as one symbol, so a macro would be picking apart a spelling. A custom reader can draw the token lines itself.

Then the rest splits. Expansion rejects malformed rules and turns them into calls. Runtime fetches the age and deals with it being missing. If an attempt form shows up, someone has to say whether its retry repeats the test, the action, or both.

后续讨论 8

顺着彼此的依据读下去
  1. 固定链接

    If attempt retries, how many notifications go out? A body that updates state and also sends something will send again on every retry, even when the state change lands once. Clojure's dosync is the familiar case, which is why I'd want the form to say up front whether its body may run again. Return the notification as data and deliver it after the attempt finishes, and the retries stop touching the effect.

  2. 固定链接

    Who knows enough to choose a replacement when the age is missing? Quite possibly the caller, not the rule evaluator. Common Lisp would signal a condition and let a handler-bind handler pick a replacement-value restart while the signaling frame is still there. Racket doesn't need that machinery for this. A parameter the caller sets around the evaluation, holding the fallback or a procedure that produces one, keeps the choice with the caller, and the runtime half of your split only has to read it.

  3. 固定链接

    age>=18=>allow looks great on a slide, sure. Now the author drops a letter and writes age>=18=>alow. What do they see? An error pointing at the action, or a shrug about one long mystery symbol? Ruby's NameError suggestions have spoiled me a bit. One missing letter ought to be easy to find.

  4. 固定链接

    Squiggle under alow. Little hint that says allow. Rule still refused, nothing runs. That's the sequence I want on screen, and the tricky part is keeping that source span alive the whole way through without the tool fixing the typo on its own. Doable?

  5. 固定链接

    Yes, and the reader is the natural place to start. A custom reader can give the action token its own source location and hand that syntax to the expander. Then the work splits. The reader rejects broken token structure. The expander rejects an action name it doesn't know, attaches the diagnostic to alow, and offers allow purely as help. Nothing gets evaluated.

    Keeping the ordinary reader is possible, but then the macro that picks apart one symbol's spelling also has to track where the action starts inside it. Otherwise the narrower span is lost and the error lands on the whole symbol.

    Either way the suggestion never changes which program is accepted.

  6. 固定链接

    Fun one to poke at. Add a single character and watch where the token lines go. age>=18==>allow has an extra =. Does the reader take >=, 18, then choke on ==>, or read = and => and hand the expander a rule with a stray = in it? Those put the error in different places, and only one of them points at the character the author actually mistyped.

    Negative numbers are the other thing worth trying. age>=-1=>allow is silly as a rule but legal-looking, and >=- is the spot where a greedy scanner and a person disagree.

  7. 固定链接

    Longest match over a fixed token set, and nothing outside the set. With >=, <=, => and = as the only symbols, the scanner reads age, >=, 18, then at ==> takes = and next =>. That's a well-formed token stream, so the reader is the wrong place to complain. The expander sees a comparison followed by a stray =, refuses the rule, and the span lands on that =. Which happens to be the mistyped character, so it works out here, but only because of how that set is shaped.

    -1 is a separate decision and I'd make it in the reader. A sign belongs to a number only right after one of those symbols. So >=-1 reads as >= and -1, and a - anywhere else is rejected, since the notation has no subtraction.

同一个问题的其他角度

  1. foldl composes fine and leaks anyway

    foldl (+) 0 over a long list is the smallest space leak I know, and it's a composition problem more than an arithmetic one. E…

    回复 6最近活动 haskell
  2. Empty reductions return the identity

    Reduce over an empty vector. APL answers. Each primitive carries its identity. Zero for plus. One for times and for and. ⌈/⍬…

    回复 3最近活动 apl
  3. Returning from a Common Lisp handler means declining

    Neat abbreviation. I'd still like to see what it's agreeing to. The wrapper macro installs a handler around a parser, and the…

    回复 4最近活动 common-lisp