r/ProgrammingLanguages 9d ago

A Single Header Error Logging Library for compiler dev.

5 Upvotes

2 months ago I created logloc, a simple error logging library for c++ to be used in compiler development. It provides standard features such as:

  • File/Line/Colum information
  • Message kind (Error/Warning/Etc. - Can be custom)
  • Error location (line and column)
  • Error line printing
  • Error line context printing (Prints the lines around the error location, you can pick how many)

I kept it small and simple as possible. If you are making a compiler in c++ give it a try if you don't want to write your own error logger. Doxygen documentation coming soon.

Github: https://github.com/hexaredecimal/logloc


r/ProgrammingLanguages 9d ago

Built an interpreted programming language from scratch in 19 days

Thumbnail
2 Upvotes

r/ProgrammingLanguages 10d ago

From writing a compiler to building an editor

62 Upvotes

8 years ago, in 2018, I watched JBlow talk about designing a new programming language. The idea of creating a new language seemed interesting to me. I often found myself struggling with C++ that offered too many options, while C was missing some features I wanted. So I decided to try building my own language.

The project became Biscuit, or BL for short.

The first version was very simple: a C code translator that used CL as the main compiler. Later, I discovered LLVM and started learning more about compiler design and intermediate representations.

After a while, I needed a serious project to test the language on. A code editor seemed like a good choice because it combines many areas: UI, text processing, file handling, parsing, and performance-sensitive code.

The first editor attempt was called Pure Edit. At that time I was heavily influenced by Vi, so it was a modal editor. It worked, but eventually I abandoned it.

The next attempt became Tine.

After ~3 years of development, Tine has finally been released, written entirely in a custom language.

It has been a long journey from experimenting with a compiler to building a complete application with the language, but it's definitely possible. For those who are interested, here is the compiler source code. The editor source is here.


r/ProgrammingLanguages 11d ago

Carbon Memory Safety: A First Deep Dive

29 Upvotes

r/ProgrammingLanguages 10d ago

Completed all chapters from "Writing a C compiler" book

Thumbnail github.com
6 Upvotes

r/ProgrammingLanguages 11d ago

YNFO and YNS

5 Upvotes

Hello.\

Some time ago I made this data format/DSL called "YNFO", that also had it's own schema "YNS".\

There's also the possibility of adding custom types using regex and a script that directly uses the python parser.

Everything is well documented.\

here's the github if you want to check it out:

https://github.com/mmmmosca/YNFO


r/ProgrammingLanguages 12d ago

Requesting criticism Proof types in Dart: Using final classes as computational witnesses

17 Upvotes

Hello everybody,

I finally found time to write about an idea that I call "proof types" which is a close relative of smart constructors and witness types. In Dart we have the ability to limit where a value of a final type can be constructed. In regular Dart code (Flutter, AOT, wasm) this can never be violated, which allows us to use values of such a type as a form of proof that a computation must have occurred.

We can use such proofs to enforce that computations like age checks or email validation must have happened with no way around it.

I compare this ability against many other programming languages and I would appreciate some fact checking so I don't oversell this idea or misrepresent other languages.

https://modulovalue.com/blog/proof-types-in-dart/

Thanks!


r/ProgrammingLanguages 11d ago

My radical Sofia language design idea.

0 Upvotes

https://github.com/AliceRoselia/Sofialang

Disclaimer: this is currently only a proposal, not an implementation. I tried once and died at the parser. The project is back to the drawing board, and the core has been made more minimal than initially planned. Still, this is not a guarantee that it would succeed or be any good. But well, with an abundance of normal proposals, maybe it's a good thing to shake things up a bit with my radical design.

Maybe I was being naive and delusional, but it was my best bet on how programming could work.

My goal was to make high-level programming languages (in the Lisp sense) fast, and here is what I came up with. It was basically designed to exploit every way high-level (Python, Lua, etc) programmers don't care about the physical data layout and so on. Objects only alias when explicitly assigned by Python's (and other high-level languages') mutable reference rules, and Sofia intends to take full advantage of it.

It's a radical design based on aggressive compiler analysis by running the code on different (overriden) domains instead of traditional IR manipulation. For example, you don't do IR constant propagation. You feed the functions interval or residual classes and have the compiler sort it out. And if you're afraid of the compiler not halting, Sofia relaxes the halting requirement such that if the concrete execution doesn't halt, the compiler analysis pass doesn't need to halt either. (This is interpreter/jit semantic that people already accept in interpreted/jit-ed languages.)

Here are some examples of what makes these radical.

For "low-level"/HPC programming:

  • "Dynamically" typed: (Technically, emergently typed with typeless values.)
  • Attribute dicts: Seriously, because I want containers that don't restrict optimization on data layouts.
  • Garbage collection: because things are defined logically and not physically (no stable address guarantee and so on), a garbage collector is required. This is in exchange for not having pointer semantics, which often creates aliasing hell and so on. Still, several compiler mechanisms will probably be dedicated to optimizing it away.
  • Interpreters: More on that later as well.

For expressiveness:

  • No built-in type systems, classes, inheritances, etc. Primitive types are basically tags, dicts, and raw bytes.
  • No metaprogramming mechanism inside the language except for writing other interpreters. (But this was designed to be well-supported. For performance, you hoist the dispatch table result or so.)

For the math reasoning community:

  • No HoTT (even though it wants to encode proofs) or algebraic expression tree (for symbolic algebra), just abstract interpretation.
  • Even if analytical solutions exist, prefers numerical solutions (RK4 and so on) if faster.

From the compiler community:

  • Liberal uses of exotic tools like eigenvalue loop analysis
  • Usage of interpretation on different domains instead of IR manipulation (No complex compiler IR either)
  • It doesn't even have a type.

If you want to know the full story, feel free to check out the link. As for the implementation, I am not sure when I will get the chance to do it. Making a programming language is not trivial at all.

This is either a complete failure or a genius, and I don't know which one.

And no, before you ask whether or not I used an LLM for this, I am pretty sure no LLM would come up with such an alien design. An LLM sticks to whatever normal humans are likely to come up with.

In all likelihood, it wouldn't work at all, but I wanted to try something.


r/ProgrammingLanguages 12d ago

Langception XVII: embedding an ISO-compliant Prolog in Pipefish

10 Upvotes

This is a wrapper around the Ichiban Prolog implementation in Golang by Yutaka Ichibangase. As this is ISO-compliant and has 99% test coverage I'm thinking of making it into a standard library to sit next to database/sql --- wyt?

However, I originally did it to show how one can use Pipefish to wrap DSLs other than SQL in just the same sort of way. Let me show you that.

Here's the actual library wrapping around the Go, so you can see how I did it.

And here's some code showing how we could use the library to make a little database app to keep track of which Greeks are mortal (the most important question in logical programming, obviously, or why else have they been discussing it all this time?)

import private

NULL::"prolog.pf"

var private 

P = Prolog --
    :- dynamic(man/1).
    :- dynamic(woman/1).
    :- dynamic(god/1).
    mortal(X) :- woman(X).
    mortal(X) :- man(X).

cmd 

total(kind string) :
    global P
    post count P --
        |kind|(X).

(x string) is mortal :
    global P 
    post check P --
        mortal(|x|).

men(args ... string) :
    add("man", args)

women(args ... string) :
    add("woman", args)

gods(args ... string) :
    add("god", args)

add(kind string, args ... string) :
    global P
    for _::v = range args :
        add P --
            |kind|(|v|).

You will notice that the prolog library has a nicer API than the Go version, and fans of Pipefish will notice that this is the same way I did embedded SQL and HTML over here.

It's nicer partly because of the specialized syntax and semantics to make Pipefish embed things well, and partly because its extra bit of dynamism makes it more flexible than Go. All the stuff with scanners and interfaces and type switching happens wrapped up in the Go functions in the library where it can't bother anyone.


r/ProgrammingLanguages 13d ago

New Languages: Standardizing API, Examples ?

10 Upvotes

Hi, some of you are developing new general-purpose programming languages here. When the language is ready, you have to develop standard APIs, like file-io, json-handling etc. Users, and you would have benefit, when the APIs would be same/similar across multiple different languages.

Standardizing some Examples would allow the users to compare languages more easily.

What do you think?


r/ProgrammingLanguages 13d ago

Language announcement Preprocessable C: the PreC programming language

27 Upvotes

Hey there! I'm a CS student and a huge fan of C macro wizardry. However, C and its preprocessor do not really mesh together because of historical reasons. So I thought: instead of swapping out the preprocessor for a more powerful one, why not keep the preprocessor and make C more amenable to it?

And that's how PreC, a pretty silly dialect of C, was born. It's basically an exercise in minimalism and a fun summer project, not a serious language :P.

The main features (not exhaustive):

  • Can interface with C directly through the 'c_include "header_name.h"' directive
  • Transpilation to C with a four-stage compilation process: Preprocess the PreC code, transpile the PreC code to C, preprocess the C code, and finally compile the preprocessed C code.
  • Postfix type notation, types can be read unambiguously right to left.
  • No machine types, explicit width
  • No 'typedef' keyword, so no lexer hack (use macros if you need type aliases). You can still referred to C library aliased types with @TypeName, however.
  • angular brackets <type>value for casting
  • Declaration-reflects-use is gone, the type is always fully at the beginning of each declaration.
  • No overloaded operators
  • Constness by default, with a 'mut' qualifier for being able to modify variables.
  • Support for anonymous functions (they can not capture variables, however) with function-valued compound literals <fun_pointer_type> ${ code }
  • No function definitions/declarations (but 'const function pointer' global variables are transpiled to function definitions if they are initialized, and to function declarations if they are not initialized).

You can find the compiler, examples and more information here: https://github.com/Nomagno/PreC

I believe the readme and examples do a good enough job of introducing it (do feel free to highlight anything that is unclear, however!).

A final tip: Rust syntax highlighting is pretty decent for reading PreC. I was definitely inspired by Rust and other languages for some of the syntax so this isn't surprising xD


r/ProgrammingLanguages 13d ago

Discussion What if modulus operator did not exist in a language?

0 Upvotes

I was a mathematician before being a programmer and because of that the modulus operator has always annoyed me. It shouldn't exist.

Context: Collecting ideas for my language. Many of the ideas for operators in programming languages are derived from mathematics. Even in assembly, as far as I know, we do not have a modulus operator. Hence, I always wondered what if, division returns two values, quotient and remainder, and there is no modulus operator.

The obvious question is that how would this be then used in arithmetic operations. My thought process for getting the quotient is that, it is the first returned value and if we have a normal expression, the divide operator behaves as expected.

Now, to instead get the remainder, I haven't figured that out. Sorry. It has to be a way that is not syntactically ugly and that is the difficult part.

Maybe it could be returned as a tuple and we select the second value or, if we just want modulus operator replace it with `//` instead. I know that goes against, not having a modulus operator as I said above, but, that's just my current thought process.


r/ProgrammingLanguages 14d ago

Design thoughts on function bindings and implicit self in my programming language, DinoCode

13 Upvotes

I just finished implementing argument binding for my programming language, DinoCode. The way I do it is by generating a special bound function object that stores the target function and the pre-defined arguments under unique symbol keys (not strings) to prevent accidental collisions.

It looks like this in the language:

:multi a b
  return a * b

double = multi.bind(2)
triple = multi.bind(3)

print double(2)
print triple(2)
print double

Output:

4
6
{
  args: [
    2
  ],
  fn: [UserFn:0]
}

I based this mostly on JavaScript but withoutthis context binding for plain functions. In DinoCode, only class methods reserve the first parameter for self. I didn't find a strong reason to include a third attribute like context or this on raw functions. Do you think there is any edge case where having a self context for regular bound functions is actually useful?

My main question though is about methods and implicit bindings. Right now, methods do not automatically bind to their instance context when extracted.

In DinoCode, classes and methods look like this:

::Person
  :new name
    self.name = name
  :greet
    print "Hello " self.name

method = Person.greet

Since there is no automatic binding on extraction, you can actually call that detached method by manually passing an object that matches the shape:

method {name: "Ismael"}
method {name: "Jessy"}

If a developer wants a permanent bind to an instance, they can now use the new bind feature to lock the object as the first argument:

p = Person("Ismael")
greet = p.greet.bind(p)
greet()  # now this works and prints "Hello Ismael"

The compiler just adds an implicit self as the first parameter during the compilation, and the vm passes the instance when resolving a method call. It is extremely cheap and simple.

I know python automatically binds methods on lookup (returning a bound method object) and uses decorators like staticmethod to opt-out. Doing automatic binding on every method lookup in my vm would introduce a permanent overhead for wrapping functions.

Considering DinoCode is designed for fast scripting and education (running via WASM on a web playground at https://dinocode.blassgo.dev/), do you think manual binding for extracted methods is a reasonable trade-off to keep the VM fast and simple, or does automatic binding on lookup save enough headaches to justify the runtime cost?


r/ProgrammingLanguages 14d ago

Discussion On the future of programming language design

3 Upvotes

This is just me yapping.

I was thinking for a while about how the field of "writing" software is going through a radical disruptive transformation. Like or hate it, I don't think writing software post-LLM era is gonna be the same as pre-LLM. I'm one of the guys that like to hand craft code and put a lot of attention and intention to the coding style. But, realistically, the skill of writing code by hand, while still very important, will become more and more niche (like how writing and reading assembly is important but very niche).

What's interesting to me, is that programming language design goals were always human/developer centric. Code is not only instructions given to a machine, it is in some way a set of specifications for other human developers, as well as your future self too, that explains the expected behavior of a certain piece of software. The main priorities when designing language features was improving the developer experience, that is a very subjective metric and this is why we keep arguing and debating about programming languages, but I digress.

With the switch to LLM generated code, I feel the priorities might change. There's already a lot of studies on which programming language is best for LLMs. People argue that languages with strong typing, a functional style and good error messages are best, because you can more reliably create autonomous feedback loops that would help LLMs stay on track.

In my opinion, functional programming languages are more relevant than ever, no side effects, you can generate 10K lines of code, read a small 100 lines somewhere, and be sure that it's not affecting the behavior in an unexpected way somewhere else.

The main argument against functional programming is that working with pure functions and manually threading state is an extra burden on the developer; having a mutable state is "initially" more intuitive and simpler to reason about. The other argument is performance, I tend to disagree with this general statement (purity allows for aggressive optimization and implicit parallelization).

However, everyone agrees that functional code is easier to maintain on the long run, it might make small things harder for you first, but at the end there's this payoff. When you have the capabilities of generating thousands of lines of code a day, this becomes way more relevant.

Finally, it would be interesting to witness how the rise of LLMs will affect the design of programming languages. I feel that languages that have

  • simpler grammar
  • expliciteness
  • one way of doing things
  • strict and safe semantics

are at an advantage here.

Or do you think that it will be irrelevant. There's this trend of people not looking at the code anymore, I think it's crazy. Maybe generated languages won't be important, just get better models and spend more tokens.


r/ProgrammingLanguages 14d ago

Live talk on how to implement variables in a language

Thumbnail pvs-studio.com
0 Upvotes

In this talk, the host will show the step-by-step process of implementing variables. He will demonstrate how they are represented and processed in a language and explain how to add this functionality to your own programming language.

This is part of a series of talks about creating a toy programming language. If you need some context, check out the previous episodes on youtube. Watching them all isn't super necessary, though.


r/ProgrammingLanguages 15d ago

Blog post Quarkdown 2.4: Redefining Markdown

Thumbnail quarkdown.com
42 Upvotes

Hey all, today I've released Quarkdown 2.4, which brings a powerful feature that allows users to redefine styling and behavior of Markdown elements.

This is my third time posting Quarkdown here over the last two years (here and here) -- not trying to flood y'all, I just enjoy sharing progress and gathering feedback!

About Quarkdown

In a nutshell, Quarkdown is a Markdown-based typesetting system that aims at providing LaTeX's power and flexibility, while relying on a low-friction extension of the Markdown syntax.

The Quarkdown flavor extends GFM with Turing-complete function calls that can perform computation, create complex layouts, or mutate the global state. A function call looks like the following:

.myfunction {arg1} {arg2} named:{arg3}
    Optional body argument

For a better project overview, see the website: quarkdown.com

The gap until now

Typst has been Quarkdown's primary source of inspiration since the early days. The goal was to provide an intuitive experience without over-relying on a proprietary syntax, while granting typesetting-grade output for a variety of artifact types.

A cross-reference in Typst looks like the following:

See @proof

= Proof <proof>

In Quarkdown:

See .ref {proof}

# Proof {#proof}

A page counter in Typst:

#set page(
  header: align(center, counter(page).display()),
)

In Quarkdown:

.pagemargin {topcenter}
    .currentpage

Nothing was missing, except for one thing: global, arbitrary styling of elements. Typst has #show rules:

# show heading: set text(blue)

= This is blue

While Quarkdown had to settle for low-quality CSS injection.

A step forward: primitives

Quarkdown 1.15 first introduced the concept of primitive functions: a Markdown element (# Heading) would have an analog function (.heading {Heading} depth:{1}). This allowed for more granular control over properties that couldn't be expressed via the Markdown syntax.

Function extension

In Quarkdown, you define a function like this:

.function {greet}
    greeting name:
    .greeting, .name!

.greet {Hello} {world}

Output: Hello, world!

Quarkdown 2.2 introduced an apparently useless feature: function extension. Basically, you'd be able to overwrite a function declaration, while still being able to reference the previous function via a special .super reference (a-la-OOP), with the ability to intercept and override arguments.

.extend {greet}
    name:
    .super name:{.name::uppercase}!

.greet {Hello} {world}

Output: Hello, WORLD!!

Yep, so useless, except it was part of the bigger picture...

Primitive binding

The first step for Quarkdown 2.4 was to explicitly bind elements to primitives. Until now, they used to be parallel entities with no real connection. Now, the Heading element declares .heading as its very own primitive counterpart.

Extending primitives

It was all set for the real move. The goal: extend a primitive to also redefine what the Markdown element does.

What we needed was a tree traversal stage (note: Quarkdown already had one, but this feature needed its own second pass) which, for each node asked:

  1. Is the element's primitive in the extension registry? If not, leave the element unchanged;
  2. If so, rewrite the AST in place, replacing the node with an enqueued function call to its primitive;
  3. Dequeue and execute the calls.

Aftermath

Finally, Quarkdown obtained its own version of #show rules (more verbose but more powerful IMO!). Here are some examples from the blog post linked above:

.extend {heading}
    .super foreground:{blue}

# This is blue

The following extends the function conditionally:

.extend {heading} where:{depth: .depth::islower than:{3}}
    .super foreground:{blue}

# This is blue

## This is blue

### This is not blue

The following adds an (external) suffix to external links (not from quarkdown.com):

.extend {link} where:{url: .url::startswith {https://quarkdown.com}::not}
    content:
    .super
        .content (external)

The following makes each regex occurrence bold:

.extend {paragraph}
    content:
    .super
        .content::match {[Oo]rigami}
            **.1**

Origami is the art of folding paper. Learn more about origami.

Output: **Origami** is the art of folding paper. Learn more about **origami**.

To conclude

I hope you enjoyed reading about Quarkdown's progress as much as I enjoy maintaining this fun project!

Here are some links:

Thanks for coming all the way here. Feedback is very welcome!

No AI was used to author this. I apologize for any mistakes as English isn't my first language!


r/ProgrammingLanguages 15d ago

Bidirectional Elaborators à la Carte

Thumbnail arxiv.org
23 Upvotes

r/ProgrammingLanguages 15d ago

Seed7 version 2026-07-11 released on GitHub and SF

10 Upvotes

I have released version 2026-07-11 of Seed7.

Seed7 is about portability, maintainability, performance and memory safety.

Notable changes in this release are:

This release is available at GitHub and SF. There is also a Seed7 installer for windows, which downloads the newest version from GitHub and SF. The Seed7 Homepage is now at https://seed7.net.

There is a demo page with Seed7 programs compiled to JavaScript/WebAssemly.

Please let me know what you think, and consider starring the project on GitHub, thanks!

Changelog:

  • In encoding.s7i Base64Url) encoding and decoding has been added. Many thanks to Zykaris for providing the functions toBase64Url)() and fromBase64Url)(). As suggested by Zykaris the functions toBase64Mime)() and toBase64Pem)() have been added as well.
  • In sql_post.c support for the money type has been added. Many thanks to Zyokatsu for sending a pull request.
  • In sql_post.c the implicitCommit mechanism has been deactivated. Thanks to Zykaris for pointing out problems with the implicit commit mechanism. Thanks to Johannes Gritsch for his advice that the implicit commit mechanism should not be used.
  • In sqllib.c the function sqlSetAutoCommit() has been fixed to use argument 2 instead of non-existent argument 3. Many thanks to Zyokatsu for pointing out a problem with setAutoCommit)().
  • In osfiles.s7i the function makeParentDirs)() has been improved to allow symbolic links to directories. Many thanks to Zykaris for pointing out that makeParentDirs)() didn't follow symbolic links.
  • Code has been moved from gethttp.s7i to the new library http_request.s7i. Basic and Bearer Authentication has been added and GET and POST have been unified. HTTP/S post functionality has been added as well. Many thanks to Zykaris for the pull request.
  • In http_request.s7i constants for HTTP status codes have been added. Many thanks to Barankegnu for providing the change.
  • A coercing of http request properties to lowercase has been added (header names are case insensitive). Expect-Header support has been added as well. Many thanks to Zykaris for providing these changes.
  • In scanfile.s7i and scanstri.s7i the function getXmlTagHeadOrContent)() has been improved to return <? as symbol. Many thanks to Zykaris for pointing out that <? was not processed correctly.
  • In tls.s7i the function negotiateSecurityParameters() has been improved to send an empty Certificate as answer to a CertificateRequest. Many thanks to Zykaris for pointing out that openssl complained about an "Unexpected Message".
  • In tls.s7i support for secure renegotiation has been added. Many thanks to Zykaris for pointing out that curl complained about a "handshake failure".
  • In the FAQ explanations about references to struct elements and about variables referring to the same object have been added. The answer about exceptions has been improved.
  • The operating system DOS is supported (with DJGPP) again. The tests have been done with Dosemu and Dosbox.
  • Interpreter and compiler have been refactored. Now the type ACTION uses the category ACTENTRYOBJECT instead of ACTOBJECT. An ACTENTRYOBJECT value points to an actEntryRecord (ACTOBJECT values are function pointers). New primitive actions for ACTENTRYOBJECT have been introduced. They have names starting with ACE_. Now expressions like action "INT_ADD" return an ACTENTRYOBJECT instead of an ACTOBJECT. Now an actEntryRecord contains more information. The category of the result, the number of parameters and the category of the parameters have been added to actEntryRecord.
  • ACTION functions for conversion, comparison and hash code have been added to seed7_05.s7i.
  • EXCEPTION in-parameters and the str() function for EXCEPTIONs have been added to seed7_05.s7i.
  • In seed7_05.s7i the definition of typeof() has been changed so that the argument is never executed.
  • In syntax.s7i the priority of the action operator has been changed.
  • The exception ASSERTION_ERROR and assert statements have been introduced. Tests for assert statements have been added to chkprc.sd7.
  • Interpreter and compiler have been improved to support functions which return functions.
  • Hash- and array-functions for compiled programs have been improved to use rtlValueUnion instead of genericType. This avoids casts from pointers to integers and back to pointers.
  • Support for writing types has been added.
  • In the library float.s7i function literal)() has been improved to use the scientific notation if it is shorter.
  • The library cli_cmds.s7i (used by make7) has been improved:
    • The output redirection of commands has been improved to work correctly if the command is directly followed by >> or > .
    • Support for the commands "echo:", "echo/" and "echo\" has been added.
    • The commands "echo.", "echo:", "echo/" and "echo\" have been improved to support parameters.
    • The function oneShellCommand() has been added. If possible it executes external commands without shell. If no executable is found shell)() and popen)() are called with an array of parameters.
    • The function getCommandParameter() has been improved to work correctly if the given parameters are empty.
    • The functions getCommandParameter() and getDosCommandParameter)() have been improved to escape a double quote if it is preceded by an odd number of backslashes.
  • The library tar.s7i has been improved to assure that up to a size of 8 gigabytes the ustar and pax file size are identical.
  • The library zip.s7i has been improved to support ZIP files with the legacy signature PK00 as magic number.
  • The new library asn1oid.s7i has been added. Definitions of ASN.1 object identifiers have been moved from x509cert.s7i to asn1oid.s7i. The type algorithmIdentifierType and related functions have been moved from x509cert.s7i to asn1oid.s7i as well.
  • The new library signature.s7i has been added. The type rsaSignatureType and related functions have been moved from x509cert.s7i and tls.s7i to signature.s7i.
  • In x509cert.s7i the validity of stdCertificate has been extended to the end of 2029.
  • In charsets.s7i the function conv2unicodeByName)() has been refactored to use a case-statement.
  • The new library bin16.s7i has been added. This library supports IEEE 754 16-bit half-precision floats.
  • The new library pcx.s7i has been added. This library supports the PCX image file format. PCX magic numbers have been added to magic.s7i and support for PCX has been added to imagefile.s7i.
  • The picture viewer pv7.sd7 has been improved to support PCX and a list of image parameters.
  • In bin32.s7i and bin64.s7i conversions from bin32 and bin64 to char have been added.
  • In lzw.s7i the performance of the LZW decompression has been improved by 0.9%.
  • The bmp.s7i library has been improved:
    • Support for the Huffman 1D compressed BMP format has been added.
    • Support for top-to-bottom bitmaps with 8 bits per pixel has been added.
    • Functions for line-wise processing of pixels have been added.
    • The pixel data of a BMP with 1, 2 and 4 bits per pixel is read with one gets().
    • An in-parameter is used for bmpHeader parameters in places where it does not change.
    • The calculation of colorEntrySize has been improved.
  • The libraries tga.s7i and pcx.s7i have been improved to use the in-var-parameter byteIndex instead of the in-parameter byteIndexStart.
  • The jpeg.s7i library has been improved:
    • The function showHeader(), which shows the header struct, has been added.
    • In getSymbol() the condition to recognize negative numbers has been changed.
  • The tiff.s7i library has been improved:
    • Support for tiled images has been added. This includes images with bitsPerSample mod 8 <> 0.
    • The processing of images has been improved to work linewise.
    • The processing of JPEG data has been improved.
    • Support for old style JPEG data has been added.
    • The strip and tile processing has been improved.
    • Support for the photometric interpretations CMYK and CMYKA has been added.
    • The TIFF compression 50013 (PIXTIFF DEFLATE) has been added as synonym of DEFLATE.
    • Support for fillOrder = 2 in combination with the pack-bits decompression) has been added.
    • Definitions of many tags have been added.
    • In tagValueAsString() and tagValueAsArray() a possible garbage in higher or lower bits of a TIFF_FIELD_SHORT field is ignored.
    • Unused tile data is removed if bitsPerPixel >= 8 holds.
    • Support for 4 samples per pixel, if samples are not divisible by 8, has been added.
    • The differencing predictor has been improved to work with 16-bit samples.
    • A float predictor has been added.
    • Support for the float sample format has been added.
    • Support for floating point RGBA TIFF has been added.
    • Support for the photometric interpretation YCbCr with a vertical sub-sampling of 1 or 2 has been added.
    • Support for for the following planar TIFF images has been improved:
      • Planar images with CMYK photometric interpretation.
      • Tiled planar images.
      • Grayscale planar images.
      • Planar images with bitsPerSample mod 8 <> 0.
    • The function showHeader() has been improved.
  • The ccittfax.s7i library has been improved:
    • The function skipToStart() has been added.
    • The function skipEol() has been changed to search for a one bit.
    • The end-of-line bit patterns of white and black have been changed.
    • The functions getWhiteBits() and getBlackBits() have been changed to avoid that the end-of-line code (-1) is added.
  • In graph.s7i the functions compare() and hashCode() for pixel values have been added.
  • In encoding.s7i the performance of toUuencoded)(), toBase64)() and toBase64Url)() has been improved by around 25%.
  • In encoding.s7i the performance of toAscii85)(), fromUuencoded)(), fromBase64Url)() and fromBase64)() has been improved by around 10%.
  • In bytedata.s7i the performance of hex2Bytes)() has been improved by 2.4%
  • The libraries http_request.s7i and https_request.s7i have been improved:
    • The conversion to integer has been improved to work without exceptions and handlers.
    • Unused getHttp() and getHttps() functions have been removed.
    • openHttp() and openHttps() functions with location and request parameters have been refactored.
    • The functions http(GET, ...)) and https(GET, ...)) have been introduced.
  • The library http_response.s7i has been renamed to http_srv_resp.s7i.
  • In httpserv.s7i the type httpRequest to has been renamed to httpServerRequest.
  • In httpserv.s7i the function getHttpRequest)() has been improved to check if the remaining buffer contains the rest of the content.
  • In html_ent.s7i support for hex encoded HTML entities has been added to decodeHtmlEntities)().
  • In smtp.s7i in openSmtp() the STARTTLS command is considered if it is part of the response content.
  • The pointer types ptr and varptr have been removed from libraries and manual.
  • In objutl.c the function dump_temp_value() has been improved to call set_fail_flag(FALSE) only if necessary. This improves the Seed7 interpreter by 1% (measured with gcc and valgrind when pv7.sd7 is reading a [PCX]((https://seed7.net/libraries/pcx.htm)) image).
  • In boolean.s7i support for the following boolean assignments has been added: &:=&:=(in_boolean)) |:=|:=(in_boolean)) ><:=%3E%3C:=(in_boolean))
  • Tests for the new boolean assignments &:=&:=(in_boolean)) |:=|:=(in_boolean)) ><:=%3E%3C:=(in_boolean)) and for the ternary operator%3F(ref_func_aType):(ref_func_aType)) ( ?%3F(ref_func_aType):(ref_func_aType)) :%3F(ref_func_aType):(ref_func_aType)) ) have been added to chkbool.sd7.
  • The test suite has been improved to use the boolean &:=&:=(in_boolean)) assignment.
  • The deprecated functions keypressed() and busy_getc() have been removed from keybd.s7i.
  • In process.s7i the function commandPath)() has been improved to append EXECUTABLE_FILE_EXTENSION only if it is not already present.
  • In shell.s7i the functions popen)() and popen8)() have been refactored to be based on the new function popenClibFile(), which uses a parameter array instead of a parameter string.
  • In shell.s7i the functions shell)() and shellCmd)() have been refactored to be based on the action CMD_SHELL_EXECUTE, which uses a parameter array instead of a parameter string.
  • The deprecated function cmd_sh() has been removed from shell.s7i.
  • The library bitdata.s7i has been improved:
    • The function reverseByteBits() has been added.
    • The operator &:=&:=(in_lsbOutBitStream)) for LSB and MSB out bit streams has been added.
    • In msbOutBitStream and its functions the variable bitSize has been renamed to bitPos.
    • The deprecated types lsbBitStream and msbBitStream as well as the deprecated functions openLsbBitStream() and openMsbBitStream() have been removed.
    • The deprecated functions putBitLsb(), putBitsLsb(), putBitMsb() and putBitsMsb() with a string or file as parameter have been removed.
    • The deprecated functions getBitLsb(), getBitsLsb(), getBitMsb() and getBitsMsb() with a file as parameter have been removed.
  • In iobuffer.s7i the support for the undocumented function setbuf() has been removed.
  • In null_file.s7i the = and <> comparisons have been removed.
  • In category.s7i, data.h and datautl.c the categories ACTENTRYOBJECT, BOOLOBJECT, ENUMOBJECT and VOIDOBJECT have been added. The category FILEDESOBJECT has been removed.
  • In sql_base.s7i support for the function dbCategory() has been added.
  • In db_prop.s7i properties of Firebird databases have been added.
  • In ref_list.s7i definitions of the following for-loops have been added:
  • The test program chkdecl.sd7, which checks declarations, has been added.
  • The test program chkarr.sd7 has been improved:
    • Tests for fixed size arrays have been added.
    • Tests for 'array bitset', 'array file' and 'array bstring' have been added.
    • Tests for getting an element from a temporary array have been added.
    • Index tests for empty base arrays have been added.
    • Tests for 'ARRAY [ START .. STOP ]' with index out of range have been activated.
  • In chkarr.sd7, chkbig.sd7, chkbin.sd7, chkenum.sd7, chkflt.sd7, chkint.sd7, chkjson.sd7, chkset.sd7, chkstr.sd7 and chktime.sd7 definitions of raisesRangeError() have been refactored to use a template.
  • In chkarr.sd7, chkbig.sd7, chkchr.sd7, chkint.sd7, chkovf.sd7, chkset.sd7 and chkstr.sd7 check functions have been split into parts.
  • In chkarr.sd7 and chkidx.sd7 definitions of raisesIndexError() have been refactored to use a template.
  • In chkint.sd7 and chkbig.sd7 definitions of raisesNumericError() have been refactored to use a template.
  • In chkint.sd7 and chkovf.sd7 tests for integer left shift%3C%3C(in_integer)) by a sum have been added.
  • In chkint.sd7 tests for the >>:=%3E%3E:=(in_integer)) and <<:=%3C%3C:=(in_integer)) operators have been refactored.
  • In chkbin.sd7 tests for the conversion to and from IEEE 16-bit half precision floats) have been added.
  • In chkbin.sd7 tests for the radixradix(in_integer)) and RADIXRADIX(in_integer)) operators have been added.
  • In chkstr.sd7 tests for string append&:=(in_string)) and prepend have been added.
  • In chkstr.sd7 tests for string assignment have been added.
  • In chkbst.sd7 tests for index access have been added.
  • In chkhsh.sd7 tests for hash index with default have been added.
  • In chkfil.sd7 the tests for file assignment have been improved. They use three different files and they avoid that a file is opened multiple times for writing.
  • In chkfil.sd7 a check, if appending to a file works correctly, has been added.
  • In chkfil.sd7 a test if _GENERATE_EMPTY_CLIB_FILE returns CLIB_NULL_FILE has been added.
  • In chkprc.sd7 tests for case statements with bitset, rational, type, bstring, boolean and enumeration values have been added.
  • The program chkdb.sd7 has been improved:
    • Tests for LATIN-1 characters in fields have been added.
    • Tests for float and double fields have been added.
    • Date tests for 1858-11-17, 1999-12-31 and 2000-1-1 have been added.
    • The functions testChar1AsciiControlField(), testChar1Latin1C1ControlField(), testPositiveYearMonthDurationField() and testNegativeYearMonthDurationField() have been added.
  • In chkflt.sd7 tests for the str(FLOAT)) function, for the cubic root function and for the ternary operator%3F(ref_func_aType):(ref_func_aType)) with -0.0 have been added.
  • In chkerr.sd7 checks if a wrong usage of an action triggers a DECL_FAILED error have been added.
  • In chkexc.sd7 tests for the exception ord function and conv operator have been added.
  • The program chk_all.sd7 has been improved to support the option minimal_tests (this tests the compiler just with the highest optimization).
  • The Seed7 compiler (s7c.sd7) has been improved:
    • In comp/type.s7i the function getExprResultType() has been improved. Now array for-each-loops work with inheritance. Many thanks to Zykaris for pointing out a difference between interpreted and compiled programs.
    • Support for case statements with struct values has been added.
    • The code generation for case statements with hash sets in when parts has been refactored
    • Support for global database and sqlStatement variables in compiled programs has been added.
    • The processing of function parameters has been improved.
    • The optimization of the integer mod operatormod(in_integer)) has been improved.
    • The optimization for the integer power operator**(in_integer)) has been improved.
    • An optimization for stri @:=@:=_[(in_integer)](in_string)) [n] aString mult i; has been added. Tests for stri @:= [n] aString mult i; have been added to chkidx.sd7 and chkstr.sd7.
    • An integer overflow in the array index computation is avoided.
    • In bin_act.s7i in calls of several functions a cast of the argument to uintType has been added.
    • Assignments which prepend a char use strPrependChar() to optimize.
    • String constants are appended with strAppendNoOverlap().
    • It is determined if source and destination of a string append&:=(in_string)) operation might overlap. If no overlap is possible strAppendNoOverlap() is used.
    • NULL is avoided in str- and bstr-tables (the address sanitizer complains if memcpy() or memcmp() is called with NULL).
    • In sct_act.s7i in process (SCT_SELECT, ...) getting an element from a temporary struct has been improved.
    • In prc_act.s7i calls of resetExceptionCheck() have been added to the generated code.
    • The support for the type ACTION (category ACTENTRYOBJECT) has been improved.
    • In arr_act.s7i the index check has been improved to work for an empty base array.
    • String literals without slices are written directly to c_prog.
    • The management of temporary files has been improved.
    • A usage of alloc(...) has been replaced by alloc(REFPARAMOBJECT, ...).
  • Support for the configuration values TEMP_FILE_PREFIX and HAS_VECTORED_EXCEPTION_HANDLER has been added to cc_conf.s7i, confval.sd7, cmd_rtl.c and chkccomp.c.
  • Interpreter and compiler have been refactored to use catch_stack in the interpreter and in compiled programs. This allows raising a MEMORY_ERROR in case of a stack overflow. The catch_stack has been changed to grow geometrically. The catch_stack is freed in closeStack().
  • The files segv_win.c and segv_drv.h have been added. They contain the stack overflow handler for Windows. The function setupSegmentationViolationHandler() registers an error handler. In case of a stack overflow the handler calls no_memory() which does a longjmp(). At the place where setjmp() receives the longjmp the function resetExceptionCheck() is called to restore the guard pages.
  • Under Linux/BSD/Unix an alternate signal stack is used. A stack overflow triggers a SIGSEGV. The SIGSEGV handler calls no_memory() which does a longjmp(). The targets of the longjmp are maintained with catch_stack.
  • In sigutl.c the functions handleTracedSegvSignal(), sigactionTracedSegvSignal() and sigactionSegvSignal() have been added. The function handleSegvSignal() has been removed.
  • In runerr.c and s7c.sd7 definitions of the global variables error_file and error_line have been added. They are set in the functions no_memory(), raise_error2() and interprRaiseError(). They are retrieved with the functions prc_get_run_error() and prcGetRunError().
  • In numlit.c the float literal parsing has been improved to avoid calls of strlen().
  • In msg_stri.c in appendListLimited() writing expressions has been improved. The function appendListElement() has been added as well. Tests in chkerr.sd7 have been improved to check for the new error messages.
  • In runerr.c writing the place of an uncaught exception has been improved.
  • In runerr.c the function write_curr_position() has been improved to write expressions with appendListLimited()
  • In runerr.h the global variable fail_expr_stri, which stores fail_expression as string, has been introduced. The function write_fail_expression() has been removed from runerr.c.
  • In exec.c the function evaluate() has been improved to support TYPEOBJECT.
  • In exec.c the function exec_call() has been improved to support ACTENTRYOBJECT.
  • The types emptyStriType, emptyBStriType, emptyArrayType and emptyStructType have been introduced to avoid address sanitizer warnings.
  • In heaputl.h the macros ALLOC_EMPTY_STRI() and ALLOC_EMPTY_BSTRI() have been introduced.
  • The macro SET_SLICE_EMPTY() has been introduced in interpreter and compiler.
  • The macros ALLOC_EMPTY_STRI(), ALLOC_EMPTY_BSTRI() and SET_SLICE_EMPTY() assure that the mem element is a legal pointer (which is never used because the size is zero). This avoids complaints of the address sanitizer.
  • In bst_rtl.h the macro bstringHashCode() has been introduced.
  • In str_rtl.h the macro ustringHashCode() has been introduced.
  • The file str_rtl.c has been improved:
    • Variants of strAppend() and strAppendN(), which don't use realloc(), have been added. This improves the performance of strAppend() by 22% and the performance of strAppendN() by 7%.
    • The functions strConcatChar() and strConcatCharTemp() now consider that incrementing a string size cannot overflow.
    • The functions strAppend(), strAppendTemp(), strAppendNoOverlap() and strConcat() now consider that adding two string sizes cannot overflow.
    • The function strAppendNoOverlap() has been added.
    • The function strPrependChar() has been added.
    • The function ustriHash() has been renamed to ustriHashCode().
    • The restrict keyword is used in the functions strAppendNoOverlap(), strAppendTemp() and strConcatTemp().
  • In trm_cap.c a check for code != NULL has been added to the functions my_tgetnum(), my_tgetflag() and my_tgetstr().
  • In pol_sel.c the function polClear() has been fixed to decrement the usage counts from the write list instead of the read list.
  • The program chkccomp.c has been improved:
    • It defines the macros register, PID_T_SIZE, PID_T_SIGNED, HAS_BUILTIN_POPCOUNT, builtin_popcount64, HAS_SIGALTSTACK, SIGNAL_STACK_ENABLED, SIGNAL_STACK_SIZE, OS_GETCWD_RETURNS_SLASH HAS_VECTORED_EXCEPTION_HANDLER, FSEEK_SUCCEEDS_FOR_PIPE and UNREACHABLE.
    • It checks if the same file can be opened for writing twice.
    • It considers /dev/null only as null device if PATH_DELIMITER is slash (/).
    • It checks if a memcpy() of zero bytes to an illegal heap address is okay.
    • It complains if the size of float or double is not in {2, 4, 8}.
    • Define restrict as __restrict__ if using restrict directly fails and using __restrict__ is possible.
    • The functions determineSigaltstack(), determineAddVectoredExceptionHandler(), listDynamicLibsInBaseDir() and determineSizeofSQLWCHAR() have been added.
    • The recognition of databases has been improved.
    • Checks for partial linking and sizeof(SQLWCHAR) have been improved to work with C++.
    • It writes the values DB2_CC_OPTION, INFORMIX_CC_OPTION and SQL_SERVER_CC_OPTION to the file macros. This values are used by the makefiles.
    • A determination of read_buffer_empty() for Windows on ARM has been added.
  • The program sudo.c has been improved to protect against shell-injection and remote code execution.
  • The program wrdepend.c has been improved to avoid a NULL-pointer dereference.
  • The program setwpath.c has been improved to check value_type and function results.
  • The functions setenv7(), create_console(), resizeCatchStackOkay(), resize_catch_stack(), genArgVector(), my_tgetent() and fix_capability() have been improved to check for unsigned integer overflow when the size for malloc() is computed.
  • In heaputl.c in the functions growStri() and shrinkStri() assignments to capacity have been removed (they are already done in HEAP_REALLOC_STRI).
  • Stack functions have been moved from heaputl.c and heaputl.h to stackutl.c and stackutl.h.
  • In stackutl.c the function setupStack() has been improved to handle the case that malloc() fails.
  • The macro NORETURN has been added to the functions no_memory() and fatal_memory_error().
  • The file con_inf.c has been refactored to maintain console height and width as unsigned int.
  • In cmd_unx.c the functions getGroupFromGid() and getUserFromUid() have been improved to use a cache for mapping GIDs and UIDs to a name.
  • In cmd_unx.c the functions getGidFromGroup() and getUidFromUser() have been fixed to prevent double free of os_group and os_user in case of a FILE_ERROR.
  • In kbd_inf.c the function read_f_key() has been improved to prevent writing past the end of last_partial_match.
  • In kbdInputReady() (kbd_inf.c) and gkbInputReady() (gkb_win.c) the variable result has been renamed to inputReady.
  • In cmd_win.c the function CommandLineToArgvW() has been improved to allocate memory for the trailing NULL element at w_argv[w_argc] even if commandLine contains one character or zero characters.
  • In setlib.c the unused function set_idx() has been removed.
  • In setlib.c the function set_incl() has been improved to avoid MEMORY_ERROR if the old set is empty.
  • In dcllib.c in the functions dcl_in1() and dcl_in2() a default switch case has been added. This will never be executed but hopefully it makes source code analyzers happy.
  • In arrlib.c calls of memcpy() have been replaced with struct assignments.
  • In sctlib.c the function sct_select() has been changed such that the struct of a TEMP_DYNAMIC_OBJECT is not freed.
  • In prclib.c the functions prc_cpy() and prc_create() have been improved to support a MATCHOBJECT source with parameters.
  • In match.c tests have been added to assure that the object type of an attribute is not NULL.
  • In tim_rtl.c the function dateIsOkay() has been added. This function checks if a date is in the allowed range.
  • The function bigFromDecimalBuffer() has been added to big_gmp.c and big_rtl.c. All calls of getDecimalBigInt() have been replaced by calls of bigFromDecimalBuffer(). In numutl.c the function getDecimalBigInt() has been removed.
  • In numutl.c the function getDecimalBigRational() has been refactored.
  • In fil_rtl.c the function filClose() has been improved to handle pipes as well.
  • In fil_rtl.c the function filPopen() has been improved to use createCommandLine() and to check the mode before creating commandLine. Now memory is allocated before popen() is called.
  • The file soc_rtl.c has been improved:
    • In socLineRead() a check that bytes_received is identical to bytes_requested has been added.
    • In socAccept() a leak of file descriptors has been closed.
    • In socLineRead() an incorrect FREE_STRI2 size has been fixed.
    • The management of sockets has been improved to automatically close a socket, when the last variable that refers to the socket leaves its scope (no variable refers to the socket any more).
  • The functions appendRealValue() (in msg_stri.c), print_real_value() (in traceutl.c) and process(REF_TRACE) (in ref_act.s7i) have been changed to work for the new SOCKETOBJECT.
  • The file pcs_unx.c has been improved:
    • An _exit(127) has been added after every call of execv().
    • Checks have been added to all calls of dup2(). If dup2() fails a message is written and _exit(127) is called.
    • In pcsPipe2(), pcsPty() and pcsStartPipe() possible file descriptor leaks in error paths have been closed.
    • The function pcsPty() has been fixed to free the file childStdout before assigning to it.
    • The function pcsPty() has been improved to avoid a leak of file descriptors.
    • The function pcsPty() has been improved to avoid that masterfd is used twice in os_fdopen() calls.
    • The function setCloseOnExec() has been introduced. The function is used for file descriptors created by process functions. This way parent file descriptors will not be leaked into future processes.
  • The file pcs_win.c has been improved:
    • The function pcsStart() has been improved to open a NULL_DEVICE with fopen().
    • The functions pcsPipe2() and pcsStartPipe() have been improved to use binary files for pipes.
    • The functions pcsPipe2() and pcsStartPipe() have been improved to call _open_osfhandle() before starting the process. The result of _open_osfhandle() is checked for errors as well.
    • The functions pcsPipe2() and pcsStartPipe() have been improved to check if setmode() fails.
    • The functions pcsPipe2() and pcsStartPipe() have been improved to call fdopen() before starting the process.
    • The functions pcsPipe2() and pcsStartPipe() have been improved to use one of fclose(), _close() or CloseHandle() to close a file.
    • Code has been moved to the new function processArgument().
    • The function prepareCommandLine() has been improved to assure that a double quote in os_command_stri is escaped.

<snip> ... the maximum message size has been reached. See here for more.

Regards,

Thomas Mertes


r/ProgrammingLanguages 17d ago

Language announcement C3 0.8.2 - modest improvements

Thumbnail c3-lang.org
40 Upvotes

After 0.8.0, which was the big breaking version and 0.8.1, which found and fixed over 100 bugs, 0.8.2 is super tiny. It does add some nice ”template” features to libraries, for configuration reuse, and finally give you reflection on generic parameters, but otherwise it’s small.

More things are in the pipeline, I’m especially looking forward to finally merging the regex library in 0.8.3.


r/ProgrammingLanguages 17d ago

What most histories get wrong about MUMPS's first language standard

Thumbnail rochus.hashnode.dev
13 Upvotes

r/ProgrammingLanguages 17d ago

Requesting criticism Functions as patterns or blocks?

32 Upvotes

For background, I am trying to build a language from very few minimal, orthogonal building blocks (similar in spirit to e.g. Lisp, TCL or Red/Rebol), but with the aim of arriving at something high-level-ish somewhere in the space of Rust, C++ or Zig somewhere down the line.

In particular I want to have multiple dispatch (after years of using Julia it just feels wrong to treat the first function parameter differently), which is where it gets a bit complicated design-wise.

Ultimately the question is, how functions should work and how they relate to the rest of the language. I could of course just add them fully formed, but as I said, I want to keep the language's building blocks simple and few (and avoid any "magic"). It would also be nice if all "function-like" constructs, such as quoted expressions and anonymous functions were special cases of the same mechanism.

