Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Simplify takebuf() API #19088

Merged
merged 2 commits into from
Nov 16, 2016
Merged

Simplify takebuf() API #19088

merged 2 commits into from
Nov 16, 2016

Conversation

nalimilan
Copy link
Member

@nalimilan nalimilan commented Oct 24, 2016

This implements one of the Stringapalooza tasks scheduled for 0.6 (#16107 and #16058 (comment)): takebuf_array is now simply takebuf, and takebuf_string(b) is now String(takebuf(b)).

Points to discuss:

  • I've removed the jl_takebuf_string C function, which was used for IOStream method and performed the conversion from array to string in C. I don't think it should be a performance issue, but could someone confirm that?
  • I've kept the name takebuf, but maybe another one is appropriate now? Could it be a method of a more generic function like collect or Array?
  • There's already a String(b::AbstractIOBuffer) method with a similar behavior, but it only works on seekable streams. One difference is that it doesn't call unmark, maybe there are others. Probably doesn't affect this PR, but I thought I would mention it.

Fixes #8575.

@vtjnash
Copy link
Member

vtjnash commented Oct 24, 2016

takebuffer? or buffer!?

@dhoegh
Copy link
Contributor

dhoegh commented Oct 24, 2016

What about take!? It does not seem in conflict with the current uses. The help list:

help?> take!
search: take! take takebuf_array takebuf_string StackOverflowError istaskdone stacktrace StackTraces

  take!(c::Channel)

  Removes and returns a value from a Channel. Blocks till data is available.

  take!(rr::RemoteChannel, args...)

  Fetch value(s) from a remote channel, removing the value(s) in the processs.

@ararslan
Copy link
Member

I like the idea of overloading take! for this purpose but IIRC that function was recently moved to a new Base.Iterators module, so you'd have to call it like Iterators.take!. I suppose it doesn't really matter, but to me the name Iterators seems a little odd in the context of working with buffers.

@nalimilan
Copy link
Member Author

take! sounds nice, but as @vtjnash told me today I/O functions don't end with a ! in general even when they mutate the input stream. So it would have to be take, which has a very different meaning.

@vtjnash Why do you suggest buffer! with an ending !?

@dpsanders
Copy link
Contributor

Can't it just be string(buf) where buf::IOBuffer?

@yuyichao
Copy link
Contributor

yuyichao commented Oct 24, 2016

string(buf)

No, string is roughly how you show (edit: print) the object.

@dpsanders
Copy link
Contributor

There is repr for that.

@yuyichao
Copy link
Contributor

No that's yet another more verbose representation of the object. http://docs.julialang.org/en/release-0.5/stdlib/strings/?highlight=repr

@nalimilan
Copy link
Member Author

It could be String(b), but as I said it already exists and has a slightly different behavior. I think the rationale it that a constructor doesn't look like it should mutate the input argument (by calling unmark!).

I've just re-discovered that there was an issue for this naming debate, but not with many proposals: #8575.

@dhoegh
Copy link
Contributor

dhoegh commented Oct 25, 2016

@ararslan as far as I can see only take and not take! is deprecated in https://github.com/JuliaLang/julia/pull/18839/files#diff-7904f4ddd9158030529e0ed5ee8707eeR1031.

@ararslan
Copy link
Member

@dhoegh Oh you're right—I mistakenly thought take! was the mutating form of Iterators.take, but that seems to not be the case. In that case, +1 to take!.

@kshyatt kshyatt added the strings "Strings!" label Oct 25, 2016
@stevengj
Copy link
Member

+1 for take!. This isn't an I/O function in the same sense as read or write, so I think ! seems appropriate.

@nalimilan
Copy link
Member Author

So is the general preference for take!?

Something that escapes me is why the docs say "Obtain the contents of an IOBuffer as an array, without copying". Looking at the code, it seems to me that a copy is always made, even when it could be avoided by reusing the data field. I would be more inclined to use take! if that field was indeed reused.

@vtjnash
Copy link
Member

vtjnash commented Nov 1, 2016

If it is seekable, writable, and backed by an Array{UInt8}, then it is no-copy. I agree that the seekable condition seems somewhat extraneous.

@nalimilan
Copy link
Member Author

Thanks, I hadn't noticed that the newly allocated array was of length 0 in the best case.

I've updated the PR to use take!. I've also renamed jl_takebuf_array and ios_takebuf to jl_take_buffer and ios_take_buffer, which seems more consistent.

@nalimilan
Copy link
Member Author

Should we merge now?

@nalimilan
Copy link
Member Author

I'll merge tomorrow barring further suggestions or objections.

@nalimilan nalimilan force-pushed the nl/takebuf branch 2 times, most recently from d263b7f to f1749ea Compare November 15, 2016 21:01
takebuf_string(b) is now simply String(take!(b)). Also remove
jl_takebuf_string, which did the same conversion from array to string in C,
and rename {jl,ios}_takebuf_array() to {jl,ios}_take_buffer().
@nalimilan nalimilan merged commit 550f5d3 into master Nov 16, 2016
@nalimilan nalimilan deleted the nl/takebuf branch November 16, 2016 11:28
@nalimilan
Copy link
Member Author

Phew! It was hard to get into a mergeable state, deprecated.jl is such a busy place these days...

@StefanKarpinski StefanKarpinski mentioned this pull request Nov 16, 2016
32 tasks
Sacha0 added a commit to Sacha0/julia that referenced this pull request May 19, 2017
tkelman pushed a commit that referenced this pull request Jun 3, 2017
@s2maki
Copy link
Contributor

s2maki commented Oct 4, 2017

This deprecation warning is sometimes wrong (and results in an error in those cases). When takebuf_string(v) is passed a UInt8 vector, it reports that String(take!(v)) is the replacement, but take!(v) doesn't accept a UInt8 vector. It should just be String(v) in that case.

@yuyichao
Copy link
Contributor

yuyichao commented Oct 4, 2017

In which version did passing a Vector{UInt8} to takebuf_string actually work?

@nalimilan
Copy link
Member Author

At least the Vector{UInt8} method (if it ever existed) wasn't removed in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
strings "Strings!"
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants