Thread overview
ternary op assign
May 02, 2024
monkyyy
May 02, 2024
Stefan Koch
May 02, 2024
monkyyy
May 16, 2024
Quirin Schroll
May 16, 2024
monkyyy
Mar 18
monkyyy
Mar 24
monkyyy
May 02, 2024

foo?=bar:baz is rewritten as foo.opOpAssign!("?:")(bar,baz)

foo[i]?=bar:baz opIndexOpAssign

for basic types it acts as foo=(bool)bar?foo:(typeof(foo))baz

May 02, 2024

On Thursday, 2 May 2024 at 17:42:28 UTC, monkyyy wrote:

>

foo?=bar:baz is rewritten as foo.opOpAssign!("?:")(bar,baz)

foo[i]?=bar:baz opIndexOpAssign

for basic types it acts as foo=(bool)bar?foo:(typeof(foo))baz

I find this syntax confusing, I would interpret that as:

foo[i] = (foo[i] ? bar : baz);

May 02, 2024

On Thursday, 2 May 2024 at 18:17:12 UTC, Stefan Koch wrote:

>

On Thursday, 2 May 2024 at 17:42:28 UTC, monkyyy wrote:

>

foo?=bar:baz is rewritten as foo.opOpAssign!("?:")(bar,baz)

foo[i]?=bar:baz opIndexOpAssign

for basic types it acts as foo=(bool)bar?foo:(typeof(foo))baz

I find this syntax confusing, I would interpret that as:

foo[i] = (foo[i] ? bar : baz);

often the statement you want to write is a=condition?b:a which repeats a, the way to simplify (and prevent int promtion issues) is with the += family of statements; but there isnt a clear one for if(cond)a=b

Simd(/waterfalled code) has to do bit mask tricks, and I think you could wrap that up in a data structure with the opslice as recursive templates for opindex logic

a/=4;
b+=a;
if(a>b)a=b;
---
a[0..4]/=4;
b[0..4]+=a[0..4];
????
May 16, 2024

On Thursday, 2 May 2024 at 17:42:28 UTC, monkyyy wrote:

>

foo?=bar:baz is rewritten as foo.opOpAssign!("?:")(bar,baz)

foo[i]?=bar:baz opIndexOpAssign

for basic types it acts as foo=(bool)bar?foo:(typeof(foo))baz

Isn’t this just if (!bar) foo = baz;?

Where would the user-defined operator be useful?

May 16, 2024

On Thursday, 16 May 2024 at 16:57:17 UTC, Quirin Schroll wrote:

>

On Thursday, 2 May 2024 at 17:42:28 UTC, monkyyy wrote:

>

foo?=bar:baz is rewritten as foo.opOpAssign!("?:")(bar,baz)

foo[i]?=bar:baz opIndexOpAssign

for basic types it acts as foo=(bool)bar?foo:(typeof(foo))baz

Isn’t this just if (!bar) foo = baz;?

Where would the user-defined operator be useful?

when bar depends on foo; such as a user defined cond, lets saya database query that takes in lamdas

foo?=a=>a%2:baz

and when its "multiable data single instruction", simd or parrellizism, ranges etc. and theres something in that index
you can not write if(!bar[foo's slice????]) foo=baz[...];

March 15
Does this appear in other languages? I'm curious what experience there is with it.

March 18
On Sunday, 16 March 2025 at 06:45:03 UTC, Walter Bright wrote:
> Does this appear in other languages? I'm curious what experience there is with it.

Not that I know of
March 23

On Thursday, 2 May 2024 at 17:42:28 UTC, monkyyy wrote:

>

foo?=bar:baz is rewritten as foo.opOpAssign!("?:")(bar,baz)

foo[i]?=bar:baz opIndexOpAssign

for basic types it acts as foo=(bool)bar?foo:(typeof(foo))baz

What will you do when you use ternary pipe?

import std.stdio;

void main()
{
    int x = 10, y = 20, z = 5;

    string result = (x > y) ? "X is largest"
                  : (y > z) ? "Y is largest"
                            : "Z is largest";

    result.writeln;
}

SDB@79

March 23

On Sunday, 23 March 2025 at 19:54:29 UTC, Salih Dincer wrote:

>

What will you do when you use ternary pipe?

import std.stdio;

struct TernaryAssignable(T) {
    T value;

    // Implements `foo ?= bar : baz`
    ref T opOpAssign(string op)(T condition, T alternative) if (op == "?:") {
        if (condition) {
            return value;
        } else {
            return value = alternative;
        }
    }
}

void main()
{
    auto foo = TernaryAssignable!int(42);
    int bar = 1;  // true condition
    int baz = 100; // alternative value

    foo ?= bar : baz; // Equivalent to: foo = (bar ? foo : baz)

    writeln(foo.value); // Should print 42, since bar is nonzero (true)

    foo ?= 0 : baz; // Now foo should take baz since condition is false

    writeln(foo.value); // Should print 100
}
>

Is it promising?

SDB@79

March 24

On Sunday, 23 March 2025 at 19:59:24 UTC, Salih Dincer wrote:

>
import std.stdio;

struct TernaryAssignable(T) {
    T value;

    // Implements `foo ?= bar : baz`
    ref T opOpAssign(string op)(T condition, T alternative) if (op == "?:") {
        if (condition) {
            return value;
        } else {
            return value = alternative;
        }
    }
}

void main()
{
    auto foo = TernaryAssignable!int(42);
    int bar = 1;  // true condition
    int baz = 100; // alternative value

    foo ?= bar : baz; // Equivalent to: foo = (bar ? foo : baz)

    writeln(foo.value); // Should print 42, since bar is nonzero (true)

    foo ?= 0 : baz; // Now foo should take baz since condition is false

    writeln(foo.value); // Should print 100
}
>

Im imagining(if you like assign pass thru)


struct TernaryAssignable(T) {
    T value;

    // Implements `foo ?= bar : baz`
    ref T opOpAssign(string op,S)(S condition, T alternative) if (op == "?:") {
        if ( ! condition(value)) {
            return value;
        } else {
            return value = alternative;
        }
    }
}
bool isEmpty(string s)=>s.length==0;
bool hasAt(string s)=>s.canFind('@');
bool hasDot(string s)=>true;//todo
string sanitizeEmail(ref TernaryAssignable!string s)=>
   s ?= &isEmpty : "missingemail@dlang.org"
     ?= &hasAt   : s~"@gmail.com"
     ?= &hasDot  : s~".com";

unittest("".sanitizeEmail=="missingemail@dlang.org");
unittest("crazymonkyyy@gmail".sanitizeEmail=="crazymonkyyy@gmail.com");