<gahr>
yes, I know about the cadence, I wanted to know about the day, given the particular time of the year.. ok I guess I can update the port on 29th or 30th
<tankf33der>
yeap, thanks
<abu[7]>
👍
<gahr>
cool, thanks both :)
<tankf33der>
afk
<geri>
unafk
<geri>
:D
<geri>
abu[7]: i had a question above about how do you know how many frames to pop off of bind stack when function has been run
<geri>
maybe theres some sort of counter im not seeing
<abu[7]>
Depends on the use case
<abu[7]>
In case of 'llvm~evExpr' it is until hitting '@'
<geri>
ah, basically a magic value for a stop marker
<geri>
that's neater that what i was thinking
taleon has joined #picolisp
<abu[7]>
For 'let' it is either just one
<abu[7]>
or remembered in 'Q'
<geri>
what's Q?
<abu[7]>
A local variable
<abu[7]>
(vi 'let)
<abu[7]>
at the end
<geri>
im honestly not a fan of every argument being named as a single letter where you have no idea what's it supposed to be doing
<geri>
xd
<abu[7]>
P and Q are usually pointers in PilSrc
<geri>
hmm
<abu[7]>
(let (P (val $Bind) Q P)
<abu[7]>
(? (== Q (setq P ...
<geri>
(== Anything (setq ...)) is such a C pattern :D
<geri>
ive seen you use it a lot in gc.c in original picolisp for example
<abu[7]>
Yeah, same
<geri>
what's going on in mapcar?
<geri>
im guessing workarounds for f expressions in some way, shape or form
<abu[7]>
"going on" in which sense?
<geri>
its huge and im confused what's actually happening inside
<geri>
:D
<geri>
cause typical map function will be like half of that side
<geri>
size
<abu[7]>
It is basisally an "apply"
<geri>
basically fexps make first class functions less nice to implement?
<geri>
but give first class macros
<geri>
is it also basically quoting the arguments before passing them to the function?
<abu[7]>
No, it is all about evaluating and applying the args
<abu[7]>
Look at 'apply' first
<abu[7]>
ad
<abu[7]>
and doc/structures
<geri>
apply is even scarier
<geri>
:D
<abu[7]>
Mapping lists is applying the elements of all lists to the fun
<geri>
that i know
<geri>
i dont know how are you making it work with fexps
<geri>
cause if mapcar is evaluating, and print is evaluating, then your list is eval'd twice and it doesnt work
<geri>
(mapcar print '(1 2 3))
<geri>
well
<geri>
(mapcar print '(a b c))
<geri>
mapcar will eval the list and get (a b c)
<geri>
if you pass it as is to print, then it'll try to eval a and that's not bound and nothing works
<geri>
if you quote it beforehand it should work...
<abu[7]>
see doc/structures
<abu[7]>
Apply
<geri>
looks like binding stack
<abu[7]>
It is more
<abu[7]>
builds an exe
<abu[7]>
which quotes the elements of the list
<abu[7]>
by putting into symbols
<geri>
doesn't sound much different from what i said
<geri>
except putting into symbols instead of using quote
<abu[7]>
T
<geri>
brb lunch
<abu[7]>
pil32 indeed used quote's in apply
<geri>
if you know that the function doesn't evaluate its arguments (or does), you could make apply work with both, no?
<geri>
just skip quoting step when it doesnt evaluate its arguments
<geri>
abu[7]: why'd you switch from quote to symbol construction?
<geri>
sounds like both are 1 pointer reference
<abu[7]>
A non-evaluating fun (FEXPR) cannot be applied at all
<geri>
its pretty much the same thing as using (private) or abusing transient namespace though
<geri>
reinventing the wheel is very fun though
<geri>
i think you only care about collissions when setting things or evaluating arbitrary forms though
<geri>
could also write a function that replaces all symbols with transient symbols with same value as current...
<geri>
for no reason whatsoever!
<beneroth>
meta-programming to generate FEXPRs would be a reason
<geri>
it's an interpreted lisp
<beneroth>
though generating FEXPRs is kinda... weird. Probably not using FEXPRs correctly or overdoing metaprogramming
<geri>
everything we do is meta
<geri>
:D
<geri>
when you say generating fexprs i think of (eval (list 'setq thing1 thing2))
<beneroth>
in FEXPRs you usually want the parameters and local variables to be transients (or namespaced) to ensure that no name collision/shadowing could happen in the evaluation within the FEXPR
<geri>
oh yeah
<geri>
in the first place i started writing this as a resolution to symbol collissions
<beneroth>
a fexpr in picolisp is a (de foo X ...) or (de foo (EvalParam1 EvalParam2 . X) ...) function
<geri>
for my interpreter though
<beneroth>
X = unevaluated argument list
<geri>
yeah i know that much
<geri>
wait
<geri>
did you see the file i sent?
<beneroth>
so usually you then use (run) or (eval) with it within the FEXPR. unless the FEXPR is a full interpreter iterating through the parameters or whatever
<geri>
that's like exactly what im doing, just limited to particular symbols
<beneroth>
FEXPRs are interpreter-functions, right. That's why they are not compilable (not in all cases), that's why compiled lisps dropped them
<geri>
just replaces every symbol provided with transients and then evaluates the body
<beneroth>
you know about (bind) yes=
<beneroth>
?
<geri>
im literally using it in with-symbols
<beneroth>
ah yes you use it
<beneroth>
good
<beneroth>
:)
<geri>
the idea is, i dont need to rewrite anything but i ensure that Args and other args will never collide with anything else
<beneroth>
yeah. you can think of (bind) relation to (let) like the relation of (set) to (setq) ;-)
<geri>
its arguments are a little different
<geri>
bind takes an alist, let just a list or even a symbol followed by some exp
<geri>
s/just a list/flat list
<geri>
also set can set pairs' car
<geri>
:D
<geri>
oh wait
<geri>
abu[7]: does it work cause car of cons is in same position as value of a symbol?
<abu[7]>
the CAR ?
<geri>
(a . b) vs (head . value)
<abu[7]>
CAR vs. VAl
<abu[7]>
T
<geri>
so in first case pointer points to a, in second to value
<geri>
the function just sets whatever's directly at the pointer
<geri>
hence double behaviour
<beneroth>
it's efficient
<abu[7]>
Exactuy
<abu[7]>
ly
<geri>
also mind bending
<geri>
not like i mind that though
<geri>
apply finally clicked today too
<beneroth>
simply elegant :)
<geri>
well, not the code but what it does in theory
<geri>
:D
<abu[7]>
(sorry, we are in Augsburg'c Xmas market, cant follow all the time)
<geri>
enjoy
<abu[7]>
☺
<beneroth>
abu[7], enjoy!
<abu[7]>
family is getting angry ;)
<geri>
haha
<geri>
well, logs are there for a reason
<abu[7]>
ok ☺
<geri>
(dolist2 (X Args) (prin X) (prinl))
<geri>
how do i properly destructure it into the X from car, Args from car and rest?
<geri>
(let (((Var . L) . Body) Args) ...) seems to not be doing L right
<geri>
without dot before L it's also wrong
<geri>
actually wait, i forgot to eval it
<geri>
actually nevermind again, i frogot that i got collissions
<geri>
xd
<beneroth>
I think you forgot a dot
<beneroth>
ah no
<beneroth>
it's a call, not definition
<beneroth>
sorry I'm busy packaging here for a short holiday vacation :)
<beneroth>
I can't follow you exactly
<beneroth>
X is an atom value or a pair?
<geri>
i fixed it
<beneroth>
if you want to iterate through all arguments you could also do e.g. like (de foo X (while X (case (++ X) (namedParam1 ..) (namedParam2 ..) (T ...)))
<beneroth>
ah okay
<beneroth>
good :)
<geri>
i also made the with-symbols function use a transient symbol for param
<geri>
:D
<beneroth>
good :)
<beneroth>
you should dolist too, to handle the case when someone calls dolist with the symbol 'Args
<geri>
dolist is solved using with-symbols
<geri>
that exact case was the whole reason im even writing this haha
<beneroth>
I don't understand the (fill ...) in with-symbols tbh
<geri>
honestly i dont either, but it works
<geri>
XD
<geri>
somehow it just replaces every symbol passed (i.e. (Args Var Body L)) in the body
<beneroth>
the (run) is supposed to evaluate the second argument to with-symbols, and the first argument in with-symbols is the argument list you secure into transients before bindings, right?
<geri>
yes
<geri>
fexps are amazing honestly
<geri>
too bad you cant compile them efficiently
<beneroth>
you can. efficiency is not the problem. the problem is, some FEXPRs you cannot compile at all, because what they do is completely up to the arguments, which might be complete runtime-dependent (e.g. based on user input) so you cannot know what to do during compile time
<beneroth>
how about:
<beneroth>
(de with-symbols "Body"
<beneroth>
(bind
<beneroth>
(mapcar '((X) (cons X (name X))) (car "Body"))
<beneroth>
(run (car "Body")) ) )
<beneroth>
(not tested)
<geri>
that won't replace the symbols with generated ones
<beneroth>
the argument "replacing" is already happening with (bind), I think (fill) is not needed?
<beneroth>
ah
<beneroth>
you're right, I see
<geri>
bind here actually only binds Body to "Body" and such
<geri>
you can probably make it simpler though
<beneroth>
T
<geri>
or not :)
<beneroth>
maybe
<geri>
youll need to alter the (de) call a lot if you dont use fill
<beneroth>
just use always transients (or namespaced) symbols for parameter names in every function definition, then you don't need this :)
<beneroth>
(though in FEXPRs is enough)
<geri>
also make sure you dont have collissions in a single file
<geri>
its not needed per se, just fun
<geri>
not in picolisp anyway
<geri>
okay so if you have an interpreter only for fexps, you can implement lambdas with eval and mapcar
<geri>
:D
<beneroth>
see also (===)
<geri>
====*
<beneroth>
FYI a (load) also closes and opens a new transient scope
<geri>
yeah
<beneroth>
can give tricky issues if you sprinkle multiple (load)s in your file instead of one at the top
<geri>
fun
<beneroth>
aye!
<beneroth>
BBL
beneroth has quit [Quit: Leaving]
bjorkintosh has joined #picolisp
bjorkintosh has joined #picolisp
<abu[7]>
geri: (prin X) (prin "!") (prinl) can be reduced to (prinl X "!")
galambo has joined #picolisp
bjorkintosh has quit [Remote host closed the connection]
DKordic has quit [Ping timeout: 265 seconds]
galambo has quit [Quit: Leaving]
galambo has joined #picolisp
chexum has quit [Remote host closed the connection]