Microsoft shrunk the TypeScript

#​640 — May 25, 2023

Read on the Web

JavaScript Weekly

DeviceScript: TypeScript for Tiny Thingamabobs — DeviceScript is a new Microsoft effort to take the TypeScript experience to low-resource microcontroller-based devices. It’s compiled to a custom VM bytecode which can run in such constrained environments. (A bit like Go’s TinyGo.) It’s aimed at VS Code users but there’s a CLI option too.

Microsoft

The State of Node.js Performance in 2023 — Node 20 gets put through its paces against 18.16 and 16.20 with a few different benchmark suites running on an EC2 instance. It goes into a lot of depth that’s worth checking out, but if you haven’t got time, the conclusion is “Node 20 is faster.” Good.

Rafael Gonzaga

Lightning Fast JavaScript Data Grid Widget — Try a professional JS data grid component which lets you edit, sort, group and filter datasets with fantastic UX & performance. Includes a TreeGrid, API docs and lots of demos. Seamlessly integrates with React, Angular & Vue apps.

Bryntum Grid sponsor

Deno 1.34: Now deno compile Supports npm PackagesDeno isn’t Node, but it increasingly likes to wear a Node-shaped costume. This release focuses on npm and Node compatibility and Deno’s compile command (for turning projects into single binary executables) now supports npm packages too which opens up a lot of use cases.

The Deno Team

⚡️ IN BRIEF:

TC39’s Hemanth.HM shares some updates from TC39’s 96th meeting. Atomics.waitAsync, the /v flag for regexes, and a method to detect well formatted Unicode strings all move up to stage 4.

The Angular team shares the results of their annual developer survey. Over 12,000 Angular developers responded.

RELEASES:

Astro 2.5

Preact 10.15 – Fast 3KB React alternative.

TypeScript 5.1 RC

Electron 24.4

MapLibre GL JS v3 – WebGL-powered vector tile maps.

???? Articles & Tutorials

Demystifying Tupper’s FormulaTupper’s self-referential formula is a formula that, when plotted, can represent itself. Confused? Luckily Eli shows us how simple the concept is and how to use JavaScript to render your own.

Eli Bendersky

An Introduction to Web Components — A practical and straightforward introduction to using the custom element API now supported in all major browsers to create a basic tabbed panel.

Mohamed Rasvi

▶  Creative Coding with p5.js in Visual Studio Codep5.js is a ‘creative coding’ library that takes a lot of inspiration from Processing. Dan does a great job at showing it off and sharing his enthusiasm for it. The main content starts at about 8-minutes in.

Daniel Shiffman and Olivia Guzzardo

Auth. Built for Devs, by Devs — Easily add login, registration, SSO, MFA, user controls and more auth features to your app in any framework.

FusionAuth sponsor

▶  Why React is Here to Stay — A rebuttal of sorts to Adam Elmore’s video from two weeks ago: ▶️ I’m Done with React.

Joscha Neske

Comparing Three Ways of Processing Arrays Non-Destructively — for-of, .reduce(), and .flatMap() go up against each other.

Dr. Axel Rauschmayer

Build Your First JavaScript ChatGPT Plugin — Plugins provide a way to extend ChatGPT’s functionality.

Mark O’Neill

How I’ve Shifted My Angular App to a Standalone Components Approach

Kamil Konopka

???? Code & Tools

Javy 1.0: A JS to WebAssembly Toolchain — Originally built at Shopify, Java takes your JS code and runs it in a WASM-embedded runtime. It’s worth scanning the example to get a feel for the process. “We’re confident that the Javy CLI is in good enough shape for general use so we’re releasing it as v1.0.0.”

Bytecode Alliance

Inkline 4.0: A Customizable Vue.js 3 UI/UX Library — A design system and numerous customizable components designed for mobile-first (but desktop friendly) and built with accessibility in mind.

Alex Grozav

Dynaboard: A Visual Web App IDE Made for Developers — Build high performance public and private web applications in a collaborative — full-stack — development environment.

Dynaboard sponsor

BlockNote: A ‘Notion-Like’ Block-Based Text Editor — Flexible and presents an extensive API so you can integrate it with whatever you want to do. You can drag and drop blocks, add real-time collaboration, add customizable ‘slash command’ menus, and more. Builds on top of ProseMirror and TipTap.

TypeCell

Windstatic: A Set of 170+ Components and Layouts Made with Tailwind and Alpine.js — Categorized under page sections, nav, and forms, and each category includes multiple components you can drop into projects.

Michael Andreuzza

ls-lint 2.0: A Fast File and Directory Name Linter — Written in Go but aimed at JS/front-end dev use cases, ls-lint provides a way to enforce rules for file naming and directory structures.

Lucas Löffel

Jest Puppeteer 9.0: Run Tests using Jest and Puppeteer — A Jest preset enabling end-to-end testing with Puppeteer.

Argos CI

ts-sql-query: Type-Safe SQL Query Builder — Want to build dynamic SQL queries in a type-safe way with TypeScript verifying queries? This is for you. Supports numerous SQL-based database systems and isn’t an ORM itself.

Juan Luis Paz Rojas

React Authentication, Simplified

Userfront sponsor

Hashids.js 2.3
↳ Generate YouTube-like IDs.

Tabulator 5.5
↳ Interactive table and data grid control.

gridstack.js 8.2
↳ Dashboard layout and creation library.

Cypress GitHub Action 5.8
↳ Action for running Cypress end-to-end tests.

ReacType 16.0
↳ Visual prototyping tool that exports React code.

Mongoose 7.2 – MongoDB modelling library.

Eta (η) 2.2 – Embedded JS template engine.

AVA 5.3 – Popular Node test runner.

MelonJS 15.3 – HTML5 game engine.

???? Jobs

Find JavaScript Jobs with Hired — Hired makes job hunting easy-instead of chasing recruiters, companies approach you with salary details up front. Create a free profile now.

Hired

Fullstack Engineer at Everfund.com — Push code, change lives. Help us become the center for good causes on the modern web with our dev tools.

Everfund

????‍???? Got a job listing to share? Here’s how.

???? Node.js developer? Check out the latest issue of Node Weekly, our sibling newsletter about all things Node.js — from tutorials and screencasts to news and releases. While we include some Node related items here in JavaScript Weekly, we save most of it for there.

→ Check out Node Weekly here.

Why Svelte is converting TypeScript to JSDoc

#​638 — May 11, 2023

Read on the Web

JavaScript Weekly

The JavaScript Ecosystem is Delightfully Weird — There are plenty of examples of how JavaScript is weird but Sam focuses on the why. If you’ve been a JS developer for many years you’ll have seen it go through many phases and morph to fit its environment. Sam paints the big picture, concluding with a talk Dan Abramov gave yesterday called “React from Another Dimension.”

Sam Ruby

The New JS Features Coming in ECMAScript 2023 — The next JavaScript update brings smaller additions familiar from other languages, but there are more significant developments waiting in the wings. 

Mary Branscombe (The New Stack)

Full Stack for Front-End Engineers with Jem Young (Netflix) — Learn what it means to become a well-rounded full-stack engineer with this hands-on video course. You’ll dive into servers, work with the command line, understand networking and security, set up continuous integration and deployment, manage databases, build containers, and more.

Frontend Masters sponsor

Vue 3.3 ‘Rurouni Kenshin’ Released — Named after a popular manga series, the latest release of Vue is focused on developer experience improvements, particular for those using TypeScript.

Evan You

John Komarnicki says ▶️ Vue 3.3’s defineModel macro will change the way you write your components.

Next.js 13.4 Released — Despite the minor version bump, this is a big release for the popular React framework. The new app router and its improved approach to filesystem based routing is now offered as a stable feature, with a new concept of server actions being introduced in alpha as a way to mutate data on the server without needing to create an in-between API layer.

Tim Neutkens and Sebastian Markbåge

⚡️ IN BRIEF:

???? Svelte is converting from TypeScript to JSDoc (example).. sort of. Rich Harris popped up on Hacker News to provide some all important context but the ultimate result will be smaller package sizes and a better experience for Svelte’s maintainers.

React now has official ‘canary’ releases if you want to use newer features than in the stable releases but still be on an officially supported channel.

Newly released Firefox 113 lets you override JS files in its debugger.

No stranger to controversy, Ruby on Rails’s David Heinemeier Hansson (DHH) tweeted: ???? “TypeScript sucked out much of the joy I had writing JavaScript.”

RELEASES:

Glint 1.0 – TypeScript powered tooling for Glimmer / Ember templates.

Elementary 2.0 – JS/C++ library for building audio apps.

???? Articles & Tutorials

ES2023’s New Array Copying Methods — The newest ECMAScript spec introduces some new methods on Array that you’ll eventually find useful in your own programs. Phil gives us the tour.

Phil Nash

Private Class Fields Considered Harmful“As a library author, I’ve decided to avoid private class fields from now on and gradually refactor them out of my existing libraries.” Why? Well, that’s the interesting part..

Lea Verou

