{"id":605124,"date":"2019-09-03T09:52:11","date_gmt":"2019-09-03T16:52:11","guid":{"rendered":"https:\/\/www.microsoft.com\/en-us\/research\/?p=605124"},"modified":"2019-09-03T09:52:11","modified_gmt":"2019-09-03T16:52:11","slug":"rocket-fast-embedded-typescript-for-makecode-arcade","status":"publish","type":"post","link":"https:\/\/www.microsoft.com\/en-us\/research\/blog\/rocket-fast-embedded-typescript-for-makecode-arcade\/","title":{"rendered":"Rocket-fast embedded TypeScript for MakeCode Arcade"},"content":{"rendered":"<p><a href=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788.png\"><img loading=\"lazy\" decoding=\"async\" class=\"size-large wp-image-605154 aligncenter\" src=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-1024x576.png\" alt=\"\" width=\"1024\" height=\"576\" srcset=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-1024x576.png 1024w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-300x169.png 300w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-768x432.png 768w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-1066x600.png 1066w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-655x368.png 655w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-343x193.png 343w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-640x360.png 640w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-960x540.png 960w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-1280x720.png 1280w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788.png 1400w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/p>\n<p>When we began developing <a href=\"https:\/\/www.microsoft.com\/en-us\/makecode\">Microsoft MakeCode<\/a>, a computing education platform, it was all about making programming easier, more engaging, and just plain friendlier. After all, if we were going to inspire the next generation of coders, easier entry into the world of computer science would be important. To accomplish this, we designed a high-level programming language with text and graphical input modalities along with a simple yet powerful set of programming libraries. Today, <a href=\"https:\/\/www.microsoft.com\/en-us\/research\/publication\/static-typescript\/\">the language, Static TypeScript (STS), is used in all seven MakeCode editors<\/a>, and its ability to meet the demands of programs requiring higher levels of performance is on full display in the latest addition to the platform, <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/arcade.makecode.com\/\">MakeCode Arcade<span class=\"sr-only\"> (opens in new tab)<\/span><\/a>.<\/p>\n<p>With Arcade, STS lets developers of all skill levels easily write cool retro-style pixelated games\u2014think Super Mario Bros., but even better because it\u2019s designed by the user\u2014to be run either inside a virtual game console in the browser or on inexpensive microcontroller-based handhelds.<\/p>\n<p>STS, a subset of TypeScript, is an evolution of previous projects on beginner-friendly programming environments that started in the <a href=\"https:\/\/www.microsoft.com\/en-us\/research\/group\/research-software-engineering-rise\/\">Research in Software Engineering group<\/a> in late 2010. This work was eventually extended to include the programming of microcontrollers (MCUs), small computers typically used in refrigerators, electric toothbrushes, car control systems, and countless other everyday objects. Unfortunately, MCUs are usually programmed in C, C++, or straight in assembly, none of which are particularly beginner friendly. So over the years, efforts have been underway to run modern languages such as JavaScript and Python on them. Because full-fledged JIT compilers like <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/v8.dev\/\">V8<span class=\"sr-only\"> (opens in new tab)<\/span><\/a> or <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/github.com\/microsoft\/ChakraCore\">ChakraCore<span class=\"sr-only\"> (opens in new tab)<\/span><\/a> require megabytes, not kilobytes of memory\u2014a typical MCU has between 2 KB and 256 KB of RAM\u2014these languages usually involve interpreters like <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/iotjs.net\/\">IoT.js<span class=\"sr-only\"> (opens in new tab)<\/span><\/a>, <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/duktape.org\/\">Duktape<span class=\"sr-only\"> (opens in new tab)<\/span><\/a>, or <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/micropython.org\/\">MicroPython<span class=\"sr-only\"> (opens in new tab)<\/span><\/a>. The problem with interpreters is high memory usage\u2014though not nearly as high as the demand from JIT compilers\u2014leaving little room on the devices themselves for the program developers have written. STS, compiled in the MakeCode web application, is a more efficient alternative to the embedded interpreter approach, and statically typed, it makes for a less surprising programming experience.<\/p>\n<h3>Throwing back with MakeCode Arcade<\/h3>\n<p>While memory usage requirements initially guided the design of the MakeCode runtime system and slow execution time isn\u2019t generally a significant problem for most MakeCode editors, execution performance became paramount with Arcade. Arcade sports a 160 \u00d7 120 pixel screen with a palette of 16 colors, a four-channel retro-appropriate sound synthesizer, and six game buttons plus menu and reset. Arcade hardware runs on MCUs with around 100 KB of RAM running at around 100 megahertz.<\/p>\n<div id=\"attachment_605142\" style=\"width: 1034px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig1.png.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-605142\" class=\"wp-image-605142 size-large\" src=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig1.png-1024x964.jpg\" alt=\"Handheld devices produced by Microsoft hardware partners use Arm Cortex-M4 MCUs, which have around 100 KB of RAM running at around 100 megahertz. Complex MakeCode Arcade games run at about 30 frames per second on the devices.\" width=\"1024\" height=\"964\" srcset=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig1.png-1024x964.jpg 1024w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig1.png-300x283.jpg 300w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig1.png-768x723.jpg 768w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig1.png.jpg 1840w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><p id=\"caption-attachment-605142\" class=\"wp-caption-text\">Handheld devices produced by Microsoft hardware partners use Arm Cortex-M4 MCUs, which have around 100 KB of RAM running at around 100 megahertz. Complex MakeCode Arcade games run at about 30 frames per second on the devices.<\/p><\/div>\n<p>While the console specification\u2014save for the speed\u2014harks back to the 1980s, Arcade provides programmers with decidedly 2010s high-level, easy-to-use APIs. Simple games can be put together in just a few lines of code or a few blocks snapped together depending on whether you\u2019re using the text or block editor. From there, games can be made progressively more involved\u2014all the way to custom AI-run opponents.<\/p>\n<div id=\"attachment_605148\" style=\"width: 1034px\" class=\"wp-caption aligncenter\"><a href=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig2.jpg\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-605148\" class=\"wp-image-605148 size-large\" src=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig2-1024x308.jpg\" alt=\"Like other MakeCode editors, Arcade includes a simulator and offers programmers the choice of writing games in blocks (left) or text (right). Most programmers using the text editor are writing very simple programs that, because of type inference, look exactly the same in TypeScript and JavaScript, so for name recognition reasons, the text editor is labeled JavaScript.\" width=\"1024\" height=\"308\" srcset=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig2-1024x308.jpg 1024w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig2-300x90.jpg 300w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig2-768x231.jpg 768w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/makecode_arcade_fig2.jpg 1238w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><p id=\"caption-attachment-605148\" class=\"wp-caption-text\">Like other MakeCode editors, Arcade includes a simulator and offers programmers the choice of writing games in blocks (left) or text (right). Most programmers using the text editor are writing very simple programs that, because of type inference, look exactly the same in TypeScript and JavaScript, so for name recognition reasons, the text editor is labeled JavaScript.<\/p><\/div>\n<p>To provide enough performance while still allowing a high-level of abstraction, MakeCode compiles a subset of <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/www.typescriptlang.org\/\">TypeScript<span class=\"sr-only\"> (opens in new tab)<\/span><\/a> directly to <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/ARM_architecture#Thumb\">Arm Thumb<span class=\"sr-only\"> (opens in new tab)<\/span><\/a> machine code, all locally in the MakeCode web application, so no installation is required. After the first load, the MakeCode web app runs fully offline, as it doesn\u2019t rely on cloud service for compilation. Programs are then transferred using a familiar USB flash drive mechanism or directly with the new <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/wicg.github.io\/webusb\/\">WebUSB standard<span class=\"sr-only\"> (opens in new tab)<\/span><\/a>.<\/p>\n<p>To support static compilation, in defining STS, we dropped <a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/makecode.com\/language\">a number of JavaScript \u201cfeatures\u201d<span class=\"sr-only\"> (opens in new tab)<\/span><\/a> of limited use in education, such as <em>eval<\/em>, <em>with<\/em>, and prototype-based inheritance, instead going with more traditional classes. While this prevents running of existing JavaScript libraries on MCUs, most of these libraries are not applicable or would need rewriting to fit the memory constraints. Moreover, it is perfectly possible to write complex programs without using these features; for example, the vast majority of MakeCode web app code, itself written in regular TypeScript, doesn\u2019t use them.<\/p>\n<h3>Compilation and runtime system<\/h3>\n<p>The compiler is quite simple as far as compilers go. It uses a simple stack-based model for temporary values, and there\u2019s no register allocation. In fact, there are no optimizations to speak of except for a simple peep-hole pass on the resulting assembly code. All values are represented uniformly as 32-bit words.<\/p>\n<p>All numbers are conceptually 64-bit floating point values as mandated by JavaScript semantics. However, when the value happens to be a signed integer fitting in 31 bits, it\u2019s stored as a tagged integer; otherwise, it\u2019s a pointer to a boxed double. Implementations of arithmetic operations check if both arguments are integers and, if so, execute the few assembly instructions needed; otherwise, they call into a software floating-point library.<\/p>\n<p>Most other values are pointers to objects either in the garbage-collected heap or read-only flash (MCUs usually have about four times as much flash as RAM, so it\u2019s important not to copy read-only data to RAM). The first word of such objects points to a virtual table, and the subsequent words contain user-defined data fields. The v-table contains runtime type information and pointers to various methods of the object, laid out based on class hierarchy, as well as a list of properties of the object and the memory addresses where they reside.<\/p>\n<p>Following regular TypeScript, the compiler doesn\u2019t generate any runtime type checks on casts. Instead, checks are generated upon usage. A property access is compiled depending on the static type of the accessed object: For classes, it\u2019s a simple memory lookup. For interfaces, we consult the hashed list of properties in the v-table, which is twice as slow, and for dynamic key-value mappings, we use a linear lookup, which is around six times slower (typically, this is the only technique used in embedded interpreters).<\/p>\n<p>Objects\u2014including classes, dynamic maps, binary buffers, and function closures\u2014are allocated on a garbage-collected heap. The garbage collection (GC) algorithm is a simple, nonmoving\u2014yet precise\u2014<a class=\"msr-external-link glyph-append glyph-append-open-in-new-tab glyph-append-xsmall\" rel=\"noopener noreferrer\" target=\"_blank\" href=\"https:\/\/en.wikipedia.org\/wiki\/Tracing_garbage_collection#Na%C3%AFve_mark-and-sweep\">mark-and-sweep<span class=\"sr-only\"> (opens in new tab)<\/span><\/a>. We previously used a reference counting allocator; however, given the complexity of control flow, including between concurrent threads of execution; the simplicity of the compiler; and the fact that all values are potentially reference counted, including numbers, we had to update reference counts on every function call. Switching to GC improved speed by a factor of two.<\/p>\n<p>The generated code uses a C++ runtime, which is compiled once in the cloud, and the generated code is linked to it. C++ functions can declare typical signatures with integers, bools, and pointers, and appropriate conversion code is inserted by the compiler at calls. If the functions don&#8217;t store them, the runtime objects coming in as arguments require no special treatment. If the pointers to them are stored, they need to be registered with the GC.<\/p>\n<p>The compiler automatically generates TypeScript function declarations from the C++ function prototypes with a specific annotation. Such annotations can also include instructions about how these are to be exposed as blocks.<\/p>\n<h3>Performance and what it means moving forward<\/h3>\n<p>Our compiler exhibits quite good performance. On benchmarks involving heavy object access, it\u2019s at least 20 times faster than MicroPython or Duktape and less than two times slower than V8. On other benchmarks, such as floating point or heavy array access, it\u2019s still two to eight times faster than interpreters. We\u2019ve also implemented a custom byte-code interpreter for potential use on Xbox and iOS, which don\u2019t allow dynamic code generation. It uses the same memory layout as the Arm back end and is about five times slower, though still much faster than other interpreters. This points to both the compiled nature and the memory layouts as causes of good performance. Complex MakeCode Arcade games run at about 30 frames per second on Arm Cortex-M4 MCUs. Extrapolating from our benchmarks, interpreters running the same code would run at an unplayable few frames per second.<\/p>\n<p>We see statically typed languages such as STS playing an important role in the future of IoT, allowing embedded devices to run more efficiently\u2014faster and, as a result, with reduced energy requirements\u2014as well as providing programmers who aren\u2019t embedded developers with an easier, higher-level alternative to the lower-level languages generally used to program these devices. But for now, we\u2019re excited for kids just learning to code and advanced developers alike to have some fun creating games they want to play and share.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When we began developing Microsoft MakeCode, a computing education platform, it was all about making programming easier, more engaging, and just plain friendlier. After all, if we were going to inspire the next generation of coders, easier entry into the world of computer science would be important. To accomplish this, we designed a high-level programming [&hellip;]<\/p>\n","protected":false},"author":38022,"featured_media":605154,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"msr-url-field":"","msr-podcast-episode":"","msrModifiedDate":"","msrModifiedDateEnabled":false,"ep_exclude_from_search":false,"_classifai_error":"","msr-author-ordering":[{"type":"user_nicename","value":"Michal Moskal","user_id":"37431"}],"msr_hide_image_in_river":0,"footnotes":""},"categories":[194481],"tags":[],"research-area":[13552,13554],"msr-region":[],"msr-event-type":[],"msr-locale":[268875],"msr-post-option":[],"msr-impact-theme":[],"msr-promo-type":[],"msr-podcast-series":[],"class_list":["post-605124","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-human-centered-computing","msr-research-area-hardware-devices","msr-research-area-human-computer-interaction","msr-locale-en_us"],"msr_event_details":{"start":"","end":"","location":""},"podcast_url":"","podcast_episode":"","msr_research_lab":[],"msr_impact_theme":[],"related-publications":[],"related-downloads":[],"related-videos":[],"related-academic-programs":[],"related-groups":[144812],"related-projects":[427296],"related-events":[],"related-researchers":[],"msr_type":"Post","featured_image_thumbnail":"<img width=\"960\" height=\"540\" src=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-960x540.png\" class=\"img-object-cover\" alt=\"a screen shot of a computer\" decoding=\"async\" loading=\"lazy\" srcset=\"https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-960x540.png 960w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-300x169.png 300w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-768x432.png 768w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-1024x576.png 1024w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-1066x600.png 1066w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-655x368.png 655w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-343x193.png 343w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-640x360.png 640w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788-1280x720.png 1280w, https:\/\/www.microsoft.com\/en-us\/research\/wp-content\/uploads\/2019\/08\/MakeCode-Arcade_Site_08_2019_1400x788.png 1400w\" sizes=\"auto, (max-width: 960px) 100vw, 960px\" \/>","byline":"Michal Moskal","formattedDate":"September 3, 2019","formattedExcerpt":"When we began developing Microsoft MakeCode, a computing education platform, it was all about making programming easier, more engaging, and just plain friendlier. After all, if we were going to inspire the next generation of coders, easier entry into the world of computer science would&hellip;","locale":{"slug":"en_us","name":"English","native":"","english":"English"},"_links":{"self":[{"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/posts\/605124","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/users\/38022"}],"replies":[{"embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/comments?post=605124"}],"version-history":[{"count":7,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/posts\/605124\/revisions"}],"predecessor-version":[{"id":606822,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/posts\/605124\/revisions\/606822"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/media\/605154"}],"wp:attachment":[{"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/media?parent=605124"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/categories?post=605124"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/tags?post=605124"},{"taxonomy":"msr-research-area","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/research-area?post=605124"},{"taxonomy":"msr-region","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/msr-region?post=605124"},{"taxonomy":"msr-event-type","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/msr-event-type?post=605124"},{"taxonomy":"msr-locale","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/msr-locale?post=605124"},{"taxonomy":"msr-post-option","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/msr-post-option?post=605124"},{"taxonomy":"msr-impact-theme","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/msr-impact-theme?post=605124"},{"taxonomy":"msr-promo-type","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/msr-promo-type?post=605124"},{"taxonomy":"msr-podcast-series","embeddable":true,"href":"https:\/\/www.microsoft.com\/en-us\/research\/wp-json\/wp\/v2\/msr-podcast-series?post=605124"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}