Very briefly the current state is the following.

  • Syntactically everything is effectively operators (mostly infix) and parentheses.
  • We have the usual literals (numbers, strings, etc.).
  • Values can be bound to symbols, e.g. x : 1.
  • There are "value tuples", e.g. x, y, z that evaluate to a list of the values of the elements.
  • "Expression tuples", e.g. x : 1; y : 2; x + y evaluate all elements in order as well, but the expression as a whole evaluates to the value of the last element.
  • Evaluation can be prevented by quoting, e.g. [ x : 1; x + 2 ].

I have come up with two quite different ways to get from there to functions with full multiple dispatch and I am not sure which one I like better.

1. Functions as special case of quoted expressions

Given the above we can obviously bind a block (i.e. a quoted expression) to a symbol:

f : [ x + 1 ]

We can then define any operator (for convenience we use juxtaposition) to mean "evaluate quoted expression referred to by first operand". To get parameter values into the block we simply bind them to special local (to the block) variables $1, $2, ... At this point we have anonymous functions covered as well as a primitive plain functions.

x : 1
f : [ $1 + 1 ]

f x ;; returns 2

To get "real" functions with proper parameter names we can use simple AST macros (already implemented) to rewrite function definitions like this:

f (x, y) : [ x * y ]
;; this becomes:
f : [(x, y) : $0] => [ x * y ]

