Tuples, iterators, and multiple return values in Eiffel? 
Author Message
 Tuples, iterators, and multiple return values in Eiffel?


[...]

Quote:
> However, I have a few comments, especially regarding the TUPLE/ROUTINE
> proposal. First, I agree that the introduction of TUPLE cleans up some
> problematic areas in the language (like manifest arrays having no
> specific type). I am, however, not particularly convinced that the

Waht about an extension like ``<<1,2,3>>[INTEGER]'' to enforce all
elements to conform to INTEGER (during compilation). Thus you'd get an
``ARRAY[INTEGER]''.

To maintain compatibility with the existing implementation, one yould
state that the type in square brackets defaults to the target type if
omitted.

[...]

Regards,
Ulrich



Mon, 26 Mar 2001 03:00:00 GMT  
 Tuples, iterators, and multiple return values in Eiffel?

--

David Clark
University of Canberra



Quote:
> Dan Higdon:

> > Repeated inheritance from a deferred class can simulate
> > "function pointer" semantics well, as demonstrated in the iterator
> > discussion of ETL.

> Can it? You still cannot pass "function pointers" around. E.g. if you
> have a COMMAND class with a single deferred feature 'execute', you can
> inherit repeatedly, but you cannot pass multiple COMMAND references to
> other parts of system -- all the COMMAND references you can extract will
> call the implementation of 'execute' that is select-ed in the repeatedly
> inheriting class.

In particular, this means that you can't implement the gang of four
SimpleCommand. (Simplecommand doesn't require arguements, see Design
Patterns, p240.) Hence you can end up with a proliferation of commands.

However, I am in general reluctant about feature creep in a language to
solve few problems - it reminds me too much of the common beaucratic
practise of inventing a new rule for every administrative foul up.

David



Tue, 27 Mar 2001 03:00:00 GMT  
 Tuples, iterators, and multiple return values in Eiffel?

Quote:

> Repeated inheritance from a deferred class can simulate
> "function pointer" semantics well...

> Can it? You still cannot pass "function pointers" around. E.g. if you
> have a COMMAND class with a single deferred feature 'execute', you can
> inherit repeatedly, but you cannot pass multiple COMMAND references to
> other parts of system -- all the COMMAND references you can extract will
> call the implementation of 'execute' that is select-ed in the repeatedly
> inheriting class.

Franck is right. If you have feature replication under repeated inheritance
you must use "select". If you use select, then you get anomalies in the
presence of dynamic binding and polymorphism.

Dan Higdon continued:

Quote:
> ...as demonstrated in the iterator discussion of ETL.

The example in ETL 2nd printing pages 174-177 has never worked on
any Eiffel compiler. Sure, the compiler and/or language could be hacked
to make this example work, but this would just squeeze the amiguities
one class higher in the inheritance heirarchy.

Quote:

> However, I am in general reluctant about feature creep in a language to
> solve few problems...

Absolutely. So the answer here is to _remove_ feature replication and the
"select" clause from the language.

ETL pages 190-191 (the section marked with the "comment" box) describes
a consequence of feature replication under repeated inheritance. Consider
these classes:

            class A
           feature f
           /       \
      class B     class C
     inherit A   inherit A
    redefine f   redefine f
           \       /
            class D
   inherit B rename f as bf
   inherit C rename f as cf select cf

Now consider this code:

   b: B
   ...
   b.f

Which version of 'f' is called? Not the one from class B, but the one
from class C (because of the "select" clause in class D). The version
from class C naturally cannot in general even be expected to maintain the
invariant of class B!

Suppose our original system included only classes A and B. Then the
call "b.f" calls B's version of 'f'. Later we add classes C and D,
and the behaviour of b.f suddenly changes!

This just isn't consistent with a language which aims to promote
correct software.

With the addition to Eiffel of the precusor construct, and the suggested
addition of ROUTINE classes, I can't see any reason to retain the pretense
of feature replication under repeated inheritance.

Regards,
Roger



Tue, 27 Mar 2001 03:00:00 GMT  
 Tuples, iterators, and multiple return values in Eiffel?

Quote:

> > However, I am in general reluctant about feature creep in a language to
> > solve few problems...

