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: _posts/2025-10-15-fn-star-talkin-bout-my-generation.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -55,7 +55,7 @@ The `ObjExpr` class maintains the following collections:
55
55
-`ProtocolCallsites`: places where protocol methods are called.
56
56
57
57
58
-
`Constants` contributes static fields to the function class. `Closes` defines the values needed for the constructor of the function class. `KeywordCallsites` and `ProtocolCallsites` also contribute static fields. We'll discuss keyword callsites in [C4: Key in-site][TBD]. We'll discuss protocol callsites in [C4: Is there a protocol for that?][TBD].
58
+
`Constants` contributes static fields to the function class. `Closes` defines the values needed for the constructor of the function class. `KeywordCallsites` and `ProtocolCallsites` also contribute static fields. We'll discuss keyword callsites in [C4: Key in-site]{{site.baseurl}}{% post_url 2025-10-19-key-in-site %}. We'll discuss protocol callsites in [C4: Is there a protocol for that?]{{site.baseurl}}{% post_url 2025-10-20-is-there-a-protocol-for-that %}.
Copy file name to clipboardExpand all lines: _posts/2025-10-16-tag-youre-int.md
+5-5Lines changed: 5 additions & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,7 +13,7 @@ Clojurists by nature are type-loose; they'd prefer not to think about types. Bu
13
13
14
14
The Clojure compiler computes and propagates type information throughout the abstract syntax tree (AST) as it is constructed. These calculations combine user-supplied type hints, characteristics of individual functions (return types, signatures of host platform methods), and inherent characteristics of the each basic expression class.
15
15
16
-
This post explores how typing information is propagated through the AST. In post [Primitive urges][TBD], we will see how the compiler uses this information to avoid boxing of numeric values. How reflection is avoided will be covered in [C4: A time for reflection][TBD].
16
+
This post explores how typing information is propagated through the AST. In post [C4: Primitive urges]({{site.baseurl}}{% post_url 2025-10-17-primitive-urges %}), we will see how the compiler uses this information to avoid boxing of numeric values. How reflection is avoided will be covered in [C4: A time for reflection][TBD].
17
17
18
18
## Just a hint
19
19
@@ -256,7 +256,7 @@ The only remaining `HostExpr` derivative is `InstanceZeroArityCallExpr`. This i
256
256
257
257
That leaves us with `NewExpr`. For `NewExpr`, we know the type we are creating; that gives us our `ClrType`.
258
258
259
-
I'll toss one more in here. Though not derived from `HostExpr`, `StaticInvokeExpr` is just a special case of `StaticMethodExpr` where the method is an `invokeStatic` on an `IFn`-derived class. This node type comes up in direct linking of function calls. For more information, refer to [C4: Functional anatomy]({{site.baseurl}}{% post_url 2025-09-04-functional-anatomy %}) and [C4: fn*: talkin' 'bout my generation][TBD].
259
+
I'll toss one more in here. Though not derived from `HostExpr`, `StaticInvokeExpr` is just a special case of `StaticMethodExpr` where the method is an `invokeStatic` on an `IFn`-derived class. This node type comes up in direct linking of function calls. For more information, refer to [C4: Functional anatomy]({{site.baseurl}}{% post_url 2025-09-04-functional-anatomy %}) and [C4: fn*: talkin' 'bout my generation]({{site.baseurl}}{% post_url 2025-10-15-fn-star-talkin-bout-my-generation %}).
We have a type if either we have a tag or we have an initialization form and _it_ has a type.
351
-
There is a condition above this which negates having a type. In English: if there is an initialization form, and it has a type and its type is a primitive type (this would have to be a tag on the initialization expression), but the initialization expression is not a `MaybePrimitiveExpr` -- something capable of emitting a primitive value -- then we are in trouble. We want to hold a primitive value without boxing, but our initialization is at best going to yield a boxed value. So we say we don't have a type. We discuss primitive types in great detail in [C4: Primitive urges][TBD].
351
+
There is a condition above this which negates having a type. In English: if there is an initialization form, and it has a type and its type is a primitive type (this would have to be a tag on the initialization expression), but the initialization expression is not a `MaybePrimitiveExpr` -- something capable of emitting a primitive value -- then we are in trouble. We want to hold a primitive value without boxing, but our initialization is at best going to yield a boxed value. So we say we don't have a type. We discuss primitive types in great detail in [C4: Primitive urges]({{site.baseurl}}{% post_url 2025-10-17-primitive-urges %}).
352
352
353
353
If we do have a type, a user-supplied tag takes precedence over the type of the initialization expression, per usual.
354
354
@@ -476,7 +476,7 @@ else
476
476
method._retType=typeof(object);
477
477
```
478
478
479
-
By the time you get through this code, `method._retType` is either `typeof(long)`, `typeof(double)`, or `typeof(object)`. Hmmm. Where have we seen this combo before? ODL ... primitive interfaces. We retain just enough information to calculate which prim interface we should implement. (See [C4: Primitive urges][TBD].)
479
+
By the time you get through this code, `method._retType` is either `typeof(long)`, `typeof(double)`, or `typeof(object)`. Hmmm. Where have we seen this combo before? ODL ... primitive interfaces. We retain just enough information to calculate which prim interface we should implement. (See [C4: Primitive urges]({{site.baseurl}}{% post_url 2025-10-17-primitive-urges %}).)
480
480
481
481
We've handled:
482
482
@@ -543,7 +543,7 @@ Does your head hurt yet? I've been whistling past this graveyard for 15 years.
543
543
544
544
## Recur-ing nightmares
545
545
546
-
We've had enough. I'll put off discussion of how type information plays into `RecurExpr` until later. See [C4: Primitive urges][TBD].
546
+
We've had enough. I'll put off discussion of how type information plays into `RecurExpr` until later. See [C4: Primitive urges]({{site.baseurl}}{% post_url 2025-10-17-primitive-urges %}).
Copy file name to clipboardExpand all lines: _posts/2025-10-17-primitive-urges.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -49,7 +49,7 @@ A given instance of a `MaybePrimitiveExpr`-implementating class may or may not b
49
49
50
50
For most of these, the computation of `CanEmitPrimitive` is straightforward. For example, `NumberExpr` can always emit a primitive value; it can emit only `long` and `double` values. Whether a `BodyExpr` can emit a primitive value depends on whether its last expression can emit a primitive value. `HostExpr`-derived classes can emit a primitive value if they are not reflections: we have the explicit `MethodInfo`/`PropertyInfo`/`FieldInfo` to work with and the return type of that is primitive. Many of the others have an explicit return type calculated; `CanEmitPrimitive` is true if that type is primitive.
51
51
52
-
The most complicated formula for `CanEmitPrimitive` is in `IfExpr`. We need both the 'then' and the 'else' expressions to be `MaybePrimitiveExpr`. They both must have `CanEmitPrimitive` be true, and they must be of the same primitive type -- or one of them can have a return type of type `Recur.RecurType`. You might recall from [C4: Tag! You're int!][TBD] that `Recur.RecurType` is a special type used as the return type of a `RecurExpr`. The only reason `RecurExpr` implements `MaybePrimitiveExpr` is to make this code work:
52
+
The most complicated formula for `CanEmitPrimitive` is in `IfExpr`. We need both the 'then' and the 'else' expressions to be `MaybePrimitiveExpr`. They both must have `CanEmitPrimitive` be true, and they must be of the same primitive type -- or one of them can have a return type of type `Recur.RecurType`. You might recall from [C4: Tag! You're int!]({{site.baseurl}}{% post_url 2025-10-16-tag-youre-int %}) that `Recur.RecurType` is a special type used as the return type of a `RecurExpr`. The only reason `RecurExpr` implements `MaybePrimitiveExpr` is to make this code work:
53
53
54
54
```c#
55
55
_thenExprisMaybePrimitiveExprtExpr
@@ -291,7 +291,7 @@ Just doing a rough timing in a loop, `calling2` is about 5x as fast as `calling1
291
291
292
292
## Intrinsics
293
293
294
-
Why `fp` has a direct IL `add` instruction but `fb` has to go through `Numbers.add` is a story worthy of its own post. See [C4: Inline skating][TBD].
294
+
Why `fp` has a direct IL `add` instruction but `fb` has to go through `Numbers.add` is a story worthy of its own post. See [C4: Inline skating]({{site.baseurl}}{% post_url 2025-10-18-inline-skating %}).
Copy file name to clipboardExpand all lines: _posts/2025-10-18-inline-skating.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ Inlining allows the compiler to replace some function calls with direct code ins
9
9
10
10
After the heavy lifting of the last few posts, this post is just a little palate cleanser.
11
11
12
-
In [C4 - Primitive urges][TBD], we looked at how unnecessary boxing of primitive types can be avoided. That is accomplished by signficant compiler magic spread over a large number of classes.
12
+
In [C4: Primitive urges]({{site.baseurl}}{% post_url 2025-10-17-primitive-urges %}), we looked at how unnecessary boxing of primitive types can be avoided. That is accomplished by signficant compiler magic spread over a large number of classes.
13
13
14
14
In contrast, inlining and intrinsic operations are very localized and easy to understand.
15
15
@@ -140,7 +140,7 @@ Inlining will help us. `f` will compile directly to a call to `clojure.lang.Num
140
140
141
141
Therearealotofoverloadsof `Numbers.add` tohandledifferenttypesofarguments.Inthiscase, becausewedonothavemorespecifictypeinformationabout `x` and `y`, wewillendupcallingtheversionthattakestwo `object` arguments.Thiswillresultinboxingif `x` and `y` areprimitivetypevalues, andabunchoftypecheckinganddispatchinginside `Numbers.add`.
142
142
143
-
Welearnedin [C4 - Primitive urges][TBD]howtoavoidboxing.Ifwerestrictthetypesof `x` and `y` to, say, `double`, wecanavoidboxing:
143
+
Welearnedin [C4: Primitive urges]({{site.baseurl}}{% post_url 2025-10-17-primitive-urges %})howtoavoidboxing.Ifwerestrictthetypesof `x` and `y` to, say, `double`, wecanavoidboxing:
0 commit comments