www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 5491] New: filter cannot be used in a function?

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5491

           Summary: filter cannot be used in a function?
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: Phobos
        AssignedTo: nobody puremagic.com
        ReportedBy: tbolsh gmail.com



PST ---
The following code:
_______________________________________________________________________________
import std.algorithm, std.conv, std.stdio;

enum UsbDevType: uint { indifferent = 0, parent_of_checked = 1, hub_dub_7 =
0x2001f103, spider_hub = 0x05e30608, gateway = 0x11A03232 }
struct UsbDevice { //{{{ 
    UsbDevType dev_type;
    // not essential here ...
    string toString(){ return to!string( dev_type ); }
}

UsbDevice [] gateways_only( UsbDevice []devices ){ return filter!("a.dev_type
== UsbDevType.gateway" )( devices ); }

unittest{
    auto devices  = [ UsbDevice( UsbDevType.gateway ), UsbDevice(
UsbDevType.indifferent ), UsbDevice( UsbDevType.hub_dub_7 ) ];
    auto gateways = gateways_only( devices );
    foreach( UsbDevice dev; gateways ) writeln( dev.toString() );
}
______________________________________________________________________________
does not compile telling:
bugs/tbolsh_d2_bug2.d(10): Error: cannot implicitly convert expression
(filter(devices)) of type Filter!(result,UsbDevice[]) to UsbDevice[]

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 26 2011
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5491




PST ---
Following variant do not work either:
______________________________________________________________________________
import std.algorithm, std.conv, std.stdio;

enum UsbDevType: uint { indifferent = 0, parent_of_checked = 1, hub_dub_7 =
0x2001f103, spider_hub = 0x05e30608, gateway = 0x11A03232 }
struct UsbDevice { //{{{ 
    UsbDevType dev_type;
    // not essential here ...
    string toString(){ return to!string( dev_type ); }
}

unittest{
    auto devices  = [ UsbDevice( UsbDevType.gateway ), UsbDevice(
UsbDevType.indifferent ), UsbDevice( UsbDevType.hub_dub_7 ) ];
    auto gateways = filter!( "a.dev_type == UsbDevType.gateway" )( devices );
    foreach( UsbDevice dev; gateways ) writeln( dev.toString() );
}
______________________________________________________________________________
compiler tells:
tbolshakov owner-laptop:~/projects/D$ dmd -unittest bugs/tbolsh_d2_bug3.d 
/usr/include/d/dmd/phobos/std/functional.d(74): Error: static assert  "Bad
unary function: a.dev_type == UsbDevType.gateway for type UsbDevice"
/usr/include/d/dmd/phobos/std/functional.d(87):        instantiated from here:
Body!(UsbDevice)
/usr/include/d/dmd/phobos/std/algorithm.d(857):        instantiated from here:
result!(UsbDevice)
/usr/include/d/dmd/phobos/std/algorithm.d(842):        instantiated from here:
Filter!(result,UsbDevice[])
bugs/tbolsh_d2_bug3.d(12):        instantiated from here: filter!(UsbDevice[])

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 26 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5491




PST ---
And this one does not compile:
__________________________________________________________________________________
import std.algorithm, std.conv, std.stdio;

enum UsbDevType: uint { indifferent = 0, parent_of_checked = 1, hub_dub_7 =
0x2001f103, spider_hub = 0x05e30608, gateway = 0x11A03232 }
struct UsbDevice { //{{{ 
    UsbDevType dev_type;
    ubyte usb_id;
    // not essential here ...
    string toString(){ return to!string( dev_type ); }
}
UsbDevice [ ubyte ] associate_devices( UsbDevice []devices ){//{{{
    UsbDevice [ubyte] retval; 
    foreach( UsbDevice dev ; devices ) retval[ dev.usb_id ] = dev;  
    return retval;
}//}}}

unittest{
    auto devices  = [ UsbDevice( UsbDevType.gateway, 1 ), UsbDevice(
UsbDevType.indifferent, 2 ), UsbDevice( UsbDevType.hub_dub_7, 3 ) ];
    auto devmap = associate_devices( 
        filter!( delegate bool( UsbDevice a ){ return a.dev_type ==
UsbDevType.gateway; } )( devices ) );
    foreach( UsbDevice dev; gateways ) writeln( dev.toString() );
}

void main(){}
______________________________________________________________________________
Telling:
tbolshakov owner-laptop:~/projects/D$ dmd -unittest bugs/tbolsh_d2_bug4.d 
bugs/tbolsh_d2_bug4.d(18): Error: function tbolsh_d2_bug4.associate_devices
(UsbDevice[] devices) is not callable using argument types
(Filter!(__dgliteral1,UsbDevice[]))
bugs/tbolsh_d2_bug4.d(19): Error: cannot implicitly convert expression
(filter(devices)) of type Filter!(__dgliteral1,UsbDevice[]) to UsbDevice[]
bugs/tbolsh_d2_bug4.d(20): Error: undefined identifier gateways
bugs/tbolsh_d2_bug4.d(20): Error: foreach: _error_ is not an aggregate type

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 26 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5491




PST ---
I am sorry for the line 

 UsbDevType.gateway; } )( devices ) );
     foreach( UsbDevice dev; gateways ) writeln( dev.toString() );
 }
It is not needed there - cut and paste error. But it will remove only 2 last errors, "filter" related errors will still be there:
 tbolshakov owner-laptop:~/projects/D$ dmd -unittest bugs/tbolsh_d2_bug4.d 
 bugs/tbolsh_d2_bug4.d(18): Error: function tbolsh_d2_bug4.associate_devices
 (UsbDevice[] devices) is not callable using argument types
 (Filter!(__dgliteral1,UsbDevice[]))
 bugs/tbolsh_d2_bug4.d(19): Error: cannot implicitly convert expression
 (filter(devices)) of type Filter!(__dgliteral1,UsbDevice[]) to UsbDevice[]
-- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 26 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5491




PST ---
I got several other similar errors in find, like

/usr/include/d/dmd/phobos/std/functional.d(74): Error: static assert  "Bad
unary function: a.parent_id == usb_id for type UsbDevice"
/usr/include/d/dmd/phobos/std/functional.d(87):        instantiated from here:
Body!(UsbDevice)
/usr/include/d/dmd/phobos/std/algorithm.d(2699):        instantiated from here:
result!(UsbDevice)
ampt/field_computer/usbmon.d(312):        instantiated from here:
find!("a.parent_id == usb_id",Filter!(gateways_pred,UsbDevice[]))

Or 

ampt/field_computer/usbmon.d(295): Error: cannot implicitly convert expression
(filter(devlist)) of type Filter!(gateways_pred,UsbDevice[]) to UsbDevice[]


That all makes functional style marginal - I do not know when and why it break
next time.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Jan 26 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5491


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc





 import std.algorithm, std.conv, std.stdio;
 
 enum UsbDevType: uint { indifferent = 0, parent_of_checked = 1, hub_dub_7 =
 0x2001f103, spider_hub = 0x05e30608, gateway = 0x11A03232 }
 struct UsbDevice { //{{{ 
     UsbDevType dev_type;
     // not essential here ...
     string toString(){ return to!string( dev_type ); }
 }
 
 UsbDevice [] gateways_only( UsbDevice []devices ){ return filter!("a.dev_type
 == UsbDevType.gateway" )( devices ); }
This works: auto gateways_only(UsbDevice[] devices) { return filter!((a){ return a.dev_type == UsbDevType.gateway; })(devices);
 The following code:
 _______________________________________________________________________________
 import std.algorithm, std.conv, std.stdio;
 
 enum UsbDevType: uint { indifferent = 0, parent_of_checked = 1, hub_dub_7 =
 0x2001f103, spider_hub = 0x05e30608, gateway = 0x11A03232 }
 struct UsbDevice { //{{{ 
     UsbDevType dev_type;
     // not essential here ...
     string toString(){ return to!string( dev_type ); }
 }
 
 UsbDevice [] gateways_only( UsbDevice []devices ){ return filter!("a.dev_type
 == UsbDevType.gateway" )( devices ); }
 
 unittest{
     auto devices  = [ UsbDevice( UsbDevType.gateway ), UsbDevice(
 UsbDevType.indifferent ), UsbDevice( UsbDevType.hub_dub_7 ) ];
     auto gateways = gateways_only( devices );
     foreach( UsbDevice dev; gateways ) writeln( dev.toString() );
 }
The formatting of your code is very bad. This works: import std.algorithm, std.conv, std.stdio; enum UsbDevType: uint { indifferent = 0, parent_of_checked = 1, hub_dub_7 = 0x2001f103, spider_hub = 0x05e30608, gateway = 0x11A03232 } struct UsbDevice { UsbDevType dev_type; string toString() { return to!string(dev_type); } } auto gateways_only(UsbDevice[] devices) { return filter!((a){ return a.dev_type == UsbDevType.gateway; })(devices); } void main() { auto devices = [UsbDevice(UsbDevType.gateway), UsbDevice(UsbDevType.indifferent), UsbDevice( UsbDevType.hub_dub_7)]; auto gateways = gateways_only(devices); foreach (UsbDevice dev; gateways) writeln(dev.toString()); } Currently string-defined functions that you give to filter, map, etc, can't use symbol names defined elsewhere, like UsbDevType. So you need to use a lambda template, as I have done here, or a proper delegate. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Jan 26 2011
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5491


SomeDude <lovelydear mailmetrash.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lovelydear mailmetrash.com



PDT ---
I haven't checked the original code, but bearophile's code gives on 2.059:

PS E:\DigitalMars\dmd2\samples> rdmd bug.d
gateway

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 22 2012
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=5491


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|NEW                         |RESOLVED
         Resolution|                            |INVALID



This bug report, and the code examples, are rather messy.

This code can't work because Phobos filter() returns a range, so if you want a
UsbDevice[] you need to attach an ".array()" at the end.

UsbDevice [] gateways_only( UsbDevice []devices ){ return filter!("a.dev_type
== UsbDevType.gateway" )( devices ); }


And because of the way "string lambdas" are defined, they can't work well here.
But we have the lambda syntax now.

So code like this works:


import std.algorithm, std.conv, std.stdio, std.array;

enum UsbDevType: uint { indifferent = 0, parent_of_checked = 1, hub_dub_7 =
0x2001f103, spider_hub = 0x05e30608, gateway = 0x11A03232 }
struct UsbDevice { //{{{
    UsbDevType dev_type;
    // not essential here ...
    string toString(){ return to!string( dev_type ); }
}

UsbDevice [] gateways_only( UsbDevice []devices ){ return filter!(a =>
a.dev_type
== UsbDevType.gateway)( devices ).array(); }

void main() {
    auto devices  = [ UsbDevice( UsbDevType.gateway ), UsbDevice(
UsbDevType.indifferent ), UsbDevice( UsbDevType.hub_dub_7 ) ];
    auto gateways = gateways_only( devices );
    foreach( UsbDevice dev; gateways ) writeln( dev.toString() );
}


So there is no bug in DMD/Phobos here, closed as INVALID.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Apr 24 2012