You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _drafts/2024-08-05-qualified-methods-for-ClojureCLR.md
+51-71Lines changed: 51 additions & 71 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,19 +1,19 @@
1
1
---
2
2
layout: post
3
-
title: Qualfied methods -- for ClojureCLR
4
-
date: 2024-08-05 00:00:00 -0500
3
+
title: Qualified methods -- for ClojureCLR
4
+
date: 2024-09-05 00:00:00 -0500
5
5
categories: general
6
6
---
7
7
8
-
Clojure has introduced a new _qualified methods_ feature allows for Java methods to be passed to higher-order functions. This feature also provides alternative ways to invoke methods and constructors, and new ways to specify type hints. We need to enhance this mechanism for ClojureCLR in the same way we enhanced 'classic' interop.
8
+
Clojure has introduced a new _qualified methods_ feature allows for Java methods to be passed to higher-order functions. This feature also provides alternative ways to invoke methods and constructors, and new ways to specify type hints. We need to enhance this mechanism for ClojureCLR in the same ways we enhanced 'classic' interop.
9
9
10
10
I'll start with a quick review of 'classic' interop, including the additions made for interop with the CLR.
11
-
I'll introduce the new qualified methods mechanism.
11
+
I'll (quickly) survey the new qualified methods mechanism.
12
12
I'll conclude with looking at how the CLR extras will be incorporated in the new mechanism.
13
13
14
14
# 'Classic' interop
15
15
16
-
I'm going to assume basic familiarity with interoperabiltiy with the JVM/CLR, at least prior to the introduction of qualified methods. If you need a refresher, you can look at the [Java interop section](https://clojure.org/reference/java_interop) of the Clojure reference.
16
+
I'm going to assume basic familiarity with interoperabiltiy with the JVM/CLR (prior to the introduction of qualified methods). If you need a refresher, you can look at the [Java interop section](https://clojure.org/reference/java_interop) of the Clojure reference.
17
17
18
18
There are several pages on the ClojureCLR wiki that talk about the additional features of CLR interop:
19
19
@@ -35,7 +35,24 @@ Symbols that represent the names of types are resolved to `Type` objects.
35
35
36
36
Classes can be `import`ed into a Clojure namespece so that the namespace of the type can be omitted, as with `String` above. (There is a default set of imports that are always available. See the note at the end for how that set is computed.)
37
37
38
-
There are types in the CLR that can not be named by symbols. (I guess Java does not yet have this problem.) See the note at the end for a few comments about this.
38
+
## Interlude: Specifying type names
39
+
There are types in the CLR that can not be named by symbols, or at least symbols that the Lisp reader can parse. (I guess Java does not yet have this problem.) See the note at the end for a few comments about this. The
40
+
[specifying types](https://github.com/clojure/clojure-clr/wiki/Specifying-types) page explains how we get around this. It is just ugly. The mechanism ties directly into the CLR's type naming and resolution machinery, thus:
You have to include fully-qualified type names, generics include a backtick and the number of type arguments, and the type arguments are enclosed in square brackets.
47
+
48
+
> I plan to introduce a new syntax for this in ClojureCLR.Next that would take advantage of imports and be otherwise nice.
49
+
When I designed the `|...|` syntax (stolen from CommonLisp), Clojure did not yet have _tagged literals_. Now we might be able to do something like
50
+
>
51
+
```
52
+
#type "IList<int>"
53
+
```
54
+
>
55
+
> (If you are interested in helping to design this, please let me know.)
39
56
40
57
## Member access
41
58
@@ -58,59 +75,53 @@ For CLR interop, we had to add some additional functionality, primarily for call
58
75
If you are familiar with C#, you have seen `ref`, `in`, and `out` used in method signatures. There is no distinction of these at the CLR level. C# adds `in` and `out` for additional compile-time analysis. Given that we don't have uninitialized variables in Clojure and that CLR doesn't distinguish, ClojureCLR only provide a `by-ref` mechanism. The example given on the wiki page looks at a class defined by:
To call `m3` with a `ref` argument, you would use:
88
+
To call `Out` with a `ref` argument, you would use:
71
89
72
90
```clojure
73
-
(let [n (int n) ]
74
-
(.m3 c (by-refn)))
91
+
(let [m (intn) ]
92
+
(.outc (by-refm)))
75
93
```
76
94
77
95
The type hint provided by the `(intn)` is required -- otherwise the it will try to match a `ref object` parameter.
78
96
79
-
The `by-ref` is a syntactic form that can only be used at the top-level of interop calls, as shown here. It can only wrap a local variable. (`by-ref` can also be used in `definterface`, `deftype`, and the like.) And yes, the value of the local variable `n` is updated by the call -- yep, that binding is not immutable. You do not want to know how this is done.
97
+
The `by-ref` is a syntactic form that can only be used at the top-level of interop calls, as shown here. It can only wrap a local variable. (`by-ref` canalsobeused in `definterface`, `deftype`, andthe like.) And yes, the value of the local variable `n` is updated by the call -- that binding is not immutable. You do not want to know how this is done.
In addition, strictly for my own convenience for dealing with 'core.clj' and other startup files, I add `System.Text.StringBuilder`, `clojure.lang.BigInteger` and `clojure.lang.BigDecimal`. (I'll change `clojure.lang.BigInteger` to `System.Numerics.BigInteger` in the ClojureCLR.Next.)
313
-
314
-
315
-
## Note: Specifying type names
316
-
317
-
The
318
-
[specifying types](https://github.com/clojure/clojure-clr/wiki/Specifying-types) page explains how we get around this. It is just ugly. The mechanism ties directly into the CLR's type naming and resolution machinery, thus:
You have to include fully-qualified type names, generics include a backtick and the number of type arguments, and the type arguments are enclosed in square brackets.
325
-
326
-
I plan to introduce a new syntax for this in ClojureCLR.Next, that would take advantage of imports and be otherwise nice.
327
-
When I designed the `|...|` syntax (stolen from CommonLisp), Clojure did not yet have _tagged literals_. Now we might be able to do something like
328
-
329
-
#type "IList<int>"
330
-
331
-
(If you are interested in helping to design this, please let me know.)
332
-
312
+
Inaddition, strictlyformyownconveniencefordealingwith 'core.clj' andotherstartupfiles, Iadd `System.Text.StringBuilder`, `clojure.lang.BigInteger` and `clojure.lang.BigDecimal`. (I'llchange `clojure.lang.BigInteger` to `System.Numerics.BigInteger` inClojureCLR.Next.)
0 commit comments