Civet: A Superset of TypeScript
132 points
3 days ago
| 43 comments
| civet.dev
| HN
danpalmer
8 hours ago
[-]
Civet. Kopi luwak coffee. It's CoffeeScript.

I wrote a bunch of CoffeeScript back in the day, and everyone I've spoken to about it feels the same, that it was a bad idea in hindsight, and a language dead end. The language was only syntactic sugar, and by not bringing anything else to the table, was unconvincing for ports and support in other ecosystems. It now seems that most codebases have been decaffeinated though.

Civet looks like it adds a little more, but the things that aren't just syntactic sugar are just a grab bag of TC39 proposals. I'm a big fan of language proposals in general, and having a language that adds all of them for research purposes seems like a nice thing to have. Haskell did this well with GHC language options. Is this a research language though? It seems not.

What's the benefit over Typescript? A few less characters? Faster TC39 proposal integrations? What happens if a proposal is rejected, does it get removed from Civet? What's the cost? What happens as Typescript and Civet diverge? What if the TS tooling doesn't support Civet features?

reply
arp242
8 hours ago
[-]
> I wrote a bunch of CoffeeScript back in the day, and everyone I've spoken to about it feels the same, that it was a bad idea in hindsight

I don't think it was a bad idea in hindsight.

JS of the era was a pain to use; CoffeeScript made writing and reading things much easier, which is the reason it took off. Since then things changed and many "CoffeeScript features" are now "JavaScript features". Only with knowledge of that future would it be a "bad idea", but it was absolutely not clear that was going to happen back in 2010 and in alternative universes we're all writing CoffeeScript today.

I also think CoffeeScript was probably helpful in getting some of these features adopted in the first place.

The same applies to TypeScript – maybe typing will be added to JavaScript, and TypeScript will become redundant – I think there was some proposal and who knows what will happen. In 15 years we can say the same about TypeScript, but that doesn't mean TypeScript wasn't useful today, with the current state of JavaScript and uncertainty what the future may or may not bring.

reply
danpalmer
8 hours ago
[-]
> CoffeeScript made writing and reading things much easier

My point is that it kinda didn't. It looked prettier on the surface, but didn't actually solve any of the deeper problems of writing JavaScript. To write CoffeeScript you had to still know JavaScript and all its oddities.

TypeScript solved those problems, and that's why it has taken off and had a meteoric rise to the point that it's practically synonymous with JavaScript.

> I also think CoffeeScript was probably helpful in getting some of these features adopted in the first place.

This may be true, but if so that suggests a benefit as a research language not a production language.

reply
dgoldstein0
6 hours ago
[-]
Coffeescript had some great features: classes, array comprehensions, default parameter values, arrow functions, optional chaining. Many of these eventually made it to ecmascript.

And then it ruined us with implicit returns, optional parentheses and brackets, and the isnt vs is not fiasco.

I worked a lot with Python and coffeescript at the same time back in the day. In Python you mess up your whitespace and 95% of the time it's an indentation error. In coffeescript it's a valid program that means something completely different than what you intended. Combined with the optional punctuation, which the community encouraged leaning into, it was far too easy to write ambiguous code that you and the compiler would come to different interpretations of.

reply
edemaine
5 hours ago
[-]
In case you wondered how Civet compared to CoffeeScript in these regards:

* `is not` is the textual equivalent of `!==`. You can use `isnt` if you turn on the feature explicitly (or even the weird CoffeeScript `is not` behavior if you want it, mainly for legacy code)

* Implicit returns are turned on by default. They are really useful, most of the time, and don't get in the way much if you use `void` return annotations (which turns them off). But if you don't like them, you can turn them off globally with a compiler flag.

* Civet's compiler is built on very different technology from CoffeeScript's (PEG parsing, similar to Python), and it is much more strict about indentation. None of those weird bugs anymore.

* We do have implicit parentheses and braces and such, but you're free to use explicit parentheses and braces as you like. We encourage people to rename their .ts files into .civet (which mostly just works without any converison) and just embrace the features/syntax they like.

