librelist archives

« back to archive

Proposals for ABSTRACT_STRING

Proposals for ABSTRACT_STRING

From:
Paolo Redaelli
Date:
2011-09-13 @ 22:44
I would like to  discuss the addition of a couple of string operators.
A substring operator, like
    infix "^" (a_range: INTEGER_RANGE): ABSTRACT_STRING is
        do
            Result := substring
            (a_range.lower.clamp(lower,upper),
            a_range.upper.clamp(lower,upper))
        end

To allow code like assert("1234567890"^4|..|6 ~ "456")
And a "fill operator" inspired by  Python's % operator and QString::arg :

    infix "#" (a_value: ABSTRACT_STRING): FILLED_STRING is
        -- Replace the placeholder "@(n)" with the lower n with the
content of `a_value'
        deferred
        ensure definition: has_substring(a_value)
        end

So that
("Hey @(2) I got @(1) with @(3)!" # "an apple" # "teacher" # "a
worm").is_equal("Hey teacher I got an apple with a worm!")

I know it may not quite efficient as we used to be but it looks so
comfortable!
I guess my afternoon exposition to Python has something related.
It may be made a little more efficient if we make it return an eventual
FILLED_STRING (a string where placeholders have been partially or fully
filled up) instead of "like Current" or ABSTRACT_STRING, so that
FILLED_STRING knows where are the placeholders or which is the next to seek.

infix "^" is so simple: I already tested it works the way I wrote; infix
"#" is not a one-liner but we may draw it from MESSAGE_FORMATTER
 
 
 --
 Caselle da 1GB, trasmetti allegati fino a 3GB e in piu' IMAP, POP3 e SMTP
autenticato? GRATIS solo con Email.it http://www.email.it/f
 
 Sponsor:
 Speciale MotoGp 4-11 settembre, soggioni 7 notti e paghi 6 all'hotel 
Mediterraneo Riccione, mezza pensione in doppia euro 86 per persona al 
giorno
 Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=11805&d=14-9

Re: [libertyeiffel] Proposals for ABSTRACT_STRING

From:
Cyril Adrian
Date:
2011-09-14 @ 08:54
*1. The infix "^" operator.*

Please, don't use *clamp* in the library. Use preconditions instead of
forcing useless computations.

BTW I guess you'd need parentheses to force the good evaluation order of
"1234567890"^4|..|6 ~ "456"

  => ("1234567890"^(4|..|6)) ~ "456"

although I'd rather write good English names:

  => "1234567890".substring(4, 6).same_as("456")

Remember, Eiffel is all about clarity. The *!!* operator was removed because
it was not clear enough. Let's not use cryptic C-like symbols all over the
code. (I guess I should apply it to the *|..|* operator too…)


*2. The infix "#" operator.*

I agree with the principle. I toyed with something similar because I need it
for the logging framework (lazy evaluation). *ROPE* is a good start.

How do you guarantee that there is the good number of arguments? Why not
using simply an *INDEXABLE[STRING]* as argument instead of having to write
it multiple times? (OTOH, why not) :-)

Also, I'd name it *infix "@"* — just as Python uses the % sign for both the
format string and the operator.

Ah, and with a good English name too, something like *fill*.

I don't agree with the signature. It should return an *ABSTRACT_STRING*, the
client does not have to care.

With those changes in mind, the example would become

  => ("Hey @(2) I got @(1) with @(3)!" @ << "an apple", "teacher", "a worm"
>>).is_equal("Hey teacher I got an apple with a worm!")

 or

  => ("Hey @(2) I got @(1) with @(3)!".fill(<< "an apple", "teacher", "a
worm" >>)).is_equal("Hey teacher I got an apple with a worm!")

Another thought. As I said, I'm playing with the same ideas. I need to make
the evaluation as lazy as possible. One bottleneck is to give the logging
framework only strings (because the `out' feature can take time for nothing
if the trace is not logged). I'm trying to use agents :-)

Cheers,

*Cyril ADRIAN** (from the office)*

