Readit News logoReadit News
hsn915 · 3 years ago
Way back in the early 2010s I was very "excited" about coffee script and similar projects. They sounded like they should be great for productivity.

When I actually tried to write a project in coffee script, the results were the opposite of what I expected.

The code was harder to read, harder to modify, harder to understand, harder to reason about.

There's something about removing stuff from syntax that makes programming harder. My hypothesis is this: your brain has to spend extra effort to "decompress" the terse syntax in order to understand it, and this makes reading code unnecessarily difficult.

So I fundamentally disagree with the underlying premise of these projects, which seems to be based on PG's concept of "terse is power".

My experience suggests the opposite: there's power in being explicit. Type declaration is an example of such a feature: it makes explicit something about the code that was implicit.

Type declarations add more to the parse tree, and require you to type more, but they actually give you more power.

The same can be said about being explicit in the language constructs.

There of course has to be a balance. If everything is way too explicit (more so than needed) then your brain will do the opposite of what it needs to do with terse code: it has to spend more effort to remove the extra fluff to get to the essence of what the code is doing.

Being terse is good, up to a point. Same with being explicit.

Languages that try to bias too strongly towards one extreme or the other tend to miss the mark. Instead of aiming for balance, they start to aim for fulfilling some higher telos.

redka · 3 years ago
I don't know how much you actually tried coffeescript but I find your opinion strange. Coffee wasn't ever like J or anything crazy terse. Its appeal came not merely from making things shorter (it did that, but not by a crazy margin), but from adding a lot of useful things to the language like ? operator, spread operator, destructuring, classes, ranges, better iteration, etc. Almost every coffeescript feature was ultimately added to Javascript (and with very similar syntax) which made coffee somewhat obsolete. Coffee's lack of brackets and semicolons everywhere and @foo instead of this.foo, as well as usage of other features certainly didn't take away any readability or explicitness, if anything - they made it better; the same way those same features make Javascript better and more readable (and, ekhm. "easier to reason about") as long as you _know_ them.
Jare · 3 years ago
Coffee added really nice and productive language features to what at the time still was a very primitive and simplistic Javascript. It also offered a different syntax to existing and new features.

The first part was great and deserves credit for pushing the language to evolve. The second part made it a terrible dev experience. My experience was identical to the gp: writing it was fast and intuitive, but reading it was much, much worse. Not just reading other people's code, but even my own: my ability to understand my own code degraded not in weeks or months, but mere days. It was so bad, the overall result was a net negative and I quickly stopped using it. I say this as someone who has enjoyed writing code in over a dozen languages, from assembly all the way to Haskell.

notShabu · 3 years ago
Same, even though a lot of syntax is theoretically unnecessary, they chunk the code into patterns that help navigate the complexity.

Otherwise it's like improving the efficiency of a closet by ripping out the shelves, drawers, dividers, coat hangers, etc... so that it's just one big volume-maximized empty room.

ikurei · 3 years ago
> Being terse is good, up to a point. Same with being explicit.

I'm thinking of using Civet for an upcoming project, I specially want `do` expressions. Even with how much noise an IIFE (`(() => {doStuff(); return ...;})()`) introduces, it's such a natural idea to me that I end up using them very often.

But what makes me question the idea is having to learn a new syntax that is close enough to the JS I already know that I'm going to get confused constantly.

Why would I care about writing `export a, b from "./cool.js"` instead of `export { a, b } from "./cool.js"`? I don't mind those curly braces, I may actually like them a bit; I do very much mind the overhead of remembering these details when I change languages, and there's no way I can remove JS/TS from my life.

Finally, there's expressions like `value min ceiling max floor`. Is that readable at all? You have to actually read each word to know which are operators, which functions, which vars... It seems to me much worse than `max(min(value, ceiling), floor)` or a Lispy alternative like `(max (min value ceiling) floor).

WorldMaker · 3 years ago
Even the pipeline operator this supports seems easier to read for this particular example: value |> Math.min(&, ceiling) |> Math.max(&, floor)
technion · 3 years ago
I didn't mind the coffeescript experience, but it's deeply hurtful to productivity to dev in a platform that doesn't end up winning.
yashap · 3 years ago
Yeah, I like a lot of the language features here, especially:

- Everything is an expression

- Pattern matching

- Spread in any position

- Dedented strings/templates

However, I wouldn't use it, because the chance of it becoming abandonware that I just have to migrate off of later is way too high. I'll write a few extra TypeScript characters here and there for the stability.

