Creează un cont pentru a te abona la acest blog și a-i urmări articolele pe pagina Lectură.
-
Language Design: Unions in Bytecode (WIP)
Overview When designing bytecode operations for unions, encoding what is being done (instead of how) leads to desirable design properties: Higher resilience against changes to the union definition, which in turn improves support for separate compilation.
-
Language Design: Unions in Memory (WIP)
Union types in the sense of typed unions share many similarities with other kinds of unions when it comes to representing union values in memory, but also pose a few question unique to typed unions.
-
Language Design: Multi-Color Number Literals
TLDR: Use multiple colors to make the various components of your number literals easily distinguishable.
-
Language Design: Equality & Identity – Part 5: Fixing Java
The recent development of Java is an interesting case, as it faces these questions more acutely with the introduction of value types in Project Valhalla.
-
Language Design: Rust's Almost-Rules
(Inspired by Almost Rules.)
-
Library Design: Naming Conventions – Part 3: Option & Result
Many languages’ Option and Result types suffer from an organically-grown and therefore inconsistently named set of functions.
-
Language Design: Rust's Struct Initializer Syntax Was a Mistake
Rust has distinct syntactic facilities for … invoking functions initializing structs and enums initializing tupled structs and enums … that provide different affordances and features: method arguments are positional and cannot be named initializer argumen…
-
Time to wind down Rust feature development
TL;DR: Regardless on where you stand on the “Rust 2.0”, Rust’s current approach to language evolution is not sustainable.
-
Language Design: Drop `break` and `continue`
TL;DR: Optimize for the common case, not the exotic ones.
-
Language Design: Unified Condition Expressions – Comparison with Rust
simple if expression if x == 1.0 { "a" } else { "z" } This translates straight-forward to Rust: if x == 1.0 { "a" } else { "z" } multiple cases, equality relation if x ... == 1.0 { "a" } ... == 2.0 { "b" } else { "z" } In Rust, using
-
Language Design: `Result` naming
I was never too happy with the existing naming approaches for the Result type: Success/Failure pro: both names have the same length, like Option’s Some/None con: quite long, concern that people may use Option over Result Ok/Err pro: short con: names don’t…
-
Language Design: Typing Terminology
Most people think only in terms of the dichotomy between Nominal-Manifest-Static-Strong and Structural-Inferred-Dynamic-Weak in any given discussion of programming language type system design.
-
Language Design: Schemas as Source Code
TLD;DR: Your compiler should treat schema definitions as a valid (alternate) source syntax of your programming language.
-
Language Design: Useful Syntax Sugar
get sugar Rule x.get(y) can be written as x(y) Explanation Instead of special-purpose syntax that is used for indexing operations (reading) in many languages, like int firstValue = someArray[0]; one can write let firstValue = someArray(0) /* same as */ l…
-
Language Design: The Cost of Everything
Merit Points Item -100 Adding a language feature to do something that can already be done -90 Adding a language feature to do something that can be implemented in a library -80 Adding a language feature to do something that can be achieved by fixing a com…
-
Language Design: Fields & Methods & Properties? – Pick Two!
TL;DR: Properties are a hack employed to retrofit “nice” syntax into languages that already shipped with fields and methods.
-
Language Design: Familiarity – Familiarity is a tie-breaker, not a self-sufficient argument
In the past, many languages did not pick up easily adoptable language design improvements and opted for familiarity instead, often in a misguided attempt to keep perceived language complexity down.
-
Language Design: Equality & Identity – Part 6: Fixing Rust
Rust designers recognized the issues with Haskell’s approach, but were not able to address the issues with Rust’s Eq and PartialEq traits.
-
Library Design: Naming Conventions – Part 5: Streaming
Projections Function Name Code Example Explanation map(<fun>) List(1, 2, 3).map(_ + 1) --> List(2, 3, 4) Returns a stream in which fun is applied to each element. mapMany(<fun>) mapMulti flatMap mapFlat mapAndFlatten List(1, 2).mapMany(x -> List(x, x)) -->
-
Library Design: Naming Conventions – Part 4: Lookup
Function Name Code Example Explanation – List(12.3, 45.6)(0) --> Some(12.3) Map("key", "val")("key") --> Some("val") retrieves the value at the given index/key at(idx) Array(12.3, 45.6).at(1) --> Some(Ref(arr, 1)) returns a reference to the given position…
-
Language Design: Against Mixed-cased Type Names
There is no good reason¹ why some type names need to start with a lower-case letter (int, float, str, …) and others with an upper-case letter (String, BigInt, Array, …).
-
Language Design: Annotations Obsolete Modifiers – Failed Attempts
Kotlin Kotlin gave up on it, as they couldn’t figure out how to recognize annotation usages as early in the compiler pipeline as modifiers previously.
-
Language Design: Annotations Obsolete Modifiers
TL;DR: If your language has annotations1, it doesn’t need modifiers.
-
Language Design: Four Kinds of Unions
Overview Syntactic Wrapping No Syntactic Wrapping No Runtime Tags untagged union (C union, C++ union, Rust union) union type (TypeScript union type) Runtime Tags discriminated union/tagged union (Rust enum, F# discriminated union) typed union (Algol united
-
Language Design: Popular, but Wrong
static members properties (see) <> for generics (see) [] for arrays (see) Type ident instead of ident: Type (see) having if-then-else and switch/case and a ternary operator (see) having both modifiers and annotations (see) async/await separate namespaces…
-
Language Design: Stop Using `<>` for Generics
TL;DR: Use [] instead of <> for generics.
-
Language Design: Modern and Minimal
A smaller language, not a bigger one namespaces: types, terms, packages , fields , methods , labels modifiers: keywords , annotations nesting: packages , modules, static members: fields, methods, properties control flow: if-then-else, return, while, break…
-
Language Design: Unified Condition Expressions – Implementation
As a first approximation – especially if an existing language shall be adapted – it makes sense to build a feature-reduced version of unified condition expressions using a different keyword, in parallel to existing syntax.
-
Language Design: Unary Operators are Unnecessary
TL;DR: Unary operators are a waste of a language’s complexity budget.
-
Language Design: Binary Operators are Overused
TL;DR: Use methods.
-
Language Design: Equality & Identity – Part 4: Fixing Haskell
Basic goals, as mentioned in the previous parts: You should not lose values inside a data structure.
-
Language Design: Comparing and Sorting
Similarly to equality and identity, most languages have severely restricted facilities to handle distinct ordering relationships like comparison and sorting.
-
Language Design: Use Consistent Keyword Length
6 letters namespacing – declaring and managing namespaces: module (unifies “object” and “package”) import export 5 letters “big” definitions (types): class (reference type) value (value type, alternative to struct) union (alternative to enum) trait (inter…
-
Library Design: Naming Conventions – Part 2: Conversion
Function Name Code Example Explanation to array.toList int32Value.toFloat64 dictionary.to[Queue] implies a (potentially lossy) conversion of a value result type might use Option or Result types to encode failures as int64Value.asFloat64 int64Value.as[Floa…
-
Library Design: Naming Conventions – Part 1: Creation
Function Name Code Example Explanation – List(1, 2, 3) Array(12.3, 45.6) Set("a", "b", "c") primary way of construction resulting instance contains provided arguments verbatim of(val1, ...)
-
Language Design: Unified Condition Expressions – Exceptions
A reasonable question that might be asked is whether this design can be extended to also handle thrown exceptions, and whether such an extension could completely replace the try-catch-finally idiom.
-
Language Design: Rust's Into in Scala
Rust’s Into Rust’s std::convert::Into let’s you define conversion functions for structs like Person: pub struct Person { name: String } impl Into<String> for Person { fn into(self: Person) -> String { self.name } } This way functions can be defined…
-
Language Design: Unified Condition Expressions – Introduction
Idea Replace the different syntactic forms of if statements/expressions switch on values match on patterns and pattern guards if-let constructs with a single, unified condition expression that scales from simple one-liners to complex pattern matches.
-
Language Design: Package Objects in Scala
Scala has the concept of package objects which allow the declaration of methods, classes etc. that appear as if they existed directly inside a package, not enclosed in an object or a class.
-
Language Design: Equality & Identity – Part 3: Solution
Let’s take a step back and think about what these equality operations do: Reference equality acts as a built-in, hard-coded comparison of the references themselves.
-
Language Design: Equality & Identity – Part 2: Problems
Containment The core issue is that equality on its own is insufficient to implement some, rather mundane, algorithms.
-
Language Design: Equality & Identity – Part 1: Overview
Most languages have a notion of equality comparisons based on value equality.
-
Language Design: (More) Mistakes of Rust
(A random grabbag of things that I haven’t managed to include into the main article yet.)
-
Language Design: Use `ident: Type`, not `Type ident`
In expressive languages, developers generally need to use fewer temporary variables.
-
Language Design: Generics
Two interconnected design decisions achieve a particularly interesting sweet-spot in language design: The ident: Type syntax allows consistent and straight-forward placement of generics, compared to languages which use Type ident1: Generics ([T]) always f…
-
Language Design: Fixing Rust's mistakes – Syntax
As Rust 2.0 is not going to happen, Rust users will never get these language design fixes:1234 A note on the lower bar of a hypothetical Rust 2.0 An article touching on "Rust 2.0" and its reactionary reception made it apparent that language evolution has…
-
Language Design: Implicit Numeric Conversions
TL;DR: The desire to make unrelated types act as if they were in a sub-typing relationship, which neither exists nor should exist, combined with syntax sugar that makes static dispatch look like dynamic dispatch creates a perfect storm of unintended, harm…