http://www.cadrian.net/cyril
My profiles: [image: Facebook] <http://www.facebook.com/cyril.adrian> [image:
LinkedIn] <http://fr.linkedin.com/in/cadrian> [image:
Twitter]<http://www.twitter.com/cadbart> [image:
Google 
Calendar]<https://www.google.com/calendar/embed?src=1t93vvvrdc26ee0f83p0cunj60%40group.calendar.google.com&ctz=Europe/Paris>
[image:
Google Plus] <http://gplus.to/cadrian>
Contact me: [image: Google Talk] cyril.adrian
Signature powered by

<http://r1.wisestamp.com/r/landing?u=5e34fc2118d9c29f&v=2.7.4&t=1315988734503&promo=5&dest=http%3A%2F%2Fwww.wisestamp.com%2Femail-install%3Futm_source%3Dextension%26utm_medium%3Demail%26utm_campaign%3Dpromo_5>

WiseStamp<http://r1.wisestamp.com/r/landing?u=5e34fc2118d9c29f&v=2.7.4&t=1315988734503&promo=5&dest=http%3A%2F%2Fwww.wisestamp.com%2Femail-install%3Futm_source%3Dextension%26utm_medium%3Demail%26utm_campaign%3Dpromo_5>



2011/9/14 Paolo Redaelli <paolo.redaelli@email.it>

