From: Matthias R. <mat...@so...> - 2002-06-03 08:10:56
|
Timothy Hickey wrote: > Jscheme does have a form of multi-methods similar to SISC's > define-method, but rather than > using chaining it lets you bind multiple functions to the same name and > then selects the best match > using dynamic dispatch, Perhaps you misunderstood me. Generic procedures in SISC have methods that get selected based on the argument types - just like in JScheme (and CLOS, Dylan etc etc). Chaining is an additional concept that allows one generic procedure to delegate calls to another generic procedure when it cannot find a suitable match. By default (define-generic foo) will create a "normal" generic procedure to which any methods are added with (define-methd (foo ...) ...), and chain it to a *special* generic procedure containing all Java methods "foo" of all classes. >> * The names of generic procedures by default are mapped to Java method >> names via an "unschemification" conversion, e.g. foo-bar-baz? becomes >> isFooBarBaz. This further blurs the distinction between doing "schemy" >> things and "javay" things. > > This is cute! But its not essential, is it? Couldn't you just as well > have used straight Java syntax here... > Yes. The philosophy behind the S2J interface in SISC is very much one of making Java blend in with Scheme. Another reason is that SISC, by default, is case-insensitive which would make using straight Java names awkward. You can do so by doing something like (define-generic |isFooBar| (generic-java-procedure '|isFooBar|) Note the || notation for case-sensitive symbols. Btw, this example also makes the chaining explicit - the generic-java-procedure call retrieves the generic procedure containing all methods isFooBar of all classes. >> * constructors are generic procedures too. > > ?????????? > Do you use chaining for selecting the appropriate constructor or method > for a straight Java call? > e.g. if there are five different constructors, does SISC select the one > that best matches the arguments > or the one that "first" matches the arguments (with respect to some > ordering...) > ?????????? > Here's an example: (define-constructor (<jstring> (next: next-method) (<jchar> c)) (next-method (->jarray (list c) <jchar>))) (make <jstring>) ;calls Java method (make <jstring> (->jchar #\o)) ;calls scheme method Handling constructors is actually somewhat complex. 'make' maintains a table of generic procedures - one per class. The above example adds a method to one of these, i.e. the generic procedure representing the <jstring> constructors. The generic procedures are chained to generic procedures holding all the Java constructors, again, on a per-class basis. Constructor selection is based on looking up the generic procedure for the constructors of the given class and then doing a normal best-match selection on the methods. >> Note that at the moment SISC generic procedures can only operate on >> Java objects, not Scheme objects (unless, of course, you use their >> Java representation). That will change soon though with the >> introduction of a SISC type system and object system. > > I look forward to seeing this, but it may be confusing having two type > systems (Java and SISC) to consider. I think > Jython has some experience dealing with these issues. > The Java type system frankly isn't good enough for me :) The two type systems will be integrated, i.e. it's going to be just one type system of which the Java types are a part of. >> 4) Many JScheme types map directly to standard Java types, making type >> conversion unnecessary when objects cross the Scheme/Java divide. In >> SISC explicit conversion is needed. > > Indeed, Jscheme is probably best thought of as a Scheme-skin for Java. > It really is programming in Java, > but the syntax is different and some higher order procedure patterns > have been incorporated into the syntax. > We're currentlly working on a syntax for implementing Java classes using > Jscheme, which would complete this > analogy. > I see. I don't think SISC is going to go down the route of class generation. There are obvious limitations to using only reflection, but it fits in better with the SISC philosophy. >> * For some Scheme types, such as numbers, the mapping to Java types is >> one-to-many, e.g. a Scheme number could be converted to a byte, short, >> int, etc. This causes ambiguities when automatic conversion of >> parameters is attempted. > > Makes sense (but couldn't a best fit mapping be made by default, i.e. > choose the smallest applicable type ....) Yes, but when using generic procedures things start to get messy. See the point further down my original list. >> * Some Java types have several corresponding Scheme types, e.g. a Java >> array could be represented as Scheme list or vector - this causes >> ambiguities when automatic conversion of results is attempted. > > The main problem is conversion from Scheme to Java (for procedure > calls), i.e., what do Strings, Lists, > and Vectors maps to. Converting back to Scheme could just do the reverse. The problem is that you start making arbitrary choices and thus taking away choice from the user. Whether I want an array returned "as is", as a list, or as a vector depends on the context. Sure, if the call always returns a vector I can convert things back into an array, or into a list, but a) I end up doing two conversions instead of one, b) in the array->vector->array conversion the object identity of the array is lost. > Conversion is indeed a tricky problem. It seems mandated by the need to > have mutable Strings No. That's just one reason. All the other reasons I mentioned are much more important. > Then you could just use a straight embedding of all > other Scheme objects into Java > by adding the Pair, Procedure, and Continuation classes to the public > Java API for SISC.... > Do you think this might work??? These classes already exist and you can pass unconverted instances to Java by wrapping them, e.g. (println (<jsystem> 'err) (java-wrap '(1 2 3))) I could have made the wrapping implicit, but at the moment it isn't. I might still change my mind on that. Generally, I want to keep the Scheme types distinct from the Java types. That's a different approach to JScheme, but is more suitable for SISC. > Anyway, I want to thank you for taking the time to write this explanation. You are welcome. I've learned a lot more about JScheme in the process. > It helps clarify the similarities and differences. I want to look at the > way we handle define-method, perhaps we should allow it to be > used over javadot names and to let it use the " . rest)" notation > as SISC's define-method does... > I'd encourage you to read the SISC manual and the code. The generic procedure code is actually reasonably portable. > I'm still interested in the possibility of adding javadot notation to SISC. It's possible. You are only saving one line of code per method name though at the expense of having to use the uglier (IMHO ;) Java names. > I think Geoff's suggestions was to look into a way of finding a canonical > method for converting SISC values into Scheme values (e.g. numbers > go to ints if possible, the longs if possible, then doubles, the floats, > then > BigIntegers or BigDecimals, but inexacts always goto doubles, floats, and > BigDecimals. The problem with conversion based on range is that if a Java method is overloaded on, say, byte, int and long then you have no idea which one is going to get called. In many cases this won't matter, because the methods will usually all do the same thing, but not always. Also, note that the numeric types are not sub-types of each other, e.g. int is not a sub-type of long. Since selection of methods from a generic procedure is based on types, automatic conversion to the smallest type will result in failures to find appropriate methods. Java gets around this by performing a widening conversion, which is completely orthogonal to type-conversion (i.e. the implicit casting to a base class) and not a concept I would want to introduce into SISC's type system. > Thus, SISC could support a version of javadot with automatic conversion. > It might even be possible to have javadot and the current SISC/java > interface work concurrently... > Yes. Anyone who wants to implement automatic conversion between Scheme and Java types in SISC this is welcome to do so. I can certainly see the attraction of the idea and perhaps some applications would indeed benefit from it. However, in the general case I believe that it creates more problems than it solves, which is why I decided against this strategy. Matthias. |