Programming Languages

1089 readers
24 users here now

Hello!

This is the current Lemmy equivalent of https://www.reddit.com/r/ProgrammingLanguages/.

The content and rules are the same here as they are over there. Taken directly from the /r/ProgrammingLanguages overview:

This community is dedicated to the theory, design and implementation of programming languages.

Be nice to each other. Flame wars and rants are not welcomed. Please also put some effort into your post.

This isn't the right place to ask questions such as "What language should I use for X", "what language should I learn", and "what's your favorite language". Such questions should be posted in /c/learn_programming or /c/programming.

This is the right place for posts like the following:

See /r/ProgrammingLanguages for specific examples

Related online communities

founded 1 year ago
MODERATORS
1
 
 

How much progress have you made since last time? What new ideas have you stumbled upon, what old ideas have you abandoned? What new projects have you started? What are you working on?

Once again, feel free to share anything you’ve been working on, old or new, simple or complex, tiny or huge, whether you want to share and discuss it, or simply brag about it - or just about anything you feel like sharing!

The monthly thread is the place for you to engage /c/programming_languages on things that you might not have wanted to put up a post for - progress, ideas, maybe even a slick new chair you built in your garage. Share your projects and thoughts on others’ ideas, and most importantly, have a great and productive month!

Also see: https://www.reddit.com/r/ProgrammingLanguages/comments/1b3fqrz/march_2024_monthly_what_are_you_working_on_thread/

2
 
 

IELR(1) a niche LR(1) parser generator. More well-known are LALR and Pager's "minimal" LR(1) algorithm (PGM(1)), but IELR(1) can generate a parser for certain grammars that those cannot. This post by the same authors goes into more detail about the problem IELR(1) solves.

The linked post is about implementing IELR(1), in particular the challenges the authors faced doing so.

They've implemented IERL(1) in their own parser generator, hocc, that they're writing for their own language, Hemlock: "a systems programming language that emphasizes reliable high performance parallel computation" that is (or at least very similar to) an ML dialect.

3
 
 

Most visual programming environments fail to get any usage. Why? They try to replace code syntax and business logic but developers never try to visualize that. Instead, developers visualize state transitions, memory layouts, or network requests.

In my opinion, those working on visual programming would be more likely to succeed if they started with aspects of software that developers already visualize.

...

Developers say they want "visual programming", which makes you think "oh, let's replace if and for". But nobody ever made a flow chart to read for (i in 0..10) if even?(i) print(i). Developers familiar with code already like and understand textual representations to read and write business logic^2^.

Let's observe what developers do, not what they say.

Developers do spend the time to visualize aspects of their code but rarely the logic itself. They visualize other aspects of their software that are important, implicit, and hard to understand.

Here are some visualizations that I encounter often in serious contexts of use:

  • Various ways to visualize the codebase overall.
  • Diagrams that show how computers are connected in a network
  • Diagrams that show how data is laid out in memory
  • Transition diagrams for state machines.
  • Swimlane diagrams for request / response protocols.

This is the visual programming developers are asking for. Developers need help with those problems and they resort to visuals to tackle them.

4
 
 

Bio is an experimental Lisp dialect similar to Scheme, with an interpreter written in Zig

Features include macros, garbage collection, error handling, a module facility, destructuring, and a standard library.

Example:

(filter
    (quicksort '(5 40 1 -3 2) <)
        (λ (x) (>= x 0)))

(1 2 5 40)
5
 
 

Supercompilation^1^ is a program transformation technique that symbolically evaluates a given program, with run-time values as unknowns. In doing so, it discovers execution patterns of the original program and synthesizes them into standalone functions; the result of supercompilation is a more efficient residual program. In terms of transformational power, supercompilation subsumes both deforestation^2^ and partial evaluation^3^, and even exhibits certain capabilities of theorem proving.

Mazeppa is a modern supercompiler intended to be a compilation target for call-by-value functional languages. Unlike previous supercompilers, Mazeppa 1) provides the full set of primitive data types, 2) supports manual control of function unfolding, 3) is fully transparent in terms of what decisions it takes during transformation, and 4) is designed with efficiency in mind from the very beginning.

