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
Keyword arguments currently use a hash map to map the names to their corresponding
positional arguments. Instead of using a hash map, the compiler should generate a list
of positional arguments. Optional arguments not provided will be set to an "undefined"
value.
Motivation
Mapping keyword argument names to their positional arguments is expensive, and complicates
the code used for running blocks. This complexity affects all method calls to a certain
degree, even when no keyword arguments need to be looked up.
Using "undefined" values allows us to fill up unspecified optional parameters, removing
the need for hash map lookups. For dynamic calls one would have to manually fill up
arguments, or pass the appropriate values. This will make dynamic calls more cumbersome,
but they are likely to be used rarely due to Inko's gradually typed nature. This could
also be made easier by having the compiler take care of this at runtime somehow.
In short: this setup will speed up method calls, without having to change the code
generated for optional arguments.
Implementation
The "undefined" type is a NULL pointer in the VM. Registers and locals are zeroed
out, removing the need for writing any additional values to set them to the "undefined"
type by default. This means we don't have to change the code generated for optional
arguments, and we only have to change LocalExists to use something like if local.is_undefined() instead of if local.is_null().
The compiler will have to generate a list of positional arguments. For example, this:
For dynamic method calls (= sending a message to Dynamic) we would have to disallow
the use of keyword arguments. Allowing this would result in arguments being set
incorrectly, without this being clear to the developer. This means that this code is
no longer valid:
let x = 'foo' as Dynamic
x.slice(length: 2, start: 0)
This would be invalid because slice is defined as slice(start: Integer, length: Integer) -> String,
and in this new setup the arguments would be mapped incorrectly.
Drawbacks
Dynamic method calls no longer support keyword arguments, and the Ruby compiler would have to be adjusted.
The text was updated successfully, but these errors were encountered:
An entirely different approach is to make argument names part of the message name, and remove optional arguments. This would be similar to Smalltalk. To illustrate, consider the following method:
def slice(start: Integer, length: Integer) {}
Right now the message name is slice. In the new setup, the message name would be slice:start:length: (or something to that extend). Optional arguments would be
implemented using method overloading:
The benefit of this approach is no runtime overhead for optional arguments, as we no longer need to check if they are given a value. This setup is also useful when your method's implementation differs a lot based on the presence of an optional arguments.
A downside is that it might be more difficult to read the code, as the code for a message is now spread across multiple methods. Another downside is that keyword arguments can no longer be passed in arbitrary order, but I don't find this a very useful feature to begin with.
Because init methods can now be defined multiple times, the compiler would have to somehow ensure they all set the same instance variables. This likely requires two passes over the list of init methods:
One pass to gather all unique names of the defined instance variables.
One pass to verify all init methods to see if they set all these variables.
Summary
Keyword arguments currently use a hash map to map the names to their corresponding
positional arguments. Instead of using a hash map, the compiler should generate a list
of positional arguments. Optional arguments not provided will be set to an "undefined"
value.
Motivation
Mapping keyword argument names to their positional arguments is expensive, and complicates
the code used for running blocks. This complexity affects all method calls to a certain
degree, even when no keyword arguments need to be looked up.
Using "undefined" values allows us to fill up unspecified optional parameters, removing
the need for hash map lookups. For dynamic calls one would have to manually fill up
arguments, or pass the appropriate values. This will make dynamic calls more cumbersome,
but they are likely to be used rarely due to Inko's gradually typed nature. This could
also be made easier by having the compiler take care of this at runtime somehow.
In short: this setup will speed up method calls, without having to change the code
generated for optional arguments.
Implementation
The "undefined" type is a NULL pointer in the VM. Registers and locals are zeroed
out, removing the need for writing any additional values to set them to the "undefined"
type by default. This means we don't have to change the code generated for optional
arguments, and we only have to change
LocalExists
to use something likeif local.is_undefined()
instead ofif local.is_null()
.The compiler will have to generate a list of positional arguments. For example, this:
Would be translated into this:
For dynamic method calls (= sending a message to
Dynamic
) we would have to disallowthe use of keyword arguments. Allowing this would result in arguments being set
incorrectly, without this being clear to the developer. This means that this code is
no longer valid:
This would be invalid because
slice
is defined asslice(start: Integer, length: Integer) -> String
,and in this new setup the arguments would be mapped incorrectly.
Drawbacks
Dynamic method calls no longer support keyword arguments, and the Ruby compiler would have to be adjusted.
The text was updated successfully, but these errors were encountered: