Oh gods, I could not disagree more; I think explicit control flow should be prominent. One of the languages I find most frustrating has a tonne of implicit and optional control flow that renders it super hard to read or write, as it allows for way too much personal style.
This is almost Rust. Everything-is-an-expression makes it possible to make entire function body just ifs and match blocks that exhaustively handle all possible cases, so you never need an explicit return.
However, in such case every last statement of every “leaf” block becomes an implicit return. If you overdo it, it’s completely inscrutable.
BTW: your list 100% matches brainfuck: no implicit control flow, no style choices, no superfluous keywords, only one kind of control flow. Less is not always better.
I don’t think this is even remotely true – there is a huge difference between “you could do that” and “there is no other way of doing it”.
The latter means that the code you haven’t written (99.99% of the code) is written in that specific style; the former only means you can make your own code follow these rules (which is rather irrelevant).
Rust has waaaaay to much going, it’s not a good data point.
Less is not always better.
At least the goal posts aren’t moving every single year about the “right” language size, like in Rust’s “more features == better language” ideology. :-)
This is why my Rust libraries (very small, only about 5 million total downloads) are permanently staying on Rust 1.13 (released 2016), because I don’t feel the feature additions in the meantime have been worth the cost.
while: alternative to recursion. Replaces for loops.
I don’t understand this, return, throw, and so on are also alternatives to if, but we’re removing them, yet loops, which can be completely removed and replaced with simple recursion are an alternative that we’re keeping? how so?
The reason is that sometimes it’s hard to write tail-recursive code (or code the compiler can turn into PTCs), so having to pick code that leaks stack frames at runtime, or having awhile loop, I’ll pick the latter.
class HashMap[K: Identity + Hash, V]()
var insertedAndDeleted: BitSet = BitSet(0)
var keys: Array[K] = Array.empty()
var values: Array[V] = Array.empty()
var size: Int = 0
var cap: Int = 0
...
fun isLive(idx: Int): Bool =
self.insertedAndDeleted.contains(2 * idx) &&
self.insertedAndDeleted.contains(2 * idx + 1).not
fun get(key: K): Option[V] =
assert(self.size < self.cap)
var hash = key.hash
var idx = hash.bitwiseAnd(self.cap - 1)
var continue = true
var result = None
while continue
do
if self.isLive(idx)
then
let currentKey = self.keys(idx)
if currentKey.hash == hash && currentKey === key
then result = Some(self.values(idx))
else ()
idx = (idx + 1).bitwiseAnd(self.cap - 1)
else
continue = false
result
I agree with most things you say, but the “for” construct is invaluable for math-heavy code where “while” feels very unnatural and verbose. I agree that the notation for “for” should be simplified to only allow an iterator over a fixed range of two constant ints. I would actually prefer to keep this “for” (which is general enough) and discard “while”. It makes your code much easier to reason about (you know exactly how many loops it is going to do, without needing to understand the logic of the program).
I think you can make that case every control flow keyword; that’s basically how most languages have accumulated every control flow keyword ever invented in the last 60 years.
I’m not claiming that not having some specific keyword isn’t inconvenient in cases that keyword would shine – I’m making the case that the inconvenience caused is smaller than having to learn, remember and understand how the half dozen control flow keywords interact with each other.
It’s a bit like static imports in Java – sure, they are sometimes convenient (when writing code), but I’d argue that having two trivial, interchangeable ways to write the same thing is a much bigger inconvenience (when reading it).
Discouraging use of control flow words makes sense for future readability, but getting rid of them completely is too strong. Sometimes you really need to use these old style control flow constructs.
J gets this right – idiomatic J code are a series of one-liners using zero old-style control words (therefore allowing code to be one-way-to-do-things idiomatic, as you suggest in a reply). But if, while, try, catch, return, for, continue, goto (?), are all still there if you need them.
Ah, I misread. Then we’re talking about different things – you were thinking about removing some keywords and I was thinking about removing all keywords.
So basically “don’t change anything”, with the result that none of the benefits are realized?
I think the idea is to encourage refactoring foreign code using if, for, and while, into a more idiomatic form using combinators and no if, for, and while. Not removing these keywords from the language outright just makes it easier to get started without knowing all about J’s combinators, which is good since everyone’s likely coming from languages that use control flow keywords. Again, this is a different view from yours.
I honestly think the flipped is worse. A lot of the time the details in a given block of code aren’t that relevant, but the structure of the code is. You don’t need syntax highlighting for code you’re writing, but code you’ve already written. You are analysing the structure of the code, highlighting the changes in code path and strtucture, not the specifics of why what is happening is happening. No amount of syntax highlighting will tell you why this function is being called or it’s overarching relevance to code execution, but the relatively minimal syntax highlighting of syntactical/structural elements does give you an understanding of the what is happening at a glance.
Syntax highlighting is especially important for me to help seeing structure fast: I have slight dyslexia. Without highlighting I cannot just glance over block of code, I really need to read everything which slows everything down a lot.
This starts to hint towards the idea of Semantic Highlighting. Examples of Semantic highlighting include having each variable as a different color– so if the one you were working with for a while suddenly is a different color, you made a typo somewhere.
Or this blog post, which introduces the idea of coloring scopes differently.
JetBrains IDEs (like CLion) color different variables depending on if they’re local or not, and the Rust plugin can be adjusted to color mutable ones different than non-mutable ones.
Rainbow brackets is an amazing tool to have braces and parentheses cycle colors based on scope. The other feature I’ve found incredibly helpful and which I miss now that I’m not on a Mac is the XCode option to dim everything of your current scope.
In practice, semantic highlighting via the rainbow-identifiers and rainbow-parens packages in emacs is the best and most useful syntax highlighting scheme I’ve used.
I agree 100% with the author, and day-to-day I use my emacs color scheme that’s designed to emphasize the “information-dense” parts of code: function declarations (not callsites!) and comments.
One problem I see is that there are languages/methodologies out there that assume your editor will de-emphasize comments, for example. I think the case for minimalist syntax highlighting (or none whatsoever) can only be made in good faith in the case of information-dense languages/coding styles.
Here’s the syntax highlighting for my current project, a safe language that maps mostly 1:1 to machine code: http://akkartik.github.io/mu/html/apps/factorial.mu.html. Like @saturn, I emphasize control flow. Like @pzel, I emphasize function declarations. (I also highlight a couple other keywords here, but only because this is a new language and the highlighting is as much for showing off the language as for the specific code on screen.)
The article hangs on an assumption that highlighting is to draw attention to important things, and that particular higher-level issue is the most important. What if it’s not?
I think highlighting helps navigate the code. To understand what the code is doing it’s (also) important to see at glance where each construct starts. After all, the difference between if, while or return is not a minor detail either.
I think it’s fair to say that both the structure of the code and the details filling it are important. That’s why we highlight both, in different colors.
Syntax highlighting is a lie.
In the last year or so I stopped using it.
Life is easier.
My eyes miss less now that they are looking at the code, not focusing on what the editor sees/thinks.
What works well for you may not work as well for others. Also, most programming languages are pretty easy for an editor to parse and understand the different structured pieces, so unless you’re using some weird poorly structured language or bad at writing syntactically correct code, the editor won’t miss anything. There’s definitely some poorly implemented editors/plugins out there too.
What works well for you may not work as well for others
Yep!
Also, most programming languages are pretty easy for an editor to parse and understand the different structured pieces, so unless you’re using some weird poorly structured language or bad at writing syntactically correct code, the editor won’t miss anything
OP was not referring to an editor, but instead to their eyes. Editors may not ‘miss anything’, but human eyes definitely will.
I also went from a super duper syntax-colorful scheme to basically having just 2-3 things being formatted differently, and it was great.
The best is no highlighting, because everything is actually important. If anything is wrong, it’s wrong, and will give you bad output - thus everything is important.
The best is no highlighting, because everything is actually important.
I prefer to have syntax highlighting for comments, so that if for
whatever reason I’m in a large comment block I can tell, and so that I
can differentiate easily between what’s a description for code and what
is code itself.
I don’t like how so many colour schemes make comments really faint. If
you shouldn’t notice them without looking, I see little purpose to them
being there at all.
I think
return
andthrow
should be emphasized. I want it to be very clear if there are early exits![Comment from banned user removed]
Oh gods, I could not disagree more; I think explicit control flow should be prominent. One of the languages I find most frustrating has a tonne of implicit and optional control flow that renders it super hard to read or write, as it allows for way too much personal style.
I’m not sure how you are disagreeing with me – my suggestion is that there is only one set of control-flow keywords:
if
: replacesreturn
,throw
,switch/case
,break
,continue
.while
: alternative to recursion. Replacesfor
loops.With this
Would absolutely love to program in a language with insane nested if statements because returning early is for chumps apparently?
Couldn’t you pick any existing language for that? It’s not like people aren’t doing it voluntarily…
This is almost Rust. Everything-is-an-expression makes it possible to make entire function body just
ifs
andmatch
blocks that exhaustively handle all possible cases, so you never need an explicitreturn
.However, in such case every last statement of every “leaf” block becomes an implicit return. If you overdo it, it’s completely inscrutable.
BTW: your list 100% matches brainfuck: no implicit control flow, no style choices, no superfluous keywords, only one kind of control flow. Less is not always better.
I don’t think this is even remotely true – there is a huge difference between “you could do that” and “there is no other way of doing it”.
The latter means that the code you haven’t written (99.99% of the code) is written in that specific style; the former only means you can make your own code follow these rules (which is rather irrelevant).
Rust has waaaaay to much going, it’s not a good data point.
At least the goal posts aren’t moving every single year about the “right” language size, like in Rust’s “more features == better language” ideology. :-)
This is why my Rust libraries (very small, only about 5 million total downloads) are permanently staying on Rust 1.13 (released 2016), because I don’t feel the feature additions in the meantime have been worth the cost.
Turing tarpit much?
I don’t understand this,
return
,throw
, and so on are also alternatives toif
, but we’re removing them, yet loops, which can be completely removed and replaced with simple recursion are an alternative that we’re keeping? how so?The reason is that sometimes it’s hard to write tail-recursive code (or code the compiler can turn into PTCs), so having to pick code that leaks stack frames at runtime, or having a
while
loop, I’ll pick the latter.a fair enough point, I understand
Would you mind showing us a code example?
Here is some write-up regarding control flow.
I agree with most things you say, but the “for” construct is invaluable for math-heavy code where “while” feels very unnatural and verbose. I agree that the notation for “for” should be simplified to only allow an iterator over a fixed range of two constant ints. I would actually prefer to keep this “for” (which is general enough) and discard “while”. It makes your code much easier to reason about (you know exactly how many loops it is going to do, without needing to understand the logic of the program).
I think you can make that case every control flow keyword; that’s basically how most languages have accumulated every control flow keyword ever invented in the last 60 years.
I’m not claiming that not having some specific keyword isn’t inconvenient in cases that keyword would shine – I’m making the case that the inconvenience caused is smaller than having to learn, remember and understand how the half dozen control flow keywords interact with each other.
It’s a bit like static imports in Java – sure, they are sometimes convenient (when writing code), but I’d argue that having two trivial, interchangeable ways to write the same thing is a much bigger inconvenience (when reading it).
Discouraging use of control flow words makes sense for future readability, but getting rid of them completely is too strong. Sometimes you really need to use these old style control flow constructs.
J gets this right – idiomatic J code are a series of one-liners using zero old-style control words (therefore allowing code to be one-way-to-do-things idiomatic, as you suggest in a reply). But if, while, try, catch, return, for, continue, goto (?), are all still there if you need them.
I didn’t propose that.
So basically “don’t change anything”, with the result that none of the benefits are realized?
Ah, I misread. Then we’re talking about different things – you were thinking about removing some keywords and I was thinking about removing all keywords.
I think the idea is to encourage refactoring foreign code using
if
,for
, andwhile
, into a more idiomatic form using combinators and noif
,for
, andwhile
. Not removing these keywords from the language outright just makes it easier to get started without knowing all about J’s combinators, which is good since everyone’s likely coming from languages that use control flow keywords. Again, this is a different view from yours.I honestly think the flipped is worse. A lot of the time the details in a given block of code aren’t that relevant, but the structure of the code is. You don’t need syntax highlighting for code you’re writing, but code you’ve already written. You are analysing the structure of the code, highlighting the changes in code path and strtucture, not the specifics of why what is happening is happening. No amount of syntax highlighting will tell you why this function is being called or it’s overarching relevance to code execution, but the relatively minimal syntax highlighting of syntactical/structural elements does give you an understanding of the what is happening at a glance.
Syntax highlighting is especially important for me to help seeing structure fast: I have slight dyslexia. Without highlighting I cannot just glance over block of code, I really need to read everything which slows everything down a lot.
This starts to hint towards the idea of Semantic Highlighting. Examples of Semantic highlighting include having each variable as a different color– so if the one you were working with for a while suddenly is a different color, you made a typo somewhere.
Or this blog post, which introduces the idea of coloring scopes differently.
JetBrains IDEs (like CLion) color different variables depending on if they’re local or not, and the Rust plugin can be adjusted to color mutable ones different than non-mutable ones.
Rainbow brackets is an amazing tool to have braces and parentheses cycle colors based on scope. The other feature I’ve found incredibly helpful and which I miss now that I’m not on a Mac is the XCode option to dim everything of your current scope.
JetBrains IDEs even have the “semantic highlighting” where each variable name gives different colors, so you can more easily track specific variables.
It’s good for tracking variables and catching typos, at least
In practice, semantic highlighting via the rainbow-identifiers and rainbow-parens packages in emacs is the best and most useful syntax highlighting scheme I’ve used.
However, I can’t see a discussion about syntax highlighting being backwards and semantic highlighting without remembering some excellent academic work on the subject: WysiScript: Programming via direct syntax highlighting by Gunther and Kell in Sigbovik 2017 (page 123 of the PDF).
It’s a nice idea but it’s something I’d want as a mode, not something I’d want all the time. It’s very distracting.
I agree 100% with the author, and day-to-day I use my emacs color scheme that’s designed to emphasize the “information-dense” parts of code: function declarations (not callsites!) and comments.
One problem I see is that there are languages/methodologies out there that assume your editor will de-emphasize comments, for example. I think the case for minimalist syntax highlighting (or none whatsoever) can only be made in good faith in the case of information-dense languages/coding styles.
Not all comments are worth highlighting: http://akkartik.name/post/2012-11-24-18-10-36-soc
For the last 6 years I use three colors for comments: https://i.imgur.com/vU783Xo_d.jpg?maxwidth=640
If you have a configurable editor you can find more useful things to highlight in the code as well: https://www.reddit.com/r/programming/comments/1w76um/comment/cezpios
(Repeating myself from the last time this came up: https://news.ycombinator.com/item?id=21665105#21665366)
Here’s the syntax highlighting for my current project, a safe language that maps mostly 1:1 to machine code: http://akkartik.github.io/mu/html/apps/factorial.mu.html. Like @saturn, I emphasize control flow. Like @pzel, I emphasize function declarations. (I also highlight a couple other keywords here, but only because this is a new language and the highlighting is as much for showing off the language as for the specific code on screen.)
The article hangs on an assumption that highlighting is to draw attention to important things, and that particular higher-level issue is the most important. What if it’s not?
I think highlighting helps navigate the code. To understand what the code is doing it’s (also) important to see at glance where each construct starts. After all, the difference between
if
,while
orreturn
is not a minor detail either.I think it’s fair to say that both the structure of the code and the details filling it are important. That’s why we highlight both, in different colors.
Syntax highlighting is a lie. In the last year or so I stopped using it. Life is easier. My eyes miss less now that they are looking at the code, not focusing on what the editor sees/thinks.
What works well for you may not work as well for others. Also, most programming languages are pretty easy for an editor to parse and understand the different structured pieces, so unless you’re using some weird poorly structured language or bad at writing syntactically correct code, the editor won’t miss anything. There’s definitely some poorly implemented editors/plugins out there too.
Yep!
OP was not referring to an editor, but instead to their eyes. Editors may not ‘miss anything’, but human eyes definitely will.
I also went from a super duper syntax-colorful scheme to basically having just 2-3 things being formatted differently, and it was great.
I don’t see a problem: most IDEs have a way to specify the syntax highlighting for basically everything, so pick your favourite.
The best is no highlighting, because everything is actually important. If anything is wrong, it’s wrong, and will give you bad output - thus everything is important.
The syntax highlight is not for the computer, it’s for the human.
Some parts are quite trivial and it’s enough when IDE gives them spotlight if there is a typo in them.
I did not say otherwise. And humans who need syntax highlighting is ok, but to me, it’s a lot of visual noise.
I prefer to have syntax highlighting for comments, so that if for whatever reason I’m in a large comment block I can tell, and so that I can differentiate easily between what’s a description for code and what is code itself.
I don’t like how so many colour schemes make comments really faint. If you shouldn’t notice them without looking, I see little purpose to them being there at all.