> I would like to  discuss the addition of a couple of string operators.
> A substring operator, like
>    infix "^" (a_range: INTEGER_RANGE): ABSTRACT_STRING is
>        do
>            Result := substring
>            (a_range.lower.clamp(lower,upper),
>            a_range.upper.clamp(lower,upper))
>        end
>
> To allow code like assert("1234567890"^4|..|6 ~ "456")
> And a "fill operator" inspired by  Python's % operator and QString::arg :
>
>    infix "#" (a_value: ABSTRACT_STRING): FILLED_STRING is
>        -- Replace the placeholder "@(n)" with the lower n with the
> content of `a_value'
>        deferred
>        ensure definition: has_substring(a_value)
>        end
>
> So that
> ("Hey @(2) I got @(1) with @(3)!" # "an apple" # "teacher" # "a
> worm").is_equal("Hey teacher I got an apple with a worm!")
>
> I know it may not quite efficient as we used to be but it looks so
> comfortable!
> I guess my afternoon exposition to Python has something related.
> It may be made a little more efficient if we make it return an eventual
> FILLED_STRING (a string where placeholders have been partially or fully
> filled up) instead of "like Current" or ABSTRACT_STRING, so that
> FILLED_STRING knows where are the placeholders or which is the next to
> seek.
>
> infix "^" is so simple: I already tested it works the way I wrote; infix
> "#" is not a one-liner but we may draw it from MESSAGE_FORMATTER
>
>
>  --
>  Caselle da 1GB, trasmetti allegati fino a 3GB e in piu' IMAP, POP3 e SMTP
> autenticato? GRATIS solo con Email.it http://www.email.it/f
>
>  Sponsor:
>  Speciale MotoGp 4-11 settembre, soggioni 7 notti e paghi 6 all'hotel
> Mediterraneo Riccione, mezza pensione in doppia euro 86 per persona al
> giorno
>  Clicca qui: http://adv.email.it/cgi-bin/foclick.cgi?mid=11805&d=14-9
>

Re: [libertyeiffel] Proposals for ABSTRACT_STRING

From:
Paolo Redaelli
Date:
2011-09-14 @ 10:00
Il 14/09/2011 10:54, Cyril ADRIAN ha scritto:
> *1. The infix "^" operator.*
>
> Please, don't use *clamp* in the library. Use preconditions instead of 
> forcing useless computations.
Good point.
"out-of-bound indexes are not an error, they will be clamped to correct 
one" is a clear pythonism.


> BTW I guess you'd need parentheses to force the good evaluation order 
> of "1234567890"^4|..|6 ~ "456"
>
>   => ("1234567890"^(4|..|6)) ~ "456"
Some parenthesis are actually required, but
("1234567890"^4|..|6) ~ "456"
magically suffices.

> although I'd rather write good English names:
>
>   => "1234567890".substring(4, 6).same_as("456")
>
> Remember, Eiffel is all about clarity. The *!!* operator was removed 
> because it was not clear enough. Let's not use cryptic C-like symbols 
> all over the code. (I guess I should apply it to the *|..|* operator too…)
I agree with the need of clarity. But I think your choice of *|..|* is 
really good because 4|..|6 is IMHO visually as readable as 4.range_to(6).
Oh, now that we are writing about ranges it may be useful to have them 
also on floats, may like an expanded class. Obviously it cannot be a 
TRAVERSABLE but something can be factored out, ending up with something 
like:

deferred class RANGE[A_COMPARABLE->COMPARABLE]
feature
     lower,upper: A_COMPARABLE
     make (a_lower, an_upper: A_COMPARABLE) require a_lower<an_upper is 
lower:=a_lower; upper:= an_upper end
end

expanded class REAL_RANGE
insert RANGE[REAL_128]
end

class INTEGER_RANGE
inherit
     RANGE[INTEGER_32]
     TRAVERSABLE[INTEGER_32] -- the rest of the class is mostly unchanged
end

My opinion is that ranges and its creation operator |..| is a good 
addition, being quite clear. We may also alias infix "|..|" as range_to.

I require a little more time to explain my rationale behind infix "#" 
... More on this soon....

Re: [libertyeiffel] Proposals for ABSTRACT_STRING

From:
Cyril Adrian
Date:
2011-09-14 @ 12:21
2011/9/14 Paolo Redaelli <paolo.redaelli@gmail.com>

> Some parenthesis are actually required, but
> ("1234567890"^4|..|6) ~ "456"
> magically suffices.
>

Ah! yes of course. the ^ operator has a specific priority.

 I agree with the need of clarity. But I think your choice of *|..|* is
> really good because 4|..|6 is IMHO visually as readable as 4.range_to(6).
>

It's not bad, to be sure. The idea is not mine (although I admit not to
remember whence I borrowed it) But an English word can also serve as
auto-documentation ;-)


> Oh, now that we are writing about ranges it may be useful to have them also
> on floats, may like an expanded class. Obviously it cannot be a TRAVERSABLE
> but something can be factored out, ending up with something like:
>

What's the use of a range if you cannot iterate on it? Do you have an actual
use for float ranges?

I require a little more time to explain my rationale behind infix "#" ...
> More on this soon....
>

no problem :-)

BTW, I wrote a new LAZY_STRING this morning along with the `lazy_out'
feature in ANY (aliased as prefix "&"). I pushed it but it is not tested at
all (no time…)
Can you have a look at it? Do you have a better proposal for the prefix
operator? (I'm not satisfied)

Cheers,


*Cyril ADRIAN** (from the office)*

http://www.cadrian.net/cyril
My profiles: [image: Facebook] <http://www.facebook.com/cyril.adrian> [image:
LinkedIn] <http://fr.linkedin.com/in/cadrian> [image:
Twitter]<http://www.twitter.com/cadbart> [image:
Google 
Calendar]<https://www.google.com/calendar/embed?src=1t93vvvrdc26ee0f83p0cunj60%40group.calendar.google.com&ctz=Europe/Paris>
[image:
Google Plus] <http://gplus.to/cadrian>
Contact me: [image: Google Talk] cyril.adrian
 [image: Twitter] <http://twitter.com/cadbart> Latest tweet: [Liberty]
http://t.co/HVba0IX Cyril Adrian - useful option.
Follow @cadbart <http://twitter.com/cadbart>

<http://twitter.com/?status=@cadbart%20&in_reply_to_status_id=106427146326654980&in_reply_to=cadbart>

Reply<http://twitter.com/?status=@cadbart%20&in_reply_to_status_id=106427146326654980&in_reply_to=cadbart>

<http://twitter.com/?status=RT%20%40cadbart%3A%20%5BLiberty%5D%20http%3A%2F%2Ft.co%2FHVba0IX%20Cyril%20Adrian%20-%20useful%20option.>

