Andy Balaam from Andy Balaam's Blog
Series: Examples, Questions
My last post Examples of Pepper3 code was a reply to my friend’s email asking what it was all about. They replied with some questions, and I thought the questions and answers might shed some more light:
Brilliant ones, thanks.
In general though you’ve said a lot about what Pepper can do without giving design decisions.
Yep, total brain dump.
Remind me again who this language is for :)
It’s a multi-paradigm (generic, functional, OO) language aimed at application programmers who want:
- “native” performance on their chosen platform (definitely including actual native machine code). This is inspired by C++.
- easy deployment (preferably a single binary containing everything, with an option to link most dependencies statically), including packaging of installers for major OSes. This is inspired by C++, and the pain of C++.
- perfect flexibility for creating types – “meta-programming” is just programming. Things you would have done using code generation (e.g. generating a class hierarchy from an XSD) are done by running arbitrary code at compile time. The powerful type system is inspired by Haskell and the book “Modern C++ Design”, and the meta-programming is inspired by Lisp.
- Simple memory management without GC through ownership. This is inspired by modern C++, and then Rust came along and implemented it before I could, thus proving it works. However, I would remove a lot of the functionality in Rust (lifetimes) to make it much simpler.
- Strong support for functional programming if you want it. This is inspired by Haskell.
- The simplest possible core language, with application programmers able to expand it by giving them the same tools as the language designers – e.g. “for” is just a function, so you can make your own. I am hoping I can even make “class” a function. This is inspired by Lisp, and oppositely-inspired by Java.
- Separation between the idea of Interfaces, which I think I will call “type specifiers” (and will allow arbitrary code execution to determine whether a type satisfies the requirements) and structs/classes, allowing us to make new Interfaces and have old code satisfy them, meaning we can do generic stuff with e.g. ints even if
no-one declared that “class Int : public Quaternion” or whatever.
- Lots of “nudges” towards things that are good: by default things will be functional and immutable – you will have to explicitly say if you want to use more dangerous constructs like side effects and mutable values.
- No implicit conversions, or really anything happening without you saying so.
Can you assign floats to ints or vice versa?
Yes, but you shouldn’t.
If you’re setting types in code at the start of a file, is this only available in the main file? Are there multiple files per program? Can
you have libraries? If so, do these decide the functionality of their types in the library or does this only happen in the main file?
I haven’t totally decided – either by being enforced, or as a matter of style, you will generally do this once at the beginning of the program (and choose on the compiler command line to do it e.g. the debug way or the release way) and it will affect all of your code.
Libraries will be packaged as Pepper3 source code, so choices you make of the type of Int etc. will be reflected through the whole dependency tree. Cool, huh?
This is inspired by Python.
Can you group variables together into structs or similar?
Yes – it will be especially easy to make “value types”, and lots of default methods will be provided, that you will be strongly encouraged to use – e.g. copy and move operations. This is inspired by Elm.
Why are variables immutable by default but mutable with a special syntax? It’s the opposite of C++ const, but why that way around?
This is one of the “nudges” – immutable stuff is much easier to think about, and makes parallel stuff easier, and allows optimisations and so on, so turning it on by default means you have to choose to take the bad path, and are inclined to take the virtuous one. This is inspired by Haskell and Rust.
Why only allow assignments, function calls and operators? I’m sure you have good reasons.
To be as simple as possible, so you only have those things to learn and the rest can be understood by just reading the code. This is inspired by Python.
I wrote more of my (earlier) thoughts in this 4-post series, which is better thought through: Goodness in Programming Languages