How to improve Julia (in 2.0 taking from [research] languages): E.g. 2nd class functions

In general, I’m pointing to research I find interesting, and asking what can, and should be adopted in Julia. Or if you had to do it again, were designing a better (Julia) language, what you would do?

Some programming language terminology is hard to digest, I’m not going to explain [side] effects, that most are familiar with, or first-class (functions, or higher-order), but “first-class” functions (well anything) might seem better, who really rather wants 2nd class anything? Well these guys:

A.
Gentrification gone too far? affordable 2nd-class values for fun and (co-) effect.

Abstract
First-class functions dramatically increase expressiveness, at the expense of static guarantees. In ALGOL or PASCAL, functions could be passed as arguments but never escape their defining scope. Therefore, function arguments could serve as temporary access tokens or capabilities, enabling callees to perform some action, but only for the duration of the call. In modern languages, such programming patterns are no longer available.

The central thrust of this paper is to re-introduce second-class functions and other values alongside first-class entities in modern languages. We formalize second-class values with stack-bounded lifetimes as an extension to […]
First, we modify the Scala Collections library and add privilege annotations to all higher-order functions. Privilege parametricity is key to retain the high degree of code-reuse between sequential and parallel as well as lazy and eager collections. Second, we use scoped capabilities to introduce a model of checked exceptions in
the Scala library, with only few changes to the code. Third, we employ second-class capabilities for memory safety in a region-based off-heap memory library.

1. Introduction
Modern programming languages offer much greater expressiveness than their ancestors from the 1960s and ’70s. Many of the advancements that directly translate to programmer productivity are the result of removing restrictions on how
certain entities can be used, and granting “first-class” status to more and more language constructs.

Most modern languages have abolished these restrictions and admit functions (or objects with methods) as first-class citizens alongside integers and real numbers. Even conservative languages, like Java and C++, have added closures, albeit with some limitations. But uniformly replacing second-class with first-class constructs1 is a process not unlike gentrification in urban development, where inexpensive living space is transformed into posh condos in an effort of modernization, but ultimately leading to an undesirable situation where inexpensive and restricted “second-class” constructs are no longer available.

1 Technically, many languages still distinguish between, e.g., normal functions and closures, but most allow converting second-class to first-class values via eta-expansion, which effectively removes the distinction.

Maybe Julia can learn from Rust, like Scala (I added bold):

Rust-like borrowing with 2nd-class values (short paper)

The Rust programming language demonstrates that memory safety can be achieved in a practical systems language, based on a sophisticated type system that controls object lifetimes and aliasing through notions of ownership and borrowing. While Scala has traditionally targeted only managed language runtimes, the ScalaNative effort makes Scala a viable low-level language as well. Thus, memory safety becomes an important concern, and the question bears asking what, if anything, Scala can learn from Rust. In addition, Rust’s type system can encode forms of protocols, state machines, and session types, which would also be useful for Scala in general. A key challenge is that Rust’s typing rules are inherently flow-sensitive, but Scala’s type system is not. In this paper, we sketch one possible method of achieving static guarantees similar to Rust with only mild extensions to Scala’s type system. Our solution is based on two components: First, the observation that continuation passing style (CPS) or monadic style can transform a flow-sensitive checking problem into a type-checking problem based on scopes. Second, on a previously presented type system extension with second-class values, which we use to model scope-based lifetimes.

B.
I didn’t mean to discuss effects, or an actual implementations of, here, just to point it out the concept, and a language implementing it:

[Koka is interesting but Effekt (new/er to me, seems better/more interesting) also, previously available as a library, so in that sense could be added to Julia in 1.0.]

Let’s keep the discussion on effects centralized in

3 Likes

Re-opening now that there’s a bit more focus on 2nd class functions :slight_smile:

2 Likes