(I'd hardly think making this work correctly is 'feature creep'. Eiffel
has had feature replication for a very long time now.)

Quote:
> Absolutely. So the answer here is to _remove_ feature replication and the
> "select" clause from the language.

Even though the bathwater seems murky, let's not throw it out, it may
contain our baby!

Quote:
> Which version of 'f' is called? Not the one from class B, but the one
> from class C (because of the "select" clause in class D). The version
> from class C naturally cannot in general even be expected to maintain the
> invariant of class B!

This seems distressingly broken. However, I think you'd find that
breaking the invariant is rare (if not impossible), because both C's and
B's invariants must be satisfied in D.

The point Roger makes echoes Bertrand's flagging of it in ETL on page
180, with the actual code being displayed at the foot of page 178.

Current problems with feature replication and dynamic binding
-------------------------------------------------------------
1. In the context of the problem Roger raised, calls to b.f when b is
dynamically bound to an instance of D executes C.f.
2. Franck reports that in some circumstrance calls to `f' and
`Current.f' can execute different features. (I don't understand what
context will cause this, though.)
3. Magic rebinding not intended to be deep. (! Again, something I don't
understand.)
4. It's impossible to get more than one part object. (! Another thing I
don't understand. Although, I suspect it refers to point 4.)
5. Calls from replicated features to replicated attributes fail to
'stick' to their partner feature. Instead, they are applied to the
attribute chosen in the `select' clause. (Yuck!)

Here is my proposal to 'fix' feature replication in the face of dynamic
binding:

Proposal: Introduce notion of "Dynamic Seed"
--------------------------------------------
ETL defines the notion of a 'seed' as the origin of a feature
(henceforward known as "seed of origin"). Where dynamic binding is in
play, the select clause currently arbitrates between which inheritor of
the seed is "closer" to the seed. [My interpretation of ETL.]

In the case that both Roger and Bertrand identify, I believe it is the
notion of the select clause arbitrating between the inheritors of the
original seed that causes the problem. Instead, I would have the select
clause arbitrate *only* between inheritors of the "dynamic seed", where
dynamic seed is defined as follows.

Dynamic Seed (definition): A feature identified in class declaration is
known as the dynamic seed. It is not the seed of origin for the feature.
But the seed of origin is not important: what is important is
conformance to the declared (ie dynamic) seed.

Dynamic Seed (examples): Given the situation in ETL pages 178-180 (and
quoted by Roger, in the previous post), the seed or origin is plainly
A.f. However, where Roger writes,

   b: B
   ...
   b := d
   ...
   b.f

the "dynamic seed" is in fact B.f. Given that there is no competition
for proximity to the dynamic seed, the select clause in D can be
completely ignored. The call to `b.f' yields, through dynamic binding,
execution of D.bf, otherwise known as B.f.

The select clause need only be invoked when there is ambiguity between
features vis a vis proximity to the dynamic seed. Such an ambiguity
would only occur (in this particular case) with a call:

   A: a
   ...
   a := d
   ...
   a.f

In this case, it is quite unambiguous that the call will result in
execution of D.cf (otherwise known as C.f).

Quite clearly, using these rules Franck's point about calls to f and
Current.f should be solved, (even though I don't know why it would exist
in the first place) because the dynamic seed of `f' is 'f' itself, and
the select clause wouldn't be invoked. You could, however, invoke the
select clause with the following (in class D):

   ... (in some feature)
   a: A
   ...
   a := Current
   a.f
   f
   ...

But then, that's what you asked for!

Proposal: Select clause clarification
-------------------------------------
(1) The select clause exists solely for the purpose of resolving which
feature is called in the face of dynamic binding. Where dynamic binding
is not at play, the select clause is completely ignored. [This flags the
fact that current interpretations by compilers in case 5. would be
incorrect.]
(2) The select clause is used to arbitrate between features when both
vie for the primary role of being closer to the dynamic seed. The select
clause is not consulted in order to arbitrate between claims to the
original seed, except where the original seed is also the dynamic seed.

Now, I'm not sure, but this proposal doesn't seem to shed much light on
fixing problem 5. Unless someone can demonstrate that this proposal
already contains the solution, I would propose another rule:

(3) Where a replicated routine calls (or assigns to) another replicated
feature (as specified in the text of the ancestor class), it will be
inherited as calling the feature named in the same inheritance clause.
[Of course, if it is redefined, the redefinition calls the feature named
in *this* class; again having nothing to do with the `select' cluse.]

