Friday, October 23, 2009

A couple of proposals

Adding "ref: REFERENCE[like Current]" in ANY
This would to allow to easily write a manifest COLLECTION[ANY] holding non-expanded objects and references to expanded like INTEGER or REAL.
The usage would to write code like
   formatter: STRING_PRINTER is once create Result.make(std_output) end
   do_stuff is
      formatter.put_message("Cluster @(1): @(2) classes, @(2)%% non-deferred",<<"a_cluster_name", 1000.ref, 0.25.ref>>)
I'm conscious this would allow for printf-like features that mimick variadic functions, a potential way toward spaghetti-code; current alternative is formatter.put_message("Cluster @(1): @(2) classes, @(2)%% non-deferred",<<"a_cluster_name", 1000.out, 0.25.out>>) that allocates two temporary strings, nullifing/thwarting one of the main reason to use a STRING_PRINTER: avoiding creation of temporary, shortly-lived strings.

Adding ROPE string and eventually a TWINE.

Sometime ago I started a little hack named LINKED_STRING, a string implemented as a linked list of strings; the idea was to make concatenation efficient, ideally an O(1) operation; then I discovered that (quite obviously) other people had the same idea. Ropes are usually not implemented using lists as in my draft. I'm still thinkering about it.


  1. The ref won't help you.

    Tip: what's the type of <<"a_cluster_name", 1000.ref, 0.25.ref>> ?

    As for the linked stings, I saw a few articles on the subject and that's quite a good idea.
    And since Liberty strings all have a common ancestor (ABSTRACT_STRING)...

  2. Answer: that array has no known type (its elements don't have a common conforming ancestor).

    What's wrong with <<"a_cluster_name", 1000.out, 0.25.out>> ?

  3. I tried this code:
    class MU
    creation make
    make is
    create {REFERENCE[INTEGER]}.set_item(1000),
    create {REFERENCE[REAL]}.set_item(3.14)>>).do_all(agent {ANY}.print_on(std_output))

    it compiles fine; AFAIK the array is a ARRAY[ANY]. But you're right, it won't save as allocating memory, it will only allocate less memory (no string duplication).
    All in all let's put aside this issue; I'll finish ROPE (aka LINKED_STRING); I think it would be nice to put infix "|" (another: ABSTRACT_STRING): ROPE -- Efficiently concatenate Current and `another' into ABSTRACT_STRING. Do you agree?

  4. I have not really thought about it but I think I'd rather change infix "+" to return an ABSTRACT_STRING.

    An afterthought: don't forget to redefine `out_in_tagged_out_memory' and `fill_tagged_out_memory' (see FIXED_STRING) so that (st1 + st2).out would return a good old STRING

  5. I would offer both solutions since one solution does not fit well in all the possible situations.
    Only the programmer dealing with specific case should be able to decide which solution is "better" in his/her case of string concatenation: getting a STRING containing the whole string or a ROPE.
    We may offer three choices indeed
    1 - getting a STRING as the "usual" plain concatenation,
    2 - getting a ROPE
    3 - getting an ABSTRACT_STRING so that implementation can choose euristically

    The first names for those features I got are:
    generic_concatenate, infix "+" (another: ABSTRACT_STRING): ABSTRACT_STRING
    -- "Opaque" typed, the implementation may return any effective heir of ABSTRACT_STRING
    glue, infix "|" (another: ABSTRACT_STRING): ROPE
    -- Efficient concatenation
    concatenate, infix "&" (another: ABSTRACT_STRING): STRING
    -- "plain" concatenation.

    but they don't satisfy me....

    More on this later.