tinco · 3 years ago
CoffeeScript did end up winning though, all of its important features ended up in the next Javascript spec. It was a bit sad to transition into the slightly less aesthetic next Javascript release, but it also felt triumphant. To me it feels like the CoffeeScript community won. Every time I type some Javascript that's actually not fragile and not absolute garbage, I remember it's because we as a community backed CoffeeScript, and that led to the browsers listening and adding its features to Javascript.

I am certain we're doing the same thing now with Typescript.

hsn915 · 3 years ago
Is it? I find most of the "winning" tech deeply unproductive. Have you tried developing in a project with Webpack and Redux? It's kind of its own little hell. Everything is way too slow and complicated. Tasks that should take 20 minutes take 3 hours.
brundolf · 3 years ago
I think you're talking about two separate things here,

1) Having to learn an entirely new syntax just to save on a few characters (it "decompresses" directly to the original thing)

2) Explicitness vs implicitness/inference

I wholly agree with you about #1 (superficial brevity isn't a very important goal and doesn't justify a whole new language), but #2 is much more of an "it depends"

cglong · 3 years ago
Go's error handling pattern is a great example of being overly explicit IMO. I personally like it, but I can understand why it causes so much controversy.
frou_dh · 3 years ago
The thing about:

    if err != nil {
        return err
    }
...is that it's not even Error Handling. It's "Error Shovelling" (manual work to move the error from one place to another).

hsn915 · 3 years ago
I find that Go errs way too strongly on the explicit side, but overall it's still better than many other alternatives.

For error handling I tend to write in a style where errors are either asserted out or "folded". If I do several operations in sequence any of them could err, I code in a way where I don't check every single op: instead I make some kind of "error accumulator", or write the code in a style such that if the previous operation failed the next operation will become effectively noop. I then check for errors at the end of the process.

That said, Go is actually right about treating errors as values and not giving special language constructs to throw/catch them.

dontlaugh · 3 years ago
The problem is that it doesn’t compose, not the verbosity.
nine_k · 3 years ago
All natural languages have a little bit of redundancy. It helps solve ambiguities more easily, especially when solving it in a strictly minimal grammar would require re-parsing the entire text from start. Having both opening and closing parens / brackets / braces is a good example.

Redundancy also helps when transmission is imperfect. And you do have imperfect transmission when writing code (typos), and even when reading (skimming text, missing a character).

CoffeScript makes every character count, especially punctuation. It's really, really easy to make a small typo in these. But CoffeeScript eschews redundancy, so the typo becomes another valid grammatical construction, with an entirely different meaning. At best, you get a cryptic translation error elsewhere. At worst, it gets accepted but works differently than you had intended.

APL has this property, too. But an APL program is very terse, you pay attention to every character in a short string of them. It does not feel like Javascript which is traditionally lax in the punctuation and whitespace department, catching you off guard.

CoffeeScript was an interesting experiment, but I'd say its result is negative.