reply
emmanueloga_
8 hours ago
[-]
CoffeeScript was not only a great idea but also successful beyond its adoption. It influenced and inspired many features that JavaScript later incorporated, such as arrow functions and destructuring assignments.

Over time, JavaScript evolved to the point where the few quality of life improvements offered by CoffeeScript no longer justified learning an entirely new syntax.

reply
MajimasEyepatch
8 hours ago
[-]
I sometimes wonder if Kotlin will end up on the same trajectory. Java has added a lot of pretty good features since Kotlin first came on the scene, and the gap has narrowed considerably. The one thing enormous thing that Kotlin has that cannot be replicated easily in Java is null safety. But lately, most of the other features in Kotlin either make me long for something more powerful like Scala or shrug and just fall back to Java.

Admittedly, I don't do much Android development, and that was a big driver of Kotlin's adoption early on. So maybe it has more of a foothold there than on the server.

reply
btown
6 hours ago
[-]
And beyond this, there’s very much a world where a few key people don’t discover Jeremy Ashkenas’ work - much of which, between CoffeeScript and Backbone, was the excitement that you could make JS feel agile - at the right time in their careers to push the industry in the direction where frontend developers become frontend engineers. We owe so much to these stepping stones.
reply
mrj
4 hours ago
[-]
Well, yeah that was expressly known about CoffeeScript. It pushed JS to the future and was expected to be not useful whenever JS gained more features, but that would take a long time. And some of the syntax features weren't adopted, which meant CoffeeScript seems like a different thing from JS but it wasn't intended to be a departure or permanent.

But JS moved faster and babel was made and eventually we could use JS-future even when browsers hadn't updated yet and CoffeeScript wasn't needed. But it was pretty easy to translate it to JS, commit that and keep rolling. CS was great at the time.

reply
edemaine
5 hours ago
[-]
One of the Civet devs here. To me, the main benefit of Civet is the ability to rapidly add useful features to the language, while preserving all the benefits of TS (tooling, etc.). We're constantly coming up with ideas — from TC39 proposals, other languages, or general brainstorming — and implementing them quickly. For example, we recently added pattern matching when catching exceptions, which took just a couple of hours of development; or Python-style from ... import ... for better autocompletion of imports. All of these features are optional; you can write well-formed TypeScript as usual, and just choose to use the features you think are worth the learning curve for readers. The plugins for VSCode, Vite, esbuild, Webpack, eslint, etc. aren't perfect, but they let Civet code enjoy most of the tooling out there.

I personally use Civet for all my coding projects, as I'm devoted to it continuing to flourish. But if you ever don't like what Civet is offering you, you can eject at any time by replacing your code with the TypeScript compilation, which we make as close as we can to your input.

