On Thu, Oct 10, 2019 at 2:42 AM Zelphir Kaltstahl <
zelphirkaltst...@gmail.com> wrote:

> … If that works for arbitrary serializable-lambda with only serializable
> parts, I could continue my process pool project.
>

Yes, this would work for any value created by `serial-lambda`.


> The only issue would then be, that any user of it would have to know in
> advance, that they cannot define their lambdas as usual, but have to use
> serializable-lambda, potentially through their entire code (as there might
> be references to things which contain references to things, which ...). The
> abstraction is in this way leaky, but it would make a working library then.
>
> `n` does not need to be serializable, because it is defined in the module
> and will be defined in the module "on the other side" as well? If I
> understand this correctly.
>
I think it can help in understanding to know a bit about how
`serial-lambda` is implemented. In a context like:
(define (make-serializable-adder n)
  (serial-lambda (x)
    (+ n x)))
 `serial-lambda` uses some advanced macrology to generate a module-level
struct declaration like:
(serializable-struct representation (n)
  #:property prop:procedure
  (λ (this x)
    (+ (representation-n this) x)))
and the `serial-lambda` expression itself expands to code constructing an
instance of the struct, like `(representation n)`.

The thing to note here is that the fields of the struct hold the contents
of the closure, i.e. local variables from the lexical environment of the
`serial-lambda` expression. These values need to be serializable so that
they can be sent across the place-channel. The arguments to the
`serial-lambda` procedure—in this case, `x`—don't need to be serializable,
because they aren't part of the struct but are supplied when the procedure
is called. Similarly, module-level variables (including imports via
`require`) can be referenced directly in the generated `prop:procedure`
value, so they also don't need to be serializable: this is why `+` in the
example is ok, but the principle also covers much more complicated cases in
general.

So, users of your process pool only need to use `serial-lambda` for
procedures that are captured in the closure you want to send to the other
place, not for all of the functions they use to actually do the
computation. From my experience programming in `#lang web-server`, where
these rules apply to the implicit closure created around a web interaction,
it doesn't turn out to be an issue most of the time.

When hearing actors, then Threads could be thought of a means of
> implementing them, but I think might not be useful to do so when thinking
> about performance. Architecturally yes, maybe. That is, why I would think
> of places as a means of implementing an actor model kind of thing.
>

It depends on how you want to use your system. If you want a few,
relatively long-lived actors, places might work well. If you want many,
potentially short-lived actors, you will want to use threads, because
creating places is expensive and doesn't give a benefit beyond
`(processor-count)` places. Potentially, you could use threads running
across a pool of places, though you would then potentially need to think
about how to optimally distribute the threads among the places.

> When you say, that loci extends the idea of places to multiple machines,
> what do you mean? I thought places can already run on multiple machines.
>
Yes, distributed places can run across multiple machines.

> It would be nice however, to not have to use a different construct to
> define serializable lambdas and to be able to go to any program and simply
> use existing lambdas to send them to a process pool to make use of multiple
> cores, instead of having to refactor many things into serializable things.
>
I do see what you mean, but I think of this as protecting me from bugs.
When a programmer writes `serial-lambda`, they are saying "I've thought
about it, and it makes sense to serialize this and later call the
deserialized procedure in some other context." If you could serialize any
first-class closure you find, without cooperation from the creator of the
closure, it might not logically make sense to call it in some other context
(perhaps because it relies on mutable state), in which case you would get
nonsense results and potentially break the other module's invariant.

 -Philip

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/racket-users/CAH3z3gbwwaHGOPM69ZLi7R30iSk%2BUqToKCstAT0Y37gArUrrfg%40mail.gmail.com.

Reply via email to