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

Introduce OneToManyValueExpression and OneToOneValueExpression #247

Closed
wants to merge 3 commits into from

Conversation

rdvdijk
Copy link
Contributor

@rdvdijk rdvdijk commented Aug 30, 2018

This removes duplicated code in these ValueExpressions: Last, First, Count and FoldCat. This is achieved by introducing a new abstract base class OneToOneValueExpression. The four classes look pretty clean now!

The old UnaryValueExpression has been renamed to OneToManyValueExpression.

The names of these classes are still open to debate, not too sure if these are the best names.

  • one-to-one meaning: one operand leads to a one (optional) value
  • one-to-many meaning: one operand leads to many (optional) values

I found that the Bytes class still contains this exact code, but is not a match for either base class, since we "expand" each result of the operand into multiple values.

@rdvdijk rdvdijk requested review from mvanaken, jvdb and ccreeten August 30, 2018 17:59
return ImmutableList.create(eval(operand.eval(parseState, encoding), parseState, encoding));
}

public abstract Optional<Value> eval(final ImmutableList<Optional<Value>> list, final ParseState parseState, final Encoding encoding);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review: I think we do not need to pass ParseState into this method, we do not use it anywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jvdb @mvanaken I think that in both this new class as in OneToManyValueExpression, there is no need to have the ParseState argument. We never access it anywhere. Even the Encoding is rarely accessed; I found only a single use of it in the code I refactored here.

@@ -33,13 +33,13 @@
import java.io.IOException;
import java.util.Optional;

import io.parsingdata.metal.expression.value.OneToManyValueExpression;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review: Fix import order.

import static io.parsingdata.metal.data.Slice.createFromSource;
import static java.math.BigInteger.ZERO;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Self-review: fix import order?

@codecov
Copy link

codecov bot commented Aug 30, 2018

Codecov Report

Merging #247 into current-iteration-levels will decrease coverage by 0.21%.
The diff coverage is 100%.

Impacted file tree graph

@@                      Coverage Diff                       @@
##             current-iteration-levels     #247      +/-   ##
==============================================================
- Coverage                         100%   99.78%   -0.22%     
+ Complexity                       1066     1018      -48     
==============================================================
  Files                              92       93       +1     
  Lines                            1430     1387      -43     
  Branches                          144      138       -6     
==============================================================
- Hits                             1430     1384      -46     
- Misses                              0        1       +1     
- Partials                            0        2       +2
Impacted Files Coverage Δ Complexity Δ
...gdata/metal/expression/value/reference/Offset.java 100% <ø> (ø) 2 <0> (ø) ⬇️
.../metal/expression/value/BinaryValueExpression.java 100% <ø> (ø) 18 <0> (ø) ⬇️
...ingdata/metal/expression/value/arithmetic/Neg.java 100% <ø> (ø) 2 <0> (ø) ⬇️
...arsingdata/metal/expression/value/bitwise/Not.java 100% <ø> (ø) 2 <0> (ø) ⬇️
...singdata/metal/expression/value/reference/Len.java 100% <ø> (ø) 3 <0> (ø) ⬇️
...ingdata/metal/expression/value/reference/Last.java 100% <100%> (ø) 3 <3> (-5) ⬇️
...ngdata/metal/expression/value/reference/Count.java 100% <100%> (ø) 3 <2> (-5) ⬇️
...etal/expression/value/OneToOneValueExpression.java 100% <100%> (ø) 7 <7> (?)
...ain/java/io/parsingdata/metal/format/Callback.java 100% <100%> (ø) 2 <1> (ø) ⬇️
.../src/main/java/io/parsingdata/metal/Shorthand.java 100% <100%> (ø) 132 <2> (ø) ⬇️
... and 8 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 16009e4...a45a815. Read the comment docs.

public static BinaryValueExpression and(final ValueExpression left, final ValueExpression right) { return new io.parsingdata.metal.expression.value.bitwise.And(left, right); }
public static BinaryValueExpression or(final ValueExpression left, final ValueExpression right) { return new io.parsingdata.metal.expression.value.bitwise.Or(left, right); }
public static UnaryValueExpression not(final ValueExpression operand) { return new io.parsingdata.metal.expression.value.bitwise.Not(operand); }
public static OneToManyValueExpression not(final ValueExpression operand) { return new io.parsingdata.metal.expression.value.bitwise.Not(operand); }
Copy link
Collaborator

@ccreeten ccreeten Aug 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referring to your naming debate, reading this does make it seem a bit funny in that it now reads like negate/not have a different cardinality between input and output (consider an identity function, it would be even more weird in my opinion), although both are simply (unbounded) ValueExpressions. Before, Unary meant a single operand, with implicitly a single output value (as always). Now I think it is a mix of two concepts.

But thinking of a good name is hard. UnaryManyToMany to me feels like I would know better what it all is about. But there might be better names to be found. Or I am just thinking about it wrong. 🆘

EDIT: as another example, last being a OneToOne just does not quite feel right to me (many to one?).

Copy link
Contributor

@jvdb jvdb Aug 30, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that because of our list semantics, the notion of what is a single operand is a bit complex... We should probably approach this in a more fundamental way: think about the possible types, then the ones that actually occur, then which ones we should implement/support and after all that, how to name them.

Copy link
Collaborator

@ccreeten ccreeten Aug 31, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good :) It is also interesting for expressions with more than one operand, where e.g. mul can have two lists, but exp can have a list as the first operand, but requires a single element as the second.

It would probably be cool to encode that information in the operand types, i.e. BinaryExpr&ToManyExpr exp(ToManyExpr value, ToOneExpr second). It can then allow us to statically check for correctness as well, as per #70 (although there are few cases where it is necessary?). Downside is that we can not pass a list expression where we know that it will only ever contain a single value, so in the exp case, it would need a wrap with a last for example.

And there are probably other things to consider.

@ccreeten
Copy link
Collaborator

The cleanup bit is nice I think!

@jvdb
Copy link
Contributor

jvdb commented Nov 7, 2018

Closing this PR for now, we'll keep it as reference for issue #246 and others.

@jvdb jvdb closed this Nov 7, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

3 participants