▶  I’m Done with React — Going from least-to-most important, the reasons this developer isn’t choosing React for future projects make for interesting watching, particularly if you too are overwhelmed by upheaval in the React world. Solid is one of the alternatives he has warmed to.

Adam Elmore

Constraining Language Runtimes with Deterministic Execution — Explore various challenges encountered while using different language runtimes to execute workflow code deterministically.

Temporal Technologies sponsor

Running JavaScript in Rust with Deno — Deno’s use of Rust makes it a natural choice if you’re building a Rust app and want to integrate a JavaScript engine.

Austin Poor

Regular Expressions in JavaScript — Powerful but often misunderstood, many will benefit from this roundup of the potential regexes offer to JavaScript developers.

Adebayo Adams

How to Measure Page Loading Time with the Performance API — The Performance API is a group of standards used to measure the performance of webapps supported in most modern browsers.

Silvestar Bistrović

How to Build a JS VST or Audio Unit Plugin on macOS — VSTs and Audio Units are both types of audio plugins for audio editing software and they’re usually built in C or C++. This tutorial doesn’t dig into the audio side of things, but more the practicalities of packaging things up to get started.

Chris Mendez

An Introduction to the Bun Runtime — If you’ve not yet played with the newest entrant into the JS runtime space, this is a high level overview.

Craig Buckler

2023 State of the Java Ecosystem

New Relic sponsor

Configuring ESLint, Prettier, and TypeScript Together

Josh Goldberg

DestroyRef: Your New Angular 16 Friend

Ion Prodan

Why Astro is My Favorite Framework

Ryan Trimble

???? Code & Tools

file-type 18.4: Detect the File Type of a Buffer, Uint8Array or ArrayBuffer — For example, give it the raw data from a PNG file, and it’ll tell you it’s a PNG file. Uses magic numbers so is targeted solely at non text-based formats.

Sindre Sorhus

Learn How the Rising Trend of Malicious Packages Can Affect Your Apps — Keep your applications secure with Snyk’s article on the increasing number of malicious OS packages and ways to mitigate these risks.

Snyk sponsor

Livefir: Build Reactive HTML Apps with Go and Alpine.js — Go isn’t a language that often pops up in the context of the frontend, but this is a neat integration between Go on the backend and Alpine.js up front.

Adnaan Badr

JZZ.js: A Developer Friendly MIDI library — For both browsers and Node, JZZ.js provides an abstraction over working with MIDI related concepts. There are many examples, but the easter egg in the top left is our favorite.

Sema / Jazz-Soft

htmlparser2 9.0: A ‘Fast and Forgiving’ HTML and XML Parser — Consumes documents and calls callbacks, but it can generate a DOM as well. Works in both Node and browser.

Felix Böhm

cRonstrue: Library to Convert cron Expressions into Human-Readable Form — Given something like */5 * * * *, it’ll return “Every 5 minutes”. No dependencies.

Brady Holt

Knip: Find Unused Files, Dependencies and Exports in TypeScript Projects — Being Dutch for “snip” is appropriate as Knip can trim away things that aren’t being used in your project.

Lars Kappert

jsPlumb 6.1
↳ Visual connectivity for webapps.

gridstack.js 8.1
↳ Build interactive dashboards quickly.

???? Jobs

Find JavaScript Jobs with Hired — Hired makes job hunting easy-instead of chasing recruiters, companies approach you with salary details up front. Create a free profile now.

Hired

Team Lead Web Development — Experienced with Node, React, and TS? Join us and lead a motivated team of devs and help grow and shape the future of our web app focused on helping millions explore the outdoors.

Komoot

????‍???? Got a job listing to share? Here’s how.

???? Don’t tell Satya Nadella..

Fake Windows 11 in Svelte — This is a cute little side project, and the code is available too. The most common complaint I’ve seen is that it’s actually more responsive than the real Windows.. ???? Be sure to check out both ‘VS Code’ and ‘Microsoft Edge’ in this environment.

Yashash Pugalia

???? Prefer Windows XP? Maybe RebornXP is more for you. Complete with the classic starting up sound!

Flatlogic Admin Templates banner

Astro 2.0 and TypeScript 5.0 beta

#​623 — January 27, 2023

Read on the Web

JavaScript Weekly

Astro 2.0: The Next-Gen ‘Islands’-Oriented Web Framework — 2.0 includes hybrid rendering (mixing of SSR and SSG outputs), type safety for Markdown & MDX, and an upgrade to Vite 4.0. Astro is worth exploring when performance is key as it works with popular frameworks but lets you deliver the least JS possible to get pages rendered.

Fred Schott

Prefer a talk? Nate Moore’s ViteConf talk ▶️ Islands Architecture, Astro, and You will bring you up to speed.

Deep Cloning Objects in JavaScript, The Modern Way — If you’ve been leaning on something like Lodash for deep cloning, you might not need to any longer. “It’s been a long time coming, but we finally now have the built-in structuredClone function to make deep cloning objects in JavaScript a breeze.”

Steve Sewell

Go From Professional Web Developer to Lead Engineer — Aspiring lead developer? Our collection of comprehensive video courses cover the fundamentals of JavaScript, TypeScript, React, web performance, and more.

Frontend Masters sponsor

Announcing TypeScript 5.0 Beta — A new major version number, but users of the popular typed JS superset will face a ‘similar upgrade experience’ to previously. Decorators make it in as a first class feature, significant performance and package size optimizations are present, export type * is supported, all enums are now union enums, and much more.

Daniel Rosenwasser (Microsoft)

AlaSQL.js 3.0: Isomorphic JavaScript SQL Database — A SQL database you can use in the browser, Node.js or mobile apps. An interesting bit of functionality is you can use SQL to query JavaScript objects – example. “The library adds the comfort of a full database engine to your JavaScript app. No, really.”

Andrey Gershun

IN BRIEF:

? If you’re really into Vue.js, you’ll soon be able to become officially certified in it.

If you’re using React, you should be using a React framework, ? says Andrew Clark of the core team.

The creator of alternative JS runtime Bun asks: “If there’s one thing missing from Bun for you to switch, what is it?” You can reply on Twitter.

jQAPI.com is an amazing meeting of old and new JavaScript – it’s an Astro powered version of jQuery’s documentation!

RELEASES:

Shoelace 2.0
↳ Agnostic library of web components.

μFuzzy 1.0
↳ Tiny fuzzy search library.

React Router 6.8

Node.js 19.5.0

? Articles & Tutorials

Getting Started with SvelteKit — SvelteKit only recently hit 1.0 and this is a comprehensive overview of how to build a site using the Svelte-oriented app framework. It covers topics like routing, layouts, data, props and more.

Adam Rackis

Using .NET Code from JavaScript using WebAssembly“Starting with .NET 7, you can easily run any .NET method from JavaScript without needing the whole Blazor framework.”

Gérald Barré

JavaScript Scratchpad for VS Code (2m+ Downloads) — Quokka.js is the #1 tool for exploring/testing JavaScript with edit-continue experience to see realtime execution and runtime values.

Wallaby.js sponsor

scrollend: A New JavaScript Event — Finally an event you won’t need a hotel booking for. scrollend provides a new way to detect that a scrolling operation is complete in the browser. Is it another Chrome-only nicety? Surprisingly not – Firefox 109+ supports it too.

Adam Argyle (Chrome Team)

Packaging Rust Apps for the npm Registry — Isn’t npm just for JavaScript projects? Nope. Node is required to make this technique work, but as long as you can package and execute a binary, you’re good to go.

Orhun Parmaksız

Making Sense of TypeScript using Set Theory — This article certainly doesn’t hang around. Neat diagrams too.

Vladimir Klepov

React Authentication, Simplified

Userfront sponsor

Accessible Hamburger Buttons without JavaScript — Sometimes you need to consider if modern techniques allow you to avoid JavaScript. Here’s a CodePen if you want to play.

Pausly

While we’re on the topic of less JavaScript, the latest episode of the Stack Overflow podcast ▶️ ‘The less JavaScript, the better’ focuses on Astro.

? Code & Tools

Uppy 3.4: Powerful, Modular JavaScript File Uploader — Upload not just from local sources but even Dropbox or Instagram. Integrates with popular frameworks and supports resumable uploads. GitHub repo.

Transloadit

Nut.js 3.0: Desktop Automation from Node — Take control of your desktop (Windows, macOS or Linux) in code with control over keyboard + pointer, along with image matching functionality. GitHub repo.

Simon Hofmann

Optimize Your Systems’ Performance With TelemetryHub – Real-Time Data Monitoring & Analysis — An advanced data visualization and analysis tool that can help you identify and resolve unseen issues in your environment. Try free.

TelemetryHub by Scout sponsor

Eleventy v2.0: First Beta of the Popular Site GeneratorEleventy is a popular Node.js static site generator and v2.0 includes enough major changes that a thorough beta is needed. The creator ▶️ made this quick video about the release.

Zach Leatherman

Mock Service Worker 1.0: API Mocking Library for Browser and Node — Intercepts requests which you can then mock. Capture outgoing requests using an Express-like routing syntax, complete with parameters, wildcards, and regexes. GitHub repo.

