Expressing intent in method calling

This is not a continuation of the type thread other than trying to continue
to discuss the ideas of adding metadata that could be used to help the
runtime environment of Ruby. Before anyone says anything, I have built lots
of Ruby code without this, and the runtime is just fine...think of this as

···

exploration. Disregard all the other syntax I wrote on earlier...and I do not care whether something is Hash-like, or is_a? Duck :wink: class Person attr_accessor :name
  end

  def greet(person)
    puts "Hello there #{person.<Person>name}"
  end

So, greet was coded thinking its sending the 'name' message to a Person
object...and that is expressed with the metadata <Person>.

  o = Object.new
  def o.name
    if called_as?(Person)
      "Rich"
    else
      to_s
    end
  end

You build your object to accept being called as a Person, but it can be
called as anything else too...it just responds to the name method
differently if its being asked 'as a Person'.

  greet(o) => "Hello there Rich"

What this adds is the ability to express the intent of the caller as to what
they mean by sending the message 'name' (ie. name, as in a Person's name).
The receiver can find out the caller's intent (called_as?(Person)). It also
lets the receiver change into what the caller wants it to be (kinda like
become...one method at a time).

-rich

Richard Kilmer wrote:

This is not a continuation of the type thread other than trying
to continue
to discuss the ideas of adding metadata that could be used to help the
runtime environment of Ruby. Before anyone says anything, I have
built lots
of Ruby code without this, and the runtime is just fine...think of this as
  end

  def greet(person)
    puts "Hello there #{person.<Person>name}"
  end

So, greet was coded thinking its sending the 'name' message to a Person
object...and that is expressed with the metadata <Person>.

  o = Object.new
  def o.name
    if called_as?(Person)
      "Rich"
    else
      to_s
    end
  end

You build your object to accept being called as a Person, but it can be
called as anything else too...it just responds to the name method
differently if its being asked 'as a Person'.

  greet(o) => "Hello there Rich"

What this adds is the ability to express the intent of the caller
as to what
they mean by sending the message 'name' (ie. name, as in a Person's name).
The receiver can find out the caller's intent
(called_as?(Person)). It also
lets the receiver change into what the caller wants it to be (kinda like
become...one method at a time).

This is a very interesting concept and, in general, I like it.

My initial reaction was why not just have a method named "person_name", but
quickly realized that this is much more powerful. Objects that respond to
name but do not understand <Person> can still be used (this might be
considered a "degraded" use, whereas an object that can use the metadata
<Person> can operate in an "enhanced" manner.

While this shows the use of metadata as part of sending a message, a similar
syntax could be used to attach metadata to methods and classes as is done in
.NET. As with .NET, this metadata could be inspected at runtime to enable
the creation of enhanced runtime facilities like Aspects and Unit Testing.

For example, I particularly like the way NUnit for .NET
(http://www.nunit.org/\) implements unit testing, and metadata for classes
and methods in Ruby could able this technique for TestUnit:

  <TestHarness> class MyTests
    <TestSetup> def create_clean_database
       ...
    end
    <Test> def create_db_entry
       ...
    end
    <Test> def update_db_entry
       ...
    end
  end

An AOP example could use metadata to identify target pointcuts (perhaps at
the method level):

  class BankAccount
    ...
    <CheckPermissions> def balance?
       ...
    end
  end

In this example, a runtime AOP framework could, for example, wrap the
"balance?" method with AOP defined permission checks.

I'm sure there are some synergistic possibilities between metedata on
methods and classes and metadata attached to messages, but I haven't had
time to think about that yet.

Curt

···

exploration. Disregard all the other syntax I wrote on earlier...and I do > not care whether something is Hash-like, or is_a? Duck :wink: > > class Person > attr_accessor :name

Isn't this effectively "to_name" or "as_name"?

Cheers

Dave

···

On Jun 8, 2004, at 9:43, Richard Kilmer wrote:

This is not a continuation of the type thread other than trying to continue
to discuss the ideas of adding metadata that could be used to help the
runtime environment of Ruby. Before anyone says anything, I have built lots
of Ruby code without this, and the runtime is just fine...think of this as
exploration. Disregard all the other syntax I wrote on earlier...and I do
not care whether something is Hash-like, or is_a? Duck :wink:

  class Person
    attr_accessor :name
  end

  def greet(person)
    puts "Hello there #{person.<Person>name}"
  end

Hi --

···

On Tue, 8 Jun 2004, Richard Kilmer wrote:

  class Person
    attr_accessor :name
  end

  def greet(person)
    puts "Hello there #{person.<Person>name}"
  end

So, greet was coded thinking its sending the 'name' message to a Person
object...and that is expressed with the metadata <Person>.

  o = Object.new
  def o.name
    if called_as?(Person)
      "Rich"
    else
      to_s
    end
  end

You build your object to accept being called as a Person, but it can be
called as anything else too...it just responds to the name method
differently if its being asked 'as a Person'.

  greet(o) => "Hello there Rich"

What this adds is the ability to express the intent of the caller as to what
they mean by sending the message 'name' (ie. name, as in a Person's name).
The receiver can find out the caller's intent (called_as?(Person)). It also
lets the receiver change into what the caller wants it to be (kinda like
become...one method at a time).

Could this metadata even be not class/module-oriented? In other
words, where you have called_as?(Person), could "Person" just be a
namespace or registry of methods? Classes would then have to register
their methods too, I guess.

David

--
David A. Black
dblack@wobblini.net

Whether it's name or to_name, he is seeking a way to differentiate
person names and Nonlinear Altitude Modulation Expositors.

To use an example from your book, he wants to distinguish
between Action#sin and Trig#sin. He can "let it ride" and see
what happens by just calling #sin, but I think the motivation
behind these threads is to provide support for methods/interfaces
which claim some conformant behavior.

···

--- Dave Thomas <dave@pragprog.com> wrote:

> class Person
> attr_accessor :name
> end
>
> def greet(person)
> puts "Hello there #{person.<Person>name}"
> end

Isn't this effectively "to_name" or "as_name"?

__________________________________
Do you Yahoo!?
Friends. Fun. Try the all-new Yahoo! Messenger.
http://messenger.yahoo.com/

I am not trying to coerce the object into another representation in general
(although in the specific example its like that). Generally, I am trying to
add to the message something more than the message symbol and parameters...I
am trying to add the 'meaning' of the message as scoped in the namespace of
the provided class/module. I am trying to add to the method additional
semantics of what I am asking from the target object. I am sending the
message 'name' with the meaning that 'name' has on a Person object. That
receiver may or may not care...answering the way it wants, but right now I
cannot express that semantics at all.

I guess I am not expressing myself with sufficient semantics :wink:

-rich

···

On 6/8/04 11:51 AM, "Dave Thomas" <dave@pragprog.com> wrote:

On Jun 8, 2004, at 9:43, Richard Kilmer wrote:

This is not a continuation of the type thread other than trying to
continue
to discuss the ideas of adding metadata that could be used to help the
runtime environment of Ruby. Before anyone says anything, I have
built lots
of Ruby code without this, and the runtime is just fine...think of
this as
exploration. Disregard all the other syntax I wrote on earlier...and I
do
not care whether something is Hash-like, or is_a? Duck :wink:

  class Person
    attr_accessor :name
  end

  def greet(person)
    puts "Hello there #{person.<Person>name}"
  end

Isn't this effectively "to_name" or "as_name"?

Well, not necessarily conformant behavior. Its so the caller can express
what they are expecting the behavior to be, and receiver then making use of
that or not. I am not 'casting' the receiver to a Person nor asking the
runtime to check to ensure that it is a Person, I am allowing the receiver
to understand something of what I want it to do beyond a simple symbol/param
list...instead its a namespaced symbol/param list, which may disambiguate
the request. The receiver can check on the supplied namespace (if present)
and act accordingly.

I guess the reason for this is we already have namespaces (modules/classes)
and methods in them...there is just no way to use the namespaces to add
meaning to a method requests.

-rich

···

On 6/8/04 12:11 PM, "Jeff Mitchell" <quixoticsycophant@yahoo.com> wrote:

--- Dave Thomas <dave@pragprog.com> wrote:

  class Person
    attr_accessor :name
  end

  def greet(person)
    puts "Hello there #{person.<Person>name}"
  end

Isn't this effectively "to_name" or "as_name"?

Whether it's name or to_name, he is seeking a way to differentiate
person names and Nonlinear Altitude Modulation Expositors.

To use an example from your book, he wants to distinguish
between Action#sin and Trig#sin. He can "let it ride" and see
what happens by just calling #sin, but I think the motivation
behind these threads is to provide support for methods/interfaces
which claim some conformant behavior.

I think that you are clear enough. x.<some_class>.some_method() means
that you want x to do what some_class does when some_method() is called.

I don't like so much the called_as() thing because it looks inefficient
to me. I would rather consider it as a something like method_missing. A
more efficient solution would be to try to call a fully named method
some_class.some_method() and default to some_method():

Some alternative syntax proposal:

class Y
  def do_it(); end
end

class X
  implement Z # declarative
  def do_it();
    if implement? Z then
      xxx
    else
    end
  end
  def Y.do_it(); end
end

y = Y.new; y.do_it() # Y's version of do_it()
x = X.new; x.do_it() # X's version of do_it()
x.Y.do_it() # X's version of Y's do_it()
x.Z.do_it() # X's version of do_it()

This may prove useful to resolve name clashes when
implementing multiple Interfaces in a class. As
a result an Interface would simply be an abstract
class (or a Module maybe).

Yours,

Jean-Hugues

···

At 03:32 09/06/2004 +0900, you wrote:

On Jun 8, 2004, at 9:43, Richard Kilmer wrote:

This is not a continuation of the type thread other than trying to
continue
to discuss the ideas of adding metadata that could be used to help the
runtime environment of Ruby. Before anyone says anything, I have
built lots
of Ruby code without this, and the runtime is just fine...think of
this as
exploration. Disregard all the other syntax I wrote on earlier...and I
do
not care whether something is Hash-like, or is_a? Duck :wink:

  class Person
    attr_accessor :name
  end

  def greet(person)
    puts "Hello there #{person.<Person>name}"
  end

Isn't this effectively "to_name" or "as_name"?

I am not trying to coerce the object into another representation in general
(although in the specific example its like that). Generally, I am trying to
add to the message something more than the message symbol and parameters...I
am trying to add the 'meaning' of the message as scoped in the namespace of
the provided class/module. I am trying to add to the method additional
semantics of what I am asking from the target object. I am sending the
message 'name' with the meaning that 'name' has on a Person object. That
receiver may or may not care...answering the way it wants, but right now I
cannot express that semantics at all.

I guess I am not expressing myself with sufficient semantics :wink:

-rich

-------------------------------------------------------------------------
Web: http://hdl.handle.net/1030.37/1.1
Phone: +33 (0) 4 92 27 74 17

"Richard Kilmer" <rich@infoether.com> schrieb im Newsbeitrag
news:BCEB7E82.B88A%rich@infoether.com...

>
>
>> This is not a continuation of the type thread other than trying to
>> continue
>> to discuss the ideas of adding metadata that could be used to help

the

>> runtime environment of Ruby. Before anyone says anything, I have
>> built lots
>> of Ruby code without this, and the runtime is just fine...think of
>> this as
>> exploration. Disregard all the other syntax I wrote on earlier...and

I

>> do
>> not care whether something is Hash-like, or is_a? Duck :wink:
>>
>> class Person
>> attr_accessor :name
>> end
>>
>> def greet(person)
>> puts "Hello there #{person.<Person>name}"
>> end
>
> Isn't this effectively "to_name" or "as_name"?
>

I am not trying to coerce the object into another representation in

general

(although in the specific example its like that). Generally, I am

trying to

add to the message something more than the message symbol and

parameters...I

am trying to add the 'meaning' of the message as scoped in the namespace

of

the provided class/module.

Well, "meaning" is a difficult term with computers. "meaning" (or
semantic) for a coputer is always syntax. You just add some kind of
symbol to the method invocation which you could transport otherwise, i.e.
as method argument:

o = Object.new

def o.name(expect=nil)
  case expect
    when :Person
      "Rich"
    else
      to_s
  end
end

Alternatively you could do it a bit more behind the scenes via some Thread
local variable that is set somehow before the invocation:

class Object
  alias :method_missing_old :method_missing
  def method_missing(sym, *args, &b)
    new_sym, ctx = sym.to_s.split(/_/, 2)
    method_missing_old(sym, *args, &b) unless ctx

    (Thread.current[:context] ||= ).push( ctx.to_sym )

    begin
      send(new_sym, *args, &b)
    ensure
      Thread.current[:context].pop
    end
  end

  def called_as?(x)
    c = Thread.current[:context]
    c && c[-1] == x.to_sym
  end
end

o = Object.new
def o.name
  if called_as?(:Person)
    "Rich"
  else
    to_s
  end
end

p o.name
p o.name_Person

I am trying to add to the method additional
semantics of what I am asking from the target object. I am sending the
message 'name' with the meaning that 'name' has on a Person object.

That

receiver may or may not care...answering the way it wants, but right now

I

cannot express that semantics at all.

As I tried to demonstrate above, you can in fact express that already.
You merey add a new syntactic construct.

Regardless of all these issues, currently I don't see the real advantage
of this concept. Maybe you can explain a little more thouroughly why you
think it's better than method arguments or something else.

I guess I am not expressing myself with sufficient semantics :wink:

:slight_smile:

Kind regards

    robert

···

On 6/8/04 11:51 AM, "Dave Thomas" <dave@pragprog.com> wrote:
> On Jun 8, 2004, at 9:43, Richard Kilmer wrote: