Programming Languages

1151 readers
2 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
51
 
 

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 introduced the language a bit and then talked about the interpreter that Chris and I built. This post is about the compiler that Chris and I built.

52
 
 

This is about Rust, but it's a great post and likely relevant to languages with Rust-style ownership. It describes four features planned for Rust to make its borrow checker more expressive and permissive:

  • Allow a function to return a reference in one branch of a conditional and not consider it "borrowed" in the other branch (this is supported by the new borrow checker, Polonius, which should be in stable Rust very soon).
  • Allow "place" lifetimes; that is, lifetimes that refer to other variables or their fields (e.g. 'foo.bar is a lifetime that, when attached to a reference, means the reference is borrowing foo.bar or some data within it).
  • View types and inter-procedural AKA "partial" borrows: define a function that can only borrow specific fields in a structure, so that the function can be called with a structure whose other fields (at the call-site) are mutably borrowed or moved.
  • Self-referential structures: structures where one field borrows another owned field (e.g. Foo { foo: String, bar: &'self.foo str }, foo is owned and bar borrows from it). Crates like self_cell and ouroboros provide this feature, but the goal is to have it in safe Rust with a cleaner syntax.
53
 
 

From the page:

My aim is to produce a superset of C++ that has a rigorously safe subset. Start a new project, or take an existing one, and write safe code in C++. Code written in the safety context exhibits the same strong safety guarantees as safe code programmed in Rust. Indeed, lifetime safety is enforced statically with borrow checking, the signature safety technology first introduced in Rust

...

What properties characterize Safe C++?

  • A superset of C++ with a safe subset. Undefined behavior is prohibited from originating in the safe subset.
  • The safe and unsafe parts of the language are clearly delineated, and users must explicitly leave the safe context to use unsafe operations.
  • The safe subset must remain useful. If we get rid of a crucial unsafe technology, like unions or pointers, we should supply a safe alternative, like choice types or borrows. A perfectly safe language is not useful if it's so inexpressive you can't get your work done.
  • The new system can't break existing code. If you point a Safe C++ compiler at existing C++ code, that code must compile normally. Users opt into the new safety mechanisms. Safe C++ is an extension of C++. It's not a new language.
#feature on safety
#include "std2.h"

int main() safe {
  std2::vector<int> vec { 11, 15, 20 };

  for(int x : vec) {
    // Ill-formed. mutate of vec invalidates iterator in ranged-for.
    if(x % 2)
      vec^.push_back(x);

    unsafe printf("%d\n", x);
  }
}
$ circle iter3.cxx
safety: iter3.cxx:10:10
      vec^.push_back(x);
         ^
mutable borrow of vec between its shared borrow and its use
loan created at iter3.cxx:7:15
  for(int x : vec) {
              ^

A couple other languages aiming to create a "C++ successor" which is fully interoperable with C++ (analogous to TypeScript and JavaScript):

  • Carbon: an entirely new language which compiles straight to LLVM, but still strives to be highly interoperable with C++. Its goal is to add "modern" features: new syntax, parametric polymorphism, as well as removing C++'s backwards-compatibility quirks.
    • It has a section on memory safety which mentions a "safe Carbon subset". But this is a longer-term goal, whereas it's the main goal of Circle.
  • Cpp2: an alternate syntax for C++. It compiles to C++, but makes new features such as modules and concepts less verbose, while hiding or removing backwards-compatibility quirks (e.g. lists are std::array and string literals are std::string).
    • 100% memory safety is a non-goal: AFAIK it doesn't do static analysis and syntactic rewrites alone aren't powerful enough to enforce it.

Compared to the other languages, Circle remains closest to C++. The other languages try to fix other C++ "problems"; Circle's only goal is to fix memory unsafety, and otherwise keep syntax and semantics the same for maximum interoperability.

54
 
 

Design documentation: https://github.com/ZILtoid1991/pixelperfectengine/blob/master/docs/formats/m2.md

It has some weird solutions due to my limited experience with the subject and the target usage favor preallocation instead of live allocation. I took some inspirations from Music Macro Language, Assembly, and Lua. Due to the lack of a MIDI 2.0 format, I thought I'd come up with my own, adding capabilities to program adaptive soundtracks (emitting MIDI commands with calculated values, conditional emitting of MIDI commands, conditional looping and pattern playback, etc).

I initially gave it the name .m2 but while M.2 is an entirely different thing, an MML format by the name .m2 does exist on the PC98, thus I'm looking for some new name for mine. The only thing I can come up on the spot is MASM (or MIDI Assembly), but it's close to an already existing MASM (Microsoft Macro Assembler).

55
 
 

Another post from the creator of Vale, the last one was "Borrow checking, RC, GC, and the Eleven (!) Other Memory Safety Approaches".

This discusses Vale's higher RAII, a feature implemented using linear types. Vale has linear types as opposed to Rust's affine types: affine types prevent using a value after it's "moved", but linear types also prevent not moving a value (i.e. cannot just let it go out of scope). Additionally in Vale, one can define a set of functions that destroy a type, and in order to destroy a value of that type, one must call a function from that set; that is what Vale calls "higher RAII".

This part of the linked post contains seven examples where Vale's higher RAII enforce invariants that Rust's affine types cannot. In a language like C, you can "forget" to use a value and it will leak. In a language like Rust, the value will be properly deallocated, but you can still have "forgotten" about it, e.g. perhaps the value represents a transaction that you meant to commit (one of the seven examples). In Vale, you can't forget about a value as long as it has a linear type, because doing so will raise a compile-time error.

The rest of the post further discusses higher RAII, elaborating on what it is and why its useful, explaining why it's more general than other languages' defer and how it could be integrated into other languages, and more.

56
 
 

From the site:

We have entered a world in which we need to do more with less. If you, like us, have frowned at the difficulty and inefficiency of creating software, and wondered if there is a better way, Meta is for you. It is a descendant of the acclaimed REBOL and Logo computer languages. Logo was designed in academia to teach programming in a simple yet powerful way. It is widely used in education and influenced many newer systems and languages. REBOL extended this concept to professional programming. It was invented by Carl Sassenrath, the chief software designer of the famous Amiga computer, the first consumer multimedia system. Meta takes the next step by combining this design with the virtues of the C programming language, which has been the standard for software interoperability and performance for half a century.

meta-lang-examples (GitHub)

Try online ("console")

57
 
 

This essay says that inheritance is harmful and if possible you should "ban inheritance completely". You see these arguments a lot, as well as things like "prefer composition to inheritance". A lot of these arguments argue that in practice inheritance has problems. But they don't preclude inheritance working in another context, maybe with a better language syntax. And it doesn't explain why inheritance became so popular in the first place. I want to explore what's fundamentally challenging about inheritance and why we all use it anyway.

58
 
 

From the article.

I present the “Lambda Screen”, a way to use terms of pure lambda calculus for generating images. I also show how recursive terms (induced by fixed-point combinators) can lead to infinitely detailed fractals.

59
60
 
 

Rye is a high level, homoiconic dynamic programming language based on ideas from Rebol, flavored by Factor, Linux shell and Go. It's still in development, but we are focused on making it useful as soon as possible.

It's written in Go and could also be seen as Go's scripting companion as Go's libraries are very easy to integrate, and Rye can be embedded into Go programs as a scripting or a config language.

I believe that as a language becomes higher level it starts bridging the gap towards user interfaces. Rye has great emphasis on interactive use (Rye console) where we intend to also explore that.

GitHub

From Wikipedia:

A language is homoiconic if a program written in it can be manipulated as data using the language…This property is often summarized by saying that the language treats code as data.

The classic example of homoiconicity is LISP. Rye borrows a lot from LISP: there are no keywords (if, for, extends are functions), mutating functions end with !, and the homepage highlights DSLs (“dialects”) and flexibility. But not many parenthesis.

Rebol, the mentioned inspiration, is its own rabbit hole. Like Rye, it touts simplicity, homoiconicity, and support for DSLs. Unlike Rye, it’s very old (although the site’s still being maintained): check out this UI.

61
 
 

Call-by-push-value is an evaluation strategy that determines when arguments to functions are evaluated. Call-by-value is what every mainstream language does: arguments are evaluated before the function is called. Call-by-name substitutes arguments directly into a function, so they may be evaluated multiple times or not at all. For example, the following pseudocode:

function foo(n, m) {
    sum = 0
    for i in 1 to 4 {
        sum = n + sum
    }
    if false {
        print(m)
    }
    print(sum)
}

foo({print("1"); 2}, {print("3"); 4})

evaluated with Call-by-Value prints:

1
3
8

evaluated with Call-by-Name prints:

1
1
1
1
8

Call-by-push-value combines both by having two "kinds" of parameters: values which are evaluated immediately (call-by-value), and computations which are substituted (call-by-name). So the following code:

function foo(value n, computation m) {
    sum = 0
    for i in 1 to 4 {
        sum = n + sum
    }
    if false {
        print(m)
    }
    print(sum)
}

foo({print("1"); 2}, {print("3"); 4})

would print

1
8

The reason call-by-push-value may be useful is because both call-by-name and call-by-value have their advantages, especially with side-effects. Besides enabling programmers to write both traditional functions and custom loops/conditionals, CBPV is particularly useful for an IR to generate efficient code.

Currently, Scala has syntactic sugar for by-name parameters, and some languages like Kotlin and Swift make zero-argument closure syntax very simple (which does allow custom loops and conditionals, though it's debatable whether this is CBPV). Other languages like Rust and C have macros, which can emulate call-by-name, albeit not ideally (you have hygiene issues and duplicating syntax makes compilation slower). I don't know of any mainstream work on CBPV in the IR side.

62
 
 

Created by Niko Matsakis, a core Rust developer (Language Team leader) who was influential in its evolution. He wrote the last article I posted. Also worked on by Brian Anderson, another core developer who worked on Rust in its early stages, on critical features such as the Result type as well as build system, testing support, and language websites.

Dada is a thought experiment. What if we were making a language like Rust, but one that was meant to feel more like Java or JavaScript, and less like C++? One that didn't aspire to being used in kernels or tiny embedded devices and was willing to require a minimal runtime. What might that look like?

...

Dada is an ownership-based language that is in some ways similar to Rust:

  • Like Rust, Dada doesn't require a garbage collector.
  • Like Rust, Dada guarantees memory safety and data-race freedom.
  • Like Rust, Dada data structures can be allocated in the stack and use flat memory layouts.

In other ways, though, Dada is very different:

  • Like TypeScript, Dada is a gradually typed language:
    • That means you can start out using Dada in the interpreter, with no type annotations, to get a feel for how it works.
    • Once you've gotten comfortable with it, you can add type annotations and use the compiler for performance comparable to Rust.
  • Dada targets WebAssembly first and foremost:
  • Dada is object-oriented, though not in a purist way:
    • Dada combines OO with nice features like pattern matching, taking inspiration from languages like Scala.

Dada also has some limitations compared to Rust:

  • Dada has a required runtime and does not target "bare metal systems" or kernels.
  • Dada does not support inline assembly or arbitrary unsafe code.
63
 
 

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/

64
65
0
submitted 10 months ago* (last edited 10 months ago) by jeffhykin@lemm.ee to c/programming_languages@programming.dev
 
 

TLDR; do you know of any general purpose languages that can also compile a function to some representation of AND/OR gates (or NAND gates, or whatever)?

Edit: actually any algebra/formal-logical system is also fine (not just boolean algebra).

Yes, a A LOT of additional info is needed, like defining how input/output is defined, and I am interested in how those would be specified. I'm not interested in printing an actual circuit, just the boolean-logic level. And I'm mostly asking because I feel like most compilers can't generate a clean/mathematical representation from their AST. There's AST to IR, there's hard-coded optimizations on the IR, and then there's hard-coded mappings from the IR to assembly, but at no point (AFAIK) is the code turned into a algebraic/logical system where something like De Morgan's Law can be applied. And that seems really sad to me.

So you could say my real question is: what compilers have a strong logical/algebraic internal representation of their own AST?

Maybe something like Haskell or Prolog do this. The Wolfram Language almost certainly does but it's closed source.

66
 
 

cross-posted from: https://programming.dev/post/1379446

Why I think Typescript is A Good Thing, But mainly a complaint about the number of programming languages. Other than objects (which were not invented), I don't think any of them are a marked improvement on PL/1.

67
 
 

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/14ngaly/july_2023_monthly_what_are_you_working_on_thread/

68
 
 

cross-posted from: https://programming.dev/post/265357

Introducing Otterkit COBOL

Given that this is a community about the COBOL programming language, I'd like to take the opportunity to make a post about this project that I'm a part of. Our goal is to create a compiler implementing the ISO 2023 standard of the COBOL language. If you're confused/interested in what that means, please read further.

Why a new COBOL Compiler?

It is often believed that COBOL is an antiquated and archaic language: the logo of this community is literally a dinosaur. But this is not true. Did you that as of the most recent version (ISO 2023), the language has:

  • objects and classes
  • generics
  • concurrent async both locally and remotely (message passing)

Sounds more like a Java or C# than a fossil, doesn't it?

As the "2023" in "ISO 2023" implies, the language has been evolving ever since it was created in the '50s. But why is the reputation of this language so bad? Firstly, it is that most code in COBOL adheres to the old 1985 standard: that was when the GNU manifesto was first published! This means that the language has been functionally stuck in the public eye for decades, as enterprise systems see little reason to put effort into modernization. This leads to a self-fulfilling prophecy, where COBOL programmers are assigned to tangles of technical debt and even FOSS compilers like GnuCOBOL target the 1985 standard because it's the one that's used. But it doesn't have to be this way.

A Vision of the Future

It is our belief in the Otterkit Project team that modern COBOL, once free of propriety vendor lock-in and outdated stereotypes, has the potential to be a modern - nay, insightful language that deserves a place in the current programming language landscape. That's why we're making an Apache 2.0-licensed COBOL compiler on the .net platform to bring modern COBOL out in the open. This way, we hope to prove that even dinosaurs can walk again.

We would appreciate any help we can get: below are links to a presentation team head KT made on the project for the .net youtube channel, and a link to the github repo. Please take some time to look around, and if it strikes your fancy please consider contributing with either code or money, any bit helps.

Useful Links

Github Repo: https://github.com/otterkit/otterkit

Presentation: https://www.youtube.com/live/UASkE7cojSE?feature=share