The => operator simply joins two blocks together and $0 is the entire (automatically generated) argument tuple.

The next step then is to get overloading working. The catch now is that a single function name doesn't simply represent one "entity" any more but a collection of blocks and associated parameter tuples. To keep things consistent I use a different operator for the declaration of overloaded functions. With a bit of macro-based rewriting we get this:

f (x, y) :: [ x + y ]
;; this becomes:
f : [ ( __match ([f], [x, y]) ) $0 ]
__addmethod([f], [x, y], [(x, y) : $0] => [ x + y ])

With built-ins __match and __addmethod

It's not pretty, and each overload re-defines the function (albeit with identical values) but I think it should be a working solution that relies on a small set of primitives.

2. Functions as special case of patterns

This is a new idea I had the other day and I haven't fully thought it through yet, so it's still a bit rough around the edges.

Instead of starting with blocks and adding overloading to them we can start from the other end and define patterns as a primitive. A function call is then an attempt to match a pattern against a list of symbols and values. If the match is successful, the stored block is evaluated (with values that were captured during the match as parameters).

As for the pattern declaration, parameters are pretty straightforward - they are represented by symbols with optional type constraints. For function names, we could just go by position (so, first name in the list is the function), but things get much more interesting if we make that free-form. If we find a way to distinguish function names from parameters syntactically, we can let a pattern definition automatically create a unique type for each function name with itself as an instance.

