Thread overview
toLower
Aug 15
Joel
Aug 15
Joel
Aug 15
bachmeier
Aug 17
Joel
Aug 17
bachmeier
Aug 17
Joel
Aug 15
ryuukk_
August 15

How come toLower works in the sort quotes, but not in the map?

void main() {
    import std;
    "EzraTezla"
        .to!(char[])
        .byCodeUnit
        .sort!"a.toLower<b.toLower"
        .map!(c => c.toLower)
        .writeln;
}

onlineapp.d(60): Error: toLower matches conflicting symbols:
/dlang/dmd/linux/bin64/../../src/phobos/std/uni/package.d(9819): function std.uni.toLower
/dlang/dmd/linux/bin64/../../src/phobos/std/ascii.d(637): function std.ascii.toLower!char.toLower
/dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(479): instantiated from here: MapResult!(__lambda4, SortedRange!(ByCodeUnitImpl, "a.toLower>b.toLower", SortedRangeOptions.assumeSorted))
onlineapp.d(60): instantiated from here: map!(SortedRange!(ByCodeUnitImpl, "a.toLower>b.toLower", SortedRangeOptions.assumeSorted))

August 15

On Tuesday, 15 August 2023 at 16:47:36 UTC, Joel wrote:

>

How come toLower works in the sort quotes, but not in the map?

void main() {
    import std;
    "EzraTezla"
        .to!(char[])
        .byCodeUnit
        .sort!"a.toLower<b.toLower"
        .map!(c => c.toLower)
        .writeln;
}

When you pass a string to a lambda, it's evaluated in std.functional.unaryFun/binaryFun.

At that point, these modules are imported for use in string expressions:

import std.algorithm, std.conv, std.exception, std.math, std.range, std.string;
import std.meta, std.traits, std.typecons;

And std.string itself publically imports:

public import std.uni : icmp, toLower, toLowerInPlace, toUpper, toUpperInPlace;

But does not import std.ascii! So there's no ambiguity inside the sort string expression between the two toLower functions..

August 15

On Tuesday, 15 August 2023 at 16:47:36 UTC, Joel wrote:

>

How come toLower works in the sort quotes, but not in the map?

void main() {
    import std;
    "EzraTezla"
        .to!(char[])
        .byCodeUnit
        .sort!"a.toLower<b.toLower"
        .map!(c => c.toLower)
        .writeln;
}

onlineapp.d(60): Error: toLower matches conflicting symbols:
/dlang/dmd/linux/bin64/../../src/phobos/std/uni/package.d(9819): function std.uni.toLower
/dlang/dmd/linux/bin64/../../src/phobos/std/ascii.d(637): function std.ascii.toLower!char.toLower
/dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/iteration.d(479): instantiated from here: MapResult!(__lambda4, SortedRange!(ByCodeUnitImpl, "a.toLower>b.toLower", SortedRangeOptions.assumeSorted))
onlineapp.d(60): instantiated from here: map!(SortedRange!(ByCodeUnitImpl, "a.toLower>b.toLower", SortedRangeOptions.assumeSorted))

This error message is unreadable, maybe an issue should be opened about it, so it could be improved, took me a while to understand, or rather "decipher", what it says..

August 15

On Tuesday, 15 August 2023 at 16:54:49 UTC, FeepingCreature wrote:

>

On Tuesday, 15 August 2023 at 16:47:36 UTC, Joel wrote:

>

[...]
When you pass a string to a lambda, it's evaluated in std.functional.unaryFun/binaryFun.

At that point, these modules are imported for use in string expressions:

import std.algorithm, std.conv, std.exception, std.math, std.range, std.string;
import std.meta, std.traits, std.typecons;

And std.string itself publically imports:

public import std.uni : icmp, toLower, toLowerInPlace, toUpper, toUpperInPlace;

But does not import std.ascii! So there's no ambiguity inside the sort string expression between the two toLower functions..

How do I get it to work?

I tried std.ascii.toLower. And using alias toLower=std.ascii.toLower;

August 15

On Tuesday, 15 August 2023 at 20:09:28 UTC, Joel wrote:

>

On Tuesday, 15 August 2023 at 16:54:49 UTC, FeepingCreature wrote:

>

On Tuesday, 15 August 2023 at 16:47:36 UTC, Joel wrote:

>

[...]
When you pass a string to a lambda, it's evaluated in std.functional.unaryFun/binaryFun.

At that point, these modules are imported for use in string expressions:

import std.algorithm, std.conv, std.exception, std.math, std.range, std.string;
import std.meta, std.traits, std.typecons;

And std.string itself publically imports:

public import std.uni : icmp, toLower, toLowerInPlace, toUpper, toUpperInPlace;

But does not import std.ascii! So there's no ambiguity inside the sort string expression between the two toLower functions..

How do I get it to work?

I tried std.ascii.toLower. And using alias toLower=std.ascii.toLower;

Changing your map line to

.map!(c => std.uni.toLower(c))

works for me.

August 16

On Tuesday, 15 August 2023 at 20:09:28 UTC, Joel wrote:

>

On Tuesday, 15 August 2023 at 16:54:49 UTC, FeepingCreature wrote:

>

But does not import std.ascii! So there's no ambiguity inside the sort string expression between the two toLower functions..

How do I get it to work?