Retweet<http://twitter.com/?status=RT%20%40cadbart%3A%20%5BLiberty%5D%20http%3A%2F%2Ft.co%2FHVba0IX%20Cyril%20Adrian%20-%20useful%20option.>
   20:06 Aug-24 <http://twitter.com/cadbart/statuses/106427146326654976>
  Get this email app!

<http://www.wisestamp.com/apps/twitter?utm_source=extension&utm_medium=email&utm_term=twitter&utm_campaign=apps>

Signature powered by

<http://r1.wisestamp.com/r/landing?u=5e34fc2118d9c29f&v=2.7.4&t=1316002542261&promo=5&dest=http%3A%2F%2Fwww.wisestamp.com%2Femail-install%3Futm_source%3Dextension%26utm_medium%3Demail%26utm_campaign%3Dpromo_5>

WiseStamp<http://r1.wisestamp.com/r/landing?u=5e34fc2118d9c29f&v=2.7.4&t=1316002542261&promo=5&dest=http%3A%2F%2Fwww.wisestamp.com%2Femail-install%3Futm_source%3Dextension%26utm_medium%3Demail%26utm_campaign%3Dpromo_5>

Re: [libertyeiffel] Proposals for ABSTRACT_STRING

From:
Paolo Redaelli
Date:
2011-09-14 @ 14:16
Il 14/09/2011 14:21, Cyril ADRIAN ha scritto:
> I agree with the need of clarity. But I think your choice of *|..|* is 
> really good because 4|..|6 is IMHO visually as readable as 4.range_to(6).
>
> It's not bad, to be sure. The idea is not mine (although I admit not 
> to remember whence I borrowed it) But an English word can also serve 
> as auto-documentation ;-)
Nothing prevents us to have both of them, with infix "|..|" implemented 
in terms of range_to (or aliased as), like many other features like 
INTEGER's «infix "|"» and «bit_or»
>
>     Oh, now that we are writing about ranges it may be useful to have
>     them also on floats, may like an expanded class. Obviously it
>     cannot be a TRAVERSABLE but something can be factored out, ending
>     up with something like:
>
>
> What's the use of a range if you cannot iterate on it? Do you have an 
> actual use for float ranges?
Engineering, statistics? x := 10.2±0.1; y := x+2; z := x*y
C++ and Java cannot have this; we can, allowing infix "±", i.e. 
switching from the format of source code from ASCII to UTF-8

