beneroth changed the topic of #picolisp to: PicoLisp language | The scalpel of software development | Channel Log: https://libera.irclog.whitequark.org/picolisp | Check www.picolisp.com for more information
lispnik has joined #picolisp
lispnik has quit [Client Quit]
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
<abu[m]> I try to paste:
<beneroth> scalpel etc.
<beneroth> yeah
<abu[m]> So point 3 is what I wrote above
<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
<abu[m]> oops, wrong paste
<beneroth> same as before
<abu[m]> yes :)
<abu[m]> Next try
<abu[m]> So vip shadows three symbols
<beneroth> nice new function (shadowing), I think it hasn't made it into pil64
<abu[m]> And llvm shadows almost everything
<beneroth> hahaha
<abu[m]> yes, shadow is new (a few weeks)
<abu[m]> also 'namespaces'
<abu[m]> Namespaces in pil64 were more limited and not so useful
<abu[m]> e.g. the automatic 'priv' namespace
<abu[m]> we can use combinations of (local) and (private)
<abu[m]> A good example is @lib/simul.l
<abu[m]> or the above @lib/svg.l
<beneroth> nice one: http://pb1n.de/?b89bd9
<beneroth> okay, I will look into it with interest
<abu[m]> ok :)
<abu[m]> (private) is also used in namespace-less libraries like @lib/form.l
<abu[m]> I kept form.l and http.l etc. without namespaces, because otherwise old apps might break
<beneroth> ok
<beneroth> thanks for everything, as always :)
<abu[m]> My pleasure! ☺
m_mans has joined #picolisp
<aw-> hey guys, I just published some Zig FFI code that works with PicoLisp
<aw-> if anyone is interested in Zig..
<abu[m]> Thanks aw-!
<abu[m]> Quite into 'native' :)
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
<beneroth> # port redefined
<beneroth> # listen redefined
<beneroth> # connect redefined
<beneroth> # accept redefined
<beneroth> # host redefined
<beneroth> # udp redefined
<beneroth> Segmentation fault (core dumped)
<beneroth> make: *** [Makefile:48: base.ll] Fehler 139
<beneroth> any idea?
<beneroth> global picolisp is pretty old (19.something), maybe that?
<abu[m]> These "redefined" are strange. You should start from a freshly unpacked picoLisp.tgz
<abu[m]> It hase a base.ll and needs no rebuild
<beneroth> yeah that was it
<beneroth> switched to newer picolisp version
<abu[m]> So no PicoLisp is used or needed
<abu[m]> ah ☺
<beneroth> well it asked for ../bin/picolisp
<beneroth> so I made a link to global
<abu[m]> So it was no fresh TGZ
<beneroth> it was
<beneroth> rolling release
<abu[m]> base.ll is newest and not needed to rebuild
<abu[m]> hmm, strange then
<beneroth> maybe (cd src; make clean) did remove it?
<beneroth> I did make clean a few times because of the earlier errors
<beneroth> now it seems to be well :)
<beneroth> ./pil
<beneroth> : (version)
<beneroth> 23.1.6
<abu[m]> Yes! "clean" removed it :)
<abu[m]> Very good!
<beneroth> ok, than that was the issue
<beneroth> so building without base.ll requires picolisp 20+ :D
<abu[m]> You could run the unit tests first
<abu[m]> $ ./pil lib/test.l -bye +
<abu[m]> I'm sure it passes
<beneroth> right yeah
<beneroth> yep passsed
<beneroth> all good
<beneroth> thanks for the help :)
<abu[m]> \☺/
<beneroth> yeeeehaaaaaa
alexshendi has joined #picolisp
<beneroth> hi alexshendi, happy new year to you!
alexshe23 has joined #picolisp
alexshendi has quit [Read error: Connection reset by peer]
alexshe23 has quit [Read error: Connection reset by peer]
alexshendi has joined #picolisp
<beneroth> abu[m], is there a way besides (version) to check if its pil64 or pil21 ?
alexshe65 has joined #picolisp
alexshendi has quit [Ping timeout: 252 seconds]
alexshe65 has quit [Read error: Connection reset by peer]
alexshendi has joined #picolisp
alexshendi has quit [Read error: Connection reset by peer]
alexshendi has joined #picolisp
<abu[m]> Hmm, not really I'm afraid. Only complicated things like (vi 'car) ;)
<abu[m]> Pil64 has a global *Led which does not exist in pil21
<abu[m]> *Led is the line editor which is readline() in pil21
alexshendi has quit [Quit: -a- Connection Timed Out]
<beneroth> nice idea with *Led
<beneroth> ah only in debug mode
alexshendi has joined #picolisp
<aw-> hi beneroth glad to see you're back
<beneroth> yeah I survived the distro-upgrade :D
alexshe38 has joined #picolisp
alexshendi has quit [Read error: Connection reset by peer]
alexshe38 has quit [Read error: Connection reset by peer]
alexshendi has joined #picolisp
alexshendi has quit [Read error: Connection reset by peer]
alexshendi has joined #picolisp
alexshendi has quit [Client Quit]