You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@royale.apache.org by Josh Tynjala <jo...@bowlerhat.dev> on 2026/02/07 01:50:14 UTC

Re: Another issue with function type expressions

This bug, and another one that a ternary in your code would have triggered
after fixing the first one, is fixed. I still have some additional tweaks
to make to support certain nested syntax, but it should unblock you for now.

--
Josh Tynjala
Bowler Hat LLC
https://bowlerhat.dev/


On Sat, Jan 31, 2026 at 3:22 PM Harbs <ha...@gmail.com> wrote:

> Yes. The second one does seem to be a bug.
>
> Here’s a corrected patch to reproduce that:
>
>
> diff --git
> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
> index 14073e1da9..d39c9a3b46 100644
> ---
> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
> +++
> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
> @@ -123,13 +123,13 @@ public interface ISort {
>       *  @playerversion AIR 2.6
>       *  @productversion Flex 4.5
>       */
> -    function get compareFunction():Function;
> +    function get compareFunction():(a:Object, b:Object,
> fields?:Array)=>int;
>
>      /**
>       *  @deprecated A future release of Apache Flex SDK will remove this
> function. Please use the constructor
>       *  argument instead.
>       */
> -    function set compareFunction(value:Function):void;
> +    function set compareFunction(value:(a:Object, b:Object,
> fields?:Array)=>int):void;
>
>      /**
>       *  An <code>Array</code> of <code>ISortField</code> objects that
> @@ -280,7 +280,7 @@ public interface ISort {
>              values:Object,
>              mode:String,
>              returnInsertionIndex:Boolean = false,
> -            compareFunction:Function = null):int;
> +            compareFunction:(a:Object, b:Object, fields?:Array)=>int =
> null):int;
>
>      /**
>       *  Return whether the specified property is used to control the sort.
>
>
>
> diff --git
> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
> index d16869fa1f..caf80b6559 100644
> ---
> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
> +++
> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
> @@ -186,7 +186,7 @@ public class Sort extends EventDispatcher implements
> ISort
>       *  @playerversion AIR 2.6
>       *  @productversion Royale 0.0
>       */
> -    public function Sort(fields:Array = null,
> customCompareFunction:Function = null, unique:Boolean = false)
> +    public function Sort(fields:Array = null,
> customCompareFunction:(a:Object, b:Object, fields?:Array)=>int = null,
> unique:Boolean = false)
>      {
>          super();
>
> @@ -236,7 +236,7 @@ public class Sort extends EventDispatcher implements
> ISort
>       *  @private
>       *  Storage for the compareFunction property.
>       */
> -    private var _compareFunction:Function;
> +    private var _compareFunction:(a:Object, b:Object, fields?:Array)=>int;
>
>      /**
>       *  @private
> @@ -253,7 +253,7 @@ public class Sort extends EventDispatcher implements
> ISort
>       *  @playerversion AIR 2.6
>       *  @productversion Royale 0.0
>       */
> -    public function get compareFunction():Function
> +    public function get compareFunction():(a:Object, b:Object,
> fields?:Array)=>int
>      {
>          return usingCustomCompareFunction ? _compareFunction :
> internalCompare;
>      }
> @@ -261,7 +261,7 @@ public class Sort extends EventDispatcher implements
> ISort
>      /**
>       *  @private
>       */
> -    public function set compareFunction(value:Function):void
> +    public function set compareFunction(value:(a:Object, b:Object,
> fields?:Array)=>int):void
>      {
>          _compareFunction = value;
>          usingCustomCompareFunction = _compareFunction != null;
> @@ -376,9 +376,9 @@ public class Sort extends EventDispatcher implements
> ISort
>                               values:Object,
>                               mode:String,
>                               returnInsertionIndex:Boolean = false,
> -                             compareFunction:Function = null):int
> +                             compareFunction:(a:Object, b:Object,
> fields?:Array)=>int = null):int
>      {
> -        var compareForFind:Function;
> +        var compareForFind:(a:Object, b:Object, fields?:Array)=>int;
>          var fieldsForCompare:Array;
>          var message:String;
>
> @@ -615,7 +615,7 @@ public class Sort extends EventDispatcher implements
> ISort
>              // the Sort.internalCompare function knows to use
> Sort._fields; that same logic
>              // needs to be part of calling a custom compareFunction. Of
> course, a user shouldn't
>              // be doing this -- so I wrap calls to compareFunction with
> _fields as the last parameter
> -            const fixedCompareFunction:Function =
> +            const fixedCompareFunction:(a:Object, b:Object)=>int =
>                      function (a:Object, b:Object):int
>                      {
>                          // append our fields to the call, since
> items.sort() won't
> @@ -760,7 +760,7 @@ public class Sort extends EventDispatcher implements
> ISort
>              var len:int = fields ? fields.length : _fields.length;
>              while (result == 0 && (i < len))
>              {
> -                var sf:ISortField = ISortField(_fields[i]);
> +                var sf:ISortField = (_fields[i] as ISortField);
>                  result = sf.compareFunction(a, b);
>                  if (sf.descending)
>                      result *= -1;
>
>
>
> > On Jan 30, 2026, at 5:17 PM, Josh Tynjala <jo...@bowlerhat.dev>
> wrote:
> >
> >> Error: Implicit coercion of a value of type (a:Object,b:Object)=>int to
> > an unrelated type
> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
> >
> > This error appears to be correct because you have omitted the third
> > parameter. The argument may be omitted only when calling the function. It
> > can’t be omitted when defining the function. You’d have a similar error
> if
> > an interface had an optional parameter, and you tried to define a method
> on
> > an implementing class that didn’t include the optional parameter.
> >
> >> Error: Implicit coercion of a value of type Function to an unrelated
> type
> > (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
> >
> > This one seems like it might be a bug, though. The compiler may be
> ignoring
> > the function type expression somewhere.
> >
> >
> > --
> > Josh Tynjala
> > Bowler Hat LLC
> > https://bowlerhat.dev/
> >
> >
> > On Fri, Jan 30, 2026 at 5:10 AM Harbs <ha...@gmail.com> wrote:
> >
> >> I tried to use them in the Sort classes, and I got the following error.
> >>
> >> Is this user error or a bug?
> >>
> >>
> >>     [java]
> >>
> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(397):
> >> col: 30 Error: Implicit coercion of a value of type Function to an
> >> unrelated type (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
> >>     [java]
> >>     [java]             compareForFind = this.compareFunction;
> >>     [java]                              ^
> >>     [java]
> >>     [java]
> >>
> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(619):
> >> col: 21 Error: Implicit coercion of a value of type
> >> (a:Object,b:Object)=>int to an unrelated type
> >> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
> >>     [java]
> >>     [java]                     function (a:Object, b:Object):int
> >>     [java]                     ^
> >>     [java]
> >>     [java]
> >>
> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(397):
> >> col: 30 Implicit coercion of a value of type Function to an unrelated
> type
> >> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
> >>     [java]
> >>     [java]             compareForFind = this.compareFunction;
> >>     [java]                              ^
> >>     [java]
> >>     [java]
> >>
> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(619):
> >> col: 21 Implicit coercion of a value of type (a:Object,b:Object)=>int
> to an
> >> unrelated type (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
> >>     [java]
> >>     [java]                     function (a:Object, b:Object):int
> >>     [java]                     ^
> >>
> >>
> >> Changes:
> >>
> >> diff --git
> >>
> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
> >>
> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
> >> index 14073e1da9..02a7bcc86d 100644
> >> ---
> >>
> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
> >> +++
> >>
> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
> >> @@ -123,13 +123,13 @@ public interface ISort {
> >>      *  @playerversion AIR 2.6
> >>      *  @productversion Flex 4.5
> >>      */
> >> -    function get compareFunction():Function;
> >> +    function get compareFunction():(values:Object, obj:Object,
> >> fieldsForCompare?:Array) => int;
> >>
> >>     /**
> >>      *  @deprecated A future release of Apache Flex SDK will remove this
> >> function. Please use the constructor
> >>      *  argument instead.
> >>      */
> >> -    function set compareFunction(value:Function):void;
> >> +    function set compareFunction(value:(values:Object, obj:Object,
> >> fieldsForCompare?:Array) => int):void;
> >>
> >>     /**
> >>      *  An <code>Array</code> of <code>ISortField</code> objects that
> >>
> >>
> >> diff --git
> >>
> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
> >>
> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
> >> index d16869fa1f..abec999093 100644
> >> ---
> >>
> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
> >> +++
> >>
> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
> >> @@ -186,7 +186,7 @@ public class Sort extends EventDispatcher implements
> >> ISort
> >>      *  @playerversion AIR 2.6
> >>      *  @productversion Royale 0.0
> >>      */
> >> -    public function Sort(fields:Array = null,
> >> customCompareFunction:Function = null, unique:Boolean = false)
> >> +    public function Sort(fields:Array = null,
> >> customCompareFunction:(values:Object, obj:Object,
> fieldsForCompare?:Array)
> >> => int = null, unique:Boolean = false)
> >>     {
> >>         super();
> >>
> >> @@ -236,7 +236,7 @@ public class Sort extends EventDispatcher implements
> >> ISort
> >>      *  @private
> >>      *  Storage for the compareFunction property.
> >>      */
> >> -    private var _compareFunction:Function;
> >> +    private var _compareFunction:(values:Object, obj:Object,
> >> fieldsForCompare?:Array) => int;
> >>
> >>     /**
> >>      *  @private
> >> @@ -253,7 +253,7 @@ public class Sort extends EventDispatcher implements
> >> ISort
> >>      *  @playerversion AIR 2.6
> >>      *  @productversion Royale 0.0
> >>      */
> >> -    public function get compareFunction():Function
> >> +    public function get compareFunction():(values:Object, obj:Object,
> >> fieldsForCompare?:Array) => int
> >>     {
> >>         return usingCustomCompareFunction ? _compareFunction :
> >> internalCompare;
> >>     }
> >> @@ -261,7 +261,7 @@ public class Sort extends EventDispatcher implements
> >> ISort
> >>     /**
> >>      *  @private
> >>      */
> >> -    public function set compareFunction(value:Function):void
> >> +    public function set compareFunction(value:(values:Object,
> obj:Object,
> >> fieldsForCompare?:Array) => int):void
> >>     {
> >>         _compareFunction = value;
> >>         usingCustomCompareFunction = _compareFunction != null;
> >> @@ -376,9 +376,9 @@ public class Sort extends EventDispatcher implements
> >> ISort
> >>                              values:Object,
> >>                              mode:String,
> >>                              returnInsertionIndex:Boolean = false,
> >> -                             compareFunction:Function = null):int
> >> +                             compareFunction:(values:Object,
> obj:Object,
> >> fieldsForCompare?:Array) => int = null):int
> >>     {
> >> -        var compareForFind:Function;
> >> +        var compareForFind:(values:Object, obj:Object,
> >> fieldsForCompare?:Array) => int;
> >>         var fieldsForCompare:Array;
> >>         var message:String;
> >>
> >> @@ -615,7 +615,7 @@ public class Sort extends EventDispatcher implements
> >> ISort
> >>             // the Sort.internalCompare function knows to use
> >> Sort._fields; that same logic
> >>             // needs to be part of calling a custom compareFunction. Of
> >> course, a user shouldn't
> >>             // be doing this -- so I wrap calls to compareFunction with
> >> _fields as the last parameter
> >> -            const fixedCompareFunction:Function =
> >> +            const fixedCompareFunction:(values:Object, obj:Object,
> >> fieldsForCompare?:Array) => int =
> >>                     function (a:Object, b:Object):int
> >>                     {
> >>                         // append our fields to the call, since
> >> items.sort() won't
> >>
> >>
>
>

Re: Another issue with function type expressions

Posted by Harbs <ha...@gmail.com>.
Cool. I added quite a few expressions in my own code as well. It seems to all work correctly.

Excellent work! :-)

Harbs

> On Feb 18, 2026, at 2:02 AM, Josh Tynjala <jo...@bowlerhat.dev> wrote:
> 
> I have applied the additional tweaks for resolving function types from
> nested expressions that I mentioned previously. I confirmed that your
> additions of function types in royale-asjs still compile correctly after my
> change.
> 
> There are no further known issues with function types on my end at this
> time.
> 
> --
> Josh Tynjala
> Bowler Hat LLC
> https://bowlerhat.dev/
> 
> 
> On Fri, Feb 6, 2026 at 5:50 PM Josh Tynjala <jo...@bowlerhat.dev>
> wrote:
> 
>> This bug, and another one that a ternary in your code would have triggered
>> after fixing the first one, is fixed. I still have some additional tweaks
>> to make to support certain nested syntax, but it should unblock you for now.
>> 
>> --
>> Josh Tynjala
>> Bowler Hat LLC
>> https://bowlerhat.dev/
>> 
>> 
>> On Sat, Jan 31, 2026 at 3:22 PM Harbs <ha...@gmail.com> wrote:
>> 
>>> Yes. The second one does seem to be a bug.
>>> 
>>> Here’s a corrected patch to reproduce that:
>>> 
>>> 
>>> diff --git
>>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>>> index 14073e1da9..d39c9a3b46 100644
>>> ---
>>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>>> +++
>>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>>> @@ -123,13 +123,13 @@ public interface ISort {
>>>      *  @playerversion AIR 2.6
>>>      *  @productversion Flex 4.5
>>>      */
>>> -    function get compareFunction():Function;
>>> +    function get compareFunction():(a:Object, b:Object,
>>> fields?:Array)=>int;
>>> 
>>>     /**
>>>      *  @deprecated A future release of Apache Flex SDK will remove this
>>> function. Please use the constructor
>>>      *  argument instead.
>>>      */
>>> -    function set compareFunction(value:Function):void;
>>> +    function set compareFunction(value:(a:Object, b:Object,
>>> fields?:Array)=>int):void;
>>> 
>>>     /**
>>>      *  An <code>Array</code> of <code>ISortField</code> objects that
>>> @@ -280,7 +280,7 @@ public interface ISort {
>>>             values:Object,
>>>             mode:String,
>>>             returnInsertionIndex:Boolean = false,
>>> -            compareFunction:Function = null):int;
>>> +            compareFunction:(a:Object, b:Object, fields?:Array)=>int =
>>> null):int;
>>> 
>>>     /**
>>>      *  Return whether the specified property is used to control the
>>> sort.
>>> 
>>> 
>>> 
>>> diff --git
>>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>>> index d16869fa1f..caf80b6559 100644
>>> ---
>>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>>> +++
>>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>>> @@ -186,7 +186,7 @@ public class Sort extends EventDispatcher implements
>>> ISort
>>>      *  @playerversion AIR 2.6
>>>      *  @productversion Royale 0.0
>>>      */
>>> -    public function Sort(fields:Array = null,
>>> customCompareFunction:Function = null, unique:Boolean = false)
>>> +    public function Sort(fields:Array = null,
>>> customCompareFunction:(a:Object, b:Object, fields?:Array)=>int = null,
>>> unique:Boolean = false)
>>>     {
>>>         super();
>>> 
>>> @@ -236,7 +236,7 @@ public class Sort extends EventDispatcher implements
>>> ISort
>>>      *  @private
>>>      *  Storage for the compareFunction property.
>>>      */
>>> -    private var _compareFunction:Function;
>>> +    private var _compareFunction:(a:Object, b:Object,
>>> fields?:Array)=>int;
>>> 
>>>     /**
>>>      *  @private
>>> @@ -253,7 +253,7 @@ public class Sort extends EventDispatcher implements
>>> ISort
>>>      *  @playerversion AIR 2.6
>>>      *  @productversion Royale 0.0
>>>      */
>>> -    public function get compareFunction():Function
>>> +    public function get compareFunction():(a:Object, b:Object,
>>> fields?:Array)=>int
>>>     {
>>>         return usingCustomCompareFunction ? _compareFunction :
>>> internalCompare;
>>>     }
>>> @@ -261,7 +261,7 @@ public class Sort extends EventDispatcher implements
>>> ISort
>>>     /**
>>>      *  @private
>>>      */
>>> -    public function set compareFunction(value:Function):void
>>> +    public function set compareFunction(value:(a:Object, b:Object,
>>> fields?:Array)=>int):void
>>>     {
>>>         _compareFunction = value;
>>>         usingCustomCompareFunction = _compareFunction != null;
>>> @@ -376,9 +376,9 @@ public class Sort extends EventDispatcher implements
>>> ISort
>>>                              values:Object,
>>>                              mode:String,
>>>                              returnInsertionIndex:Boolean = false,
>>> -                             compareFunction:Function = null):int
>>> +                             compareFunction:(a:Object, b:Object,
>>> fields?:Array)=>int = null):int
>>>     {
>>> -        var compareForFind:Function;
>>> +        var compareForFind:(a:Object, b:Object, fields?:Array)=>int;
>>>         var fieldsForCompare:Array;
>>>         var message:String;
>>> 
>>> @@ -615,7 +615,7 @@ public class Sort extends EventDispatcher implements
>>> ISort
>>>             // the Sort.internalCompare function knows to use
>>> Sort._fields; that same logic
>>>             // needs to be part of calling a custom compareFunction. Of
>>> course, a user shouldn't
>>>             // be doing this -- so I wrap calls to compareFunction with
>>> _fields as the last parameter
>>> -            const fixedCompareFunction:Function =
>>> +            const fixedCompareFunction:(a:Object, b:Object)=>int =
>>>                     function (a:Object, b:Object):int
>>>                     {
>>>                         // append our fields to the call, since
>>> items.sort() won't
>>> @@ -760,7 +760,7 @@ public class Sort extends EventDispatcher implements
>>> ISort
>>>             var len:int = fields ? fields.length : _fields.length;
>>>             while (result == 0 && (i < len))
>>>             {
>>> -                var sf:ISortField = ISortField(_fields[i]);
>>> +                var sf:ISortField = (_fields[i] as ISortField);
>>>                 result = sf.compareFunction(a, b);
>>>                 if (sf.descending)
>>>                     result *= -1;
>>> 
>>> 
>>> 
>>>> On Jan 30, 2026, at 5:17 PM, Josh Tynjala <jo...@bowlerhat.dev>
>>> wrote:
>>>> 
>>>>> Error: Implicit coercion of a value of type (a:Object,b:Object)=>int to
>>>> an unrelated type
>>> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>>>> 
>>>> This error appears to be correct because you have omitted the third
>>>> parameter. The argument may be omitted only when calling the function.
>>> It
>>>> can’t be omitted when defining the function. You’d have a similar error
>>> if
>>>> an interface had an optional parameter, and you tried to define a
>>> method on
>>>> an implementing class that didn’t include the optional parameter.
>>>> 
>>>>> Error: Implicit coercion of a value of type Function to an unrelated
>>> type
>>>> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>>>> 
>>>> This one seems like it might be a bug, though. The compiler may be
>>> ignoring
>>>> the function type expression somewhere.
>>>> 
>>>> 
>>>> --
>>>> Josh Tynjala
>>>> Bowler Hat LLC
>>>> https://bowlerhat.dev/
>>>> 
>>>> 
>>>> On Fri, Jan 30, 2026 at 5:10 AM Harbs <ha...@gmail.com> wrote:
>>>> 
>>>>> I tried to use them in the Sort classes, and I got the following error.
>>>>> 
>>>>> Is this user error or a bug?
>>>>> 
>>>>> 
>>>>>    [java]
>>>>> 
>>> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(397):
>>>>> col: 30 Error: Implicit coercion of a value of type Function to an
>>>>> unrelated type (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>>>>>    [java]
>>>>>    [java]             compareForFind = this.compareFunction;
>>>>>    [java]                              ^
>>>>>    [java]
>>>>>    [java]
>>>>> 
>>> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(619):
>>>>> col: 21 Error: Implicit coercion of a value of type
>>>>> (a:Object,b:Object)=>int to an unrelated type
>>>>> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>>>>>    [java]
>>>>>    [java]                     function (a:Object, b:Object):int
>>>>>    [java]                     ^
>>>>>    [java]
>>>>>    [java]
>>>>> 
>>> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(397):
>>>>> col: 30 Implicit coercion of a value of type Function to an unrelated
>>> type
>>>>> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>>>>>    [java]
>>>>>    [java]             compareForFind = this.compareFunction;
>>>>>    [java]                              ^
>>>>>    [java]
>>>>>    [java]
>>>>> 
>>> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(619):
>>>>> col: 21 Implicit coercion of a value of type (a:Object,b:Object)=>int
>>> to an
>>>>> unrelated type (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>>>>>    [java]
>>>>>    [java]                     function (a:Object, b:Object):int
>>>>>    [java]                     ^
>>>>> 
>>>>> 
>>>>> Changes:
>>>>> 
>>>>> diff --git
>>>>> 
>>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>>>>> 
>>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>>>>> index 14073e1da9..02a7bcc86d 100644
>>>>> ---
>>>>> 
>>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>>>>> +++
>>>>> 
>>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>>>>> @@ -123,13 +123,13 @@ public interface ISort {
>>>>>     *  @playerversion AIR 2.6
>>>>>     *  @productversion Flex 4.5
>>>>>     */
>>>>> -    function get compareFunction():Function;
>>>>> +    function get compareFunction():(values:Object, obj:Object,
>>>>> fieldsForCompare?:Array) => int;
>>>>> 
>>>>>    /**
>>>>>     *  @deprecated A future release of Apache Flex SDK will remove
>>> this
>>>>> function. Please use the constructor
>>>>>     *  argument instead.
>>>>>     */
>>>>> -    function set compareFunction(value:Function):void;
>>>>> +    function set compareFunction(value:(values:Object, obj:Object,
>>>>> fieldsForCompare?:Array) => int):void;
>>>>> 
>>>>>    /**
>>>>>     *  An <code>Array</code> of <code>ISortField</code> objects that
>>>>> 
>>>>> 
>>>>> diff --git
>>>>> 
>>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>>>>> 
>>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>>>>> index d16869fa1f..abec999093 100644
>>>>> ---
>>>>> 
>>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>>>>> +++
>>>>> 
>>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>>>>> @@ -186,7 +186,7 @@ public class Sort extends EventDispatcher
>>> implements
>>>>> ISort
>>>>>     *  @playerversion AIR 2.6
>>>>>     *  @productversion Royale 0.0
>>>>>     */
>>>>> -    public function Sort(fields:Array = null,
>>>>> customCompareFunction:Function = null, unique:Boolean = false)
>>>>> +    public function Sort(fields:Array = null,
>>>>> customCompareFunction:(values:Object, obj:Object,
>>> fieldsForCompare?:Array)
>>>>> => int = null, unique:Boolean = false)
>>>>>    {
>>>>>        super();
>>>>> 
>>>>> @@ -236,7 +236,7 @@ public class Sort extends EventDispatcher
>>> implements
>>>>> ISort
>>>>>     *  @private
>>>>>     *  Storage for the compareFunction property.
>>>>>     */
>>>>> -    private var _compareFunction:Function;
>>>>> +    private var _compareFunction:(values:Object, obj:Object,
>>>>> fieldsForCompare?:Array) => int;
>>>>> 
>>>>>    /**
>>>>>     *  @private
>>>>> @@ -253,7 +253,7 @@ public class Sort extends EventDispatcher
>>> implements
>>>>> ISort
>>>>>     *  @playerversion AIR 2.6
>>>>>     *  @productversion Royale 0.0
>>>>>     */
>>>>> -    public function get compareFunction():Function
>>>>> +    public function get compareFunction():(values:Object, obj:Object,
>>>>> fieldsForCompare?:Array) => int
>>>>>    {
>>>>>        return usingCustomCompareFunction ? _compareFunction :
>>>>> internalCompare;
>>>>>    }
>>>>> @@ -261,7 +261,7 @@ public class Sort extends EventDispatcher
>>> implements
>>>>> ISort
>>>>>    /**
>>>>>     *  @private
>>>>>     */
>>>>> -    public function set compareFunction(value:Function):void
>>>>> +    public function set compareFunction(value:(values:Object,
>>> obj:Object,
>>>>> fieldsForCompare?:Array) => int):void
>>>>>    {
>>>>>        _compareFunction = value;
>>>>>        usingCustomCompareFunction = _compareFunction != null;
>>>>> @@ -376,9 +376,9 @@ public class Sort extends EventDispatcher
>>> implements
>>>>> ISort
>>>>>                             values:Object,
>>>>>                             mode:String,
>>>>>                             returnInsertionIndex:Boolean = false,
>>>>> -                             compareFunction:Function = null):int
>>>>> +                             compareFunction:(values:Object,
>>> obj:Object,
>>>>> fieldsForCompare?:Array) => int = null):int
>>>>>    {
>>>>> -        var compareForFind:Function;
>>>>> +        var compareForFind:(values:Object, obj:Object,
>>>>> fieldsForCompare?:Array) => int;
>>>>>        var fieldsForCompare:Array;
>>>>>        var message:String;
>>>>> 
>>>>> @@ -615,7 +615,7 @@ public class Sort extends EventDispatcher
>>> implements
>>>>> ISort
>>>>>            // the Sort.internalCompare function knows to use
>>>>> Sort._fields; that same logic
>>>>>            // needs to be part of calling a custom compareFunction. Of
>>>>> course, a user shouldn't
>>>>>            // be doing this -- so I wrap calls to compareFunction with
>>>>> _fields as the last parameter
>>>>> -            const fixedCompareFunction:Function =
>>>>> +            const fixedCompareFunction:(values:Object, obj:Object,
>>>>> fieldsForCompare?:Array) => int =
>>>>>                    function (a:Object, b:Object):int
>>>>>                    {
>>>>>                        // append our fields to the call, since
>>>>> items.sort() won't
>>>>> 
>>>>> 
>>> 
>>> 


Re: Another issue with function type expressions

Posted by Josh Tynjala <jo...@bowlerhat.dev>.
I have applied the additional tweaks for resolving function types from
nested expressions that I mentioned previously. I confirmed that your
additions of function types in royale-asjs still compile correctly after my
change.

There are no further known issues with function types on my end at this
time.

--
Josh Tynjala
Bowler Hat LLC
https://bowlerhat.dev/


On Fri, Feb 6, 2026 at 5:50 PM Josh Tynjala <jo...@bowlerhat.dev>
wrote:

> This bug, and another one that a ternary in your code would have triggered
> after fixing the first one, is fixed. I still have some additional tweaks
> to make to support certain nested syntax, but it should unblock you for now.
>
> --
> Josh Tynjala
> Bowler Hat LLC
> https://bowlerhat.dev/
>
>
> On Sat, Jan 31, 2026 at 3:22 PM Harbs <ha...@gmail.com> wrote:
>
>> Yes. The second one does seem to be a bug.
>>
>> Here’s a corrected patch to reproduce that:
>>
>>
>> diff --git
>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>> index 14073e1da9..d39c9a3b46 100644
>> ---
>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>> +++
>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>> @@ -123,13 +123,13 @@ public interface ISort {
>>       *  @playerversion AIR 2.6
>>       *  @productversion Flex 4.5
>>       */
>> -    function get compareFunction():Function;
>> +    function get compareFunction():(a:Object, b:Object,
>> fields?:Array)=>int;
>>
>>      /**
>>       *  @deprecated A future release of Apache Flex SDK will remove this
>> function. Please use the constructor
>>       *  argument instead.
>>       */
>> -    function set compareFunction(value:Function):void;
>> +    function set compareFunction(value:(a:Object, b:Object,
>> fields?:Array)=>int):void;
>>
>>      /**
>>       *  An <code>Array</code> of <code>ISortField</code> objects that
>> @@ -280,7 +280,7 @@ public interface ISort {
>>              values:Object,
>>              mode:String,
>>              returnInsertionIndex:Boolean = false,
>> -            compareFunction:Function = null):int;
>> +            compareFunction:(a:Object, b:Object, fields?:Array)=>int =
>> null):int;
>>
>>      /**
>>       *  Return whether the specified property is used to control the
>> sort.
>>
>>
>>
>> diff --git
>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>> index d16869fa1f..caf80b6559 100644
>> ---
>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>> +++
>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>> @@ -186,7 +186,7 @@ public class Sort extends EventDispatcher implements
>> ISort
>>       *  @playerversion AIR 2.6
>>       *  @productversion Royale 0.0
>>       */
>> -    public function Sort(fields:Array = null,
>> customCompareFunction:Function = null, unique:Boolean = false)
>> +    public function Sort(fields:Array = null,
>> customCompareFunction:(a:Object, b:Object, fields?:Array)=>int = null,
>> unique:Boolean = false)
>>      {
>>          super();
>>
>> @@ -236,7 +236,7 @@ public class Sort extends EventDispatcher implements
>> ISort
>>       *  @private
>>       *  Storage for the compareFunction property.
>>       */
>> -    private var _compareFunction:Function;
>> +    private var _compareFunction:(a:Object, b:Object,
>> fields?:Array)=>int;
>>
>>      /**
>>       *  @private
>> @@ -253,7 +253,7 @@ public class Sort extends EventDispatcher implements
>> ISort
>>       *  @playerversion AIR 2.6
>>       *  @productversion Royale 0.0
>>       */
>> -    public function get compareFunction():Function
>> +    public function get compareFunction():(a:Object, b:Object,
>> fields?:Array)=>int
>>      {
>>          return usingCustomCompareFunction ? _compareFunction :
>> internalCompare;
>>      }
>> @@ -261,7 +261,7 @@ public class Sort extends EventDispatcher implements
>> ISort
>>      /**
>>       *  @private
>>       */
>> -    public function set compareFunction(value:Function):void
>> +    public function set compareFunction(value:(a:Object, b:Object,
>> fields?:Array)=>int):void
>>      {
>>          _compareFunction = value;
>>          usingCustomCompareFunction = _compareFunction != null;
>> @@ -376,9 +376,9 @@ public class Sort extends EventDispatcher implements
>> ISort
>>                               values:Object,
>>                               mode:String,
>>                               returnInsertionIndex:Boolean = false,
>> -                             compareFunction:Function = null):int
>> +                             compareFunction:(a:Object, b:Object,
>> fields?:Array)=>int = null):int
>>      {
>> -        var compareForFind:Function;
>> +        var compareForFind:(a:Object, b:Object, fields?:Array)=>int;
>>          var fieldsForCompare:Array;
>>          var message:String;
>>
>> @@ -615,7 +615,7 @@ public class Sort extends EventDispatcher implements
>> ISort
>>              // the Sort.internalCompare function knows to use
>> Sort._fields; that same logic
>>              // needs to be part of calling a custom compareFunction. Of
>> course, a user shouldn't
>>              // be doing this -- so I wrap calls to compareFunction with
>> _fields as the last parameter
>> -            const fixedCompareFunction:Function =
>> +            const fixedCompareFunction:(a:Object, b:Object)=>int =
>>                      function (a:Object, b:Object):int
>>                      {
>>                          // append our fields to the call, since
>> items.sort() won't
>> @@ -760,7 +760,7 @@ public class Sort extends EventDispatcher implements
>> ISort
>>              var len:int = fields ? fields.length : _fields.length;
>>              while (result == 0 && (i < len))
>>              {
>> -                var sf:ISortField = ISortField(_fields[i]);
>> +                var sf:ISortField = (_fields[i] as ISortField);
>>                  result = sf.compareFunction(a, b);
>>                  if (sf.descending)
>>                      result *= -1;
>>
>>
>>
>> > On Jan 30, 2026, at 5:17 PM, Josh Tynjala <jo...@bowlerhat.dev>
>> wrote:
>> >
>> >> Error: Implicit coercion of a value of type (a:Object,b:Object)=>int to
>> > an unrelated type
>> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>> >
>> > This error appears to be correct because you have omitted the third
>> > parameter. The argument may be omitted only when calling the function.
>> It
>> > can’t be omitted when defining the function. You’d have a similar error
>> if
>> > an interface had an optional parameter, and you tried to define a
>> method on
>> > an implementing class that didn’t include the optional parameter.
>> >
>> >> Error: Implicit coercion of a value of type Function to an unrelated
>> type
>> > (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>> >
>> > This one seems like it might be a bug, though. The compiler may be
>> ignoring
>> > the function type expression somewhere.
>> >
>> >
>> > --
>> > Josh Tynjala
>> > Bowler Hat LLC
>> > https://bowlerhat.dev/
>> >
>> >
>> > On Fri, Jan 30, 2026 at 5:10 AM Harbs <ha...@gmail.com> wrote:
>> >
>> >> I tried to use them in the Sort classes, and I got the following error.
>> >>
>> >> Is this user error or a bug?
>> >>
>> >>
>> >>     [java]
>> >>
>> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(397):
>> >> col: 30 Error: Implicit coercion of a value of type Function to an
>> >> unrelated type (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>> >>     [java]
>> >>     [java]             compareForFind = this.compareFunction;
>> >>     [java]                              ^
>> >>     [java]
>> >>     [java]
>> >>
>> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(619):
>> >> col: 21 Error: Implicit coercion of a value of type
>> >> (a:Object,b:Object)=>int to an unrelated type
>> >> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>> >>     [java]
>> >>     [java]                     function (a:Object, b:Object):int
>> >>     [java]                     ^
>> >>     [java]
>> >>     [java]
>> >>
>> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(397):
>> >> col: 30 Implicit coercion of a value of type Function to an unrelated
>> type
>> >> (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>> >>     [java]
>> >>     [java]             compareForFind = this.compareFunction;
>> >>     [java]                              ^
>> >>     [java]
>> >>     [java]
>> >>
>> /Users/harbs/Apache/royale-asjs/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as(619):
>> >> col: 21 Implicit coercion of a value of type (a:Object,b:Object)=>int
>> to an
>> >> unrelated type (values:Object,obj:Object,fieldsForCompare?:Array)=>int.
>> >>     [java]
>> >>     [java]                     function (a:Object, b:Object):int
>> >>     [java]                     ^
>> >>
>> >>
>> >> Changes:
>> >>
>> >> diff --git
>> >>
>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>> >>
>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>> >> index 14073e1da9..02a7bcc86d 100644
>> >> ---
>> >>
>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>> >> +++
>> >>
>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/ISort.as
>> >> @@ -123,13 +123,13 @@ public interface ISort {
>> >>      *  @playerversion AIR 2.6
>> >>      *  @productversion Flex 4.5
>> >>      */
>> >> -    function get compareFunction():Function;
>> >> +    function get compareFunction():(values:Object, obj:Object,
>> >> fieldsForCompare?:Array) => int;
>> >>
>> >>     /**
>> >>      *  @deprecated A future release of Apache Flex SDK will remove
>> this
>> >> function. Please use the constructor
>> >>      *  argument instead.
>> >>      */
>> >> -    function set compareFunction(value:Function):void;
>> >> +    function set compareFunction(value:(values:Object, obj:Object,
>> >> fieldsForCompare?:Array) => int):void;
>> >>
>> >>     /**
>> >>      *  An <code>Array</code> of <code>ISortField</code> objects that
>> >>
>> >>
>> >> diff --git
>> >>
>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>> >>
>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>> >> index d16869fa1f..abec999093 100644
>> >> ---
>> >>
>> a/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>> >> +++
>> >>
>> b/frameworks/projects/Collections/src/main/royale/org/apache/royale/collections/Sort.as
>> >> @@ -186,7 +186,7 @@ public class Sort extends EventDispatcher
>> implements
>> >> ISort
>> >>      *  @playerversion AIR 2.6
>> >>      *  @productversion Royale 0.0
>> >>      */
>> >> -    public function Sort(fields:Array = null,
>> >> customCompareFunction:Function = null, unique:Boolean = false)
>> >> +    public function Sort(fields:Array = null,
>> >> customCompareFunction:(values:Object, obj:Object,
>> fieldsForCompare?:Array)
>> >> => int = null, unique:Boolean = false)
>> >>     {
>> >>         super();
>> >>
>> >> @@ -236,7 +236,7 @@ public class Sort extends EventDispatcher
>> implements
>> >> ISort
>> >>      *  @private
>> >>      *  Storage for the compareFunction property.
>> >>      */
>> >> -    private var _compareFunction:Function;
>> >> +    private var _compareFunction:(values:Object, obj:Object,
>> >> fieldsForCompare?:Array) => int;
>> >>
>> >>     /**
>> >>      *  @private
>> >> @@ -253,7 +253,7 @@ public class Sort extends EventDispatcher
>> implements
>> >> ISort
>> >>      *  @playerversion AIR 2.6
>> >>      *  @productversion Royale 0.0
>> >>      */
>> >> -    public function get compareFunction():Function
>> >> +    public function get compareFunction():(values:Object, obj:Object,
>> >> fieldsForCompare?:Array) => int
>> >>     {
>> >>         return usingCustomCompareFunction ? _compareFunction :
>> >> internalCompare;
>> >>     }
>> >> @@ -261,7 +261,7 @@ public class Sort extends EventDispatcher
>> implements
>> >> ISort
>> >>     /**
>> >>      *  @private
>> >>      */
>> >> -    public function set compareFunction(value:Function):void
>> >> +    public function set compareFunction(value:(values:Object,
>> obj:Object,
>> >> fieldsForCompare?:Array) => int):void
>> >>     {
>> >>         _compareFunction = value;
>> >>         usingCustomCompareFunction = _compareFunction != null;
>> >> @@ -376,9 +376,9 @@ public class Sort extends EventDispatcher
>> implements
>> >> ISort
>> >>                              values:Object,
>> >>                              mode:String,
>> >>                              returnInsertionIndex:Boolean = false,
>> >> -                             compareFunction:Function = null):int
>> >> +                             compareFunction:(values:Object,
>> obj:Object,
>> >> fieldsForCompare?:Array) => int = null):int
>> >>     {
>> >> -        var compareForFind:Function;
>> >> +        var compareForFind:(values:Object, obj:Object,
>> >> fieldsForCompare?:Array) => int;
>> >>         var fieldsForCompare:Array;
>> >>         var message:String;
>> >>
>> >> @@ -615,7 +615,7 @@ public class Sort extends EventDispatcher
>> implements
>> >> ISort
>> >>             // the Sort.internalCompare function knows to use
>> >> Sort._fields; that same logic
>> >>             // needs to be part of calling a custom compareFunction. Of
>> >> course, a user shouldn't
>> >>             // be doing this -- so I wrap calls to compareFunction with
>> >> _fields as the last parameter
>> >> -            const fixedCompareFunction:Function =
>> >> +            const fixedCompareFunction:(values:Object, obj:Object,
>> >> fieldsForCompare?:Array) => int =
>> >>                     function (a:Object, b:Object):int
>> >>                     {
>> >>                         // append our fields to the call, since
>> >> items.sort() won't
>> >>
>> >>
>>
>>