And oh, BTW we still do not have COMPLEX, which will also require
- re(a_real: REAL): COMPLEX,
- im(a_value: REAL): COMPLEX,
- polar(an_x,a_rho: REAL): COMPLEX
- cartesian(a_re, an_im: REAL): COMPLEX)
Which is quite funny since one of the selling point of Meyer's OOSC when 
rejecting signature-based C++ like constructor in favor of Eiffel's 
creation clauses is precisely the polar/cartesian example....
>
>     I require a little more time to explain my rationale behind infix
>     "#" ... More on this soon....
>
>
> no problem :-)
>
> BTW, I wrote a new LAZY_STRING this morning along with the `lazy_out' 
> feature in ANY (aliased as prefix "&"). I pushed it but it is not 
> tested at all (no time…)
> Can you have a look at it? Do you have a better proposal for the 
> prefix operator? (I'm not satisfied)
Perhaps having arg(an_index: INTEGER; a_value: ABSTRACT_STRING): 
ABSTRACT_STRING where the Result is actually a "linked-string" with some 
LAZY_STRINGs instead of @(x) ... I'll try to work it out this evening....

Re: [libertyeiffel] Proposals for ABSTRACT_STRING

From:
Paolo Redaelli
Date:
2011-09-14 @ 14:22
A little preamble: this mail is quite confused; I have to work this 
concept out a little more...

Il 14/09/2011 10:54, Cyril ADRIAN ha scritto:
> *2. The infix "#" operator.*
>
> I agree with the principle. I toyed with something similar because I 
> need it for the logging framework (lazy evaluation). *ROPE* is a good 
> start.
I have to tweak ROPE a little since AFAIR it causes current compiler to 
crash when compiling tests.
>
> How do you guarantee that there is the good number of arguments? 
I wouldn't, as Python's % and QString::arg don't do; or better a 
precondition may be computed but would be far more costly than the infix 
"#" query itself. Thought it is not wrong to have costly preconditions I 
would switch from a single call requiring to allocate a collection to 
multiple queries returning a partially computed answer.

Hey, but Python and C++ do not have design-by-contract! :)
> Why not using simply an *INDEXABLE[STRING]* as argument instead of 
> having to write it multiple times? (OTOH, why not) :-)
>
> Also, I'd name it *infix "@"* — just as Python uses the % sign for 
> both the format string and the operator.
"traditionally" infix "@" is used to access elements of strings; 
changing its semantic would rather break a lot of the small Eiffel 
code-base.
Actually position arguments like @(x) are far easier to parse than %n 
beside solving several ambiguities. See how simple is MESSAGE_FORMATTER. 
It solve this:
century := 19.to_string
assert("@(1)00".arg(century).is_equal("1900"))

>
> Ah, and with a good English name too, something like *fill*.
>
> I don't agree with the signature. It should return an 
> *ABSTRACT_STRING*, the client does not have to care.
Right, showing the actual type does not matter.
>
> With those changes in mind, the example would become
>
>   => ("Hey @(2) I got @(1) with @(3)!" @ << "an apple", "teacher", "a 
> worm" >>).is_equal("Hey teacher I got an apple with a worm!")
>
>  or
>
>   => ("Hey @(2) I got @(1) with @(3)!".fill(<< "an apple", "teacher", 
> "a worm" >>)).is_equal("Hey teacher I got an apple with a worm!")
This way you allocate an array every time you invoke fill that is not 
required by multiple calls to arg.

An eventual fill implementation that hides the allocation into itself 
may be in *ABSTRACT_STRING*:*
*arg (a_value: STRING): ABSTRACT_STRING is
     -- A copy of Current where the positional argument with the lowest 
number is replaced with `a_value'
     local fillable_string: FILLABLE_STRING
do
     find_the_highest_n
     create fillable_string.with_placeholders (n) -- will have 1+2*n 
elements
     -- where fillable string is a string implemented as a linked list 
of string pieces and an array of placeholders
     split Current, adding it to linked_string, so that it looks like a 
collection of strings
     "Hey ", placeholders@2," I got ",placeholders@1," with 
",placeholders@3,"!"
     placeholders.set(1,a_value)
     Result := fillable_string
  end

Further calls of arg will be made to a FILLABLE_STRING where it can 
implemented like:
arg (an_x: ABSTRACT_STRING): ABSTRACT_STRING is
     do
         current_index := current_index+1
         placeholders.set(current_index, an_x)
    end

This is something resembling a rope but still does not allow lazy 
evaluation, beside using two collections.
This approach couples LAZY_STRING like bread and butter...

Re: [libertyeiffel] Proposals for ABSTRACT_STRING

From:
Cyril Adrian
Date:
2011-09-14 @ 14:38
2011/9/14 Paolo Redaelli <paolo.redaelli@gmail.com>

> **
> I have to tweak ROPE a little since AFAIR it causes current compiler to
> crash when compiling tests.
>

I'm also working on it :-)

 How do you guarantee that there is the good number of arguments?
>
> I wouldn't, as Python's % and QString::arg don't do; or better a
> precondition may be computed but would be far more costly than the infix "#"
> query itself. Thought it is not wrong to have costly preconditions I would
> switch from a single call requiring to allocate a collection to multiple
> queries returning a partially computed answer.
>
> Hey, but Python and C++ do not have design-by-contract! :)
>

indeed :-)


>  Why not using simply an *INDEXABLE[STRING]* as argument instead of having
> to write it multiple times? (OTOH, why not) :-)
>
> Also, I'd name it *infix "@"* — just as Python uses the % sign for both
> the format string and the operator.
>
> "traditionally" infix "@" is used to access elements of strings; changing
> its semantic would rather break a lot of the small Eiffel code-base.
>

