<gahr>
but I don't understand the meaning of private
<abu[7]>
Seeems not really "private"
<gahr>
yeah
<gahr>
I'm not familiar with how our symbol maps work
<tankf33der>
Release and make announce in ml
<abu[7]>
Yeah, let's everybody test it
<beneroth>
thanks guys
<abu[7]>
Hi beneroth
<gahr>
I was looking at the source code, and was wondering why some functions use "X" for argument names instead of X
<gahr>
was that an older convention?
<beneroth>
no, "X" is a transient symbol
<abu[7]>
No, this is still actual
<beneroth>
meaning it's scoped to the file
<abu[7]>
It is not really a naming convention, but means "transient" symbols
<abu[7]>
Usually you can use (private) symbols now for those
<abu[7]>
Transients are automatically private in the current source file
<gahr>
because symbols are dynamically scoped?
<abu[7]>
Not scoped
<beneroth>
binded
<abu[7]>
yes they are "bound"
<beneroth>
transients for parameters are mainly used in F-Expressions which don't receive their arguments evaluated but evaluate them themselves (or not, whatever they like to do). Using transient "X" instead of normal global X helps in case the code the fexpr receives contains X which could give name collision
<abu[7]>
The scope of a symbol is something different
<beneroth>
maybe we can say "scope of the name" ?
<gahr>
right
<abu[7]>
yes, the name
<abu[7]>
"scope" means "visibility"
<beneroth>
the name in source code points to a symbol, evaluated during reading.
<gahr>
(de bar () (prinl X) ) (de foo (X) (bar X) ) (foo "hello")
<gahr>
I guess I am a bit puzzled that bar prints hello :)
<gahr>
I mean, I'm unused to this
<beneroth>
well think through what happens, step by step
<beneroth>
(de ...) defines the functions (binds the value of the symbol to the list which makes the function definition)
<beneroth>
now during call (foo "hello")
<beneroth>
first the (X) from (de foo (X)) is getting bound to your "hello" symbol (also a transient symbol)
<abu[7]>
'X' is called a "free" variable in 'bar'
<gahr>
I can think of symbols as parameters in scheme.. or dynamic variables in lisp
<beneroth>
"hello" is evaluated, but as it has no value, transients symbols have the special mechanic of evaluating to themselves.
<beneroth>
then we call 'bar with X bound to "hello"
<gahr>
I mean, all symbols are dynamic at global scope (or file scope for transient)
<gahr>
yep the evaluation is clear :)
<beneroth>
you must differ between name scoping during reading a file/repl code, and bindings during evaluaitng
<abu[7]>
dynamic refers only to binding
<beneroth>
calling (bar) is like (let (X ...) ..) environment
<beneroth>
the X gets locally bound, points to a new value, independent of the value it has in the upper environment
<beneroth>
all symbols which don't get a local binding, keep their bindings from the upper environment - that's the dynamic binding
<gahr>
yes
<abu[7]>
"all symbols are dynamic" this is correct if you mean "all symbols are dynamically bound"
<gahr>
yes
<abu[7]>
there is no lexical binding in pil
<beneroth>
and datatype is an attribute of the value, not the variable, in picolisp
<beneroth>
(variables in pil are actually always symbols)
<gahr>
so how do you pick a variable name for you variable locals?
<beneroth>
so in the (bar X) call, with X being already bound to "hello" from (foo "hello"), the X gets again bound to "hello". Then (prinl X) gets called, receiving "hello", evaluating "hello" which gives "hello", and writes that to stdout
<gahr>
do you need to know every free variable used in everuy function you call?
<abu[7]>
Free variables are usually avoided
<beneroth>
easy rule: uppercase symbols, and when it's a FEXPR make it a transient or namespaced
<abu[7]>
The convention is that functions having free variables start with "_"
<abu[7]>
(de _foo () (bar X))
<gahr>
ok, so if free variables are avoided, what's the benefit of using a transient symbol for function parameters?
<abu[7]>
'lint' will otherwise warn
<beneroth>
if you use variables in a function which were not handed over as parameters, they should be globales *Uppercase or the function prefixed with _ to indicate that behaviour to the programmer
<abu[7]>
The transients are for other purpose
<abu[7]>
To avoid shadowing
<gahr>
sure but what would you shadow, if not a free variable?
<beneroth>
transient = during reading (in repl step), only search for definitions for that name in the current file scope, not global scope
<beneroth>
ah good thinking
<beneroth>
T in a fexpr you get usualyl a lot of free variables, because you are evaluating code from an upper environment usually
<beneroth>
*usually
<abu[7]>
There is a FAQ entry: Are there no problems caused by dynamic binding?
<beneroth>
you got started with this by the (de tag "X" ...) definition in @lib/xhtm.l ?
<gahr>
still you don't know if the expr you pass unevaluated contains any transient symbol
<beneroth>
it could contian transient symbols, but those will be scoped to the reading environment when they where loaded
<gahr>
not specifically, I was just seeing that some functions used transient symbols as params, and some did not
<beneroth>
so if they came from a different file, it's a different scope
<beneroth>
if its the same file, the names will be bound to the same symbols
<abu[7]>
gahr, it is always for the two reasons
<abu[7]>
A transient or private won't conflict
<abu[7]>
(de myPush (Var Val) (set Var (cons Val (val Var]
<abu[7]>
(push 'L 7)
<abu[7]>
BUT: (push 'Var 7) won't work
<abu[7]>
At "(set Var" Var *is* Var
<abu[7]>
So the value is unbound when 'myPush' returns
<abu[7]>
thus (de myPush ("Var" Val) ...
<gahr>
but you can't (myPush "Var" 7)
<abu[7]>
This is safe, as "Var" never can be passed
<abu[7]>
You can
<abu[7]>
"Var" is another symbol
<gahr>
even if it's in the same file?
<abu[7]>
No
<abu[7]>
If you use "Var" in the same file in a call to myPush
<abu[7]>
you must do (====) to cut off the scope
<abu[7]>
or now better use (private)
<abu[7]>
(private) Var
<gahr>
right I see
<gahr>
so it's probably best to use a transient symbol for an argument for which you expect a symbol
<abu[7]>
(private) is more flexible and more readable
<gahr>
and you must be careful how you call it within the same file
<abu[7]>
Just expecting a symbol is not a problem
<abu[7]>
Only if the value of that symbol is modified
<abu[7]>
e.g. 'set' like above
<gahr>
yep that makes sense
<beneroth>
gahr> so it's probably best to use a transient symbol for an argument for which you expect a symbol
<beneroth>
yup
<gahr>
I guess this needs a bit of getting used to :)
<gahr>
it's a mindset shift
<beneroth>
everything does
<beneroth>
but yeah
<beneroth>
pil looks like other languages, but quite different things happen
<beneroth>
VM with cells linking to cells linking to cells
<beneroth>
instead of translation into words and arrays being copied around
<gahr>
yep, the concepts are very simple, which is what attracts me, but the consequences might be deep
<gahr>
needs some thinking..
<abu[7]>
In praxis it is no problem, as long as one keeps the two cases in mind
<tankf33der>
abu[7]: will you take a look why native does not work on macos or *bsd ?
<tankf33der>
or will wait until first request?
<abu[7]>
This was always not working, right? Not just with today's change?
theruran has quit [Quit: Connection closed for inactivity]
<tankf33der>
Always, from beggining
<abu[7]>
Would be nice to find the reason
<tankf33der>
lets debug then on freebsd
<tankf33der>
did you released todays modifications?
<gahr>
can I help with some freebsd-foo?
<abu[7]>
tankf33der, I did not release yet
<abu[7]>
only the above pub/
<abu[7]>
gahr, yes, nice
<abu[7]>
gahr, to the bindings issue, a simple example:
<abu[7]>
: (de foo (Fun) (mapcar Fun (1 2 3)))
<abu[7]>
then
<abu[7]>
(let X 2 (foo '((N) (+ X N))))
<abu[7]>
-> (3 4 5)
<abu[7]>
All right
<abu[7]>
But:
<abu[7]>
(let Fun 7 (foo '((N) (+ Fun N))))
<abu[7]>
it gives "((N) (+ Fun N)) -- Number expected"
<abu[7]>
in 'foo', Fun should be private or transient
<gahr>
yep
<abu[7]>
So sources lik @lib/xhtml, @lib/svg.l make heavy use of privates
<gahr>
that's point 1 in the Are there problems.. faq right?
<abu[7]>
Yes
<gahr>
so whenever your argument is not an atom, i.e., it can be expanded (e.g., by evaluation for its value or by list execution), it's better not to use an internal symbol
<gahr>
probably atom is not a pil terminology, but you get the point
<abu[7]>
only if it is passed throug a binding
<abu[7]>
'foo' binds 'Fun'
<gahr>
yes
<abu[7]>
Atom or list does not matter
<abu[7]>
The issue is that 'Fun' may overshadow another binding of 'Fun'
<abu[7]>
This is only if an executable list is passed
<abu[7]>
a function, an exe or a prg
<abu[7]>
exe and prg are used in the references
<abu[7]>
prg is a list of exe's
<abu[7]>
and a function is a parameter list and a prg
<abu[7]>
(params . prg) is a function
<abu[7]>
((X Y Z) (foo X) (bar Y Z))
<abu[7]>
(foo X) is an exe
<abu[7]>
((foo X) (bar Y Z)) is a prg
<abu[7]>
The concepts are technically simple, but it is hard initially to get one's head around it ;)
<abu[7]>
I also have to rethink it sometimes
<abu[7]>
But it is sufficient to just keep the two rules in mind
<beneroth>
[security] it seems Intel got scary to lose the lead on fundamental CPU security falws after zenbleed on AMD ... but Intel keeps failing: https://downfall.page/
calle has joined #picolisp
<beneroth>
s/scary/scared
<beneroth>
s/falws/flaws
* beneroth
has english broken
calle has quit [Ping timeout: 246 seconds]
aw- has quit [Ping timeout: 260 seconds]
aw- has joined #picolisp
stultulo has joined #picolisp
f8l has quit [Ping timeout: 260 seconds]
stultulo has quit [Remote host closed the connection]
stultulo has joined #picolisp
oldf8l has joined #picolisp
stultulo has quit [Ping timeout: 244 seconds]
oldf8l has quit [Read error: Connection reset by peer]