Pull to refresh

Comments 5

Любопытная идея, но кажется что могут быть неоднозначности, например:

  • Строка не будет матчиться с самой собой, если в ней есть фигурные скобки (вероятно стоит сделать два типа литералов, различающихся кавычками)

  • Как сматчить с существующим значением? Например,

    someAge = 18;
    match user {
        { age: someAge } -> ...
    }
    

    не сработает, придется писать так?

    match user {
        { age: tmpAge if tmpAge == someAge } -> ...
    }
    
  • Непонятно как работает вывод типов и их сопоставление, например у вас фигурирует тип Option, а какого конкретно типа будет литерал None и по каким правилам он выводится?

  1. Строка не будет матчиться с самой собой, если в ней есть фигурные скобки
    Верно, спасибо за замечание! Исправили, теперь можно ловить фигурные скобки:

    print $ match "value {x}" {
        "value {{x}}" -> "literal braces"     // matches "{x}"
        "value {captured}" -> captured        // captures value
        _ -> "no match"
    }


    Подробнее: тесты

  2. Как сматчить с существующим значением?
    И опять спасибо за вопрос! Вы были правы. Подумали и добавили возможность запина значения:

    expectedAge = 18
    user = { name: "Alice", age: 18 }
    
    print $ match user {
        { age: ^expectedAge } -> "exactly 18"  // compares with expectedAge
        { age: age } -> "other: " ++ show(age) // creates new binding
    }

    Подробнее: тесты

  3. Непонятно как работает вывод типов и их сопоставление, например у вас фигурирует тип Option, а какого конкретно типа будет литерал None и по каким правилам он выводится?

    TL;DR:

    Zero (аналог None) — полиморфный, его тип выводится из контекста:

    // Контекст = аннотация
    x: Option<Int> = Zero      // Zero: Option<Int>
    y: Option<String> = Zero   // Zero: Option<String>
    
    // Контекст = параметр функции
    fun process(opt: Option<Int>) { ... }
    process(Zero)              // Zero: Option<Int>
    
    // Контекст = возвращаемый тип
    fun empty() -> Option<Float> { Zero }  // Zero: Option<Float>
    
    // Контекст = использование рядом с типизированным значением
    opt = Some(42)
    if opt == Zero { ... }     // Zero: Option<Int> (как у opt)

    Правило: анализатор смотрит где Zero используется и подставляет нужный T для Option<T>.

    В рантайме: параметр стирается — getType(Zero) вернёт просто type(Option), без <Int>.

Документация про паттерн матчинг
Документация про типы

Выглядит очень интересно. Я взглянул на примеры и увидел знакомый синтаксис. Не ожидал, что в Go можно создать язык подобным образом.

Реализовали виртуальную машину, получили ускорение 5-10x, что в два раза ниже ожидаемого, но для начала неплохо.

Sign up to leave a comment.

Articles