In other words, when you have this going on:

   REPL_A
      select
         set_attr, attr
      end

   REPL_A
      rename
         set_attr as set_attr1,
         attr as attr1
      end

set_attr will assign to attr; and set_attr1 will assign to attr1.

AND, when the select is reversed, the result is still the same:

   REPL_A

   REPL_A
      rename
         set_attr as set_attr1,
         attr as attr1
      select
         set_attr1, attr1
      end

set_attr will assign to attr; and set_attr1 will assign to attr1.

By corrolary, when you examine these rules, the following falls out:

(4) Where a non-replicated routine calls (or assigns to) a replicated
feature (as specified in the text of the ancestor class), it will be
inherited as calling the feature named in the select clause.

I actually don't think this needs to be a special rule, because I think
the dynamic seed is clearly the feature in the ancestor class, and it
needs resolving by the select clause anyway. It's good for explanation
of how the mechanism should work, and stands in contrast to (3).

----------

Clearly, I didn't understand some of the points that Franck raised
(namely, 2, 3, 4). However, I think you'll find that these emendations
to the rules solves  a number of problems inherent in replication and
dynamic binding. I hope it doesn't introduce any of its own.

I think whether or not the ROUTINE proposal is accepted, this aspect of
replication should be addressed. I don't think replication should be
outlawed, because I suspect the rules that would need to be enforced
would be as troublesome as the current rules (wrt. class design, rather
than language definition).

