[nem-en] Late Binding in Nemerle
Tobias Linsefors
tobias.linsefors at telia.com
Wed Jul 5 10:32:58 CEST 2006
l have been loking a bit at this and I want to give some support to the
"late member access" operator.
It works good except for writing (to propertys or fields)
!. used as late member operator as I assositate -> with functions as it is used in function types
#pragma indent
using Nemerle.Compiler
using BF = System.Reflection.BindingFlags
[assembly: Nemerle.Internal.OperatorAttribute ("Nemerle.Core", "!.", false, 285, 286)]
set namespace LateBinding
macro @!. (a, b)
def (var, flags, args) = match (b)
| <[ $(x : dyn)(.. $args) ]> => (x, BF.InvokeMethod, args)
| <[ $(x : dyn)[.. $args] ]> => (x, BF.GetProperty, args)
| <[ $(x : dyn) ]> => (x, BF.GetField | BF.GetProperty, [])
| e => Message.FatalError ($ "Not suported $e")
<[
def args = array[..$args] : array[object];
def e = $a;
e.GetType().InvokeMember($(var : string), $(flags : enum), null, e, args)
]>
def o : object = "teststring"
def b = o!.StartsWith("test") :> bool
def c = o!.Chars[1] :> char
def l = o!.Length :> int
// tested
obj!.Prop = 1 // don't work
> def obj = Create() : object;
> late {
> def x = obj.Bar();
> x.Foo();
> }
>
> late obj.Baz();
> def y = late (obj.Prop) :> int;
would be
def obj = Create() : object
def x = obj!.Bar()
_ = x!.Foo()
_ = obj!.Baz()
def y = obj!.Prop :> int
You can add suport for
obj!.Prop = 1
by using a more unnatural operator precedence
but it will make it force you to use extra () in the other cases
there is no support for ref, out, or named parameters
----- Original Message -----
From: "Kamil Skalski" <kamil.skalski at gmail.com>
To: <devel-en at nemerle.org>
Sent: Tuesday, July 04, 2006 6:16 PM
Subject: Re: [nem-en] Late Binding in Nemerle
> The "late member access" operator is a nice idea. It is easy to
> implement for fields, but there is a bit problem for method
> invocations, because
>
> foo.bar ()
>
> is parsed as (foo.bar) () and later processed by compiler in a
> proper way. In case of
>
> foo -> bar ()
>
> macro -> would transform foo->bar into MemberAccess (foo, "bar") and
> its value would be then applied to (), instead of Invoke (foo,
> "bar").
>
> From all propositions I mostly like the similarity to 'checked' /
> 'unchecked' keywords:
>
> def obj = Create() : object;
> late {
> def x = obj.Bar();
> x.Foo();
> }
>
> late obj.Baz();
> def y = late (obj.Prop) :> int;
>
> So the late applies always to what is given inside of it or the next
> expression (in case of 'late expr').
>
>
> 06-07-04, NoiseEHC <NoiseEHC at freemail.hu> napisał(a):
>> Why do not create an operator which translates to late(expr) ?
>> BTW I do not have an idea whether it is possible with macros.
>>
>> VB used !, but it would conflict with Nullable<> it it would be
>> implemented fully.
>> Probably -> would suffice (o->SomeFunc(o->Prop1, o->Prop2 )
>> I do not know anything how hard it would be but certainly looks better...
>>
>> Snaury wrote:
>> > Well, it *is* possible, however, imagine you want to do:
>> >
>> > late(o).SomeFunc(late(o).Prop1, late(o).Prop2)
>> >
>> > If we translate it to this style of macro, it will be:
>> >
>> > late {
>> > o.SomeFunc(o.Prop1, o.Prop2)
>> > }
>> >
>> > So far so good, we good scan inner levels as well (it's complicated
>> > though). Now something harder:
>> >
>> > late {
>> > o.SomeFunc(p.Prop1, p.Prop2)
>> > }
>> >
>> > How to determine if you want late(p).Prop1 or p.Prop1 here? Actually,
>> > I now have an idea to rewrite macro so that it would be easier:
>> >
>> > late o.foo().bar
>> > late o.SomeFunc(late o.Prop1, late o.Prop2)
>> > late give_me_o().foo()
>> > late (give_me_a().give_me_o()).foo()
>> >
>> > and the like.
>> >
>> > On 7/3/06, Kamil Skalski <kamil.skalski at gmail.com> wrote:
>> >> I would rather stay with macro like
>> >> late {
>> >> obj.foo ().bar
>> >> }
>> >>
>> >> and not touch type system.
>> >>
>> >> 2006/7/3, Snaury <snaury at gmail.com>:
>> >> > VB.NET does it by forwarding all unresolved calls on object to their
>> >> > static method on LateBinding class (in Microsoft.VisualBasic
>> >> > assembly), which does a lot of magic, has their own binder (which
>> >> > seems to allow constructs like o.Property[a, b] to decide if Property
>> >> > is direct indexer or something returning object that further needs
>> >> > calling default indexer, and which seems to check and make sure that
>> >> > positional parameters are always positional, unlike just "unnamed" as
>> >> > they are in my macro).
>> >> >
>> >> > Boo does it by having a specialized subimplementation of their
>> >> > ExternalType which somewhat like marks object as being duck type (and
>> >> > it then further processed). I think for Nemerle it is also possible,
>> >> > but I don't completely grok compiler to understand where it should be
>> >> > done. First thing seems like adding MType.Duck, but where it should be
>> >> > processed and all the rest - I don't yet know...
>> >> >
>> >> > I did it as a macro because a) it was simpler b) didn't want to call
>> >> > religious wrath ("he touched our compiler with his dirty hands!") if
>> >> > idea would be disliked. :)
>> >> >
>> >> > On 7/3/06, Alejandro Serrano <trupill at yahoo.es> wrote:
>> >> > > Maybe we could see how the Microsoft VB.NET compiler implements late
>> >> > > binding (mostly using Reflection at run-time) or also take some
>> >> ideas
>> >> > > from Boo, so we could have something like:
>> >> > >
>> >> > > late
>> >> > > {
>> >> > > def n = SomeActiveXControl ();
>> >> > > n.Method ();
>> >> > > }
>> >> > >
>> >> > > or maybe
>> >> > >
>> >> > > def n : duck = SomeActiveXControl ();
>> >> > > n.Method () <- every call in a 'duck' type would use late binding
>> >> > >
>> >> > > Kamil Skalski escribió:
>> >> > > > Generating such proxy classes should be relatively easy using a
>> >> macro.
>> >> > > > def x = dynamic_implement (obj, IFoo, IBar, IWazz);
>> >> > > > x.foo();
>> >> > > > x.bar();
>> >> > > >
>> >> > > > would be quite nice. :)
>> >> > > >
>> >> > > > dynamic_implement would generate a class implementing IFoo, IBar,
>> >> > > > IWazz (maybe doing some caching to avoid generating the same proxy
>> >> > > > classes several times) and create its instance.
>> >> > > >
>> >> > > > 2006/7/2, Arthur Peters <amp at singingwizard.org>:
>> >> > > >> This is quite cool. I've been a Python programmer in the past
>> >> so the
>> >> > > >> ability to do duck typing when needed could be really nice.
>> >> > > >>
>> >> > > >> I ran across a page about duck typing in Java. It provides a
>> >> class that
>> >> > > >> can take an object and return a proxy object that implements an
>> >> > > >> interface you give even if the original object did not.
>> >> > > >> ( http://www.coconut-palm-software.com/the_visual_editor/?p=25 )
>> >> > > >>
>> >> > > >> This seems like it could be nice in addition to your macro,
>> >> because it
>> >> > > >> would allow you to pass the proxy into places that don't know
>> >> about the
>> >> > > >> whole duck typing thing. Also it provides a middle ground: You
>> >> can
>> >> > > >> access functions based on only name and signature and you have
>> >> the type
>> >> > > >> safety provided by a defined interface.
>> >> > > >>
>> >> > > >> I think it would be possible in .NET, but it looks complicated
>> >> because
>> >> > > >> you would need to generate IL opcodes to create the proxy.
>> >> > > >>
>> >> > > >> If people think this would be useful I will take a crack at
>> >> implementing
>> >> > > >> it.
>> >> > > >>
>> >> > > >> Thanks for the good work, everyone!
>> >> > > >> -Arthur
>> >> > > >>
>> >> > > >> On Sat, 2006-07-01 at 18:33 +0400, Snaury wrote:
>> >> > > >> > Hi everyone,
>> >> > > >> >
>> >> > > >> > I was trying to grok nemerle's macros for some time when an
>> >> idea
>> >> > > >> > suddenly popped in my mind how I could do late binding aka
>> >> dynamic
>> >> > > >> > typing aka duck typing in a pretty simple and (maybe?) rich
>> >> way. So I
>> >> > > >> > wrote a macro for this, source code here:
>> >> > > >> > http://www.furry.ru/kitsu/nemerle/Kitsu.LateBindingMacro.n.txt
>> >> > > >> >
>> >> > > >> > It allows to use late binding on (I think) any expression,
>> >> you just
>> >> > > >> > have to wrap it with late, and use like this:
>> >> > > >> >
>> >> > > >> > late(expr).CallMe(param1, param2, param3).CallOtherMe(param,
>> >> param,
>> >> > > >> > param).Property[param, param, param] = value
>> >> > > >> >
>> >> > > >> > It also supports ref/out and named parameters:
>> >> > > >> >
>> >> > > >> > late(expr).CallMe(namedparameter = ref variable, out
>> >> variable, and
>> >> > > >> > the like...)
>> >> > > >> >
>> >> > > >> > though one needs to be very careful with named parameters,
>> >> because
>> >> > > >> > when you name a parameter, other (unnamed) parameters might get
>> >> > > >> > shifted, for example in function:
>> >> > > >> >
>> >> > > >> > public void SomeFunc(a : int, b : int) : void
>> >> > > >> >
>> >> > > >> > when you use
>> >> > > >> >
>> >> > > >> > late(obj).SomeFunc(v1, a = v2)
>> >> > > >> >
>> >> > > >> > SomeFunc will be called as SomeFunc(v2, v1), i.e. it won't
>> >> produce any
>> >> > > >> > errors, it would just silently accept it.
>> >> > > >> >
>> >> > > >> > Also, there's not much error checking there (and to be
>> >> honest I don't
>> >> > > >> > even know how I can do more error checking from within a
>> >> macro), and
>> >> > > >> > if something goes wrong, you'll probably won't even know
>> >> where exactly
>> >> > > >> > error happend, none the less I was extremely amazed at WHAT
>> >> I could do
>> >> > > >> > with Nemerle's macro syntax so I though I'd share it with
>> >> other people
>> >> > > >> > like me, who might really need to use late binding in their
>> >> programs.
>> >> > > >> > =^_^=
>> >> > > >> >
>> >> > > >> > Now I can say it even more: Nemerle Rocks!
>> >> > > >> >
>> >> > > >> > P.S.
>> >> > > >> > If someone can help me to improve it, help in form of
>> >> patches would be
>> >> > > >> > greatly appreciated :)
>> >> > > >> >
>> >> > > >> > P.P.S.
>> >> > > >> >
>> >> > > >> > When I was searching the net on any info about duck typing
>> >> in Nemerle
>> >> > > >> > I occasionaly found this particular statement:
>> >> > > >> >
>> >> > > >> > http://nemerle.org/irc/nemerle-2006-01-09
>> >> > > >> > 13:50 <malekith> the main differences between boo and
>> >> nemerle is that
>> >> > > >> > we do not allow dynamic typing to sneak at without notice,
>> >> we have
>> >> > > >> > better support for metaprogramming (quotations) and compiler
>> >> written
>> >> > > >> > in Nemerle (booc is in C#)
>> >> > > >> >
>> >> > > >> > After reading it I'm even a little scared if my idea of
>> >> dynamic typing
>> >> > > >> > would be met with knifes and banished like something evil.
>> >> All I'm
>> >> > > >> > trying to do is to give power when one needs it, especially
>> >> when one
>> >> > > >> > *really* needs it. x_x
>> >> > > >> >
>> >> > > >> > _______________________________________________
>> >> > > >> > https://nemerle.org/mailman/listinfo/devel-en
>> >> > > >>
>> >> > > >>
>> >> > > >> _______________________________________________
>> >> > > >> https://nemerle.org/mailman/listinfo/devel-en
>> >> > > >>
>> >> > > >
>> >> > > >
>> >> > >
>> >> > >
>> >> > >
>> >> > > ______________________________________________
>> >> > > LLama Gratis a cualquier PC del Mundo.
>> >> > > Llamadas a fijos y m?viles desde 1 c?ntimo por minuto.
>> >> > > http://es.voice.yahoo.com
>> >> > >
>> >> > >
>> >> > > _______________________________________________
>> >> > > https://nemerle.org/mailman/listinfo/devel-en
>> >> > >
>> >> >
>> >> > _______________________________________________
>> >> > https://nemerle.org/mailman/listinfo/devel-en
>> >> >
>> >> >
>> >> >
>> >>
>> >>
>> >> --
>> >> Kamil Skalski
>> >> http://nazgul.omega.pl
>> >>
>> >> _______________________________________________
>> >> https://nemerle.org/mailman/listinfo/devel-en
>> >>
>> >>
>> >>
>> > ------------------------------------------------------------------------
>> >
>> > _______________________________________________
>> > https://nemerle.org/mailman/listinfo/devel-en
>> >
>>
>> _______________________________________________
>> https://nemerle.org/mailman/listinfo/devel-en
>>
>
>
> --
> Kamil Skalski
> http://nazgul.omega.pl
>
> _______________________________________________
> https://nemerle.org/mailman/listinfo/devel-en
>
More information about the devel-en
mailing list