Runtime Type Collection and its usage in Code Transpiling

esug 35 views 31 slides Oct 07, 2024
Slide 1
Slide 1 of 31
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9
Slide 10
10
Slide 11
11
Slide 12
12
Slide 13
13
Slide 14
14
Slide 15
15
Slide 16
16
Slide 17
17
Slide 18
18
Slide 19
19
Slide 20
20
Slide 21
21
Slide 22
22
Slide 23
23
Slide 24
24
Slide 25
25
Slide 26
26
Slide 27
27
Slide 28
28
Slide 29
29
Slide 30
30
Slide 31
31

About This Presentation

Talk from IWST 2024: "Runtime Type Collection and its usage in Code Transpiling"

PDF: http://archive.esug.org/ESUG2024/iwst-day1/04-pavel-typeCollection.pdf


Slide Content

Pavel Krivanek, Richard Uttner

> error detection
> facilitation of code refactoring
> documentation
> information source for JIT
> code transpiling *)
*) our motivation
static typing
Pavel Krivanek, Richard Uttner

> optional static typing
> grammar extensions
> fastest Smalltalk of its time
> BSD license

Strongtalk
Pavel Krivanek, Richard Uttner

> no standard syntax for optional types
> pragmas (Bloc...)
> laborious to annotate

Pharo
Pavel Krivanek, Richard Uttner

> collect during runtime
> inference of the rest *)
> generate annotations
> repeat, keep them up-to-date
*) RoelTyper (https://github.com/RMODINRIA/RoelTyper )

type annotations
Pavel Krivanek, Richard Uttner

occurrencesOf: o
<arg: #o type: Object>
<returns: #Integer>
<var: #c type: #Integer>
<blockArg: #e type: #Object>
| c |
c := 0.
self do: [ :e | e = o ifTrue:[ c := c + 1 ]].
^c
our pragmas
occurrencesOf: o <Object> ^<Int>
| c <Int> |
c := 0.
self do: [ :e <E> | e = o ifTrue:[ c := c + 1 ]].
^c
Strongtalk
Pavel Krivanek, Richard Uttner

> require distinct names
> name prefixes (block number)
<blockArg: #_1_each type: #Integer>
<blockArg: #_2_each type: #Point>

block arguments
Pavel Krivanek, Richard Uttner

> similar to method-level annotations
_slotTypes
<slot: #commandContext type: #CommandContext>
<slot: #labelString type: #String>

class-level annotations
Pavel Krivanek, Richard Uttner

<var: #temp type: #Symbol>
<var: #temp type: #(Symbol Number)>
<var: #temp type: #(Symbol UndefinedObject)>
<var: #temp type: #Symbol::> *)
*) unfortunatelly, #Symbol? Is not available
simple types
Pavel Krivanek, Richard Uttner

#(Array of Symbol)
#(Dictionary of Symbol keys Object)
#(Association key Symbol value Number)
#(Array of (Number String))
#(Array of (Array of String))

complex types
Pavel Krivanek, Richard Uttner

> assigned to variables:
#FullBlockClosure
#(FullBlockClosure returning Integer)
#(FullBlockClosure:: arguments #(Integer #(Number Fraction)))
#(FullBlockClosure arguments #(String Object) returning Integer)

block types
Pavel Krivanek, Richard Uttner

> for literals, is the block void or actually used?
“ ”
> resolving type of an existing object (block)
> select: vs. do:
> required for translation to lambdas
<block: 1 returnsValue: false>

block types
Pavel Krivanek, Richard Uttner
argument type specified
by blockArg: pragma

> install Metalinks on
* all types of variable assignments
* method beginning, return

runtime type collecting
Pavel Krivanek, Richard Uttner

> detect and store object class on each invocation
> slow for complex types (Dictionary...)
> post-processing
> write annotations

runtime type collecting
Pavel Krivanek, Richard Uttner

> generated:
<arg: #anObject type: Object generated: true>
> fixed by programmer:
<arg: #anObject type: Object>
<arg: #anObject type: Object generated: false>
type annotations
Pavel Krivanek, Richard Uttner

> custom block closure subclass
> swap blocks with custom #value, value: methods

returning proxy
> detect assignment of this proxy or calling a message to
it
> become:

block return value usage
detection
Pavel Krivanek, Richard Uttner

> experiment with translation to C#
* class based object-oriented
* GC
* keyword arguments
* closures (lambdas since 2005)

usage for transpilation
Pavel Krivanek, Richard Uttner

> notable differences
* statically typed
(with type inference)
* more complex grammar
* different standard library

Pavel Krivanek, Richard Uttner

self next. Next;
3+4*5 (3+4)*5
= Equals()

unary and binary messages
Pavel Krivanek, Richard Uttner

chooseFrom: aList title: aString
ChooseFrom(someList, title: actualTitle);
public long ChooseFrom(object aList, string title /* aString */ )
{
var aString = title;


}
keyword messages
Pavel Krivanek, Richard Uttner
method header in
Pharo
in C#
Implementation in C#
keyword used as the
argument name

> ifTrue:, ifFalse:, ifNil:, ifEmpty:, whileTrue:, do:
* use C# statements
> others are forbidden (Pharo code refactoring needed)
> tools to detect
> exceptions in the future

non-local returns
Pavel Krivanek, Richard Uttner

> Pharo: uses statement-like expressions without limits
> C#:
* only expressions like ?:, ??
* cannot include statements
> during transpilation, mark AST subtree
> others require rewrite of Pharo code

expressions
Pavel Krivanek, Richard Uttner

Dictionary new.
new Dictionary<string, int>();
> try to detect type from assignment, if present
> explicitly add an extra assignment into
a variable with defined type
new
Pavel Krivanek, Richard Uttner

> no alternative in C#
> crate temporary variables
var cascade = new Dictionary<string><string>();
cascade.At("uid", put: uid);
cascade.At("label", put: label);
return cascade;
> can be embedded and used inside other expressions (order!)
cascade
Pavel Krivanek, Richard Uttner

> use static methods
> no static methods polymorphism in C#
> detect instance creation, translate to
constructors, forbid rest
> no polymorphism of constructors in C#

metaclasses
Pavel Krivanek, Richard Uttner

> castAs: #typeName
* does nothing in Pharo
> application specific hooks like automatic casting to method return
type
> C# and collections casting
static void ProcessList(List<object> list) { }
List<MyObject> myList = new List<MyObject>();
ProcessList(myList); X
casting
Pavel Krivanek, Richard Uttner

> traits as interfaces (but no stateful traits)
> method categories as #region
> comments preserving
> limited extension methods
> conflicts with C# keywords
> presence of primitive object types (makes some general
collection methods impossible to implement)

etc., etc
Pavel Krivanek, Richard Uttner

> 20,000 lines of compilable and working C# code
> readable, non-idiomatic C# code
> Pharo code evolving in the meantime
* regeneration
> Pharo subset
* small tools to detect issues
> Pharo as language with optional static typing
experiment
Pavel Krivanek, Richard Uttner

> no significant type error in existing code
> but runtime errors after compilation still common

value of static typing
Pavel Krivanek, Richard Uttner

Pavel Krivanek, Richard Uttner
beyond current the
experiment
> more complete standard library support
> RoelTyper
> improve non-local returns using exceptions
> metaclasses
> other languages (TypeScript, Java, C++...)
...

https://github.com/pavel-krivanek/Pharo-CSharp
https://github.com/pavel-krivanek/Runtime-Type-Collector

thank you for your
attention!
Pavel Krivanek, Richard Uttner