Supercompilation explained on Stack Overflow

Mazeppa example (https://github.com/mazeppa-dev/mazeppa/blob/master/examples/sum-squares/main.mz):

main(xs) := sum(mapSq(xs));

sum(xs) := match xs {
    Nil() -> 0i32,
    Cons(x, xs) -> +(x, sum(xs))
};

mapSq(xs) := match xs {
    Nil() -> Nil(),
    Cons(x, xs) -> Cons(*(x, x), mapSq(xs))
};

Mazeppa automatically translates the above program into the semantically-equivalent but more efficient:

main(xs) := f0(xs);

f0(x0) := match x0 {
    Cons(x1, x2) -> +(*(x1, x1), f0(x2)),
    Nil() -> 0i32
};

It also generates a graph to visualize and debug the transformation (SVG if it doesn't load):

Mazeppa is written in OCaml and can be used as an OCaml library.

6
 
 

Think Repl.it, but a simpler version for esoteric languages, with a visual debugger catered to each language, that runs in your browser.

The linked example shows a Brainfuck "Hello world!" program. You can run it and visualize instructions executed in real time, the memory, and the output. You can pause/step, insert breakpoints, adjust the delay after each instruction, and enter user input. There's also syntax highlighting and checking.

All languages

7
 
 

Some features:

  • Ruby-like syntax, terse lambdas that look like regular control statements.
  • Everything is an object.
  • Integrated package manager.

Jaguar is a small app that wirelessly connects to an ESP32 and can load and live-reload Toit programs. This is opposed to something like connecting the device via USB and re-installing the program every time you make a change.

Example (https://github.com/toitlang/toit/blob/master/examples/wifi/scan.toit, see the GitHub link for syntax highlighting):

// Copyright (C) 2022 Toitware ApS.
// Use of this source code is governed by a Zero-Clause BSD license that can
// be found in the examples/LICENSE file.

// This example illustrates how to scan for WiFi access points.

import net.wifi

SCAN-CHANNELS := #[1, 2, 3, 4, 5, 6, 7]

main:
  access-points := wifi.scan
      SCAN-CHANNELS
      --period-per-channel-ms=120
  if access-points.size == 0:
    print "Scan done, but no APs found"
    return

  print """
      $(%-32s "SSID") $(%-18s "BSSID") \
      $(%-6s "RSSI") $(%-8s "Channel") \
      $(%-8s "Author")\n"""

  access-points.do: | ap/wifi.AccessPoint |
    print """
        $(%-32s ap.ssid) $(%-18s ap.bssid-name) \
        $(%-6s ap.rssi) $(%-8s ap.channel) \
        $(%-8s ap.authmode-name)"""
8
 
 

Scrapscript is a small, pure, functional, content-addressable, network-first programming language.

fact 5
. fact =
  | 0 -> 1
  | n -> n * fact (n - 1)

My previous post talked about the compiler that Chris and I built. This post is about some optimization tricks that we've added since.

Pretty much all of these tricks are standard operating procedure for language runtimes (OCaml, MicroPython, Objective-C, Skybison, etc). We didn't invent them.

They're also somewhat limited in scope; the goal was to be able to add as much as possible to the baseline compiler without making it or the runtime notably more complicated. A fully-featured optimizing compiler is coming soon™ but not ready yet.

9
 
 

The blog explains how to solve the following problem using Picat and planner programming, a form of logic programming:

Suppose that at the beginning there is a blank document, and a letter "a" is written in it. In the following steps, only the three functions of "select all", "copy" and "paste" can be used.

Find the minimum number of steps to reach at least 100,000 a's (each of the three operations of "select all", "copy" and "paste" is counted as one step). If the target number is not specified, and I want to get the exact amount of "a"s, is there a general formula?

- Math Stack Exchange

10
 
 

A programming model that is a graph, where code is written on the edges to add behavior and interactivity to the connected nodes.

Video demo:

Live demo

11
 
 

I wanted people to be able to try out my language online, and it’s now possible with a vscode like interface, sending code to a docker image running the interpreter!

It was easier than I thought to implement, and yes, security was a concern, but I have been able to harden the docker container as well as implement restrictions on the websocket server to avoid having users escaping the docker image and getting access to the VM it’s running on.

12
 
 

This pattern [(multi-stage programming)], which I'll refer to as "biphasic programming," is characterized by languages and frameworks that enable identical syntax to express computations executed in two distinct phases or environments while maintaining consistent behavior (i.e., semantics) across phases. These phases typically differ temporally (when they run), spatially (where they run), or both.

An older (2017) page on multi-stage programming

Winglang ("a programming language for the cloud"), the author's language

13
 
 

Abstract:

We present associated effects, a programming language feature that enables type classes to abstract over the effects of their function signatures, allowing each type class instance to specify its concrete effects.

Associated effects significantly increase the flexibility and expressive power of a programming language that combines a type and effect system with type classes. In particular, associated effects allow us to (i) abstract over total and partial functions, where partial functions may throw exceptions, (ii) abstract over immutable data structures and mutable data structures that have heap effects, and (iii) implement adaptors that combine type classes with algebraic effects.

We implement associated effects as an extension of the Flix programming language and refactor the Flix Standard Library to use associated effects, significantly increasing its flexibility and expressive power. Specifically, we add associated effects to 11 type classes, which enables us to add 28 new type class instances.

See also: the Flix programming language

14
15
 
 

Abstract:

The expression problem describes how most types can easily be extended with new ways to produce the type or new ways to consume the type, but not both. When abstract syntax trees are defined as an algebraic data type, for example, they can easily be extended with new consumers, such as print or eval, but adding a new constructor requires the modification of all existing pattern matches. The expression problem is one way to elucidate the difference between functional or data-oriented programs (easily extendable by new consumers) and object-oriented programs (easily extendable by new producers).

This difference between programs which are extensible by new producers or new consumers also exists for dependently typed programming, but with one core difference: Dependently-typed programming almost exclusively follows the functional programming model and not the object-oriented model, which leaves an interesting space in the programming language landscape unexplored.

In this paper, we explore the field of dependently-typed object-oriented programming by deriving it from first principles using the principle of duality. That is, we do not extend an existing object-oriented formalism with dependent types in an ad-hoc fashion, but instead start from a familiar data-oriented language and derive its dual fragment by the systematic use of defunctionalization and refunctionalization

Our central contribution is a dependently typed calculus which contains two dual language fragments. We provide type- and semantics-preserving transformations between these two language fragments: defunctionalization and refunctionalization. We have implemented this language and these transformations and use this implementation to explain the various ways in which constructions in dependently typed programming can be explained as special instances of the general phenomenon of duality.

Background:

Expression problem (wikipedia)

Defunctionalization (wikipedia)

Codata in action, or how to connect Functional Programming and Object Oriented Programming (Javier Casas)

16
 
 

Several months ago I gave a talk at work about Hindley-Milner type inference. When I agreed to give the talk I didn't know much about the subject, so I learned about it. And now I'm writing about it, based on the contents of my talk but more fleshed out and hopefully better explained.

I call this a reckless introduction, because my main source is wikipedia. A bunch of people on the internet have collectively attempted to synthesise a technical subject. I've read their synthesis, and now I'm trying to re-synthesise it, without particularly putting in the effort to check my own understanding. I'm not going to argue that this is a good idea. Let's just roll with it.

17
 
 

In this post, I will talk about the first version of the Intermediate Representation I designed for Kunai Static Analyzer, this is a dalvik analysis library that I wrote as a project for my PhD, also as a way of learning about the Dalvik file format and improving my programming skills.

Kunai source (Github)

Kunai paper

Shuriken (Kunai successor)

Dalvik is a discountinued VM for Android

18
 
 

Pre-Scheme is an interesting Scheme dialect which is being ported to modern systems. The language, why its being ported, and the porting effort are described in the linked post.

As described in the Pre-Scheme paper, the language offers a unique combination of features:

  • Scheme syntax, with full support for macros, and a compatibility library to run Pre-Scheme code in a Scheme interpreter. The compiler is also implemented in Scheme, enabling both interactive development and compile-time evaluation.
  • A static type system based on Hindley/Milner type reconstruction, as used in the ML family of languages (eg. Standard ML, OCaml, Haskell). Pre-Scheme supports parametric polymorphism, and has nascent support for algebraic data types and pattern matching, which are recently gaining popularity in mainstream languages.
  • An optimizing compiler targeting C, allowing for efficient native code generation and portable low-level machine access. C remains the common interface language for operating system facilities, and compatibility at this level is essential for modern systems languages.

Due to the restrictions of static typing and the C runtime model, Pre-Scheme does not (currently) support many of Scheme's high-level features, such as garbage collection, universal tail-call optimization, heap-allocated runtime closures, first-class continuations, runtime type checks, heterogenous lists, and the full numeric tower. Even with these limitations, Pre-Scheme enables a programming style that is familiar to Scheme programmers and more expressive than writing directly in C.

Ironically, Pre-Scheme's original purpose was to implement the interpreter for another Scheme dialect, Scheme 48 (Wikipedia). But the lower-level Pre-Scheme is now getting its own attention, in part due to the popularity of Rust and Zig. Pre-Scheme has the portability and speed of C (or at least close to it), but like Rust and Haskell it also has a static type system with ADTs and parametric polymorphism; and being a LISP dialect, like most other dialects it has powerful meta-programming and a REPL.

19
 
 

GitHub

From README:

Lady Deirdre is a framework for incremental programming language compilers, interpreters, and source code analyzers.

This framework helps you develop a hybrid program that acts as a language compiler or interpreter and as a language server for a code editor's language extension. It offers the necessary components to create an in-memory representation of language files, including the source code, their lexis and syntax, and the semantic model of the entire codebase. These components are specifically designed to keep the in-memory representation in sync with file changes as the codebase continuously evolves in real time.

Key Features

  • Parser Generator Using Macros.
  • Hand-Written Parsers.
  • Error Resilience.
  • Semantics Analysis Framework.
  • Incremental Compilation.
  • Parallel Computations.
  • Web-Assembly Compatibility.
  • Source Code Formatters.
  • Annotated Snippets.
  • Self-Sufficient API.
20
21
 
 

F is written in K, another small language. In fact, the entire implementation is in one file: http://www.nsl.com/k/f/f.k.

Example program (defines factorial and computes fac(6), from http://www.nsl.com/k/f/f/fac.f):

[[1=][][dup!pred!fac!*]cond!]fac

The main site, "no stinking loops", is full of links including to other languages (scroll down) and resources on K. Although many are broken 🙁.

22
 
 

Discuss.

23
 
 

Adding Rust FFI into Vale, in particular the part where the Vale compiler determines the signature and proper overload of a Rust function.

Our ultimate goal is to write this Vale code:

import rust.std.vec.Vec;

exported func main() {
  vec = Vec<int>.with_capacity(42);
  println("Length: " + vec.capacity());
}
Length: 42

...which would successfully make a Rust Vec and call capacity on it.

Previous

24
 
 

vvvv is a node-based visual programming environment whose programs run on the CLR (same virtual machine as C#). It has hot reloading (compilation happens in the background) and can be extended with custom nodes written in C#. It has built-in libraries for 2D and 3D rendering, image recognition, machine learning, networking, and IO for various devices (Kinect and cameras). It's been used for a lot of interactive art installations, as seen in the "showcase" section on the website.

25
 
 

See also: earlier years.

view more: next ›