geri has joined #picolisp
<
geri>
hey, could you remind me how saving environment works when doing catch?
<
abu[7]>
Basically a memcpy
<
abu[7]>
(vi 'catch) then click on 'putCaEnv'
<
geri>
does it copy every single symbol in the system?
<
abu[7]>
No symbol at all
<
geri>
then what is this "env" its copying?
<
abu[7]>
Click on it
<
abu[7]>
A set of globals
<
geri>
some table, hm
<
abu[7]>
globals arranged in a single structure
<
geri>
oh, bind frames too
<
geri>
so when it pops out it unbinds same way as functions do?
<
abu[7]>
and let, use, for etc.
<
geri>
that makes sense
<
abu[7]>
bindings, open files etc.
<
abu[7]>
Perhaps 'throw' in more interesting
<
abu[7]>
it does the work
<
abu[7]>
Also done in error exit
<
geri>
is unbinding everything what is "heavy" about catch/throw?
<
geri>
i guess also saving the env
<
geri>
unwind is scary
<
geri>
do you like anything about lexical binding at all? :D
<
abu[7]>
How do you mean that?
<
abu[7]>
Hmm, perhaps that closures are implicit?
<
geri>
you can create them with a function by using gensyms though :D
<
abu[7]>
Not needed. Just 'job'. But it is explicit (which may be also an advantage)
<
geri>
not needed, but you can get implicit closures using some helper function a la (closure (X) X)
<
geri>
closures are really nice for functional composition apparently because of static environment
<
abu[7]>
As I see it, is a closure the combination of variable bindings with executable code. Why gensyms (= anonymous symbols) then?
<
abu[7]>
Variables are non-anonymous by nature
geri has quit [Remote host closed the connection]
geri has joined #picolisp
<
geri>
abu[7]: that's how i found you can emulate lexical scoping in a dynamic binding language
<
geri>
every symbol gets replaced by a new one with current value when executing
<
geri>
basically becoming static
<
geri>
thats from me trying to do static binding that feels as natural as normal functions anyway
<
geri>
also, do setqs persist even if you throw out of (catch ...), if you modify something introduced from outside?
<
geri>
(catch "x" (setq 'some-global 5) (throw "x"))
<
geri>
without quote
<
abu[7]>
No, globals are not unbound, only if you do it in a 'finally' clause
<
abu[7]>
Else how should 'throw' know? Every symbol is "global"
<
geri>
you'd need to actually copy every single symbol to know
<
geri>
and that aint worth it
<
geri>
do you know, if you throw after some code that mutates variables, does it not get set?
<
geri>
in java for example
<
geri>
s/does it not get set/is the variable actually mutated/
<
abu[7]>
You mean it is not mutated?
<
abu[7]>
after the code?
<
geri>
(but in java), basically (let (X 5) (catch 'error (setq X 7) (throw 'error)) X) => 5 or 7?
<
abu[7]>
In Pil X is it 5. In Java I haven't tried
<
geri>
wait, it's 5 in pil?
<
abu[7]>
Because it is not bound in between
<
geri>
can you try it in java if not too difficult?
<
geri>
ill try in python
<
abu[7]>
I can't compile Java here
<
abu[7]>
on my phone
<
abu[7]>
Is it important?
<
geri>
no, just curious
<
abu[7]>
In Pil, X is global when seen in the 'catch' body
<
geri>
in python x is mutated
<
abu[7]>
The 'let' is outside
<
geri>
probably reasonable default
<
abu[7]>
Not just default I think. It is natural
<
geri>
it does feel rather natural honestly
<
abu[7]>
An assignmet like "x = 7" is not kept track of
<
abu[7]>
You cannot undo everything that was done
<
geri>
yeah, especially side effect stuff
<
geri>
"unprint this please"
<
abu[7]>
yeah, any side effect
<
geri>
oh by the way
<
geri>
scroll to the picture
<
geri>
basically a "vector" that has fast access time and insertion, built purely on cons cells
<
geri>
sounds interesting, even though meant as an immutable data structure
<
geri>
maybe cons cells are indeed all you need :D
<
geri>
its horrifying, but if you got this "vector", i think you can do a hash map built on top of it
<
abu[7]>
Cells are a bit overhead in Java
<
geri>
gonna eat a lot of memory though
<
abu[7]>
I did that in ErsatzLisp
<
abu[7]>
One Cell is one object
<
geri>
yeah, with all the associated meta data
<
abu[7]>
A Java object has 24 bytes overhead
<
geri>
so 8 bytes in pil21 is 32 in erstaz?
<
abu[7]>
I think so
<
geri>
sounds painful
<
abu[7]>
It was for fun only
<
geri>
i respect your meaning of "having fun"
<
geri>
i think in theory only arrays has a more complete feature set
<
geri>
but a lot more complexity
<
abu[7]>
What features do you think of?
<
geri>
like you can build more out of arrays efficiently
<
geri>
you get hash maps, vectors, structs and anything else from there
<
geri>
but then again, more types means more functions you need to maintain, more complexity in general
<
abu[7]>
I think cells have more "features"
<
geri>
and gc will need more work too
<
geri>
abu[7]: cell is just an array of 2 machine words, but a bit smaller cause specialized
<
geri>
structs are just arrays + some layout system
<
geri>
hash maps and vectors can just be implemented on top of structs
<
geri>
its a ton of moving parts for all that power though
<
geri>
maybe that's the kind of interpreter i gotta write in the end :D
<
abu[7]>
Based on arrays?
<
geri>
just symbols, numbers and arrays
<
abu[7]>
I think it is a lot less flewible
<
geri>
probably doesn't count as a lisp though
<
geri>
how so? abu[7]
<
geri>
(brb in ~30 mins)
<
geri>
so how are arrays less flexible than cons cells?
<
geri>
cons-idering you can just have arrays of 2 elements in place of every cons cell and get exact same thing
<
abu[7]>
I think basing on arrays is not a good idea, Back in 30 mins ;)
<
bjorkintosh>
CONS-idering.
<
bjorkintosh>
clever.
<
abu[7]>
bjorkintosh 👍 ☺
<
abu[7]>
On the language (not implementation) level, if you want to settle for one type, cons cells are a lot more flexible
<
abu[7]>
Manipulations like passing the CDR
<
abu[7]>
Consing in front
<
abu[7]>
With cells you can easily manipulate complex data structures
<
abu[7]>
With arrays you end up copying lots of stuff
<
geri>
you can emulate cons cells with arrays though...
<
geri>
but it may cost 1.5 times if not more of memory per cell
<
geri>
cause you need metadata for length of an array
<
geri>
how does language and implementation level differ btw?
<
geri>
oh i guess like (+ a b) being one array vs it being a linked list (no matter if cells are specifically cons cells or arrays of size 2)
<
abu[7]>
On the language level cells are much easier, just a single pointer
<
abu[7]>
With arrays you nesd an index
<
geri>
yeah, youll at least need to pass an extra arg for index
<
geri>
and a lot of functions manipulate the ast structure
<
abu[7]>
It is the cell which makes Lisp such a powerful language
<
geri>
i thought it was about user-manipulatable AST
<
abu[7]>
That's a result ;)
<
geri>
is it though?
<
abu[7]>
I think so
<
geri>
arrays are not as convinient for insertion and such, but you can manipulate them too
<
abu[7]>
Yes, but not dissect them
<
abu[7]>
CAR and CDR
<
abu[7]>
and the second aspect of Lisp
<
abu[7]>
are symbols
<
geri>
yeah i cant imagine a lisp without symbols
<
abu[7]>
like Scheme :D
<
geri>
imo they're still present, but they're nowhere as "real" as in picolisp
<
geri>
common lisp actually has a value cell, its used for dynamic variables
<
abu[7]>
They are just names
<
abu[7]>
identifiers
<
abu[7]>
CL has symbols, yes
<
abu[7]>
and all other Lisps
<
abu[7]>
Scheme and Clojure are not Lisps
<
geri>
honestly "being a lisp" means different things for everyone
<
beneroth>
geri, the essential thing about arrays is that they are a continuous block of memory
<
geri>
pairs themselves are also continuous in memory
<
geri>
just 2 machine words stuck together
<
beneroth>
yes, but linked lists are not