What happens if a TC39 proposal is rejected? That's actually the good case for us, because it means we can keep the feature as is. Civet already transpiles all features to TypeScript, so they can live here forever if we think they're good. The trickier part is when Java/TypeScript changes in a way that's incompatible with Civet. Then we plan to change Civet to match Java/TypeScript, so that we don't diverge (though compiler flags allow us to also support the older form with explicit opt-in if we think it's worth doing so).

JavaScript and TypeScript move slow. Largely that's a good thing; they're a stable foundation, and we don't want to mess them up. But it's also exciting to be on the bleeding edge, explore new ideas, and obtain new features as quickly as we can design them, instead of waiting a decade. Many features are also too niche / add to much complexity for the general JavaScript language, but they're still fair game for languages that transpile to JavaScript. See also the recent JS0 vs. JSSugar discussion.

reply
lifthrasiir
4 hours ago
[-]
I think you need to drop or at least weaken an inspiration from CoffeeScript if that's a goal, otherwise everyone will immediately draw a connection to that and overlook any other aspect of Civet. (I personally hate CoffeeScript especially for its indentation and that contributed to my initial reaction.) You can't solve this problem with simply supporting two radically different coding styles---the front page seems to prefer one over another anyway.
reply
mistercow
5 hours ago
[-]
CoffeeScript was great except for a few fatal mistakes. The biggest was implicit variable declarations, which meant that to write maintainable code, you had to reintroduce explicit declarations via iifes. Otherwise, you’d risk a future code change introducing shadowing which would have consequences that were super painful to debug.

The other big one, which unfortunately Civet seems to be doing too, is implicit return combined with “everything is an expression”. You can have one of those, but not both. With both, it’s far too easy to write loops intended to be statements, and which accidentally turn into gigantic multi-dimensional array returns which can’t easily be optimized out by the compiler. Fortunately, this would be only mildly inconvenient to work around with a lint rule that forces explicit return in all functions.

reply
edemaine
5 hours ago
[-]
You can also turn off implicit returns in Civet if you don't like them. They also work well with TypeScript annotations: if you annotate a return value of `void`, then there's no implicit return.

I agree it can be easy to make and throw away big arrays if you're not aware of what's going on. But it can also save a lot of time. For loops as arrays are super useful, integrating the equivalent of "map" into the language itself. We also recently added generator versions (for*). JSX is a nice example where for loops as expressions and implicit return are powerful; see e.g. https://civet.dev/reference#code-children

reply
mistercow
5 hours ago
[-]
Yeah those examples are compelling.

What might work well is a lint rule to error if a loop expression ends an actual function declaration (i.e. not an inline callback), and the function doesn’t explicitly define a return type. I think that catches almost every bad case, aside from the odd memory leak in really unusual edge cases.

reply
acjohnson55
3 hours ago
[-]
CoffeeScript was great. It was vastly more pleasant to code in than ES5-era JS. Once ES6 came out, we simply migrated to it and moved on.
reply
lgas
8 hours ago
[-]
I think everyone mostly agrees that CoffeeScript was a dead end, but I think it drove at lot of innovation at the time. Hopefully Civet can do the same, even if it ends up being another dead end.
reply
bhouston
8 hours ago
[-]
CoffeScript was really good at driving innovation in JavaScript. The arrow operator, string literals, and for...in/for...of seemed to be driven specifically from CoffeeScript's innovations.
reply
danpalmer
8 hours ago
[-]
What makes Civet more likely to drive that innovation than TC39 proposals themselves?
reply
Yahivin
3 hours ago
[-]
We ship
reply
reissbaker
8 hours ago
[-]
Considering it's not just a grab-bag of TC39 proposals (e.g. removing braces), I suspect rejected TC39 proposals will just... linger.

I agree a research language feels potentially useful — and in fact that's what CoffeeScript's real legacy is (arrow functions, splats, destructuring assignments, and ES6 classes among others are direct ports of CoffeeScript syntax features, and many of the original JS class proposals that CoffeeScript-style classes replaced were quite bad) — but I'd be similarly leery of using this to ship much.

reply
Yahivin
3 hours ago
[-]
Something interesting I've found while designing Civet is that TypeScript actually mitigates in a lot of the downsides of CoffeeScript.

Types help quite a bit with implicit returns so you don't accidentally return an iteration results array from a void function.

They also help reduce the downsides of terse syntax, just hover over things in the IDE and see what they are. Missed a step in a pipeline? The IDE will warn you if there's a mismatch.

reply
Myrmornis
4 hours ago
[-]
That's a really mean / uncharitable take. As others have pointed out, coffeescript did a great job of moving the language in a good direction, and that's presumably exactly what's intended here.
reply
vekker
1 hour ago
[-]
This is terrible. I was so happy CoffeeScript died a quiet death. Now someone thinks of this.

Keep it simple. Code should be easy to read. Also, ain't nobody got time to learn yet another obscure abstraction that will add only a marginal productivity gain at best (and probably sacrifice readability + add another build step + add another learning curve to new devs in the process).

reply
vivzkestrel
3 hours ago
[-]
Its not about how concise or short your code looks, its how about much time the new intern coming tomorrow needs to understand those 1000 line files. I find the syntax very hard to remember and confusing
reply
speedgoose
1 minute ago
[-]
Some people don't code for the interns but to have fun. But I agree this isn't a very enterprise programming language, à la Java or Golang.
reply
progx
10 minutes ago
[-]
And in times of Copilot & others writing become less and less a problem, as code completion works very well.

Like this example: https://civet.dev/#everything-is-an-expression `items = for item of items`, in js you type `for`and copilot wrote nearly the full correct for-code. So you have to type not much and can read it easy.

reply
rochak
1 hour ago
[-]
Pretty much what I feel about Rust
reply
rjknight
8 hours ago
[-]
Some of these seem good to me:

- "everything is an expression" is a nicer solution for conditional assignments and returns than massive ternary expressions

- the pipe operator feels familiar from Elixir and is somewhat similar to Clojure's threading macros.

- being able to use the spread operator in the middle of an array? Sure, I guess.

I want to like the pattern matching proposal, but the syntax looks slightly too minimal.

The other proposals are either neutral or bad, in my opinion. Custom infix operators? Unbraced object literals? I'm not sure that anyone has a problem that these things solve, other than trying to minimize the number of characters in their source code.

Still, I'm glad that this exists, because allowing people to play with these things and learn from them is a good way to figure out which proposals are worth pursuing. I just won't be using it myself.

reply
dgoldstein0
33 minutes ago
[-]
I'll pass on the pipe operator, but it's not particularly objectionable.

Agree there's some good ideas. Pattern matching looks like a great idea with the wrong syntax - let's just get a match statement similar to the switch statement - if we can't reuse switch.

String dedent and chained comparisons look nice. Though I think the latter is a breaking change if it were done in js. I'd also be fine with default const for loop variables.

"Export convenience" is going to confuse people. The syntax looks different than named exports and looks closer to the export form of default imports which is begging for trouble.

reply
btown
6 hours ago
[-]
For “everything is an expression” https://github.com/tc39/proposal-do-expressions may be of interest, though discussion seems to have paused.
reply
xixixao
34 minutes ago
[-]
I tried to build the braceless syntax some years back (after I worked on CoffeeScript and it mostly died):

https://xixixao.github.io/lenientjs/

But this was before Prettier.

The real challenge in languages now is flawless LSP implementation, auto-formatter and AI completion. It’s possible for CoffeeScript like syntax, but just the existence of an auto-formatter mostly removes the need for dropping all the syntax.

I’d maybe take dropping of parens from if, to align with Rust, but even some of Rust’s syntax makes the language hard to read (if let bindings for example, which switch the flow from right to left), so I don’t consider it a golden standard to strive for anymore.

The other thing I would take is custom operators, not for any production code, but for building games and simulations, to simplify vector math.

I’ll check out the Civet IDE experience, but I suspect it’ll have large cons compared with TS.

reply
xixixao
31 minutes ago
[-]
The other thing that was hard to do with Lenient was to pass the thousands of tests in Babel to ensure the syntax handles every edge case.
reply
SSchick
8 hours ago
[-]
Really redminds me of coffeescript, lots of special syntax that doesn't really help readability?

I have a hard time understanding the motivation of this project other than syntactic sugar-maxxing JS/TS.

reply
Myrmornis
4 hours ago
[-]
The motivation is giving people a chance to try these features and thus ultimately helping move the language in a good direction. That's what coffeescript did also.
reply
smt88
8 hours ago
[-]
Languages like this don't make sense anymore. You can just pick a mature, feature-rich language you like (Rust, Kotlin, Python, probably many more) and transpile to JS.
reply
chrismorgan
39 minutes ago
[-]
That approach only makes any sense if you have broadly compatible semantics; otherwise execution will pay a heavy penalty (CPU usage, memory usage, bundle size). And let me tell you, your “Rust, Kotlin, Python, probably many more” don’t transpile to JS well. If you genuinely mean transpiling as distinct from compiling, I think you could even reasonably say that it’s simply not possible for many languages due to fundamental and incompatible differences. I’d count Rust as that due to things like resolution and aliasing.

If you’re interested in targeting JavaScript, languages like this are your only reasonable alternative to JavaScript itself. (If you’re interested in targeting the web more generally, WebAssembly is a better target.)

reply
Yahivin
3 hours ago
[-]
The GWT approach has its own downsides as well.
reply
smt88
3 hours ago
[-]
A) GWT is 20 years old and not similar to how modern transpilation works