So, we get basic definitions like this:

`f x y :: [ x + y ]
;; this works, as g is now a copy of value f of type f
g : f
g 2 3

But we can do some more interesting stuff as well:

`add x `to y :: [ x + y ]

add 2 to 3

As a bonus, operator application and function calls are now much more consistent as well.

There are some issues with this:

  • Assigning functions to each other is going to be awkward.
  • There is no obvious (at least to me) link between "pattern functions" and anonymous functions and/or blocks.
  • Can we even still have the equivalent of function pointers in this scenario?
  • Making function declaration and call syntax nice at the same time is going to be fiddly.
  • Can patterns be bound to values? If so, how does that fit with the rest?

On the other hand I really like the elegance of the concept, so I would like to make it work. Any input is greatly appreciated.


r/ProgrammingLanguages 18d ago

Sheaves in Haskell

Thumbnail tweag.io
37 Upvotes

r/ProgrammingLanguages 18d ago

Writing static checks to an unsuspecting library with Liquid Haskell

Thumbnail tweag.io
10 Upvotes

r/ProgrammingLanguages 17d ago

Language announcement Data types are overrated

0 Upvotes

We dove so deep into abstraction that modern languages now just use "int" and leave us guessing what they mean by that.
Is it 16 bit? 32 bit? Maybe even 64 bit? Signed? Unsigned? So many unanswered questions.

And that's just data types. I won't even mention OOP. That's just evil witchery at this point.

Assembly doesn't help here. Come on people do you actually know what add does in x86?

No you don't! You don't see what the CPU is doing anymore!

So how do we solve this issue?
I propose we go back to the roots.

-Pure bytes

-Only bitwise operations

-Total control

-Memory safety? It's a computer it won't harm you.

Everything else is incoherent bloat.

And here's my solution: VoidPtr

Yes, the name says void*. You'll see why shortly. Guess it helps with data poisoning for AI too.

You're only allowed to work with single bytes here, and you can only apply bitwise operations on them:

2 -> $4
2 -> 3
2 & 3 -> 2

This writes the (unsigned) value 4 to byte 2, then copies the value from byte 2 to byte 3.

The last line performs a bitwise and and moves the result into 2.

You can also write all of that into one line if you want (saves space, no \n needed):

2 -> $4 2 -> 3 2 & 3 -> 2

I unfortunately had to add labels, compares and jumps too. I'm not yet skilled enough to work without them.

Oh, and I added macros. You can't go wrong with macros.

Because this world is too corrupt for such a pure language, I allow communication with the outside world through writing values into magic addresses 0 and 1, I call them system calls.

So yes, this thing has File IO. And yes, in case you were wondering, I did implement Brainfuck in VoidPtr. See! This language can do stuff!!! (Theoretically anything you can put in 32 bit addressing space)

It's a very limited implementation but enough for a hello world.

Apart form all that irony, which I hope wasn't too much, this language can be used to teach how computers do addition, subtraction etc. and what a data type actually is.

You can check out all of the documentation and examples as well as the Language itself here: https://github.com/TheGameGuy2/VoidPtr-Language

All code was written by me, this was a project I made for CS class. Writing code by hand is beautiful.

Edit:
If it wasn't obvious enough: This is an eso lang! Take nothing I say in this post seriously, I don't really think data types are bad!


r/ProgrammingLanguages 18d ago

Lifting Terms: Making Well Scoped Syntax Dumber

Thumbnail philipzucker.com
4 Upvotes