As for Franck claiming that current Eiffel programmers don't need
feature replication / iterating-several-actions, I recently documented
four instances in which I wnated to use it (but couldn't). I also note
that myself, Patrick Doyle, Ted Velkoff, Dan Higdon, and numerous others
over the years have posted to c.l.e., asking why their code wasn't
working as described in ETL. I suggest we clean this issue up, whether
or not we also accept the ROUTINE proposal.

Loryn Jenkins

PS: Sorry for my poor drafting. I've never attempted to write language
rules before.



Wed, 28 Mar 2001 03:00:00 GMT  
 Tuples, iterators, and multiple return values in Eiffel?
I greatly appreciate the feedback on these proposals. For lack
of time I can only write a short answer, which addresses only
some of the questions and does not name individual commenters.
No offense is meant to them and their thoughtful comments; it's
just that there are only 24 hours a day.
(Not added during proofreading: well, the note turned out not that
short after all.)

1. It is really not true that the introduction of these mechanisms
violates the principle that "there should be one good way to do
anything". You will now be able to write the following:

        my_list: LINKED_LIST [SOME_TYPE]

        my_action (t: SOME_TYPE) is do ... end
        my_test (t: SOME_TYPE): BOOLEAN is do ... end

        ...

        my_list.do_if (~my_action, ~my_test)

to apply `my_action' to every element of the list, or, if the routines
have more arguments, something like

        my_list.do_if (~my_action, ~my_test, action_arg1, action_arg2, test_arg)

Of course you can achieve the same effect with the current language,
but not as nicely.

2. Very important: Contrary to what has been written, there is NO
contradiction between routine objects and the technique, popular
in Eiffel, of using command classes (see EiffelVision, EiffelBuild,
chapter 20 of "Object-Oriented Software Construction", 2nd edition).
Having routine objects simplifies command classes and makes them
much more effective. The technique is used extensively in the new
version of EiffelVision (described in an earlier message of today).
Routine objects make command classes very nice and effective,
simplifying the writing of the application by eliminating the
need for many auxiliary classes.

3. Even the creation expression mechanism does not violate the "one
good way" principle. Creation expressions are mainly useful for
passing arguments. For creating an object attached to an attribute
or local entity it's nicer to write `create x.make (...)' than using
a creation expression and an assignment, since you don't need to specify
the type if it's the one declared for `x'.

4. An argument for tuples is that they establish a better symmetry between
routine arguments and results, which I think is good. As a special case
this makes it possible to have functions with multiple return values without
introducing a class just for that purpose. (It may be argued that this is not
O-O enough; indeed using a tuple result is not a substitute for defining
the right abstraction -- the right class -- when that abstraction does
make sense on its own. But there are cases in which a tuple result
seems the right approach, and defining a special class might be overkill.
Think for example of a division operation (not necessarily on integers)
that returns a pair <<quotient, remainder>>.)

5. Another nice application of tuples is for output operations.
Formated output, for example, is nicely handled by tuples (although
it can of course be dealt with in the current language).

6. As pointed out in the proposal, manifest arrays are in the current
language the only kind of construct that doesn't have a clearly
defined type (a manifest array actually has a set of types). This
is an elegance concern rather than a practical problem (as the type rules
for manifest arrays are safe and unambiguous), but it's nice to have
it resolved.

7. The above points seem to confirm that we have a language extension that
does satisfy one of the principal requirements: solving several problems
at once, not just providing an ad hoc solution to one perceived concern.

8. Tuple-based iterators are not redundant with the proper implementation of
replication under repeated inheritance. The latter has not been a major
customer priority until now but of course it will be done.

9. It is true that `item (i)' for a tuple can only be declared as returning ANY,
so that assignment attempt is needed to do something useful with the result.
We have envisioned including well-typed functions `first', `second', `third',
`fourth' and `fifth' (introduced respectively in TUPLE [X], TUPLE [X, Y] etc.,
hence declared as returning X, Y etc.). We have had the comment "why stop at 5?"
(indeed, this is an arbitrary limit) and the suggestion of having an infinite
set of features item_1, item_2 etc. with the proper types, which would have
to be known to the compiler since they are really fictitious (if I can use
these two words together). I have mixed feelings about this idea
and would appreciate opinions about it.

10. The general idea behind the tuple etc. proposal is to provide more "meta"
facilities for Eiffel. This is not a new idea; Roger Rousseau from the
University of Nice has been lobbying me to do something like this for
something like ten years. Richard Bielak and Nick Leaton
have more recently started an independent effort with a similar
goal, which I haven't had time to study yet. I think it's clear that
a successful extension in this direction will not just address pet
peeves but significantly elevate the expressive power of the language.
Of course the trick is in "successful", which is what this discussion
is all about.

11. We are very customer-driven. The catalysis for the tuple, routine object
and iterator design was the request of a large customer -- a company which had
convincing arguments that it needed some better ways of defining
iterators. I am not using this observation as a shield, as I would never
suggest a language change with which I disagree, whatever the customer,
but simply to indicate that these mechanisms are not just the effect of
too much summer sun on my restless mind.

As another testimonial, Paul Dubois (referring to his work for the design
and implementation of the EiffelMath library,
http://eiffel.com/products/math.html,
discussed in his book "Object Technology for Scientific Computing",
Prentice Hall, see
http://eiffel.com/doc/documentation.html#otsc)
commented rather forcefully, when I presented the new constructs at
TOOLS USA a few weeks ago, that he would really have liked to have
them available when he did that work. I take this as evidence for
both of the conjectures underlying this message: that it was possible,
to work without the new mechanisms -- since EiffelMath is a
very successful design; but also that the new mechanisms are
powerful and desirable.

12. Eiffel as a language has been incredibly stable. The last significant
language revision dates back to 92 (finalized over the following two
years). Even that revision was a fairly incremental update of the
original September 1985 version. Since 1990 most other languages
have either gone away or undergone major revisions, and many are
still changing all the time. During that time, of course, the computer
industry has continued to experience constant upheaval.

I take the stability of Eiffel's original ideas (and the fact that
when an extension is proposed so many people react skeptically on
comp.lang.eiffel) as a token of their success and adequacy.
But after 8 years or so of almost total stability, it is not unreasonable
to start looking at new, better ways of doing things, being
very careful not to destroy the edifice, submitting every
proposal to intense scrutiny, trying out implementations before
finalizing the ideas, and taking account of every criticism.
That's what we are trying to do right now.

I intend to keep the process open and to continue discussing all
issues within NICE and on comp.lang.eiffel, as was done (regarding
the latter -- NICE wasn't in operation) between 1989 and 1991
for the greatest benefit of the Eiffel community.

--
Bertrand Meyer, Interactive Software Engineering
ISE Building, 2nd Floor, 270 Storke Road Goleta, CA 93117 USA
805-685-1006, Fax 805-685-6869,



Thu, 29 Mar 2001 03:00:00 GMT  
 Tuples, iterators, and multiple return values in Eiffel?
[...]

Quote:
> 1. It is really not true that the introduction of these mechanisms
> violates the principle that "there should be one good way to do
> anything". You will now be able to write the following:

>    my_list: LINKED_LIST [SOME_TYPE]

>    my_action (t: SOME_TYPE) is do ... end
>    my_test (t: SOME_TYPE): BOOLEAN is do ... end

>    ...

>    my_list.do_if (~my_action, ~my_test)

> to apply `my_action' to every element of the list, or, if the routines
> have more arguments, something like

>    my_list.do_if (~my_action, ~my_test, action_arg1, action_arg2, test_arg)

> Of course you can achieve the same effect with the current language,
> but not as nicely.

I have no problem with something like:

class ACTION [T]

feature { ANY }

  action(arg: T) is
  deferred
  end -- action

end -- class ACTION

class CONDITIONAL_ACTION [T] inherit
  ACTION [T]

feature { ANY }

  test(arg: T): BOOLEAN is
  deferred
  end -- test

  execute(arg: T) is
  deferred
  end -- execute

  action(arg: T) is
  do
    if test(arg) then
      execute(arg)
    end
  end -- action

end -- class CONDITIONAL_ACTION

Then create subclasses from that.

I do not see what about this approach is lacking elegance. In fact, it
seems to result in a more powerful framework than the function pointer
approach.

Quote:
> 2. Very important: Contrary to what has been written, there is NO
> contradiction between routine objects and the technique, popular
> in Eiffel, of using command classes (see EiffelVision, EiffelBuild,
> chapter 20 of "Object-Oriented Software Construction", 2nd edition).
> Having routine objects simplifies command classes and makes them
> much more effective. The technique is used extensively in the new
> version of EiffelVision (described in an earlier message of today).
> Routine objects make command classes very nice and effective,
> simplifying the writing of the application by eliminating the
> need for many auxiliary classes.

I would like to point you to

        http://x10.dejanews.com/getdoc.xp?AN=104894350

This is an article with the Subject "Re: no function pointers in
Eiffel", written by you, and arguing the exact opposite position. I also
note that the article mentions EiffelMath, which you give further below
as an example of a library that would have benefited from the extension.

So I would like to know what changed your mind. Note: This is not meant
as a personal attack; only fanatics never change their opinions. But
your change in position is so dramatic that I'd really like to know what
caused it.

Quote:
> 3. Even the creation expression mechanism does not violate the "one
> good way" principle. Creation expressions are mainly useful for
> passing arguments. For creating an object attached to an attribute
> or local entity it's nicer to write `create x.make (...)' than using
> a creation expression and an assignment, since you don't need to specify
> the type if it's the one declared for `x'.

Hmm. I didn't see anything about creation expressions anywhere in either
proposal (correct me if I'm wrong). However, I _do_ remember a forceful
argument against them in ETL (sorry, can't give a page reference; my
copy is still in Germany). You basically argued (I'm paraphrasing) that
every instance of such a creation expression for a type T could be
replaced by a function call new_T; and that introducing this additional
language feature would violate the "one good way" principle. In fact, if
I remember correctly, this was your most prominent example.

Quote:
> 4. An argument for tuples is that they establish a better symmetry between
> routine arguments and results, which I think is good. As a special case
> this makes it possible to have functions with multiple return values without
> introducing a class just for that purpose. (It may be argued that this is not
> O-O enough; indeed using a tuple result is not a substitute for defining
> the right abstraction -- the right class -- when that abstraction does
> make sense on its own. But there are cases in which a tuple result
> seems the right approach, and defining a special class might be overkill.
> Think for example of a division operation (not necessarily on integers)
> that returns a pair <<quotient, remainder>>.)

class DIVISION_RESULT [T -> NUMERIC]

creation
  make

feature { ANY } -- creation

  make(a_quotient, a_remainder: T) is
  do
    quotient := a_quotient
    remainder := a_remainder
  end -- make

feature { ANY } -- attributes

  quotient: T
  remainder: T

end -- class DIVISION_RESULT

Personally, I don't have any problem with this. In fact, one nice thing
about Eiffel has always been that there were pretty much no complex
anonymous entities, because you always had to give names to concepts.

I would also like to point out that it makes the postcondition of a
division operation far more readable if you can write:

        ensure
          is_equal(Result.quotient * divisor + Result.remainder)

rather than:

        ensure
          is_equal(Result.first * divisor + Result.second)

where due to the anonymity of the names it is easy to confuse both.
Given that pre-/postconditions also serve as documentation, this is
an important aspect.

The same applies to _using_ the result, of course. I don't want to
ask myself all the time: "Is x.first the quotient or the remainder?"

Quote:
> 5. Another nice application of tuples is for output operations.
> Formated output, for example, is nicely handled by tuples (although
> it can of course be dealt with in the current language).

I have no problems whatsoever with using manifest arrays for this
purpose; in fact, I do not see what tuples gain you here. But I'd really
like to see an in-depth explanation.

Quote:
> 6. As pointed out in the proposal, manifest arrays are in the current
> language the only kind of construct that doesn't have a clearly
> defined type (a manifest array actually has a set of types). This
> is an elegance concern rather than a practical problem (as the type rules
> for manifest arrays are safe and unambiguous), but it's nice to have
> it resolved.

I would add that it also makes reasoning about the language easier. I
have no problems with that part. But that does not in itself provide
sufficient incentive for a language change.

Quote:
> 7. The above points seem to confirm that we have a language extension that
> does satisfy one of the principal requirements: solving several problems
> at once, not just providing an ad hoc solution to one perceived concern.

Frankly, I do not see what problems it solves any better than the
current approach.

[...]

Quote:
> 9. It is true that `item (i)' for a tuple can only be declared as
> returning ANY, so that assignment attempt is needed to do something
> useful with the result. We have envisioned including well-typed
> functions `first', `second', `third', `fourth' and `fifth' (introduced
> respectively in TUPLE [X], TUPLE [X, Y] etc., hence declared as
> returning X, Y etc.). We have had the comment "why stop at 5?"
> (indeed, this is an arbitrary limit) and the suggestion of having an
> infinite set of features item_1, item_2 etc. with the proper types,
> which would have to be known to the compiler since they are really
> fictitious (if I can use these two words together). I have mixed
> feelings about this idea and would appreciate opinions about it.

Well, that wouldn't be too different from the BIT n "magic". I agree
that I don't feel too comfortable with it, either. In any event, that
is a concern that arises _once_ it has been demonstrated that TUPLE is
a useful addition to the language.

Quote:
> 10. The general idea behind the tuple etc. proposal is to provide more
> "meta" facilities for Eiffel. This is not a new idea; Roger Rousseau
> from the University of Nice has been lobbying me to do something like
> this for something like ten years. Richard Bielak and Nick Leaton have
> more recently started an independent effort with a similar goal, which
> I haven't had time to study yet. I think it's clear that a successful
> extension in this direction will not just address pet peeves but
> significantly elevate the expressive power of the language. Of course
> the trick is in "successful", which is what this discussion is all
> about.

I cannot comment on this, as the ROUTINE/TUPLE proposal then obviously
is a small piece of a much larger picture. If Eiffel is to be extended
to include a number of meta facilities, I'd prefer to see the entire
proposal first before I discuss individual facets of a complex mosaic.

Quote:
> 11. We are very customer-driven. The catalysis for the tuple, routine object
> and iterator design was the request of a large customer -- a company which had
> convincing arguments that it needed some better ways of defining
> iterators. I am not using this observation as a shield, as I would never
> suggest a language change with which I disagree, whatever the customer,
> but simply to indicate that these mechanisms are not just the effect of
> too much summer sun on my restless mind.

I do have a problem with this statement; obviously, "we" does not refer
to NICE, as NICE doesn't have customers. On the other hand, if "we"
refers to ISE, is NICE supposed to accept extensions implemented at ISE
as a fait accompli? Or will NICE Eiffel and ISE Eiffel eventually
diverge?

[...]

Quote:
> 12. Eiffel as a language has been incredibly stable. The last significant
> language revision dates back to 92 (finalized over the following two
> years). Even that revision was a fairly incremental update of the
> original September 1985 version. Since 1990 most other languages
> have either gone away or undergone major revisions, and many are
> still changing all the time. During that time, of course, the computer
> industry has continued to experience constant upheaval.

I think most Eiffel programmers both like this stability and don't mind
having the language reevaluated. However, the proposed extensions seem
to herald a change in direction -- towards a different Eiffel. Allow me
to ...

read more »



Fri, 30 Mar 2001 03:00:00 GMT  
 Tuples, iterators, and multiple return values in Eiffel?

Quote:


> [...]

> > 10. The general idea behind the tuple etc. proposal is to provide more
> > "meta" facilities for Eiffel. This is not a new idea; Roger Rousseau
> > from the University of Nice has been lobbying me to do something like
> > this for something like ten years. Richard Bielak and Nick Leaton have
> > more recently started an independent effort with a similar goal, which
> > I haven't had time to study yet. I think it's clear that a successful
> > extension in this direction will not just address pet peeves but
> > significantly elevate the expressive power of the language. Of course
> > the trick is in "successful", which is what this discussion is all
> > about.

> I cannot comment on this, as the ROUTINE/TUPLE proposal then obviously
> is a small piece of a much larger picture. If Eiffel is to be extended
> to include a number of meta facilities, I'd prefer to see the entire
> proposal first before I discuss individual facets of a complex mosaic.

I would say that Eiffel has, so far, taken a fairly extreme 'non-meta'
position, and Bertrand has expounded various cogent arguments for this.
So if the language changes discussed previously are indeed part of a
'general idea ... to provide more "meta" facilities for Eiffel', then as
Reimer says, it would be helpful for Bertrand to outline the nature and
scope of this idea.  From what I've seen so far, the Tuple, Routine
Object, etc, proposals seem considerably more radical than, say, the
Precursor construct, or the generic type creation proposals (fine by
me).

In anticipation...
Regards
Roy macLean



Fri, 30 Mar 2001 03:00:00 GMT  
 Tuples, iterators, and multiple return values in Eiffel?
...
Quote:
> 9. It is true that `item (i)' for a tuple can only be declared as returning ANY,
> so that assignment attempt is needed to do something useful with the result.
> We have envisioned including well-typed functions `first', `second', `third',
> `fourth' and `fifth' (introduced respectively in TUPLE [X], TUPLE [X, Y] etc.,
> hence declared as returning X, Y etc.). We have had the comment "why stop at 5?"
> (indeed, this is an arbitrary limit) and the suggestion of having an infinite
> set of features item_1, item_2 etc. with the proper types, which would have
> to be known to the compiler since they are really fictitious (if I can use
> these two words together). I have mixed feelings about this idea
> and would appreciate opinions about it.

...

Class TUPLE represents lists of objects, so it may provide usual "list"
operations:

   head: "type of the 1st parameter" is
      require
         not_empty: count > 0

   tail: TUPLE [2nd parameter type, 3rd parameter type, ...] is
      require
         not_empty: count > 0
      ensure
         proper_result: ( count = 1 implies Result = Void ) and then
                              ( count > 1 implies Result /= Void )

So for TUPLE[X, Y, Z] we will have
   head: X
   tail: TUPLE [Y, Z]
This will solve the problem mentioned above in a uniform way. Though
the fifth element of the tuple 'x' will be denoted as
   x.tail.tail.tail.tail.head
in most cases we will need only a few first elements.

Feature 'tail' may be either a function (as shown above) or a procedure
(to avoid creation of the new object).

--
Alexander Kogtenkov
Object Tools, Moscow



Fri, 30 Mar 2001 03:00:00 GMT  
 Tuples, iterators, and multiple return values in Eiffel?
I would like to clarify the following situation with TUPLE:

What is the type of << 1, Void, "a" >>?
Accordingly to the definition, it is TUPLE [ INTEGER, NONE, STRING ].
Am I correct?

Thanks,
--
Alexander Kogtenkov
Object Tools, Moscow



Fri, 30 Mar 2001 03:00:00 GMT  
 
 [ 35 post ]  Go to page: [1] [2] [3]

 Relevant Pages 
 

 
Powered by phpBB® Forum Software