Artem Zakharchenko

Drift: A Self-Hostable Gist-Like / Pastebin Service — Built with Next.js 13.

Max Leiter

Dygraphs 2.2
↳ Interactive charts of time series data.

actions/github-script 6.4
↳ Write GitHub Actions workflows in JS.

Playwright 1.30
↳ Browser automation framework.

Faast.js 6.4
↳ Serverlessly call JS functions on AWS Lambda & Google Cloud Functions.

Cypress 12.4
↳ Testing framework for anything in a browser.

D3plus 2.1
↳ Extend D3.js with more visualization types.

? Jobs

Developer Relations Manager — Join the CKEditor team to build community around an Open Source project used by millions of users around the world ?

CKEditor

Senior Full-Stack Engineer – React + TypeScript — Come help Qwire modernize how studios, composers, artists, publishers, labels, and the rest of the industry manage music rights.

Qwire

Find JavaScript Jobs with Hired — Create a profile on Hired to connect with hiring managers at growing startups and Fortune 500 companies. It’s free for job-seekers.

Hired

Flatlogic Admin Templates banner

Typescript vs. Javascript: The Key Differences You Should Know in 2022

Let’s start the battle TypeScript vs JavaScript with an introduction of both technologies. JavaScript is a scripting language, that was developed by EMCA’s Technical Committee and Brendan Eich. It works perfectly in web-browsers without the help of any web-server or a compiler. It allows you to change HTML and CSS in the browsers without a full page reload. That is why it is used to create dynamic and interactive web pages. 

TypeScript vs. JavaScript. A short comparison before we start

JS and TS – key differences
Type system
Compiler
Server-side / client-side
Declaration files
Size of projects
Salaries
IDE’s

Typescript vs. Javascript. A comparison table
So what to choose?
Typescript vs. JavaScript. Resume

TypeScript is a superset of the JavaScript language. It was presented and developed by Microsoft technical fellow Anders Hejlsberg in 2012. Typescript has appeared for a certain reason: the more JavaScript grew, the heavier and more unreadable js code became. It turned up especially evident when developers started to use JavaScript for server-side technologies.

TypeScript is an open-source language that has a compiler, that converts TypeScript code to JavaScript code (see TypeScript playground service). That compiler is cross-browser and also open-source. To start using TypeScript, you can rename your .js files to .ts files, and if there are no logical mistakes in the js code, you get valid TypeScript code. So, TypeScript code Is JavaScript code (and vice versa) just with some additions. To learn more about those additions, watch the original video presentation of TypeScript. Meanwhile, we discuss the key differences between JS and TS in 2022.   

TypeScript vs. JavaScript. A short comparison before we start

To be honest, almost nothing has changed in JavaScript and TypeScript technologies (and as a result in differences between them) for previous years. If you are already familiar with them, be calm because your knowledge is still up-to-date. 

And yet, there is one black swan that the world hasn’t faced before. It’s a coronavirus that made a shift not only in the technology sector but in the whole world. Companies went to remote working, economies have been isolated from each other for several months; some still do. That led to a disruption in the world value chain for hardware production. Even when factories will be reopened and deliveries will be resumed, it will take time to revive the production. It’s possible, that software becomes the growth catalyst for the technology sector in the coming time, and demand for software programmers will increase. We expect the growth both in small and large projects, so use any language: either JavaScript that is convenient for development not very complicated projects in small teams or TypeScript that is designed to work with large projects in huge teams from all over the world. 

And yet, JS and TS – key differences

Type system

The first important thing to speak about is a type system. JavaScript is dynamically typed. That means that technically you can do anything you want because JavaScript doesn’t know the type of a variable until the code is running. That leads to irritating bugs when you try to use the variables with wrong types for some commands. One of the instrument JavaScript offers to solve that problem is “use strict” mode that prevents you from using undeclared variables and throws an error for any assignment to a non-existing property/variable/object.  

For its part, TypeScript has a static typing. TypeScript type system offers you incredibly rich opportunities: interfaces, enums, hybrid types, generics, union/intersection types, access modifiers, and much more. And you are not allowed to use undeclared variables. 

Dynamic typing is more flexible by allowing programs to execute the code skipping some insignificant errors that static typing never allows. That decreases the development time, learning is easier in JavaScript, the amount of lines of the code is less. Nevertheless, dynamic typing may lead to errors we have mentioned. And since JavaScript tries to execute the code anyway despite the run-time errors, debugging becomes difficult. 

The advanced static type system of TypeScript helps to avoid such a situation, but cost you more time to set up a codebase with proper strict typing. However, one of the goals for the development of TypeScript was to help catch mistakes early and make development efficient. 

Compiler

JavaScript code doesn’t need to be compiled, while TypeScript code does. After code compilation TypeScript code becomes pure JavaScript, so it’s a development instrument first.

Server-side / client-side

Some people compare JavaScript and TypeScript in terms of their usage on client / server-side and claim that js has an advantage because it’s both client and server-side, while ts is not. From our point of view that is an incorrect comparison, because TypeScript code compiles to pure JavaScript that is both server and client-side. So here you shouldn’t worry about the differences.

Declaration files

The basic principle that needs to understand is that TypeScript basically stays very true to JavaScript type system and just allows you to statically describe what is going on in JavaScript. The purpose of declaration files is to define a semantic subset of JavaScript libraries and that makes sense. 

Let’s get on with it. 

Declaration files, if you’re not familiar with them, are just files with d.ts. extension that contains declarations of modules and namespaces, where a module is any file containing values, functions, or classes. And we speak exactly about declarations of them, not implementation. That files generated automatically by TypeScript compiler when you run your code through it. When TypeScript code is compiled, it becomes pure JavaScript code with all functions that the original code has. Sharing JavaScript code and a declaration file allows developers to use the original code without the presence of the original TypeScript code. In other words, declaration files help distribute js libraries

To learn more, you can clone the “DefinitelyTyped” repository from GitHub to get access to all popular libraries. When you need to use external script files in ts, you understand how convenient declaration files are.

Another feature that declaration files offer and that can be helpful is completion in your editor. That speeds up your development process and make coding easier. 

When the code is converted, JavaScript doesn’t use declaration files, so they need only to TypeScript compiler and your TypeScript code. 

Size of projects

TypeScript is a language that makes the code more consistent, clean, simple, and reusable. Thanks to static typing and declaration files TypeScript code is much easier to maintain and share. Also, TypeScript works great in bug prevention and helps to avoid spending time looking through code to find a silly mistake. So, it is better to use TypeScript for large projects.

Should you use TypeScript in all projects? No

You can’t debug TS code in a browser, but using JS you can. It is impossible to skip the compile step in TS (and the step takes time), in JS there is no need to wait. You can’t quickly write a code in TS because you need to declare everything, in JS you can write whatever code you want and it will work if there are no logical errors in it. We can say, that JavaScript is perfect for simple web applications, and that will stay true for much longer. 

Salaries

According to Stack Overflow, salaries for TypeScript and JavaScript developers are approximately the same both in the United States and all over the globe. In the United States companies pay TypeScript developers 120 thousand dollars a year, while they pay 8 thousand dollars less to JavaScript developers. Over the globe, these numbers are 57 and 53 thousand dollars respectively. 

IDE’s

TypeScript supports a lot of different IDEs, while JavaScript does not. For most developers that is a basic tool required to write and test the code, and refactoring becomes much easier as well. Using IDEs, you get intelligent code completion and error catch as you type that drastically speeds up the process of coding. The best and most popular IDEs are Visual Studio Code, WebStorm, Atom.  

Typescript vs. Javascript. A comparison table

TypeScript
JavaScript

Type system
Static typing
Dynamic typing

Compiler
Needs to be compiled
Doesn’t need to be compiled

Declaration files
Declaration files are used with TypeScript compiler and TypeScript code
JavaScript doesn’t use declaration files

Size of projects
It is better to use TypeScript for large projects
JavaScript is perfect for simple web applications

IDE’s
Supports a lot of different IDEs
Supports much less IDEs

So what to choose?

As a novice

You should definitely start with learning JavaScript. But when you learn the basics of that go to TypeScript. The biggest hurdle for TypeScript is the learning curve. Yeah, TypeScript offers a lot of useful tools to manage, share, debug, and write the code, but you need to know how that tools work to use them efficiently. Besides that, TypeScript is a superset of JavaScript, so you must know JS before starting to learn its more complicated roommate.  

As a middle developer

If you don’t know TypeScript but have a desire to work on more complicated projects, it’s time to learn TS. From the other side, if you are an experienced developer who is working on relatively small coding projects and in small teams, JavaScript is fine. Since salaries are almost equal, there is no financial reason to switch to TypeScript too. However, if you have knowledge, ideas, or need for team development, then Typescript becomes a more preferred option.  

As a senior developer 

Well, you have already known everything possible about JavaScript and TypeScript, and we guess that you have skills in them both. You do not need to choose any of them and the only thing you should know is that this year we don’t think anything will change in those technologies.  

Typescript vs. Javascript. Resume

JavaScript is an easy language to learn, while TypeScript has a tough learning curve and requires prior knowledge of scripting. Airbnb, Codeacademy, and Instagram are a few companies that use JavaScript, while TypeScript is used by Asana, Clever, Screen Awards, etc. TypeScript supports static typing, which allows you to type-check at compile-time, whereas JavaScript does not. The compiler significantly reduces the likelihood of “dumb” mistakes, such as missing commas and misspelled variable names, but it also kills the beauty of JS when most of the solutions could be written on their knees and tested in the browser console.

Strong typing of TypeScript allows you to more fully describe the properties and methods of objects and classes, which eliminates the need, which, for some developers, is very annoying, to check all arguments included in a method or function. This item works both for good and for bad because it is necessary to describe all types for all objects, classes, variables, which was not typical of JavaScript before.
It will be easier to read the code in TypeScript since there is no jumble of code typical of Javascript. But it should be noted that if you use abstractions can in JS, that greatly simplifies the perception of the code.

It should be noted that many are attracted by JavaScript. But as soon as they begin to study it, a kind of chaos and unpredictability of the language strikes the eye. If you prefer TypeScript, it is possible to transfer all your favorite libraries from JS to TS, if necessary. However, migration of existing popular JS solutions to TS requires labor costs. You see, for each ported lib it is necessary to describe the .d.ts file, which contains all the returned types and the description of all methods. Although porting monsters like jQuery, for example, took a lot more effort. So maybe this is not that much work after all. TypeScript currently has support in every popular IDE, including IDEA, WebStorm, Sublime, Atom, and so on. That is why you won’t have to change your favorite development environment.

Thanks for reading…

You might also like these articles:

14+ Best Node.js Open Source Projects
8 Essential Bootstrap Components for Your Web App
Best 14+ Bootstrap Open- Source Projects

The post Typescript vs. Javascript: The Key Differences You Should Know in 2022 appeared first on Flatlogic Blog.Flatlogic Admin Templates banner

MSBuild and 64-bit Visual Studio 2022

Visual Studio’s shift to 64-bit means your builds in Visual Studio 2022 will run in a 64-bit MSBuild. This will not cause any problems for most people. However, if your build includes a task that is 32-bit only and does not correctly mark itself as a 32-bit task, your build may fail.

The best way to know if this will affect you is by testing your build with a 64-bit version of MSBuild. Visual Studio and Build Tools have included 64-bit MSBuild since Visual Studio 2013, so you can do this in your current version of Visual Studio, as well as with the Visual Studio 2022 previews.

Background and what’s changed

MSBuild is part of both Visual Studio and the .NET SDK. The changes described here affect only the Visual Studio MSBuild and will not affect builds started through dotnet build.

MSBuild has both 32- and 64-bit executables. Both are installed in every copy of Visual Studio and Visual Studio Build Tools, and scripts that call msbuild.exe by full path can select which to use. The Developer Command Prompt for Visual Studio also sets PATH to include the MSBuild bin folder.

Visual Studio 2019 is the last version of Visual studio that used the 32-bit version of MSBuild for builds within Visual Studio. Since Visual Studio 2022 is now 64-bit and runs MSBuild in-process, it now runs a 64-bit version of MSBuild, including when you hit F5 or Ctrl-F5. Consistent with the change to 64-bit, the Visual Studio Developer Command Prompt now points to the 64-bit version of MSBuild in the PATH (the 32-bit version was on the PATH in earlier releases).

The 32-bit MSBuild is run by default in the Azure Pipelines Visual Studio Build and MSBuild tasks. To change this, specify msbuildArchitecture: ‘x64’ in your YAML job definition. For GitHub Actions, the setup-msbuild action allows for specifying this same setting using msbuild-architecture: ‘x64’.

How does this affect my build?

Changes in Windows between environments may cause problems, if part of your build has a dependency on the 32-bit filesystem or registry redirection.

Most MSBuild tasks build for AnyCPU and should not have a problem running in a 64-bit environment. Many tasks invoke tools via the command line (they “shell out”) and to those tools it will make no difference whether the task is 32- or 64-bit since the tool continues to run in its own process.

Some tasks p/invoke into native libraries and thus are sensitive to the architecture they run in.

If you maintain a task, you do not have to rewrite it to run in a 64-bit environment. Instead, you can mark it so that MSBuild runs it in a process with the correct bitness: the 64-bit version of MSBuild can start 32-bit tasks out of process, as the 32-bit version can start 64-bit tasks. See “Guidance for Task Owners” below.

Don’t feel alone if you encounter this—even the Visual Studio SDK had issues with 64-bit MSBuild compatibility. Some of its tasks are thin wrappers over libraries written in C++ and built for 32-bit x86. We discovered this early in the Visual Studio 2022 lifecycle and the Visual Studio SDK has been updated to support 64-bit MSBuild using the techniques described below since Microsoft.VSSDK.BuildTools 16.8.1015.

Potential issues with MSBuild tasks

MSBuild tasks are .NET assemblies that add extra functionality to MSBuild. You use them in your normal build, even if you have never written one. MSBuild tasks normally run inside the parent MSBuild process.

If a task is not compatible with 64-bit MSBuild, the task may not be found or it may throw an error. Contact the task owner (such as by filing an issue in their repo), possibly referencing this breaking change blog post. If you are the task owner, see “Guidance for task owners” below.

Tasks incompatible with 64-bit MSBuild may fail in a variety of ways; the most common are MSB4018 with a System.DllNotFoundException and MSB4062 “task could not be loaded” errors.

Guidance for task (NuGet package) owners

You have the option of rewriting your task to support running in a 32- or 64-bit environment and deploying both copies of native assemblies, but this is often difficult, so you may prefer to configure MSBuild to run your task in a 32-bit process (even from a 64-bit build).

Because this requires starting a new process and communicating with it, it takes more time during the build than running a task in the existing MSBuild process. This is usually not a problem unless the task is called many, many times in your build.

Tasks are made available for use with UsingTask elements. You can configure the task to indicate that it requires a specific runtime environment by specifying the Architecture attribute in the UsingTask element.

A well-specified UsingTask for a 32-bit-only assembly looks something like this:

<UsingTask TaskName=”TaskThatNeedsX86Library”
AssemblyFile=”$(MSBuildThisFileDirectory)ArchSpecificTasks.dll”
Architecture=”x86″ />

This change is backward compatible since MSBuild has supported running tasks in a different architecture since .NET 4.5 and Visual Studio 2012. Specifying Architecture will not change how the task runs in a 32-bit MSBuild environment, but will cause 64-bit MSBuild to run it in a secondary 32-bit process. Because of this, we recommend making this change unconditionally and not trying to detect Visual Studio 2022 (MSBuild 17) specifically.

Testing

We recommend testing your task in a few build scenarios to make sure your changes are working:

UI-driven builds in Visual Studio 2019 (to ensure that there hasn’t been a regression in that scenario).
Command-line builds using 32-bit MSBuild.exe from Visual Studio 2019 (MSBuild 16).
Command-line builds using 64-bit MSBuild.exe from Visual Studio 2019 (MSBuild 16).
UI-driven builds in the latest Visual Studio 2022 (this is a primary developer scenario going forward).
Command-line builds using 64-bit MSBuild.exe from Visual Studio 2022 (MSBuild 17).
Command-line builds using the .NET SDK (if your task supports this environment). These use dotnet build and should be unaffected by your changes.

Known issues

If a task is defined in a .NET assembly compiled as 32-bit only, MSBuild will fail to load it with an error like

S:BitnessInMSBuildShowErrors.proj(13,5): error MSB4062: The “TaskCompiledForx86” task could not be loaded from the assembly S:BitnessInMSBuildTaskCompiledForx86binDebugnet472TaskCompiledForx86.dll. Could not load file or assembly ‘file:///S:BitnessInMSBuildTaskCompiledForx86binDebugnet472TaskCompiledForx86.dll’ or one of its dependencies. An attempt was made to load a program with an incorrect format. Confirm that the <UsingTask> declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.

even if the UsingTask correctly declares an Architecture. This is tracked by dotnet/msbuild#6461.

You can work around this issue by recompiling your task assembly as AnyCPU and additionally specifying the Architecture. In that case, the MSBuild engine can load the task in a 64-bit environment but it will only execute it in a 32-bit process.

Mitigation for users of tasks that they don’t own

Unfortunately, it is difficult to work around task misconfiguration if you do not control the UsingTask. dotnet/msbuild#5541 tracks a change that would make it easier to override an incorrect UsingTask in your project. Please let us know if this would be useful to you in a future Visual Studio/MSBuild release.

Next Steps

The upgrade to Visual Studio 2022 is an exciting one. 64-bit MSBuild is just one of the new features we’ve prepared for you and we’re excited for you to try them out. When you do, be sure to leave your feedback below, we’d love to hear about your experiences with the upgrade and with 64-Bit MSBuild overall!

