To be honest, I was fatigued the moment it looked like just another programming language. After seeing there is absolutely no documentation, I don't even understand why anyone would upvote this.
Documentation encourages hacking, not the other way around. People are usually substituting previously-learned docs when there isn’t any.
Especially for a language, though, understanding the intended use and the direction the language is growing helps prevent undocumented or unintended usage, and early obsolescence.
Oh come on, people can't show off their projects anymore until they're perfect? This habit of immediately searching for the flaws of whatever gets posted is not helping anyone. If you want polished well presented shit, go to techcrunch or something.
Of course, but this project is like a car maker inviting the press to present a new model and showing a couple different windshields ("we aren't sure about the angle") and not even a picture. There are standards: a car needs complete prototypes, and a programming language needs something that it does better than the competition and a decent explanation of how cool it is.
Every user will prefer Turing completeness (first order functons with no control structures aren't enough) to hot reloading.
>Message content is ended with \0 byte, followed by a digit between 0-10 describing font colour.
What hacker does is pass `\0\0` to check if null byte is valid digit or painfully crashes system an if invalid values are handled correctly when error handling mechanisms aren't described in documentation. I think what you mean by hacking is closer to RE.
Nearly any first post comment will get upvotes, if the sentiment of a first post comment is negative, it steers the whole discussion in being over critical. First post and top comments provide a positive feedback loop that is often too hard to overcome.
I don't know what the answer is, but I think internet points make things worse in general. I'd love to see a forum with sentiment analysis built in and automoderators that dynamically reorder or weight posts so as to not encourage gaming the system.
Maybe upvotes on critical comments should count for less?
There's not that much work done to be able to comment something about this language; maybe it would be interesting after about a year or two.
It is entirely possible to create a statically-typed language with C-like performance and scripting-language-like interactivity (the most similar is Julia, which also uses LLVM under the hood), but the details would be pretty complex enough to make this quite a big project.
Still, it's good to see there are languages other than Jai trying to compete in the rather niche gamedev programming space.
Depends on the language but in Haskell, the (->) arrow is a function type constructor (i.e. constructs function at type level) where a -> b constructs a function type from a to b.
This is often chained to produce functions that 'take multiple arguments'. i.e. a -> b -> b. I put that in quotations because in reality all functions take only one argument, this is called currying. It gives functions flexibility in that you can partially apply them at will.
In languages like Rust and Swift, the syntax is (a: A, b: B) -> B. Because these languages are "uncurried", they use the syntax of uncurried functions. Meaning, they cannot be readily partially applied.
The thing about adopting the ASCII Art pseudo arrow is that it bakes in an assumption that the dash character lines up vertically with the point on the angle bracket character. This simply isn't the case in plenty of fonts. So it often looks like crap if you pay attention.
Which fonts does it not look good in? Haskell, Rust, Swift, Ocaml, and I'm sure some others, all use this notation. And I've never seen the '->' look odd in any font I've ever used.
I just went to the Rust homepage and clicked until I found an example of a function. It's being presented in Monaco where the dash is noticeably higher than the centre of the angle bracket.
I don't think it makes sense to say `fn read(s: string) -> int` as in Rust though. If an arrow were used in such a function declaration, it should probably look something more like:
fn read: (s: string) -> int
As another commenter has indicated, `fn read(s: string): int` states that `read(s)` is of type `int`, which is logical.
Having -> denote a return variable has the benefit that you the syntax "a -> b" is non-ambiguously a function type.
For example, a function that accepts a function as an argument can be written:
fn foo(f: int -> string)
Or if the argument name isn't needed in this context (e.g. think interface declarations):
fn foo(int -> string)
If you see ":" as meaning "has type", then using it for a return type isn't necessarily more consistent, because it's not the function that has a type.
It's not inconsistent, just terser. You could say that "fn" declares a function by name; the type of foo is int -> str.
In Haskell, this is written:
foo :: int -> str
Of course, Haskell is based on lambda calculus, so multiple arguments are just a generalization of partial function application:
foo :: int -> int -> str
(A function taking two int arguments and returning a string, which is indistinguishable from a function that takes a single int and returns a function that takes a single int and returns a string.)
In functional programming (the origin of this syntax),
add(a: int, b: int): int
can be read as a function 'add' when applied to the parameter tuple (a: int, b: int) has type int, I believe Ocaml, SML, actually support this syntax, whereas '->' (arrow) is a function type constructor in functional programming with 'A -> B' denoting a function from A to B. The type of add by itself in a language like Haskell would be:
You can certaintly have tupled function arguments in SML/Ocaml, in fact that seems to have been the more common style there, whereas Haskell uses curried functions more commonly.
As far as the original sugestion, using '->' (arrow) to denote a return type (like Rust) is nonsense in a functional language and kind of butchering the functional inherited syntax IMHO.
I've never heard of OCaml tuples being more common in arguments. If anything, my impression is they're discouraged (in OCaml, not SML) as a replacement for curried arguments. E.g. see [1].
> is nonsense in a functional language
SML/OCaml and Haskell all use ->, so I'm not sure what you mean by this?
It is quite common in SML/ML code I've encountered, probably not as common in modern OCaml. BTW, in OCaml
let add ((a:int), (b:int)) : int = a + b
Works just fine, whereas:
let add ((a:int), (b:int)) -> int = a + b
is nonsense, because '->' is a type constructer in OCaml (a function from types to types) not part of an ad-hoc syntax for function declarations (like Rust).
Right, I'm not sure with OCaml is inconsistent there. -> is also used in pattern matching and in the syntax "fun x -> x + 1", perhaps it's some historical thing to avoid ambiguity?
The above usage of -> is a syntax error in OCaml, -> can be used in the left hand side of a let expression, but only as part of a type expression. As you say the other usage is used to construct terms (clauses) that are used in pattern matching, of course Haskell does something similar.
The Rust syntax seems to emulate functional programming, but inconsistently since -> is not used purely as a type constructor or term constructor something like a mix of both in the defintion of functions, also it doesn't seem to support currying.
It looks like the intent of this language is something that can replace Lua as an embedded language in games and other applications that require scripting, without the overhead of requiring JIT compilation to be performant (which you can't have on iOS). The JVM is a bad candidate for that. I believe Dart uses JIT as well.
After reading the web site, I looked at the sources (e.g. mun/crates/mun_syntax/tests/data/parser/ok/) because my disbelief was unusually stretched, and it seems that the examples and explanations in the almost nonexistent documentation cover fairly well the almost nonexistent features.
Why publish a project that, while already showing technical proficiency (the Twitter timeline suggests only 2-3 months of work), is still a very long way to do something useful, let alone compete with other programming languages? The fashionable web site layout adds insult to injury instead of looking good.
I've been working on a game project over the past year. Everyone I had shown videos to was supportive. I felt like I got a lot done in a short few months. But no one other than myself had gotten their hands on the game proper.
I had planned on doing a single point of release when it was finished. I'd done that with a game release before however. After months of work release day came, the game flopped, and by a week later it was more or less lost to the void. Not wanting the same to happen on this project I changed my mind and released it as it was one random weekend.
It had very little documentation, and even worse known bugs and crashes. But a couple people downloaded it and one guy liked the concept enough to kick me $5. By the next week I had some more info on what those people liked and what they could live without. I had motivation to fix some bugs that I had learned to work around in my using of the game. My development rate on the game has gone up significantly since releasing it in an unfinished state, and the community is very small but two months later the game hasn't dropped into the internet void.
I can sympathize with the mindset of "I've been working on this in a vacuum and just want someone else to see it, warts (or lack of content) and all". In my case it's worked out for the benefit of the project as well.
Why not publish? What's the problem with developing in public? I think it's just welcoming for potential contributors, if anything.
Compare with a language like Jonathan Blow's "Jai", which is developed in private with update videos published every now and then. Sure, that's one way to do things, but personally I much prefer being able to follow the progress of a project more on my own terms, with the source in my hands.
One of the creators here. I appreciate the upvotes but its way too soon for that. Mun is currently in the very very early stages of development. It originated out of frustrations with Lua game development at Abbey Games. Lua is a great language but lacks performance, refactoring functionality and doesn't scale well with modern technology. However, there is no real alternative when it comes to code iteration times.
I do understand some of the comments questioning the publication of a website for a programming language that isn't even finished. Our goal was to have a platform to share progress and gauge interest on the topic to further help us develop Mun. We feel like there is no point in developing a programming language in private. Instead we want to actively engage with the community while developing Mun.
The website does state that its still in very early development. Should we emphasize this more?
LuaJIT performance on PC is very fast when its using the JIT. However, on consoles and some mobile platforms JITing is not allowed due to not being allowed to write to executable memory for security reasons.
Mun compiles to machine code with LLVM so it should be very fast as well, hotloading overhead can be completely removed in builds where hotloading is not required (production builds for instance). Mun should therefor be able to run as fast as native code on all platforms.
LuaJIT is not available on every platform. Love2D for example is pretty slow on iOS, especially at computing paths etc for custom draw calls.
Defold is slightly different, still allowing Lua scripting, but not more than that, which is the appropriate place for Lua in a mobile-dominated market.
Can I suggest that what you wrote here is actually a much better opening motivation than what’s on your site?
1) We like this thing that fits into the following use case
2) But we feel it has the following limitations
3) Which we’re planning to address like this.
I think it’s really important to establish what ecosystem slot you’re aiming at. If it makes it to others, fine.
> We take inspiration from a scala of application, scripting, and systems programming languages
The word "scala" reads really oddly in that sentence; none of the English-language meanings of the word [1] fits, and to a technical reader it's just asking for confusion with the Scala language. Maybe replace with a clearer and less formal "bunch"?
The syntax shown looks very Rusty, and I believe this started as a thought experiment for Rust. Do you see value in keeping that link explicit? That is, using Mun as a prototyping language for early iteration, then "freezing" it to vanilla Rust with minimal syntax changes once happy with the result?
Also, if the goal here is fast iteration, it'd be interesting to see some ballpark figures for compilation times, which is one of Rust's major Achilles heels today.
From the goals and bits of code, this looks a lot like Zig. What about Mun makes it distinct from Zig and the other little imperative LLVM languages that have been coming out recently (Zig, V, and a couple others come to mind)?
Mun is primarily focused on hotloading, the ability to change your code while its running. Our goal is to enable hotloading of all constructs including structs (similar to how Lua works) and without having to annotate anything.
So, why do we need yet another language to reap hot-reloading, instead of adding it to say Rust, Zig or (blow me) Jai? Is there something about those languages that complicates hot-reloading?
Jai is actually closed source, so that was not an option.
But in general there are no predefined best practices for achieving hot reloading of both functions and data. Experimenting with those while also fighting with complex compilers makes the problem space exponentially more intractable.
This is written in Rust, and the reloading mechanism looks like it aims to hot reload Rust libraries. So this could be used as a development workbench to glue together Rust libraries, think Python gluing a bunch of C++ libs together.
Language wise, it looks like it is in the Swift/Julia/Haxe space but with first class support for Rust. This looks interesting, I wish them luck and would love to use this in the future.
Off topic but it would be cool to have function types use just > for brevity, such as “add: int>int>int” and have equality operators use two characters, such as << >> >= <= ==.
The syntax of code snippet looks like go and typescript, they don't support hot reload thought.
Why do you choose to create a new language, instead adding features you miss into existing language ?
I just started learning and using Nim[0] (which recently hit release 1.0), this language appears to be very similar - statically typed, can use llvm, cross-compile, similar looking syntax. I'll be keeping an eye on this language as it looks like it will pair well with Rust. Looking forward to seeing some documentation. Keep up the good work!
Standard "new programming language" question(s): What's the memory management aspect like? Is there garbage collection?
LLVM has some support for garbage collection, but I've never heard of any language implementors actually being happy with what it offered in terms of features, correctness, and performance. (Counterexamples would be welcome.)
To me the most ideal form of hot-reloading and runtime compilation is probably the approach found in Scopes. While it leverages the LLVM MCJIT, it takes the approach of having compilation done when the programmer specifically wants it to be done, making it less of a "JIT" and more of a "runtime AOT"
82 comments
[ 2.6 ms ] story [ 145 ms ] threadEdit: seems like some basic syntax docs could be generated from their source, actually. https://github.com/mun-lang/mun/tree/master/crates/mun_synta...
Every user will prefer Turing completeness (first order functons with no control structures aren't enough) to hot reloading.
>Message content is ended with \0 byte, followed by a digit between 0-10 describing font colour.
What hacker does is pass `\0\0` to check if null byte is valid digit or painfully crashes system an if invalid values are handled correctly when error handling mechanisms aren't described in documentation. I think what you mean by hacking is closer to RE.
https://news.ycombinator.com/newsguidelines.html
I don't know what the answer is, but I think internet points make things worse in general. I'd love to see a forum with sentiment analysis built in and automoderators that dynamically reorder or weight posts so as to not encourage gaming the system.
Maybe upvotes on critical comments should count for less?
You're right that the problem is much worse when it's a first post. Threads are so sensitive to initial conditions.
It is entirely possible to create a statically-typed language with C-like performance and scripting-language-like interactivity (the most similar is Julia, which also uses LLVM under the hood), but the details would be pretty complex enough to make this quite a big project.
Still, it's good to see there are languages other than Jai trying to compete in the rather niche gamedev programming space.
fn name(a: int, b: int) -> void {}
This also helps with clean functional type arguments.
swift and rust support this.
A single consistent notation will be helpful for new polyglots.
This is often chained to produce functions that 'take multiple arguments'. i.e. a -> b -> b. I put that in quotations because in reality all functions take only one argument, this is called currying. It gives functions flexibility in that you can partially apply them at will.
In languages like Rust and Swift, the syntax is (a: A, b: B) -> B. Because these languages are "uncurried", they use the syntax of uncurried functions. Meaning, they cannot be readily partially applied.
Funny; I'm reading this in a HN android app; I don't know which font it uses but I swear I'm staring at such a misaligned example.
A function of type `Int -> String` allows you to get a `String` from an `Int`.
The proposition `A -> B` (`A` implies `B`) means that `A` being true allows `B` to be true; we can deduce `B` from `A`.
For the link between functions and implication, see: https://en.wikipedia.org/wiki/Curry%E2%80%93Howard_correspon...
I don't think it makes sense to say `fn read(s: string) -> int` as in Rust though. If an arrow were used in such a function declaration, it should probably look something more like:
As another commenter has indicated, `fn read(s: string): int` states that `read(s)` is of type `int`, which is logical.void name(int a, int b) {}
C, C++, Java, and C# support this.
A single consistent notation will be helpful for new polyglots.
This way it would be consistent with how variable types are declared.
For example, a function that accepts a function as an argument can be written:
Or if the argument name isn't needed in this context (e.g. think interface declarations): If you see ":" as meaning "has type", then using it for a return type isn't necessarily more consistent, because it's not the function that has a type.In Haskell, this is written:
Of course, Haskell is based on lambda calculus, so multiple arguments are just a generalization of partial function application: (A function taking two int arguments and returning a string, which is indistinguishable from a function that takes a single int and returns a function that takes a single int and returns a string.)The Haskell language looks interesting. Maybe I should spend some time to study it.
add :: (int, int) -> int
These languages "emulate" multiple arguments through partial function application. OCaml does not use tuples for arguments.
As far as the original sugestion, using '->' (arrow) to denote a return type (like Rust) is nonsense in a functional language and kind of butchering the functional inherited syntax IMHO.
> is nonsense in a functional language
SML/OCaml and Haskell all use ->, so I'm not sure what you mean by this?
[1] https://stackoverflow.com/questions/10666913/why-prefer-curr...
The Rust syntax seems to emulate functional programming, but inconsistently since -> is not used purely as a type constructor or term constructor something like a mix of both in the defintion of functions, also it doesn't seem to support currying.
Why publish a project that, while already showing technical proficiency (the Twitter timeline suggests only 2-3 months of work), is still a very long way to do something useful, let alone compete with other programming languages? The fashionable web site layout adds insult to injury instead of looking good.
I had planned on doing a single point of release when it was finished. I'd done that with a game release before however. After months of work release day came, the game flopped, and by a week later it was more or less lost to the void. Not wanting the same to happen on this project I changed my mind and released it as it was one random weekend.
It had very little documentation, and even worse known bugs and crashes. But a couple people downloaded it and one guy liked the concept enough to kick me $5. By the next week I had some more info on what those people liked and what they could live without. I had motivation to fix some bugs that I had learned to work around in my using of the game. My development rate on the game has gone up significantly since releasing it in an unfinished state, and the community is very small but two months later the game hasn't dropped into the internet void.
I can sympathize with the mindset of "I've been working on this in a vacuum and just want someone else to see it, warts (or lack of content) and all". In my case it's worked out for the benefit of the project as well.
Compare with a language like Jonathan Blow's "Jai", which is developed in private with update videos published every now and then. Sure, that's one way to do things, but personally I much prefer being able to follow the progress of a project more on my own terms, with the source in my hands.
1. Mun exists because of frustrations with Lua.
2. Lua means "moon" in Portuguese.
3. The "moon" in KSP is named: Mun.
Voila
I do understand some of the comments questioning the publication of a website for a programming language that isn't even finished. Our goal was to have a platform to share progress and gauge interest on the topic to further help us develop Mun. We feel like there is no point in developing a programming language in private. Instead we want to actively engage with the community while developing Mun.
The website does state that its still in very early development. Should we emphasize this more?
Mun compiles to machine code with LLVM so it should be very fast as well, hotloading overhead can be completely removed in builds where hotloading is not required (production builds for instance). Mun should therefor be able to run as fast as native code on all platforms.
Defold is slightly different, still allowing Lua scripting, but not more than that, which is the appropriate place for Lua in a mobile-dominated market.
Yes the Work in Progress Part should swap its places with Pillars. And it should include "Pre Alpha" in it. So we know what stage it is in.
State that it is not suitable for production yet. Perhaps a link to show the most advanced program that currently exists to show where the limits are.
If you are seeking donations, be clear about _who_ you are. Otherwise you could be seen as a scam project.
1) We like this thing that fits into the following use case 2) But we feel it has the following limitations 3) Which we’re planning to address like this.
I think it’s really important to establish what ecosystem slot you’re aiming at. If it makes it to others, fine.
Come again?
I was under the impression that Lua, especially luajit, were incredibly fast languages
> We take inspiration from a scala of application, scripting, and systems programming languages
The word "scala" reads really oddly in that sentence; none of the English-language meanings of the word [1] fits, and to a technical reader it's just asking for confusion with the Scala language. Maybe replace with a clearer and less formal "bunch"?
The syntax shown looks very Rusty, and I believe this started as a thought experiment for Rust. Do you see value in keeping that link explicit? That is, using Mun as a prototyping language for early iteration, then "freezing" it to vanilla Rust with minimal syntax changes once happy with the result?
Also, if the goal here is fast iteration, it'd be interesting to see some ballpark figures for compilation times, which is one of Rust's major Achilles heels today.
[1] https://en.wiktionary.org/wiki/scala#English
Isn't static typing kindof clashing with the hot reloading focus anyway? Maybe make it possible to add the types later.
Language wise, it looks like it is in the Swift/Julia/Haxe space but with first class support for Rust. This looks interesting, I wish them luck and would love to use this in the future.
Two other languages to check out are
Dyon, https://github.com/PistonDevelopers/dyon
Gluon, https://github.com/gluon-lang/gluon
[0] https://nim-lang.org/
LLVM has some support for garbage collection, but I've never heard of any language implementors actually being happy with what it offered in terms of features, correctness, and performance. (Counterexamples would be welcome.)