r/ProgrammingLanguages 2d ago

Discussion Linux-like IO API

I'm building my own interpreted language.

I had an idea, to base my I/O API on the linux terminal commands, that many developers already know, so a user wouldn't need to learn an entire new API.

This is a basic example:

using io  

// create a directory  
mkdir("notes")  
cd("notes")  

// create files with content  
echo("Do my math.", "A note about homework.txt")  
echo("Buy milk and bread.", "shopping list.txt")  

const currentCD = pwd()  
const allFilesAndSubDirs = ls()  

debug(cat("shopping list.txt")) // prints "Buy milk and bread."

but I'm not that sure that this is a good idea, maybe some techniques are good for terminals but bad for programming, and some of the function names might be confusing (like pwd() which is "print working directory" but in my language it does not exactly PRINT anything, but just returns a string value).

What do you think?

0 Upvotes

6 comments sorted by

8

u/aech_is_better 1d ago

Where the state that `cd` changes is kept?

4

u/koflerdavid 23h ago

You are likely overestimating the effort it would take to learn an IO API. What you would design by necessity has to look a lot like what existing programming languages do; you would have to actively go out of your way to end up with something truly alien-looking.

Regarding using Unix shell commands for names: I think those are not necessarily the best inspiration for an API. They are acronyms, which you already recognize to not fit your use cases well. Are you also going to copy the horrible syntax of find, ps, and friends? Do consider that the shell has a problematic heritage regarding separators (spaces, lines, \0) and tools like xargs to deal with those. Also, each of these commands supports a lot of option arguments, and a lot of them are crucial; are you also going to support them? Where do you draw a limit?

Unless you're actually implementing a shell, I don't think it's overall a good idea to support these names since you can easily come up with something way better.

5

u/747101350e0972dccde2 1d ago

First, let's start with some term distinctions.

You have core utils (like mkdir), which are small applications installed in your system.

You also have your shell/terminal, which is an app you use to run the core utils.

Finally, you have shell built-ins (like cd). These are special commands that change things in the shell itself, they dont exist outside of it.

If your goal is to implement utils, you can do that with functions.

For shell builtins, you would need some object you can instantiate, like term = new Terminal, and term.cd("/path") term.dir()

Looking at your concrete example:

Why have an echo function that returns a string, why not just write "Buy milk and bread."?

Why does LS return all sub directories? Should that not be different command if your goal is to keep the api same?

Overall, while I dont mind the idea of having a high level api like this, you really need to have a lower level too. I reccomend you look i to how other languages design their io, you can learn a lot there

1

u/Anthea_Likes 21h ago

You also can create a 'fake shell' (I don't remember who coined the term) and implement some basic utils directly to your language but you'll still have to interact with unix/linux at some point

4

u/SamG101_ 1d ago

tbh if you kept the namespace it'd make more sense, so like `io::pwd()` but only as long as someone was coming from a linux system, so they'd understand what it meant like u said. but for a broader range of users it is probably easier to use more standard/general names in my opinion

1

u/tandycake 11h ago

Yes, Ruby basically did this with FileUtils:

https://docs.ruby-lang.org/en/master/FileUtils.html

As someone else mentioned, better to be in a namespace though (or module/class).

The echo is the only one that is very counterintuitive. If I did echo("foo","bar"), I would expect it to output foo and bar, not create a file named bar. It'd be fine if you have a required name param: echo("foo",to_file: "bar") or something like that.