seninha has quit [Remote host closed the connection]
m_mans has joined #picolisp
m_mans has quit [Remote host closed the connection]
m_mans has joined #picolisp
m_mans_ has joined #picolisp
m_mans has quit [Ping timeout: 272 seconds]
m_mans_ has quit [Read error: Connection reset by peer]
m_mans has joined #picolisp
m_mans has quit [Remote host closed the connection]
seninha has joined #picolisp
cess11 has joined #picolisp
<cess11>
seems penti is fine now, thanks!
<abu[m]>
Great! Thanks for the feedback cess11! I would not have noticed.
cess11 has quit [Ping timeout: 260 seconds]
chexum has quit [Quit: No Ping reply in 180 seconds.]
chexum has joined #picolisp
<abu[m]>
> Unfortunately this Forth does not work on pil21, because of readline IIRC
<abu[m]>
I was wrong. Seems to work fine also on pil21 ☺
seninha has quit [Quit: Leaving]
seninha has joined #picolisp
<beneroth>
abu[m], how would readline disturb this Forth you suspected?
<beneroth>
disturbing the reading?
<abu[m]>
I just suspected so, because I believed to remember it behaved strange.
<abu[m]>
Not the reading itself, but the key handling
<abu[m]>
I thought forth.l calls (key) in (raw T) mode directly, but that's not the case
<abu[m]>
It simply calls (char)
<abu[m]>
In case of raw mode, I'm never sure, because readline() does its own raw handling
<beneroth>
okay I see
<beneroth>
well.. (raw T) and (key) is kinda "here be dragons" :-/
<abu[m]>
yep
<beneroth>
I haven't fully mapped out that area, full of old weird legacy stuff
<abu[m]>
Used on their own, they work fine though
<beneroth>
(char) is good
<beneroth>
though I need the (char) and "how many bytes did I read?"-thingy.. so I gonna try pil21 and its new functions :)
<abu[m]>
yes, and (key) also e.g. in vip
<beneroth>
T
<abu[m]>
(raw T) works also fine e.g. in @bin/pty
<abu[m]>
I need it also in some front end scripts to ssh
<beneroth>
abu[m], re pil21, I think (arg) (cnt arg now being mandatory, not optional anymore) and (run) only offsetting @.. thats the thing I should be aware of, right? did I forget somethign?
<abu[m]>
and in the front end emulating a keyboard in X11 with Penti ;)
<beneroth>
:)
<abu[m]>
yes, (arg) without args is not supported
<beneroth>
cnt should just default to 1 and its like old arg again, no?
<beneroth>
:P
<abu[m]>
and also yes regarding (run)
<abu[m]>
and (eval)
<abu[m]>
No, it is not a default
<beneroth>
ah yes, (eval) same as (run), I see
<abu[m]>
It has internal reasons
<beneroth>
yep its not the default. maybe it should be
<beneroth>
ok
<abu[m]>
The arg is not known
<abu[m]>
i.e. after (next)
<abu[m]>
It is kind of popped off the list
<beneroth>
ah I see, yes I wrote BS above, (arg) was the last (next) result
<beneroth>
so you got rid of another global variable, so to say
<abu[m]>
yeah
<beneroth>
well not global, but yeah
<abu[m]>
To support it, it would require extra internal runtime overhead
<beneroth>
yep, a cell to hold the last result of (next)
<abu[m]>
ie. keeping it somewhere in case (arg) were called
<abu[m]>
T
<abu[m]>
So this is now delegated to the user ;)
<beneroth>
(rest) is not (and never was) consuming, right?
<beneroth>
so (arg 1) is arguably the same as (car (rest)) ?
<abu[m]>
(let V (next) ..
<beneroth>
T
<abu[m]>
(arg 1): yes
<beneroth>
C++ Template style.. if you use it, you can, if you don't then you don't pay anything for it
<beneroth>
hm
<abu[m]>
yes, in a compiled system
<beneroth>
yeah I agree with the change with (arg). doing it explicitly when needed and otherwise not spending on it
<abu[m]>
so here the user must do (let V (next) ...) if the value is needed again
<abu[m]>
Also, (arg) is a function call and thus expensive just to get a value we already have
<beneroth>
T
<beneroth>
well how to weight off function calls against cell spent? :D
<abu[m]>
lib/form.l had a few such cases
<abu[m]>
e.g. in 'url'
<beneroth>
makes sense
<abu[m]>
lib/db.l too
<beneroth>
I must check by DSLs
<beneroth>
*my
<abu[m]>
yes
<beneroth>
it uses often functions with arbitrary many evaluated arguments as context/parser
<beneroth>
hm...
<beneroth>
(input) and (output) give some more fine control, that's good
<abu[m]>
right, that's new
<beneroth>
I still need an implementation of (char) which also lets me know how many bytes were read, or to limit the number of bytes to read maximum
<abu[m]>
You can see the bytes count with (size )
<beneroth>
maybe it could be done easier now by reading 1 byte and then compare with (char T) instead of manual byte coding to see if there is more UTF-8 bytes belonging to the same char?
<beneroth>
right, thats an idea. put every read char through size
<beneroth>
still though not limiting the reading, if you want to read maximum 20 bytes and if the last one is a garbled UTF-8 char then indicate somehow that, but never attempt to read more
<beneroth>
hmmm
<abu[m]>
there is no low level byte count during reading. Only lines are counted.
<beneroth>
ok
<abu[m]>
You need something like : (size "赤") -> 3 ?
<beneroth>
more like: read me one char, up to 3 bytes, let me know how many bytes you read
<beneroth>
to handle incoming buffers / known content length
<beneroth>
instead of reading until newline or number of characters and trusting the sender
<abu[m]>
Do you need a fixed buffer at all?
<abu[m]>
You could collect chars into a list
<abu[m]>
or fifo
<abu[m]>
(fifo 'Buf (char))
<aw->
interesting discussion.. i believe I ran into this issue as well a while back and just ended up writing some glue code in Rust to handle that
<abu[m]>
or call a C function with buffer limits
<aw->
abu[m]: yes same thing, but I'd rather write in Rust than in C haha.
<abu[m]>
ok
<beneroth>
I've handled it now in pil64 but in a quite ugly way, I believe
<beneroth>
the issue is not the fixed buffer, but not ending up reading more bytes then intended (ending up in lock while waiting for sender, or getting of course in the parsing of the input)
<abu[m]>
I see, yes
<abu[m]>
Happens only on error?
<beneroth>
yes.. error or malicious sender
<beneroth>
the aim would be to detect it as early as possible and then abort
<abu[m]>
So you could just use (abort ...)
<beneroth>
timing, yes
<beneroth>
invalid input, nope
<abu[m]>
yeah, abort takes too long
<beneroth>
its good to use abort though, if untrusted network channel
<beneroth>
when just doing (line) on untrusted network input, the program can be DOSed easily by sending endless stream without newline. filling up the memory and DOSing the whole thing.
<beneroth>
ofc sender still has to send all the stuff, not much leveraging/multiplying of the size, but still
<abu[m]>
Can you implement your own protocol? Then you could require a Conten-Length count first.
<beneroth>
aw-, btw. fun thing about nginx: it doesn't validate the input when proxying. well it does, but if it cannot make sense out if it, it just passes it on. so its no protection for a webserver behind it. (on the other hand, just passing on allows funny stuff like turning the http connection in something else)
<beneroth>
abu[m], well it also applies to HTTP. there is Content-Length. now read the body. how to keep count how many bytes your read? Content-Length is in bytes, not chars.
<abu[m]>
right
<beneroth>
my pil64 currently reads (char) by char, detects if it got a multibyte UTF-8 char then reassembles it into a single char.
<beneroth>
that needs kinda to happen. maybe (char T) makes this now easier
<abu[m]>
But you can pre-allocate the buffer, then (%@ "fgets"
<abu[m]>
But (char) reads already multibyte
<beneroth>
ah you mean read the whole buffer in C (or rust or whatever), and then use the buffer as picolisp input channel?
<abu[m]>
yes
<beneroth>
nice idea, though I don't wanna do that as I like my http parser to only read whats needed, gives a speed up xD
<beneroth>
but yeah
<abu[m]>
(buf P Size (%@ "fgets"
<beneroth>
how would you do that, how to turn a buffer into a picolisp input channel?
<abu[m]>
you can get e.g. a string with (struct P 'S)
<abu[m]>
Both 'buf' and the struct syntax are new in pil21 btw
<abu[m]>
(struct P 'S) I mean
<abu[m]>
"* Useful atomic result specifications" in doc/diff
<beneroth>
nice, thanks!
<beneroth>
so we're still on topic ("things beneroth should be aware while starting srsly with pil21") :)
<abu[m]>
yep
<abu[m]>
But I think the two points you mentioned are the critical ones. (arg) and (run) / (eval)
<beneroth>
T
<abu[m]>
And perhaps using libs which don't exist any more, like lib/ps.l or lib/tex.l
<abu[m]>
I had to adjust some pathes for these libs
<abu[m]>
i.e. change "@lib/ps.l" to "lib/ps.l"
<beneroth>
svg.l still exists?
<abu[m]>
Besides this, all my old apps continued to work fine
<beneroth>
I used that one to make PDFs
<abu[m]>
yes, but svg now is in its own namespace
<abu[m]>
so this needs some attention
<beneroth>
ok, good to know, should be easy to adapt
<beneroth>
I just thought about one more thing but forgot instantly again... damn
<abu[m]>
You can jus prefix with "svg~", but I prefer (symbols 'ap 'svg 'pico)
<abu[m]>
i.e. putting the whole app into its own 'ap' namespace
<abu[m]>
Cleans up things ☺
<beneroth>
for libs namespaces are okay, you can always intern just the public functions, often the lib does that anyway, right?
<abu[m]>
Intern is anyway, but (local) is recommended to hide stuff if wanted
<beneroth>
but in general... I'm careful with not overusing namespacing. I like to store code into pilDB, easier if I don't have to ensure namespace symbol list everywhere which can be different
<beneroth>
(ht:) still works the same, and : read macro still works the same, right?
<abu[m]>
There are a few rules which make it pretty predictable (I think we talked about them in PilCon)
<beneroth>
pil namespaces are great, very powerful, but must not be sprinkled over everything as namespacing is often used in other languages
<beneroth>
invariant namespace orders + combination of possibly many libraries in a ever changing way is what makes me careful
<beneroth>
for general application
<beneroth>
pure libraries are another thing
<abu[m]>
If you take care to keep the order always the same, then there is no risk of getting the wrong symbol in property accesses
<abu[m]>
I think PilBox is a good example
<abu[m]>
The namespaces are switched all the time
<beneroth>
yep but you have multiple different orders in different files/contexts, or a very big namespace list quickly (when using many namespaces/libraries), no?
<abu[m]>
but the *order* in each case stays the same
<beneroth>
in PilBox you have one per app, right?
<abu[m]>
yes
<abu[m]>
and the apps are switched at runtime within the same pil process
<abu[m]>
s/within/between
<beneroth>
yes, but they're total separated, not intermixed, right?
<beneroth>
actually you use the namespacing to separate them?
<abu[m]>
What do you mean with intermixed?
<abu[m]>
I use it to avoid conflicts
<beneroth>
e.g. two apps working with the same database objects
<abu[m]>
Also in pil itself, e.g. vip has its own
<abu[m]>
It redefines some pil functions
<beneroth>
yeah makes sense
<beneroth>
I do this usually with (let) :)
<beneroth>
as you know
<beneroth>
but for something like vip it makes sense to do it on the whole namespace
m_mans has quit [Remote host closed the connection]
<aw->
yes I've always liked (native) even though I fight with it a lot
<aw->
i think it's the most difficult part of PicoLisp
<aw->
but also one of the most useful features of PicoLisp, like a superpower.
<abu[m]>
Indeed. I also need to fight to use it. (doc 'native) to get the args right.
<beneroth>
aw-, nice, thanks!
<beneroth>
abu[m], which LLVM version do I need? seems I have 6.0.0 installed
<abu[m]>
According to tankf33der's research at least 7 is needed
<beneroth>
building pil21 fails with multiple instances of "Intrinsic has incorrect argument type! void (i8*, i8*, i64, i1)* @llvm.memcpy.p0i8.p0i8.i64"
<beneroth>
ok, that explains it
<abu[m]>
yeah
<abu[m]>
I have 15 on Termux and 14 on Debian
m_mans has joined #picolisp
m_mans has quit [Remote host closed the connection]
<beneroth>
bbl, updating my system...
beneroth has quit [Quit: Leaving]
<aw->
(01:08:14) beneroth: bbl, updating my system...
<aw->
Famous last words
<abu[m]>
haha ☺
m_mans has joined #picolisp
m_mans has quit [Ping timeout: 252 seconds]
beneroth has joined #picolisp
<beneroth>
abu[m], got now LLVM 14.0.0, still got problems