Expressing intent in method calling...

R

Richard Kilmer

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 ;-)

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
 
C

Curt Hibbs

Richard said:
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 ;-)

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).

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
 
D

Dave Thomas

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 ;-)

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"?


Cheers

Dave
 
J

Jeff Mitchell

--- Dave Thomas said:
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.





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

David A. Black

Hi --

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
 
R

Richard Kilmer

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 ;-)

-rich
 
R

Richard Kilmer

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.

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
 
J

Jean-Hugues ROBERT

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 ;-)

-rich

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
 
R

Robert Klemme

Richard Kilmer said:
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 ;-)

:)

Kind regards

robert
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top