Hi Srini, > I am trying to understand this example from the reference: > (prog1 # Parallel background calculation of square numbers > (mapcan '((N) (later (cons) (* N N))) (1 2 3 4)) > (wait NIL (full @)) )
> Could you please explain how it works, because it has many > interrelated pieces: cons,mapcan, wait that I thought I understood > individually but still I do not understand the example. This call to 'prog1' executes two expressions, returning the result of the first one, but _after_ executing the second one. The first expression calls 'mapcan' on the list (1 2 3 4), by applying the function ((N) (later (cons) (* N N))) to each of the numbers. This function in turn returns the result of 'later'. So the key here is 'later'. As the reference says, (later 'var . prg) -> var 'later' accepts a 'var' (i.e. a symbol or a list cell), and returns that var. As a side effect, it takes a program (a 'prg' which is a list of expressions), runs that in a child process, and stores the result of that 'prog' in the 'var' at some later point when the child process is done. For a simple example, we can execute in the REPL : (later 'A (+ 1 2 3 4 5)) -> A We see that 'later' returs the variable 'A'. But if we look a moment after that into the value of 'A' : A -> 15 we see that it has received the result of the calculation. A single call to 'later' is not very useful, because we might instead directly execute the expression. But if one same expression has to be done in parallel (a typical use case is starting a parallel database query on remote machines), then we pass list cells instead of a single variable to 'later'. This is done with the 'mapcan' and 'cons' above. Remember that (cons) is just a shortcut of (cons NIL NIL), and that 'mapcan' concatenates the returned results. Thus, the above call without 'later' gives: : (mapcan '((N) (cons NIL NIL)) (1 2 3 4)) -> (NIL NIL NIL NIL) However, if we have (mapcan '((N) (later (cons) (* N N))) (1 2 3 4)) Then as a side effect each call to 'later' receives its private, newly 'cons'ed list cell - i.e. a 'var' - which it duefully retunrs to 'mapcan' to be concatenated to the full list. At the same time, each 'later' remembers its private cell, and stores its result from the child process there. Then 'wait' waits until ALL cells are filled (i.e. non-NIL). > Another confusing thing is the "@". How does one find which of the > previous functions updated the @, and which did not. I know that control This is documented in "http://software-lab.de/doc/ref.html". Exclusively the (flow) functions listed there will modify '@'. There's also a nice article by Thorsten: The many uses of @ in PicoLisp http://picolisp.com/wiki/?atmark ♪♫ Alex -- UNSUBSCRIBE: mailto:picolisp@software-lab.de?subject=Unsubscribe