B) What are the downsides?

reply
Yahivin
3 hours ago
[-]
The built in browser debugger is incredibly good. As long as the transpilation is simple and matches JS semantics you can still use the debugger. I haven't seen good debugging tools when using languages more distant from JS but I'd love to know if they've become viable.
reply
troupo
1 hour ago
[-]
All those mature feature-rich languages started as "languages like this make no sense"
reply
chrismorgan
38 minutes ago
[-]
That’s certainly not true of Rust: Rust had a particular goal, easily recognised as worthwhile, which wasn’t possible with any existing languages. Everyone sensible agreed the language made a lot of sense, even if they weren’t sold on the practicality of its specific approach.
reply
bfung
3 hours ago
[-]
Or compile to wasm
reply
inlined
4 hours ago
[-]
Things I like:

- Everything is an expression

- Async imports just work without thought

- Yaml-like object structuring

- JSX improvements

- Multi-line string literals without leading whitespace

Things I’m on the fence about:

- Pipe operators (better than .pipe I guess?)

- Pattern matching (love it in Scala and swift, but this doesn’t feel done right)

Things I loathe:

- Signifiant whitespace (removing brackets in general)

- Optional parentheses in function calls (a foot-gun in VB and Ruby)

- Splats in the middle of function definitions (I can’t imagine how this works with overload definitions)