The post MSBuild and 64-bit Visual Studio 2022 appeared first on .NET Blog.

Announcing LLILC – A new LLVM-based Compiler for .NET

The .NET Foundation was set up to foster open source innovation and collaboration around .NET and so I’m very pleased to announce that we have released an initial version of a new project called LLILC (pronounced “lilac”) on GitHub. This is a new LLVM-based native code compiler for .NET Core which is being contributed to the .NET Foundation by Microsoft. LLVM is a very popular open source compiler framework which supports targeting multiple CPU types. LLILC creates a bridge into LLVM for .NET, making LLVM’s broad chip support and tools available to .NET Core.

We are envisioning using the LLVM infrastructure for a number of scenarios. The first tool in LLILC is a Just in Time(JIT) compiler for CoreCLR.

Why a new JIT for CoreCLR?

While the CoreCLR already has JIT, we saw an opportunity to provide a new code generator that has the potential to run across all the targets and platforms supported by LLVM. To enable this, as part of the LLILC project we’re opening a CIL reader that operates directly against the same common JIT interface as the production JIT (RyuJIT). This new JIT will allow any C# program written for the .NET Core class libraries to run on any platform that CoreCLR can be ported to and that LLVM will target.

There are several ongoing efforts to compile MSIL in the LLVM community. Why build another one?

When we started thinking about the fastest way to get a LLVM based code generation working we looked around at the current open source projects (SharpLang is a very cool one and LLVMSharp is also good) as well as code Microsoft had internally. While a number of the OSS projects already targeted LLVM BitCode, no one had anything yet that was a close match for the new CoreCLR interface. Looking at the options it was quickest for us to refactor and modify a working MSIL reader to target BitCode then get an existing project to support the contracts and APIs the CoreCLR uses for JIT’ing MSIL. Using an existing MSIL reader let us get the project bootsrapped using a number of building-block components that we think the wider community will also be able to take advantage of. This rapid bootstrap for C# across multiple platforms was the idea that was the genesis of this project and the compelling reason to start a new effort. We hope LLILC will provide a useful example – and a set of reusable components – for the whole community and make it easier for lots of other projects to interoperate with the CoreCLR runtime.

Why LLVM?

Basically LLVM is awesome. It’s already got great support across many platforms and chipsets and the community is amazingly active. The ability for LLVM to operate as both a JIT and as an AOT compiler was especially attractive. By bringing MSIL semantics to LLVM we plan to construct a number of tools that can work against CoreCLR or some sub set of its components. By putting all this out in an early state, we also hope folks will be able to produce tools and technologies that we haven’t even thought of yet.

Roadmap

As we said, it’s early days for the LLILC project but the current plan is to start with a classic JIT, then move to Install-time JIT (what we talk of as “NGen” in the .NET world). Next the LLILC project team want to look at an Ahead of Time compiler (AOT) – a build lab compiler that produces standalone native executables for many platforms, using some shared components from CoreCLR. The AOT compiler could also be used to improve startup time for important command line applications like the Roslyn Compiler.

The LLIC JIT will be a functionally correct and complete JIT for the CoreCLR runtime and a great reference implementation. It’s too early to say but it may not have sufficient throughput to be a first-tier JIT, but it is expected to produce high-quality code and so might make a very interesting second-tier or later JIT, or a good vehicle for prototyping codegen changes to feed back into RyuJIT.

Right now the core LLILC project team have been focusing on Windows along with Linux and Mac OS X but we would be very keen on folks getting involved that wanted to widen th platform base.

Current Status

Today on Windows we have the MSIL reader & LLVM JIT implemented well enough to compile a significant number of methods in the JIT bring up the tests included in CoreCLR. In these tests we compile about half the methods and then fall back to RyuJIT for cases we can’t handle yet. The testing experience is pretty decent for developers. The tests we run can be seen in the CoreCLR test repo. All tests run against the CoreCLR GC in conservative mode – which scans the frame for roots – rather than precise mode. We don’t yet support Exception Handling.

We’ve established builds on Linux and Mac OSX and are pulling together mscorlib, the base .NET Core library from CoreFx, and test asset dependencies to get testing off-the-ground for those platforms.

The LLILC team are starting to engage with the very cool folks in the LLVM community on the project (see the LLVM blog post) but we also hope that developers and academics who are familiar with LLVM will also get involved, helping C# and the other .NET languages be supported for LLVM.

The LLILC team will be working in the LLILC and LLVM repos over the next several months. They will be posting to the Forums as they make progress. As .NET Core becomes more fully supported on Linux and OS X, it is their intention to provide an LLILC implementation at a similar quality, so that you can use both projects together. It is also a great opportunity for us to get feedback, since we expect a lot of experimentation with .NET Core.

While it is early days, we’d love to have you join in and help bring the potential that LLILC offers to .NET Core via LLVM a reality. We want to know about your experience, either positive or issues that you encounter. If you have LLVM experience or want to gain that experience by working on the project, please do engage directly with the LLILC project. The team will actively be monitoring for any PRs, responding to issues and wanting to discuss any changes we are proposing to LLVM to help it support .NET.

LLVM and .NET are an interesting combination. .NET provides multiple-language support via a common language runtime, while LLVM supports “compilation of arbitrary programming languages” to multiple CPU targets. By combining these two worlds, LLILC provides a promising path to multiple platform support for .NET languages and by extension to the .NET developers across the globe. Exciting stuff.

Martin Woodward
Executive Director, .NET Foundation

What’s new in F# 6

We’re excited to announce the availability F# 6, shipping with .NET 6 RC2 and Visual Studio 2022 RC2. It’s the next step to making it easier for you to write robust, succinct and performant code. You can get F# 6 in the following ways:

Install the latest .NET 6 SDK RC2 preview
Install Visual Studio 2022 RC2 preview
Use .NET Interactive Notebooks in Jupyter or VS Code

F# 6 is about making F# simpler and more performant. This applies to the language design, library, and tooling. A major goal of long-term language evolution is to remove corner-cases in the language that surprise users or are unnecessary hurdles on the path to adoption. We are very pleased to have worked with the F# community in this release to make the F# language simpler, more performant, and easier to learn.

To learn more about F#, see The .NET Conf Focus Day on F# including the F# Bonanza, Guido van Rossum Learns F# and Starting Your F# Journey.

Making F# faster and more interopable with task {…}

One of the most requested features for F# – and the most significant technical feature in this release – has been to make authoring asynchronous tasks simpler, more performant and more interoperable with other .NET languages like C#. Previously, creating .NET tasks required using async {…} to create a task and then invoking it with Async.AwaitTask. With F# 6 you can now use task {…} directly to create the task and await it. For example, consider the following F# code to create a .NET-compatible task:

let readFilesTask (path1, path2) =
async {
let! bytes1 = File.ReadAllBytesAsync(path1) |> Async.AwaitTask
let! bytes2 = File.ReadAllBytesAsync(path2) |> Async.AwaitTask
return Array.append bytes1 bytes2
} |> Async.StartAsTask

This code can now become:

let readFilesTask (path1, path2) =
task {
let! bytes1 = File.ReadAllBytesAsync(path1)
let! bytes2 = File.ReadAllBytesAsync(path2)
return Array.append bytes1 bytes2
}

The built-in support for task {…} is available ubiquitously in F# code – no namespaces need to be opened.

Task support has previously been available for F# 5.0 through the excellent TaskBuilder.fs and Ply libraries. These guided the design of the support in F# 6 and provided an important source of tests. The authors of these libraries have been major contributors to the design of F# 6, both directly and indirectly. Migrating code to the built-in support should be straightforward. There are however some differences: namespaces and type-inference differ slightly between the built-in support and these libraries, and some additional type annotations may be needed. These community libraries can still be used with F# 6, if explicitly referenced and the correct namespaces opened in each file.

Using task {…} is very similar to async {…}, and both are supported. Using task {…} has several advantages over async {…}:

The performance of task {…} is much better.
Debugging stepping and stack traces for task {…} is better.
Interoperating with .NET packages expecting or producing tasks is easier.

If you’re familiar with async {…}, there are some differences to be aware of:

task {…} immediately executes the task to the first asynchronous yield.

task {…} does not implicitly propagate a cancellation token.

task {…} does not perform implicit cancellation checks.

task {…} does not support asynchronous tailcalls. This means using return! .. recursively may result in stack overflows if there are no intervening asynchronous yields.

In general, you should consider using task {…} over async {…} in new code if interoperating with .NET libraries that uses tasks. Review code before switching to task {…} to ensure you are not relying on the above characteristics of async {…}.

The task {…} support of F# 6 is built on a foundation called “resumable code” RFC FS-1087. Resumable code is a core technical feature which can be used to build many kinds of high-performance asynchronous and yielding state machines.

In the coming months we will be working with the F# community to utilise this feature to make available two key optional packages:

A fast re-implementation of F# async {…} using resumable code.
A fast re-implementation of asynchronous sequences asyncSeq {…} using resumable code.

Initially these will be delivered via community packages such as FSharp.Control.AsyncSeq. In future versions they may be integrated into FSharp.Core.

