Bosque Language - le nouveau langage de programmation de Microsoft

Il y a quelques jours à peine, Microsoft a présenté au public un nouveau langage de programmation. La langue a reçu le nom de Bosque. La principale mission de la conception du langage est vaut mieux être riche et sain que pauvre et malade afin qu'il soit simple et compréhensible à la fois pour une personne et un ordinateur.



Il y a très peu d'informations jusqu'à présent, la langue est encore très fraîche et instable. Il n'y a que du papier de Mark Maron et du dock au stade initial de l'écriture .


Essayons de considérer quelques fonctionnalités du langage.


1) Toutes les valeurs de Bosque sont immuables afin que chaque bloc de code ne contienne aucun effet secondaire. Selon les auteurs du langage, cela est utile à la fois pour une personne et pour un ordinateur.


, , , 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/fr448814/


All Articles