Closed mwgkgk closed 6 years ago
Was able to work around it with dup
:
(1 'hello 3) (dup quotation? quote ('hello ==) (false) if) find
Leaving the issue open because quote-define
is probably bugged.
The above solution is polluting the stack! Which also causes the code in first quotation to execute if we go into the (false)
branch. So it's not a good workaround.
Hi again!
Yes, I’ll look into adding more permissive predicates to cover those use cases as well, it makes sense.
Concerning quote-define
... There is a bug in the docs! #
is the sigil for quote-bind
while for quote-define
you have to use =
.
More info:
("hello" puts!) "a" =
Fails with [=]: Undefined symbol '='
, despite it being defined in the source:
def.sigil("=") do (i: In):
i.push("quote-define".newSym)
This works:
("hello" puts!) "a" quote-define
OK so for now:
Beautiful!
One more question on comparisons: how to safely find
a function in a quote?
("hello" puts!) :experiment
(1 2 3 experiment) (quote 'experiment ==) find
The predicate function above starts with quote
because unquoted experiment
is not equal to 'experiment
. The problem is though that find
is executing experiment
(by placing it on stack?) before the predicate comes into play. Same issue with reduce
.
Actually it turns out that all the predicates leave the element on the stack! Now, from the docs they should remove it after checking, so I am going to consider it a bug and change their behavior.
Also, I am planning on adding two new logical operators to allow short-circuiting: dequote-and
and dequote-or
, so you’ll be able to write things like this:
(1 8 “a” 3 “b” 4 5 6) (:x (x number?) (x 5 <) dequote-and) filter
# returns (1 3 4)
...without having to wrap checks in an if
or when
.
I'm not sure if that's going to help with my find
usecase, because the evaluation of the experiment
there happens before the predicate gets evaluated, so it has nothing to compare against.
string?
quotation?
etc are indeed leaving the element on stack and push the boolean after it, my bad for not realizing the behavior was uninteded - because signatures in the docs clearly don't match. I used to work around it with nip
.
Your original use case now works with ==:
(1 2 ‘test ‘hello 4 5) (‘hello ==) find
# returns 3
No need for the quotation?
check anymore in this case.
Problem is the symbol in array is a function call:
(1 2 3 experiment)
Rather than a quoted symbol:
(1 2 3 'experiment)
What I'm doing is parsing the source of a function. So it has actual calls rather than quoted calls
Ahh ok got it. I could introduce a new quote-map
symbol to quote the elements of a quotation without evaluating them... so you could write the following:
(2 3 + 4 *) quote-map (‘+ ==) find
Any better idea?
This is an elegant solution: no find's, reduce's and who-knows-what-else's need to be touched.
Trying to use
find
like this:Fails with
[==]: Two non-symbol values of similar type are required on the stack
. (Which is probably a usecase in it's own - to have a scheme-like hierarchy ofeq?
eqv?
equal?
with more-permissive and less-permissive variants).Trying to safeguard this with
quotation?
, I cannot figure out a way to apply multiple predicates, becausequotation?
just executes and puts it's result on the stack, and we have nothing left to check against. Trying to quote-define the argument for reuse like this:Results in
[bind]: Attempting to bind undefined symbol: item
. In general I couldn't get quote-define to work even in the form it's seen in tutorial:Using the github version of Min.
Thank you for your time <3