edgedb / easy-edgedb

An illustrated textbook designed to be a one-stop shop for learning EdgeDB
https://www.edgedb.com/easy-edgedb
77 stars 39 forks source link

Chapter 11: Wrong `fight` function #74

Closed vladpi closed 1 year ago

vladpi commented 2 years ago

Chapter 11 has a function fight:

function fight(one: Person, two: Person) -> str
  using (
    one.name ++ ' wins!' IF one.strength > two.strength ELSE two.name ++ ' wins!'
  );

But when I try to create it, I get this error:

error: return cardinality mismatch in function declared to return exactly one value
    ┌─ ./dbschema/default.esdl:104:13
    │  
104 │         using (
    │ ╭─────────────^
105 │ │         one.name ++ ' wins!' IF one.strength > two.strength ELSE two.name ++ ' wins!'
106 │ │       );
    │ ╰───────^ error
    │  
    = Function may return an empty set.

edgedb error: cannot proceed until .esdl files are fixed

As far as I understand, this happens because name and strength are optional fields and the function may return an empty set. The problem is solved by coalescing, but this is discussed in the next chapter (12)

riolly commented 2 years ago

Because name and strength are possibly null, we have to handle that condition. The easiest way is using ??

function fight(one: Person, two: Person) -> str
    using (
      (one.name ?? '') ++ ' wins!' IF (one.strength ?? 0) > (two.strength ?? 0) ELSE (two.name ?? '') ++ ' wins!'
    )

Or you can use WITH for more easy-to-read if statement

function fight(first_person: Person, second_person: Person) -> str
    using (
      with 
        first_person_name := first_person.name ?? 'First person',
        first_person_strength := first_person.strength ?? 0,
        second_person_name := second_person.name ?? 'Second person',
        second_person_strength := second_person.strength ?? 0,
      select (
        first_person_name ++ ' wins!' 
          if first_person_strength > second_person_strength 
        else 'Draw!' 
          if first_person_strength = second_person_strength
        else second_person_name ++ ' wins!'
      )
    )
autistechsolutions commented 1 year ago

The overloaded fight function in Chapter 12 throws the same error.

Dhghomon commented 1 year ago

I see the fight functions have been fixed, added them to the chapter schemas as well so should be good to close now.