oops! your are right… I forgot it since I exclusively use `item' these days.

The other solution is to do exacly the opposite: keep infix "#" but replace
@ by # as a marker in the format string.


Actually position arguments like @(x) are far easier to parse than %n beside
> solving several ambiguities. See how simple is MESSAGE_FORMATTER. It solve
> this:
> century := 19.to_string
> assert("@(1)00".arg(century).is_equal("1900"))
>

No problem with the parentheses, although something more like the widespread
printf format (albeit using something other that %) would have been good
too.

 This way you allocate an array every time you invoke fill that is not
> required by multiple calls to arg.
>

That's true, and quite a good argument, too.


>  This is something resembling a rope but still does not allow lazy
> evaluation, beside using two collections.
> This approach couples LAZY_STRING like bread and butter...
>

:-)

Cheers,

*Cyril ADRIAN** (from the office)*

http://www.cadrian.net/cyril
My profiles: [image: Facebook] <http://www.facebook.com/cyril.adrian> [image:
LinkedIn] <http://fr.linkedin.com/in/cadrian> [image:
Twitter]<http://www.twitter.com/cadbart> [image:
Google 
Calendar]<https://www.google.com/calendar/embed?src=1t93vvvrdc26ee0f83p0cunj60%40group.calendar.google.com&ctz=Europe/Paris>
[image:
Google Plus] <http://gplus.to/cadrian>
Contact me: [image: Google Talk] cyril.adrian
 [image: Twitter] <http://twitter.com/cadbart> Latest tweet: [Liberty]
http://t.co/HVba0IX Cyril Adrian - useful option.
Follow @cadbart <http://twitter.com/cadbart>

<http://twitter.com/?status=@cadbart%20&in_reply_to_status_id=106427146326654980&in_reply_to=cadbart>

Reply<http://twitter.com/?status=@cadbart%20&in_reply_to_status_id=106427146326654980&in_reply_to=cadbart>

<http://twitter.com/?status=RT%20%40cadbart%3A%20%5BLiberty%5D%20http%3A%2F%2Ft.co%2FHVba0IX%20Cyril%20Adrian%20-%20useful%20option.>

Retweet<http://twitter.com/?status=RT%20%40cadbart%3A%20%5BLiberty%5D%20http%3A%2F%2Ft.co%2FHVba0IX%20Cyril%20Adrian%20-%20useful%20option.>
   20:06 Aug-24 <http://twitter.com/cadbart/statuses/106427146326654976>
  Get this email app!

<http://www.wisestamp.com/apps/twitter?utm_source=extension&utm_medium=email&utm_term=twitter&utm_campaign=apps>

 [image: Google Plus] <http://plus.google.com/100388810006463519079> My
latest G+: 
Path....<http://plus.google.com/100388810006463519079/posts/9uXjuVnRxr3/>
My G+ <http://plus.google.com/100388810006463519079> -
Posts<http://plus.google.com/100388810006463519079/posts/>- Add
to Circles <http://plus.google.com/100388810006463519079/about/> - 10:45
Aug-31 <http://plus.google.com/100388810006463519079/about/>
  Get this email app!

<http://www.wisestamp.com/apps/plus?utm_source=extension&utm_medium=email&utm_term=plus&utm_campaign=apps>

Signature powered by

<http://r1.wisestamp.com/r/landing?u=5e34fc2118d9c29f&v=2.7.4&t=1316010841790&promo=5&dest=http%3A%2F%2Fwww.wisestamp.com%2Femail-install%3Futm_source%3Dextension%26utm_medium%3Demail%26utm_campaign%3Dpromo_5>

WiseStamp<http://r1.wisestamp.com/r/landing?u=5e34fc2118d9c29f&v=2.7.4&t=1316010841790&promo=5&dest=http%3A%2F%2Fwww.wisestamp.com%2Femail-install%3Futm_source%3Dextension%26utm_medium%3Demail%26utm_campaign%3Dpromo_5>