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
<tankf33der> Morning all
<tankf33der> you are right, pil64 returns tag error too
<abu[7]> Good to know
<tankf33der> Do know exactly string, will paste in several hours
<tankf33der> do -> dont
<abu[7]> Pil64 used different algorithms here, so not comparable
msavoritias has joined #picolisp
rob_w has joined #picolisp
<abu[7]> Added a check for terminated originator in 'yield'
<abu[7]> 'a' is the originator coroutine of 'b'
beneroth has quit [Quit: Leaving]
<abu[7]> and when 'b' returns from 'yield', 'a' is already gone and the c
<abu[7]> stacks cannot be restored
<abu[7]> I see no other way how 'b' could recover from that situation
<tankf33der> Checking
<tankf33der> Tests failed
<tankf33der> alarm
<tankf33der> i will paste error asap
<abu[7]> The check is not 100% correct anyway, because meanwhile another co may occupy the stack frame
<abu[7]> It is hard to check for disappeared coroutines
msavoritias has quit [Ping timeout: 268 seconds]
<tankf33der> abu[7]: crashing this code
<abu[7]> Meetng, back in a few hours.
<tankf33der> found shorter or similar way:
msavoritias has joined #picolisp
msavoritias has quit [Remote host closed the connection]
<abu[7]> done
<abu[7]> checking
<abu[7]> I see, a yield from the main routine to itself
<abu[7]> So a different issue
<abu[7]> I'm more worried about the disappeared coroutines
<abu[7]> How to detect this in general
<abu[7]> I investigate the yield to T first
<abu[7]> Can be shorter btw: (co 'a 7) (yield T T)
rob_w has quit [Remote host closed the connection]
<abu[7]> Fixed it. My change this morning was in ther wrong place by one line off!
<tankf33der> Passed
gahr has quit [Ping timeout: 260 seconds]
<tankf33der> now i have another illegal issue, pasting
gahr has joined #picolisp
<abu[7]> Too small stack segment size?
<tankf33der> Maybe :)
<tankf33der> it was simple error before
<tankf33der> stack overflow etc
<abu[7]> I use 8 as minimum
<abu[7]> If the stack is such small, even erro handhing is not doable
<tankf33der> Yea
<abu[7]> I'm still thinking about the terminated onignator coroutines
<abu[7]> This is ugly
<abu[7]> I cannot check
<abu[7]> (co 'a (co 'b (throw (yield))))
<abu[7]> 'a' is gone
<abu[7]> At first ok, but the segment might be used by a new coroutine when 'b' continues
<abu[7]> Then some stack links in 'b' might be faulty
<abu[7]> The check from today does not notice that
<abu[7]> Because coroutines run completely independent from each other, a check is not possible currently
<abu[7]> When a coroutine terminates, it does not care if any child routines are still running (and this even may be desired)
<tankf33der> ? (stack)
<tankf33der> -> ((a . 63) ((NIL) . 57) ((NIL) . 57) ((NIL) . 57) (T . 249) . 64)
<tankf33der> illegal play
<abu[7]> hui
<tankf33der> this is russian word
<tankf33der> :)
<abu[7]> Means? ;)
<tankf33der> dick or penis
<abu[7]> Uh, sorry ;)
<abu[7]> How did you mess up the stack?
<tankf33der> (co (cons) (yield))
<abu[7]> Ah, ok, so not messed up
<abu[7]> Tag may be anything
<abu[7]> a symbol is just more efficient
msavoritias has joined #picolisp
<tankf33der> Bus error (core dumped)
<tankf33der> never seen this before
<abu[7]> ok
<tankf33der> now hang
<tankf33der> i am close
<tankf33der> like this
<abu[7]> Hmm
<abu[7]> Why the "'a" in (co (stack) 'a ... ?
<tankf33der> another variation: http://pb1n.de/?cb2e78
<abu[7]> Ignored, right?
<tankf33der> first time yes
<abu[7]> Why not second time?
<tankf33der> unknown
<abu[7]> You mean "second versipn"?
<abu[7]> Anyway, no idea what exactly is relevant
<tankf33der> first version hang, second version coredumps
<abu[7]> Why does the second example have (stack)? You did not (co ...
<tankf33der> Stream of consciousness.
<tankf33der> the same variation, bus error - http://pb1n.de/?618b89
<tankf33der> exhausted
<abu[7]> (co (stack) 'a (stack 3)) is OK
<abu[7]> It is (co 64 (stack))
<tankf33der> yeap
<abu[7]> Meaningless though
<abu[7]> So what exactly is illegal?
<abu[7]> Is it starting 'co' inside error handler?
<tankf33der> i pasted snapshot what i typed
<abu[7]> Yes
<abu[7]> Probably starting 'co' inside error handler is a problem, because the co is in an unknown state? And it is reentrant then
<tankf33der> with 3 different behaviour - hang, segmentation and bus error
<abu[7]> The concrete behavior is random I think
<abu[7]> The point is what exactly is the illegal operation?
<abu[7]> What destoys which structure
<abu[7]> (co 'a (yield 'a 'a)) terminates and starts/stops 'a' while *in* 'a' (in error handler)
<abu[7]> No idea what happens exactly ;)
<abu[7]> Maybe the stack frame of 'a' is freed and reused while in the error
<abu[7]> In general it is dangerous to continue processing while in an error break. Remember your case (let (* 3 4)
<abu[7]> then calling '*' while still in error
<abu[7]> because '*' is bound to 3 until you rewind to top level
<abu[7]> An error break is to *inspect' the state of the program that caused it
<tankf33der> bus error without errors
<abu[7]> The calls (co '((((T . 254) . 64) . 6... just create many (inaccessible) coroutines
<abu[7]> So is (co 'bc (co 'b (yield 'b 'b))) the problem?
<abu[7]> Looks legal to me
<tankf33der> two calls is enough
<abu[7]> Does not crash or Termux but gives "b -- Coroutine not found"
<tankf33der> try debian then
<abu[7]> Ah, hangs also
<tankf33der> good
<abu[7]> As (co 'bc ...) seems legal, perhaps the lists as coroutine tasks are a problem?
fuxoft has joined #picolisp
<abu[7]> Tag is 'any', but perhaps there is an assdmption somewhere that they are symbols?
<abu[7]> I check
<fuxoft> Hello. I am trying to learn about forking and inter-process communication but I am failing miserably. I expected this to print 7 lines of increasing "unique counter" integer but it prints garbage instead: https://gist.github.com/fuxoft/52da8949edba4961c059c18014d90cc3
<abu[7]> Hi fuxoft!
<abu[7]> I get http://pb1n.de/?5506fb
<abu[7]> Is this wrong?
<fuxoft> Yeah, I expected the expression in parentheses to increase from ("unique counter" 1) to ("unique counter" 7)
<abu[7]> You are in 2 processes
<abu[7]> So the counters are per process
<fuxoft> I thought the counter is in separate 3rd process ("pipe")
<abu[7]> Yes, but you don't know which process reads what
<fuxoft> Oh, I thought that both printing processes read one item from the counting process.
<abu[7]> It is a single pipe
<fuxoft> So it's a problem for 2 processes to read from a single pipe?
<abu[7]> you *do* get unique nums
<abu[7]> No, is ok
<abu[7]> but the reads are not atomic
<abu[7]> So yes, gives garbage ;)
<fuxoft> Is there a way to do something similar atomically, I.e. one process providing a stream of general values and several other processes taking the next available item from this stream?
<abu[7]> A pipe is a stream of blocks of 512 bytes
<abu[7]> buffered by the receivers
<abu[7]> Hmm, what is the best way?
<abu[7]> Best would be a pipe to each receiver
<abu[7]> (for Pid (kids) (tell Pid 'println (inc 'N]
<fuxoft> But in this case, would it work if one process consumes the counter e.g. at twice the rate of another process?
<abu[7]> No, it is the senden who controls it
<abu[7]> There must be a way
fuxoft has quit [Quit: Client closed]
fuxoft has joined #picolisp
<fuxoft> I was thinking about inter-process messages similar to Erlang. Clearly pipes work quite differently...
<abu[7]> In pil interprocess messages are done via 'tell'
<abu[7]> But that's the sender
<abu[7]> It needs some handshaking then
<abu[7]> A receiver 'tells' the sender to 'tell' to him
<abu[7]> (tell *SendPid 'tell *Pid ...
<fuxoft> BTW the docs for (tell) say "See also kids, detach and hear." - And the docs for "hear" don't exist
<abu[7]> oh
<abu[7]> No, there is a ref for 'hear'
<abu[7]> the link works for me
<abu[7]> (locally)
<fuxoft> Strange, when I click the "hear" link, I see the top of refH.html file
<abu[7]> here it works software-lab.de/doc/refT.html#tell
<fuxoft> Oh, sorry, scratch that, it was problem with my browser
<abu[7]> I never use the index
<abu[7]> Ah, ok
<fuxoft> I have to learn more about tell and hear.
<fuxoft> Are there more examples for these somewhere?
<abu[7]> (tell *SendPid 'tell *Pid '(list 'println '*Pid '(inc 'N]
<abu[7]> Something like that :)
<abu[7]> Needs careful thinking about the right quoting, not tested
<fuxoft> To receive the (tell) program, the child has to be in the (wait) state?
<abu[7]> Yes
<tankf33der> i see more tell examples
<abu[7]> T
<abu[7]> (tell *SendPid 'tell *Pid '(list 'println '*Pid (inc 'N]
<abu[7]> better perhaps
<abu[7]> Without parens rather
<fuxoft> Is the (task) system related to this in any way?
<abu[7]> (tell *SendPid 'tell *Pid 'list ''println ''*Pid '(inc 'N]
<abu[7]> Only internally
<abu[7]> It is the same place that handles tasks and IPC
<fuxoft> This https://git.envs.net/mpech/tankf33der/raw/branch/master/Burger/rosettacode.l looks like lots of useful examples. What's that? Is it a part of something bigger?
<tankf33der> fuxoft: this is all rosettacode.org tasks in one file
<abu[7]> It is the rosetta code project, covering *very* many langs
<tankf33der> fuxoft: i have not small codebase but never played with IPC, cannot help you here
<fuxoft> For the (task) function, the first argument (when negative) is the invocation interval and this is also the id of the task? So I cannot have two different tasks with the same invocation interval?
<abu[7]> Right
<abu[7]> You can add the bodies
<abu[7]> in one task then
<fuxoft> Oh ok
<fuxoft> It just seemed weird at the first sight :)
<abu[7]> Or use slightly different times
<abu[7]> Yeah
<abu[7]> *Run does not care
<tankf33der> afk
<abu[7]> 'task' is just a front end
<abu[7]> See you tankf33der!
<fuxoft> So when I do the example at https://software-lab.de/doc/refW.html#wait , it all gets executed in a single process?
<fuxoft> No (fork)ing involved?
<abu[7]> Correct
<fuxoft> Heureka! :)
<abu[7]> A somewhat conceived example
<abu[7]> Better with task and co
<fuxoft> Let's say I want to do a system that handles incoming data from various endlessly running Linux commands (e.g. mosquitto_sub) from various sources. I can do all this using *Run, in a single process, without forking?
<abu[7]> )
<abu[7]> )
<abu[7]> )
<abu[7]> Oops
<abu[7]> yes
<fuxoft> That's great.
<abu[7]> (task -2000 0 (co 'cnt (for I 6 (println I) (yield)) (task -2000)))
<fuxoft> And back to processes: Is there a simple way to (kill) a process and all its children and all their children etc... (the whole subtree)?
<abu[7]> Yes, just kill the parent
<abu[7]> SIGTERM
<fuxoft> Oh, so I have to do (detach) to prevent the child being killed?
<abu[7]> I don't remember the details
<fuxoft> Never mind. Thank you again for all your help
<abu[7]> Welcome :)
fuxoft has quit [Quit: Client closed]
<abu[7]> For the records: (vi 'llvm~sighandler)
<abu[7]> ((val (setq P (ofs $Signal SIGTERM)))
<abu[7]> So 'detach' will prevent killing
msavoritias has quit [Ping timeout: 255 seconds]
<abu[7]> tankf33der: I said I cannot well check for terminated originator coroutines, but at least I added a plausibility check that it is a coroutine with the same tag
<abu[7]> Can you run all your tests to make sure I did not break it?
<tankf33der> Sure
<abu[7]> 😎
<tankf33der> Passed
<tankf33der> What about the rest?
<abu[7]> Great! Thanks.
<abu[7]> I investigate the list tag issue
<tankf33der> Good, thanks
<abu[7]> Minimal so far:
<abu[7]> (do 2 (co (1) 7)) (co 'bc (co 'b (yield)))
<abu[7]> Still no idea
<tankf33der> did you checked structures?
<abu[7]> Not directly
<tankf33der> ok
<abu[7]> I know where it fails
<abu[7]> (co 'bc (co 'b (yield))) should first terminate 'bc'
<abu[7]> (and then 'b' waits in yield and would error if continued)
<abu[7]> But: It first tries to stop 'b'
<abu[7]> Makes no sense, so the co frames must be corrupt somewhere
<abu[7]> I give up for today and have a beer
<abu[7]> Let's see tomorrow ...
<tankf33der> good.
<tankf33der> afk.
<abu[7]> o/
fuxoft has joined #picolisp
<fuxoft> Is this the correct / simplest way to handle input from several independently running shell commands? https://gist.github.com/fuxoft/bf38c8ade7ff6cff7f2735f708a57fa5
<abu[7]> Yes, very good, I would also check for NIL (end of file) and then close FD and task
<fuxoft> Got that.
<abu[7]> (in @ (ifn (line T) (task (close ..)) (prnitln ...
<fuxoft> Why exactly is the '@' correctly populated here, is that some "task" magic?
<abu[7]> Yes, just for convenience, cause it is almost always needed
<fuxoft> At 20:06:35, why is there "(task (close ..." and not just "(close ..." ?
<abu[7]> To stop also the task
<fuxoft> Oh, because "(close ..." returns the number and then it stops the task
<fuxoft> OK
<abu[7]> close returs the FD
<abu[7]> T
<abu[7]> This pattern is often in the system, e.g. @lib/http.l
fuxoft has quit [Ping timeout: 250 seconds]
pablo_escoberg has joined #picolisp
pablo_escoberg has quit [Quit: Client closed]