lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Tue, Jun 16, 2015 at 8:57 AM, Nagaev Boris <bnagaev@gmail.com> wrote:
> On Tue, Jun 16, 2015 at 3:46 PM, Coda Highland <chighland@gmail.com> wrote:
>> On Tue, Jun 16, 2015 at 8:37 AM, Rodrigo Azevedo <rodrigoams@gmail.com> wrote:
>>>
>>>> >> > command = input:urldecode():lower():trim():split(' ')
>>>> >
>>>> >
>>>> > You can do this:
>>>> > command = filter.urldecode.lower.trim.split(' ')(input)
>>>> >
>>>> > One of the nice things about this is that the filter chain can be cached
>>>> > easily:
>>>> >
>>>> > f = filter.urldecode.lower.trim.split(' ')
>>>> > command = f(input)
>>>> > command2 = f(input2)
>>>
>>>
>>> I'm sorry, I would want to know if the patch I've proposed (the one in the
>>> subject) can also solve this problem:
>>>
>>> f = function(str) -- do something with str
>>>         return str:upper:lower .. "one"
>>> end
>>>
>>> str = "Testing This "
>>> str = f(str)
>>>
>>> f2 = function(str) -- example given
>>>        return str:urldecode:lower:trim:split(' ')
>>> end
>>>
>>> command2 = f2(input2)
>>>
>>> that also solves the problem?
>>>
>>> because with this you can easily understand that ":" are function calls, and
>>> not confuse with "." syntactic sugar.
>>>
>>
>> It should be noted that these chained filters are NOT function calls!
>> They are not in fact operating on the value of their parameter.
>> They're not invoked until you pass a parameter to the end result of
>> the chain.
>>
>> Every filter is an object that possesses properties that are the
>> result of certain transformations being performed upon the filter
>> itself. These could be precomputed at time of construction except for
>> the recursion, so they're constructed lazily, but they're not function
>> calls in any practical high-level sense.
>>
>> It should also be noted that Boris Nagaev's implementation that
>> requires the use of : for split can actually be fixed to not need it
>> with a little bit of cleverness. (Specifically, it just needs to
>> return a closure with the current filter as an upvalue, so the current
>> filter doesn't have to be passed in as a parameter.)
>>
>> /s/ Adam
>
> I think the use of . can introduce ambiguity.
> Consider the following code:
>
> y = filter.upper.sub(x)
>
> Should y be a function-like object (1) or the result of applying
> 'filter.upper.sub' to x (2) ?
>
> 1) in this case y(z) means z:upper():sub(x)
> 2) in this case y is equal to x:upper():sub()
>

Maybe it's because I'm a C++ programmer and applying filters to
streams is a standard operation for me, but I don't see an ambiguity.

Yes, it would be ambiguous if you didn't know that the sub filter
required a parameter. But any given filter expression only has a
single unambiguous interpretation, and knowing what the filters are
makes that interpretation likewise unambiguous to the reader.

If your filter names are so opaque that you can't tell by looking at
it, that's a problem with your choice of API, not with the syntax.

That said, an alternate resolution to the ambiguity is to not use
__call to invoke the filter -- instead, use :apply(x), and everything
becomes clear.

/s/ Adam