Making F# simpler to learn: indexing with expr[idx]

In F# 6, we begin allowing the syntax expr[idx] for indexing syntax.

Up to and including F# 5.0, F# has used expr.[idx] as indexing syntax. This syntax was based on a similar notation used in OCaml for string indexed lookup. Allowing the use of expr[idx] is based on repeated feedback from those learning F# or seeing F# for the first time that the use of dot-notation indexing comes across as an unnecessary divergence from standard industry practice. There is no need for F# to diverge here.

This is not a breaking change – by default no warnings are emitted on the use of expr.[idx]. However, some informational messages are emitted related to this change suggesting code clarifications, and some further informational messages can be optionally activated. For example, an optional informational warning (/warnon:3566) can be activated to start reporting uses of the expr.[idx] notation. See Indexer Notation for details.

In new code, we recommend the systematic use of expr[idx] as the indexing syntax.

Making F# faster: Struct representations for partial active patterns

F# includes the active patterns feature that allows users to extend pattern matching in intuitive and powerful ways. In F# 6 we’ve augmented that feature with optional Struct representations for active patterns. This allows you to use an attribute to constrain a partial active pattern to return a value option:

[<return: Struct>]
let (|Int|_|) str =
match System.Int32.TryParse(str) with
| true, int -> ValueSome(int)
| _ -> ValueNone

The use of the attribute is required. At usage sites, code doesn’t change. The net result is that allocations are reduced.

Making F# more uniform: overloaded custom operations in computation expressions

F# 6 activates the feature “overloaded custom operations in computation expressions” which has been in preview since F# 5.0. This allows for simpler DSLs in F# including for validation and web programming.

The feature was previously described in the announcement for F# 5.0 preview and implements F# RFC 1056.

Making F# more uniform: “as” patterns

In F# 6, the right hand side of an “as” pattern can now itself be a pattern. This is important when a type test has given a stronger type to an input. For example, consider the code

type Pair = Pair of int * int

let analyzeObject (input: obj) =
match input with
| 😕 (int * int) as (x, y) -> printfn $”A tuple: {x}, {y}”
| 😕 Pair as Pair (x, y) -> printfn $”A DU: {x}, {y}”
| _ -> printfn “Nope”

let input = box (1, 2)

In each pattern case the input object is type-tested. The right-hand-side of the “as” pattern is now allowed to be a further pattern which can itself match the object at the stronger type.

Making F# more uniform: Indentation syntax revisions

The F# community has contributed some key improvements to make the F# language more uniform in F# 6. The most important of these is removing a number of inconsistencies and limitations in F#’s use of indentation-aware syntax, see RFC FS-1108. This resolved 10 significant issues highlighted by the F# users since F# 4.0.

For example, in F# 5.0 the following was allowed:

let c = (
printfn “aaaa”
printfn “bbbb”
)

However the following was not (producing a warning)

let c = [
1
2
]

In F# 6, both are allowed. This makes F# simpler and easier to learn. The F# community contributor Hadrian Tang has led the way on this including remarkable and highly valuable systematic testing of the feature.

Making F# more uniform: Discards on use bindings

F# 6 allows _ to be used in a use binding, for example:

let doSomething () =
use _ = System.IO.File.OpenText(“input.txt”)
printfn “reading the file”

This feature implements F# RFC FS-1102.

Making F# more uniform: Formatting for binary numbers

F# 6 adds the %B pattern to the available format specifiers for binary number formats. Consider the following F# code:

printf “%o” 123
printf “%B” 123

This code prints the following output:

173
1111011

This feature implements F# RFC FS-1100.

Making F# faster: InlineIfLambda

In F# 6, we’ve added a new declarative feature that allows code to optionally indicate that lambda arguments should be inlined at callsites.

For example, consider the following iterate function to traverse an array:

let inline iterateTwice ([<InlineIfLambda>] action) (array: ‘T[]) =
for j = 0 to array.Length-1 do
action array[j]
for j = 0 to array.Length-1 do
action array[j]

If the callsite is

let arr = [| 1.. 100 |]
let mutable sum = 0
arr |> iterateTwice (fun x ->
sum <- sum + x)

then after inlining and other optimizations the code becomes:

let arr = [| 1.. 100 |]
let mutable sum = 0
for j = 0 to array.Length-1 do
sum <- array[i] + x
for j = 0 to array.Length-1 do
sum <- array[i] + x

Unlike previous versions of F#, this optimization applied regardless of the size of the lambda expression involved. This feature can also be used to implement loop unrolling and similar transformations reliably.

An opt-in warning (/warnon:3517, off by default) can be turned on to indicate places in your code where InlineIfLambda arguments are not bound to lambda expressions at callsites. In normal situations, this warning should not be enabled, however in certain kinds of high-performance programming it can be useful to ensure all code is inlined and flattened.

Making F# faster: Improved performance and debugging for list and array expressions

In F# 6, the compiled form of generative list and array expressions is now up to 4x faster (see the relevant pull request). Generative list and array expressions also have greatly improved debugging. For example:

let generateList (i: int) =
[ “a”
“b”
for j in 1 .. 10 do
“c”
if i % 3 = 0 then
“d”
“e”
]

This function generates lists of size 13 or 23 depending on the input and now executes more efficiently and breakpoints can be set on the individual lines

Making F# simpler and more interoperable: Implicit conversions

In F# 6 we have activated support for additional “implicit” and “type-directed” conversions in F#, as described in RFC FS-1093.

This change achieves three things.

Fewer explicit upcasts are required
Fewer explicit integer conversions are required
First-class support for .NET-style implicit conversions is added

Additional implicit upcast conversions

In F# 5.0 and before, upcasts were needed for the return expression when implementing a function where the expressions have different subtypes on different branches, even when a type annotation was present. Consider the following F# 5.0 code (StreamReader derives from TextReader):

open System
open System.IO

let findInputSource() : TextReader =
if DateTime.Now.DayOfWeek = DayOfWeek.Monday then
// On Monday a TextReader
Console.In
else
// On other days a StreamReader
File.OpenText(“path.txt”) :> TextReader

Here the branches of the conditional compute a TextReader and StreamReader respectively, and the upcast was added to make both branches have type TextReader. In F# 6, these upcasts are now added automatically. This means the code can now be simpler:

let findInputSource() : TextReader =
if DateTime.Now.DayOfWeek = DayOfWeek.Monday then
// On Monday a TextReader
Console.In
else
// On other days a StreamReader
File.OpenText(“path.txt”)

You may optionally enable the warning /warnon:3388 to show a warning at every point an additional implicit upcast is used, as described below.

Implicit integer conversions

Type-directed conversions also allow for automatically widening 32-bit integers to 64-bit integers more often. For example, the use of 64-bit integers is now ubiquitous in machine-learning libraries. Consider a typical API shape:

type Tensor(…) =
static member Create(sizes: seq<int64>) = Tensor(…)

In F# 5.0, integer literals for int64 must be used:

Tensor.Create([100L; 10L; 10L])

or

Tensor.Create([int64 100; int64 10; int64 10])

In F# 6, widening happens automatically for int32 to int64, int32 to nativeint and int32 to double, when both source and destination type are known during type inference, so in cases such as the above int32 literals can be used:

Tensor.Create([100; 10; 10])

Despite this change, F# still continues to use explicit widening of numeric types in most cases. For example, implicit widening does not apply to other numeric types such as int8 or int16, nor from float32 to float64, nor when either source or destination type is unknown. You may also optionally enable the warning /warnon:3389to show a warning at every point op_Implicit is used for method arguments.

NOTE: High-performance modern tensor implementations are available through TorchSharp and TensorFlow.NET.

First-class support for .NET-style implicit conversions

The addition of type-directed conversions allows .NET “op_Implicit” conversions to be applied automatically in F# code when calling methods. For example, in F# 5.0 it was necessary to use XName.op_Implicit when working with .NET APIs for XML:

open System.Xml.Linq

let purchaseOrder = XElement.Load(“PurchaseOrder.xml”)

let partNos = purchaseOrder.Descendants(XName.op_Implicit “Item”)

In F# 6, op_Implicit conversions are applied automatically for argument expressions when they are available and the types are known for the source expression and target type:

open System.Xml.Linq

let purchaseOrder = XElement.Load(“PurchaseOrder.xml”)

let partNos = purchaseOrder.Descendants(“Item”)

You may optionally enable the warning /warnon:3390 to show a warning at every point implicit numeric widening is used, as described below.

Optional warnings for implicit conversions

When used widely, or inappropriately, type-directed and implicit conversions can interact poorly with type inference and lead to code that is harder to understand. For this reason, some mitigations are in-place to help ensure this feature is not widely abused in F# code. First, both source and destination type must be strongly known, with no ambiguity or additional type inference arising. Secondly, opt-in warnings can be activated to report any use of implicit conversions, with one warning on by default:

/warnon:3388 (additional implicit upcast)

/warnon:3389 (implicit numeric widening)

/warnon:3390 (op_Implicit at method arguments)

