Bosque Language: el nuevo lenguaje de programación de Microsoft

Hace solo unos días, Microsoft presentó al público un nuevo lenguaje de programación. El idioma recibió el nombre de Bosque. La misión principal del diseño del lenguaje es mejor ser rico y saludable que pobre y enfermo para que sea simple y comprensible tanto para una persona como para una computadora.



Hasta el momento hay muy poca información, el lenguaje aún es muy fresco e inestable. Solo hay papel de Mark Maron y el muelle en la etapa inicial de la escritura .


Tratemos de considerar algunas características del lenguaje.


1) Todos los valores en Bosque son inmutables para que cada bloque de código no contenga ningún efecto secundario. Según los autores del lenguaje, esto es útil tanto para una persona como para una computadora.


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


All Articles