reply
miffy900
3 hours ago
[-]
Not a fan of YAML at all myself, but it's interesting that you like 'Yaml-like object structuring' yet then loathe 'Signifiant whitespace'? I mean that's basically YAML.
reply
keyle
8 hours ago
[-]
So make sure you introduce this in your company; become the subject expert in it, invite everyone to very cool sessions demonstrating how cool it is, and secure your job until the next rewrite!

Looking at the examples, 1/5th of it looked neat, which probably would be best to submit a proposal for |> to the typescript committee rather than write another alienation.

This is a solution looking for a problem to solve. It introduces an alternative and does so as a superset; which is not only dangerous to existing code bases, but also silly.

reply
scubbo
3 hours ago
[-]
> It introduces an alternative and does so as a superset; which is not only dangerous to existing code bases...

How so?

reply
keyle
2 hours ago
[-]
An alternative way to do something in a code base, for no other reason than style, is a recipe for technical debt. It builds up a larger cognitive load on the developers navigating and working the code base and induces more chances of bugs via half-refactors, or half-considerations.

As for the superset comment, I meant that if you introduce a completely different language, you probably have a valid reason; e.g. it does something different. Adding to an existing language with a superset without any need for it is also dangerous. It's not like it's a DSL at a higher level helping people get repetitive or scriptable things done faster. It's only an alternative, leading people down rabbit hole and second guessing with a lot more to remember.

reply
erulabs
14 minutes ago
[-]
Like coffeescript, this looks lovely to write and horrible to read.
reply
meandmycode
1 hour ago
[-]
I think the most exciting aspect here is this might actually push JavaScript to add some missing features that can make a lot of difference, the pipeline operator for example can really improve the design of JavaScript code and has been proven already in several languages, C#, swift, kotlin to name a few I know
reply
marcofiset
8 hours ago
[-]
The industry has deemed those languages completely unnecessary when we migrated away from coffeescript.

Syntactic sugar can’t be the only thing that makes a programming language.

reply
boredtofears
3 hours ago
[-]
C is syntactic sugar on top of assembly
reply
082349872349872
2 hours ago
[-]
C++ was, for a long time, syntactic sugar on top of C
reply
omeid2
6 hours ago
[-]
If you find this interesting, you might also wanna suss out https://rescript-lang.org/

It is a shame that Bloomberg and Facebook made the whole situation pretty confusing though, but still, it is a nice idea.

reply
c0balt
8 hours ago
[-]
That looks interesting but imo the syntax is too terse. Coming from Rust and Golang I very much appreciate the use of sigils and syntax sugar in moderation but especially the pipe operators look like they could lead to hard to debug code very easily.
reply
botanical76
8 hours ago
[-]
You get used to it. It's really nice in Elixir. I'm not a fan of the fat pipe though.
reply
Kab1r
8 hours ago
[-]
Am I the only one that really dislikes the syntax choices here?
reply
Aeolun
8 hours ago
[-]
I feel like there is a specific kind of person that likes all this, and there is very little overlap between those people and the people that choose to use Typescript.