/warnon:3391 (op_Implicit at non-method arguments, on by default)

If your team wants to ban all uses of implicit conversions you can also use /warnaserror:3388, /warnaserror:3389, /warnaserror:3390, /warnaserror:3391.

Making F# simpler: Updating immutable collections

This release sees the addition of five new operations to the core collection functions in FSharp.Core. These are:

List/Array/Seq.insertAt
List/Array/Seq.removeAt
List/Array/Seq.updateAt
List/Array/Seq.insertManyAt
List/Array/Seq.removeManyAt

These all perform copy-and-update operations on the corresponding collection type or sequence. Examples of using these functions can be seen in the documentation, e.g. for List.insertAt.

As an example, consider the model, message and update logic for a simple “Todo List” application written in the Elmish style. Here the user interacts with the application, generating messages, and the update function processes these messages, producing a new model:

type Model =
{ ToDo: string list }

type Message =
| InsertToDo of index: int * what: string
| RemoveToDo of index: int
| LoadedToDos of index: int * what: string list

let update (model: Model) (message: Message) =
match message with
| InsertToDo (index, what) ->
{ model with ToDo = model.ToDo |> List.insertAt index what }
| RemoveToDo index ->
{ model with ToDo = model.ToDo |> List.removeAt index }
| LoadedToDos (index, what) ->
{ model with ToDo = model.ToDo |> List.insertManyAt index what }

With these new functions, the logic is clear and simple and relies only on immutable data.

Making F# simpler: Map has Keys and Values

In FSharp.Core 6.0.0.0 the Map type new supports Keys and Values properties. These do not copy the underlying collection.

Making F# simpler: Additional intrinsics for NativePtr

In FSharp.Core 6.0.0.0 we add new intrinsics to the NativePtr module:

NativePtr.nullPtr
NativePtr.isNullPtr
NativePtr.initBlock
NativePtr.clear
NativePtr.copy
NativePtr.copyBlock
NativePtr.ofILSigPtr
NativePtr.toILSigPtr

As with other functions in NativePtr these functions are inlined and their use emits warnings unless /nowarn:9 is used. The use of these functions is restricted to unmanaged types.

Making F# more uniform: Additional numeric types with unit annotations

F# supports Units of Measure, allowing annotation tags to be added to numeric types. However, in previous versions not all numeric types supported these annotations. In F# 6, the following types or type abbreviation aliases now support unit-of-measure annotations, the new additions are shown with a +:

F# alias
CLR Type

float32/single++
System.Single

float/double+
System.Double

decimal
System.Decimal

sbyte/int8+
System.SByte

int16
System.Int16

int/int32+
System.Int32

int64
System.Int64

byte+/uint8+
System.Byte

uint16+
System.UInt16

uint+/uint32+
System.UInt32

uint64+
System.UIn64

nativeint+
System.IntPtr

unativeint+
System.UIntPtr

For example, you can annotate an unsigned integer as follows:

[<Measure>]
type days

let better_age = 3u<days>

This design revision was championed, designed and implemented by community member Paulmichael Blasucci.

Bringing F# forward: Reducing use of rarely used symbolic operators

In F# programming, “ref cells” can be used for heap-allocated mutable registers. While they are occasionally useful, in modern F# coding these are rarely needed as let mutable can normally be used instead. The F# core library includes two operators := and ! and two functions incr and decr specifically related to reference calls. The presence of these operators makes reference cells more central to F# programming than they need to be, requiring all F# programmers to know these operators. Further, the ! operator can be easily confused with the not operation in C# and other languages, a potentially subtle source of bugs when translating code.

As a result, in F# 6 we’ve made a decision to give soft guidance that de-normalizes the use of :=, !, incr and decr in F# 6 and beyond. Using these operators and functions will now given informational messages asking you to replace your code with explicit use of the Value property.

The rationale for this change is to reduce the number of operators the F# programmer needs to know.

For example, consider the following F# 5.0 code:

let r = ref 0

let doSomething() =
printfn “doing something”
r := !r + 1

First, in modern F# coding reference cells are rarely needed, as let mutable can normally be used instead:

let mutable r = 0

let doSomething() =
printfn “doing something”
r <- r + 1

If reference cells are used, then the in F# 6 an informational warning is emitted asking you to change the last line to r.Value <- r.Value + 1, and linking you to further guidance on the appropriate use of reference cells.

let r = ref 0

let doSomething() =
printfn “doing something””
r.Value <- r.Value + 1

These messages are not warnings – they are “informational messages” shown in the IDE. This remains backwards-compatible, and is described in RFC FS-1111.

Bringing F# forward: Removing long-deprecated legacy features

F# 2.0 deprecated several F# features, giving warnings if they were used. These features been removed in F# 6.0 and will give errors, unless you explicitly use /langversion:5.0 or before. The features that now give errors are:

Multiple generic parameters using a postfix type name, for example (int, int) Dictionary. This becomes an error in F# 6 and the standard Dictionary<int,int> should be used instead.

#indent “off”. This becomes an error in F# 6

x.(expr). This becomes an error in F# 6

module M = struct … end . This becomes an error in F# 6
Use of inputs *.ml and *.mli. This becomes an error in F# 6
Use of (*IF-CAML*) or (*IF-OCAML*). This becomes an error in F# 6
Use of land, lor, lxor, lsl, lsr or asr as infix operators. These are infix keywords in F# because they were infix keywords in OCaml and are not defined in FSharp.Core. Using these keywords will now emit a warning (not error)

These are described in RFC FS-1114

F# tooling: Pipeline debugging!

One of the most anticipated features in the F# 6 toolchain is the addition of “Pipeline debugging”. Now, the F# compiler emits debug stepping points for each position in an F# pipeline involving |>, ||> and |||> operators. At each step, the input or intermediate stage of the pipeline can be inspected in a typical debugger.

For example:

Breakpoints can also be set at each point in the pipeline, for example:

Pipeline debugging activates by default when you re-compile your code with the F# 6 compiler, regardless of the language version or IDE you are using. Play with stepping and breakpoints and let us know what you think!

F# tooling: Value shadowing shown in debugger

The updated F# 6 toolchain makes another important improvement to debugging. For example, consider the code

let someFunctionUsingShadowing x =
let yyy = “aa”
let yyy = “aa”.Length – 1
yyy + 3

Here the second yyy “shadows” the first. This is allowed in F# and the technique is a common one because F# defaults to immutable bindings, hence new versions of bindings often replace previous ones.

When using an F# 6 toolchain, the names associated with locals are adjusted for those portions of scopes where shadowing occurs. For example, when a breakpoint is placed on the expression yyy + 3 of the above function, the locals are displayed as follows:

F# tooling: Performance and Scalability

In F# 6, we have made dramatic improvements to Compiler/IDE-tooling perf/scalability improvements in both the core implementation of the language and the Visual Studio components.

The F# compiler now performs the parsing stage in parallel, resulting in approximately 5% performance improvement for large projects.
Analysis results are now performed concurrently. When working in the IDE, analysis requests are no longer serialized through a single “reactor” compilation thread. Instead, the F# Compiler Service is now concurrent. This greatly improves performance in many situations.
Improved performance of analysis in F# projects that contain signature files. If you are using signature files in your project you will see diagnostics and other analysis results much more quickly when a change is made to an implementation file without change to the signature file. This change was also included in the final releases of Visual Studio 2019.
Find-all references is now performed concurrently, in parallel across multiple projects.
Major performance improvements to “Close solution” and “Switch configuration”. For example, some simple use cases have reduced “Close solution” from 16 seconds to 1 second. For a demonstration of this see this tweet by contributor Will Smith.

F# tooling: In-memory cross-project referencing!

In F# 6, we made working between F# and C# projects simpler and more reliable through “In-memory cross-project referencing” from F# to C#.

This means in C# projects are now reflected immediately in a F# project without having to compile the C# project on-disk. It also means analysis results are available in uncompiled solutions.

F# tooling: .NET Core the default for scripting

If you open or execute an F# Script (.fsx) in Visual Studio, by default the script will be analysed and executed using .NET Core with 64-bit execution. This functionality was in preview in Visual Studio 2019 and is now enabled by default.

To enable .NET Framework scripting, use Tools -> Options -> F# Tools -> F# Interactive and set Use .NET Core Scripting to false and restart the F# Interactive window. This setting affects both script editing and script execution.

64-bit scripting is now also the default. To enable 32-bit execution for .NET Framework scripting, also set 64-bit F# Interactive to false. There is no 32-bit option for .NET Core scripting.

F# tooling: F# scripts now respect global.json

If you execute a script using dotnet fsi in a directory containing a global.json with a .NET SDK setting, then the listed version of the .NET SDK will be used to execute and for editing the the script. This feature has been in preview in the later versions of .NET 5.

For example, assume is a script is in a directory with the following global.json specifying a .NET SDK version policy:

{
“sdk”: {
“version”: “5.0.200”,
“rollForward”: “minor”
}
}

This is a powerful feature that lets you “lock down” the SDK used to compile, analyse and execute your scripts.

