gpulost / lepl

Automatically exported from code.google.com/p/lepl
Other
0 stars 0 forks source link

lepl.String() does not match empty-string: "" #24

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
lepl.String() "filters out" empty strings. Example:

>>> import lepl
>>> lepl.__version__
'5.0.1'
>>> lepl.String().parse('""')
[]

Here's what I was expecting:

>>> lepl.String().parse('""')
['']

I'm getting around this by doing the following:

>>> (lepl.String() > (lambda args:args and args[0] or '')).parse('""')
['']

But really I think this should be the default behavior, or if there is good 
reason not to then the docs should be updated to reflect this behavior. It took 
me a while to figure out what was going wrong because this “feature” (if it 
is not in fact a bug) is very counter-intuitive.

Original issue reported on code.google.com by m...@friedenbach.org on 16 Mar 2012 at 6:06

GoogleCodeExporter commented 9 years ago
eww.  that doesn't look right.  i'll try check and fix this weekend.  sorry, 
andrew.

Original comment by acooke....@gmail.com on 16 Mar 2012 at 6:36

GoogleCodeExporter commented 9 years ago
i'm not sure this is the right fix, but i've made String() and related matchers 
more string-specific, and they now work as expected.

in general, lepl doesn't assume much about the input (it will "parse" an 
iterable of objects, if you can supply the logic), so is completely agnostic 
about output type.  this change breaks that, but only for those matchers.

an alternative would be to do something based on the type of the input data (ie 
use s_join()).  but that makes a pile of assumptions about output being the 
same as input.

and i feel i am missing something deeper about why an empty string is different 
from nothing.  what would it mean to match a string against a list of integers, 
say?  currently it cannot mean anything since that will give an error.  but 
what would be better than that?  an empty list i guess.

anyway, we'll see how this flies.  5.0.2 is available for download/install.

Original comment by acooke....@gmail.com on 17 Mar 2012 at 10:18

GoogleCodeExporter commented 9 years ago
Thanks! I updated to 5.0.2, removed my hack, ran my test suite, and everything 
looks good.

I'm not sure I understand the workings of LEPL well enough to comment, but the 
fix you applied is what I had in mind as well. It's an issue for any sequence 
type that can be empty (so I can see it showing up for Lisp s-expressions as 
well), but I don't think there's a need to generalize beyond that.

Cheers, Mark.

Original comment by m...@friedenbach.org on 17 Mar 2012 at 11:52

GoogleCodeExporter commented 9 years ago
OK, after thinking some more I understand what the "philosophical issue" is 
here (I'm writing this down really just for my own internal docs).

String() uses Add() internally, where Add() is defined as applying a "+" to 
some data.  But that's not a good way to think of reducing sequence data, 
because it leaves open what the "zero" value is.  We already have a better way 
of doing this in functional programming: to reduce a sequence of values to one, 
we use fold (or, in python terms, reduce).

And reduce takes two values: zero and operation.  Where in this case, operation 
is "+" and zero is what is missing.

So the fix was half-way there (I changed the code to use Repeat with a reduce 
operator).  But a complete fix would introduce a Reduce() matcher that takes a 
zero, and String() would allow that to be set.

Which I will do now.  In fact, Add() should perhaps be deprecated!

Original comment by acooke....@gmail.com on 18 Mar 2012 at 2:46