Kinda feels like someone was forced to work in Typescript and really wanted to scratch their own itch.

reply
Yahivin
5 hours ago
[-]
Nailed it
reply
afavour
8 hours ago
[-]
Having worked in Rust I love the pattern matching proposal. Having dabbled in Swift I like the single argument function part (though keep the brackets, please)

Much of the rest I could take or leave… but then is that just because I’m not familiar with them? Stuff like the pipe operator makes sense to me but it reminds me of .reduce(): there are a few legitimate uses of it but the vast majority will be entirely-too-smart—for-its-own-good show off coding.

reply
Kab1r
8 hours ago
[-]
I fell in love with pattern matching the first time I used Haskell. Having the feature is great, but I really don't like the syntax used here.
reply
mpowaga
8 hours ago
[-]
It appears to prioritize easier and faster typing over readability, which is a poor choice as programmers spend more time reading rather than writing code.
reply
antoineMoPa
8 hours ago
[-]
Nope! I'm also not convinced by it.
reply
Myrmornis
1 hour ago
[-]
One nice aspect of Python compared to TS/JS is the presence of list, set, map, and generator comprehensions. How far in that direction is civet likely to go? I see that arrays can be built from a for...of expression.
reply
emmanueloga_
8 hours ago
[-]
The pattern matching (TC39 stage 1) and pipeline operators (TC39 stage 2) look great, and I'd love to have those in TypeScript. It will probably take a loooong while for those features to be available in JavaScript, but I feel like I can live without those for now :-).

Fwiw it seems a lot of people really like the concept of "significant indentation". I'm thinking Python, YAML, Godot's GDScript. Not a lof of languages implement it but those that do seem to get a lot of users.

Interestingly, it seems like Erik Demain [1] is one of the contributors [2] of this project.

--

1: https://github.com/DanielXMoore/Civet/graphs/contributors

2: https://erikdemaine.org/

reply
runarberg
3 hours ago
[-]
Note that the pipe operator is the rejected tacit pipes from TC-39. TC-39 made the (IMO) wrong choice of what they call hack style pipes (with a mandatory token) where instead of the pipe being a simple way to call unary functions. Civet seems to have picked the better pipes.
reply
dang
4 hours ago
[-]
Related:

CoffeeScript for TypeScript - https://news.ycombinator.com/item?id=34962782 - Feb 2023 (135 comments)

Show HN: Civet the CoffeeScript of TypeScript v0.4.20 - https://news.ycombinator.com/item?id=33834312 - Dec 2022 (3 comments)

Civet: The CoffeeScript of TypeScript - https://news.ycombinator.com/item?id=33323574 - Oct 2022 (17 comments)

The CoffeeScript of TypeScript - https://news.ycombinator.com/item?id=33198931 - Oct 2022 (2 comments)

reply
fabiospampinato
8 hours ago
[-]
Civet has so many quality of life improvements! It's good that it exists sort of as a playground for ideas that could maybe in the future be adopted by JS itself, kinda like how it went with CoffeeScript.
reply
hyperhello
8 hours ago
[-]
JavaScript already has the best use of C syntax I’ve seen. Destructuring, JSON, functions. It’s so easy.
reply
gregwebs
8 hours ago
[-]
The JSX seems compelling. You are already doing a non-standard HTML embedding HTML into javascript, why not do it better? https://civet.dev/reference#jsx

I am not convinced that all the syntax nicety is necessary, but improved pattern matching is often a great thing. On the other hand their examples seem to be to pattern match on highly dynamic types, which you can avoid 95% of the time with TypeScript.

reply
recursive
5 hours ago
[-]
JSX has a spec. This thing they're doing... I don't know what it is, but it ain't JSX.
reply
edemaine
5 hours ago
[-]
The JSX spec hasn't changed for almost 10 years, and I'd guess there will never be a JSX 2.0. On the other hand, ideas for a better JSX are plentiful (check out the issues on the JSX repo, for example). If the spec never changes, how can we improve the JSX experience? Transpilation!