j-krieger · 3 years ago
I agree. The Rust foundation (or Mozilla's Rust Team in the early stages) tried out a sigil heavy approach in the beginning, but they ultimately made the decision to steer Rust away from being overloaded with single character keywords of differing significance.

Sadly, with Steve Klabnik's withdrawal from the core Team, the current maintainers are on a path to repeat these mistakes.

onion2k · 3 years ago
Reading CoffeeScript, and this Civit language, feels like reading prose that doesn't have any punctuation. Slightly quicker to write, much harder to read.
dewmal · 3 years ago
We also had same experience with cofeescript. It was a not a nice experience. Later we move with JS because of maintenance issues.
hyperthesis · 3 years ago
\tangent Things stated by implication are harder to understand because of the cognitive load.

But I wonder, if the compiler can get by without it, perhaps we can too? With a different mental model/abstraction, that simply does not need that information - not even by implication. If there is one, probably not easy to come up with.

Like kinematics omitting force (e.g. high school physics, x = x_0 + vt + 1/2at^2). https://wikipedia.org/wiki/Kinematics

Throw999999 · 3 years ago
As terse as possible for me, I think you underestimate the human brain.
aerhardt · 3 years ago
I don't underestimate the human brain - however, I know as a fact, through ample empirical evidence, that implicit or dynamic typing makes my head hurt and has me scrambling through multiple code panes trying to understand the input or return types for code that I wrote five days ago.

I also know as a fact that programmers 100x my caliber have nevertheless written great large-scale software without types.

So I don't make generalizations on the human condition and just do what works for me!

lukehoban · 3 years ago
It’s funny - when we were first designing TypeScript - I often described it as "TypeScript is to CoffeeScript as C#/C++/Java is to Ruby" often adding "and there are 50x more of the former developers than the latter" [0]. And CoffeeScript’s approach of transpiling down to clean JavaScript was a big inspiration for TypeScript. In the 10 years since then, some of the Ruby/CoffeeScript aesthetic has become more mainstream in other programming languages (Swift, Rust), and gradual type systems have become more of an expectation even in dynamic languages like Ruby (Sorbet), Python (mypy) and PHP (Hack). So it does seem very natural to bring these back together now like Civet is doing.

[0] https://medium.com/hackernoon/the-first-typescript-demo-905e...

justsomeuser · 3 years ago
Under "Everything is an Expression":

        items = (() => {
          const results = [];
          for (const item of items) {
            if (item.length) {
              results.push(item.toUpperCase());
            } else {
              results.push("<empty>");
            }
          }
          return results;
        })();

Seems like they are purposely making the JS version extra long. It could be:

        items = items.map(x => x.length > 0 ? x.toUpperCase() : `<empty>`)

Edit: Just realised the code on the right is the compiled code, not the "equivalent hand written JS".

8f2ab37a-ed6c · 3 years ago
My kingdom for "everything is an expression" in JS/TS, but that would likely require an entirely new language.
eyelidlessness · 3 years ago
If you’re willing to accept a little bit of extra syntax/ceremony, the `do` expressions proposal[1] is pretty much this (but it’s only stage 1 so who knows when/if it’ll land).

1: https://github.com/tc39/proposal-do-expressions

davedx · 3 years ago
At some point you might as well just use lisp, right? :D
mattigames · 3 years ago
Given than in JS an empty string is a falsy value you can go even shorter:

     items = items.map(x => x.toUpperCase() || `<empty>`)

chii · 3 years ago
The original ternary "fixes" the cases where `x` is "wrong" (e.g., is not a string - `x.length` does not fail, but evaluates to false, and thus you still get `<empty>`).

This even more terser code will fail if `x.toUpperCase()` fails with an exception (such as when x is not a string).

root_axis · 3 years ago
Your version doesn't correspond to the code written on the left side.
justsomeuser · 3 years ago
You are right, I did not realise it was the compiled code.

I thought it was the comparable hand written JS.

Deleted Comment

Deleted Comment

nforgerit · 3 years ago
It might be me but "expressive syntax" does not automatically translate to any metric of productivity or "fun". Especially not in a job, where we put most of our work time into reading, researching, searching, conception and discussions. Only a fraction of my work time consists of "actually typing in some form of syntax".

I for one appreciate simplicity and would prefer Clojure anytime over Scala. The further comes with barely any syntax, has a couple of quick-to-grep concepts and once you trained your brain to read it and your editor to juggle the parens it is a lot of fun. The latter looks very nice and casual in the beginning but to me feels like a rabbit hole of complex concepts that were always heavier than the domain I was using it for. YMMV.

Tho civet code examples look nice I'm afraid it adds much more complexity than needed, both the concepts you have to keep in your brain's working memory and the whole TS toolchain which is already kind of horrible these days.

vore · 3 years ago
I'm not sure if getting some extra syntactic sugar is worth adopting a whole other language into a codebase: at least, that seemed to be one of the lessons from CoffeeScript.
zarzavat · 3 years ago
Do you like writing this everywhere?

    var that = this;
    function() {
      ...
    }
Back when there was no async/await and no promises, passing callbacks like this was extremely tedious, and node.js had a lot. CoffeeScript was worth using for the fat arrows alone.

CoffeeScript didn't die. JavaScript (ES3/5) died and we are all using CoffeeScript now!

winrid · 3 years ago
Oh God, that = this made my heart jump a little. Is this what it's like to feel old? :)
polyamid23 · 3 years ago
was function() { .. }.bind(this) not around yet?
dagw · 3 years ago
As someone who used to be a big CoffeeScript advocate, I agree that adopting CoffeeScript over modern JavaScript isn't worth it. However adopting CoffeeScript when it came out over what JavaScript looked like at the time was a much bigger win.

That being said, as much as I liked using CoffeeScript in my own personal projects, adopting it for a non-trivial project at work probably turned out to be a net mistake all things considered. The only positive was that the .js output files where clean any easy enough to work with that we could quite easily just drop CoffeeScript and continue developing directly with those .js file

Klathmon · 3 years ago
Eh, as long as the team is on board, and the sugar is simple enough and maps well to the underlying language without a ton of extra code, then I have no issues with it.

If it ever becomes a liability, you just check in the "transformed" code and it's gone.

bigyikes · 3 years ago
You check in the transformed code and it’s gone, except for the Ghost of Syntactic Sugar which will haunt your codebase forever and make the juniors wonder why all the code is so awful.
vichle · 3 years ago
> If it ever becomes a liability, you just check in the "transformed" code and it's gone.

I've done this and regretted it - CS transpires to ES3 and specifically null chaining is completely unreadable.

From a backend perspective it's no biggie to instead keep the CS dependency and gradually convert files manually when you have to make changes anyway, or when you have 15 minutes to spare between meetings.

You become fluent enough to not even need tests after a while (yikes!).

smt88 · 3 years ago
JS is flexible enough that you can get 90% of the sugar from CoffeeScript without leaving the language.

That said, I always found CoffeeScript to be a worse language (syntactically) than JS.

Waterluvian · 3 years ago
"The Modern Way to Write TypeScript."

I feel like this is exactly the right kind of slogan for a project like this. Smug and opinionated, disregarding anyone who might not feel the same.

Yahivin · 3 years ago
Help me come up with a better slogan and I'll use it.
Waterluvian · 3 years ago
A Great Way to Write TypeScript

A Concise and Powerful Dialect of TypeScript. (my favourite but some might argue that Civet is more than a dialect. I think it's a dialect.)

TypeScript, Streamlined

Write Less, Do More

Expressive Syntax and Faster Coding. (there's already two slogans, and this one is great, plus you don't have to repeat the name of the project in the title section)

Expressive Syntax, Fast Coding. (feels a bit crisper to my ears)

I think there's many ways you can say, "this is an awesome, fast, concise way to write web code that compiles to TS/JS" without suggesting it's _the_ way to write _modern_ TypeScript.

gitonthescene · 3 years ago
A Modern Way to Write Javascript?
appleiigs · 3 years ago
"In my opinion, not to offend, acknowledging diveristy, a modern way he/she/they write typescript"
bogdan · 3 years ago
For what's worth, I think your current slogan is fine.
jevgeni · 3 years ago
Civet: If You Like Stubbing Your Toes, You'll Love Our Switch Statements
0x62c1b43e · 3 years ago
If I were going to do this, I’d probably go all the way to using ReScript, but it’s a nice idea.

I’m quite surprised it’s not called ToffeeScript though.

capableweb · 3 years ago
Maybe because ToffeeScript is prior art? https://github.com/jiangmiao/toffeescript

Wasn't super popular, but wasn't unknown either.

jacknews · 3 years ago
+1 for tofeescript.

'Civet' certainly implies your code is being processed, but I'm not sure the connotation is desirable.

And all IMHO of course, but significant-whitespace is the worst idea ever.

chowells · 3 years ago
Wait, what's wrong with making sure indentation and code structure are always the same? Lying indentation structure is always wrong.
nkozyra · 3 years ago
> I'm not sure the connotation is desirable.

You'd think not, and yet ...

Yahivin · 3 years ago
Civets, they're nature's transpilers.
capableweb · 3 years ago
> significant-whitespace is the worst idea ever

Hear hear! I never heard a single argument for significant invisible characters that makes sense, ever.

Who would want to have a program that fails because you used invisible character X instead of invisible character Y?

fulafel · 3 years ago
+1 for FP family tree languages that compile to JS.

This might be a good stepping stone though to sway skeptics.

feeela · 3 years ago
Is this an April fools joke? You compile Coffeescript to Typescript to JavaScript to bytecode.

What problem ist actually solved by being able to compile pseudo-languages like Coffeescript or Typescript into each other?

Leftium · 3 years ago
I used to use CoffeeScript because the syntax was more convenient. I could do the same thing with less code. Less code can mean less maintenance (although some people have said CoffeeScript can overdo this...)

Now I use TypeScript to get the benefit of type-checking. It really helps catch silly little mistakes.

I would use Civet just to be able to use the new pipe operator syntax.

There are even compilers that compile future versions of JS into the current version of JS so future language features can be used in current browsers.

I've heard JS is the new assembly language.

altun · 3 years ago
The real joke, I guess, is that hundreds of people are talking about this.