If you now execute the script using dotnet fsi, from this directory, the SDK version will be respected. If the SDK is not found, you may need to install it on your development machine.
Visual Studio and other IDEs will respect this setting when you are editing script.
When you start or reset the F# Interactive evaluation window in Visual Studio, the SDK choice is delayed until you first use “Send to Interactive” (Alt-Enter) from the script. At this point, the SDK chosen will the one used for editing and executing the script.

On Linux and other UNIX systems you can combine a global.json with a shebang with a language version for direct execution of the script. A simple shebang for script.fsx is:

#!/usr/bin/env -S dotnet fsi

printfn “Hello, world”

The script can be executed directly with script.fsx. You can combine this with a specific, non-default language version like this:

#!/usr/bin/env -S dotnet fsi –langversion:5.0

Note that this setting will be ignored by editing tools, which will analyse the script assuming latest language version.

F# tooling: .NET Interactive in Visual Studio Code and Visual Studio!

.NET Interactive Notebooks allow you to use notebook-style programming with F# and C#. Many improvements have been made in recent releases including excellent support in Visual Studio Code.

Also just announced is a Notebook Editor extension for Visual Studio 2022.

Making F# simpler to learn: Code Examples!

In October, the F# community has worked on an initiative to add code examples for all public entry points to the F# Core Library. 800 code examples have now been contributed! For example:

All functions in the List, Array, Seq and Map modules now have code examples.
Functions and methods in advanced modules such as Quotations now have examples.

You can contribute to this initiative via this GitHub issue.

System.Text.Json support for common F# types

Starting with .NET 6 System.Text.Json will have built-in support for common F# types. An example is shown below.

User-defined discriminated unions are not yet supported in this way. Thank you to Eirik Tsarpalis for contributing this to .NET.

General Improvements in .NET 6

F# 6 is built on .NET 6, and F# programmers benefit both directly and indirectly from a host of new features and improvements in the runtime. Some of these are listed below, summarized from the announcements for .NET 6 Release Candidate 1 and previous release announcements.

Source build, a scenario and infrastructure being developed with Red Hat that is intended to satisfy packaging rules of commonly used Linux distributions, such as Debian and Fedora. Also, source build is intended to enable .NET Core contributors to build a .NET Core SDK with coordinated changes in multiple repositories. The technology is intended to solve common challenges that developers encounter when trying to build the whole .NET Core SDK from source.

Profile-guided optimization, which is based on the assumption that code executed as part of a startup often is uniform and that higher level performance can be delivered by leveraging it. PGO can compile startup code at higher quality, reduce binary size, and rearrange application binaries so code used at startup is co-located near the start of the file.

Dynamic PGO, a mirror image of PGO, integrated with the RyuJIT .NET just-in-time compiler. Performance is improved.

Crossgen2, to generate and optimize code via ahead-of-time compilation, is now enabled by default when publishing ReadyToRun images.

Intel Control Enforcement Technology (CET), available in some new Intel and AMD processors to protect against common types of attacks involving control-flow hijacking.

HTTP/3, previewed in .NET 6, solves functional and performance challenges with previous versions of HTTP.

W^X, a security mitigation to block attack paths by disallowing memory pages to be writable and executable at the same time.

Other improvements in .NET 6 include:

Interface casting performance has been improved by 16 percent to 38 percent.
Code generation has been improved in RyuJIT via multiple changes, to make the process more efficient or resulting code run faster.
Single-file bundles now support compression.
Single-file application publishing improvements including improved analysis to allow for custom warnings.
Enhanced date, time, and time zone support.
Significantly improved FileStream performance on Windows.
OpenSSL 3 support has been added for cryptography on Linux.
OpenTelemetry Metrics API support has been added. OpenTelemetry, which has been supported in recent .NET versions, promotes observability.
WebSocket compression for libraries reduces the amount of data transmitted over a network.
Package validation tools enable NuGet library developers to validate that packages are consistent and well-formed.
TLS support for DirectoryServices.Protocols.
Native memory allocation APIs.

General Improvements in Visual Studio

The release of F# 6 coincides with the release of Visual Studio 2022 on Windows. F# programmers using this IDE experience will benefit from many improvements in this release:

Visual Studio 2022 on Windows is now a 64-bit application. This means you can open, edit, run, and debug even the biggest and most complex solutions without running out of memory.

Find in Files is faster. Find in Files is now as much as 3x faster when searching large solutions such as Orchard Core.

Multi-repo support with Git in the IDE. If you’ve worked with projects hosted on different Git repositories, you might have used external tools or multiple instances of Visual Studio to connect to them. With Visual Studio 2022, you can work with a single solution that has projects in multiple repositories and contribute to them all from a single instance of Visual Studio.

Personalization improvements. For example, Visual Studio 2022 offers you the ability to sync with your Windows theme – if you’ve enabled the “night light” feature there, Visual Studio uses it, too.

What’s next

Now that F# 6 is released, we’re moving our focus to a few areas:

Simplifying the F# learning experience
Continuing to modernize the F# language service implementation
Planning for the next F# version

Cheers, and happy F# coding!

Thanks and Acknowledgments!

F# is developed as a collaboration between the .NET Foundation, the F# Software Foundation, their members and other contributors including Microsoft. The F# community is involved at all stages of innovation, design, implementation and delivery and we’re proud to be a contributing part of this community.

Many people have contributed directly and indirectly to F# 6, including all who have contributed to the F# Language Design Process through fsharp/fslang-suggestions and fsharp/fslang-design repositories. Robert Peele developed TaskBuilder.fs and Nino Floris developed Ply.

Will Smith, Kevin Ransom, Vlad Zarytovskii, Phillip Carter, Don Syme, Brett V. Forsgren contributed directly at Microsoft under the guidance of Jon Sequeira and Tim Heuer.

Eugene Auduchinok made 41 PRs to the F# core implementation, including significant improvements to error recovery. Florian Verdonck made 24 PRs, including improved source trees for the Fantomas source code formatter. Hadrian Tang made 22 PRs, including several of the language features and simplifications outlined in this blog post. GitHub user kerams made 13 pull requests, including support for SkipLocalsInit and performance improvements. Scott Hutchinson made 9 PRs, Goswin Rothenthal made 7 PRs, Ryan Coy made 6 PRs, Victor Baybekov made 5 PRs, including performance improvements to Map and Set in FSharp.Core. Some of these improvements were shipped in later versions of FSharp.Core 5.0.x.

Other direct contributors to the dotnet/fsharp repository in the F# 6.0 time period include forki, smoothdevelopers, cristianosuzuki77, ErikSchierboom, jonfortescue, teo-tsirpanis, MaxWilson, mmitche, DedSec256, uxsoft, Swoorup, En3Tho, 0x6a62, uweigand, MecuStefan, JYCabello, Yatao Li, amieres, chillitom, Daniel-Svensson, Krzysztof-Cieslak, thinkbeforecoding, abelbraaksma and ShalokShalom.

Many other people are contributing to the rollout of F# 6 and .NET 6 in Fable, Ionide, Bolero, FSharp.Data, Giraffe, Saturn, SAFE Stack, WebSharper, FsCheck, DiffSharp, Fantomas and other community-delivered technologies.

Contributor Showcase

In this and future announcements we will highlight some of the individuals who contribute to F#. This text is written in the contributors’ own words:

I’m Nino Floris, co-founder of Crowded and contributor to Npgsql and other projects. At Crowded we endeavor to create a friendly community platform, written in F# with a focus on fast apis and principled flexibility. I am interested in statically typed programming languages that bring adaptable, performant, and usable programming experiences to more places. Small open source communities with big impact hold a special place in my heart – when I’m not busy with work you may see me contributing to Npgsql, (web) frameworks, or sharing my enthusiasm for programming by helping people in the community.

I’m Hadrian Tang, a 19-year-old student at Hong Kong University of Science and Technology studying Information Systems for the second year. I started programming in 2014 by picking up a book on VB.NET at the school library. I moved to C#, then started looking into F# after reading a comment by Charles Roddie in 2018. I was reluctant to adopt F#, but the simple syntax and interoperability ultimately won me over. However, like every language, F# has much to improve, which is why I’m the author of 17% of currently open issues at the F# suggestions repo. Last summer, I took a shot at some of the easy features that ultimately made it to F# 6. I use F# for mobile development using and for my next project plan to use Fable and web interfaces to improve interoperability with JavaScript’s huge array of libraries, teaming up with [WhiteBlackGoose] (https://github.com/WhiteBlackGoose).

Much thanks to Don Syme for creating such an amazing language with simple syntax and great interoperability, and to the F# Discord for a great place to help each other: I could get help from the community with any problems that I faced. Moreover, GitHub and .NET also give a great foundation for all F# work. I love how F# is agile: starting PRs to implement unapproved features can lead to approval. I look forward to the future of F#, especially with the theme of making F# simple! And much thanks to the F# community as a whole for libraries, tooling and support!

The post What’s new in F# 6 appeared first on .NET Blog.