Civet's futuristic JSX compiles to actual spec-compliant JSX, to it's compatible with all forms of JSX, including React, Solid, etc. We'd like to support other DSLs like Astro and Svelte as well.

reply
epolanski
8 hours ago
[-]
Interesting but not sure how much do I buy it.

I would rather do with a stricter super set of TypeScript with some sugar/conveniences around its many verbose but useful features like branded types.

reply
edemaine
5 hours ago
[-]
We're definitely looking for ways to improve ways to specify types! I think destructured typing [https://civet.dev/reference#destructured-typing] is already quite useful, especially for React. On the readability side, if/then/else [https://civet.dev/reference#conditional-types] seems easier to read than ?: ternaries, and "Partial Record Name, Info" seems easier to read than "Partial<Record<Name, Info>>" (implicit type arguments — https://civet.dev/reference#implicit-type-arguments). But we'd love to hear more ideas for features like branded types. Join us in Discord if you're interested!
reply
steve_adams_86
2 hours ago
[-]
I really like that everything is an expression. I know the extra work is happening in the background, but this kind of developer experience is really nice in my opinion.
reply
smilekzs
8 hours ago
[-]
I know this hasn't been updated, and I know it's a fork of CoffeeScript, but https://livescript.net/ has had a lot of the "magic" syntax here for quite a while.
reply
edemaine
5 hours ago
[-]
Yes, Civet has taken a lot of syntactic inspiration from LiveScript. At this point, I think we have most of the good features, but we might be missing some. Let us know what you think!

The big difference, of course, is that Civet fully supports TypeScript, and is up-to-date with the latest JavaScript and TypeScript features.

reply
k__
10 minutes ago
[-]
Nice!

I loved LiveScript, but it got kinda lost in the wake of ES6.

They planned to add types, but never got around doing it (at least the last time I looked).

reply
adamtaylor_13
8 hours ago
[-]
This is way less readable than normal TS. For that reason alone I doubt I’d use it.
reply
diath
8 hours ago
[-]
This just looks like it's trying to remove as much syntax as possible and as a consequence makes it harder for me to follow what's going on. Kind of like a write-only language.
reply
bhouston
8 hours ago
[-]
I do not particularly like the lack of brackets everywhere. I think it is hard to know precedence perfectly and brackets ensure you do not make stupid mistakes.

Also there is the classic issue where you take an if statement that has a line one expression and you add a second line, but now because it didn't have brackets (and you are not using indentation style), you just introduced a bug. Or you have an if statement with an expression and you comment out the expression but not the if, then your next statement is now the if conditional expression, which is not obvious.

reply
edemaine
5 hours ago
[-]
But we are using indentation style; that's one of the major design principles. In Civet, the body of an "if" can be multiple lines, and it's clear (from indentation) what they're nested under. Also, the body of an "if" statement can be empty, so if you comment out the body, the "if" doesn't apply to anything else. (This is an improvement over Python, which requires non-empty bodies, even if just to say "pass".)

I think there's a reason that Python is among the most popular programming languages, and part of it is the indentation-based syntax and lack of brackets. The core of Civet's syntax (originally inspired by CoffeeScript) is like a combination of JavaScript/TypeScript and Python, the two/three most popular programming languages.

But also, if you like brackets, you can include them! Most JavaScript/TypeScript code is also valid Civet. Just use the features you like.

reply
lifthrasiir
3 hours ago
[-]
Python used an indentation-based syntax from the beginning and its syntax is particularly optimized for that. In particular, any block statement (formally, a statement followed by a "suite") would end with `:` and that's effectively the only place where a dangling `:` can happen [1], so you can easily recognize such statement from any directions.

In comparison, at least some people would find CoffeeScript and Civet to be hard to read because they solely rely on left-bearing indents. If my eye is pointing to the rightmost column and scanning to left, I wouldn't be sure about any nature of the line until the very first token and thus preceding indent is reached. This problem is not unique but can be somehow alleviated with some tweaks to the syntax. Ruby `if` for example is also prone to this issue but an explicit `end` token keeps it on track in most cases. CoffeeScript did nothing.

[1] The only other case is `lambda ...:` in parenthesized expressions. `lambda` in Python is quite exceptional in its syntax after all...

