Mint-lang: a language for the front-end web

8 years ago (mint-lang.com)

What I would really like is for JS to have a good macro system so I don't have to subscribe to the two caste hierarchy of language creator and language user.

Sweet.js [1] did it for me initially as cspjs[2] had async, await and more years before ... but I never found the time to ramp up to the updated version sadly so I can't comment on its state now.

[1] https://www.sweetjs.org/

[2] https://gitHub.com/srikumarks/cspjs

  • The two caste hierarchy is my biggest issue with Golang. Macro capability exists in Golang, but only for the upper caste of language creators. It makes me feel like the language creators of Golang purposefully decide that users of the language aren’t smart.

    • Rob Pike, in his own words, claims that programmers at google are "not capable of understanding a brilliant language", and that this is the reason why Go is designed the way it is.

      The full quote:

      > The key point here is our programmers are Googlers, they're not researchers. They're typically, fairly young, fresh out of school, probably learned Java, maybe learned C or C++, probably learned Python. They're not capable of understanding a brilliant language but we want to use them to build good software. So, the language that we give them has to be easy for them to understand and easy to adopt.

      -- Rob Pike, 2014, at ~20m50s of https://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Fr...

      5 replies →

    • It's not a comment on a users intelligence. It is instead a recognition that not all users value the same things. Therefore it is helpful for consistency and the writing of robust maintainable code that Go be opinionated at the language level. You don't have agree to with them but they made their choices informed by their years of writing large complicated codebases and they enforce those decisions at the language level. They have no wish to allow someone else to subvert those decisions since it would be counter to the goal of the language.

      You as a user can choose to live with those decisions or use a language that gives you more freedom. All such decisions come with a series of tradeoffs. Just make sure you are making the decision in as informed a way as you can.

    • You might be interested in trying out Nim. It's a language that empowers the user, giving access to AST macros, compile-time function execution and generics.

      I would say that using Nim's metaprogramming capabilities to create a great SPA framework is a better direction than creating a brand new language.

      3 replies →

    • Programming is as much about communicating with your peers as it is about getting the computer to do what you want. Go's inflexibility results in uniform code which makes it easier to understand.

      Macros allow you to introduce dialects which can be powerful in their expressiveness but often result in significant departures from the original language.

      When someone new comes into the project they have to learn the dialect before they can even read the code. More often than not they give up and rewrite the code from scratch in a language they understand.

      Sometimes additions to the language make sense, but there's a real cost, a cost that often gets ignored. Do it to much and you kill the golden goose.

      1 reply →

    • > It makes me feel like the language creators of Golang purposefully decide that users of the language aren’t smart.

      If they are anything like Guido for Python, I think the idea is quite the contrary.

      Language users are smart. Just too smart for their own good.

      Like the coyotes we talked about recently on HN (https://news.ycombinator.com/item?id=17079369) who are "winning the mini-game of each human interaction, but they are losing the meta-game of what society will do if coyotes aren’t scared."

      Well, just like that, language users with macros are winning the mini-game of their interaction with the current opened files in their editor, but they are loosing the meta game of maintainable projects, shareable knowledge and reusable tools.

      Macros (or their small brother, "just a little DSL") are the most abuse feature in dev, period. They are too clever, the results almost never documented or even tested properly while often being very specific to the creator use cases.

      I really think macros are one of the reasons why Lisp never became more popular: a small smart population love it for macros while the rest of the population just doesn't want to have to deal with all the macros BS created by the former population.

      Same for Ruby. Honestly, having to go through yet another DSL du jour killed it for me.

      So my guess is that the Goland creators know very well how smart the language users are. And they are afraid, very afraid.

      4 replies →

  • JS has tagged template literals. I think they're still underused.

    • Since this is a comment in response to an expressed desire to use macros, I'm curious -- is there some way you could use tagged template literals as a macro system? Beyond what eval gives you?

      1 reply →

  • What's missing, as far as I've been able to determine, is a way to use Sweet.js or similar with typescript. What I really want is a language that provides me with static types but lets me have macros to generate the boilerplate that tends to result.

    • OCaml has its macro system and compiles to JS (via BuckleScript or js_of_ocaml). I'm not sure if ReasonML also has macros, but I wouldn't be surprised if it did, and there's a lot of articles lately about using it with React.

      Personally, I never used OCaml on the frontend, but have some experience writing native apps in it and it's a really good language. Its type system is top-notch, its object system is unorthodox and powerful, the camlp4 macros allow for adding new syntax to the language - and so on. Worth taking a look at if you're searching for strongly, statically typed language for the frontend.

For the ones who want to get (a similar) developer experience while coding actual JS(X): you can use `react` together with `mobx` to the same effect. Additionally, take a look at `mobx-state-tree` to get more structured code.

And of course, there's Elm if you want to get a completely different thing.

  • mobx-state-tree is really neat and feels like the next step beyond redux. Not having to create explicit event names and 'action dispatchers' is a real boon to DRY. The only issue I've had is more to do with typescript and using mobx-state-tree plus react router... the type definitions and type error messages can get rather confusing to debug.

  • Elm, Elm, Elm!

    • Elm is extremely opinionated and bottlenecked by one person. It’s great for the specific usecases it was designed for, but it gets tedious once you start interacting with external code and the outside world. The development cycle is slow and communication from the dev team is sparse. Some would argue that the slow deliberate, development pace is a good thing, but I was personally turned off by the fact that compiler bugs (and even documentation spelling mistakes) would stay open for months or years.

      I know somebody is going to jump in and tell me I’m wrong, that they’re using Elm in production and it’s the best, etc. This is my personal experience from using Elm on several side projects and also in production at my last job.

      3 replies →

I can see why they colour coded blocks. I think that project would have been unreadable otherwise. Which is ironic because even the worst of HTML with inlined CSS and JavaScript is more readable (albeit less maintainable).

Author here, please keep in mind that Mint is still very young and I'm still working to get things in order for a first stable-ish release (there are a lot of documentation to write and lot of cleanup work)

I'm glad that this project was written on Crystal. But does it tries to be like Elm?

  • The author here, I was using Elm for a while invested a lot of time in it so there are parts of it that I like and that are parts that I don't.

    In a sense it tries to be like Elm:

    - good developer experience with nice error messages

    - single binary that have all the tools

    - enforcing types

    - no runtime exceptions is you don't use JS interop

    In an other sense it tries not to be like Elm:

    - JSX syntax with easy compose-ability

    - Straightforward JS interop

    - Decentralized and open package management

  • The author had been using Elm before (they're an author of elm-ui, for example), so maybe there's an inspiration?

I don't think I can make up my mind over small example. I don't think it is bad it is using patterns from React or Mobx as they are well known and it can help us think about development.

Syntax is not such that I am immediately sold, but also not put off. What I didn't see is some performance promise like Elm, or simplicity, where it make sense to use this over anything else.

I think it is good that a lot of people are thinking about languages and how to improve development, not everything has to be ground breaking. I will keep an eye for future work and how it develops.

  • Thank you for this comment! It really helps a lot to get decent feedback.

    > What I didn't see is some performance promise like Elm, or simplicity, where it make sense to use this over anything else.

    I was focusing on the example, it seems I should really put up more information about this on the website, but to answer for this is basically:

    - it uses React under the hood meaning you have the same performance, the devtools works the same, it is possible (with some work) to use components from Mint in React and vice versa.

    - the error messages are really nice (there 281 unique error messages overall) both for syntax errors and type errors

    - easy JS interop using backticks

    - no import statements

    - fast compile times (the website compiles around 1 second)

    - single binary with all the tools included (development server, production builder, favicon generator, test runner)

>The else branch must be present, if it's missing you will get a syntax error this is to make sure that all of the possibilities are covered

Is there itsokay statement to pacify the compiler more?

  • If if/else is an expression, what would be the return type of `if (true) { 42 }`?

    •     int option 

      which is basically a variant/union like this:

          Result of 'a | Void
      

      You could also have a `discard` or `ignore` function/operator, which can swallow every type, so it doesn't matter what it was. Some languages actually require you to use such operators, for example, Nim and F#.

Web languages seem to be the new web frameworks for JavaScript - in the sense that there seem to be more and more of them coming out all the time.

This is really cool, and I did something very similar (more hackish) ten years ago. This is a very powerful technique, and I wish the mint team the best. The downside is really a combination of building a community and educating people about it; this is where I failed along with SEO.

  • > The downside is really a combination of building a community and educating people about it

    Yes, this is what I'm worried about.

    I'm still tweaking a lot of things and I wanted to share it with HN when I thought it was ready, but on the other hand it's a nice that it got some attention already.

    I hope there will be enough interest over time to actually build up a community.

Awesome!!!

  • Why do you think it's awesome? It's just another zealous implementation of some guys unearned and unfounded ideology. You know you can write the same thing with regular JavaScript and cut out the middle-man.

    • A polyglot is harder to reason about than a single language, due to social concerns. Mostly this is due to the efficiency of singular concern and custodianship as opposed to disjointed languages with their own.

How about just biting the bullet and writing JavaScript?

If I decided I wanted to use Delphi, but I didn't like Object Pascal, so I implemented a Scheme over the top that gave weird deep backtraces with wrong line numbers whenever an error occurred, compiled to a single-line semicolon-delimited mess of unidiomatic Pascal, and often required me to write some Pascal anyway, you'd think I was nuts. Why do we think it's a good idea just because it's in a browser?

JavaScript has its problems, but it's far from the worst language out there. Just write JavaScript already.

  • I see your point, but I also think a smaller, more focused language can be useful for teams; in order to enforce best practices.

    Think Elm: it's impossible to produce side-effects or mutate objects, cause the language simply does not have the facilities to do so. The guarantees Elm gives you would be hard to maintain if it was just a library which had to deal with JS's constant dynamicness.

    Moreover this guarantees do not only improve developer experience; but also compiler optimizations.

  • The difference is that there's no other way to target the browser. With your Delphi example, you could just use a Scheme implementation that targets the same platform. With the browser, JS is the only way to run code. That's starting to change with WASM, but it'll be while before it can be used for everything JS is used for.

  • I think you just described ES6 compiled by Babel pretty well. Most people have gotten used to this disconnect.

  • On the other hand, i could rewrite your comment about assembler, in the early days of C and B and the like. As source maps and debugging get better, we get closer to being able to ignore the javascript.

  • Unfortunately, that ship sailed long ago, and the javascript community has coalesced around avoiding direct contact with the language at any cost.

    • Why is it unfortunate that people improve their tools with things like Elm and Mint?

      And how is "just use Javascript" a response to that? Seems like yall should first try to understand why people use tools like Elm and Mint instead of assuming it's just some flippant aversion to Javascript?

      2 replies →

Working on a project in Angular right now I’m really questioning if the layers of abstraction on front end code are worth the cost. The compile times and performance costs over writing standard JS are real.

  • The complexity and maintenance costs of developing a real-world application in standard JS are also real.

    • Or you could design your application to not need all the bells and whistles and complicated shit that modern front-end web UIs throw in. 90% of pages could be static HTML. Probably 95% of "web applications" could be a set of forms with post-backs.

      If I'm trying to make a thick-client, I'd rather build it in a language and platform that I don't have to fight quite so much.

      2 replies →

    • I would only consider something like Typescript mandatory, because static typing is just so hugely important for any maintainable project. But beyond that, it's a little more work to come up with a clean MVC pattern yourself, but also perfectly feasible to not use React/Angular/etc.

      Depends on scope and number of developers I guess.

Do we really need yet another language for the web?

  • We do need better languages, but we should get rid of languages that marginally improve. Take CoffeeScript: it pushed EcmaScript forward, but does not offer enough feature today to justify pouring enourmous man-hour resources into it.

    And this is true for many more languages (Flow, PureScript, LiveScript, IcedCoffeeScript, ...) which don't innovate on many aspects but just offer a slightly different - sometimes improved - syntax. I do recognize that many languages add value, but that must be offset to the cost of using these languages. Costs which are often quite high: Googleability, StackOverflowability, documentation, tooling, develop mindshare, library support, stability - these things don't come cheap and take years to mature.

    Furthermore, these "innovate slightly" languages in the webspace take away resources from improving the current state of the art in mainstream (EcmaScript, TypeScript, Dart, C#, Java, ...). For instance, instead of improving some JS tool now resources go into e.g. writing a language server for aforementioned language.

    A good example is Elm which does try to innovate on core concepts (builtin reactivity). That's a conceptual feature which can bring the state of the art of programming language design further.

    Last, I do not mean that we should not write any more new languages; but we should stop trying to get large-audience adoption for "innovate-slightly" languages. It's a waste of braincycles and actually hurts the ecosystem.

    • PureScript is not JavaScript with a different syntax: it is a language with a full Hindley-Milner type system.

      "A strongly-typed functional programming language that compiles to JavaScript -- Build real-world applications using functional techniques and expressive types, such as: Algebraic data types and pattern matching; Row polymorphism and extensible records; Higher kinded types; Type classes with functional dependencies; Higher-rank polymorphism" http://www.purescript.org

      1 reply →

    • I understand the general sentiment, but the two categories you describe seem subjective to me.

      For example, why do you consider TypeScript to be a "state of the art in mainstream" worth improving, and Flow to be just an "innovate-slightly" language? Those two projects are very close in nature. And if the key difference is adoption, then why is Dart along with EcmaScript and TypeScript?

      10 replies →

  • No, we don’t “need” it. But how do you think progress is made? People come up with new techniques and tools all the time, based on their previous experiences with a platform.

    Sometimes these projects wither and die. Sometimes they find niches where they’re particularly useful. Sometimes they hang around with a core of dedicated users. Sometimes the ideas they introduce go on to influence other languages. Those are all beneficial.

    I’m surprised to see this same complaint levelled so often.