This project is read-only.

Casting to interface and previous repl value.

Jan 27, 2010 at 6:08 PM

Some quick questions! Is there any way to get the previous REPL value. I know in lisp i use *, *, and *** to retrieve the three previous values returned. It would be nice for an interactive repl to incorporate this functionality.

Also, is there any way to cast an object to an interface? Im using a method which returns an Object which must then be cast to

an ITradeDeskAut interface. When i attempt to do this the type of the object remains System.__ComObject. I could then attempt to

call a method on it, which would work if i wanted to use clr-call, but I would like to use my shorthand form which uses reflection. I can only use this if the type of the object is

the correct type, not if it remains a general System.__ComObject!

Any ideas?

Jan 27, 2010 at 6:30 PM


Can I assume you sorted out the interface issue?  :)

Maybe I can provide the previous value(s) functionality via a user-supplied eval hook?




Jan 27, 2010 at 9:51 PM

Thatd be great! Then we could create our own functions to keep track of however many previous values we wanted. I suppose something like

(let ((previous-vals ...)) (add-eval-hook (lambda ...)) (lambda (amount-back-to-get) ...)) Though then we would need an initialization file to put that code in that is loaded on startup.

Technically, i haven't really sorted out the interface issue. To give you a general picture, i have my two little functions:

(defn (create-trade-desk) (cast ITradeDeskAut (: CreateTradeDesk (cast CoreAut (new CoreAutClass)) "trader"))) ;;<--- casting does nothing
(defn (login user pass
         (connection "Real")
         (url ""))
  (assert (or (equal? connection "Demo")
          (equal? connection "Real")))
  (let ((trade-desk (create-trade-desk)))
    (: Login trade-desk user pass url connection)

The : function uses the (ironscheme clr dynamic) library and memoization to call the members of an object. However. (create-trade-desk) returns an object of type System.__ComObject. This makes sense because

the CreateTradeDesk method returns an object. However, when i attempt to cast it to the interface ITradeDeskAut, nothing happens: it still remains a System.__ComObject. Coming down to the (: Login) method an error is thrown:

(login "sdf" "sdf")
Unhandled exception during evaluation:
&who: clr-call-site
&message: "no candidates found for method"
&irritants: (Login #<clr-type System.RuntimeType "System.__ComObject">)

Which wouldn't happen if the cast had been successful. I can 'get around' this by changing the (: login) line to

(clr-call ITradeDeskAut Login trade-desk ...) which works. However I would prefer to cast it once and then let reflection do its thing.

As a mini test i tried to do this:

(cast CoreAut (new CoreAutClass))

but it again returns

#<clr-type FXCore.CoreAutClass>

While it should now be of type CoreAut. In the c# code they succesfully do the casts, but in this scheme code the casts aren't working.

Now I really dont know too much about c#, in fact im learning only via interfacing it with ironscheme, so there must be something I'm missing!


Jan 28, 2010 at 5:35 AM


Casting does not change the type of an object. It only says, we have some unknown type, but I believe it to be of a certain type (or any derived type) or it implements an interface.

Example, in .NET System.String implements IEnumerable, but even when you cast it to IEnumerable, the type still stays a string.

Same goes for something like a System.Windows.Forms.Form. You can cast it to a Control, but it still stays a Form.

To use reflection on such a type, calling it's interface methods, you will need to get the type of the object, then enumerate through all it's interfaces too when looking up a method.

Does that make sense to you?



PS: I will look into an eval-hook over the weekend/next week.

Jan 28, 2010 at 2:12 PM

It does. Basically i have to specify the type every time or store it somehow. I think i will change cast to memoize its type.  On another topic, wouldn't it be great if we could inline c# code into our programs? Hmm, i wonder how hard that would be, emitting the c# code from a text string....