On 6 July 2011 16:37, Mark Proctor <mproctor(a)codehaus.org> wrote:
The text in this blog has been amended and corrected in several places after
it was sent in this email. In my comments I've been trying to consider these
changes.
-----
Duck typing is the ability to say that something implements an
interface. In this article I'll focus on triples (sets of key value
pairs) such as Maps in Java or Dictionaries in other languages.
An amendment cites the definition of "triples" from the document set
around the Resource Description Framework: RDF triples are
subject-predicate-object expressions. There is no way a (single)
Map is capable of representing RDF triples for more than one
subject and more than one relation. An unrestricted set of
RDF triples requires a Set of Map objects.
The terms map and triple set will be used interchangeably.
Without some clarification such as that a single subject is implied
by a single map
this statement is confusing to the reader.
I'll use MVEL like syntax to demonstrate:
bean = [ name = "Zod", age = 150 ]
bean dons Human
assertEquals( "Zod", bean.name )
assertEquals( 150, bean.age)
Without the don's keyword to duck type the map to the interface this
would not compile as the compiler
Which "compiler" would accept the above without the "dons"
expression?
would report a static typing error of
unknown fields for “name” and “age”.
rule Human when
$tp : Map( this contains [ "name" : String, "age" : int ] )
then
$tp dons Human// that $tp instance is now recognised by all other rules
that match on Human
end
Is this meant to be correct in an existing system? AFAIK, a bracketed
expressions is an MVEL inline Map, but instead of "String" and "int"
we
would need expressions. I would have thought that
$tp.containsKey( "name" ) && $tp.containsKey( "age" )
would be a good test for determining that the Map object is capable of
donning Human.
rule HelloWorld when
$s : Human() // this will actually match against the Map "donned" to
Human
then
println( "hello " + $s.name );
end
We can see the rule that applies the trait can probably have a first
class representation for it's use case.
I do not understand what the previous sentence is trying to express.
What is a "first class representation for it's use case"?
For instance if someone is Human and is also 18 years of age or
younger
we can apply a further abstraction and say the are not just Human but
also a Student. We use the "dons" keyword after the arguments to say the
existing traits the Map must already wear, i.e. abstractions we
already
It may be necessary to be able to specify more than one existing trait in
order
to establish another one?
> know about the thing.
> trait Student( String name, int age ) dons Human when
> age(< 18; )
> end
> The syntax is ugly, but also confusing, since we now also
have field names
acting as pattern "type". Moreover, the hitherto existing type is Human
and I would think that the restriction for donning Student must be based
on a Human's property, hence
trait Human dons Student when
Human( age < 18 )
end
"name" and "age" both have to be represented as
objects the system is
going to bloat fast.
But the String object for "name" and the Integer object
(let's ignore simple types) for "age" must be around in any case?
The relations are what we refer to for
each of the key/value pairs in the triple set, i.e. a property (bean
getter and setter pair, normally on a member field) is a relation on a
class.
A bean property with its getter and setter pair implements a relation
between the bean's class and the property type.
which is generated as an actual class from which beans can be initiated,
“name”, “age” and “gender” are static relations. Young, Boy and
FussyEater are all interfaces.
The example seems to insinuate that only marker interfaces can be added
dynamically.
Is this so?
If not, how would one "don" a trait with properties?
> Human extends TripleSet so that we know
> that further dynamic relations can be added and traits applied. We
> detect the bean instance is “< 18” and thus the trait Young is applied
> and that if the gender is M the trait Boy is applied. Further if a
> property exists, either static or dynamic (the two are seamless in the
> syntax) called “dislikes” with a value of “carrots” we apply the
> FussyEater trait.
> declare Human extends TripleSet
> String name;
> int age;
> Gender gender; // M/F enum
> end<
> s/<//
Deus ex machina! Here class TripleSet is thrown at us, like a bone to a dog.
Don't we deserve a wee bit of explanation?
> trait Young(int age) dons Human when
> age(< 18; )
> en
> trait Boy(Gender gender) dons Young when
> Gender( Gender.M; )
> end
> trait FussyEater(String dislikes) dons Boy when
> dislikes( “carrots”; )
> end
Here suddenly the property
"dislikes" is pulled out of the hat. Is it a
property of Boy?
I realise that "dislikes" is added to Human as a dynamic property, but is it
recognized
in all sorts of Boy as well? If yes, then this implies that I have access to
any property
of the bearer of a donned interface *via that interface.*
Human human = new Human( “Zod”, 16 )
> human.add( [dislikes : “carrots”] )
Method "add" is coming from TripleSet? Semantics?
The argument's Java type is what?
> insert ( human )
> insert( new GiveIceCream( human ) );
> We can now have a single rule that disallows fussy eaters
from getting
> ice cream. How cool is that :)
> rule “Don't give icecream to boys who are fussy
eaters”
> $f : FussyEater()
> $d : GiveIceCream( $f; )
> then
> retract ( $d )
> end