Giter Club home page Giter Club logo

Comments (12)

gilch avatar gilch commented on June 17, 2024

I remember thinking I might need weird lambda calculus tricks to implement a yield macro. I thought about continuation-passing style and call/cc. Still not sure if that's doable. However, Ensue might make that unnecessary.

The full injection is not quite as bad as I made it sound. If a tree-walker could recognize the if-else, it could avoid expanding it before processing its subexpressions, which is basically how it would work as a special form. Each special form has to be special cased in the walker. That's why having only two of them makes writing code walkers a lot easier. All other (non-string injecting) macros could be macroexpanded to make them expressible in terms of these.

I feel like string-injection macros might be a common problem that walkers can't be expected to anticipate. They might kind of work like the "compiler macros" of Common Lisp (which are not the same thing as "macros"). Maybe if there were a standard way to mark these (an expand-after macro?) or a way to choose between an injected or non-injected implementation (an *inject* var?) then this could be made to work better.

from hissp.

gilch avatar gilch commented on June 17, 2024

I'm tempted to just do this. The inject-body version, I mean. But it's going to break a lot of examples in the docs, which would be a pain. I feel like I should finish the current doc project before I begin another one. Unlike a full injection, which would probably require a redo of all affected examples, I could probably just do a find and replace. Maybe it won't be that bad.

from hissp.

gilch avatar gilch commented on June 17, 2024

Looks like not that bad. Undoing it would be harder, but maybe still possible with a regex find-and-replace.

from hissp.

gilch avatar gilch commented on June 17, 2024

Looks like I can do @ lists and # sets just as easily.

There are a number of other macros that could benefit from this treatment, but they're more complicated. The best way to do % dicts is probably to create a dict literal in the body with string manipulation. The unpacking makes it tricky, but it's doable. && and || would be trivial if they were strictly binary. Making them multiary recursively like they are now wouldn't realize as much benefit as creating an inline helper function of the proper arity. Same with cond, which would just be a multiary if-else. when and unless would get a little bit simpler, since the nil case would not have to be passed in.

I feel like I implemented an injected throw before I found the walk_tb. Deserves another look if I can find it.

from hissp.

gilch avatar gilch commented on June 17, 2024

It was in the wiki here https://github.com/gilch/hissp/wiki/Bundled-macro-candidates#raise

.#"(x for x in'')", to make the generator, but it still needs to be closed. Could wrap in a doto. Longer injectables could close it too.

(g:=(x for x in'')).close()or g  # Leaks g.
(lambda g=(x for x in''):g.close()or g)()  # Doesn't, but longer.

Leaking is really not OK even with a gensym. (Although Hy did it a lot, last I checked.) The alternative is pretty much a doto, so I may as well doto.

from hissp.

gilch avatar gilch commented on June 17, 2024

doto doesn't auto-wrap like ->. Must have missed that. Fixed in feature branch. ensue is implemented in terms of ->, so should be fine. Were there any others?

from hissp.

gilch avatar gilch commented on June 17, 2024

when and unless were fairly easy fixes, but they break a lot of examples and can't be fixed with a simple regex find-and-replace, since their arity changed. I just have to go through all the examples.

%, &&, ||, and cond will need to compute a helper string to inject because it will depend on arity. These are going to be the most difficult. Their examples are going to change too, and not in a way I can fix with a regex. I'll probably have to redo all of them.

from hissp.

gilch avatar gilch commented on June 17, 2024

when/unless are done. The rest will have to wait for tomorrow, at least.

from hissp.

gilch avatar gilch commented on June 17, 2024

&& and || are done. Not as easy, but not really harder than writing a normal macro. Implementing one made the other pretty obvious.

cond may be slightly more difficult. % will probably be the hardest. The unpacking makes it tricky.

from hissp.

gilch avatar gilch commented on June 17, 2024

cond was harder, but doable given the && and ||. The old recursive macro definition in terms of if-else was really quite a bit simpler.

An optimization for these branching macros occurred to me. Any literal expressions need not be thunkified to delay evaluation. That's only required for evaluable forms (tuples and strings, and not the strings containing literals). However, this means that the body must avoid calling them like thunks as well, but still call anything thunkified. Matching these up would complicate the macros, although I suppose it's doable with enough code. if-else, when, and unless might be better defined in terms of cond in that case. It's not clear if && and || should be.

That just leaves %, which seems at least as difficult as cond was.

Given this technique, I'm wondering if there are any additional Python expressions I would want macros for. Generator expressions/comprehensions perhaps, but I don't see this working any better than the itertools and builtins. I'll have to look over that wiki page.

from hissp.

gilch avatar gilch commented on June 17, 2024

% is done. It was about as hard as cond.

I can't say that I should have done them this way in the first place. The old non-injecting implementations were worth writing for dogfooding purposes. The dynamic string-manipulation ones are fairly complex. Their expansions are a lot less noisy, but their implementations are a lot more difficult to understand. These would have been hard to write without the macro suite in place. I'm not sure this was an improvement. This feels like bloat. I'm tempted to just make them binary (or binary-recursive), but that wouldn't work for %.

from hissp.

gilch avatar gilch commented on June 17, 2024

Because it's a bit cryptic, I also wanted to mention somewhere that the X+1&-2 in cond is so that an odd number of arguments will crash (it ensures the helper always has an even number of parameters). cond is defined pretty early and I didn't have throw available yet.

from hissp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.