Short answer: It's a bug.
Longer answer:  It's a problem with type propagation in let.  It'll
take me a day or so to fix it.

The handling of non-primitive value types by the compiler still has
some problems. Any place where the JVM compiler is discriminating
between primitive types and reference types, the CLR compiler needs to
discriminate between primitive types, non-primitive value types and
reference types.  I need to make a pass back through the compiler code
and make sure I catch all the places where it matters.  I'll put this
at the top of the list.

Boring detail for the very curious: At the moment, your (a) works
because it uses reflection and (a2) fails because it is trying to do
the right thing.  The (doto) expands into a let that introduces a box
followed by a cast that causes the struct to be copied.  The .Scale is
applied to the copy.  That's why you don't see the change.  In C#, the
compiled code looks like:

(a) looks like:
    object target = new Matrix();
    object[] args = new object[] {2.0, 3.0 };
    Reflector.CallInstanceMethod("Scale", target, args);
    return target;

(a2) looks like:

   object obj2 = new Matrix();
    ((Matrix) obj2).Scale(2.0, 3.0);
    return obj2;

I need to make (a2) look like:

   Matrix obj2 = new Matrix();
    obj2.Scale(2.0, 3.0);
    return obj2;


-David




On Sep 29, 9:55 am, Shawn Hoover <shawn.hoo...@gmail.com> wrote:
> Updates to local CLR struct instances seem to be lost as soon as they're
> made. Is this expected? In the test below, function a2 returns the identity
> matrix despite my attempt to scale it. Function a passes the newly
> constructed matrix to another function to do the scaling, and it returns the
> scaled matrix as desired. UriBuilder is a class and works either way.
>
> (System.Reflection.Assembly/Load "WindowsBase, Version=3.0.0.0,
> Culture=neutral, PublicKeyToken=31bf3856ad364e35")
> (import '(System.Windows.Media Matrix))
> (import '(System UriBuilder))
>
> ; Test struct
> (defn b [matrix] (doto matrix (.Scale 0.5 -0.5)))
> (defn a [] (b (Matrix.)))
>
> (defn a2 [] (doto (Matrix.) (.Scale 0.5 -0.5)))
>
> ; Test class
> (defn b3 [builder] (doto builder (.set_Port 9090)))
> (defn a3 [] (b3 (UriBuilder.)))
>
> (defn a4 [] (doto (UriBuilder.) (.set_Port 9090)))
>
> (println "Matrix struct" (a) (a2)
>          (= (a) (a))
>          (= (a2) (a2))
>          (= (a) (a2))) ; True True False
> (println "UriBuilder class "(a3) (a4)
>          (= 9090 (.Port (a3)) (.Port (a3)))
>          (= 9090 (.Port (a4)) (.Port (a4)))
>          (= 9090 (.Port (a3)) (.Port (a4)))) ; True True True
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.com
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
clojure+unsubscr...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to