reply
vosper
9 hours ago
[-]
I see a language that compiles to JS. What makes this a superset of Typescript? Are there more types? A more powerful type system?
reply
afavour
8 hours ago
[-]
The linked page is pretty self explanatory. It’s TS with some extra features, many of which are already proposals for the language. Cool for an experiment, not good for a maintained codebase.
reply
mhh__
6 hours ago
[-]
|> is such a breath of fresh air when otherwise stuck without it, or worse being forced to do OOP style "design your abstraction before your logic".
reply
fire_lake
1 hour ago
[-]
Typescript with a dash of F#
reply
hbbio
8 hours ago
[-]
Pattern matching: yes, it's needed and maybe the only useful feature in here.

The syntax and some other features, no. Some are even anti-features or "magic" that takes the actual semantics away from the developer.

reply
adamwong246
8 hours ago
[-]
Someone needs to mix this together with https://www.derw-lang.com/
reply
worldsayshi
2 hours ago
[-]
This has to be an error in the documentation:

<ul class="items">

Should be:

<ul className="items">

reply
zarzavat
1 hour ago
[-]
Depends on the framework. You can use class= in Preact.
reply
koolba
8 hours ago
[-]
What does this do?

    operator {min, max} := Math
    value min ceiling max floor
Is that a declaration or an invocation?
reply
edemaine
5 hours ago
[-]
It's doing a few things at once:

First line:

* `{min, max} := Math` is a destructuring declaration. It's similar to the destructuring assignment `{min, max} = Math` (i.e., `min = Math.min; max = Math.max`), but also declares min and max as const.

* The `operator` prefix means to treat min and max as new infix operators in the rest of the program.

Second line:

Given that min and max are infix operators, `value min ceiling max floor` is equivalent to `max(min(value, ceiling), floor)`. Yes, the latter is gross. That's why we like to write `value min ceiling max floor` instead. Think of it as "value minned with ceilling (i.e. capped at ceiling), then maxed with floor (i.e. prevented from going below floor)".

reply
ht85
7 hours ago
[-]
It looks like rubyist brainrot
reply
paulddraper
8 hours ago
[-]
CoffeeScript never dies.
reply
beders
5 hours ago
[-]
What's the compilation time impact of that?
reply
edemaine
5 hours ago
[-]
Good question! I don't have hard numbers, but for larger files, I find that it can take on the order of a second to compile. It's still fast enough to get real-time feedback from TypeScript in VSCode, but it could definitely be faster. There's lots of optimization left to do; for now, we're focusing on features over speed, but we'll get to speed as well. (I am an algorithms guy after all!)
reply
Yahivin
6 hours ago
[-]
This is pretty neat but I wonder how it compares to Arc...
reply
north_african
1 hour ago
[-]
We need a language that compiles to js with strong typing not another ts!
reply
pyrelight
8 hours ago
[-]
It's time to stop. Too much mental overhead in front-end dev right now.
reply
paulddraper
6 hours ago
[-]
"Everything is an expression" is low-key nice.

Scala has it. Other languages too.

reply
melodyogonna
1 hour ago
[-]
Lol. A superset of a superset. I wonder how far we can go with this
reply
01HNNWZ0MV43FF
7 hours ago
[-]
No relation to CivetWeb
reply
colesantiago
8 hours ago
[-]
Civet reminds me of Coffeescript but now in TypeScript.

This has made me even more convinced that the future of JavaScript is JavaScript.

We will be seeing JavaScript (natively) having all the types, features and proposals that TypeScript has and the industry will eventually move on from TypeScript.

reply
recursive
5 hours ago
[-]
I feel like typescript would officially deprecate itself if that ever happened. But I also feel like that won't ever happen. It would be cool if ES would get optional type annotations or something, even if they were ignored at runtime. But someone would still want a static type checker. TS does that, and if there's nothing to replace that part, then TS still has a viable mission statement.
reply
jcmontx
8 hours ago
[-]
This looks like F#
reply
coolThingsFirst
8 hours ago
[-]
Just dont….
reply
williamstein
8 hours ago
[-]
This is seriously triggering my CoffeeScript PTSD.
reply