Re: Trouble replacing deprecated map< function

2016-02-16 Thread James Reeves
Thanks for the reply. Now that you point it out, I see what you mean about
channels being queues, rather than generic communication streams.

Perhaps rather than return a bidirectional channel, Chord should instead
return two channels, one for input and one for output. Or perhaps it should
take them as an argument, allowing for transducers to be used directly.

- James

On 15 February 2016 at 20:24, Francis Avila  wrote:

> I think the difficulty here is that Chord has a bidirectional channel,
> where putting and taking operate on different "streams" inside the channel.
> (Internally, Chord is actually using a different channel for reads and
> writes. It constructs the "joined" channel using chord.channels/bidi-ch)
>
> I don't think this was envisioned as a proper way to use channels. I think
> they were envisioned as a queue, and queues hold values, not communication
> streams. When you put onto a channel, it contains what you put until you
> take it off. (Note that channels with attached transducers must be buffered
> because it needs a place to hold the result of the reduction step.) A Chord
> channel isn't like this: when you put on it, the value is gone, and
> different values from some other place appear when you take from it.  The
> more usual solution is to use a pair of channels.
>
> map<, map>, etc happened to work because they always put/take a value
> unchanged in the opposite direction onto the transformed channel.
>
> I suspect the core developers were only using map>, map< et al in
> pipelines (where transducers are fine) and not realizing people were using
> them in a way that relied on the other direction being pass-through.
>
> You will always need either a pair of channels to undo the unification
> done by Chord, or you will need to implement a channel (using reify and the
> WritePort and ReadPort protocols) where take and put mean different things
> and you can attach a transducer independently to each. Something like that
> would probably not make it in to core because it encourages the use of
> Chord-style "multistream" channels.
>
> You could try something like this:
>
> (defn eduction> [xform ch]
>   (let [in-stream (chan 1 xform)
> out-stream (chan)]
> (pipe in-stream ch)
> (pipe ch out-stream)
> (chord.channels/bidi-ch in-stream out-stream)))
>
> Of course it would be more efficient to use reify and implement the
> channel interfaces directly, like map> does, but with transducer semantics
> for f (including the finalize arity and when the f is called).
>
>
> On Friday, February 12, 2016 at 1:41:20 PM UTC-6, James Reeves wrote:
>>
>> I currently have some core.async code that looks like:
>>
>> (map< :foo ch)
>>
>> However, map< and map> are now deprecated, with the suggestion to use
>> transducers instead. Unfortunately it's not obvious how to go about that.
>>
>> At first I thought that I could use a pipe and a new channel:
>>
>> (pipe ch (chan 1 (map :foo)))
>>
>> But there's no distinction between channel input and output here. This
>> matters because I'm using a bidirectional channel from Chord
>> .
>>
>> I'm thinking that it would be nice to have some functions like:
>>
>> (eduction< ch xform)
>> (eduction> ch xform)
>> (eduction ch xform)
>>
>> So I could write something like:
>>
>> (eduction< ch (map :foo))
>>
>> Have I missed anything? Is there some equivalent to this functionality
>> already in core.async that I haven't noticed?
>>
>> - James
>>
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Trouble replacing deprecated map< function

2016-02-15 Thread Francis Avila
I think the difficulty here is that Chord has a bidirectional channel, 
where putting and taking operate on different "streams" inside the channel. 
(Internally, Chord is actually using a different channel for reads and 
writes. It constructs the "joined" channel using chord.channels/bidi-ch)

I don't think this was envisioned as a proper way to use channels. I think 
they were envisioned as a queue, and queues hold values, not communication 
streams. When you put onto a channel, it contains what you put until you 
take it off. (Note that channels with attached transducers must be buffered 
because it needs a place to hold the result of the reduction step.) A Chord 
channel isn't like this: when you put on it, the value is gone, and 
different values from some other place appear when you take from it.  The 
more usual solution is to use a pair of channels.

map<, map>, etc happened to work because they always put/take a value 
unchanged in the opposite direction onto the transformed channel.

I suspect the core developers were only using map>, map< et al in pipelines 
(where transducers are fine) and not realizing people were using them in a 
way that relied on the other direction being pass-through.

You will always need either a pair of channels to undo the unification done 
by Chord, or you will need to implement a channel (using reify and the 
WritePort and ReadPort protocols) where take and put mean different things 
and you can attach a transducer independently to each. Something like that 
would probably not make it in to core because it encourages the use of 
Chord-style "multistream" channels.

You could try something like this:

(defn eduction> [xform ch]
  (let [in-stream (chan 1 xform)
out-stream (chan)]
(pipe in-stream ch)
(pipe ch out-stream)
(chord.channels/bidi-ch in-stream out-stream)))

Of course it would be more efficient to use reify and implement the channel 
interfaces directly, like map> does, but with transducer semantics for f 
(including the finalize arity and when the f is called).


On Friday, February 12, 2016 at 1:41:20 PM UTC-6, James Reeves wrote:
>
> I currently have some core.async code that looks like:
>
> (map< :foo ch)
>
> However, map< and map> are now deprecated, with the suggestion to use 
> transducers instead. Unfortunately it's not obvious how to go about that.
>
> At first I thought that I could use a pipe and a new channel:
>
> (pipe ch (chan 1 (map :foo)))
>
> But there's no distinction between channel input and output here. This 
> matters because I'm using a bidirectional channel from Chord 
> .
>
> I'm thinking that it would be nice to have some functions like:
>
> (eduction< ch xform)
> (eduction> ch xform)
> (eduction ch xform)
>
> So I could write something like:
>
> (eduction< ch (map :foo))
>
> Have I missed anything? Is there some equivalent to this functionality 
> already in core.async that I haven't noticed?
>
> - James
>

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Trouble replacing deprecated map< function

2016-02-12 Thread James Reeves
I currently have some core.async code that looks like:

(map< :foo ch)

However, map< and map> are now deprecated, with the suggestion to use
transducers instead. Unfortunately it's not obvious how to go about that.

At first I thought that I could use a pipe and a new channel:

(pipe ch (chan 1 (map :foo)))

But there's no distinction between channel input and output here. This
matters because I'm using a bidirectional channel from Chord
.

I'm thinking that it would be nice to have some functions like:

(eduction< ch xform)
(eduction> ch xform)
(eduction ch xform)

So I could write something like:

(eduction< ch (map :foo))

Have I missed anything? Is there some equivalent to this functionality
already in core.async that I haven't noticed?

- James

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.