Műveletek és függvények

Ahogy a qubit adattípus leírásában részletesebben is kifejtjük, a kvantumszámítások a célzott kvantumprocesszoron natívan támogatott műveletek mellékhatásai formájában lesznek végrehajtva. Ezek valójában az egyetlen mellékhatásai a Q#. Mivel minden típus nem módosítható, nincs olyan mellékhatás, amely hatással lenne egy olyan értékre, amely kifejezetten szerepel a fájlban Q#. Ezért mindaddig, amíg egy adott meghívható implementáció nem hívja meg közvetlenül vagy közvetve ezen natívan implementált műveletek egyikét sem, a végrehajtás mindig ugyanazt a kimenetet eredményezi, ugyanazzal a bemenettel.

Q# lehetővé teszi az ilyen tisztán determinisztikus számítások függvényekre való explicit felosztását. Mivel a natívan támogatott utasítások nem rögzítettek, és magukba a nyelvbe vannak beépítve, hanem teljes mértékben konfigurálhatók és kódtárként Q# vannak kifejezve, a determinizmust az garantálja, hogy a függvények csak más függvényeket tudnak meghívni, és nem tudnak műveleteket meghívni. Emellett a nem determinisztikus natív utasítások, azaz a kvantumállapotra gyakorolt hatásuk miatt műveletekként jelennek meg. Ezzel a két korlátozással a függvények azonnal kiértékelhetők, amint ismert a bemeneti értékük, és elvileg soha nem kell többször kiértékelni ugyanazt a bemenetet.

Q# ezért a hívható elemek két típusát különbözteti meg: a műveleteket és a függvényeket. Minden hívható egyetlen argumentumot (potenciálisan rekordértéket) fogad bemenetként, és egyetlen értéket (rekordot) állít elő kimenetként. Szintaktikailag a művelettípus kifejezése <TIn> => <TOut> is <Char>, ahol <TIn> az argumentumtípussal kell helyettesíteni, <TOut> a visszatérési típussal kell lecserélni, és <Char> a műveleti jellemzőkkel kell helyettesíteni. Ha nincs szükség jellemzők megadására, a szintaxis a következőre <TIn> => <TOut>egyszerűsíthető: . Hasonlóképpen, a függvénytípusok a következőképpen vannak kifejezve: <TIn> -> <TOut>.

A determinizmus garanciája mellett a műveletek és a függvények között nincs különbség. Mindkettő olyan első osztályú érték, amely szabadon átadható; ezek más hívható függvényeknek visszaadott értékekként vagy argumentumként használhatók, ahogy az alábbi példában látható:

function Pow<'T>(op : 'T => Unit, pow : Int) : 'T => Unit {
    return PowImpl(op, pow, _);
}

Mindkettő példányosítható egy típusparametrikás definíció alapján, például a fenti típusparametrizált függvény Pow alapján, és részben alkalmazhatók a return példában szereplő utasításban leírtak szerint.

A művelet jellemzői

A bemeneti és kimeneti típussal kapcsolatos információk mellett a művelet típusa a művelet jellemzőire vonatkozó információkat is tartalmaz. Ez az információ például azt ismerteti, hogy a művelet mely funktorokat támogatja. A belső reprezentáció emellett optimalizálással kapcsolatos információkat is tartalmaz, amelyeket a fordító kikövetkeztetett.

A műveletek jellemzői előre definiált és beépített címkék. Ezek egy speciális kifejezés formájában vannak kifejezve, amely a típus aláírásának része. A kifejezés egy előre definiált címkekészletből vagy egy támogatott bináris operátoron keresztüli jellemzőkifejezések kombinációjából áll.

Két előre definiált készlet van, Adj és Ctl.

  • Adj az a készlet, amely egyetlen címkét tartalmaz, amely azt jelzi, hogy egy művelet szomszédos, ami azt jelenti, hogy támogatja a Adjoint funktort , és az alkalmazott kvantumátalakítás "visszavonható", azaz invertált lehet.
  • Ctl az a készlet, amely egyetlen címkét tartalmaz, amely azt jelzi, hogy egy művelet irányítható, ami azt jelenti, hogy támogatja a Controlled funktort , és a végrehajtása más qubitek állapotán konfigurálható.

A jellemzőkifejezések részeként támogatott két operátor a halmaz uniója + és a halmaz metszete *. Az EBNF-ben

    predefined = "Adj" | "Ctl";
    characteristics = predefined 
        | "(", characteristics, ")" 
        | characteristics ("+"|"*") characteristics;

Ahogy várható volt, nagyobb a prioritása, * mint + a balszociatívnak. Az egységművelet típusa például a következőképpen van kifejezve <TIn> => <TOut> is Adj + Ctl: , ahol <TIn> le kell cserélni a művelet argumentumának típusára, és <TOut> a visszaadott érték típusára kell cserélni.

Megjegyzés

Az ilyen jellegű műveletek jellemzőinek jelzése két fő előnnyel jár; egy esetében az új címkék anélkül vezethetők be, hogy exponenciálisan sok nyelvi kulcsszót kellene használniuk a címkék összes kombinációjához. Talán ennél is fontosabb, hogy a műveletek jellemzőinek jelzésére használt kifejezések a jövőben is támogatják a műveleti jellemzők paraméterezését.