ほんの数日前、マイクロソフトは新しいプログラミング言語を公開しました。 この言語にはBosqueという名前が付けられました。 言語設計の主な使命は 貧しくて病気よりも金持ちで健康である方が良い そのため、人にとってもコンピューターにとっても簡単で理解しやすいものになります。
今のところ情報はほとんどなく、言語はまだ非常に新鮮で不安定です。 執筆の初期段階ではマークマロンとドックからの紙しかありません。
言語のいくつかの機能を検討してみましょう。
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
//------------------------------------------------------------------------------------------------------- // 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). .. , , .