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

Potential trap with concatenating Bufs/Blobs, [~] returns a Str #2124

Closed
AlexDaniel opened this issue Jun 25, 2018 · 20 comments
Closed

Potential trap with concatenating Bufs/Blobs, [~] returns a Str #2124

AlexDaniel opened this issue Jun 25, 2018 · 20 comments
Assignees
Labels

Comments

@AlexDaniel
Copy link
Member

AlexDaniel commented Jun 25, 2018

Let's say you have a bunch of Bufs or Blobs in array @chunks, and you want to concat them:

my @chunks = Blob.new(60, 61, 62), Blob.new(63, 64, 65);
my $x = [~] @chunks;
say $x; # Blob:0x<3c 3d 3e 3f 40 41>

This will work fine as long as you have something in @chunks. However, if it happens that @chunks is empty, then [~] returns an empty Str ("").

my @chunks;
my $x = [~] @chunks;
say $x.perl; # ""

Further operations with $x may fail because you don't necessarily expect a Str there. For example, doing $x.decode will not work.

The shortest way to get what you actually want (with all inputs) is Blob.new: |«@chunks, or alternatively you can call .append on a Buf in a loop.

@rafaelschipiura
Copy link
Contributor

Should Nil ~ Nil return an empty Str at all?

@JJ
Copy link
Contributor

JJ commented Jun 25, 2018

I seem to remember there was something related to that kind of operator working on empty lists... It's kind of a more general thing if I remember correctly.
Also, since when do we have the trap label?

@JJ
Copy link
Contributor

JJ commented Jun 25, 2018

I think this is basically the consequence of putting Nil or Any in a string context. ~ becomes the string contextualizer then. But... that's rightfully a trap, the problem is that I don't know how general will that be. My hunch is that any empty list will get the same treatment.

@rafaelschipiura
Copy link
Contributor

@JJ AlexDaniel created the trap label a few hours ago: #1603 (comment)

@AlexDaniel
Copy link
Member Author

It has nothing to do with Nils. It's just that calling &infix:<~>() with no args returns an empty string. You can do this kind of stuff with other ops, like * returns 1, + returns 0, min returns Inf.

@AlexDaniel
Copy link
Member Author

@JJ
Copy link
Contributor

JJ commented Jun 25, 2018

But my point is that the trap would be concatenating anything that is concatenated with ~. Come to think of it, it might be only Blob/Bufs and Strs...

@JJ
Copy link
Contributor

JJ commented Jun 26, 2018

Please also note that @chunks above is an empty Positional, not an empty Blob...

@JJ
Copy link
Contributor

JJ commented Jun 26, 2018

In fact:

my Blob $chunks; 
say $chunks.^name; 
say ([~] $chunks).^name; 
# OUTPUT: «Blob␤Use of uninitialized value of type Blob in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
Str␤  in block <unit> at /tmp/S2dkUqd2ea line 1␤»

So the traps is unrelated to Blob/Buf, as far as I can see...

@JJ JJ closed this as completed in 249c087 Jun 26, 2018
@AlexDaniel
Copy link
Member Author

No trap was added?

@AlexDaniel AlexDaniel reopened this Jun 26, 2018
@JJ
Copy link
Contributor

JJ commented Jun 26, 2018

Well, the whole thing is mentioned but not as a trap. I don't really see it as a trap, but I can add an entry there pointing to the explanation in the contexts page.

@JJ JJ closed this as completed in 4f18e4e Jun 26, 2018
@AlexDaniel
Copy link
Member Author

I don't think it's entirely right, and I don't think that the issue mentioned in this ticket is covered. To recap, the issue here is that the identity element for concatenation is an empty String, it has nothing to do with concatenating Bufs/Blobs with other types. I'll edit it later myself.

@AlexDaniel AlexDaniel reopened this Jun 26, 2018
@AlexDaniel AlexDaniel self-assigned this Jun 26, 2018
@JJ
Copy link
Contributor

JJ commented Jun 26, 2018

@AlexDaniel I think it does. The problem is that ~ concats either Bufs or Strings. Not everything can be converted to Buf, but most stuff can be converted to Str. So as long as there's something that's not Buf, the first form kicks in, trying to convert a Buf into a String.

@JJ
Copy link
Contributor

JJ commented Jun 26, 2018

I mean, in your example above, $x is already a String. Of course any Buf operation fails, it's not a Buf.

@AlexDaniel
Copy link
Member Author

The problem is that ~ concats either Bufs or Strings

Correct.

[…] So as long as there's something that's not Buf

The problem is that when there's nothing (no Bufs, no Strs), it gives its identity element "" (which isn't obviously what you expect when you're working with Bufs/Blobs).

I mean, in your example above, $x is already a String. Of course any Buf operation fails, it's not a Buf.

Correct, but I never intended it to be a Str. That's what this trap is about. I was working with array of Blobs, and I didn't think of an edge case when my array of Blobs was actually empty (so it's an array of nothing, I understand).

@JJ
Copy link
Contributor

JJ commented Jun 26, 2018

Let me see if I follow you. What you are saying is that we reduce an empty array via the concat operator. It's empty, so it could be either strings or bufs so it could opt for returning an empty string or an empty Buf. However, it opts for the former, and that's a trap. Is that it?

@JJ
Copy link
Contributor

JJ commented Jun 26, 2018

Also, this reduce operator on an empty list should return identity for the operation. But that's old, and a lot has rained since then...

@JJ
Copy link
Contributor

JJ commented Jun 27, 2018

Ping...

@JJ JJ assigned JJ and unassigned AlexDaniel Jun 27, 2018
@JJ JJ closed this as completed in 2856dd3 Jun 27, 2018
@AlexDaniel
Copy link
Member Author

Yeah, it's much better now. But there's a way to go for perfection, I'll do some finishing touches during the squashathon.

@AlexDaniel AlexDaniel reopened this Jun 27, 2018
@JJ
Copy link
Contributor

JJ commented Jul 7, 2018

Ping...

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

No branches or pull requests

3 participants