Passing STRINGs to 'separate' objects

42 views
Skip to first unread message

Curly

unread,
Apr 24, 2019, 2:34:19 PM4/24/19
to Eiffel Users
I'm trying to use SCOOP for the first time, and am having trouble making sense of the compiler messages.

I have a class I wish to run concurrently:

class
    RACE

feature {NONE} -- Initialization

    starttime: STRING
    course: STRING
    going: STRING
    distance: REAL


    make (passed_startTime: STRING; passed_course: STRING; passed_going: STRING; passed_distance: REAL)

        do
            create startTime.make_from_string (passed_startTime)
            create course.make_from_string (passed_course)
            create going.make_from_string (passed_going)
            create distance.make_from_reference (passed_distance)

        end

---

Trying to create/call the class from another:

    get_races

        -- get races from db

        do

            das_dah_db_1_get_races.execute (agent (returned_row: SQLITE_RESULT_ROW): BOOLEAN

                local

                    returned_startTime:    STRING
                    returned_course:        STRING
                    returned_going:          STRING
                    returned_distance:     REAL

                    race_details:               separate RACE

                    do
                        returned_starttime        := returned_row.string_value (1)
                        returned_course           := returned_row.string_value (2)
                        returned_going             := returned_row.string_value (3)
                        returned_distance        := returned_row.real_value   (4)

                        create race_details.make (returned_starttime, returned_course, returned_going, returned_distance)

                        start_race_process_thread (race_details)

                    end )

        end -- get_races

    start_race_process_thread (race_details: separate RACE)

            -- create a new thread to process race details

        do
            race_details.process_race

        end -- start_race_process_thread

---

The compiler tells me that returned_starttime, returned_course and returned_going in the "create race_details.make" should be separate types.

If I make them separate, the compiler complains that they are not separate in the RACE class - but I don't want them separate in that class, as they are only used once to start the next part of the process.

I notice it doesn't complain about the numerical type, just the STRING type.

What am I missing?

(sorry in advance if the formatting is all over the place)

Alexander Kogtenkov

unread,
Apr 25, 2019, 2:55:11 AM4/25/19
to eiffel...@googlegroups.com
The difference between STRING types and numerical types is in the reattachment semantics. STRING types have reference semantics, i.e. during reattachment, a reference to the object is passed, there is just a single copy of that object. Basic numerical types (REAL_32, INTEGER, etc.) have copy semantics (they are expanded), i.e. during reattachment a new copy of the object is created, there are multiple copies.

A copy of an expanded object is created on the target SCOOP processor/region, so it is OK to pass REAL and other basic expanded types from one SCOOP processor to another. However, when you pass a string from a processor A to a processor B (assuming the string is created on the processor A), it is “foreign” (separate in SCOOP terms) to the processor B, because it belongs to a different processor A. Therefore, according to the language rules, when there is a call to a feature on a separate object, the arguments of the feature should be marked as separate. In your example, the formal arguments of the feature RACE.make should be separate.

After this change, creation instructions like `create startTime.make_from_string (passed_startTime)` in the creation procedure RACE.make would be invalid, because `make_from_string` takes a non-separate argument. They should be using `make_from_separate` instead.

Hope this helps,
Alexander Kogtenkov


Curly <gimmean...@gmail.com>:

Curly

unread,
Apr 25, 2019, 5:08:57 AM4/25/19
to Eiffel Users
Thanks Alexander, well explained.

Larry Rix

unread,
May 1, 2019, 5:26:36 PM5/1/19
to Eiffel Users
The remaining question for me is: How do I make a string that is separate? The argument in `make_from_separate' has to be separate. So, what does that creation look like?

On Thursday, April 25, 2019 at 2:55:11 AM UTC-4, Alexander Kogtenkov wrote:
... They should be using `make_from_separate` instead.

Larry Rix

unread,
May 1, 2019, 5:35:29 PM5/1/19
to Eiffel Users
Also—eventually, I want to pass the string as an argument, but I get an error

Error code: VUAR(2)

Type error: non-compatible actual argument in feature call. 
What to do: make sure that type of actual argument is compatible with
  the type of corresponding formal argument. 

Class: PRIMARY_SERVER
Feature: initialize
Called feature: set_service_option (a_name: READABLE_STRING_GENERAL; a_value: detachable ANY) from WSF_LAUNCHABLE_SERVICE
Argument name: a_value
Argument position: 2
Formal argument type: detachable ANY
Actual argument type: separate STRING_8
Line: 61
        if attached verbose_level_alert as al_string then
->        set_service_option ("verbose_level", al_string)
        end

I know there is documentation for this and I am going to go look for it.

Curly

unread,
May 1, 2019, 6:39:29 PM5/1/19
to Eiffel Users
The mistake I had made was that the arguments needed to be defined as separate both in the calling class and the called procedure. Within the procedure you use make_from_separate to convert from separate back to an ordinary string.

Larry Rix

unread,
May 1, 2019, 8:44:28 PM5/1/19
to Eiffel Users
Gotcha!

Larry Rix

unread,
May 2, 2019, 9:31:27 AM5/2/19
to Eiffel Users
Good morning, Curly!

I ended up making two mistakes, where this thread helped me with the first and your last response helped with the last. The solutions to those mistakes were:

  1. Creation of a separate STRING to send as an argument to a creation procedure of a separate feature. In this case I created a separate STRING with a function, whose Result I then pass to the creation procedure.
  2. Creation of a non-separate STRING from the separate STRING argument in the creation procedure to which the argument was passed. This is then stored in an attribute feature of the receiving separate object for use in later processing.
Item #1 I was able to see from your exchange of information in this thread.

Item #2 I was able to see from your last response to me.

So—now I have this working as I had intended for it to work. This process is teaching me that concurrent coding not only means a keyword, but understanding how to construct the code to obey the rules and requirements. I thank God for a super smart compiler. Bertrand & Co. have given us a super finely crafted compiler. It never ceases to amaze me at how helpful this thing is and how it makes my job simpler and easier to cope with!


L

On Wednesday, May 1, 2019 at 6:39:29 PM UTC-4, Curly wrote:
Reply all
Reply to author
Forward
0 new messages