<geri>
is resolved_path is NULL, string gets malloc'd instead
<geri>
hm
<abu[7]>
T
<abu[7]>
tricky
<geri>
im pretty happy with my script all things considered
<abu[7]>
native allocates the struct from the nrgument list, fills R, and discards the mem
<abu[7]>
Yes, but perhaps this acceses free'd memory
<abu[7]>
Let me check the sources of native
<geri>
if it accessed freed memory i bet it'd crast 10k times while testing q
<abu[7]>
No, depends
<abu[7]>
it is allocated on the stack
<abu[7]>
From the ref: "native takes care of allocating memory for strings, arrays or structures, and frees that memory when done"
<geri>
so all is good?
<abu[7]>
No
<abu[7]>
The return value is the pointer to the struct
<geri>
(%@ "getenv" 'S "TERM")
<geri>
from the manual for %@
<geri>
how is this any different from realpath example
<abu[7]>
Good point
<geri>
afaik the base idea is - %@ allocates some buffer, no idea how much and fills it with data that realpath returns
<geri>
after, it allocates a symbol (cause 'S) normally and returns that as the response
<geri>
and then the buffer gets discarded
<abu[7]>
Thats the question
<abu[7]>
*when* it is discarded
<geri>
output value is now on the heap as usual symbols are with 0 references to original buffer
<geri>
idk, you wrote it, you tell me :D
<geri>
but in my experience this realpath is pretty reliable so far
<geri>
when i read wrong memory it usually crashes my programs every 5th or so time
<abu[7]>
I dig into it, forgot the details
<geri>
anyway, script works and works nicer than ever before
<geri>
happi
<geri>
i love not having to covert between strings and symbol and numbers
<abu[7]>
Such memory behavior is not predictable. May work a million times for a give calling setup
<abu[7]>
and is still by luck
<geri>
eh
<abu[7]>
because the setup does not yet overwrite the mem
<abu[7]>
let me dig into it
<abu[7]>
The question is *when* it is freed
<geri>
while you're researching ill go for a walk
<geri>
laters
<abu[7]>
👍
<abu[7]>
'native' does (tailcall (ffi Exe Lib Fun Args))
<abu[7]>
'ffi' calls 'ffiCall' in src/lib.c
<abu[7]>
'ffiCall' allocates the structs on the stack, fills variables like 'R', and returns
<abu[7]>
Thus the memory of the struct is no longer valid
<abu[7]>
'ffi' thea looks at the return value
<abu[7]>
In case of "realpath" this is however the pointer to the struct (which may still be on the stack on a lower address, but can any time be overwritten)
<abu[7]>
So there are 2 "correct" ways:
<abu[7]>
(use R (%@ "realpath" 'N "lib.l" '(R (`PATH_MAX C . `PATH_MAX))) (pack R))
<abu[7]>
or
<abu[7]>
(buf P PATH_MAX (%@ "realpath" 'S "lib.l" P) (struct P 'S))
<abu[7]>
(%@ "getenv" 'S "TERM") is OK, because getenv() returns a pointer to a static string in the environment
<abu[7]>
(cond ((atom) a) ((pair) b)) is a bit overkill ;) (if (atom) a b) should do
<abu[7]>
In any case very nice
<geri>
ikr :D
<beneroth>
Ahoy geri, abu[7] :)
<abu[7]>
o/
<geri>
hihi
diogenes has joined #picolisp
<diogenes>
hello, i was curious what the equivalent for let* was in picolisp. I want to define things locally sequentially and be able to refer to them in my function.
<abu[7]>
Hi diogenes! PicoLisp's 'let' behaves like 'let*'
<abu[7]>
(ie. binding one after the other)
<diogenes>
oh then my function must have another bug with it...
<diogenes>
(de time-in-secs (n unit)
<diogenes>
(let
<diogenes>
(seconds 1
<diogenes>
minutes (* 60 seconds)
<diogenes>
hours (* minutes minutes)
<diogenes>
days (* hours 24)
<diogenes>
work-days (* 8 hours)
<diogenes>
weeks (* days 7)
<diogenes>
work-weeks (* days 5)
<diogenes>
months (* days 31)
<diogenes>
years (* days 365)
<diogenes>
work-months (* work-weeks 4)
<diogenes>
work-years (* work-weeks 49) )
<diogenes>
(case unit
<abu[7]>
The let looks fine
<diogenes>
hmm
<diogenes>
then my case is fucked up
<abu[7]>
Please note that for locally bound symbols upper case is recomended
<diogenes>
okay
<abu[7]>
(let (Seconds ...
<abu[7]>
But here is no conflict I think
<abu[7]>
What goer wrong?
<diogenes>
well it doesn't return anything when i run (time-in-seconds 2 sec) -> NIL
<diogenes>
I expect 2
<abu[7]>
Perhaps some typo in one of the variables?
<abu[7]>
'*' gives NIL if any of the args is NIL
<abu[7]>
I would set a breakpoint
<abu[7]>
(! case unit
<diogenes>
okay thank you
<abu[7]>
Then look at each symbol
<diogenes>
let me try that now
<abu[7]>
👍
<diogenes>
okay weird it says that seconds is NIL
<diogenes>
so there must be something weird happening with the let binding
<abu[7]>
'minutes' is also NIL then?
<diogenes>
yes so is weeks etc
<abu[7]>
Strange indeed
<diogenes>
it says time-in-seconds -- Undefined
<abu[7]>
Just from looking it seems ok
<abu[7]>
But you called it?
<abu[7]>
to get to the breakpoint
<diogenes>
yes
<abu[7]>
It is time-in-secs
<diogenes>
lol no wonder
<diogenes>
it works now lol
<diogenes>
type
<diogenes>
typo
<abu[7]>
good
<diogenes>
i learned about break points so that is a success imo
<abu[7]>
hours (* minutes minutes) is correct, but more clear would be 60
<diogenes>
:pray:
<abu[7]>
')
<abu[7]>
:)
<diogenes>
how would i go about adding something like a documentation string to my functions? kind of like cl's defun that includes and optional doc string. does plisp have a way to do this?
<abu[7]>
Not really, just com
<abu[7]>
ments
<diogenes>
okay
<beneroth>
no built-in for that, but it would be possible in principle
<beneroth>
e.g. making another variant of (de) which then sets a documentation string as property, similar to how (de) sets the *Dbg and doc properties
<beneroth>
then again, why do a doc-string when you have the full source :)
<diogenes>
hmm
<diogenes>
i guess i do like to just do (explain 'func)
<diogenes>
no need to nav to file
<diogenes>
kind of like being able to pp
<beneroth>
there is (pp) for that :)
<diogenes>
but pp ignores comments
<beneroth>
T
<diogenes>
also some functions are foriegn. and pp de gets you just apointer
<diogenes>
so functions like that
<diogenes>
pp doesn't help
<beneroth>
when you started picolisp in debug mode (with + argument at the end in CLI), you can do (de my-func ...) and then (show 'my-func) to see the 'doc and '*Dbg property of the 'my-func symbol which were put by (de)
<beneroth>
built-ins refer here to their source code in the LLVM code
<diogenes>
yeah i see that now
<diogenes>
hmm
<beneroth>
on one hand, programmers should strife to name and structure the code clear-enough for it to be self-explanatory. on the other hand, this is not always possible. on third-hand, in cases where the code does such a complex thing a short string is probably not a good enough explanation and it needs a dedicated txt file anyway.
<diogenes>
I see what you mean, sometimes when deving i usually just put a doc-string as like a way to remind what this function should do i guess. but what you said i understand
<beneroth>
well, find a way which works for you and makes you productive :)
<diogenes>
T
<beneroth>
I use comments a lot, especially to explain functions or their parameters. and I try to have a certain system/pattern when naming things.
<diogenes>
what does your system look like?
<beneroth>
a lot is also just a matter of habit. Picolisp favours shorter names as it has no strong separation between source code and the running program, the running program is just a binary representation in memory.
<beneroth>
so shorter code uses less memory and therefore is often also faster
<beneroth>
afk for a while
<beneroth>
back already
<beneroth>
diogenes, it's really highly recommended to follow the naming convention, protects you from most accidental mistakes: https://software-lab.de/doc/ref.html#conv