I tried std.ascii.toLower. And using alias toLower=std.ascii.toLower;

To elaborate more, toLower doesn't work because function-scope aliases are not considered for UFCS.

    alias toLower = std.ascii.toLower;

    ...
    // So this does actually work:
        .map!toLower
    // but this does not, because it looks for a UFCS-capable symbol
        .map!(c => c.toLower)
    // but this does again
        .map!(c => toLower(c))

August 17

On Wednesday, 16 August 2023 at 05:40:09 UTC, FeepingCreature wrote:

>

On Tuesday, 15 August 2023 at 20:09:28 UTC, Joel wrote:

>

On Tuesday, 15 August 2023 at 16:54:49 UTC, FeepingCreature wrote:

>

But does not import std.ascii! So there's no ambiguity inside the sort string expression between the two toLower functions..

How do I get it to work?

I tried std.ascii.toLower. And using alias toLower=std.ascii.toLower;

To elaborate more, toLower doesn't work because function-scope aliases are not considered for UFCS.

    alias toLower = std.ascii.toLower;

    ...
    // So this does actually work:
        .map!toLower
    // but this does not, because it looks for a UFCS-capable symbol
        .map!(c => c.toLower)
    // but this does again
        .map!(c => toLower(c))

I get an compile time error with sort after using toLower, putting in array before sort, didn’t work:

```d
void main() {
    Import std;

    "EzraTezla"
        .to!(char[])
        .byCodeUnit
        .map!(std.uni.toLower)
        .sort!"a<b"
        .writeln;
}
```
onlineapp.d(8): Error: none of the overloads of template `std.algorithm.sorting.sort` are callable using argument types `!("a<b")(MapResult!(toLower, ByCodeUnitImpl))`
/dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/sorting.d(1925):        Candidate is: `sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)`
  with `less = "a<b",
       ss = SwapStrategy.unstable,
       Range = MapResult!(toLower, ByCodeUnitImpl)`
  must satisfy one of the following constraints:
`       hasSwappableElements!Range
       hasAssignableElements!Range
       ss != SwapStrategy.unstable`
August 17

On Thursday, 17 August 2023 at 09:28:05 UTC, Joel wrote:

>

I get an compile time error with sort after using toLower, putting in array before sort, didn’t work:

```d
void main() {
    Import std;

    "EzraTezla"
        .to!(char[])
        .byCodeUnit
        .map!(std.uni.toLower)
        .sort!"a<b"
        .writeln;
}
```

It works for me. Modifying your code to

void main() {
    import std;

    "EzraTezla"
        .to!(char[])
        .byCodeUnit
        .map!(std.uni.toLower)
        .array
        .sort!"a<b"
        .writeln;
}

compiles and gives the expected output. https://run.dlang.io/is/85VjiL

August 17

On Thursday, 17 August 2023 at 14:14:00 UTC, bachmeier wrote:

>

On Thursday, 17 August 2023 at 09:28:05 UTC, Joel wrote:

>

I get an compile time error with sort after using toLower, putting in array before sort, didn’t work:

```d
void main() {
    Import std;

    "EzraTezla"
        .to!(char[])
        .byCodeUnit
        .map!(std.uni.toLower)
        .sort!"a<b"
        .writeln;
}
```

It works for me. Modifying your code to

void main() {
    import std;

    "EzraTezla"
        .to!(char[])
        .byCodeUnit
        .map!(std.uni.toLower)
        .array
        .sort!"a<b"
        .writeln;
}

compiles and gives the expected output. https://run.dlang.io/is/85VjiL

void main() {
    import std;

    "EzraTezla"
        .to!(char[])
        .byCodeUnit
        .map!(std.ascii.toLower)
        .array
        .sort!"a<b"
        .writeln;
}

std.uni.toLower works, but not ascii. Ascii works with bycode after map, though.

/Library/D/dmd/src/phobos/std/algorithm/sorting.d(1936): Error: static assert: "When using SwapStrategy.unstable, the passed Range 'char[]' must either fulfill hasSwappableElements, or hasAssignableElements, both were not the case"
once.d(9): instantiated from here: sort!("a<b", SwapStrategy.unstable, char[])

August 18

On Thursday, 17 August 2023 at 09:28:05 UTC, Joel wrote:

>
        .map!(std.uni.toLower)
        .sort!"a<b"
        .writeln;
}
```
onlineapp.d(8): Error: none of the overloads of template `std.algorithm.sorting.sort` are callable using argument types `!("a<b")(MapResult!(toLower, ByCodeUnitImpl))`
/dlang/dmd/linux/bin64/../../src/phobos/std/algorithm/sorting.d(1925):        Candidate is: `sort(alias less = "a < b", SwapStrategy ss = SwapStrategy.unstable, Range)(Range r)`
  with `less = "a<b",
       ss = SwapStrategy.unstable,
       Range = MapResult!(toLower, ByCodeUnitImpl)`
  must satisfy one of the following constraints:
`       hasSwappableElements!Range
       hasAssignableElements!Range
       ss != SwapStrategy.unstable`

map generates a range r whose elements can be accessed by mutable reference only if the result of calling the map function (on a source element) is a mutable reference. But std.uni.toLower returns by value, and sort requires r.front to be a mutable reference.

I'll look at improving the docs.