-
Notifications
You must be signed in to change notification settings - Fork 15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement melt(q) builtin #61
Comments
I propose "unwrap" as the name |
Oh, and I should mention that I had a
But what should be the exact semantics of
First I thought "well, clearly the second behavior is way more flexible, let's do that". And then "ooh! looks like
So, yeah... Maybe the former semantics (always evaluate fully, and then give back the literal or whatever) makes sense. But I haven't found a use case yet, to be honest. So I'm not proposing we add |
Well, "unwrap" makes a lot of sense for literal Qtrees. Less so for identifiers or expression trees. |
After implementing this, I realized that since This is not what I intended. I don't see any horrendous consequences of the language suddenly having
Not sure what to do about this, which is why I'm not opening a new ticket about it. Blacklisting function calls altogether feels unfair to operators, which are effectively function calls with sugar on top. What I think we do want to do is whitelist a bunch of operators and functions among the built-ins. Basically anything that constant folding would be able to relate to. This is a thought for the future — let's hope in the meantime users don't get heavily dependent on the unintended semantics. |
maybe restrict its use to BEGIN time? |
|
It's easy to go from runtime values to Qtrees: just throw something into a macro, or pass it into a quasi. It's less easy to go the other way: have Qtree, want runtime value.
Maybe think of it as an
eval
function, but rather than a string, the input is a Qtree (that is, already parsed or built synthetically). I don't want to call iteval
— too much risk of confusion. So let's call itmelt
. The metaphor here sort of is that Qtrees are solid/frozen because they tend to hang around at compile time, whereas runtime values are liquid/runny because they, well.Here, have an example:
What do I see it being used for?
Let me show an example of the latter (and what led me to want
melt()
):The function
call
allows you to pass in a string"foo"
, and the functionfoo()
will be called.Note that
melt()
decidedly is not a general-purpose evaluator — another reason not to call iteval
. It returns values only. Do not expect it to do the right thing if you pass it Qtrees for blocks, unquotes, parameter lists, argument lists, statements, or traits. Anything that's a subtype ofQ::Expr
is fine though, including:Similar to how splicing works in other places: if you melt a Qtree that comes from code (either a quasi or a macro argument), then it'll do lexical lookups from its original position in the code. If you melt a synthetic Qtree (that you built by hand, you craftsperson you!), then lookup will happen form the site of the
melt()
call. (That is, frommelt
's caller — in the above example, from insidecall
.)You're free to use
melt()
in a macro or aBEGIN
block, but do note that any identifiers you try to resolve will resolve very early. That is, if you're trying to melt an expression with a variable in it, chances are you'll be disappointed and getNone
. (Melting something inside aquasi
block would work, but I doubt it has any advantages compared to the more powerful unquote.)The text was updated successfully, but these errors were encountered: