لغة بوسك - لغة البرمجة الجديدة من Microsoft

منذ بضعة أيام فقط ، قدمت Microsoft للجمهور لغة برمجة جديدة. أعطيت اللغة اسم بوسكي. المهمة الرئيسية لتصميم اللغة هي من الأفضل أن تكون غنيًا وصحيًا من الفقراء والمرضى بحيث تكون بسيطة ومفهومة لكل من الشخص والكمبيوتر.



هناك القليل جدا من المعلومات حتى الآن ، واللغة لا تزال جديدة جدا وغير مستقرة. لا يوجد سوى ورقة من مارك مارون والرسو في المرحلة الأولى من الكتابة .


دعنا نحاول النظر في بعض ميزات اللغة.


1) جميع القيم في Bosque غير قابلة للتغيير بحيث لا تحتوي كل فقرة من التعليمات البرمجية على أي آثار جانبية. وفقًا لمؤلفي اللغة ، يعد هذا مفيدًا لكل من الشخص والكمبيوتر.


, , , var!. , .


, , , . —


function internString(ref env: Map<String, Int>, str: String): Int {
    if(env.has(str)) {              //use the ref parameter
        return env.get(str);
    }

    env = env.add(str, env.size()); //update the ref parameter
    return env.size();
}

- , - , Map , .


2) for, while .. . . , map, filter ..


3) . .., , - -zipcode, type- . zipcode, , . : String[Zipcode].


, ZipCode. , ZipCode — . , , .


4) , : myfunc(x=1, y=2)


5) , . map, filter .., .


var v: List[Int?] = List@{1, 2, none, 4};

//Chained - List@{1, 4, 16}
v->filter(fn(x) => x != none)->map[Int](fn(x) => x*x)

//Piped none filter - List@{1, 4, 16}
v |> filter(fn(x) => x != none) |> map[Int](fn(x) => x*x)

//Piped with noneable filter - List@{1, 4, 16}
v |??> map[Int](fn(x) => x*x)

//Piped with none to result - List@{1, 4, none, 16}
v |?> map[Int](fn(x) => x*x)

6) , , rec


7) Bosque . . , , ; .. - , ,


8) entity concept.


concept Bar {
    field f: Int;
}

entity Baz provides Bar {
    field g: Int;
    field h: Bool = true;
}

var y = Baz@{f=1, g=2, h=false}; //Create a Baz entity with the given field values
var x = Baz@{f=1, g=2};          //Create a Baz entity with default value for h


- Boscque
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

//
//This is a bosque test/benchmark for a tic-tac-toe program.
//

namespace NSMain;

entity Board {
    const playerX: String[PlayerMark] = 'x'#PlayerMark;
    const playerO: String[PlayerMark] = 'o'#PlayerMark;

    const allCellPositions: List[[Int, Int]] = List[[Int, Int]]@{
        @[ 0, 0 ], @[ 1, 0 ], @[ 2, 0 ],
        @[ 0, 1 ], @[ 1, 1 ], @[ 2, 1 ],
        @[ 0, 2 ], @[ 1, 2 ], @[ 2, 2 ]
    };

    const winPositionOptions: List[List[[Int, Int]]] = List[List[[Int, Int]]]@{
        List[[Int, Int]]@{ @[ 0, 0 ], @[ 0, 1 ], @[ 0, 2 ] },
        List[[Int, Int]]@{ @[ 0, 1 ], @[ 1, 1 ], @[ 2, 1 ] },
        List[[Int, Int]]@{ @[ 0, 2 ], @[ 1, 2 ], @[ 2, 2 ] },

        List[[Int, Int]]@{ @[ 0, 0 ], @[ 1, 0 ], @[ 2, 0 ] },
        List[[Int, Int]]@{ @[ 1, 0 ], @[ 1, 1 ], @[ 1, 2 ] },
        List[[Int, Int]]@{ @[ 2, 0 ], @[ 2, 1 ], @[ 2, 2 ] },

        List[[Int, Int]]@{ @[ 0, 0 ], @[ 1, 1 ], @[ 2, 2 ] },
        List[[Int, Int]]@{ @[ 0, 2 ], @[ 1, 1 ], @[ 2, 0 ] }
    };

    //Board is a list of marks, indexed by x,y coords from upper left 0 based
    field cells: List[String[PlayerMark]?];

    factory static createInitialBoard(): { cells: List[String[PlayerMark]?] } {
        return @{ cells=List[String[PlayerMark]?]::createOfSize(9, none) };
    }

    method getOpenCells(): List[[Int, Int]] {
        return Board::allCellPositions->filter(fn(pos: [Int, Int]): Bool => {
            return !this->isCellOccupied(pos[0], pos[1]);
        });
    }

    method getCellContents(x: Int, y: Int): String[PlayerMark]? 
        requires 0 <= x && x < 3 && 0 <= y && y < 3;
    {
        return this.cells->at(x + y * 3);
    }

    method isCellOccupied(x: Int, y: Int): Bool {
        return this->getCellContents(x, y) != none;
    }

    method isCellOccupiedWith(x: Int, y: Int, mark: String[PlayerMark]): Bool 
        requires mark == Board::playerX || mark == Board::playerO; 
    {
        return this->getCellContents(x, y) == mark;
    }

    method markCellWith(x: Int, y: Int, mark: String[PlayerMark]): Board 
        requires mark == Board::playerX || mark == Board::playerO;
        requires 0 <= x && x < 3 && 0 <= y && y < 3;
        requires !this->isCellOccupied(x, y);
    {
        return this<~(cells=this.cells->set(x + y * 3, mark));
    }

    hidden method checkSingleWinOption(opt: List[[Int, Int]], mark: String[PlayerMark]): Bool {
        return opt->all(fn(entry: [Int, Int]): Bool => this->isCellOccupiedWith(entry[0], entry[1], mark));
    }

    hidden method checkSingleWinner(mark: String[PlayerMark]): Bool {
        return Board::winPositionOptions->any(fn(opt: List[[Int, Int]]): Bool => this->checkSingleWinOption(opt, mark));
    }

    method checkForWinner(): String[PlayerMark]? {
        if(this->checkSingleWinner(Board::playerX)) {
            return Board::playerX;
        }
        elif(this->checkSingleWinner(Board::playerO)) {
            return Board::playerO;
        }
        else {
            return none;
        }
    }
}

entity Game {
    field winner: String[PlayerMark]? = none;
    field board: Board = Board@createInitialBoard();

    method hasWinner(): Bool {
        return this.winner != none;
    }

    method getWinner(): String[PlayerMark] 
        requires this->hasWinner();
    {
        return this.winner->as[String[PlayerMark]]();
    }

    method makeAutoMove(mark: String[PlayerMark], rnd: Int): Game
        requires !this->hasWinner();
    {
        var! nboard: Board;
        if(!this.board->isCellOccupied(1, 1)) {
            nboard = this.board->markCellWith(1, 1, mark);
        }
        else {
            var opts = this.board->getOpenCells();
            var tup = opts->uniform(rnd);
            nboard = this.board->markCellWith(...tup, mark);
        }

        return this<~( board=nboard, winner=nboard->checkForWinner() );
    }

    method makeExplicitMove(x: Int, y: Int, mark: String[PlayerMark]): Game 
        requires !this.board->isCellOccupied(x, y);
    {
        var nboard = this.board->markCellWith(x, y, mark);
        return this<~( board=nboard, winner=nboard->checkForWinner() );
    }
}

entity PlayerMark provides Parsable {
    field mark: String;

    override static tryParse(str: String): PlayerMark | None {
        return (str == "x" || str == "o") ? PlayerMark@{ mark=str } : none;
    }
}

entrypoint function main(): Game {
    var! game = Game@{};

    game = game->makeAutoMove(Board::playerX, 0);
    game = game->makeAutoMove(Board::playerO, 1);
    game = game->makeAutoMove(Board::playerX, 2);

    game = game->makeExplicitMove(2, 0, Board::playerO);
    game = game->makeExplicitMove(2, 1, Board::playerX);

    return game;
}


, , , Bosque . proof of concept. , , -. , .


Bosque Typescript, , (, Typescript Typescript). .. , , .


" " Bosque, . .

Source: https://habr.com/ru/post/ar448814/


All Articles